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;
+
+ 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;
+}
#include "mesh.h"
#include "hair.h"
+#include "object.h"
#define MAX_NUM_SPAWNS 400
#define THRESH 0.5
static float cam_theta, cam_phi = 25, cam_dist = 8;
static float head_rz, head_rx; /* rot angles x, z axis */
static Mat4 head_xform;
+static CollSphere coll_sphere; /* sphere used for collision detection */
int main(int argc, char **argv)
{
return false;
}
+ coll_sphere.radius = 1.0;
+ coll_sphere.center = Vec3(0, 0.6, 0.53);
+
if(!hair.init(mesh_head, MAX_NUM_SPAWNS, THRESH)) {
fprintf(stderr, "Failed to initialize hair\n");
return false;
}
+ hair.add_collider(&coll_sphere);
+
return true;
}
/* multiplying with the head rot matrix */
glPushMatrix();
glMultMatrixf(head_xform[0]);
+ glPushAttrib(GL_LINE_BIT);
+ glLineWidth(1);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
for(size_t i=0; i<meshes.size(); i++) {
meshes[i]->draw();
}
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ glPopAttrib();
+
glPopMatrix();
hair.set_transform(head_xform);
hair.update(dt);
hair.draw();
+/*
+ glPushAttrib(GL_ENABLE_BIT);
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_LIGHTING);
+ glBegin(GL_POINTS);
+ for (int i=0; i<500; i++) {
+ Vec3 p;
+ p.x = (float)rand() / RAND_MAX * 8 - 4;
+ p.y = (float)rand() / RAND_MAX * 4;
+ p.z = 0;
+
+ Vec3 tmp = inverse(head_xform) * p;
+ if(coll_sphere.contains(tmp)) {
+ glColor3f(1, 0, 0);
+ }
+ else glColor3f(0, 1, 0);
+
+ glVertex3f(p.x, p.y, p.z);
+ }
+ glEnd();
+ glPopAttrib();
+ */
+
glutSwapBuffers();
assert(glGetError() == GL_NO_ERROR);
}