perdoname_
November 13th, 2008, 06:00 PM
Hello,
I'm implementing a mocap viewer but unfortunately i've got a problem showing the skeleton on the screen. it shows the texture only.
can anyone have a look at my code and tell me what's going wrong?
Thanks in advance for any help !!
#include "display.h"
SKELETON* gSkel; /* Holds skeleton data - available to any function */
MOCAP* gMo; /* Hold motion data - available to any function */
int gDelay=0; /* Holds delay information - available to any function */
//camera
static float camera_yaw = 0.0f;
static float camera_pitch = -20.0f;
static float camera_distance = 5.0f;
//mouse
static int drag_mouse_r = 0;
static int drag_mouse_l = 0;
static int drag_mouse_m = 0;
static int last_mouse_x, last_mouse_y;
static int win_width, win_height;
/* Entry point from MAIN.C */
void dorender(int argc, char** argv, SKELETON* skel, MOCAP* mo, int delay) {
/* Create GLUT window */
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize (600, 600);
glutInitWindowPosition( 0, 0 );
glutCreateWindow ("Mocap");
/* Setup GLUT callbacks */
glutReshapeFunc (reshape);
glutKeyboardFunc (keyboard);
glutDisplayFunc (display);
glutMouseFunc( mouse );
glutMotionFunc( motion );
glutIdleFunc (idle);
/* Initialise any OpenGL state */
init();
//initEnvironment();
/* Set global variables */
gSkel=skel;
gMo=mo;
gDelay=delay;
/* Kick off the GLUT main loop */
glutMainLoop();
}
void drawMessage( int line_no, const char * message )
{
int i;
if ( message == NULL )
return;
glMatrixMode( GL_PROJECTION );
glPushMatrix();
glLoadIdentity();
gluOrtho2D( 0.0, win_width, win_height, 0.0 );
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
glLoadIdentity();
glDisable( GL_DEPTH_TEST );
glDisable( GL_LIGHTING );
glColor3f( 1.0, 0.0, 0.0 );
glRasterPos2i( 8, 24 + 18 * line_no );
for ( i=0; message[i]!='\0'; i++ )
glutBitmapCharacter( GLUT_BITMAP_HELVETICA_18, message[i] );
glEnable( GL_DEPTH_TEST );
glEnable( GL_LIGHTING );
glMatrixMode( GL_PROJECTION );
glPopMatrix();
glMatrixMode( GL_MODELVIEW );
glPopMatrix();
}
void boneDraw(BONE *root)
{
int i;
glPushMatrix();
glTranslatef(root->direction.x, root->direction.y, 0.0);
//glRotatef/*(RAD2DEG*/(root->direction.z), 0.0, 0.0, 1.0/*)*/;
glBegin(GL_LINES);
glColor3f(1.0, 0.0, 0.0);
glVertex2f(0, 0);
glColor3f(0.0, 1.0, 0.0);
//glVertex2f(root->l, 0);
glEnd();
//glTranslatef(root->l, 0.0, 0.0);
for (i = 0; i < root->children_enum; i++)
boneDraw(root->children[i]);
glPopMatrix();
}
void draw_arrow(float len) {
float h = 0.15f / 0.45f * len; //head size.
float s = len - h; //shaft length
glBegin(GL_TRIANGLE_STRIP);
glVertex3f( 0.0f, 0.0f,-0.05f);
glVertex3f(-0.05f, 0.0f, 0.0f);
glVertex3f( 0.05f, 0.0f, 0.0f);
glVertex3f(-0.05f - 0.02f / 0.15f * h, 0.0f, s);
glVertex3f( 0.05f + 0.02f / 0.15f * h, 0.0f, s);
glVertex3f(-0.05f - 0.13f / 0.15f * h, 0.0f, s);
glVertex3f( 0.05f + 0.13f / 0.15f * h, 0.0f, s);
glVertex3f( 0.0f, 0.0f, s + h);
glEnd();
}
/* Keyboard callback from GLUT */
void keyboard(unsigned char key, int x, int y)
{
/* ESCAPE to exit */
switch(key) {
case 0x1b:
parser_free_skeleton(gSkel);
parser_free_mocap(gMo);
exit(0);
break;
}
}
/* Mouse callback from GLUT */
void mouse( int button, int state, int mx, int my )
{
if ( ( button == GLUT_LEFT_BUTTON ) && ( state == GLUT_DOWN ) )
drag_mouse_l = 1;
else if ( ( button == GLUT_LEFT_BUTTON ) && ( state == GLUT_UP ) )
drag_mouse_l = 0;
if ( ( button == GLUT_RIGHT_BUTTON ) && ( state == GLUT_DOWN ) )
drag_mouse_r = 1;
else if ( ( button == GLUT_RIGHT_BUTTON ) && ( state == GLUT_UP ) )
drag_mouse_r = 0;
if ( ( button == GLUT_MIDDLE_BUTTON ) && ( state == GLUT_DOWN ) )
drag_mouse_m = 1;
else if ( ( button == GLUT_MIDDLE_BUTTON ) && ( state == GLUT_UP ) )
drag_mouse_m = 0;
glutPostRedisplay();
last_mouse_x = mx;
last_mouse_y = my;
}
void motion( int mx, int my )
{
if ( drag_mouse_r )
{
camera_yaw -= ( mx - last_mouse_x ) * 1.0;
if ( camera_yaw < 0.0 )
camera_yaw += 360.0;
else if ( camera_yaw > 360.0 )
camera_yaw -= 360.0;
camera_pitch -= ( my - last_mouse_y ) * 1.0;
if ( camera_pitch < -90.0 )
camera_pitch = -90.0;
else if ( camera_pitch > 90.0 )
camera_pitch = 90.0;
}
if ( drag_mouse_l )
{
camera_distance += ( my - last_mouse_y ) * 0.2;
if ( camera_distance < 2.0 )
camera_distance = 2.0;
}
last_mouse_x = mx;
last_mouse_y = my;
glutPostRedisplay();
}
/* Called back when GLUT idling */
void idle() {
}
/* Called back by GLUT when the window is resized */
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60,(GLfloat)w/(GLfloat)h,0.01,100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
win_width = w;
win_height = h;
}
/* Called by us in dorender() to init any OpenGL state */
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
}
void initEnvironment( void )
{
float light0_position[] = { 10.0, 10.0, 10.0, 1.0 };
float light0_diffuse[] = { 0.8, 0.8, 0.8, 1.0 };
float light0_specular[] = { 1.0, 1.0, 1.0, 1.0 };
float light0_ambient[] = { 0.1, 0.1, 0.1, 1.0 };
glLightfv( GL_LIGHT0, GL_POSITION, light0_position );
glLightfv( GL_LIGHT0, GL_DIFFUSE, light0_diffuse );
glLightfv( GL_LIGHT0, GL_SPECULAR, light0_specular );
glLightfv( GL_LIGHT0, GL_AMBIENT, light0_ambient );
glEnable( GL_LIGHT0 );
glEnable( GL_LIGHTING );
glEnable( GL_COLOR_MATERIAL );
glEnable( GL_DEPTH_TEST );
glCullFace( GL_BACK );
glEnable( GL_CULL_FACE );
glClearColor( 0.5, 0.5, 0.8, 0.0 );
}
/* Called when GLUT wants to repaint the screen */
void display( void )
{
float light0_position[] = { 10.0, 10.0, 10.0, 1.0 };
float size = 1.5f;
int num_x = 10, num_z = 10;
double ox, oz;
int x,z;
double aspect;
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
glEnable(GL_DEPTH_TEST) ;
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glTranslatef( 0.0, 0.0, - camera_distance );
glRotatef( - camera_pitch, 1.0, 0.0, 0.0 );
glRotatef( - camera_yaw, 0.0, 1.0, 0.0 );
glTranslatef( 0.0, -0.5, 0.0 );
// glTranslatef(gMo->root_pos, gMo->root_orient, gMo->bones_orient);
//float light0_position[] = { 10.0, 10.0, 10.0, 1.0 };
glLightfv( GL_LIGHT0, GL_POSITION, light0_position );
glBegin( GL_QUADS );
glNormal3d( 0.0, 1.0, 0.0 );
ox = -(num_x * size) / 2;
for ( x=0; x<num_x; x++, ox+=size )
{
oz = -(num_z * size) / 2;
for ( z=0; z<num_z; z++, oz+=size )
{
if ( ((x + z) % 2) == 0 )
glColor3f( 1.0, 1.0, 1.0 );
else
glColor3f( 0.8, 0.8, 0.8 );
glVertex3d( ox, 0.0, oz );
glVertex3d( ox, 0.0, oz+size );
glVertex3d( ox+size, 0.0, oz+size );
glVertex3d( ox+size, 0.0, oz );
}
}
glEnd();
glColor3f( 1.0f, 0.0f, 0.0f );
//g<o->RenderFigure( frame_no, 0.02f );
/*
*
* char message[ 64 ];
* if ( asf )
* sprintf( message, "%.2f (%d)", animation_time, frame_no );
* else
* sprintf( message, "Press 'L' key to Load ASF/AMC file" );
* drawMessage( 0, message );
*
*****/
glutSwapBuffers();
}
static void draw_triad()
{
glBegin(GL_LINES);
/* draw x axis in red, y axis in green, z axis in blue */
glColor3f(1., .2, .2);
glVertex3f(0., 0., 0.);
glVertex3f(1., 0., 0.);
glColor3f(.2, 1., .2);
glVertex3f(0., 0., 0.);
glVertex3f(0., 1., 0.);
glColor3f(.2, .2, 1.);
glVertex3f(0., 0., 0.);
glVertex3f(0., 0., 1.);
glEnd();
}
static void draw_bone_axis()
{
glBegin(GL_LINES);
// draw x axis in red, y axis in green, z axis in blue
glColor3f(1., .2, .2);
glVertex3f(0., 0., 0.);
glVertex3f(.5, 0., 0.);
glColor3f(.2, 1., .2);
glVertex3f(0., 0., 0.);
glVertex3f(0., .5, 0.);
glColor3f(.2, .2, 1.);
glVertex3f(0., 0., 0.);
glVertex3f(0., 0., .5);
glEnd();
}
//Draws a line from point a to point b
static void draw_vector(float *a, float *b)
{
glBegin(GL_LINES);
glColor3f(.5, .5, .5);
glVertex3f(a[0], a[1], a[2]);
glVertex3f(b[0], b[1], b[2]);
glEnd();
}
void drawBone( float x0, float y0, float z0, float x1, float y1, float z1 )
{
double length;
GLdouble up_x, up_y, up_z;
GLdouble dir_x = x1 - x0;
GLdouble dir_y = y1 - y0;
GLdouble dir_z = z1 - z0;
GLdouble bone_length = sqrt( dir_x*dir_x + dir_y*dir_y + dir_z*dir_z );
GLdouble m, radius, slices, stack;
double side_x, side_y, side_z;
static GLUquadricObj * quad_obj = NULL;
if ( quad_obj == NULL )
quad_obj = gluNewQuadric();
gluQuadricDrawStyle( quad_obj, GLU_FILL );
gluQuadricNormals( quad_obj, GLU_SMOOTH );
glPushMatrix();
glTranslated( x0, y0, z0 );
length = sqrt( dir_x*dir_x + dir_y*dir_y + dir_z*dir_z );
if ( length < 0.0001 ) {
dir_x = 0.0; dir_y = 0.0; dir_z = 1.0; length = 1.0;
}
dir_x /= length; dir_y /= length; dir_z /= length;
up_x = 0.0;
up_y = 1.0;
up_z = 0.0;
side_x = up_y * dir_z - up_z * dir_y;
side_y = up_z * dir_x - up_x * dir_z;
side_z = up_x * dir_y - up_y * dir_x;
length = sqrt( side_x*side_x + side_y*side_y + side_z*side_z );
if ( length < 0.0001 ) {
side_x = 1.0; side_y = 0.0; side_z = 0.0; length = 1.0;
}
side_x /= length; side_y /= length; side_z /= length;
up_x = dir_y * side_z - dir_z * side_y;
up_y = dir_z * side_x - dir_x * side_z;
up_z = dir_x * side_y - dir_y * side_x;
/*
m[16] = { side_x, side_y, side_z, 0.0,
up_x, up_y, up_z, 0.0,
dir_x, dir_y, dir_z, 0.0,
0.0, 0.0, 0.0, 1.0 };*/
//glMultMatrixd( m );
radius= 0.01;
slices = 8.0;
stack = 3.0;
gluCylinder( quad_obj, radius, radius, bone_length, slices, stack );
glPopMatrix();
}
void CreateBoneDLists(BONE *bone)
{
if (bone->children_enum > 0)
{
// CREATE THE DISPLAY LIST FOR A BONE
glNewList(bone->id,GL_COMPILE);
glBegin(GL_LINE_STRIP);
glVertex3f( 0.0f, 0.4f, 0.0f); // 0
glVertex3f(-0.4f, 0.0f,-0.4f); // 1
glVertex3f( 0.4f, 0.0f,-0.4f); // 2
// glVertex3f( 0.0f, bone->children->direction.y, 0.0f); // Base
glVertex3f(-0.4f, 0.0f,-0.4f); // 1
glVertex3f(-0.4f, 0.0f, 0.4f); // 4
glVertex3f( 0.0f, 0.4f, 0.0f); // 0
glVertex3f( 0.4f, 0.0f,-0.4f); // 2
glVertex3f( 0.4f, 0.0f, 0.4f); // 3
glVertex3f( 0.0f, 0.4f, 0.0f); // 0
glVertex3f(-0.4f, 0.0f, 0.4f); // 4
//glVertex3f( 0.0f, bone->children->trans.y, 0.0f); // Base
glVertex3f( 0.4f, 0.0f, 0.4f); // 3
glVertex3f(-0.4f, 0.0f, 0.4f); // 4
glEnd();
glEndList();
/*
// CHECK IF THIS BONE HAS CHILDREN, IF SO RECURSIVE CALL
if (bone->childCnt > 0)
CreateBoneDLists(bone->children);
}*/
}
}
GLvoid drSkeleton(BONE *rootBone)
{
/// Local Variables ///////////////////////////////////////////////////////////
int loop;
BONE *curBone;
///////////////////////////////////////////////////////////////////////////////
curBone = rootBone->children;
for (loop = 0; loop < rootBone->children_enum; loop++)
{
glPushMatrix();
// Set base orientation and position
glTranslatef(curBone->direction.x, curBone->direction.y, curBone->direction.z);
glRotatef(curBone->direction.z, 0.0f, 0.0f, 1.0f);
glRotatef(curBone->direction.y, 0.0f, 1.0f, 0.0f);
glRotatef(curBone->direction.x, 1.0f, 0.0f, 0.0f);
// THE SCALE IS LOCAL SO I PUSH AND POP
glPushMatrix();
//glScalef(curBone->scale.x, curBone->scale.y, curBone->scale.z);
// DRAW THE AXIS OGL OBJECT
//glCallList(OGL_AXIS_DLIST);
// DRAW THE ACTUAL BONE STRUCTURE
// ONLY MAKE A BONE IF THERE IS A CHILD
if (curBone->children_enum > 0)
{
//if (curBone == m_SelectedBone)
glColor3f(1.0f, 1.0f, 0.0f); // Selected bone is bright Yellow
//else
glColor3f(0.4f, 0.4f, 0.0f); // Selected bone is dull Yellow
// DRAW THE BONE STRUCTURE
glCallList(curBone->id);
}
// GRAB THE MATRIX AT THIS POINT SO I CAN USE IT FOR THE DEFORMATION
//glGetFloatv(GL_MODELVIEW_MATRIX,curBone->bonearray_enum);
glPopMatrix(); // THIS POP IS JUST FOR THE SCALE
// CHECK IF THIS BONE HAS CHILDREN, IF SO RECURSIVE CALL
if (curBone->children_enum > 0)
drSkeleton(curBone);
glPopMatrix(); // THIS POPS THE WHOLE MATRIX
curBone++;
}
}
and thats how it parses the bones:
parser.h:
#ifndef MOCAP_PARSER_INCLUDED
#define MOCAP_PARSER_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define PI (3.141)
#ifdef WIN32
#include "windows.h"
#define strcasecmp stricmp
#endif
/* A basic type for representing 3D quantities */
typedef struct _3dcoord {
float x;
float y;
float z;
} POINT3D;
/* Type for representing bones */
typedef struct _bone {
int id;
char* name;
POINT3D direction;
float length;
POINT3D axis;
int xyzflags;
int children_enum;
struct _bone** children;
struct _bone* parent;
} BONE;
/* Type for representing the skeleton (collection of bones) */
typedef struct _skeleton {
POINT3D init_position; /* Initial translation of the root (world) reference frame */
POINT3D init_orientation; /* Initial orientation of the root (world) reference frame */
int children_enum; /* How many children bones off the root ? */
struct _bone** children; /* Array of pointers to children bones e.g. children[0 to children_enum] */
int bonearray_enum; /* Number of bones in bonearray */
struct _bone* bonearray;
} SKELETON;
/* Type for representing a motion capture set (how the skeleton moves) */
typedef struct _mocap {
int frames_enum; /* Number of frames of animation */
POINT3D* root_pos; /* Translation of root (world) reference frame - root_pos[0] to root_pos[frames_enum-1] */
POINT3D* root_orient; /* Orientation of root (world) reference frame - root_orient[0] to root_orient[frames_enum-1] */
POINT3D** bones_orient; /* Orientation of bones - bones_orient[framenumber][bonenumber] */
} MOCAP;
SKELETON* parser_loadSkeleton(char* argFilename);
MOCAP* parser_loadMocap(char* argFilename, SKELETON* skel);
void parser_debugskeletonTree(SKELETON* skel);
void parser_free_skeleton(SKELETON* skel);
void parser_free_mocap(MOCAP* mocap);
void RotateBoneDirToLocalCoordSystem(SKELETON* skel);
void vector_rotationXYZ(POINT3D* v, float a, float b, float c);
void matrix_transform_affine(double m[4][4], double x, double y, double z, POINT3D* v);
void rotationX(double r[][4], float a);
void rotationY(double r[][4], float a);
void rotationZ(double r[][4], float a);
#endif
I'm implementing a mocap viewer but unfortunately i've got a problem showing the skeleton on the screen. it shows the texture only.
can anyone have a look at my code and tell me what's going wrong?
Thanks in advance for any help !!
#include "display.h"
SKELETON* gSkel; /* Holds skeleton data - available to any function */
MOCAP* gMo; /* Hold motion data - available to any function */
int gDelay=0; /* Holds delay information - available to any function */
//camera
static float camera_yaw = 0.0f;
static float camera_pitch = -20.0f;
static float camera_distance = 5.0f;
//mouse
static int drag_mouse_r = 0;
static int drag_mouse_l = 0;
static int drag_mouse_m = 0;
static int last_mouse_x, last_mouse_y;
static int win_width, win_height;
/* Entry point from MAIN.C */
void dorender(int argc, char** argv, SKELETON* skel, MOCAP* mo, int delay) {
/* Create GLUT window */
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize (600, 600);
glutInitWindowPosition( 0, 0 );
glutCreateWindow ("Mocap");
/* Setup GLUT callbacks */
glutReshapeFunc (reshape);
glutKeyboardFunc (keyboard);
glutDisplayFunc (display);
glutMouseFunc( mouse );
glutMotionFunc( motion );
glutIdleFunc (idle);
/* Initialise any OpenGL state */
init();
//initEnvironment();
/* Set global variables */
gSkel=skel;
gMo=mo;
gDelay=delay;
/* Kick off the GLUT main loop */
glutMainLoop();
}
void drawMessage( int line_no, const char * message )
{
int i;
if ( message == NULL )
return;
glMatrixMode( GL_PROJECTION );
glPushMatrix();
glLoadIdentity();
gluOrtho2D( 0.0, win_width, win_height, 0.0 );
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
glLoadIdentity();
glDisable( GL_DEPTH_TEST );
glDisable( GL_LIGHTING );
glColor3f( 1.0, 0.0, 0.0 );
glRasterPos2i( 8, 24 + 18 * line_no );
for ( i=0; message[i]!='\0'; i++ )
glutBitmapCharacter( GLUT_BITMAP_HELVETICA_18, message[i] );
glEnable( GL_DEPTH_TEST );
glEnable( GL_LIGHTING );
glMatrixMode( GL_PROJECTION );
glPopMatrix();
glMatrixMode( GL_MODELVIEW );
glPopMatrix();
}
void boneDraw(BONE *root)
{
int i;
glPushMatrix();
glTranslatef(root->direction.x, root->direction.y, 0.0);
//glRotatef/*(RAD2DEG*/(root->direction.z), 0.0, 0.0, 1.0/*)*/;
glBegin(GL_LINES);
glColor3f(1.0, 0.0, 0.0);
glVertex2f(0, 0);
glColor3f(0.0, 1.0, 0.0);
//glVertex2f(root->l, 0);
glEnd();
//glTranslatef(root->l, 0.0, 0.0);
for (i = 0; i < root->children_enum; i++)
boneDraw(root->children[i]);
glPopMatrix();
}
void draw_arrow(float len) {
float h = 0.15f / 0.45f * len; //head size.
float s = len - h; //shaft length
glBegin(GL_TRIANGLE_STRIP);
glVertex3f( 0.0f, 0.0f,-0.05f);
glVertex3f(-0.05f, 0.0f, 0.0f);
glVertex3f( 0.05f, 0.0f, 0.0f);
glVertex3f(-0.05f - 0.02f / 0.15f * h, 0.0f, s);
glVertex3f( 0.05f + 0.02f / 0.15f * h, 0.0f, s);
glVertex3f(-0.05f - 0.13f / 0.15f * h, 0.0f, s);
glVertex3f( 0.05f + 0.13f / 0.15f * h, 0.0f, s);
glVertex3f( 0.0f, 0.0f, s + h);
glEnd();
}
/* Keyboard callback from GLUT */
void keyboard(unsigned char key, int x, int y)
{
/* ESCAPE to exit */
switch(key) {
case 0x1b:
parser_free_skeleton(gSkel);
parser_free_mocap(gMo);
exit(0);
break;
}
}
/* Mouse callback from GLUT */
void mouse( int button, int state, int mx, int my )
{
if ( ( button == GLUT_LEFT_BUTTON ) && ( state == GLUT_DOWN ) )
drag_mouse_l = 1;
else if ( ( button == GLUT_LEFT_BUTTON ) && ( state == GLUT_UP ) )
drag_mouse_l = 0;
if ( ( button == GLUT_RIGHT_BUTTON ) && ( state == GLUT_DOWN ) )
drag_mouse_r = 1;
else if ( ( button == GLUT_RIGHT_BUTTON ) && ( state == GLUT_UP ) )
drag_mouse_r = 0;
if ( ( button == GLUT_MIDDLE_BUTTON ) && ( state == GLUT_DOWN ) )
drag_mouse_m = 1;
else if ( ( button == GLUT_MIDDLE_BUTTON ) && ( state == GLUT_UP ) )
drag_mouse_m = 0;
glutPostRedisplay();
last_mouse_x = mx;
last_mouse_y = my;
}
void motion( int mx, int my )
{
if ( drag_mouse_r )
{
camera_yaw -= ( mx - last_mouse_x ) * 1.0;
if ( camera_yaw < 0.0 )
camera_yaw += 360.0;
else if ( camera_yaw > 360.0 )
camera_yaw -= 360.0;
camera_pitch -= ( my - last_mouse_y ) * 1.0;
if ( camera_pitch < -90.0 )
camera_pitch = -90.0;
else if ( camera_pitch > 90.0 )
camera_pitch = 90.0;
}
if ( drag_mouse_l )
{
camera_distance += ( my - last_mouse_y ) * 0.2;
if ( camera_distance < 2.0 )
camera_distance = 2.0;
}
last_mouse_x = mx;
last_mouse_y = my;
glutPostRedisplay();
}
/* Called back when GLUT idling */
void idle() {
}
/* Called back by GLUT when the window is resized */
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60,(GLfloat)w/(GLfloat)h,0.01,100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
win_width = w;
win_height = h;
}
/* Called by us in dorender() to init any OpenGL state */
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
}
void initEnvironment( void )
{
float light0_position[] = { 10.0, 10.0, 10.0, 1.0 };
float light0_diffuse[] = { 0.8, 0.8, 0.8, 1.0 };
float light0_specular[] = { 1.0, 1.0, 1.0, 1.0 };
float light0_ambient[] = { 0.1, 0.1, 0.1, 1.0 };
glLightfv( GL_LIGHT0, GL_POSITION, light0_position );
glLightfv( GL_LIGHT0, GL_DIFFUSE, light0_diffuse );
glLightfv( GL_LIGHT0, GL_SPECULAR, light0_specular );
glLightfv( GL_LIGHT0, GL_AMBIENT, light0_ambient );
glEnable( GL_LIGHT0 );
glEnable( GL_LIGHTING );
glEnable( GL_COLOR_MATERIAL );
glEnable( GL_DEPTH_TEST );
glCullFace( GL_BACK );
glEnable( GL_CULL_FACE );
glClearColor( 0.5, 0.5, 0.8, 0.0 );
}
/* Called when GLUT wants to repaint the screen */
void display( void )
{
float light0_position[] = { 10.0, 10.0, 10.0, 1.0 };
float size = 1.5f;
int num_x = 10, num_z = 10;
double ox, oz;
int x,z;
double aspect;
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
glEnable(GL_DEPTH_TEST) ;
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glTranslatef( 0.0, 0.0, - camera_distance );
glRotatef( - camera_pitch, 1.0, 0.0, 0.0 );
glRotatef( - camera_yaw, 0.0, 1.0, 0.0 );
glTranslatef( 0.0, -0.5, 0.0 );
// glTranslatef(gMo->root_pos, gMo->root_orient, gMo->bones_orient);
//float light0_position[] = { 10.0, 10.0, 10.0, 1.0 };
glLightfv( GL_LIGHT0, GL_POSITION, light0_position );
glBegin( GL_QUADS );
glNormal3d( 0.0, 1.0, 0.0 );
ox = -(num_x * size) / 2;
for ( x=0; x<num_x; x++, ox+=size )
{
oz = -(num_z * size) / 2;
for ( z=0; z<num_z; z++, oz+=size )
{
if ( ((x + z) % 2) == 0 )
glColor3f( 1.0, 1.0, 1.0 );
else
glColor3f( 0.8, 0.8, 0.8 );
glVertex3d( ox, 0.0, oz );
glVertex3d( ox, 0.0, oz+size );
glVertex3d( ox+size, 0.0, oz+size );
glVertex3d( ox+size, 0.0, oz );
}
}
glEnd();
glColor3f( 1.0f, 0.0f, 0.0f );
//g<o->RenderFigure( frame_no, 0.02f );
/*
*
* char message[ 64 ];
* if ( asf )
* sprintf( message, "%.2f (%d)", animation_time, frame_no );
* else
* sprintf( message, "Press 'L' key to Load ASF/AMC file" );
* drawMessage( 0, message );
*
*****/
glutSwapBuffers();
}
static void draw_triad()
{
glBegin(GL_LINES);
/* draw x axis in red, y axis in green, z axis in blue */
glColor3f(1., .2, .2);
glVertex3f(0., 0., 0.);
glVertex3f(1., 0., 0.);
glColor3f(.2, 1., .2);
glVertex3f(0., 0., 0.);
glVertex3f(0., 1., 0.);
glColor3f(.2, .2, 1.);
glVertex3f(0., 0., 0.);
glVertex3f(0., 0., 1.);
glEnd();
}
static void draw_bone_axis()
{
glBegin(GL_LINES);
// draw x axis in red, y axis in green, z axis in blue
glColor3f(1., .2, .2);
glVertex3f(0., 0., 0.);
glVertex3f(.5, 0., 0.);
glColor3f(.2, 1., .2);
glVertex3f(0., 0., 0.);
glVertex3f(0., .5, 0.);
glColor3f(.2, .2, 1.);
glVertex3f(0., 0., 0.);
glVertex3f(0., 0., .5);
glEnd();
}
//Draws a line from point a to point b
static void draw_vector(float *a, float *b)
{
glBegin(GL_LINES);
glColor3f(.5, .5, .5);
glVertex3f(a[0], a[1], a[2]);
glVertex3f(b[0], b[1], b[2]);
glEnd();
}
void drawBone( float x0, float y0, float z0, float x1, float y1, float z1 )
{
double length;
GLdouble up_x, up_y, up_z;
GLdouble dir_x = x1 - x0;
GLdouble dir_y = y1 - y0;
GLdouble dir_z = z1 - z0;
GLdouble bone_length = sqrt( dir_x*dir_x + dir_y*dir_y + dir_z*dir_z );
GLdouble m, radius, slices, stack;
double side_x, side_y, side_z;
static GLUquadricObj * quad_obj = NULL;
if ( quad_obj == NULL )
quad_obj = gluNewQuadric();
gluQuadricDrawStyle( quad_obj, GLU_FILL );
gluQuadricNormals( quad_obj, GLU_SMOOTH );
glPushMatrix();
glTranslated( x0, y0, z0 );
length = sqrt( dir_x*dir_x + dir_y*dir_y + dir_z*dir_z );
if ( length < 0.0001 ) {
dir_x = 0.0; dir_y = 0.0; dir_z = 1.0; length = 1.0;
}
dir_x /= length; dir_y /= length; dir_z /= length;
up_x = 0.0;
up_y = 1.0;
up_z = 0.0;
side_x = up_y * dir_z - up_z * dir_y;
side_y = up_z * dir_x - up_x * dir_z;
side_z = up_x * dir_y - up_y * dir_x;
length = sqrt( side_x*side_x + side_y*side_y + side_z*side_z );
if ( length < 0.0001 ) {
side_x = 1.0; side_y = 0.0; side_z = 0.0; length = 1.0;
}
side_x /= length; side_y /= length; side_z /= length;
up_x = dir_y * side_z - dir_z * side_y;
up_y = dir_z * side_x - dir_x * side_z;
up_z = dir_x * side_y - dir_y * side_x;
/*
m[16] = { side_x, side_y, side_z, 0.0,
up_x, up_y, up_z, 0.0,
dir_x, dir_y, dir_z, 0.0,
0.0, 0.0, 0.0, 1.0 };*/
//glMultMatrixd( m );
radius= 0.01;
slices = 8.0;
stack = 3.0;
gluCylinder( quad_obj, radius, radius, bone_length, slices, stack );
glPopMatrix();
}
void CreateBoneDLists(BONE *bone)
{
if (bone->children_enum > 0)
{
// CREATE THE DISPLAY LIST FOR A BONE
glNewList(bone->id,GL_COMPILE);
glBegin(GL_LINE_STRIP);
glVertex3f( 0.0f, 0.4f, 0.0f); // 0
glVertex3f(-0.4f, 0.0f,-0.4f); // 1
glVertex3f( 0.4f, 0.0f,-0.4f); // 2
// glVertex3f( 0.0f, bone->children->direction.y, 0.0f); // Base
glVertex3f(-0.4f, 0.0f,-0.4f); // 1
glVertex3f(-0.4f, 0.0f, 0.4f); // 4
glVertex3f( 0.0f, 0.4f, 0.0f); // 0
glVertex3f( 0.4f, 0.0f,-0.4f); // 2
glVertex3f( 0.4f, 0.0f, 0.4f); // 3
glVertex3f( 0.0f, 0.4f, 0.0f); // 0
glVertex3f(-0.4f, 0.0f, 0.4f); // 4
//glVertex3f( 0.0f, bone->children->trans.y, 0.0f); // Base
glVertex3f( 0.4f, 0.0f, 0.4f); // 3
glVertex3f(-0.4f, 0.0f, 0.4f); // 4
glEnd();
glEndList();
/*
// CHECK IF THIS BONE HAS CHILDREN, IF SO RECURSIVE CALL
if (bone->childCnt > 0)
CreateBoneDLists(bone->children);
}*/
}
}
GLvoid drSkeleton(BONE *rootBone)
{
/// Local Variables ///////////////////////////////////////////////////////////
int loop;
BONE *curBone;
///////////////////////////////////////////////////////////////////////////////
curBone = rootBone->children;
for (loop = 0; loop < rootBone->children_enum; loop++)
{
glPushMatrix();
// Set base orientation and position
glTranslatef(curBone->direction.x, curBone->direction.y, curBone->direction.z);
glRotatef(curBone->direction.z, 0.0f, 0.0f, 1.0f);
glRotatef(curBone->direction.y, 0.0f, 1.0f, 0.0f);
glRotatef(curBone->direction.x, 1.0f, 0.0f, 0.0f);
// THE SCALE IS LOCAL SO I PUSH AND POP
glPushMatrix();
//glScalef(curBone->scale.x, curBone->scale.y, curBone->scale.z);
// DRAW THE AXIS OGL OBJECT
//glCallList(OGL_AXIS_DLIST);
// DRAW THE ACTUAL BONE STRUCTURE
// ONLY MAKE A BONE IF THERE IS A CHILD
if (curBone->children_enum > 0)
{
//if (curBone == m_SelectedBone)
glColor3f(1.0f, 1.0f, 0.0f); // Selected bone is bright Yellow
//else
glColor3f(0.4f, 0.4f, 0.0f); // Selected bone is dull Yellow
// DRAW THE BONE STRUCTURE
glCallList(curBone->id);
}
// GRAB THE MATRIX AT THIS POINT SO I CAN USE IT FOR THE DEFORMATION
//glGetFloatv(GL_MODELVIEW_MATRIX,curBone->bonearray_enum);
glPopMatrix(); // THIS POP IS JUST FOR THE SCALE
// CHECK IF THIS BONE HAS CHILDREN, IF SO RECURSIVE CALL
if (curBone->children_enum > 0)
drSkeleton(curBone);
glPopMatrix(); // THIS POPS THE WHOLE MATRIX
curBone++;
}
}
and thats how it parses the bones:
parser.h:
#ifndef MOCAP_PARSER_INCLUDED
#define MOCAP_PARSER_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define PI (3.141)
#ifdef WIN32
#include "windows.h"
#define strcasecmp stricmp
#endif
/* A basic type for representing 3D quantities */
typedef struct _3dcoord {
float x;
float y;
float z;
} POINT3D;
/* Type for representing bones */
typedef struct _bone {
int id;
char* name;
POINT3D direction;
float length;
POINT3D axis;
int xyzflags;
int children_enum;
struct _bone** children;
struct _bone* parent;
} BONE;
/* Type for representing the skeleton (collection of bones) */
typedef struct _skeleton {
POINT3D init_position; /* Initial translation of the root (world) reference frame */
POINT3D init_orientation; /* Initial orientation of the root (world) reference frame */
int children_enum; /* How many children bones off the root ? */
struct _bone** children; /* Array of pointers to children bones e.g. children[0 to children_enum] */
int bonearray_enum; /* Number of bones in bonearray */
struct _bone* bonearray;
} SKELETON;
/* Type for representing a motion capture set (how the skeleton moves) */
typedef struct _mocap {
int frames_enum; /* Number of frames of animation */
POINT3D* root_pos; /* Translation of root (world) reference frame - root_pos[0] to root_pos[frames_enum-1] */
POINT3D* root_orient; /* Orientation of root (world) reference frame - root_orient[0] to root_orient[frames_enum-1] */
POINT3D** bones_orient; /* Orientation of bones - bones_orient[framenumber][bonenumber] */
} MOCAP;
SKELETON* parser_loadSkeleton(char* argFilename);
MOCAP* parser_loadMocap(char* argFilename, SKELETON* skel);
void parser_debugskeletonTree(SKELETON* skel);
void parser_free_skeleton(SKELETON* skel);
void parser_free_mocap(MOCAP* mocap);
void RotateBoneDirToLocalCoordSystem(SKELETON* skel);
void vector_rotationXYZ(POINT3D* v, float a, float b, float c);
void matrix_transform_affine(double m[4][4], double x, double y, double z, POINT3D* v);
void rotationX(double r[][4], float a);
void rotationY(double r[][4], float a);
void rotationZ(double r[][4], float a);
#endif