X-Git-Url: http://git.mutantstargoat.com?p=hair;a=blobdiff_plain;f=src%2Fhair.cc;h=b99d133994ac0028d5fde2b6f13bf7db68f4634e;hp=171c7e838f0d08e0f08df551e5af481e7f860e24;hb=a65a977df6fa8fee831c91cdc754d62e023b6630;hpb=ed91d376224c1efe305d483c05f837820df75b71 diff --git a/src/hair.cc b/src/hair.cc index 171c7e8..b99d133 100644 --- a/src/hair.cc +++ b/src/hair.cc @@ -8,6 +8,11 @@ #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]; @@ -77,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) @@ -122,56 +127,88 @@ bool Hair::init(const Mesh *m, int max_num_spawns, float thresh) 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 end */ - 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_LIGHTING); glPointSize(5); - glLineWidth(2); + 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; + Vec3 new_pos = hair[i].pos + hair[i].velocity * dt; + + hair[i].pos = handle_collision(new_pos); + + dbg_force = force; + } +} + +void Hair::add_collider(CollSphere *cobj) { + colliders.push_back(cobj); +} + +Vec3 Hair::handle_collision(const Vec3 &v) const +{ + /* if we transform the center and the radius of the collider sphere + * we might end up with a spheroid, so better just multiply the + * position with the inverse transform before check for collisions :*/ + + Vec3 new_v = inverse(xform) * v; + + for(size_t i=0; icontains(new_v)) { + new_v = colliders[i]->project_surf(new_v); + } + } + return xform * new_v; +}