#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];
for(size_t i=0; i<hair.size(); i++) {
hair[i].pos = hair[i].spawn_pt + hair[i].spawn_dir * hair_length;
-
+
/* orthonormal basis */
Vec3 vk = hair[i].spawn_dir;
Vec3 vi = Vec3(1, 0, 0);
for(int j=0; j<3; j++) {
float angle = (float)j / 3.0 * 2 * M_PI;
- /* dir of each anchor relative to hair end */
+ /* 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_LIGHTING);
glPointSize(5);
- glLineWidth(2);
+ glLineWidth(3);
glBegin(GL_LINES);
for(size_t i=0; i<hair.size(); i++) {
glColor3f(1, 0, 1);
- glVertex3f(hair[i].pos.x, hair[i].pos.y, hair[i].pos.z);
- Vec3 p = hair[i].spawn_pt;
+ Vec3 p = xform * hair[i].spawn_pt;
glVertex3f(p.x, p.y, p.z);
+ Vec3 dir = normalize(hair[i].pos - p) * hair_length;
+ Vec3 end = p + dir;
+ glVertex3f(end.x, end.y, end.z);
+/*
+ glColor3f(1, 1, 0);
+ glVertex3f(hair[i].pos.x, hair[i].pos.y, hair[i].pos.z);
+ Vec3 end = hair[i].pos + dbg_force * 2.0;
+ glVertex3f(end.x, end.y, end.z);
+ */
}
glEnd();
+ /*
glBegin(GL_POINTS);
glColor3f(0.5, 1.0, 0.5);
- for(size_t i=0; i<hair.size(); i++) {
- for(int j=0; j<3; j++) {
- Vec3 p = hair[i].spawn_pt + hair[i].anchor_dirs[j];
- glVertex3f(p.x, p.y, p.z);
- }
+ for(size_t i = 0; i < hair.size(); i++) {
+ Vec3 p = xform * (hair[i].spawn_pt + hair[i].spawn_dir * hair_length);
+ glVertex3f(p.x, p.y, p.z);
}
- glEnd();
+ glEnd();*/
glPopAttrib();
}
{
this->xform = 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;
+ }
+}
#include "mesh.h"
#include "hair.h"
-#define MAX_NUM_SPAWNS 4
+#define MAX_NUM_SPAWNS 400
#define THRESH 0.5
static bool init();
static void display()
{
+ static unsigned long prev_time;
+ unsigned long msec = glutGet(GLUT_ELAPSED_TIME);
+ float dt = (float)(msec - prev_time) / 1000.0;
+ prev_time = msec;
+
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
head_xform = Mat4::identity;
glTranslatef(0, 0, -cam_dist);
glRotatef(cam_phi, 1, 0, 0);
glRotatef(cam_theta, 0, 1, 0);
-
+ /* multiplying with the head rot matrix */
+ glPushMatrix();
glMultMatrixf(head_xform[0]);
-
for(size_t i=0; i<meshes.size(); i++) {
meshes[i]->draw();
}
+ glPopMatrix();
hair.set_transform(head_xform);
+ hair.update(dt);
hair.draw();
glutSwapBuffers();
if(head_rx > 45) head_rx = 45;
if(head_rz < -90) head_rz = -90;
- if(head_rz > 90) head_rx = 90;
+ if(head_rz > 90) head_rz = 30;
}
}
else {