X-Git-Url: https://eleni.mutantstargoat.com/git/?p=hair;a=blobdiff_plain;f=src%2Fhair.cc;h=a369465e76a35d3ddd1cd04e59577ff286c380ed;hp=c86044b56494737809c461e475635c47e3fb7239;hb=HEAD;hpb=b07896ffc92093a3e8adb4953d22927a5874e43d diff --git a/src/hair.cc b/src/hair.cc index c86044b..a369465 100644 --- a/src/hair.cc +++ b/src/hair.cc @@ -110,6 +110,7 @@ bool Hair::init(const Mesh *m, int max_num_spawns, float thresh) if (res && !kd_res_end(res)) { Vec3 nearest; kd_res_item3f(res, &nearest.x, &nearest.y, &nearest.z); + kd_res_free(res); if(distance_sq(rpoint, nearest) < min_dist * min_dist) continue; } @@ -147,6 +148,7 @@ void Hair::draw() const glVertex3f(p.x, p.y, p.z); Vec3 dir = normalize(hair[i].pos - p) * hair_length; Vec3 end = p + dir; + glColor3f(1, 1, 0); glVertex3f(end.x, end.y, end.z); /* glColor3f(1, 1, 0); @@ -185,8 +187,43 @@ void Hair::update(float dt) Vec3 accel = force; /* mass 1 */ hair[i].velocity += ((-hair[i].velocity * DAMPING) + accel) * dt; - hair[i].pos += hair[i].velocity * dt; + Vec3 new_pos = hair[i].pos + hair[i].velocity * dt; + + /* collision detection with the head */ + Vec3 normal = xform.upper3x3() * hair[i].spawn_dir; + Vec3 root = xform * hair[i].spawn_pt; + Vec3 dir = new_pos - root; + + normal.normalize(); + + /* angle that will cause the hair to be rendered inside the head */ + float d = dot(dir, normal); + if(d < 0) { + new_pos += -d * normal; + } + + 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; +}