9 #include <gmath/gmath.h>
15 #define MAX_NUM_SPAWNS 400
19 static void cleanup();
20 static void display();
21 static void reshape(int x, int y);
22 static void keydown(unsigned char key, int x, int y);
23 static void keyup(unsigned char key, int x, int y);
24 static void mouse(int bn, int st, int x, int y);
25 static void motion(int x, int y);
28 static std::vector<Mesh*> meshes;
29 static Mesh *mesh_head;
32 static int win_width, win_height;
33 static float cam_theta, cam_phi = 25, cam_dist = 8;
34 static float head_rz, head_rx; /* rot angles x, z axis */
35 static Mat4 head_xform;
36 static CollSphere coll_sphere; /* sphere used for collision detection */
38 int main(int argc, char **argv)
40 glutInit(&argc, argv);
41 glutInitWindowSize(800, 600);
42 glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
43 glutCreateWindow("hair test");
45 /* for the keydown, keyup functions to work */
46 glutSetKeyRepeat(GLUT_KEY_REPEAT_OFF);
48 glutDisplayFunc(display);
49 glutReshapeFunc(reshape);
50 glutKeyboardFunc(keydown);
51 glutKeyboardUpFunc(keyup);
53 glutMotionFunc(motion);
69 glEnable(GL_DEPTH_TEST);
70 glEnable(GL_CULL_FACE);
71 glEnable(GL_COLOR_MATERIAL);
73 glEnable(GL_LIGHTING);
76 glClearColor(0.5, 0.5, 0.5, 1);
77 meshes = load_meshes("data/head.fbx");
79 fprintf(stderr, "Failed to load mesh.\n");
83 for(size_t i=0; i<meshes.size(); i++) {
84 meshes[i]->calc_bbox();
86 Vec3 v0 = meshes[i]->bbox.v0;
87 Vec3 v1 = meshes[i]->bbox.v1;
89 printf("mesh: %s\n", meshes[i]->name.c_str());
90 printf("AABB mesh %d: v0: (%f, %f, %f) v1: (%f, %f, %f)\n",
91 (int)i, v0.x, v0.y, v0.z, v1.x, v1.y, v1.z);
93 meshes[i]->update_vbo(MESH_ALL);
95 printf("num vertices: %d num triangles: %d\n",
96 (int)meshes[i]->vertices.size(),
97 (int)meshes[i]->indices.size() / 3);
99 if(meshes[i]->name == "head") {
100 mesh_head = meshes[i];
104 fprintf(stderr, "Failed to find the head mesh.\n");
108 coll_sphere.radius = 1.0;
109 coll_sphere.center = Vec3(0, 0.6, 0.53);
111 if(!hair.init(mesh_head, MAX_NUM_SPAWNS, THRESH)) {
112 fprintf(stderr, "Failed to initialize hair\n");
116 hair.add_collider(&coll_sphere);
121 static void cleanup()
123 for(size_t i=0; i<meshes.size(); i++) {
128 static void display()
130 static unsigned long prev_time;
131 unsigned long msec = glutGet(GLUT_ELAPSED_TIME);
132 float dt = (float)(msec - prev_time) / 1000.0;
135 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
137 head_xform = Mat4::identity;
138 head_xform.rotate_x(gph::deg_to_rad(head_rx));
139 head_xform.rotate_z(-gph::deg_to_rad(head_rz));
141 glMatrixMode(GL_MODELVIEW);
143 glTranslatef(0, 0, -cam_dist);
144 glRotatef(cam_phi, 1, 0, 0);
145 glRotatef(cam_theta, 0, 1, 0);
146 /* multiplying with the head rot matrix */
148 glMultMatrixf(head_xform[0]);
150 glPushAttrib(GL_LINE_BIT);
152 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
154 for(size_t i=0; i<meshes.size(); i++) {
158 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
164 hair.set_transform(head_xform);
169 glPushAttrib(GL_ENABLE_BIT);
170 glDisable(GL_DEPTH_TEST);
171 glDisable(GL_LIGHTING);
173 for (int i=0; i<500; i++) {
175 p.x = (float)rand() / RAND_MAX * 8 - 4;
176 p.y = (float)rand() / RAND_MAX * 4;
179 Vec3 tmp = inverse(head_xform) * p;
180 if(coll_sphere.contains(tmp)) {
183 else glColor3f(0, 1, 0);
185 glVertex3f(p.x, p.y, p.z);
192 assert(glGetError() == GL_NO_ERROR);
195 static void reshape(int x, int y)
197 glViewport(0, 0, x, y);
201 glMatrixMode(GL_PROJECTION);
203 gluPerspective(50.0, (float)x / (float)y, 0.5, 500.0);
206 static bool hpressed;
207 static void keydown(unsigned char key, int /*x*/, int /*y*/)
221 static void keyup(unsigned char key, int /*x*/, int /*y*/)
236 static void mouse(int bn, int st, int x, int y)
238 bnstate[bn] = st == GLUT_DOWN;
243 static void motion(int x, int y)
250 if(!dx && !dy) return;
257 if(head_rx < -45) head_rx = -45;
258 if(head_rx > 45) head_rx = 45;
260 if(head_rz < -90) head_rz = -90;
261 if(head_rz > 90) head_rz = 30;
266 cam_theta += dx * 0.5;
269 if(cam_phi < -90) cam_phi = -90;
270 if(cam_phi > 90) cam_phi = 90;
273 cam_dist += dy * 0.1;
274 if(cam_dist < 0) cam_dist = 0;