2 Copyright (C) 1999-2007 id Software, Inc. and contributors.
\r
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
\r
5 This file is part of GtkRadiant.
\r
7 GtkRadiant is free software; you can redistribute it and/or modify
\r
8 it under the terms of the GNU General Public License as published by
\r
9 the Free Software Foundation; either version 2 of the License, or
\r
10 (at your option) any later version.
\r
12 GtkRadiant is distributed in the hope that it will be useful,
\r
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
15 GNU General Public License for more details.
\r
17 You should have received a copy of the GNU General Public License
\r
18 along with GtkRadiant; if not, write to the Free Software
\r
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\r
22 #include "qd_skeletons.h"
\r
23 #include "skeletons.h"
\r
24 #include "qd_fmodel.h"
\r
28 #include "reference.h"
\r
35 // We're assuming no more than 16 reference points, with no more than 32 characters in the name
\r
36 char RefPointNameList[REF_MAX_POINTS][REF_MAX_STRLEN];
\r
37 int RefPointNum = 0;
\r
39 Skeletalfmheader_t g_skelModel;
\r
41 void ClearSkeletalModel()
\r
43 g_skelModel.type = SKEL_NULL;
\r
44 g_skelModel.clustered = false;
\r
45 g_skelModel.references = REF_NULL;
\r
48 //==========================================================================
\r
52 //==========================================================================
\r
54 // Places the null terminated src string into the dest string less any trailing digits or underscores
\r
55 void StripTrailingDigits(char *src, char *dest)
\r
58 int max = SKELETAL_NAME_MAX; // should be sufficient for inteded use on names from hrc files
\r
62 while(src[i] != '\0')
\r
70 while((src[--i] >= '0' && src[i] <= '9') || src[i] == '_')
\r
75 memcpy(dest, src, ++i);
\r
80 static void LoadHRCClustered(char *fileName, int **clusterList, int *num_verts, int skelType)
\r
82 extern void HandleHRCModel(triangle_t **triList, int *triangleCount,
\r
83 mesh_node_t **nodesList, int *num_mesh_nodes, int ActiveNode, int Depth);
\r
85 extern mesh_node_t *pmnodes;
\r
87 triangle_t *triList;
\r
88 // mesh_node_t *nodesList;
\r
89 int num_mesh_nodes = 0, triangleCount = 0;
\r
94 char stripped[SKELETAL_NAME_MAX];
\r
96 for( i = 1; i < numJointsInSkeleton[skelType] + 1; ++i)
\r
101 TK_OpenSource(fileName);
\r
102 TK_FetchRequire(TK_HRCH);
\r
103 TK_FetchRequire(TK_COLON);
\r
104 TK_FetchRequire(TK_SOFTIMAGE);
\r
106 TK_Beyond(TK_CLUSTERS);
\r
108 while(TK_Search(TK_CLUSTER_NAME) != TK_EOF)
\r
110 TK_Require(TK_STRING);
\r
112 StripTrailingDigits(tk_String, stripped);
\r
114 for( i = 0; i < numJointsInSkeleton[skelType]; ++i)
\r
116 if(stricmp(stripped, skeletonJointNames[skeletonNameOffsets[skelType]+i]) == 0)
\r
118 i = -i + numJointsInSkeleton[skelType] - 1;
\r
120 TK_BeyondRequire(TK_NUM_CLUSTER_VERTICES, TK_INTNUMBER);
\r
122 numVerts = tk_IntNumber;
\r
124 if(!num_verts[i+1]) // first set of verts for cluster
\r
126 clusterList[i] = SafeMalloc(numVerts*sizeof(int), "LoadHRCClustered");
\r
127 assert(clusterList[i]);
\r
129 else // any later sets of verts need to copy current
\r
133 temp = SafeMalloc((num_verts[i+1]+numVerts)*sizeof(int), "LoadHRCClustered");
\r
136 memcpy(temp + numVerts, clusterList[i], num_verts[i+1]*sizeof(int));
\r
138 free(clusterList[i]);
\r
140 clusterList[i] = temp;
\r
143 // currently this function is only called by LoadModelClusters.
\r
144 // Apparently the matching free has disappeared,
\r
145 // should probably be free at the end of FMCmd_Base
\r
147 TK_Beyond(TK_LBRACE);
\r
149 for(j = 0; j < numVerts; ++j)
\r
151 TK_Require(TK_INTNUMBER);
\r
152 clusterList[i][j] = tk_IntNumber;
\r
156 num_verts[i+1] += numVerts;
\r
163 num_verts[0] = numJointsInSkeleton[skelType];
\r
166 #if 1 // get the index number localized to the root
\r
167 // for( i = 1; i < numJointsInSkeleton[skelType] + 1; ++i)
\r
169 // g_skelModel.num_verts[i] = 0;
\r
172 TK_OpenSource(fileName);
\r
173 TK_FetchRequire(TK_HRCH);
\r
174 TK_FetchRequire(TK_COLON);
\r
175 TK_FetchRequire(TK_SOFTIMAGE);
\r
178 TK_Beyond(TK_MODEL);
\r
180 triList = (triangle_t *) SafeMalloc(MAXTRIANGLES*sizeof(triangle_t), "Triangle list");
\r
181 memset(triList,0,MAXTRIANGLES*sizeof(triangle_t));
\r
182 // nodesList = SafeMalloc(MAX_FM_MESH_NODES * sizeof(mesh_node_t), "Mesh Node List");
\r
183 pmnodes = (mesh_node_t *) SafeMalloc(MAX_FM_MESH_NODES * sizeof(mesh_node_t), "Mesh Node List");
\r
185 memset(pmnodes, 0, MAX_FM_MESH_NODES * sizeof(mesh_node_t));
\r
187 // this should eventually use a stripped down version of this
\r
188 HandleHRCModel(&triList, &triangleCount, &pmnodes, &num_mesh_nodes, 0, 0);
\r
190 // free(nodesList);
\r
193 num_verts[0] = numJointsInSkeleton[skelType];
\r
197 void ReadHRCClusterList(mesh_node_t *meshNode, int baseIndex)
\r
199 int i, j, numVerts;
\r
200 tokenType_t nextToken;
\r
201 char stripped[SKELETAL_NAME_MAX];
\r
203 meshNode->clustered = true;
\r
205 nextToken = TK_Get(TK_CLUSTER_NAME);
\r
207 while (nextToken == TK_CLUSTER_NAME)
\r
209 TK_FetchRequire(TK_STRING);
\r
211 StripTrailingDigits(tk_String, stripped);
\r
213 for( i = 0; i < numJointsInSkeleton[g_skelModel.type]; ++i)
\r
215 if(stricmp(stripped, skeletonJointNames[skeletonNameOffsets[g_skelModel.type]+i]) == 0)
\r
217 i = -i + numJointsInSkeleton[g_skelModel.type] - 1;
\r
219 TK_BeyondRequire(TK_NUM_CLUSTER_VERTICES, TK_INTNUMBER);
\r
221 numVerts = tk_IntNumber;
\r
225 meshNode->clusters[i] = (int *) SafeMalloc(numVerts*sizeof(int), "ReadHRCClusterList");
\r
226 assert(meshNode->clusters[i]);
\r
232 temp = meshNode->clusters[i];
\r
233 meshNode->clusters[i] = (int *) SafeMalloc((meshNode->num_verts[i+1]+numVerts)*sizeof(int), "ReadHRCClusterList");
\r
234 assert(meshNode->clusters[i]);
\r
236 memcpy(meshNode->clusters[i], temp, meshNode->num_verts[i+1]*sizeof(int));
\r
240 // currently this function is only called by LoadModelClusters.
\r
241 // Apparently the matching free has disappeared,
\r
242 // should probably be free at the end of FMCmd_Base
\r
244 TK_Beyond(TK_LBRACE);
\r
246 for(j = 0; j < numVerts; ++j)
\r
248 TK_Require(TK_INTNUMBER);
\r
249 meshNode->clusters[i][baseIndex+j] = tk_IntNumber+baseIndex;
\r
255 meshNode->num_verts[i+1] += numVerts;
\r
259 meshNode->num_verts[i+1] = numVerts;
\r
266 TK_BeyondRequire(TK_CLUSTER_STATE, TK_INTNUMBER);
\r
267 nextToken = TK_Fetch();
\r
271 static void LoadHRCGlobals(char *fileName)
\r
275 TK_OpenSource(fileName);
\r
276 TK_FetchRequire(TK_HRCH);
\r
277 TK_FetchRequire(TK_COLON);
\r
278 TK_FetchRequire(TK_SOFTIMAGE);
\r
279 TK_Beyond(TK_MODEL);
\r
281 TK_Beyond(TK_SCALING);
\r
282 for(i = 0; i < 3; i++)
\r
284 TK_Require(TK_FLOATNUMBER);
\r
285 g_skelModel.scaling[i] = tk_FloatNumber;
\r
289 TK_Beyond(TK_ROTATION);
\r
290 for(i = 0; i < 3; i++)
\r
292 TK_Require(TK_FLOATNUMBER);
\r
293 g_skelModel.rotation[i] = tk_FloatNumber;
\r
297 TK_Beyond(TK_TRANSLATION);
\r
298 for(i = 0; i < 3; i++)
\r
300 TK_Require(TK_FLOATNUMBER);
\r
301 g_skelModel.translation[i] = tk_FloatNumber;
\r
306 static void ParseVec3(vec3_t in)
\r
308 TK_Require(TK_FLOATNUMBER);
\r
309 in[1] = tk_FloatNumber;
\r
310 TK_FetchRequire(TK_FLOATNUMBER);
\r
311 in[2] = tk_FloatNumber;
\r
312 TK_FetchRequire(TK_FLOATNUMBER);
\r
313 in[0] = tk_FloatNumber;
\r
316 static void ParseVec3d(vec3d_t in)
\r
318 TK_Require(TK_FLOATNUMBER);
\r
319 in[1] = tk_FloatNumber;
\r
320 TK_FetchRequire(TK_FLOATNUMBER);
\r
321 in[2] = tk_FloatNumber;
\r
322 TK_FetchRequire(TK_FLOATNUMBER);
\r
323 in[0] = tk_FloatNumber;
\r
326 static void ParseRotation3(vec3_t in)
\r
328 TK_Require(TK_FLOATNUMBER);
\r
329 in[1] = tk_FloatNumber;
\r
330 TK_FetchRequire(TK_FLOATNUMBER);
\r
331 in[2] = tk_FloatNumber;
\r
332 TK_FetchRequire(TK_FLOATNUMBER);
\r
333 in[0] = tk_FloatNumber;
\r
336 static void ParseRotation3d(vec3d_t in)
\r
338 TK_Require(TK_FLOATNUMBER);
\r
339 in[1] = tk_FloatNumber;
\r
340 TK_FetchRequire(TK_FLOATNUMBER);
\r
341 in[2] = tk_FloatNumber;
\r
342 TK_FetchRequire(TK_FLOATNUMBER);
\r
343 in[0] = tk_FloatNumber;
\r
346 static void ParseTranslation3(vec3_t in)
\r
348 TK_Require(TK_FLOATNUMBER);
\r
349 in[1] = tk_FloatNumber;
\r
350 TK_FetchRequire(TK_FLOATNUMBER);
\r
351 in[2] = tk_FloatNumber;
\r
352 TK_FetchRequire(TK_FLOATNUMBER);
\r
353 in[0] = tk_FloatNumber;
\r
356 static void ParseTranslation3d(vec3d_t in)
\r
358 TK_Require(TK_FLOATNUMBER);
\r
359 in[1] = tk_FloatNumber;
\r
360 TK_FetchRequire(TK_FLOATNUMBER);
\r
361 in[2] = tk_FloatNumber;
\r
362 TK_FetchRequire(TK_FLOATNUMBER);
\r
363 in[0] = tk_FloatNumber;
\r
366 static void LoadHRCJointList(char *fileName, QD_SkeletalJoint_t *jointList, int skelType)
\r
368 #define MAX_STACK 64
\r
370 vec3d_t curTranslation[MAX_STACK], curRotation[MAX_STACK], curScale[MAX_STACK];
\r
371 int curCorrespondingJoint[MAX_STACK];
\r
372 int currentStack = 0, stackSize;
\r
373 double cx, sx, cy, sy, cz, sz;
\r
376 char stripped[SKELETAL_NAME_MAX];
\r
377 Placement_d_t *placement;
\r
379 TK_OpenSource(fileName);
\r
380 TK_FetchRequire(TK_HRCH);
\r
381 TK_FetchRequire(TK_COLON);
\r
382 TK_FetchRequire(TK_SOFTIMAGE);
\r
384 TK_Beyond(TK_MODEL);
\r
386 while(TK_Search(TK_NAME) != TK_EOF)
\r
388 TK_Require(TK_STRING);
\r
390 StripTrailingDigits(tk_String, stripped);
\r
392 if(stricmp(stripped, skeletonRootNames[skeletonRNameOffsets[skelType]]) == 0)
\r
398 if(tk_Token == TK_EOF)
\r
400 Error("Bone Chain Root: %s not found\n", skeletonRootNames[skeletonRNameOffsets[skelType]]);
\r
404 TK_Beyond(TK_SCALING);
\r
406 ParseVec3d(curScale[currentStack]);
\r
408 TK_Beyond(TK_ROTATION);
\r
410 ParseRotation3d(curRotation[currentStack]);
\r
412 TK_Beyond(TK_TRANSLATION);
\r
414 ParseVec3d(curTranslation[currentStack]);
\r
416 // account for global model translation
\r
417 curTranslation[currentStack][1] += g_skelModel.translation[0];
\r
418 curTranslation[currentStack][2] += g_skelModel.translation[1];
\r
419 curTranslation[currentStack][0] += g_skelModel.translation[2];
\r
421 curCorrespondingJoint[currentStack] = -1;
\r
425 for(i = 0; i < numJointsInSkeleton[skelType]; ++i)
\r
429 TK_Beyond(TK_MODEL);
\r
431 TK_BeyondRequire(TK_NAME, TK_STRING);
\r
433 StripTrailingDigits(tk_String, stripped);
\r
435 if(stricmp(stripped, skeletonJointNames[skeletonNameOffsets[skelType]+i]) == 0)
\r
438 TK_Beyond(TK_SCALING);
\r
440 ParseVec3d(curScale[currentStack]);
\r
442 TK_Beyond(TK_ROTATION);
\r
444 ParseRotation3d(curRotation[currentStack]);
\r
446 TK_Beyond(TK_TRANSLATION);
\r
448 ParseVec3d(curTranslation[currentStack]);
\r
450 curCorrespondingJoint[currentStack] = -1;
\r
455 TK_Beyond(TK_SCALING);
\r
457 ParseVec3d(curScale[currentStack]);
\r
459 TK_Beyond(TK_ROTATION);
\r
461 ParseRotation3d(curRotation[currentStack]);
\r
463 jointList[i].rotation[1] = curRotation[currentStack][1];
\r
464 jointList[i].rotation[2] = curRotation[currentStack][2];
\r
465 jointList[i].rotation[0] = curRotation[currentStack][0];
\r
467 TK_Beyond(TK_TRANSLATION);
\r
469 ParseVec3d(curTranslation[currentStack]);
\r
471 // jointList[i].placement.origin[1] = curTranslation[currentStack][1];
\r
472 // jointList[i].placement.origin[2] = curTranslation[currentStack][2];
\r
473 // jointList[i].placement.origin[0] = curTranslation[currentStack][0];
\r
475 jointList[i].placement.origin[1] = 0.0;
\r
476 jointList[i].placement.origin[2] = 0.0;
\r
477 jointList[i].placement.origin[0] = 0.0;
\r
479 jointList[i].placement.direction[1] = 20.0;
\r
480 jointList[i].placement.direction[2] = 0.0;
\r
481 jointList[i].placement.direction[0] = 0.0;
\r
483 jointList[i].placement.up[1] = 0.0;
\r
484 jointList[i].placement.up[2] = 20.0;
\r
485 jointList[i].placement.up[0] = 0.0;
\r
487 curCorrespondingJoint[currentStack] = i;
\r
492 stackSize = currentStack;
\r
495 // rotate the direction and up vectors to correspond to the rotation
\r
496 for(i = 0; i < numJointsInSkeleton[skelType]; ++i)
\r
498 rx = jointList[i].rotation[0]*ANGLE_TO_RAD;
\r
499 ry = jointList[i].rotation[1]*ANGLE_TO_RAD;
\r
500 rz = jointList[i].rotation[2]*ANGLE_TO_RAD;
\r
511 // y-axis rotation for direction
\r
512 x2 = jointList[i].placement.direction[0]*cy+jointList[i].placement.direction[2]*sy;
\r
513 z2 = -jointList[i].placement.direction[0]*sy+jointList[i].placement.direction[2]*cy;
\r
514 jointList[i].placement.direction[0] = x2;
\r
515 jointList[i].placement.direction[2] = z2;
\r
517 // y-axis rotation for up
\r
518 x2 = jointList[i].placement.up[0]*cy+jointList[i].placement.up[2]*sy;
\r
519 z2 = -jointList[i].placement.up[0]*sy+jointList[i].placement.up[2]*cy;
\r
520 jointList[i].placement.up[0] = x2;
\r
521 jointList[i].placement.up[2] = z2;
\r
523 // z-axis rotation for direction
\r
524 x2 = jointList[i].placement.direction[0]*cz-jointList[i].placement.direction[1]*sz;
\r
525 y2 = jointList[i].placement.direction[0]*sz+jointList[i].placement.direction[1]*cz;
\r
526 jointList[i].placement.direction[0] = x2;
\r
527 jointList[i].placement.direction[1] = y2;
\r
529 // z-axis rotation for up
\r
530 x2 = jointList[i].placement.up[0]*cz-jointList[i].placement.up[1]*sz;
\r
531 y2 = jointList[i].placement.up[0]*sz+jointList[i].placement.up[1]*cz;
\r
532 jointList[i].placement.up[0] = x2;
\r
533 jointList[i].placement.up[1] = y2;
\r
535 // x-axis rotation for direction vector
\r
536 y2 = jointList[i].placement.direction[1]*cx-jointList[i].placement.direction[2]*sx;
\r
537 z2 = jointList[i].placement.direction[1]*sx+jointList[i].placement.direction[2]*cx;
\r
538 jointList[i].placement.direction[1] = y2;
\r
539 jointList[i].placement.direction[2] = z2;
\r
541 // x-axis rotation for up vector
\r
542 y2 = jointList[i].placement.up[1]*cx-jointList[i].placement.up[2]*sx;
\r
543 z2 = jointList[i].placement.up[1]*sx+jointList[i].placement.up[2]*cx;
\r
544 jointList[i].placement.up[1] = y2;
\r
545 jointList[i].placement.up[2] = z2;
\r
547 // translate direction to a point in the model
\r
548 jointList[i].placement.direction[0] += jointList[i].placement.origin[0];
\r
549 jointList[i].placement.direction[1] += jointList[i].placement.origin[1];
\r
550 jointList[i].placement.direction[2] += jointList[i].placement.origin[2];
\r
552 // translate up to a point in the model
\r
553 jointList[i].placement.up[0] += jointList[i].placement.origin[0];
\r
554 jointList[i].placement.up[1] += jointList[i].placement.origin[1];
\r
555 jointList[i].placement.up[2] += jointList[i].placement.origin[2];
\r
559 for(i = stackSize - 1; i >= 0; --i)
\r
561 rx = curRotation[i][0]*ANGLE_TO_RAD;
\r
562 ry = curRotation[i][1]*ANGLE_TO_RAD;
\r
563 rz = curRotation[i][2]*ANGLE_TO_RAD;
\r
575 for(j = i; j < stackSize; ++j)
\r
577 if(curCorrespondingJoint[j] != -1)
\r
579 placement = &jointList[curCorrespondingJoint[j]].placement;
\r
581 // y-axis rotation for origin
\r
582 x2 = placement->origin[0]*cy+placement->origin[2]*sy;
\r
583 z2 = -placement->origin[0]*sy+placement->origin[2]*cy;
\r
584 placement->origin[0] = x2;
\r
585 placement->origin[2] = z2;
\r
587 // y-axis rotation for direction
\r
588 x2 = placement->direction[0]*cy+placement->direction[2]*sy;
\r
589 z2 = -placement->direction[0]*sy+placement->direction[2]*cy;
\r
590 placement->direction[0] = x2;
\r
591 placement->direction[2] = z2;
\r
593 // y-axis rotation for up
\r
594 x2 = placement->up[0]*cy+placement->up[2]*sy;
\r
595 z2 = -placement->up[0]*sy+placement->up[2]*cy;
\r
596 placement->up[0] = x2;
\r
597 placement->up[2] = z2;
\r
599 // z-axis rotation for origin
\r
600 x2 = placement->origin[0]*cz-placement->origin[1]*sz;
\r
601 y2 = placement->origin[0]*sz+placement->origin[1]*cz;
\r
602 placement->origin[0] = x2;
\r
603 placement->origin[1] = y2;
\r
605 // z-axis rotation for direction
\r
606 x2 = placement->direction[0]*cz-placement->direction[1]*sz;
\r
607 y2 = placement->direction[0]*sz+placement->direction[1]*cz;
\r
608 placement->direction[0] = x2;
\r
609 placement->direction[1] = y2;
\r
611 // z-axis rotation for up
\r
612 x2 = placement->up[0]*cz-placement->up[1]*sz;
\r
613 y2 = placement->up[0]*sz+placement->up[1]*cz;
\r
614 placement->up[0] = x2;
\r
615 placement->up[1] = y2;
\r
617 // x-axis rotation for origin
\r
618 y2 = placement->origin[1]*cx-placement->origin[2]*sx;
\r
619 z2 = placement->origin[1]*sx+placement->origin[2]*cx;
\r
620 placement->origin[1] = y2;
\r
621 placement->origin[2] = z2;
\r
623 // x-axis rotation for direction vector
\r
624 y2 = placement->direction[1]*cx-placement->direction[2]*sx;
\r
625 z2 = placement->direction[1]*sx+placement->direction[2]*cx;
\r
626 placement->direction[1] = y2;
\r
627 placement->direction[2] = z2;
\r
629 // x-axis rotation for up vector
\r
630 y2 = placement->up[1]*cx-placement->up[2]*sx;
\r
631 z2 = placement->up[1]*sx+placement->up[2]*cx;
\r
632 placement->up[1] = y2;
\r
633 placement->up[2] = z2;
\r
635 // translate origin
\r
636 placement->origin[0] += curTranslation[i][0];
\r
637 placement->origin[1] += curTranslation[i][1];
\r
638 placement->origin[2] += curTranslation[i][2];
\r
640 // translate back to local coord
\r
641 placement->direction[0] += curTranslation[i][0];
\r
642 placement->direction[1] += curTranslation[i][1];
\r
643 placement->direction[2] += curTranslation[i][2];
\r
645 // translate back to local coord
\r
646 placement->up[0] += curTranslation[i][0];
\r
647 placement->up[1] += curTranslation[i][1];
\r
648 placement->up[2] += curTranslation[i][2];
\r
652 // This screwed up and needs to be sorted out!!!
\r
653 // The stack info needs to be written too instead of the jointList for j > numJoints for Skeleton
\r
654 for(j = i-1; j < stackSize-1; ++j)
\r
656 // y-axis rotation for origin
\r
657 x2 = jointList[j].placement.origin[0]*cy+jointList[j].placement.origin[2]*sy;
\r
658 z2 = -jointList[j].placement.origin[0]*sy+jointList[j].placement.origin[2]*cy;
\r
659 jointList[j].placement.origin[0] = x2;
\r
660 jointList[j].placement.origin[2] = z2;
\r
662 // y-axis rotation for direction
\r
663 x2 = jointList[j].placement.direction[0]*cy+jointList[j].placement.direction[2]*sy;
\r
664 z2 = -jointList[j].placement.direction[0]*sy+jointList[j].placement.direction[2]*cy;
\r
665 jointList[j].placement.direction[0] = x2;
\r
666 jointList[j].placement.direction[2] = z2;
\r
668 // y-axis rotation for up
\r
669 x2 = jointList[j].placement.up[0]*cy+jointList[j].placement.up[2]*sy;
\r
670 z2 = -jointList[j].placement.up[0]*sy+jointList[j].placement.up[2]*cy;
\r
671 jointList[j].placement.up[0] = x2;
\r
672 jointList[j].placement.up[2] = z2;
\r
674 // z-axis rotation for origin
\r
675 x2 = jointList[j].placement.origin[0]*cz-jointList[j].placement.origin[1]*sz;
\r
676 y2 = jointList[j].placement.origin[0]*sz+jointList[j].placement.origin[1]*cz;
\r
677 jointList[j].placement.origin[0] = x2;
\r
678 jointList[j].placement.origin[1] = y2;
\r
680 // z-axis rotation for direction
\r
681 x2 = jointList[j].placement.direction[0]*cz-jointList[j].placement.direction[1]*sz;
\r
682 y2 = jointList[j].placement.direction[0]*sz+jointList[j].placement.direction[1]*cz;
\r
683 jointList[j].placement.direction[0] = x2;
\r
684 jointList[j].placement.direction[1] = y2;
\r
686 // z-axis rotation for up
\r
687 x2 = jointList[j].placement.up[0]*cz-jointList[j].placement.up[1]*sz;
\r
688 y2 = jointList[j].placement.up[0]*sz+jointList[j].placement.up[1]*cz;
\r
689 jointList[j].placement.up[0] = x2;
\r
690 jointList[j].placement.up[1] = y2;
\r
692 // x-axis rotation for origin
\r
693 y2 = jointList[j].placement.origin[1]*cx-jointList[j].placement.origin[2]*sx;
\r
694 z2 = jointList[j].placement.origin[1]*sx+jointList[j].placement.origin[2]*cx;
\r
695 jointList[j].placement.origin[1] = y2;
\r
696 jointList[j].placement.origin[2] = z2;
\r
698 // x-axis rotation for direction vector
\r
699 y2 = jointList[j].placement.direction[1]*cx-jointList[j].placement.direction[2]*sx;
\r
700 z2 = jointList[j].placement.direction[1]*sx+jointList[j].placement.direction[2]*cx;
\r
701 jointList[j].placement.direction[1] = y2;
\r
702 jointList[j].placement.direction[2] = z2;
\r
704 // x-axis rotation for up vector
\r
705 y2 = jointList[j].placement.up[1]*cx-jointList[j].placement.up[2]*sx;
\r
706 z2 = jointList[j].placement.up[1]*sx+jointList[j].placement.up[2]*cx;
\r
707 jointList[j].placement.up[1] = y2;
\r
708 jointList[j].placement.up[2] = z2;
\r
710 if(curCorrespondingJoint[j+1] != -1)
\r
712 // translate origin
\r
713 jointList[j].placement.origin[0] += curTranslation[i-1][0];
\r
714 jointList[j].placement.origin[1] += curTranslation[i-1][1];
\r
715 jointList[j].placement.origin[2] += curTranslation[i-1][2];
\r
717 // translate back to local coord
\r
718 jointList[j].placement.direction[0] += curTranslation[i-1][0];
\r
719 jointList[j].placement.direction[1] += curTranslation[i-1][1];
\r
720 jointList[j].placement.direction[2] += curTranslation[i-1][2];
\r
722 // translate back to local coord
\r
723 jointList[j].placement.up[0] += curTranslation[i-1][0];
\r
724 jointList[j].placement.up[1] += curTranslation[i-1][1];
\r
725 jointList[j].placement.up[2] += curTranslation[i-1][2];
\r
732 void LoadModelTransform(char *fileName)
\r
737 char InputFileName[256];
\r
739 dotstart = strrchr(fileName,dot); // Does it already have an extension on the file name?
\r
743 strcpy(InputFileName, fileName);
\r
744 strcat(InputFileName, ".hrc");
\r
745 if((file1 = fopen(InputFileName, "rb")) != NULL)
\r
749 LoadHRCGlobals(InputFileName);
\r
751 printf(" - assuming .HRC\n");
\r
755 Error("\n Could not open file '%s':\n"
\r
756 "No HRC match.\n", fileName);
\r
760 if((file1 = fopen(fileName, "rb")) != NULL)
\r
764 if (strcmp(dotstart,".hrc") == 0 || strcmp(dotstart,".HRC") == 0)
\r
766 LoadHRCGlobals(fileName);
\r
771 Error("Could not open file '%s':\n",fileName);
\r
775 void LoadModelClusters(char *fileName, int **clusterList, int *num_verts, int skelType)
\r
780 char InputFileName[256];
\r
782 dotstart = strrchr(fileName,dot); // Does it already have an extension on the file name?
\r
786 strcpy(InputFileName, fileName);
\r
787 strcat(InputFileName, ".hrc");
\r
788 if((file1 = fopen(InputFileName, "rb")) != NULL)
\r
792 LoadHRCClustered(InputFileName, clusterList, num_verts, skelType);
\r
794 printf(" - assuming .HRC\n");
\r
798 Error("\n Could not open file '%s':\n"
\r
799 "No HRC match.\n", fileName);
\r
803 if((file1 = fopen(fileName, "rb")) != NULL)
\r
807 if (strcmp(dotstart,".hrc") == 0 || strcmp(dotstart,".HRC") == 0)
\r
809 LoadHRCClustered(fileName, clusterList, num_verts, skelType);
\r
814 Error("Could not open file '%s':\n",fileName);
\r
818 void LoadSkeleton(char *fileName, QD_SkeletalJoint_t *jointList, int skelType)
\r
823 char InputFileName[256];
\r
825 dotstart = strrchr(fileName,dot); // Does it already have an extension on the file name?
\r
829 strcpy(InputFileName, fileName);
\r
830 strcat(InputFileName, ".hrc");
\r
831 if((file1 = fopen(InputFileName, "rb")) != NULL)
\r
835 LoadHRCJointList(InputFileName, jointList, skelType);
\r
837 printf(" - assuming .HRC\n");
\r
841 Error("\n Could not open file '%s':\n"
\r
842 "No HRC.\n", fileName);
\r
846 if((file1 = fopen(fileName, "rb")) != NULL)
\r
850 if (strcmp(dotstart,".hrc") == 0 || strcmp(dotstart,".HRC") == 0)
\r
852 LoadHRCJointList(fileName, jointList, skelType);
\r
858 Error("Could not open file '%s':\n",fileName);
\r
867 void GrabSkeletalFrame(char *frame)
\r
873 framefile = FindFrameFile (frame);
\r
875 sprintf (file1, "%s/%s", cdarchive, framefile);
\r
876 ExpandPathAndArchive (file1);
\r
878 sprintf (file1, "%s/%s",cddir, framefile);
\r
880 printf ("Grabbing Skeletal Frame %s\n", file1);
\r
882 fr = &g_frames[fmheader.num_frames - 1]; // last frame read in
\r
884 LoadSkeleton(file1, fr->joints, g_skelModel.type);
\r
892 void GrabModelTransform(char *frame)
\r
898 framefile = FindFrameFile (frame);
\r
900 sprintf (file1, "%s/%s", cdarchive, framefile);
\r
901 ExpandPathAndArchive (file1);
\r
903 sprintf (file1, "%s/%s",cddir, framefile);
\r
905 // printf ("grabbing %s\n", file1);
\r
907 fr = &g_frames[fmheader.num_frames - 1]; // last frame read in
\r
909 LoadModelTransform(file1);
\r
912 void Cmd_FMCluster()
\r
916 GetScriptToken (false);
\r
918 printf ("---------------------\n");
\r
919 sprintf (file1, "%s/%s", cdpartial, token);
\r
920 printf ("%s\n", file1);
\r
922 ExpandPathAndArchive (file1);
\r
924 sprintf (file1, "%s/%s", cddir, token);
\r
926 g_skelModel.clustered = -1;
\r
928 LoadModelClusters(file1, (int **)&g_skelModel.clusters, (int *)&g_skelModel.num_verts, g_skelModel.type);
\r
930 g_skelModel.new_num_verts[0] = g_skelModel.num_verts[0];
\r
932 g_skelModel.clustered = true;
\r
935 void Cmd_FMSkeleton()
\r
937 GetScriptToken (false);
\r
938 g_skelModel.type = atoi(token);
\r
941 void Cmd_FMSkeletalFrame()
\r
943 while (ScriptTokenAvailable())
\r
945 GetScriptToken (false);
\r
948 GetScriptToken (false);
\r
951 if (g_release || g_archive)
\r
953 fmheader.num_frames = 1; // don't skip the writeout
\r
954 GetScriptToken (false);
\r
958 H_printf("#define FRAME_%-16s\t%i\n", token, fmheader.num_frames);
\r
960 GrabModelTransform (token);
\r
962 GrabSkeletalFrame (token);
\r
964 // need to add the up and dir points to the frame bounds here
\r
965 // using AddPointToBounds (ptrivert[index_xyz].v, fr->mins, fr->maxs);
\r
966 // then remove fudge in determining scale on frame write out
\r
970 static void LoadHRCReferences(char *fileName, fmframe_t *fr)
\r
972 #define MAX_STACK 64
\r
974 vec3d_t curTranslation[MAX_STACK], curRotation[MAX_STACK];
\r
975 int curCorrespondingJoint[MAX_STACK];
\r
976 int currentStack, stackSize;
\r
977 double cx, sx, cy, sy, cz, sz;
\r
980 char stripped[SKELETAL_NAME_MAX];
\r
981 Placement_d_t *placement;
\r
984 TK_OpenSource(fileName);
\r
985 TK_FetchRequire(TK_HRCH);
\r
986 TK_FetchRequire(TK_COLON);
\r
987 TK_FetchRequire(TK_SOFTIMAGE);
\r
989 if (RefPointNum <= 0)
\r
990 { // There were no labels indicated in the QDT, so use the hard-coded stuff.
\r
991 refnum = numReferences[g_skelModel.references];
\r
995 refnum = RefPointNum;
\r
998 for(k = 0; k < refnum; ++k)
\r
1002 // Load the root to get translation and initial rotation
\r
1003 // TK_Beyond(TK_MODEL);
\r
1005 while(TK_Search(TK_NAME) != TK_EOF)
\r
1007 TK_Require(TK_STRING);
\r
1009 StripTrailingDigits(tk_String, stripped);
\r
1011 if (RefPointNum == 0)
\r
1012 { // Hard coded refpoint labels
\r
1013 if(stricmp(stripped,
\r
1014 referenceRootNames[referenceRootNameOffsets[g_skelModel.references]+k]) == 0)
\r
1020 { // labels indicated by the QDT
\r
1021 if(stricmp(stripped, RefPointNameList[k]) == 0)
\r
1028 if(tk_Token == TK_EOF)
\r
1030 if (RefPointNum == 0)
\r
1031 { // Hard coded refpoint labels
\r
1032 Error("Bone Chain Root: %s not found\n", referenceRootNames[referenceRootNameOffsets[g_skelModel.references]]);
\r
1035 { // labels indicated by the QDT
\r
1036 Error("Bone Chain Root: %s not found\n", RefPointNameList[k]);
\r
1041 // TK_Beyond(TK_SCALING);
\r
1043 // ParseVec3d(curScale[currentStack]);
\r
1045 TK_Beyond(TK_ROTATION);
\r
1047 ParseRotation3d(curRotation[currentStack]);
\r
1049 TK_Beyond(TK_TRANSLATION);
\r
1051 ParseVec3d(curTranslation[currentStack]);
\r
1053 // account for global model translation
\r
1054 curTranslation[currentStack][1] += g_skelModel.translation[0];
\r
1055 curTranslation[currentStack][2] += g_skelModel.translation[1];
\r
1056 curTranslation[currentStack][0] += g_skelModel.translation[2];
\r
1058 curCorrespondingJoint[currentStack] = -1;
\r
1060 // rjr - this one not needed, as there is also a stack increment 20 lines below???
\r
1061 // ++currentStack;
\r
1063 // Load the joint to get orientation
\r
1064 TK_Beyond(TK_MODEL);
\r
1066 // TK_Beyond(TK_SCALING);
\r
1068 // ParseVec3d(curScale[currentStack]);
\r
1070 TK_Beyond(TK_ROTATION);
\r
1072 ParseRotation3d(curRotation[currentStack]);
\r
1074 // TK_Beyond(TK_TRANSLATION);
\r
1076 // ParseVec3d(curTranslation[currentStack]);
\r
1078 fr->references[k].placement.origin[1] = 0.0;
\r
1079 fr->references[k].placement.origin[2] = 0.0;
\r
1080 fr->references[k].placement.origin[0] = 0.0;
\r
1082 fr->references[k].placement.direction[1] = 20.0;
\r
1083 fr->references[k].placement.direction[2] = 0.0;
\r
1084 fr->references[k].placement.direction[0] = 0.0;
\r
1086 fr->references[k].placement.up[1] = 0.0;
\r
1087 fr->references[k].placement.up[2] = 20.0;
\r
1088 fr->references[k].placement.up[0] = 0.0;
\r
1090 curCorrespondingJoint[currentStack] = k;
\r
1094 stackSize = currentStack;
\r
1096 for(i = stackSize - 1; i >= 0; --i)
\r
1098 rx = curRotation[i][0]*ANGLE_TO_RAD;
\r
1099 ry = curRotation[i][1]*ANGLE_TO_RAD;
\r
1100 rz = curRotation[i][2]*ANGLE_TO_RAD;
\r
1111 for(j = i; j < stackSize; ++j)
\r
1113 if(curCorrespondingJoint[j] != -1)
\r
1115 placement = &fr->references[curCorrespondingJoint[j]].placement;
\r
1117 // y-axis rotation for origin
\r
1118 x2 = placement->origin[0]*cy+placement->origin[2]*sy;
\r
1119 z2 = -placement->origin[0]*sy+placement->origin[2]*cy;
\r
1120 placement->origin[0] = x2;
\r
1121 placement->origin[2] = z2;
\r
1123 // y-axis rotation for direction
\r
1124 x2 = placement->direction[0]*cy+placement->direction[2]*sy;
\r
1125 z2 = -placement->direction[0]*sy+placement->direction[2]*cy;
\r
1126 placement->direction[0] = x2;
\r
1127 placement->direction[2] = z2;
\r
1129 // y-axis rotation for up
\r
1130 x2 = placement->up[0]*cy+placement->up[2]*sy;
\r
1131 z2 = -placement->up[0]*sy+placement->up[2]*cy;
\r
1132 placement->up[0] = x2;
\r
1133 placement->up[2] = z2;
\r
1135 // z-axis rotation for origin
\r
1136 x2 = placement->origin[0]*cz-placement->origin[1]*sz;
\r
1137 y2 = placement->origin[0]*sz+placement->origin[1]*cz;
\r
1138 placement->origin[0] = x2;
\r
1139 placement->origin[1] = y2;
\r
1141 // z-axis rotation for direction
\r
1142 x2 = placement->direction[0]*cz-placement->direction[1]*sz;
\r
1143 y2 = placement->direction[0]*sz+placement->direction[1]*cz;
\r
1144 placement->direction[0] = x2;
\r
1145 placement->direction[1] = y2;
\r
1147 // z-axis rotation for up
\r
1148 x2 = placement->up[0]*cz-placement->up[1]*sz;
\r
1149 y2 = placement->up[0]*sz+placement->up[1]*cz;
\r
1150 placement->up[0] = x2;
\r
1151 placement->up[1] = y2;
\r
1153 // x-axis rotation for origin
\r
1154 y2 = placement->origin[1]*cx-placement->origin[2]*sx;
\r
1155 z2 = placement->origin[1]*sx+placement->origin[2]*cx;
\r
1156 placement->origin[1] = y2;
\r
1157 placement->origin[2] = z2;
\r
1159 // x-axis rotation for direction vector
\r
1160 y2 = placement->direction[1]*cx-placement->direction[2]*sx;
\r
1161 z2 = placement->direction[1]*sx+placement->direction[2]*cx;
\r
1162 placement->direction[1] = y2;
\r
1163 placement->direction[2] = z2;
\r
1165 // x-axis rotation for up vector
\r
1166 y2 = placement->up[1]*cx-placement->up[2]*sx;
\r
1167 z2 = placement->up[1]*sx+placement->up[2]*cx;
\r
1168 placement->up[1] = y2;
\r
1169 placement->up[2] = z2;
\r
1171 // translate origin
\r
1172 placement->origin[0] += curTranslation[i][0];
\r
1173 placement->origin[1] += curTranslation[i][1];
\r
1174 placement->origin[2] += curTranslation[i][2];
\r
1176 // translate back to local coord
\r
1177 placement->direction[0] += curTranslation[i][0];
\r
1178 placement->direction[1] += curTranslation[i][1];
\r
1179 placement->direction[2] += curTranslation[i][2];
\r
1181 // translate back to local coord
\r
1182 placement->up[0] += curTranslation[i][0];
\r
1183 placement->up[1] += curTranslation[i][1];
\r
1184 placement->up[2] += curTranslation[i][2];
\r
1189 printf("%f, %f, %f\n", placement->origin[0], placement->origin[1], placement->origin[2]);
\r
1194 void Cmd_FMReferenced()
\r
1198 GetScriptToken (false);
\r
1199 g_skelModel.references = atoi(token);
\r
1201 // Guess what? Now, we now want a list of strings to look for here instead of a hard-coded list
\r
1202 for (i=0; i<REF_MAX_POINTS; i++)
\r
1204 if (ScriptTokenAvailable())
\r
1205 { // There is yet another reference point waiting.
\r
1206 GetScriptToken(false);
\r
1207 strcpy(RefPointNameList[i], token);
\r
1217 if (RefPointNum > 0)
\r
1219 printf("Searching for %d different reference points.\n", RefPointNum);
\r
1223 printf("Using built-in reference points.\n");
\r
1228 void LoadReferences(char *fileName, fmframe_t *fr)
\r
1233 char InputFileName[256];
\r
1235 dotstart = strrchr(fileName,dot); // Does it already have an extension on the file name?
\r
1239 strcpy(InputFileName, fileName);
\r
1240 strcat(InputFileName, ".hrc");
\r
1241 if((file1 = fopen(InputFileName, "rb")) != NULL)
\r
1245 LoadHRCReferences(InputFileName, fr);
\r
1247 printf(" - assuming .HRC\n");
\r
1251 Error("\n Could not open file '%s':\n"
\r
1252 "No HRC.\n", fileName);
\r
1256 if((file1 = fopen(fileName, "rb")) != NULL)
\r
1260 if (strcmp(dotstart,".hrc") == 0 || strcmp(dotstart,".HRC") == 0)
\r
1262 LoadHRCReferences(fileName, fr);
\r
1268 Error("Could not open file '%s':\n",fileName);
\r
1272 void GrabReferencedFrame(char *frame)
\r
1278 framefile = FindFrameFile (frame);
\r
1280 sprintf (file1, "%s/%s", cdarchive, framefile);
\r
1281 ExpandPathAndArchive (file1);
\r
1283 sprintf (file1, "%s/%s",cddir, framefile);
\r
1285 printf ("Grabbing Referenced %s\n", file1);
\r
1287 fr = &g_frames[fmheader.num_frames - 1]; // last frame read in
\r
1289 LoadReferences(file1, fr);
\r