4 #include <gmath/gmath.h>
25 static Vec3 calc_rand_point(const Triangle &tr, Vec3 *bary)
27 float u = (float)rand() / (float)RAND_MAX;
28 float v = (float)rand() / (float)RAND_MAX;
35 float c = 1 - (u + v);
37 Vec3 rp = u * tr.v[0] + v * tr.v[1] + c * tr.v[2];
46 static void get_spawn_triangles(const Mesh *m, float thresh, std::vector<Triangle> *faces)
49 fprintf(stderr, "Func: %s, invalid mesh.\n", __func__);
52 float min_y = FLT_MAX;
53 float max_y = -FLT_MAX;
55 for(size_t i=0; i<m->indices.size() / 3; i++) {
58 for(int j=0; j<3; j++) {
59 idx[j] = m->indices[i * 3 + j];
60 float c = (m->colors[idx[j]].x + m->colors[idx[j]].y + m->colors[idx[j]].z) / 3;
69 for(int j=0; j<3; j++) {
70 t.v[j] = m->vertices[idx[j]];
71 t.n[j] = m->normals[idx[j]];
80 /* printf("spawn tri AABB: min y: %f max y: %f\n", min_y, max_y);*/
83 bool Hair::init(const Mesh *m, int max_num_spawns, float thresh)
85 std::vector<Triangle> faces;
86 kdtree *kd = kd_create(3);
87 const float min_dist = 0.05;
90 fprintf(stderr, "Func %s: invalid mesh.\n", __func__);
94 get_spawn_triangles(m, thresh, &faces);
96 for(int i = 0; i < max_num_spawns; i++) {
98 int rnum = (float)((float)rand() / (float)RAND_MAX) * faces.size();
99 Triangle rtriangle = faces[rnum];
101 Vec3 rpoint = calc_rand_point(rtriangle, &bary);
103 kdres *res = kd_nearest3f(kd, rpoint.x, rpoint.y, rpoint.z);
105 if (res && !kd_res_end(res)) {
107 kd_res_item3f(res, &nearest.x, &nearest.y, &nearest.z);
108 if(distance_sq(rpoint, nearest) < min_dist * min_dist)
113 /* weighted sum of the triangle's vertex normals */
114 strand.spawn_dir = normalize(rtriangle.n[0] * bary.x + rtriangle.n[1] * bary.y + rtriangle.n[2] * bary.z);
115 strand.spawn_pt = rpoint;
116 hair.push_back(strand);
118 kd_insert3f(kd, rpoint.x, rpoint.y, rpoint.z, 0);
123 for(size_t i=0; i<hair.size(); i++) {
124 hair[i].pos = hair[i].spawn_pt + hair[i].spawn_dir * hair_length;
126 /* orthonormal basis */
127 Vec3 vk = hair[i].spawn_dir;
128 Vec3 vi = Vec3(1, 0, 0);
129 if(fabs(vk.x > 0.99)) {
132 Vec3 vj = normalize(cross(vk, vi));
135 /* identity when the hair points to the z axis */
136 Mat4 basis = Mat4(vi, vj, vk);
138 for(int j=0; j<3; j++) {
139 float angle = (float)j / 3.0 * 2 * M_PI;
140 /* dir of each anchor relative to hair end */
141 Vec3 dir = Vec3(cos(angle), sin(angle), 0);
143 hair[i].anchor_dirs[j] = hair[i].pos + dir - hair[i].spawn_pt;
149 void Hair::draw() const
151 glPushAttrib(GL_ENABLE_BIT);
152 // glDisable(GL_DEPTH_TEST);
153 glDisable(GL_LIGHTING);
158 for(size_t i=0; i<hair.size(); i++) {
160 glVertex3f(hair[i].pos.x, hair[i].pos.y, hair[i].pos.z);
161 Vec3 p = hair[i].spawn_pt;
162 glVertex3f(p.x, p.y, p.z);
167 glColor3f(0.5, 1.0, 0.5);
168 for(size_t i=0; i<hair.size(); i++) {
169 for(int j=0; j<3; j++) {
170 Vec3 p = hair[i].spawn_pt + hair[i].anchor_dirs[j];
171 glVertex3f(p.x, p.y, p.z);
179 void Hair::set_transform(Mat4 &xform)