- /////////////////////////////////////////////
- //
- // Skeletal Animation
- // Sylwester Feduk
- /////////////////////////////////////////////
- #include <iostream>
- #include <vector>
- #include <string>
- #include <stdio.h>
- #include <glew.h>
- #include <wglew.h>
- #include <windows.h>
- #include <mmsystem.h>
- #include <GL/glut.h>
- 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;
- }
- ///////////////////////////////////////////