2 Copyright (C) 1999-2006 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)
66 TK_OpenSource(fileName);
67 TK_FetchRequire(TK_HRCH);
68 TK_FetchRequire(TK_COLON);
69 TK_FetchRequire(TK_SOFTIMAGE);
71 TK_Beyond(TK_CLUSTERS);
73 while(TK_Search(TK_CLUSTER_NAME) != TK_EOF)
75 TK_Require(TK_STRING);
77 for( i = 0; i < numJointsForSkeleton[skelType]; ++i)
79 if(stricmp(tk_String, SKEL_NAMES[NAME_OFFSETS[skelType]+i]) == 0)
81 i = -i + numJointsForSkeleton[skelType] - 1;
83 TK_BeyondRequire(TK_NUM_CLUSTER_VERTICES, TK_INTNUMBER);
85 num_verts[i+1] = tk_IntNumber;
87 clusterList[i] = (int *) SafeMalloc(num_verts[i+1]*sizeof(int), "LoadHRCClustered");
88 assert(clusterList[i]);
89 // currently this function is only called by LoadTriangleListClustered, which in turn is only
90 // called by Cmd_Base in qdata. This is where the only call to free for this memory is being made.
94 for(j = 0; j < num_verts[i+1]; ++j)
96 TK_Require(TK_INTNUMBER);
97 clusterList[i][j] = tk_IntNumber;
106 num_verts[0] = numJointsForSkeleton[skelType];
109 static void LoadHRCGlobals(char *fileName)
113 TK_OpenSource(fileName);
114 TK_FetchRequire(TK_HRCH);
115 TK_FetchRequire(TK_COLON);
116 TK_FetchRequire(TK_SOFTIMAGE);
119 TK_Beyond(TK_SCALING);
120 for(i = 0; i < 3; i++)
122 TK_Require(TK_FLOATNUMBER);
123 g_scaling[i] = tk_FloatNumber;
127 TK_Beyond(TK_ROTATION);
128 for(i = 0; i < 3; i++)
130 TK_Require(TK_FLOATNUMBER);
131 g_rotation[i] = tk_FloatNumber;
135 TK_Beyond(TK_TRANSLATION);
136 for(i = 0; i < 3; i++)
138 TK_Require(TK_FLOATNUMBER);
139 g_translation[i] = tk_FloatNumber;
144 static void ParseVec3(vec3_t in)
146 TK_Require(TK_FLOATNUMBER);
147 in[1] = tk_FloatNumber;
148 TK_FetchRequire(TK_FLOATNUMBER);
149 in[2] = tk_FloatNumber;
150 TK_FetchRequire(TK_FLOATNUMBER);
151 in[0] = tk_FloatNumber;
154 static void ParseRotation3(vec3_t in)
156 TK_Require(TK_FLOATNUMBER);
157 in[1] = -tk_FloatNumber;
158 TK_FetchRequire(TK_FLOATNUMBER);
159 in[2] = tk_FloatNumber;
160 TK_FetchRequire(TK_FLOATNUMBER);
161 in[0] = tk_FloatNumber;
164 static void ParseTranslation3(vec3_t in)
166 TK_Require(TK_FLOATNUMBER);
167 in[1] = tk_FloatNumber;
168 TK_FetchRequire(TK_FLOATNUMBER);
169 in[2] = tk_FloatNumber;
170 TK_FetchRequire(TK_FLOATNUMBER);
171 in[0] = tk_FloatNumber;
174 static void LoadHRCJointList(char *fileName, QDataJoint_t *jointList, int skelType)
178 vec3_t curTranslation[MAX_STACK], curRotation[MAX_STACK], curScale[MAX_STACK];
179 int curCorrespondingJoint[MAX_STACK];
180 int currentStack = 0, stackSize;
182 float cx, sx, cy, sy, cz, sz;
187 TK_OpenSource(fileName);
188 TK_FetchRequire(TK_HRCH);
189 TK_FetchRequire(TK_COLON);
190 TK_FetchRequire(TK_SOFTIMAGE);
198 TK_BeyondRequire(TK_NAME, TK_STRING);
200 if(_stricmp(tk_String, SKEL_ROOT_NAMES[skelType]) == 0)
204 TK_Beyond(TK_SCALING);
206 ParseVec3(curScale[currentStack]);
208 TK_Beyond(TK_ROTATION);
210 ParseRotation3(curRotation[currentStack]);
212 TK_Beyond(TK_TRANSLATION);
214 ParseVec3(curTranslation[currentStack]);
216 // account for global model translation
217 curTranslation[currentStack][1] += g_translation[0];
218 curTranslation[currentStack][2] += g_translation[1];
219 curTranslation[currentStack][0] += g_translation[2];
223 for(i = 0; i < NUM_JOINTS_RAVEN; ++i)
229 // TK_BeyondRequire(TK_NAME, TK_STRING);
231 // if(_stricmp(tk_String, SKEL_NAMES[NAME_OFFSETS[skelType]+i]) == 0)
234 TK_Beyond(TK_SCALING);
236 ParseVec3(curScale[currentStack]);
238 TK_Beyond(TK_ROTATION);
240 ParseRotation3(curRotation[currentStack]);
242 TK_Beyond(TK_TRANSLATION);
244 ParseVec3(curTranslation[currentStack]);
246 curCorrespondingJoint[currentStack] = -1;
251 TK_Beyond(TK_SCALING);
253 ParseVec3(curScale[currentStack]);
255 TK_Beyond(TK_ROTATION);
257 ParseRotation3(curRotation[currentStack]);
259 jointList[i].rotation[1] = curRotation[currentStack][1];
260 jointList[i].rotation[2] = curRotation[currentStack][2];
261 jointList[i].rotation[0] = curRotation[currentStack][0];
263 TK_Beyond(TK_TRANSLATION);
265 ParseVec3(curTranslation[currentStack]);
267 jointList[i].placement.origin[1] = curTranslation[currentStack][1];
268 jointList[i].placement.origin[2] = curTranslation[currentStack][2];
269 jointList[i].placement.origin[0] = curTranslation[currentStack][0];
271 jointList[i].placement.direction[1] = 7.5;
272 jointList[i].placement.direction[2] = 0.0;
273 jointList[i].placement.direction[0] = 0.0;
275 jointList[i].placement.up[1] = 0.0;
276 jointList[i].placement.up[2] = 7.5;
277 jointList[i].placement.up[0] = 0.0;
279 curCorrespondingJoint[currentStack] = i;
284 stackSize = currentStack;
286 for(i = 0; i < NUM_JOINTS_RAVEN; ++i)
288 rx = jointList[i].rotation[0]*ANGLE_TO_RAD;
289 ry = jointList[i].rotation[1]*ANGLE_TO_RAD;
290 rz = jointList[i].rotation[2]*ANGLE_TO_RAD;
301 // y-axis rotation for direction
302 x2 = jointList[i].placement.direction[0]*cy+jointList[i].placement.direction[2]*sy;
303 z2 = -jointList[i].placement.direction[0]*sy+jointList[i].placement.direction[2]*cy;
304 jointList[i].placement.direction[0] = x2;
305 jointList[i].placement.direction[2] = z2;
307 // y-axis rotation for up
308 x2 = jointList[i].placement.up[0]*cy+jointList[i].placement.up[2]*sy;
309 z2 = -jointList[i].placement.up[0]*sy+jointList[i].placement.up[2]*cy;
310 jointList[i].placement.up[0] = x2;
311 jointList[i].placement.up[2] = z2;
313 // z-axis rotation for direction
314 x2 = jointList[i].placement.direction[0]*cz-jointList[i].placement.direction[1]*sz;
315 y2 = jointList[i].placement.direction[0]*sz+jointList[i].placement.direction[1]*cz;
316 jointList[i].placement.direction[0] = x2;
317 jointList[i].placement.direction[1] = y2;
319 // z-axis rotation for up
320 x2 = jointList[i].placement.up[0]*cz-jointList[i].placement.up[1]*sz;
321 y2 = jointList[i].placement.up[0]*sz+jointList[i].placement.up[1]*cz;
322 jointList[i].placement.up[0] = x2;
323 jointList[i].placement.up[1] = y2;
325 // x-axis rotation for direction vector
326 y2 = jointList[i].placement.direction[1]*cx-jointList[i].placement.direction[2]*sx;
327 z2 = jointList[i].placement.direction[1]*sx+jointList[i].placement.direction[2]*cx;
328 jointList[i].placement.direction[1] = y2;
329 jointList[i].placement.direction[2] = z2;
331 // x-axis rotation for up vector
332 y2 = jointList[i].placement.up[1]*cx-jointList[i].placement.up[2]*sx;
333 z2 = jointList[i].placement.up[1]*sx+jointList[i].placement.up[2]*cx;
334 jointList[i].placement.up[1] = y2;
335 jointList[i].placement.up[2] = z2;
337 // translate to position in model
338 jointList[i].placement.direction[0] += jointList[i].placement.origin[0];
339 jointList[i].placement.direction[1] += jointList[i].placement.origin[1];
340 jointList[i].placement.direction[2] += jointList[i].placement.origin[2];
342 // translate to position in model
343 jointList[i].placement.up[0] += jointList[i].placement.origin[0];
344 jointList[i].placement.up[1] += jointList[i].placement.origin[1];
345 jointList[i].placement.up[2] += jointList[i].placement.origin[2];
348 baseJoint = NUM_JOINTS_RAVEN;
350 for(i = stackSize/*NUM_JOINTS_RAVEN*/ - 1; i > 0; --i)
353 rx = curRotation[i-1][0]*ANGLE_TO_RAD;
354 ry = curRotation[i-1][1]*ANGLE_TO_RAD;
355 rz = curRotation[i-1][2]*ANGLE_TO_RAD;
366 for(j = i-1; j < stackSize-1; ++j)
368 // y-axis rotation for origin
369 x2 = jointList[j].placement.origin[0]*cy+jointList[j].placement.origin[2]*sy;
370 z2 = -jointList[j].placement.origin[0]*sy+jointList[j].placement.origin[2]*cy;
371 jointList[j].placement.origin[0] = x2;
372 jointList[j].placement.origin[2] = z2;
374 // y-axis rotation for direction
375 x2 = jointList[j].placement.direction[0]*cy+jointList[j].placement.direction[2]*sy;
376 z2 = -jointList[j].placement.direction[0]*sy+jointList[j].placement.direction[2]*cy;
377 jointList[j].placement.direction[0] = x2;
378 jointList[j].placement.direction[2] = z2;
380 // y-axis rotation for up
381 x2 = jointList[j].placement.up[0]*cy+jointList[j].placement.up[2]*sy;
382 z2 = -jointList[j].placement.up[0]*sy+jointList[j].placement.up[2]*cy;
383 jointList[j].placement.up[0] = x2;
384 jointList[j].placement.up[2] = z2;
386 // z-axis rotation for origin
387 x2 = jointList[j].placement.origin[0]*cz-jointList[j].placement.origin[1]*sz;
388 y2 = jointList[j].placement.origin[0]*sz+jointList[j].placement.origin[1]*cz;
389 jointList[j].placement.origin[0] = x2;
390 jointList[j].placement.origin[1] = y2;
392 // z-axis rotation for direction
393 x2 = jointList[j].placement.direction[0]*cz-jointList[j].placement.direction[1]*sz;
394 y2 = jointList[j].placement.direction[0]*sz+jointList[j].placement.direction[1]*cz;
395 jointList[j].placement.direction[0] = x2;
396 jointList[j].placement.direction[1] = y2;
398 // z-axis rotation for up
399 x2 = jointList[j].placement.up[0]*cz-jointList[j].placement.up[1]*sz;
400 y2 = jointList[j].placement.up[0]*sz+jointList[j].placement.up[1]*cz;
401 jointList[j].placement.up[0] = x2;
402 jointList[j].placement.up[1] = y2;
404 // x-axis rotation for origin
405 y2 = jointList[j].placement.origin[1]*cx-jointList[j].placement.origin[2]*sx;
406 z2 = jointList[j].placement.origin[1]*sx+jointList[j].placement.origin[2]*cx;
407 jointList[j].placement.origin[1] = y2;
408 jointList[j].placement.origin[2] = z2;
410 // x-axis rotation for direction vector
411 y2 = jointList[j].placement.direction[1]*cx-jointList[j].placement.direction[2]*sx;
412 z2 = jointList[j].placement.direction[1]*sx+jointList[j].placement.direction[2]*cx;
413 jointList[j].placement.direction[1] = y2;
414 jointList[j].placement.direction[2] = z2;
416 // x-axis rotation for up vector
417 y2 = jointList[j].placement.up[1]*cx-jointList[j].placement.up[2]*sx;
418 z2 = jointList[j].placement.up[1]*sx+jointList[j].placement.up[2]*cx;
419 jointList[j].placement.up[1] = y2;
420 jointList[j].placement.up[2] = z2;
422 if(curCorrespondingJoint[j+1] != -1)
425 jointList[j].placement.origin[0] += curTranslation[i-1][0];
426 jointList[j].placement.origin[1] += curTranslation[i-1][1];
427 jointList[j].placement.origin[2] += curTranslation[i-1][2];
429 // translate back to local coord
430 jointList[j].placement.direction[0] += curTranslation[i-1][0];
431 jointList[j].placement.direction[1] += curTranslation[i-1][1];
432 jointList[j].placement.direction[2] += curTranslation[i-1][2];
434 // translate back to local coord
435 jointList[j].placement.up[0] += curTranslation[i-1][0];
436 jointList[j].placement.up[1] += curTranslation[i-1][1];
437 jointList[j].placement.up[2] += curTranslation[i-1][2];
443 void LoadGlobals(char *fileName)
448 char InputFileName[256];
450 dotstart = strrchr(fileName,dot); // Does it already have an extension on the file name?
454 strcpy(InputFileName, fileName);
455 strcat(InputFileName, ".hrc");
456 if((file1 = fopen(InputFileName, "rb")) != NULL)
460 LoadHRCGlobals(InputFileName);
462 printf(" - assuming .HRC\n");
466 Error("\n Could not open file '%s':\n"
467 "No HRC match.\n", fileName);
471 if((file1 = fopen(fileName, "rb")) != NULL)
475 if (strcmp(dotstart,".hrc") == 0 || strcmp(dotstart,".HRC") == 0)
477 LoadHRCGlobals(fileName);
482 Error("Could not open file '%s':\n",fileName);
486 void LoadClusters(char *fileName, int **clusterList, int *num_verts, int skelType)
491 char InputFileName[256];
493 dotstart = strrchr(fileName,dot); // Does it already have an extension on the file name?
497 strcpy(InputFileName, fileName);
498 strcat(InputFileName, ".hrc");
499 if((file1 = fopen(InputFileName, "rb")) != NULL)
503 LoadHRCClustered(InputFileName, clusterList, num_verts, skelType);
505 printf(" - assuming .HRC\n");
509 Error("\n Could not open file '%s':\n"
510 "No HRC match.\n", fileName);
514 if((file1 = fopen(fileName, "rb")) != NULL)
518 if (strcmp(dotstart,".hrc") == 0 || strcmp(dotstart,".HRC") == 0)
520 LoadHRCClustered(fileName, clusterList, num_verts, skelType);
525 Error("Could not open file '%s':\n",fileName);
529 void LoadJointList(char *fileName, QDataJoint_t *jointList, int skelType)
534 char InputFileName[256];
536 dotstart = strrchr(fileName,dot); // Does it already have an extension on the file name?
540 strcpy(InputFileName, fileName);
541 strcat(InputFileName, ".hrc");
542 if((file1 = fopen(InputFileName, "rb")) != NULL)
546 LoadHRCJointList(InputFileName, jointList, skelType);
548 printf(" - assuming .HRC\n");
552 Error("\n Could not open file '%s':\n"
553 "No HRC.\n", fileName);
557 if((file1 = fopen(fileName, "rb")) != NULL)
561 if (strcmp(dotstart,".hrc") == 0 || strcmp(dotstart,".HRC") == 0)
563 LoadHRCJointList(fileName, jointList, skelType);
569 Error("Could not open file '%s':\n",fileName);