/* Copyright (C) 1999-2006 Id Software, Inc. and contributors. For a list of contributors, see the accompanying CONTRIBUTORS file. This file is part of GtkRadiant. GtkRadiant is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. GtkRadiant is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GtkRadiant; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "token.h" #include "joints.h" #include "angles.h" #include "inout.h" char *SKEL_ROOT_NAMES[] = { "RAVEN_SPINE" }; char *SKEL_NAMES[] = { "RAVEN_WAIST1", "RAVEN_WAIST2", "RAVEN_NECK" }; int NAME_OFFSETS[] = { 0 }; int numJointsForSkeleton[] = { NUM_JOINTS_RAVEN, NUM_JOINTS_BOX }; float g_scaling[3]; float g_rotation[3]; float g_translation[3]; //========================================================================== // // LoadHRCClustered // //========================================================================== static void LoadHRCClustered( char *fileName, int **clusterList, int *num_verts, int skelType ){ int i, j; TK_OpenSource( fileName ); TK_FetchRequire( TK_HRCH ); TK_FetchRequire( TK_COLON ); TK_FetchRequire( TK_SOFTIMAGE ); TK_Beyond( TK_CLUSTERS ); while ( TK_Search( TK_CLUSTER_NAME ) != TK_EOF ) { TK_Require( TK_STRING ); for ( i = 0; i < numJointsForSkeleton[skelType]; ++i ) { if ( stricmp( tk_String, SKEL_NAMES[NAME_OFFSETS[skelType] + i] ) == 0 ) { i = -i + numJointsForSkeleton[skelType] - 1; TK_BeyondRequire( TK_NUM_CLUSTER_VERTICES, TK_INTNUMBER ); num_verts[i + 1] = tk_IntNumber; clusterList[i] = (int *) SafeMalloc( num_verts[i + 1] * sizeof( int ), "LoadHRCClustered" ); assert( clusterList[i] ); // currently this function is only called by LoadTriangleListClustered, which in turn is only // called by Cmd_Base in qdata. This is where the only call to free for this memory is being made. TK_Beyond( TK_LBRACE ); for ( j = 0; j < num_verts[i + 1]; ++j ) { TK_Require( TK_INTNUMBER ); clusterList[i][j] = tk_IntNumber; TK_Fetch(); } break; } } } num_verts[0] = numJointsForSkeleton[skelType]; } static void LoadHRCGlobals( char *fileName ){ int i; TK_OpenSource( fileName ); TK_FetchRequire( TK_HRCH ); TK_FetchRequire( TK_COLON ); TK_FetchRequire( TK_SOFTIMAGE ); TK_Beyond( TK_MODEL ); TK_Beyond( TK_SCALING ); for ( i = 0; i < 3; i++ ) { TK_Require( TK_FLOATNUMBER ); g_scaling[i] = tk_FloatNumber; TK_Fetch(); } TK_Beyond( TK_ROTATION ); for ( i = 0; i < 3; i++ ) { TK_Require( TK_FLOATNUMBER ); g_rotation[i] = tk_FloatNumber; TK_Fetch(); } TK_Beyond( TK_TRANSLATION ); for ( i = 0; i < 3; i++ ) { TK_Require( TK_FLOATNUMBER ); g_translation[i] = tk_FloatNumber; TK_Fetch(); } } static void ParseVec3( vec3_t in ){ TK_Require( TK_FLOATNUMBER ); in[1] = tk_FloatNumber; TK_FetchRequire( TK_FLOATNUMBER ); in[2] = tk_FloatNumber; TK_FetchRequire( TK_FLOATNUMBER ); in[0] = tk_FloatNumber; } static void ParseRotation3( vec3_t in ){ TK_Require( TK_FLOATNUMBER ); in[1] = -tk_FloatNumber; TK_FetchRequire( TK_FLOATNUMBER ); in[2] = tk_FloatNumber; TK_FetchRequire( TK_FLOATNUMBER ); in[0] = tk_FloatNumber; } static void ParseTranslation3( vec3_t in ){ TK_Require( TK_FLOATNUMBER ); in[1] = tk_FloatNumber; TK_FetchRequire( TK_FLOATNUMBER ); in[2] = tk_FloatNumber; TK_FetchRequire( TK_FLOATNUMBER ); in[0] = tk_FloatNumber; } static void LoadHRCJointList( char *fileName, QDataJoint_t *jointList, int skelType ){ #define MAX_STACK 64 int i, j; vec3_t curTranslation[MAX_STACK], curRotation[MAX_STACK], curScale[MAX_STACK]; int curCorrespondingJoint[MAX_STACK]; int currentStack = 0, stackSize; int baseJoint; float cx, sx, cy, sy, cz, sz; float rx, ry, rz; float x2, y2, z2; TK_OpenSource( fileName ); TK_FetchRequire( TK_HRCH ); TK_FetchRequire( TK_COLON ); TK_FetchRequire( TK_SOFTIMAGE ); TK_Beyond( TK_MODEL ); TK_Beyond( TK_MODEL ); /* while(1) { TK_Beyond(TK_MODEL); TK_BeyondRequire(TK_NAME, TK_STRING); if(_stricmp(tk_String, SKEL_ROOT_NAMES[skelType]) == 0) break; }*/ TK_Beyond( TK_SCALING ); ParseVec3( curScale[currentStack] ); TK_Beyond( TK_ROTATION ); ParseRotation3( curRotation[currentStack] ); TK_Beyond( TK_TRANSLATION ); ParseVec3( curTranslation[currentStack] ); // account for global model translation curTranslation[currentStack][1] += g_translation[0]; curTranslation[currentStack][2] += g_translation[1]; curTranslation[currentStack][0] += g_translation[2]; ++currentStack; for ( i = 0; i < NUM_JOINTS_RAVEN; ++i ) { while ( 1 ) { TK_Beyond( TK_MODEL ); // TK_BeyondRequire(TK_NAME, TK_STRING); // if(_stricmp(tk_String, SKEL_NAMES[NAME_OFFSETS[skelType]+i]) == 0) break; TK_Beyond( TK_SCALING ); ParseVec3( curScale[currentStack] ); TK_Beyond( TK_ROTATION ); ParseRotation3( curRotation[currentStack] ); TK_Beyond( TK_TRANSLATION ); ParseVec3( curTranslation[currentStack] ); curCorrespondingJoint[currentStack] = -1; ++currentStack; } TK_Beyond( TK_SCALING ); ParseVec3( curScale[currentStack] ); TK_Beyond( TK_ROTATION ); ParseRotation3( curRotation[currentStack] ); jointList[i].rotation[1] = curRotation[currentStack][1]; jointList[i].rotation[2] = curRotation[currentStack][2]; jointList[i].rotation[0] = curRotation[currentStack][0]; TK_Beyond( TK_TRANSLATION ); ParseVec3( curTranslation[currentStack] ); jointList[i].placement.origin[1] = curTranslation[currentStack][1]; jointList[i].placement.origin[2] = curTranslation[currentStack][2]; jointList[i].placement.origin[0] = curTranslation[currentStack][0]; jointList[i].placement.direction[1] = 7.5; jointList[i].placement.direction[2] = 0.0; jointList[i].placement.direction[0] = 0.0; jointList[i].placement.up[1] = 0.0; jointList[i].placement.up[2] = 7.5; jointList[i].placement.up[0] = 0.0; curCorrespondingJoint[currentStack] = i; ++currentStack; } stackSize = currentStack; for ( i = 0; i < NUM_JOINTS_RAVEN; ++i ) { rx = jointList[i].rotation[0] * ANGLE_TO_RAD; ry = jointList[i].rotation[1] * ANGLE_TO_RAD; rz = jointList[i].rotation[2] * ANGLE_TO_RAD; cx = cos( rx ); sx = sin( rx ); cy = cos( ry ); sy = sin( ry ); cz = cos( rz ); sz = sin( rz ); // y-axis rotation for direction x2 = jointList[i].placement.direction[0] * cy + jointList[i].placement.direction[2] * sy; z2 = -jointList[i].placement.direction[0] * sy + jointList[i].placement.direction[2] * cy; jointList[i].placement.direction[0] = x2; jointList[i].placement.direction[2] = z2; // y-axis rotation for up x2 = jointList[i].placement.up[0] * cy + jointList[i].placement.up[2] * sy; z2 = -jointList[i].placement.up[0] * sy + jointList[i].placement.up[2] * cy; jointList[i].placement.up[0] = x2; jointList[i].placement.up[2] = z2; // z-axis rotation for direction x2 = jointList[i].placement.direction[0] * cz - jointList[i].placement.direction[1] * sz; y2 = jointList[i].placement.direction[0] * sz + jointList[i].placement.direction[1] * cz; jointList[i].placement.direction[0] = x2; jointList[i].placement.direction[1] = y2; // z-axis rotation for up x2 = jointList[i].placement.up[0] * cz - jointList[i].placement.up[1] * sz; y2 = jointList[i].placement.up[0] * sz + jointList[i].placement.up[1] * cz; jointList[i].placement.up[0] = x2; jointList[i].placement.up[1] = y2; // x-axis rotation for direction vector y2 = jointList[i].placement.direction[1] * cx - jointList[i].placement.direction[2] * sx; z2 = jointList[i].placement.direction[1] * sx + jointList[i].placement.direction[2] * cx; jointList[i].placement.direction[1] = y2; jointList[i].placement.direction[2] = z2; // x-axis rotation for up vector y2 = jointList[i].placement.up[1] * cx - jointList[i].placement.up[2] * sx; z2 = jointList[i].placement.up[1] * sx + jointList[i].placement.up[2] * cx; jointList[i].placement.up[1] = y2; jointList[i].placement.up[2] = z2; // translate to position in model jointList[i].placement.direction[0] += jointList[i].placement.origin[0]; jointList[i].placement.direction[1] += jointList[i].placement.origin[1]; jointList[i].placement.direction[2] += jointList[i].placement.origin[2]; // translate to position in model jointList[i].placement.up[0] += jointList[i].placement.origin[0]; jointList[i].placement.up[1] += jointList[i].placement.origin[1]; jointList[i].placement.up[2] += jointList[i].placement.origin[2]; } baseJoint = NUM_JOINTS_RAVEN; for ( i = stackSize /*NUM_JOINTS_RAVEN*/ - 1; i > 0; --i ) { rx = curRotation[i - 1][0] * ANGLE_TO_RAD; ry = curRotation[i - 1][1] * ANGLE_TO_RAD; rz = curRotation[i - 1][2] * ANGLE_TO_RAD; cx = cos( rx ); sx = sin( rx ); cy = cos( ry ); sy = sin( ry ); cz = cos( rz ); sz = sin( rz ); for ( j = i - 1; j < stackSize - 1; ++j ) { // y-axis rotation for origin x2 = jointList[j].placement.origin[0] * cy + jointList[j].placement.origin[2] * sy; z2 = -jointList[j].placement.origin[0] * sy + jointList[j].placement.origin[2] * cy; jointList[j].placement.origin[0] = x2; jointList[j].placement.origin[2] = z2; // y-axis rotation for direction x2 = jointList[j].placement.direction[0] * cy + jointList[j].placement.direction[2] * sy; z2 = -jointList[j].placement.direction[0] * sy + jointList[j].placement.direction[2] * cy; jointList[j].placement.direction[0] = x2; jointList[j].placement.direction[2] = z2; // y-axis rotation for up x2 = jointList[j].placement.up[0] * cy + jointList[j].placement.up[2] * sy; z2 = -jointList[j].placement.up[0] * sy + jointList[j].placement.up[2] * cy; jointList[j].placement.up[0] = x2; jointList[j].placement.up[2] = z2; // z-axis rotation for origin x2 = jointList[j].placement.origin[0] * cz - jointList[j].placement.origin[1] * sz; y2 = jointList[j].placement.origin[0] * sz + jointList[j].placement.origin[1] * cz; jointList[j].placement.origin[0] = x2; jointList[j].placement.origin[1] = y2; // z-axis rotation for direction x2 = jointList[j].placement.direction[0] * cz - jointList[j].placement.direction[1] * sz; y2 = jointList[j].placement.direction[0] * sz + jointList[j].placement.direction[1] * cz; jointList[j].placement.direction[0] = x2; jointList[j].placement.direction[1] = y2; // z-axis rotation for up x2 = jointList[j].placement.up[0] * cz - jointList[j].placement.up[1] * sz; y2 = jointList[j].placement.up[0] * sz + jointList[j].placement.up[1] * cz; jointList[j].placement.up[0] = x2; jointList[j].placement.up[1] = y2; // x-axis rotation for origin y2 = jointList[j].placement.origin[1] * cx - jointList[j].placement.origin[2] * sx; z2 = jointList[j].placement.origin[1] * sx + jointList[j].placement.origin[2] * cx; jointList[j].placement.origin[1] = y2; jointList[j].placement.origin[2] = z2; // x-axis rotation for direction vector y2 = jointList[j].placement.direction[1] * cx - jointList[j].placement.direction[2] * sx; z2 = jointList[j].placement.direction[1] * sx + jointList[j].placement.direction[2] * cx; jointList[j].placement.direction[1] = y2; jointList[j].placement.direction[2] = z2; // x-axis rotation for up vector y2 = jointList[j].placement.up[1] * cx - jointList[j].placement.up[2] * sx; z2 = jointList[j].placement.up[1] * sx + jointList[j].placement.up[2] * cx; jointList[j].placement.up[1] = y2; jointList[j].placement.up[2] = z2; if ( curCorrespondingJoint[j + 1] != -1 ) { // translate origin jointList[j].placement.origin[0] += curTranslation[i - 1][0]; jointList[j].placement.origin[1] += curTranslation[i - 1][1]; jointList[j].placement.origin[2] += curTranslation[i - 1][2]; // translate back to local coord jointList[j].placement.direction[0] += curTranslation[i - 1][0]; jointList[j].placement.direction[1] += curTranslation[i - 1][1]; jointList[j].placement.direction[2] += curTranslation[i - 1][2]; // translate back to local coord jointList[j].placement.up[0] += curTranslation[i - 1][0]; jointList[j].placement.up[1] += curTranslation[i - 1][1]; jointList[j].placement.up[2] += curTranslation[i - 1][2]; } } } } void LoadGlobals( char *fileName ){ FILE *file1; int dot = '.'; char *dotstart; char InputFileName[256]; dotstart = strrchr( fileName,dot ); // Does it already have an extension on the file name? if ( !dotstart ) { strcpy( InputFileName, fileName ); strcat( InputFileName, ".hrc" ); if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) { fclose( file1 ); LoadHRCGlobals( InputFileName ); printf( " - assuming .HRC\n" ); return; } Error( "\n Could not open file '%s':\n" "No HRC match.\n", fileName ); } else { if ( ( file1 = fopen( fileName, "rb" ) ) != NULL ) { printf( "\n" ); fclose( file1 ); if ( strcmp( dotstart,".hrc" ) == 0 || strcmp( dotstart,".HRC" ) == 0 ) { LoadHRCGlobals( fileName ); return; } } Error( "Could not open file '%s':\n",fileName ); } } void LoadClusters( char *fileName, int **clusterList, int *num_verts, int skelType ){ FILE *file1; int dot = '.'; char *dotstart; char InputFileName[256]; dotstart = strrchr( fileName,dot ); // Does it already have an extension on the file name? if ( !dotstart ) { strcpy( InputFileName, fileName ); strcat( InputFileName, ".hrc" ); if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) { fclose( file1 ); LoadHRCClustered( InputFileName, clusterList, num_verts, skelType ); printf( " - assuming .HRC\n" ); return; } Error( "\n Could not open file '%s':\n" "No HRC match.\n", fileName ); } else { if ( ( file1 = fopen( fileName, "rb" ) ) != NULL ) { printf( "\n" ); fclose( file1 ); if ( strcmp( dotstart,".hrc" ) == 0 || strcmp( dotstart,".HRC" ) == 0 ) { LoadHRCClustered( fileName, clusterList, num_verts, skelType ); return; } } Error( "Could not open file '%s':\n",fileName ); } } void LoadJointList( char *fileName, QDataJoint_t *jointList, int skelType ){ FILE *file1; int dot = '.'; char *dotstart; char InputFileName[256]; dotstart = strrchr( fileName,dot ); // Does it already have an extension on the file name? if ( !dotstart ) { strcpy( InputFileName, fileName ); strcat( InputFileName, ".hrc" ); if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) { fclose( file1 ); LoadHRCJointList( InputFileName, jointList, skelType ); printf( " - assuming .HRC\n" ); return; } Error( "\n Could not open file '%s':\n" "No HRC.\n", fileName ); } else { if ( ( file1 = fopen( fileName, "rb" ) ) != NULL ) { printf( "\n" ); fclose( file1 ); if ( strcmp( dotstart,".hrc" ) == 0 || strcmp( dotstart,".HRC" ) == 0 ) { LoadHRCJointList( fileName, jointList, skelType ); return; } } Error( "Could not open file '%s':\n",fileName ); } }