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