Updated README.md with build instructions
[hair] / src / hair.cc
index c86044b..a369465 100644 (file)
@@ -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; i<colliders.size(); i++) {
+               if(colliders[i]->contains(new_v)) {
+                       new_v = colliders[i]->project_surf(new_v);
+               }
+       }
+       return xform * new_v;
+}