X-Git-Url: http://git.mutantstargoat.com?a=blobdiff_plain;f=src%2Fhair.cc;h=0fc026d7b6d5a28f90e3cb6078b0deb1441b58c5;hb=6a6b355866e9c227415ed028966362d3760353de;hp=33bdd0d43f2f41ac91c4d773032ce6d15c619ed2;hpb=43078ddde36cc81375cddfe45f47f806b9d19307;p=hair diff --git a/src/hair.cc b/src/hair.cc index 33bdd0d..0fc026d 100644 --- a/src/hair.cc +++ b/src/hair.cc @@ -8,13 +8,24 @@ #include "kdtree.h" #include "hair.h" +/* spring constant */ + +#define K_ANC 4.0 +#define DAMPING 1.5 + struct Triangle { Vec3 v[3]; Vec3 n[3]; }; -Hair::Hair() {} -Hair::~Hair() {} +Hair::Hair() +{ + hair_length = 0.5; +} + +Hair::~Hair() +{ +} static Vec3 calc_rand_point(const Triangle &tr, Vec3 *bary) { @@ -34,7 +45,6 @@ static Vec3 calc_rand_point(const Triangle &tr, Vec3 *bary) bary->y = v; bary->z = c; -// printf("u %f v %f c %f sum: %f\n", u, v, c, u+v+c); return rp; } @@ -72,7 +82,7 @@ static void get_spawn_triangles(const Mesh *m, float thresh, std::vectorpush_back(t); } } - printf("spawn tri AABB: min y: %f max y: %f\n", min_y, max_y); +/* printf("spawn tri AABB: min y: %f max y: %f\n", min_y, max_y);*/ } bool Hair::init(const Mesh *m, int max_num_spawns, float thresh) @@ -104,28 +114,99 @@ bool Hair::init(const Mesh *m, int max_num_spawns, float thresh) continue; } + HairStrand strand; /* weighted sum of the triangle's vertex normals */ - Vec3 spawn_dir = rtriangle.n[0] * bary.x + rtriangle.n[1] * bary.y + rtriangle.n[2] * bary.z; - spawn_directions.push_back(normalize(spawn_dir)); - spawn_points.push_back(rpoint); + strand.spawn_dir = normalize(rtriangle.n[0] * bary.x + rtriangle.n[1] * bary.y + rtriangle.n[2] * bary.z); + strand.spawn_pt = rpoint; + hair.push_back(strand); + kd_insert3f(kd, rpoint.x, rpoint.y, rpoint.z, 0); } kd_free(kd); + + for(size_t i=0; i 0.99)) { + vi = Vec3(0, -1, 0); + } + Vec3 vj = normalize(cross(vk, vi)); + vi = cross(vj, vk); + + /* identity when the hair points to the z axis */ + Mat4 basis = Mat4(vi, vj, vk); + + for(int j=0; j<3; j++) { + float angle = (float)j / 3.0 * 2 * M_PI; + /* dir of each anchor relative to hair root */ + Vec3 dir = Vec3(cos(angle), sin(angle), 0); + dir = basis * dir; + hair[i].anchor_dirs[j] = hair[i].pos + dir - hair[i].spawn_pt; + } + } return true; } +static Vec3 dbg_force; void Hair::draw() const { glPushAttrib(GL_ENABLE_BIT); - glDisable(GL_DEPTH_TEST); +// glDisable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); - glPointSize(2); - glBegin(GL_POINTS); - for(size_t i = 0; i < spawn_points.size(); i++) { + glPointSize(5); + glLineWidth(3); + + glBegin(GL_LINES); + for(size_t i=0; ixform = xform; +} + +void Hair::update(float dt) +{ + for(size_t i = 0; i < hair.size(); i++) { + /* in local space */ + Vec3 hair_end = hair[i].spawn_pt + hair[i].spawn_dir * hair_length; + Vec3 anchor = xform * hair_end; + + Vec3 force = (anchor - hair[i].pos) * K_ANC; + + Vec3 accel = force; /* mass 1 */ + hair[i].velocity += ((-hair[i].velocity * DAMPING) + accel) * dt; + hair[i].pos += hair[i].velocity * dt; + + dbg_force = force; + } +}