///////////////////////////////////////////// // // Skeletal Animation // Sylwester Feduk ///////////////////////////////////////////// #include #include #include #include #include #include #include #include #include using namespace std; #pragma comment(lib,"winmm.lib") /////////////////////////////////////////// #include "core.h" #include "Bmp.h" #include "ogl.h" #include "glsl.h" /////////////////////////////////////////// vec4f lightvec(-1, 0, -1, 0); #include "Mesh.h" ///////////////////////////////////////////////////////// // // EXERCISES // ///////////////////////////////////////////////////////// /////////////////////////////////////////// void printBone(Mesh halo, int index, int level) { //TO DO } /////////////////////////////////////////// void updateChilds(Mesh& mesh, int index); void AnimateBone(Mesh& mesh, char* boneName, float phiX, float phiY, float phiZ) { matrix33 rx(1, 0, 0, 0, cos(phiX), -sin(phiX), 0, sin(phiX), cos(phiX)); matrix33 ry(cos(phiY), 0, sin(phiY), 0, 1, 0, -sin(phiY), 0, cos(phiY)); matrix33 rz(cos(phiZ), -sin(phiZ), 0, sin(phiZ), cos(phiZ), 0, 0, 0, 1); int id = mesh.animation.GetBoneIndexOf(boneName); matrix33 result = rx * ry * rz; mesh.animation.bones[id].matrix.x_component() = result.x_component(); mesh.animation.bones[id].matrix.y_component() = result.y_component(); mesh.animation.bones[id].matrix.z_component() = result.z_component(); updateChilds(mesh, id + 1); } void updateChilds(Mesh& mesh, int index) { MeshAnimation::TBone b = mesh.animation.bones[index]; matrix44 m; // bind pose : default vec3f pos(b.pos[0], b.pos[1], b.pos[2]); m.set(b.rot[0], b.rot[1], b.rot[2], b.rot[3]); m.set_translation(pos); if (mesh.animation.bones[index].parent >= 0) mesh.animation.bones[index].matrix = m*mesh.animation.bones[b.parent].matrix; else mesh.animation.bones[index].matrix = m; //std::cout << b.name << ", "; loopi(0, b.childs.size()) { int childIndex = b.childs[i]; updateChilds(mesh, childIndex); } } ///////////////////////////////////////////////////////// bool direction = true; float x = -5; float y = 0; float z = 0; void AnimateArms(Mesh& mesh) { if (direction) { z += 0.0001; AnimateBone(mesh, "joint3", x, y, z); AnimateBone(mesh, "joint6", -x, y, z); if (z >= 0.6) { direction = false; } } else { z -= 0.0001; AnimateBone(mesh, "joint3", x, y, z); AnimateBone(mesh, "joint6", -x, y, z); if (z <= 0.0) { direction = true; } } } ///////////////////////////////////////////////////////// // // END // ///////////////////////////////////////////////////////// void DrawScene() { if (GetAsyncKeyState(VK_ESCAPE)) exit(0); // mouse pointer position POINT cursor; GetCursorPos(&cursor); // camera orientation float viewangle_x = float(cursor.x - 1280 / 2) / 4.0; float viewangle_y = float(cursor.y - 768 / 2) / 4.0; //time static uint t0 = timeGetTime(); double time_elapsed = double(timeGetTime() - t0) / 1000; // clear and basic glClearDepth(1); glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); // projection int vp[4]; glMatrixMode(GL_PROJECTION); glLoadIdentity(); glGetIntegerv(GL_VIEWPORT, vp); gluPerspective(90.0, float(vp[2]) / float(vp[3]), 0.01, 100); // modelview glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glRotatef(viewangle_y, 1, 0, 0); // set rotation glRotatef(viewangle_x, 0, 1, 0); // set rotation // select level of detail for rendering // (lods are generated automatically by the ogre xml converter ) int lod = 0; if (GetAsyncKeyState(VK_F1)) lod = 1; if (GetAsyncKeyState(VK_F2)) lod = 2; if (GetAsyncKeyState(VK_F3)) lod = 3; if (GetAsyncKeyState(VK_F4)) lod = 4; if (GetAsyncKeyState(VK_F5)) lod = 5; // Test 1 : Halo character (animated mesh) static Mesh halo("../data/halo/halo.material", // required material file) "../data/halo/halo.mesh.xml", // required mesh file "../data/halo/halo.skeleton.xml"); // optional skeleton file //halo.skinning = false; loopi(0, 2) { // Set the skeleton to an animation at a given time //int idle = halo.animation.GetAnimationIndexOf("idle"); // <- in case we dont know the animation id halo.animation.SetPose( i / 2, // animation id (2 animations, 0 and 1, are available) time_elapsed); // time in seconds // F6 : example to manually set the shoulder - for shooting a weapon e.g. if (GetAsyncKeyState(VK_F7)) { printBone(halo, 0, 0); } if (GetAsyncKeyState(VK_F6)) { AnimateArms(halo); } // Draw the model halo.Draw( vec3f(i * 7, -5, 7), // position vec3f(0,/*time_elapsed*0.3*/ 1.57F, 0), // rotation lod, // LOD level (i & 1) == 1); // draw skeleton ? } // Test 2 : moon (static mesh) //static Mesh moon ("../data/moon/moon.material", // required material file) // "../data/moon/moon.mesh.xml"); // required mesh file // moon.Draw( // vec3f( 1.1,-0,-1), // position // vec3f( // time_elapsed*0.2, // rotation // time_elapsed*0.1, // time_elapsed*0.4), // lod // LOD level // ); // Swap glutSwapBuffers(); } /////////////////////////////////////////// int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH); glutInitWindowSize(1280, 768); glutInitWindowPosition(0, 0); glutCreateWindow("Skeletal Animation"); glutDisplayFunc(DrawScene); glutIdleFunc(DrawScene); glewInit(); wglSwapIntervalEXT(0); glutMainLoop(); return 0; } ///////////////////////////////////////////