2 Copyright (C) 1999-2007 id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
5 This file is part of GtkRadiant.
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 char *SKEL_ROOT_NAMES[] =
46 int numJointsForSkeleton[] =
54 float g_translation[3];
56 //==========================================================================
60 //==========================================================================
62 static void LoadHRCClustered( char *fileName, int **clusterList, int *num_verts, int skelType ){
65 TK_OpenSource( fileName );
66 TK_FetchRequire( TK_HRCH );
67 TK_FetchRequire( TK_COLON );
68 TK_FetchRequire( TK_SOFTIMAGE );
70 TK_Beyond( TK_CLUSTERS );
72 while ( TK_Search( TK_CLUSTER_NAME ) != TK_EOF )
74 TK_Require( TK_STRING );
76 for ( i = 0; i < numJointsForSkeleton[skelType]; ++i )
78 if ( stricmp( tk_String, SKEL_NAMES[NAME_OFFSETS[skelType] + i] ) == 0 ) {
79 i = -i + numJointsForSkeleton[skelType] - 1;
81 TK_BeyondRequire( TK_NUM_CLUSTER_VERTICES, TK_INTNUMBER );
83 num_verts[i + 1] = tk_IntNumber;
85 clusterList[i] = (int *) SafeMalloc( num_verts[i + 1] * sizeof( int ), "LoadHRCClustered" );
86 assert( clusterList[i] );
87 // currently this function is only called by LoadTriangleListClustered, which in turn is only
88 // called by Cmd_Base in qdata. This is where the only call to free for this memory is being made.
90 TK_Beyond( TK_LBRACE );
92 for ( j = 0; j < num_verts[i + 1]; ++j )
94 TK_Require( TK_INTNUMBER );
95 clusterList[i][j] = tk_IntNumber;
104 num_verts[0] = numJointsForSkeleton[skelType];
107 static void LoadHRCGlobals( char *fileName ){
110 TK_OpenSource( fileName );
111 TK_FetchRequire( TK_HRCH );
112 TK_FetchRequire( TK_COLON );
113 TK_FetchRequire( TK_SOFTIMAGE );
114 TK_Beyond( TK_MODEL );
116 TK_Beyond( TK_SCALING );
117 for ( i = 0; i < 3; i++ )
119 TK_Require( TK_FLOATNUMBER );
120 g_scaling[i] = tk_FloatNumber;
124 TK_Beyond( TK_ROTATION );
125 for ( i = 0; i < 3; i++ )
127 TK_Require( TK_FLOATNUMBER );
128 g_rotation[i] = tk_FloatNumber;
132 TK_Beyond( TK_TRANSLATION );
133 for ( i = 0; i < 3; i++ )
135 TK_Require( TK_FLOATNUMBER );
136 g_translation[i] = tk_FloatNumber;
141 static void ParseVec3( vec3_t in ){
142 TK_Require( TK_FLOATNUMBER );
143 in[1] = tk_FloatNumber;
144 TK_FetchRequire( TK_FLOATNUMBER );
145 in[2] = tk_FloatNumber;
146 TK_FetchRequire( TK_FLOATNUMBER );
147 in[0] = tk_FloatNumber;
150 static void ParseRotation3( vec3_t in ){
151 TK_Require( TK_FLOATNUMBER );
152 in[1] = -tk_FloatNumber;
153 TK_FetchRequire( TK_FLOATNUMBER );
154 in[2] = tk_FloatNumber;
155 TK_FetchRequire( TK_FLOATNUMBER );
156 in[0] = tk_FloatNumber;
159 static void ParseTranslation3( vec3_t in ){
160 TK_Require( TK_FLOATNUMBER );
161 in[1] = tk_FloatNumber;
162 TK_FetchRequire( TK_FLOATNUMBER );
163 in[2] = tk_FloatNumber;
164 TK_FetchRequire( TK_FLOATNUMBER );
165 in[0] = tk_FloatNumber;
168 static void LoadHRCJointList( char *fileName, QDataJoint_t *jointList, int skelType ){
171 vec3_t curTranslation[MAX_STACK], curRotation[MAX_STACK], curScale[MAX_STACK];
172 int curCorrespondingJoint[MAX_STACK];
173 int currentStack = 0, stackSize;
175 float cx, sx, cy, sy, cz, sz;
180 TK_OpenSource( fileName );
181 TK_FetchRequire( TK_HRCH );
182 TK_FetchRequire( TK_COLON );
183 TK_FetchRequire( TK_SOFTIMAGE );
185 TK_Beyond( TK_MODEL );
186 TK_Beyond( TK_MODEL );
191 TK_BeyondRequire(TK_NAME, TK_STRING);
193 if(_stricmp(tk_String, SKEL_ROOT_NAMES[skelType]) == 0)
197 TK_Beyond( TK_SCALING );
199 ParseVec3( curScale[currentStack] );
201 TK_Beyond( TK_ROTATION );
203 ParseRotation3( curRotation[currentStack] );
205 TK_Beyond( TK_TRANSLATION );
207 ParseVec3( curTranslation[currentStack] );
209 // account for global model translation
210 curTranslation[currentStack][1] += g_translation[0];
211 curTranslation[currentStack][2] += g_translation[1];
212 curTranslation[currentStack][0] += g_translation[2];
216 for ( i = 0; i < NUM_JOINTS_RAVEN; ++i )
220 TK_Beyond( TK_MODEL );
222 // TK_BeyondRequire(TK_NAME, TK_STRING);
224 // if(_stricmp(tk_String, SKEL_NAMES[NAME_OFFSETS[skelType]+i]) == 0)
227 TK_Beyond( TK_SCALING );
229 ParseVec3( curScale[currentStack] );
231 TK_Beyond( TK_ROTATION );
233 ParseRotation3( curRotation[currentStack] );
235 TK_Beyond( TK_TRANSLATION );
237 ParseVec3( curTranslation[currentStack] );
239 curCorrespondingJoint[currentStack] = -1;
244 TK_Beyond( TK_SCALING );
246 ParseVec3( curScale[currentStack] );
248 TK_Beyond( TK_ROTATION );
250 ParseRotation3( curRotation[currentStack] );
252 jointList[i].rotation[1] = curRotation[currentStack][1];
253 jointList[i].rotation[2] = curRotation[currentStack][2];
254 jointList[i].rotation[0] = curRotation[currentStack][0];
256 TK_Beyond( TK_TRANSLATION );
258 ParseVec3( curTranslation[currentStack] );
260 jointList[i].placement.origin[1] = curTranslation[currentStack][1];
261 jointList[i].placement.origin[2] = curTranslation[currentStack][2];
262 jointList[i].placement.origin[0] = curTranslation[currentStack][0];
264 jointList[i].placement.direction[1] = 7.5;
265 jointList[i].placement.direction[2] = 0.0;
266 jointList[i].placement.direction[0] = 0.0;
268 jointList[i].placement.up[1] = 0.0;
269 jointList[i].placement.up[2] = 7.5;
270 jointList[i].placement.up[0] = 0.0;
272 curCorrespondingJoint[currentStack] = i;
277 stackSize = currentStack;
279 for ( i = 0; i < NUM_JOINTS_RAVEN; ++i )
281 rx = jointList[i].rotation[0] * ANGLE_TO_RAD;
282 ry = jointList[i].rotation[1] * ANGLE_TO_RAD;
283 rz = jointList[i].rotation[2] * ANGLE_TO_RAD;
294 // y-axis rotation for direction
295 x2 = jointList[i].placement.direction[0] * cy + jointList[i].placement.direction[2] * sy;
296 z2 = -jointList[i].placement.direction[0] * sy + jointList[i].placement.direction[2] * cy;
297 jointList[i].placement.direction[0] = x2;
298 jointList[i].placement.direction[2] = z2;
300 // y-axis rotation for up
301 x2 = jointList[i].placement.up[0] * cy + jointList[i].placement.up[2] * sy;
302 z2 = -jointList[i].placement.up[0] * sy + jointList[i].placement.up[2] * cy;
303 jointList[i].placement.up[0] = x2;
304 jointList[i].placement.up[2] = z2;
306 // z-axis rotation for direction
307 x2 = jointList[i].placement.direction[0] * cz - jointList[i].placement.direction[1] * sz;
308 y2 = jointList[i].placement.direction[0] * sz + jointList[i].placement.direction[1] * cz;
309 jointList[i].placement.direction[0] = x2;
310 jointList[i].placement.direction[1] = y2;
312 // z-axis rotation for up
313 x2 = jointList[i].placement.up[0] * cz - jointList[i].placement.up[1] * sz;
314 y2 = jointList[i].placement.up[0] * sz + jointList[i].placement.up[1] * cz;
315 jointList[i].placement.up[0] = x2;
316 jointList[i].placement.up[1] = y2;
318 // x-axis rotation for direction vector
319 y2 = jointList[i].placement.direction[1] * cx - jointList[i].placement.direction[2] * sx;
320 z2 = jointList[i].placement.direction[1] * sx + jointList[i].placement.direction[2] * cx;
321 jointList[i].placement.direction[1] = y2;
322 jointList[i].placement.direction[2] = z2;
324 // x-axis rotation for up vector
325 y2 = jointList[i].placement.up[1] * cx - jointList[i].placement.up[2] * sx;
326 z2 = jointList[i].placement.up[1] * sx + jointList[i].placement.up[2] * cx;
327 jointList[i].placement.up[1] = y2;
328 jointList[i].placement.up[2] = z2;
330 // translate to position in model
331 jointList[i].placement.direction[0] += jointList[i].placement.origin[0];
332 jointList[i].placement.direction[1] += jointList[i].placement.origin[1];
333 jointList[i].placement.direction[2] += jointList[i].placement.origin[2];
335 // translate to position in model
336 jointList[i].placement.up[0] += jointList[i].placement.origin[0];
337 jointList[i].placement.up[1] += jointList[i].placement.origin[1];
338 jointList[i].placement.up[2] += jointList[i].placement.origin[2];
341 baseJoint = NUM_JOINTS_RAVEN;
343 for ( i = stackSize /*NUM_JOINTS_RAVEN*/ - 1; i > 0; --i )
346 rx = curRotation[i - 1][0] * ANGLE_TO_RAD;
347 ry = curRotation[i - 1][1] * ANGLE_TO_RAD;
348 rz = curRotation[i - 1][2] * ANGLE_TO_RAD;
359 for ( j = i - 1; j < stackSize - 1; ++j )
361 // y-axis rotation for origin
362 x2 = jointList[j].placement.origin[0] * cy + jointList[j].placement.origin[2] * sy;
363 z2 = -jointList[j].placement.origin[0] * sy + jointList[j].placement.origin[2] * cy;
364 jointList[j].placement.origin[0] = x2;
365 jointList[j].placement.origin[2] = z2;
367 // y-axis rotation for direction
368 x2 = jointList[j].placement.direction[0] * cy + jointList[j].placement.direction[2] * sy;
369 z2 = -jointList[j].placement.direction[0] * sy + jointList[j].placement.direction[2] * cy;
370 jointList[j].placement.direction[0] = x2;
371 jointList[j].placement.direction[2] = z2;
373 // y-axis rotation for up
374 x2 = jointList[j].placement.up[0] * cy + jointList[j].placement.up[2] * sy;
375 z2 = -jointList[j].placement.up[0] * sy + jointList[j].placement.up[2] * cy;
376 jointList[j].placement.up[0] = x2;
377 jointList[j].placement.up[2] = z2;
379 // z-axis rotation for origin
380 x2 = jointList[j].placement.origin[0] * cz - jointList[j].placement.origin[1] * sz;
381 y2 = jointList[j].placement.origin[0] * sz + jointList[j].placement.origin[1] * cz;
382 jointList[j].placement.origin[0] = x2;
383 jointList[j].placement.origin[1] = y2;
385 // z-axis rotation for direction
386 x2 = jointList[j].placement.direction[0] * cz - jointList[j].placement.direction[1] * sz;
387 y2 = jointList[j].placement.direction[0] * sz + jointList[j].placement.direction[1] * cz;
388 jointList[j].placement.direction[0] = x2;
389 jointList[j].placement.direction[1] = y2;
391 // z-axis rotation for up
392 x2 = jointList[j].placement.up[0] * cz - jointList[j].placement.up[1] * sz;
393 y2 = jointList[j].placement.up[0] * sz + jointList[j].placement.up[1] * cz;
394 jointList[j].placement.up[0] = x2;
395 jointList[j].placement.up[1] = y2;
397 // x-axis rotation for origin
398 y2 = jointList[j].placement.origin[1] * cx - jointList[j].placement.origin[2] * sx;
399 z2 = jointList[j].placement.origin[1] * sx + jointList[j].placement.origin[2] * cx;
400 jointList[j].placement.origin[1] = y2;
401 jointList[j].placement.origin[2] = z2;
403 // x-axis rotation for direction vector
404 y2 = jointList[j].placement.direction[1] * cx - jointList[j].placement.direction[2] * sx;
405 z2 = jointList[j].placement.direction[1] * sx + jointList[j].placement.direction[2] * cx;
406 jointList[j].placement.direction[1] = y2;
407 jointList[j].placement.direction[2] = z2;
409 // x-axis rotation for up vector
410 y2 = jointList[j].placement.up[1] * cx - jointList[j].placement.up[2] * sx;
411 z2 = jointList[j].placement.up[1] * sx + jointList[j].placement.up[2] * cx;
412 jointList[j].placement.up[1] = y2;
413 jointList[j].placement.up[2] = z2;
415 if ( curCorrespondingJoint[j + 1] != -1 ) {
417 jointList[j].placement.origin[0] += curTranslation[i - 1][0];
418 jointList[j].placement.origin[1] += curTranslation[i - 1][1];
419 jointList[j].placement.origin[2] += curTranslation[i - 1][2];
421 // translate back to local coord
422 jointList[j].placement.direction[0] += curTranslation[i - 1][0];
423 jointList[j].placement.direction[1] += curTranslation[i - 1][1];
424 jointList[j].placement.direction[2] += curTranslation[i - 1][2];
426 // translate back to local coord
427 jointList[j].placement.up[0] += curTranslation[i - 1][0];
428 jointList[j].placement.up[1] += curTranslation[i - 1][1];
429 jointList[j].placement.up[2] += curTranslation[i - 1][2];
435 void LoadGlobals( char *fileName ){
439 char InputFileName[256];
441 dotstart = strrchr( fileName,dot ); // Does it already have an extension on the file name?
444 strcpy( InputFileName, fileName );
445 strcat( InputFileName, ".hrc" );
446 if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
449 LoadHRCGlobals( InputFileName );
451 printf( " - assuming .HRC\n" );
455 Error( "\n Could not open file '%s':\n"
456 "No HRC match.\n", fileName );
460 if ( ( file1 = fopen( fileName, "rb" ) ) != NULL ) {
463 if ( strcmp( dotstart,".hrc" ) == 0 || strcmp( dotstart,".HRC" ) == 0 ) {
464 LoadHRCGlobals( fileName );
469 Error( "Could not open file '%s':\n",fileName );
473 void LoadClusters( char *fileName, int **clusterList, int *num_verts, int skelType ){
477 char InputFileName[256];
479 dotstart = strrchr( fileName,dot ); // Does it already have an extension on the file name?
482 strcpy( InputFileName, fileName );
483 strcat( InputFileName, ".hrc" );
484 if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
487 LoadHRCClustered( InputFileName, clusterList, num_verts, skelType );
489 printf( " - assuming .HRC\n" );
493 Error( "\n Could not open file '%s':\n"
494 "No HRC match.\n", fileName );
498 if ( ( file1 = fopen( fileName, "rb" ) ) != NULL ) {
501 if ( strcmp( dotstart,".hrc" ) == 0 || strcmp( dotstart,".HRC" ) == 0 ) {
502 LoadHRCClustered( fileName, clusterList, num_verts, skelType );
507 Error( "Could not open file '%s':\n",fileName );
511 void LoadJointList( char *fileName, QDataJoint_t *jointList, int skelType ){
515 char InputFileName[256];
517 dotstart = strrchr( fileName,dot ); // Does it already have an extension on the file name?
520 strcpy( InputFileName, fileName );
521 strcat( InputFileName, ".hrc" );
522 if ( ( file1 = fopen( InputFileName, "rb" ) ) != NULL ) {
525 LoadHRCJointList( InputFileName, jointList, skelType );
527 printf( " - assuming .HRC\n" );
531 Error( "\n Could not open file '%s':\n"
532 "No HRC.\n", fileName );
536 if ( ( file1 = fopen( fileName, "rb" ) ) != NULL ) {
539 if ( strcmp( dotstart,".hrc" ) == 0 || strcmp( dotstart,".HRC" ) == 0 ) {
540 LoadHRCJointList( fileName, jointList, skelType );
546 Error( "Could not open file '%s':\n",fileName );