1 #include <gmath/gmath.h>
16 static Vec3 calc_rand_point(const Triangle &tr, Vec3 *bary)
18 float u = (float)rand() / (float)RAND_MAX;
19 float v = (float)rand() / (float)RAND_MAX;
26 float c = 1 - (u + v);
28 Vec3 rp = u * tr.v[0] + v * tr.v[1] + c * tr.v[3];
37 static void get_spawn_triangles(const Mesh *m, float thresh, std::vector<Triangle> *faces)
39 for(size_t i=0; i<m->indices.size() / 3; i++) {
42 for(int j=0; j<3; j++) {
44 float c = (m->colors[idx[j]].x + m->colors[idx[j]].y + m->colors[idx[j]].z) / 3;
53 for(int j=0; j<3; j++) {
54 t.v[j] = m->vertices[idx[j]];
55 t.n[j] = m->normals[idx[j]];
62 bool Hair::init(const Mesh *m, int max_num_spawns, float thresh)
64 std::vector<Triangle> faces;
65 kdtree *kd = kd_create(3);
66 const float min_dist = 0.05;
68 get_spawn_triangles(m, thresh, &faces);
70 for(int i = 0; i < max_num_spawns; i++) {
72 int rnum = (float)((float)rand() / (float)RAND_MAX) * faces.size();
73 Triangle rtriangle = faces[rnum];
75 Vec3 rpoint = calc_rand_point(rtriangle, &bary);
77 kdres *res = kd_nearest3f(kd, rpoint.x, rpoint.y, rpoint.z);
78 if (!kd_res_end(res)) {
80 kd_res_item3f(res, &nearest.x, &nearest.y, &nearest.z);
81 if(distance_sq(rpoint, nearest) < min_dist * min_dist)
85 /* weighted sum of the triangle's vertex normals */
86 Vec3 spawn_dir = rtriangle.n[0] * bary.x + rtriangle.n[1] * bary.y + rtriangle.n[2] * bary.z;
87 spawn_directions.push_back(normalize(spawn_dir));
88 spawn_points.push_back(rpoint);
89 kd_insert3f(kd, rpoint.x, rpoint.y, rpoint.z, 0);
96 void Hair::draw() const