added forces + damping, k factors
authorEleni Maria Stea <estea@igalia.com>
Sun, 6 Jan 2019 07:34:48 +0000 (09:34 +0200)
committerEleni Maria Stea <estea@igalia.com>
Sun, 6 Jan 2019 07:34:48 +0000 (09:34 +0200)
src/hair.cc
src/hair.h
src/main.cc

index 2431f50..0fc026d 100644 (file)
@@ -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];
@@ -122,7 +127,7 @@ bool Hair::init(const Mesh *m, int max_num_spawns, float thresh)
 
        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);
@@ -137,7 +142,7 @@ bool Hair::init(const Mesh *m, int max_num_spawns, float thresh)
 
                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;
@@ -146,32 +151,40 @@ bool Hair::init(const Mesh *m, int max_num_spawns, float thresh)
        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();
 }
@@ -180,3 +193,20 @@ void Hair::set_transform(Mat4 &xform)
 {
        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;
+       }
+}
index 23aff83..6cbf14e 100644 (file)
@@ -28,6 +28,7 @@ public:
        void draw() const;
 
        void set_transform(Mat4 &xform);
+       void update(float dt);
 };
 
 #endif //PARTICLES_H_
index 307f647..54959a8 100644 (file)
@@ -11,7 +11,7 @@
 #include "mesh.h"
 #include "hair.h"
 
-#define MAX_NUM_SPAWNS 4
+#define MAX_NUM_SPAWNS 400
 #define THRESH 0.5
 
 static bool init();
@@ -120,6 +120,11 @@ static void cleanup()
 
 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;
@@ -131,14 +136,16 @@ static void display()
        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();
@@ -211,7 +218,7 @@ static void motion(int x, int y)
                        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 {