]> git.xonotic.org Git - xonotic/netradiant.git/blob - tools/quake2/qdata_heretic2/jointed.c
transfer from internal tree r5311 branches/1.4-gpl
[xonotic/netradiant.git] / tools / quake2 / qdata_heretic2 / jointed.c
1 /*\r
2 Copyright (C) 1999-2007 id Software, Inc. and contributors.\r
3 For a list of contributors, see the accompanying CONTRIBUTORS file.\r
4 \r
5 This file is part of GtkRadiant.\r
6 \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
11 \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
16 \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
20 */\r
21 \r
22 #include <assert.h>\r
23 #include <math.h>\r
24 #include "token.h"\r
25 #include "joints.h"\r
26 #include "angles.h"\r
27 #include "inout.h"\r
28 \r
29 char *SKEL_ROOT_NAMES[] =\r
30 {\r
31         "RAVEN_SPINE"\r
32 };\r
33 \r
34 char *SKEL_NAMES[] =\r
35 {\r
36         "RAVEN_WAIST1",\r
37         "RAVEN_WAIST2",\r
38         "RAVEN_NECK"\r
39 };\r
40 \r
41 int NAME_OFFSETS[] =\r
42 {\r
43         0\r
44 };\r
45 \r
46 int numJointsForSkeleton[] = \r
47 {\r
48         NUM_JOINTS_RAVEN,\r
49         NUM_JOINTS_BOX\r
50 };\r
51 \r
52 float g_scaling[3];\r
53 float g_rotation[3];\r
54 float g_translation[3];\r
55 \r
56 //==========================================================================\r
57 //\r
58 // LoadHRCClustered\r
59 //\r
60 //==========================================================================\r
61 \r
62 static void LoadHRCClustered(char *fileName, int **clusterList, int *num_verts, int skelType)\r
63 {\r
64         int i, j;\r
65 \r
66         TK_OpenSource(fileName);\r
67         TK_FetchRequire(TK_HRCH);\r
68         TK_FetchRequire(TK_COLON);\r
69         TK_FetchRequire(TK_SOFTIMAGE);\r
70 \r
71         TK_Beyond(TK_CLUSTERS);\r
72 \r
73         while(TK_Search(TK_CLUSTER_NAME) != TK_EOF)\r
74         {\r
75                 TK_Require(TK_STRING);\r
76 \r
77                 for( i = 0; i < numJointsForSkeleton[skelType]; ++i)\r
78                 {\r
79                         if(stricmp(tk_String, SKEL_NAMES[NAME_OFFSETS[skelType]+i]) == 0)\r
80                         {\r
81                                 i = -i + numJointsForSkeleton[skelType] - 1;\r
82 \r
83                                 TK_BeyondRequire(TK_NUM_CLUSTER_VERTICES, TK_INTNUMBER);\r
84 \r
85                                 num_verts[i+1] = tk_IntNumber;\r
86 \r
87                                 clusterList[i] = (int *) SafeMalloc(num_verts[i+1]*sizeof(int), "LoadHRCClustered");\r
88                                 assert(clusterList[i]);\r
89                                 // currently this function is only called by LoadTriangleListClustered, which in turn is only\r
90                                 // called by Cmd_Base in qdata.  This is where the only call to free for this memory is being made.\r
91 \r
92                                 TK_Beyond(TK_LBRACE);\r
93 \r
94                                 for(j = 0; j < num_verts[i+1]; ++j)\r
95                                 {\r
96                                         TK_Require(TK_INTNUMBER);\r
97                                         clusterList[i][j] = tk_IntNumber;\r
98                                         TK_Fetch();\r
99                                 }\r
100 \r
101                                 break;\r
102                         }\r
103                 }\r
104         }\r
105 \r
106         num_verts[0] = numJointsForSkeleton[skelType];\r
107 }\r
108 \r
109 static void LoadHRCGlobals(char *fileName)\r
110 {\r
111         int i;\r
112 \r
113         TK_OpenSource(fileName);\r
114         TK_FetchRequire(TK_HRCH);\r
115         TK_FetchRequire(TK_COLON);\r
116         TK_FetchRequire(TK_SOFTIMAGE);\r
117         TK_Beyond(TK_MODEL);\r
118 \r
119         TK_Beyond(TK_SCALING);\r
120         for(i = 0; i < 3; i++)\r
121         {\r
122                 TK_Require(TK_FLOATNUMBER);\r
123                 g_scaling[i] = tk_FloatNumber;\r
124                 TK_Fetch();\r
125         }\r
126 \r
127         TK_Beyond(TK_ROTATION);\r
128         for(i = 0; i < 3; i++)\r
129         {\r
130                 TK_Require(TK_FLOATNUMBER);\r
131                 g_rotation[i] = tk_FloatNumber;\r
132                 TK_Fetch();\r
133         }\r
134 \r
135         TK_Beyond(TK_TRANSLATION);\r
136         for(i = 0; i < 3; i++)\r
137         {\r
138                 TK_Require(TK_FLOATNUMBER);\r
139                 g_translation[i] = tk_FloatNumber;\r
140                 TK_Fetch();\r
141         }\r
142 }\r
143 \r
144 static void ParseVec3(vec3_t in)\r
145 {\r
146         TK_Require(TK_FLOATNUMBER);\r
147         in[1] = tk_FloatNumber;\r
148         TK_FetchRequire(TK_FLOATNUMBER);\r
149         in[2] = tk_FloatNumber;\r
150         TK_FetchRequire(TK_FLOATNUMBER);\r
151         in[0] = tk_FloatNumber;\r
152 }\r
153 \r
154 static void ParseRotation3(vec3_t in)\r
155 {\r
156         TK_Require(TK_FLOATNUMBER);\r
157         in[1] = -tk_FloatNumber;\r
158         TK_FetchRequire(TK_FLOATNUMBER);\r
159         in[2] = tk_FloatNumber;\r
160         TK_FetchRequire(TK_FLOATNUMBER);\r
161         in[0] = tk_FloatNumber;\r
162 }\r
163 \r
164 static void ParseTranslation3(vec3_t in)\r
165 {\r
166         TK_Require(TK_FLOATNUMBER);\r
167         in[1] = tk_FloatNumber;\r
168         TK_FetchRequire(TK_FLOATNUMBER);\r
169         in[2] = tk_FloatNumber;\r
170         TK_FetchRequire(TK_FLOATNUMBER);\r
171         in[0] = tk_FloatNumber;\r
172 }\r
173 \r
174 static void LoadHRCJointList(char *fileName, QDataJoint_t *jointList, int skelType)\r
175 {\r
176 #define MAX_STACK 64\r
177         int i, j;\r
178         vec3_t curTranslation[MAX_STACK], curRotation[MAX_STACK], curScale[MAX_STACK];\r
179         int curCorrespondingJoint[MAX_STACK];\r
180         int currentStack = 0, stackSize;\r
181         int baseJoint;\r
182         float cx, sx, cy, sy, cz, sz;\r
183         float rx, ry, rz;\r
184         float x2, y2, z2;\r
185 \r
186 \r
187         TK_OpenSource(fileName);\r
188         TK_FetchRequire(TK_HRCH);\r
189         TK_FetchRequire(TK_COLON);\r
190         TK_FetchRequire(TK_SOFTIMAGE);\r
191 \r
192         TK_Beyond(TK_MODEL);\r
193         TK_Beyond(TK_MODEL);\r
194 \r
195 /*      while(1)\r
196         {\r
197                 TK_Beyond(TK_MODEL);\r
198                 TK_BeyondRequire(TK_NAME, TK_STRING);\r
199 \r
200                 if(_stricmp(tk_String, SKEL_ROOT_NAMES[skelType]) == 0)\r
201                         break;\r
202         }*/\r
203 \r
204         TK_Beyond(TK_SCALING);\r
205 \r
206         ParseVec3(curScale[currentStack]);\r
207 \r
208         TK_Beyond(TK_ROTATION);\r
209 \r
210         ParseRotation3(curRotation[currentStack]);\r
211 \r
212         TK_Beyond(TK_TRANSLATION);\r
213 \r
214         ParseVec3(curTranslation[currentStack]);\r
215 \r
216         // account for global model translation\r
217         curTranslation[currentStack][1] += g_translation[0];\r
218         curTranslation[currentStack][2] += g_translation[1];\r
219         curTranslation[currentStack][0] += g_translation[2];\r
220 \r
221         ++currentStack;\r
222 \r
223         for(i = 0; i < NUM_JOINTS_RAVEN; ++i)\r
224         {\r
225                 while(1)\r
226                 {\r
227                         TK_Beyond(TK_MODEL);\r
228 \r
229 //                      TK_BeyondRequire(TK_NAME, TK_STRING);\r
230 \r
231 //                      if(_stricmp(tk_String, SKEL_NAMES[NAME_OFFSETS[skelType]+i]) == 0)\r
232                                 break;\r
233 \r
234                         TK_Beyond(TK_SCALING);\r
235 \r
236                         ParseVec3(curScale[currentStack]);\r
237 \r
238                         TK_Beyond(TK_ROTATION);\r
239 \r
240                         ParseRotation3(curRotation[currentStack]);\r
241 \r
242                         TK_Beyond(TK_TRANSLATION);\r
243 \r
244                         ParseVec3(curTranslation[currentStack]);\r
245 \r
246                         curCorrespondingJoint[currentStack] = -1;\r
247 \r
248                         ++currentStack;\r
249                 }\r
250 \r
251                 TK_Beyond(TK_SCALING);\r
252 \r
253                 ParseVec3(curScale[currentStack]);\r
254 \r
255                 TK_Beyond(TK_ROTATION);\r
256 \r
257                 ParseRotation3(curRotation[currentStack]);\r
258 \r
259                 jointList[i].rotation[1] = curRotation[currentStack][1];\r
260                 jointList[i].rotation[2] = curRotation[currentStack][2];\r
261                 jointList[i].rotation[0] = curRotation[currentStack][0];\r
262 \r
263                 TK_Beyond(TK_TRANSLATION);\r
264 \r
265                 ParseVec3(curTranslation[currentStack]);\r
266 \r
267                 jointList[i].placement.origin[1] = curTranslation[currentStack][1];\r
268                 jointList[i].placement.origin[2] = curTranslation[currentStack][2];\r
269                 jointList[i].placement.origin[0] = curTranslation[currentStack][0];\r
270 \r
271                 jointList[i].placement.direction[1] = 7.5;\r
272                 jointList[i].placement.direction[2] = 0.0;\r
273                 jointList[i].placement.direction[0] = 0.0;\r
274 \r
275                 jointList[i].placement.up[1] = 0.0;\r
276                 jointList[i].placement.up[2] = 7.5;\r
277                 jointList[i].placement.up[0] = 0.0;\r
278 \r
279                 curCorrespondingJoint[currentStack] = i;\r
280 \r
281                 ++currentStack;\r
282         }\r
283 \r
284         stackSize = currentStack;\r
285 \r
286         for(i = 0; i < NUM_JOINTS_RAVEN; ++i)\r
287         {\r
288                 rx = jointList[i].rotation[0]*ANGLE_TO_RAD;\r
289                 ry = jointList[i].rotation[1]*ANGLE_TO_RAD;\r
290                 rz = jointList[i].rotation[2]*ANGLE_TO_RAD;\r
291 \r
292                 cx = cos(rx);\r
293                 sx = sin(rx);\r
294 \r
295                 cy = cos(ry);\r
296                 sy = sin(ry);\r
297 \r
298                 cz = cos(rz);\r
299                 sz = sin(rz);\r
300 \r
301                 // y-axis rotation for direction\r
302                 x2 = jointList[i].placement.direction[0]*cy+jointList[i].placement.direction[2]*sy;\r
303                 z2 = -jointList[i].placement.direction[0]*sy+jointList[i].placement.direction[2]*cy;\r
304                 jointList[i].placement.direction[0] = x2;\r
305                 jointList[i].placement.direction[2] = z2;\r
306 \r
307                 // y-axis rotation for up\r
308                 x2 = jointList[i].placement.up[0]*cy+jointList[i].placement.up[2]*sy;\r
309                 z2 = -jointList[i].placement.up[0]*sy+jointList[i].placement.up[2]*cy;\r
310                 jointList[i].placement.up[0] = x2;\r
311                 jointList[i].placement.up[2] = z2;\r
312 \r
313                 // z-axis rotation for direction\r
314                 x2 = jointList[i].placement.direction[0]*cz-jointList[i].placement.direction[1]*sz;\r
315                 y2 = jointList[i].placement.direction[0]*sz+jointList[i].placement.direction[1]*cz;\r
316                 jointList[i].placement.direction[0] = x2;\r
317                 jointList[i].placement.direction[1] = y2;\r
318 \r
319                 // z-axis rotation for up\r
320                 x2 = jointList[i].placement.up[0]*cz-jointList[i].placement.up[1]*sz;\r
321                 y2 = jointList[i].placement.up[0]*sz+jointList[i].placement.up[1]*cz;\r
322                 jointList[i].placement.up[0] = x2;\r
323                 jointList[i].placement.up[1] = y2;\r
324 \r
325                 // x-axis rotation for direction vector\r
326                 y2 = jointList[i].placement.direction[1]*cx-jointList[i].placement.direction[2]*sx;\r
327                 z2 = jointList[i].placement.direction[1]*sx+jointList[i].placement.direction[2]*cx;\r
328                 jointList[i].placement.direction[1] = y2;\r
329                 jointList[i].placement.direction[2] = z2;\r
330 \r
331                 // x-axis rotation for up vector\r
332                 y2 = jointList[i].placement.up[1]*cx-jointList[i].placement.up[2]*sx;\r
333                 z2 = jointList[i].placement.up[1]*sx+jointList[i].placement.up[2]*cx;\r
334                 jointList[i].placement.up[1] = y2;\r
335                 jointList[i].placement.up[2] = z2;\r
336 \r
337                 // translate to position in model\r
338                 jointList[i].placement.direction[0] += jointList[i].placement.origin[0];\r
339                 jointList[i].placement.direction[1] += jointList[i].placement.origin[1];\r
340                 jointList[i].placement.direction[2] += jointList[i].placement.origin[2];\r
341 \r
342                 // translate to position in model\r
343                 jointList[i].placement.up[0] += jointList[i].placement.origin[0];\r
344                 jointList[i].placement.up[1] += jointList[i].placement.origin[1];\r
345                 jointList[i].placement.up[2] += jointList[i].placement.origin[2];\r
346         }\r
347 \r
348         baseJoint = NUM_JOINTS_RAVEN;\r
349 \r
350         for(i = stackSize/*NUM_JOINTS_RAVEN*/ - 1; i > 0; --i)\r
351         {\r
352 \r
353                 rx = curRotation[i-1][0]*ANGLE_TO_RAD;\r
354                 ry = curRotation[i-1][1]*ANGLE_TO_RAD;\r
355                 rz = curRotation[i-1][2]*ANGLE_TO_RAD;\r
356 \r
357                 cx = cos(rx);\r
358                 sx = sin(rx);\r
359 \r
360                 cy = cos(ry);\r
361                 sy = sin(ry);\r
362 \r
363                 cz = cos(rz);\r
364                 sz = sin(rz);\r
365 \r
366                 for(j = i-1; j < stackSize-1; ++j)\r
367                 {\r
368                         // y-axis rotation for origin\r
369                         x2 = jointList[j].placement.origin[0]*cy+jointList[j].placement.origin[2]*sy;\r
370                         z2 = -jointList[j].placement.origin[0]*sy+jointList[j].placement.origin[2]*cy;\r
371                         jointList[j].placement.origin[0] = x2;\r
372                         jointList[j].placement.origin[2] = z2;\r
373 \r
374                         // y-axis rotation for direction\r
375                         x2 = jointList[j].placement.direction[0]*cy+jointList[j].placement.direction[2]*sy;\r
376                         z2 = -jointList[j].placement.direction[0]*sy+jointList[j].placement.direction[2]*cy;\r
377                         jointList[j].placement.direction[0] = x2;\r
378                         jointList[j].placement.direction[2] = z2;\r
379 \r
380                         // y-axis rotation for up\r
381                         x2 = jointList[j].placement.up[0]*cy+jointList[j].placement.up[2]*sy;\r
382                         z2 = -jointList[j].placement.up[0]*sy+jointList[j].placement.up[2]*cy;\r
383                         jointList[j].placement.up[0] = x2;\r
384                         jointList[j].placement.up[2] = z2;\r
385 \r
386                         // z-axis rotation for origin\r
387                         x2 = jointList[j].placement.origin[0]*cz-jointList[j].placement.origin[1]*sz;\r
388                         y2 = jointList[j].placement.origin[0]*sz+jointList[j].placement.origin[1]*cz;\r
389                         jointList[j].placement.origin[0] = x2;\r
390                         jointList[j].placement.origin[1] = y2;\r
391 \r
392                         // z-axis rotation for direction\r
393                         x2 = jointList[j].placement.direction[0]*cz-jointList[j].placement.direction[1]*sz;\r
394                         y2 = jointList[j].placement.direction[0]*sz+jointList[j].placement.direction[1]*cz;\r
395                         jointList[j].placement.direction[0] = x2;\r
396                         jointList[j].placement.direction[1] = y2;\r
397 \r
398                         // z-axis rotation for up\r
399                         x2 = jointList[j].placement.up[0]*cz-jointList[j].placement.up[1]*sz;\r
400                         y2 = jointList[j].placement.up[0]*sz+jointList[j].placement.up[1]*cz;\r
401                         jointList[j].placement.up[0] = x2;\r
402                         jointList[j].placement.up[1] = y2;\r
403 \r
404                         // x-axis rotation for origin\r
405                         y2 = jointList[j].placement.origin[1]*cx-jointList[j].placement.origin[2]*sx;\r
406                         z2 = jointList[j].placement.origin[1]*sx+jointList[j].placement.origin[2]*cx;\r
407                         jointList[j].placement.origin[1] = y2;\r
408                         jointList[j].placement.origin[2] = z2;\r
409 \r
410                         // x-axis rotation for direction vector\r
411                         y2 = jointList[j].placement.direction[1]*cx-jointList[j].placement.direction[2]*sx;\r
412                         z2 = jointList[j].placement.direction[1]*sx+jointList[j].placement.direction[2]*cx;\r
413                         jointList[j].placement.direction[1] = y2;\r
414                         jointList[j].placement.direction[2] = z2;\r
415 \r
416                         // x-axis rotation for up vector\r
417                         y2 = jointList[j].placement.up[1]*cx-jointList[j].placement.up[2]*sx;\r
418                         z2 = jointList[j].placement.up[1]*sx+jointList[j].placement.up[2]*cx;\r
419                         jointList[j].placement.up[1] = y2;\r
420                         jointList[j].placement.up[2] = z2;\r
421 \r
422                         if(curCorrespondingJoint[j+1] != -1)\r
423                         {\r
424                                 // translate origin\r
425                                 jointList[j].placement.origin[0] += curTranslation[i-1][0];\r
426                                 jointList[j].placement.origin[1] += curTranslation[i-1][1];\r
427                                 jointList[j].placement.origin[2] += curTranslation[i-1][2];\r
428 \r
429                                 // translate back to local coord\r
430                                 jointList[j].placement.direction[0] += curTranslation[i-1][0];\r
431                                 jointList[j].placement.direction[1] += curTranslation[i-1][1];\r
432                                 jointList[j].placement.direction[2] += curTranslation[i-1][2];\r
433 \r
434                                 // translate back to local coord\r
435                                 jointList[j].placement.up[0] += curTranslation[i-1][0];\r
436                                 jointList[j].placement.up[1] += curTranslation[i-1][1];\r
437                                 jointList[j].placement.up[2] += curTranslation[i-1][2];\r
438                         }\r
439                 }\r
440         }\r
441 }\r
442 \r
443 void LoadGlobals(char *fileName)\r
444 {\r
445         FILE *file1;\r
446     int dot = '.';\r
447         char *dotstart;\r
448         char    InputFileName[256];\r
449 \r
450         dotstart = strrchr(fileName,dot); // Does it already have an extension on the file name?\r
451 \r
452         if (!dotstart)\r
453         {\r
454                 strcpy(InputFileName, fileName);\r
455                 strcat(InputFileName, ".hrc");\r
456                 if((file1 = fopen(InputFileName, "rb")) != NULL)\r
457                 {\r
458                         fclose(file1);\r
459 \r
460                         LoadHRCGlobals(InputFileName);\r
461 \r
462                         printf(" - assuming .HRC\n");\r
463                         return;\r
464                 }\r
465 \r
466                 Error("\n Could not open file '%s':\n"\r
467                         "No HRC match.\n", fileName);\r
468         }\r
469         else\r
470         {\r
471                 if((file1 = fopen(fileName, "rb")) != NULL)\r
472                 {\r
473                         printf("\n");\r
474                         fclose(file1);\r
475                         if (strcmp(dotstart,".hrc") == 0 || strcmp(dotstart,".HRC") == 0)\r
476                         {\r
477                                 LoadHRCGlobals(fileName);\r
478                                 return;\r
479                         }\r
480                 }\r
481 \r
482                 Error("Could not open file '%s':\n",fileName);\r
483         }\r
484 }\r
485 \r
486 void LoadClusters(char *fileName, int **clusterList, int *num_verts, int skelType)\r
487 {\r
488         FILE *file1;\r
489     int dot = '.';\r
490         char *dotstart;\r
491         char    InputFileName[256];\r
492 \r
493         dotstart = strrchr(fileName,dot); // Does it already have an extension on the file name?\r
494 \r
495         if (!dotstart)\r
496         {\r
497                 strcpy(InputFileName, fileName);\r
498                 strcat(InputFileName, ".hrc");\r
499                 if((file1 = fopen(InputFileName, "rb")) != NULL)\r
500                 {\r
501                         fclose(file1);\r
502 \r
503                         LoadHRCClustered(InputFileName, clusterList, num_verts, skelType);\r
504 \r
505                         printf(" - assuming .HRC\n");\r
506                         return;\r
507                 }\r
508 \r
509                 Error("\n Could not open file '%s':\n"\r
510                         "No HRC match.\n", fileName);\r
511         }\r
512         else\r
513         {\r
514                 if((file1 = fopen(fileName, "rb")) != NULL)\r
515                 {\r
516                         printf("\n");\r
517                         fclose(file1);\r
518                         if (strcmp(dotstart,".hrc") == 0 || strcmp(dotstart,".HRC") == 0)\r
519                         {\r
520                                 LoadHRCClustered(fileName, clusterList, num_verts, skelType);\r
521                                 return;\r
522                         }\r
523                 }\r
524 \r
525                 Error("Could not open file '%s':\n",fileName);\r
526         }\r
527 }\r
528 \r
529 void LoadJointList(char *fileName, QDataJoint_t *jointList, int skelType)\r
530 {\r
531         FILE *file1;\r
532     int dot = '.';\r
533         char *dotstart;\r
534         char    InputFileName[256];\r
535 \r
536         dotstart = strrchr(fileName,dot); // Does it already have an extension on the file name?\r
537 \r
538         if (!dotstart)\r
539         {\r
540                 strcpy(InputFileName, fileName);\r
541                 strcat(InputFileName, ".hrc");\r
542                 if((file1 = fopen(InputFileName, "rb")) != NULL)\r
543                 {\r
544                         fclose(file1);\r
545 \r
546                         LoadHRCJointList(InputFileName, jointList, skelType);\r
547 \r
548                         printf(" - assuming .HRC\n");\r
549                         return;\r
550                 }\r
551 \r
552                 Error("\n Could not open file '%s':\n"\r
553                         "No HRC.\n", fileName);\r
554         }\r
555         else\r
556         {\r
557                 if((file1 = fopen(fileName, "rb")) != NULL)\r
558                 {\r
559                         printf("\n");\r
560                         fclose(file1);\r
561                         if (strcmp(dotstart,".hrc") == 0 || strcmp(dotstart,".HRC") == 0)\r
562                         {\r
563                                 LoadHRCJointList(fileName, jointList, skelType);\r
564 \r
565                                 return;\r
566                         }\r
567                 }\r
568 \r
569                 Error("Could not open file '%s':\n",fileName);\r
570         }\r
571 }\r
572 \r