Added anchor points and hair strands.
authorEleni Maria Stea <estea@igalia.com>
Wed, 21 Nov 2018 14:42:53 +0000 (16:42 +0200)
committerEleni Maria Stea <estea@igalia.com>
Wed, 21 Nov 2018 14:42:53 +0000 (16:42 +0200)
Makefile
src/hair.cc
src/hair.h
src/main.cc

index 517443a..660400a 100755 (executable)
--- a/Makefile
+++ b/Makefile
@@ -10,7 +10,7 @@ inc = -Isrc -Isrc/shaders -Isrc/math
 
 CXX = g++
 CXXFLAGS = -pedantic -Wall $(dbg) $(opt) $(inc)
-LDFLAGS = -lGL -lGLU -lglut -lGLEW -limago -lassimp
+LDFLAGS = -lGL -lGLU -lglut -lGLEW -limago -lassimp -lgmath
 
 $(bin): $(obj)
        $(CXX) -o $@ $(obj) $(LDFLAGS)
index 33bdd0d..171c7e8 100644 (file)
@@ -13,8 +13,14 @@ struct Triangle {
        Vec3 n[3];
 };
 
-Hair::Hair() {}
-Hair::~Hair() {}
+Hair::Hair()
+{
+       hair_length = 0.5;
+}
+
+Hair::~Hair()
+{
+}
 
 static Vec3 calc_rand_point(const Triangle &tr, Vec3 *bary)
 {
@@ -34,7 +40,6 @@ static Vec3 calc_rand_point(const Triangle &tr, Vec3 *bary)
        bary->y = v;
        bary->z = c;
 
-//     printf("u %f v %f c %f sum: %f\n", u, v, c, u+v+c);
        return rp;
 }
 
@@ -104,28 +109,69 @@ bool Hair::init(const Mesh *m, int max_num_spawns, float thresh)
                                continue;
                }
 
+               HairStrand strand;
                /* weighted sum of the triangle's vertex normals */
-               Vec3 spawn_dir = rtriangle.n[0] * bary.x + rtriangle.n[1] * bary.y + rtriangle.n[2] * bary.z;
-               spawn_directions.push_back(normalize(spawn_dir));
-               spawn_points.push_back(rpoint);
+               strand.spawn_dir = normalize(rtriangle.n[0] * bary.x + rtriangle.n[1] * bary.y + rtriangle.n[2] * bary.z);
+               strand.spawn_pt = rpoint;
+               hair.push_back(strand);
+
                kd_insert3f(kd, rpoint.x, rpoint.y, rpoint.z, 0);
        }
 
        kd_free(kd);
+
+       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);
+               if(fabs(vk.x > 0.99)) {
+                       vi = Vec3(0, -1, 0);
+               }
+               Vec3 vj = normalize(cross(vk, vi));
+               vi = cross(vj, vk);
+
+               /* identity when the hair points to the z axis */
+               Mat4 basis = Mat4(vi, vj, vk);
+
+               for(int j=0; j<3; j++) {
+                       float angle = (float)j / 3.0 * 2 * M_PI;
+                       /* dir of each anchor relative to hair end */
+                       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;
 }
 
 void Hair::draw() const
 {
        glPushAttrib(GL_ENABLE_BIT);
-       glDisable(GL_DEPTH_TEST);
+//     glDisable(GL_DEPTH_TEST);
        glDisable(GL_LIGHTING);
-       glPointSize(2);
+       glPointSize(5);
+       glLineWidth(2);
+
+       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;
+               glVertex3f(p.x, p.y, p.z);
+       }
+       glEnd();
+
        glBegin(GL_POINTS);
-       for(size_t i = 0; i < spawn_points.size(); i++) {
-               glColor3f(1, 1, 0);
-               glVertex3f(spawn_points[i].x, spawn_points[i].y, spawn_points[i].z);
+       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);
+               }
        }
        glEnd();
+
        glPopAttrib();
 }
index 19fa82e..be979ee 100644 (file)
@@ -5,10 +5,19 @@
 
 #include "mesh.h" 
 
+struct HairStrand {
+       Vec3 pos;
+       Vec3 velocity;
+       /* directions relative to the spawn point */
+       Vec3 anchor_dirs[3];
+       Vec3 spawn_pt;
+       Vec3 spawn_dir;
+};
+
 class Hair {
 private:
-       std::vector<Vec3> spawn_points;
-       std::vector<Vec3> spawn_directions;
+       float hair_length;
+       std::vector<HairStrand> hair;
 
 public:
        Hair();
index 750a2d8..2bdbad9 100644 (file)
@@ -9,7 +9,8 @@
 #include "mesh.h"
 #include "hair.h"
 
-#define MAX_NUM_SPAWNS 500
+#define MAX_NUM_SPAWNS 4
+#define THRESH 0.5
 
 static bool init();
 static void cleanup();
@@ -90,7 +91,7 @@ static bool init()
                return false;
        }
 
-       if(!hair.init(mesh_head, MAX_NUM_SPAWNS, 0.1)) {
+       if(!hair.init(mesh_head, MAX_NUM_SPAWNS, THRESH)) {
                fprintf(stderr, "Failed to initialize hair\n");
                return false;
        }