Failed hack for collision detection with a sphere.
authorEleni Maria Stea <estea@igalia.com>
Sat, 26 Jan 2019 18:29:25 +0000 (20:29 +0200)
committerEleni Maria Stea <estea@igalia.com>
Sat, 26 Jan 2019 18:29:25 +0000 (20:29 +0200)
src/hair.cc
src/hair.h
src/main.cc
src/object.cc [new file with mode: 0644]
src/object.h [new file with mode: 0644]

index c86044b..b99d133 100644 (file)
@@ -185,8 +185,30 @@ 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;
+
+               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;
+}
index 5ef54d0..9ef5130 100644 (file)
@@ -4,6 +4,7 @@
 #include <gmath/gmath.h>
 
 #include "mesh.h" 
+#include "object.h"
 
 struct HairStrand {
        Vec3 pos;
@@ -17,6 +18,7 @@ private:
        float hair_length;
        std::vector<HairStrand> hair;
        Mat4 xform;
+       std::vector<CollSphere *> colliders;
 
 public:
        Hair();
@@ -27,6 +29,8 @@ public:
 
        void set_transform(Mat4 &xform);
        void update(float dt);
+       void add_collider(CollSphere *cobj);
+       Vec3 handle_collision(const Vec3 &v) const;
 };
 
 #endif //PARTICLES_H_
index 54959a8..01f6716 100644 (file)
@@ -10,6 +10,7 @@
 
 #include "mesh.h"
 #include "hair.h"
+#include "object.h"
 
 #define MAX_NUM_SPAWNS 400
 #define THRESH 0.5
@@ -32,6 +33,7 @@ static int win_width, win_height;
 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)
 {
@@ -103,11 +105,16 @@ static bool init()
                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;
 }
 
@@ -139,15 +146,44 @@ static void display()
        /* 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);
 }
diff --git a/src/object.cc b/src/object.cc
new file mode 100644 (file)
index 0000000..ae33bb1
--- /dev/null
@@ -0,0 +1,16 @@
+#include "object.h"
+
+CollSphere::CollSphere()
+{
+       radius = 1.0;
+}
+
+bool CollSphere::contains(const Vec3 &v) const
+{
+       return length_sq(v - center) <= radius * radius;
+}
+
+Vec3 CollSphere::project_surf(const Vec3 &v) const
+{
+       return center + normalize(v - center) * radius;
+}
diff --git a/src/object.h b/src/object.h
new file mode 100644 (file)
index 0000000..2efedf7
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef OBJECT_H_
+#define OBJECT_H_
+
+#include <gmath/gmath.h>
+
+class CollSphere {
+public:
+       float radius;
+       Vec3 center;
+
+       CollSphere();
+
+       bool contains(const Vec3 &v) const;
+       Vec3 project_surf(const Vec3 &v) const;
+};
+
+#endif // OBJECT_H_