1 /*
2  * Skeleton.cpp
3  * Copyright (C) 2007 by Bryan Duff <duff0097@gmail.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18  * USA
19  */
20 /**> HEADER FILES <**/
21 #include "Skeleton.h"
22 #include "Serialize.h"
23 
24 extern double multiplier;
25 extern unsigned int gSourceID[100];
26 extern unsigned int gSampleSet[100];
27 extern int visions;
28 extern Camera camera;
29 extern float soundscalefactor;
30 
31 extern XYZ vel;
32 extern XYZ midp;
33 extern XYZ newpoint1, newpoint2;
34 
35 extern float oldlength;
36 extern float relaxlength;
37 
38 extern float friction;
39 extern int numrepeats;
40 extern float groundlevel;
41 extern float offset;
42 extern XYZ impact;
43 extern XYZ overpoint;
44 extern XYZ underpoint;
45 extern int whichtri;
46 extern XYZ normalrotated;
47 extern bool groundish;
48 
49 
DoConstraint()50 void Joint::DoConstraint()
51 {
52 
53   if(hasparent) {
54     //Find midpoint
55     midp = (position + parent->position) / 2;
56     //Find vector from midpoint to second vector
57     vel = parent->position - midp;
58     //Change to unit vector
59     Normalise(&vel);
60     //Apply velocity change
61     velocity += ((midp - vel * length / 2) - position);
62     parent->velocity += ((midp + vel * length / 2) - parent->position);
63     //Move child point to within certain distance of parent point
64     if(!locked)
65       position = midp - vel * length / 2;
66     if(!parent->locked)
67       parent->position = midp + vel * length / 2;
68   }
69 }
70 
DoConstraint(int broken)71 void Muscle::DoConstraint(int broken)
72 {
73   oldlength = length;
74   relaxlength = findDistance(parent1->position, parent2->position);
75 
76   if(type == boneconnect)
77     strength = 1;
78   if(type == constraint)
79     strength = 0;
80 
81   if(strength < 0)
82     strength = 0;
83   if(strength > 1)
84     strength = 1;
85 
86   length -=
87       (length - relaxlength) * (1 - strength) * multiplier * multiplier * 10000;
88   length -=
89       (length - targetlength) * (strength) * multiplier * multiplier * 10000;
90   if(strength == 0)
91     length = relaxlength;
92 
93   if((relaxlength - length > 0 && relaxlength - oldlength < 0)
94      || (relaxlength - length < 0 && relaxlength - oldlength > 0))
95     length = relaxlength;
96 
97   if(length < minlength)
98     length = minlength;
99   if(length > maxlength && !broken)
100     length = maxlength;
101 
102   //Find midpoint
103   midp = (parent1->position + parent2->position) / 2;
104   //Find vector from midpoint to second vector
105   vel = parent2->position - midp;
106   //Change to unit vector
107   Normalise(&vel);
108   //Apply velocity change
109   newpoint1 = midp - vel * length / 2;
110   newpoint2 = midp + vel * length / 2;
111   parent1->velocity += (newpoint1 - parent1->position);
112   parent2->velocity += (newpoint2 - parent2->position);
113   //Move child point to within certain distance of parent point
114   if(!parent1->locked)
115     parent1->position = newpoint1;
116   if(!parent2->locked)
117     parent2->position = newpoint2;
118 }
119 
DoConstraints()120 void Skeleton::DoConstraints()
121 {
122   numrepeats = 3;
123 
124   for(int j = 0; j < numrepeats; j++) {
125     for(int i = 0; i < num_joints; i++) {
126       joints[i].DoConstraint();
127     }
128   }
129 }
130 
DoConstraints(Model * collide,XYZ * move,float rotation)131 void Skeleton::DoConstraints(Model * collide, XYZ * move, float rotation)
132 {
133   friction = 20;
134   numrepeats = 2;
135   groundlevel = 0;
136 
137   move->y += .35;
138 
139   for(int j = 0; j < numrepeats; j++) {
140     for(int i = 0; i < num_joints; i++) {
141       if(joints[i].existing || i == jointlabels[lefthand]
142          || i == jointlabels[righthand]) {
143         //Length constraints
144         joints[i].DoConstraint();
145         //Ground constraint
146         offset = 0;
147         overpoint = joints[i].position;
148         overpoint.y += 10;
149         underpoint = joints[i].position;
150         underpoint.y -= offset;
151         whichtri =
152             collide->LineCheck2(overpoint, underpoint, &impact, *move,
153                                 rotation);
154         if(collide->normals[whichtri].y <= .8)
155           whichtri =
156               collide->LineCheck2(joints[i].realoldposition, joints[i].position,
157                                   &impact, *move, rotation);
158         if(joints[i].position.y <= groundlevel + offset || whichtri != -1) {
159           if(whichtri == -1
160              || (whichtri != -1 && collide->normals[whichtri].y > .8)) {
161             if(whichtri == -1)
162               joints[i].position.y = groundlevel + offset;
163             if(whichtri != -1) {
164               joints[i].position = impact;
165               joints[i].position.y += offset;
166             }
167             joints[i].velocity.y *= -.3;
168             joints[i].velocity.x *= .3;
169             joints[i].velocity.z *= .3;
170           }
171           offset = .2;
172           if(whichtri != -1 && collide->normals[whichtri].y <= .8) {
173             normalrotated =
174                 DoRotation(collide->normals[whichtri], 0, rotation, 0);
175             joints[i].position = impact + normalrotated * offset;
176             ReflectVector(&joints[i].velocity, &normalrotated);
177             joints[i].velocity *= .3;
178           }
179           if(broken <= 1) {
180             XYZ avgvelocity;
181             avgvelocity = 0;
182             float gLoc[3];
183             ALint tempint;
184             for(int k = 0; k < num_joints; k++) {
185               avgvelocity += joints[k].velocity;
186             }
187             avgvelocity /= num_joints;
188             if(joints[i].label == head
189                && (findLengthfast(joints[i].velocity) > 2
190                    || findLengthfast(avgvelocity) > 2)) {
191               avgvelocity += joints[i].velocity;
192               gLoc[0] = joints[i].position.x / soundscalefactor;
193               gLoc[1] = joints[i].position.y / soundscalefactor;
194               gLoc[2] = joints[i].position.z / soundscalefactor;
195 #ifdef DEBIAN_NEEDS_TO_UPDATE_THEIR_OPENAL
196               alGetSourceiv(gSourceID[headlandsound], AL_SOURCE_STATE,
197                             &tempint);
198 #else
199               alGetSourcei(gSourceID[headlandsound], AL_SOURCE_STATE, &tempint);
200 #endif
201               if(tempint != AL_PLAYING) {
202                 alSourcef(gSourceID[headlandsound], AL_MIN_GAIN,
203                           ALfloat(findLengthfast(avgvelocity) * 2 /
204                                   findDistancefast(joints[i].position,
205                                                    camera.position) *
206                                   soundscalefactor * 2));
207                 alSourcef(gSourceID[headlandsound], AL_MAX_GAIN,
208                           ALfloat(findLengthfast(avgvelocity) * 2 /
209                                   findDistancefast(joints[i].position,
210                                                    camera.position) *
211                                   soundscalefactor * 2));
212                 alSourcefv(gSourceID[headlandsound], AL_POSITION, gLoc);
213                 alSourcePlay(gSourceID[headlandsound]);
214               }
215             }
216             avgvelocity = 0;
217             for(int k = 0; k < num_joints; k++) {
218               avgvelocity += joints[k].velocity;
219             }
220             avgvelocity /= num_joints;
221             if((joints[i].label == abdomen)
222                && (findLengthfast(joints[i].velocity) > 2
223                    || findLengthfast(avgvelocity) > 2)) {
224               avgvelocity += joints[i].velocity;
225               gLoc[0] = joints[i].position.x / soundscalefactor;
226               gLoc[1] = joints[i].position.y / soundscalefactor;
227               gLoc[2] = joints[i].position.z / soundscalefactor;
228 #ifdef DEBIAN_NEEDS_TO_UPDATE_THEIR_OPENAL
229               alGetSourceiv(gSourceID[bodylandsound], AL_SOURCE_STATE,
230                             &tempint);
231 #else
232               alGetSourcei(gSourceID[bodylandsound], AL_SOURCE_STATE, &tempint);
233 #endif
234               if(tempint != AL_PLAYING) {
235                 alSourcef(gSourceID[bodylandsound], AL_MIN_GAIN,
236                           ALfloat(findLengthfast(joints[i].velocity) * 1 /
237                                   findDistancefast(joints[i].position,
238                                                    camera.position) *
239                                   soundscalefactor * 2));
240                 alSourcef(gSourceID[bodylandsound], AL_MAX_GAIN,
241                           ALfloat(findLengthfast(joints[i].velocity) * 1 /
242                                   findDistancefast(joints[i].position,
243                                                    camera.position) *
244                                   soundscalefactor * 2));
245                 alSourcefv(gSourceID[bodylandsound], AL_POSITION, gLoc);
246                 alSourcePlay(gSourceID[bodylandsound]);
247               }
248             }
249           }
250         }
251       }
252     }
253     if(num_muscles)
254       for(int i = 0; i < num_muscles; i++) {
255         //Length constraints
256         muscles[i].DoConstraint(broken);
257       }
258   }
259 
260   for(int i = 0; i < num_joints; i++) {
261     joints[i].realoldposition = joints[i].position;
262   }
263 
264   //Add velocity
265   for(int i = 0; i < num_joints; i++) {
266     if(joints[i].existing || i == jointlabels[lefthand]
267        || i == jointlabels[righthand])
268       joints[i].position = joints[i].position + joints[i].velocity * multiplier;
269   }
270 }
271 
DoGravity()272 void Skeleton::DoGravity()
273 {
274   for(int i = 0; i < num_joints; i++) {
275     joints[i].velocity.y += gravity * multiplier;
276   }
277 }
278 
Draw(int muscleview)279 void Skeleton::Draw(int muscleview)
280 {
281   float jointcolor[4];
282 
283   if(muscleview != 2) {
284     jointcolor[0] = 0;
285     jointcolor[1] = 0;
286     jointcolor[2] = .5;
287     jointcolor[3] = 1;
288   }
289 
290   if(muscleview == 2) {
291     jointcolor[0] = 0;
292     jointcolor[1] = 0;
293     jointcolor[2] = 0;
294     jointcolor[3] = .5;
295   }
296   //Calc motionblur-ness
297   for(int i = 0; i < num_joints; i++) {
298     joints[i].oldposition = joints[i].position;
299     joints[i].blurred =
300         findDistance(joints[i].position, joints[i].oldposition) * 100;
301     if(joints[i].blurred < 1)
302       joints[i].blurred = 1;
303   }
304 
305   //Do Motionblur
306   glDepthMask(0);
307   glEnable(GL_BLEND);
308   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
309   glBegin(GL_QUADS);
310   for(int i = 0; i < num_joints; i++) {
311     if(joints[i].hasparent) {
312       glColor4f(jointcolor[0], jointcolor[1], jointcolor[2],
313                 jointcolor[3] / joints[i].blurred);
314       glVertex3f(joints[i].position.x, joints[i].position.y,
315                  joints[i].position.z);
316       glColor4f(jointcolor[0], jointcolor[1], jointcolor[2],
317                 jointcolor[3] / joints[i].parent->blurred);
318       glVertex3f(joints[i].parent->position.x, joints[i].parent->position.y,
319                  joints[i].parent->position.z);
320       glColor4f(jointcolor[0], jointcolor[1], jointcolor[2],
321                 jointcolor[3] / joints[i].parent->blurred);
322       glVertex3f(joints[i].parent->oldposition.x,
323                  joints[i].parent->oldposition.y,
324                  joints[i].parent->oldposition.z);
325       glColor4f(jointcolor[0], jointcolor[1], jointcolor[2],
326                 jointcolor[3] / joints[i].blurred);
327       glVertex3f(joints[i].oldposition.x, joints[i].oldposition.y,
328                  joints[i].oldposition.z);
329     }
330   }
331   for(int i = 0; i < num_muscles; i++) {
332     if(muscles[i].type == boneconnect) {
333       glColor4f(jointcolor[0], jointcolor[1], jointcolor[2],
334                 jointcolor[3] / muscles[i].parent2->blurred);
335       glVertex3f(muscles[i].parent1->position.x, muscles[i].parent1->position.y,
336                  muscles[i].parent1->position.z);
337       glColor4f(jointcolor[0], jointcolor[1], jointcolor[2],
338                 jointcolor[3] / muscles[i].parent2->blurred);
339       glVertex3f(muscles[i].parent2->position.x, muscles[i].parent2->position.y,
340                  muscles[i].parent2->position.z);
341       glColor4f(jointcolor[0], jointcolor[1], jointcolor[2],
342                 jointcolor[3] / muscles[i].parent2->blurred);
343       glVertex3f(muscles[i].parent2->oldposition.x,
344                  muscles[i].parent2->oldposition.y,
345                  muscles[i].parent2->oldposition.z);
346       glColor4f(jointcolor[0], jointcolor[1], jointcolor[2],
347                 jointcolor[3] / muscles[i].parent1->blurred);
348       glVertex3f(muscles[i].parent1->oldposition.x,
349                  muscles[i].parent1->oldposition.y,
350                  muscles[i].parent1->oldposition.z);
351     }
352   }
353   glEnd();
354 
355   glBegin(GL_LINES);
356   for(int i = 0; i < num_joints; i++) {
357     if(joints[i].hasparent) {
358       glColor4f(jointcolor[0], jointcolor[1], jointcolor[2],
359                 jointcolor[3] / joints[i].blurred);
360       glVertex3f(joints[i].position.x, joints[i].position.y,
361                  joints[i].position.z);
362       glColor4f(jointcolor[0], jointcolor[1], jointcolor[2],
363                 jointcolor[3] / joints[i].parent->blurred);
364       glVertex3f(joints[i].parent->position.x, joints[i].parent->position.y,
365                  joints[i].parent->position.z);
366     }
367   }
368   for(int i = 0; i < num_muscles; i++) {
369     if(muscles[i].type == boneconnect) {
370       glColor4f(jointcolor[0], jointcolor[1], jointcolor[2],
371                 jointcolor[3] / muscles[i].parent1->blurred);
372       glVertex3f(muscles[i].parent1->position.x, muscles[i].parent1->position.y,
373                  muscles[i].parent1->position.z);
374       glColor4f(jointcolor[0], jointcolor[1], jointcolor[2],
375                 jointcolor[3] / muscles[i].parent2->blurred);
376       glVertex3f(muscles[i].parent2->position.x, muscles[i].parent2->position.y,
377                  muscles[i].parent2->position.z);
378     }
379   }
380   glColor3f(.6, .6, 0);
381   if(muscleview == 1)
382     for(int i = 0; i < num_muscles; i++) {
383       if(muscles[i].type != boneconnect) {
384         glVertex3f(muscles[i].parent1->position.x,
385                    muscles[i].parent1->position.y,
386                    muscles[i].parent1->position.z);
387         glVertex3f(muscles[i].parent2->position.x,
388                    muscles[i].parent2->position.y,
389                    muscles[i].parent2->position.z);
390       }
391     }
392   glEnd();
393 
394   if(muscleview != 2) {
395     glPointSize(3);
396     glBegin(GL_POINTS);
397     for(int i = 0; i < num_joints; i++) {
398       if(i != selected)
399         glColor4f(0, 0, .5, 1);
400       if(i == selected)
401         glColor4f(1, 1, 0, 1);
402       if(joints[i].locked && i != selected)
403         glColor4f(1, 0, 0, 1);
404       glVertex3f(joints[i].position.x, joints[i].position.y,
405                  joints[i].position.z);
406     }
407     glEnd();
408   }
409   //Set old position to current position
410   if(muscleview == 2)
411     for(int i = 0; i < num_joints; i++) {
412       joints[i].oldposition = joints[i].position;
413     }
414   glDepthMask(1);
415 }
416 
AddJoint(float x,float y,float z,int which)417 void Skeleton::AddJoint(float x, float y, float z, int which)
418 {
419   if(num_joints < max_joints - 1) {
420     joints[num_joints].velocity = 0;
421     joints[num_joints].position.x = x;
422     joints[num_joints].position.y = y;
423     joints[num_joints].position.z = z;
424     joints[num_joints].locked = 0;
425 
426     if(which >= num_joints || which < 0)
427       joints[num_joints].hasparent = 0;
428     if(which < num_joints && which >= 0) {
429       joints[num_joints].parent = &joints[which];
430       joints[num_joints].hasparent = 1;
431       joints[num_joints].length =
432           findDistance(joints[num_joints].position,
433                        joints[num_joints].parent->position);
434     }
435     num_joints++;
436   }
437 }
438 
DeleteJoint(int whichjoint)439 void Skeleton::DeleteJoint(int whichjoint)
440 {
441   if(whichjoint < num_joints && whichjoint >= 0) {
442     for(int i = 0; i < num_muscles; i++) {
443       while(muscles[i].parent1 == &joints[whichjoint] && i < num_muscles)
444         DeleteMuscle(i);
445       while(muscles[i].parent2 == &joints[whichjoint] && i < num_muscles)
446         DeleteMuscle(i);
447     }
448     for(int i = 0; i < num_joints; i++) {
449       if(joints[i].parent == &joints[whichjoint])
450         joints[i].hasparent = 0;
451     }
452     joints[whichjoint].hasparent = 0;
453   }
454 }
455 
DeleteMuscle(int whichmuscle)456 void Skeleton::DeleteMuscle(int whichmuscle)
457 {
458   if(whichmuscle < num_muscles) {
459     muscles[whichmuscle].minlength = muscles[num_muscles - 1].minlength;
460     muscles[whichmuscle].maxlength = muscles[num_muscles - 1].maxlength;
461     muscles[whichmuscle].strength = muscles[num_muscles - 1].strength;
462     muscles[whichmuscle].parent1 = muscles[num_muscles - 1].parent1;
463     muscles[whichmuscle].parent2 = muscles[num_muscles - 1].parent2;
464     muscles[whichmuscle].length = muscles[num_muscles - 1].length;
465     muscles[whichmuscle].visible = muscles[num_muscles - 1].visible;
466     muscles[whichmuscle].type = muscles[num_muscles - 1].type;
467     muscles[whichmuscle].targetlength = muscles[num_muscles - 1].targetlength;
468 
469     num_muscles--;
470   }
471 }
472 
SetJoint(float x,float y,float z,int which,int whichjoint)473 void Skeleton::SetJoint(float x, float y, float z, int which, int whichjoint)
474 {
475   if(whichjoint < num_joints) {
476     joints[whichjoint].velocity = 0;
477     joints[whichjoint].position.x = x;
478     joints[whichjoint].position.y = y;
479     joints[whichjoint].position.z = z;
480 
481     if(which >= num_joints || which < 0)
482       joints[whichjoint].hasparent = 0;
483     if(which < num_joints && which >= 0) {
484       joints[whichjoint].parent = &joints[which];
485       joints[whichjoint].hasparent = 1;
486       joints[whichjoint].length =
487           findDistance(joints[whichjoint].position,
488                        joints[whichjoint].parent->position);
489     }
490   }
491 }
492 
AddMuscle(int attach1,int attach2,float minlength,float maxlength,int type)493 void Skeleton::AddMuscle(int attach1, int attach2, float minlength,
494                          float maxlength, int type)
495 {
496   if(num_muscles < max_muscles - 1 && attach1 < num_joints
497      && attach1 >= 0 & attach2 < num_joints && attach2 >= 0
498      && attach1 != attach2) {
499     muscles[num_muscles].parent1 = &joints[attach1];
500     muscles[num_muscles].parent2 = &joints[attach2];
501     muscles[num_muscles].length =
502         findDistance(muscles[num_muscles].parent1->position,
503                      muscles[num_muscles].parent2->position);
504     muscles[num_muscles].targetlength =
505         findDistance(muscles[num_muscles].parent1->position,
506                      muscles[num_muscles].parent2->position);
507     muscles[num_muscles].strength = .7;
508     muscles[num_muscles].type = type;
509     muscles[num_muscles].minlength = minlength;
510     muscles[num_muscles].maxlength = maxlength;
511 
512     num_muscles++;
513   }
514 }
515 
MusclesSet()516 void Skeleton::MusclesSet()
517 {
518   for(int i = 0; i < num_muscles; i++) {
519     muscles[i].length =
520         findDistance(muscles[i].parent1->position,
521                      muscles[i].parent2->position);
522   }
523 }
524 
FindRotationJoint(int which)525 void Skeleton::FindRotationJoint(int which)
526 {
527   XYZ temppoint1, temppoint2, tempforward;
528   float distance;
529 
530   temppoint1 = joints[which].position;
531   temppoint2 = joints[which].parent->position;
532   distance = findDistance(temppoint1, temppoint2);
533   joints[which].rotate2 =
534       asin((temppoint1.y - temppoint2.y) / distance) * RAD2DEG;
535   temppoint1.y = 0;
536   temppoint2.y = 0;
537   joints[which].rotate1 =
538       acos((temppoint1.z - temppoint2.z) / findDistance(temppoint1,
539                                                         temppoint2)) * RAD2DEG;
540   if(temppoint1.x > temppoint2.x)
541     joints[which].rotate1 = 360 - joints[which].rotate1;
542   if(joints[which].label == head)
543     tempforward = specialforward[0];
544   else if(joints[which].label == rightshoulder
545           || joints[which].label == rightelbow
546           || joints[which].label == rightwrist
547           || joints[which].label == righthand)
548     tempforward = specialforward[1];
549   else if(joints[which].label == leftshoulder
550           || joints[which].label == leftelbow
551           || joints[which].label == leftwrist
552           || joints[which].label == lefthand)
553     tempforward = specialforward[2];
554   else if(joints[which].label == righthip || joints[which].label == rightknee
555           || joints[which].label == rightankle)
556     tempforward = specialforward[3];
557   else if(joints[which].label == lefthip || joints[which].label == leftknee
558           || joints[which].label == leftankle)
559     tempforward = specialforward[4];
560   else if(!joints[which].lower)
561     tempforward = forward;
562   else if(joints[which].lower)
563     tempforward = lowforward;
564   tempforward = DoRotation(tempforward, 0, joints[which].rotate1 - 90, 0);
565   tempforward = DoRotation(tempforward, 0, 0, joints[which].rotate2 - 90);
566   tempforward.y = 0;
567   Normalise(&tempforward);
568   joints[which].rotate3 = acos(0 - tempforward.z) * RAD2DEG;
569   if(0 > tempforward.x)
570     joints[which].rotate3 = 360 - joints[which].rotate3;
571 }
572 
FindRotationMuscle(int which)573 void Skeleton::FindRotationMuscle(int which)
574 {
575   XYZ temppoint1, temppoint2, tempforward;
576   float distance;
577 
578   temppoint1 = muscles[which].parent1->position;
579   temppoint2 = muscles[which].parent2->position;
580   distance = findDistance(temppoint1, temppoint2);
581   muscles[which].rotate2 =
582       asin((temppoint1.y - temppoint2.y) / distance) * RAD2DEG;
583   temppoint1.y = 0;
584   temppoint2.y = 0;
585   muscles[which].rotate1 =
586       acos((temppoint1.z - temppoint2.z) / findDistance(temppoint1,
587                                                         temppoint2));
588   muscles[which].rotate1 *= 360 / 6.28;
589   if(temppoint1.x > temppoint2.x)
590     muscles[which].rotate1 = 360 - muscles[which].rotate1;
591   if(muscles[which].parent1->label == head)
592     tempforward = specialforward[0];
593   else if(muscles[which].parent1->label == rightshoulder
594           || muscles[which].parent1->label == rightelbow
595           || muscles[which].parent1->label == rightwrist)
596     tempforward = specialforward[1];
597   else if(muscles[which].parent1->label == leftshoulder
598           || muscles[which].parent1->label == leftelbow
599           || muscles[which].parent1->label == leftwrist)
600     tempforward = specialforward[2];
601   else if(muscles[which].parent1->label == righthip
602           || muscles[which].parent1->label == rightknee
603           || muscles[which].parent1->label == rightankle)
604     tempforward = specialforward[3];
605   else if(muscles[which].parent1->label == lefthip
606           || muscles[which].parent1->label == leftknee
607           || muscles[which].parent1->label == leftankle)
608     tempforward = specialforward[4];
609   else if(!muscles[which].parent1->lower)
610     tempforward = forward;
611   else if(muscles[which].parent1->lower)
612     tempforward = lowforward;
613   tempforward = DoRotation(tempforward, 0, muscles[which].rotate1 - 90, 0);
614   tempforward = DoRotation(tempforward, 0, 0, muscles[which].rotate2 - 90);
615   tempforward.y = 0;
616   Normalise(&tempforward);
617   muscles[which].rotate3 = acos(0 - tempforward.z) * RAD2DEG;
618   for(int i = 0; i < num_joints; i++) {
619     if(&joints[i] == muscles[which].parent1) {
620       joints[i].rotate1 = muscles[which].rotate1;
621       joints[i].rotate2 = muscles[which].rotate2;
622       joints[i].rotate3 = muscles[which].rotate3;
623     }
624   }
625   if(0 > tempforward.x)
626     muscles[which].rotate3 = 360 - muscles[which].rotate3;
627 }
628 
629 extern Skeleton testskeleton;
630 
Load(char * fileName)631 void Animation::Load(char *fileName)
632 {
633   files.OpenFile((unsigned char *)fileName);
634   if(files.sFile) {
635     ReadInt(files.sFile, 1, &numframes);
636     for(int i = 0; i < numframes; i++) {
637       for(int j = 0; j < max_joints; j++) {
638         ReadXYZ(files.sFile, 1, &position[j][i]);
639       }
640       for(int j = 0; j < max_joints; j++) {
641         ReadFloat(files.sFile, 1, &twist[j][i]);
642       }
643       for(int j = 0; j < max_joints; j++) {
644         ReadBool(files.sFile, 1, &onground[j][i]);
645       }
646       ReadFloat(files.sFile, 1, &speed[i]);
647       ReadFloat(files.sFile, 1, &gunrotation[i]);
648     }
649     for(int i = 0; i < numframes; i++) {
650       for(int j = 0; j < max_joints; j++) {
651         ReadFloat(files.sFile, 1, &twist2[j][i]);
652       }
653     }
654   }
655 
656   files.EndLoad();
657 
658   for(int j = 0; j < numframes; j++) {
659     for(int i = 0; i < testskeleton.num_joints; i++) {
660       testskeleton.joints[i].position = position[i][j];
661     }
662     //Find forward vectors
663     CrossProduct(testskeleton.joints[testskeleton.forwardjoints[1]].position -
664                  testskeleton.joints[testskeleton.forwardjoints[0]].position,
665                  testskeleton.joints[testskeleton.forwardjoints[2]].position -
666                  testskeleton.joints[testskeleton.forwardjoints[0]].position,
667                  &testskeleton.forward);
668     Normalise(&testskeleton.forward);
669 
670     CrossProduct(testskeleton.joints[testskeleton.lowforwardjoints[1]].
671                  position -
672                  testskeleton.joints[testskeleton.lowforwardjoints[0]].position,
673                  testskeleton.joints[testskeleton.lowforwardjoints[2]].
674                  position -
675                  testskeleton.joints[testskeleton.lowforwardjoints[0]].position,
676                  &testskeleton.lowforward);
677     Normalise(&testskeleton.lowforward);
678 
679     //Special forwards
680     testskeleton.specialforward[0] = testskeleton.forward;
681 
682     testskeleton.specialforward[1] =
683         testskeleton.joints[testskeleton.jointlabels[rightshoulder]].position +
684         testskeleton.joints[testskeleton.jointlabels[rightwrist]].position;
685     testskeleton.specialforward[1] =
686         testskeleton.joints[testskeleton.jointlabels[rightelbow]].position -
687         testskeleton.specialforward[1] / 2;
688     testskeleton.specialforward[1] += testskeleton.forward * .2;
689     Normalise(&testskeleton.specialforward[1]);
690     testskeleton.specialforward[2] =
691         testskeleton.joints[testskeleton.jointlabels[leftshoulder]].position +
692         testskeleton.joints[testskeleton.jointlabels[leftwrist]].position;
693     testskeleton.specialforward[2] =
694         testskeleton.joints[testskeleton.jointlabels[leftelbow]].position -
695         testskeleton.specialforward[2] / 2;
696     testskeleton.specialforward[2] += testskeleton.forward * .2;
697     Normalise(&testskeleton.specialforward[2]);
698 
699     testskeleton.specialforward[3] =
700         testskeleton.joints[testskeleton.jointlabels[righthip]].position +
701         testskeleton.joints[testskeleton.jointlabels[rightankle]].position;
702     testskeleton.specialforward[3] =
703         testskeleton.specialforward[3] / 2 -
704         testskeleton.joints[testskeleton.jointlabels[rightknee]].position;
705     testskeleton.specialforward[3] += testskeleton.lowforward * .2;
706     Normalise(&testskeleton.specialforward[3]);
707     testskeleton.specialforward[4] =
708         testskeleton.joints[testskeleton.jointlabels[lefthip]].position +
709         testskeleton.joints[testskeleton.jointlabels[leftankle]].position;
710     testskeleton.specialforward[4] =
711         testskeleton.specialforward[4] / 2 -
712         testskeleton.joints[testskeleton.jointlabels[leftknee]].position;
713     testskeleton.specialforward[4] += testskeleton.lowforward * .2;
714     Normalise(&testskeleton.specialforward[4]);
715 
716     //Find joint rotations
717     for(int i = 0; i < testskeleton.num_joints; i++) {
718       if(testskeleton.joints[i].hasparent && testskeleton.joints[i].visible) {
719         testskeleton.FindRotationJoint(i);
720       }
721     }
722     for(int i = 0; i < testskeleton.num_muscles; i++) {
723       if(testskeleton.muscles[i].visible) {
724         testskeleton.FindRotationMuscle(i);
725       }
726     }
727     for(int i = 0; i < testskeleton.num_muscles; i++) {
728       if(testskeleton.muscles[i].visible) {
729         mrotate1[i][j] = testskeleton.muscles[i].rotate1;
730         mrotate2[i][j] = testskeleton.muscles[i].rotate2;
731         mrotate3[i][j] = testskeleton.muscles[i].rotate3;
732         if(j != 0 && mrotate3[i][j] > mrotate3[i][j - 1] + 180)
733           mrotate3[i][j] -= 360;
734         if(j != 0 && mrotate3[i][j] < mrotate3[i][j - 1] - 180)
735           mrotate3[i][j] += 360;
736         if(j != 0 && mrotate2[i][j] > mrotate2[i][j - 1] + 180)
737           mrotate2[i][j] -= 360;
738         if(j != 0 && mrotate2[i][j] < mrotate2[i][j - 1] - 180)
739           mrotate2[i][j] += 360;
740         if(j != 0 && mrotate1[i][j] > mrotate1[i][j - 1] + 180)
741           mrotate1[i][j] -= 360;
742         if(j != 0 && mrotate1[i][j] < mrotate1[i][j - 1] - 180)
743           mrotate1[i][j] += 360;
744       }
745     }
746     for(int i = 0; i < testskeleton.num_joints; i++) {
747       if(testskeleton.joints[i].hasparent && testskeleton.joints[i].visible) {
748         rotate1[i][j] = testskeleton.joints[i].rotate1;
749         rotate2[i][j] = testskeleton.joints[i].rotate2;
750         rotate3[i][j] = testskeleton.joints[i].rotate3;
751         if(j != 0 && rotate3[i][j] > rotate3[i][j - 1] + 180)
752           rotate3[i][j] -= 360;
753         if(j != 0 && rotate3[i][j] < rotate3[i][j - 1] - 180)
754           rotate3[i][j] += 360;
755         if(j != 0 && rotate2[i][j] > rotate2[i][j - 1] + 180)
756           rotate2[i][j] -= 360;
757         if(j != 0 && rotate2[i][j] < rotate2[i][j - 1] - 180)
758           rotate2[i][j] += 360;
759         if(j != 0 && rotate1[i][j] > rotate1[i][j - 1] + 180)
760           rotate1[i][j] -= 360;
761         if(j != 0 && rotate1[i][j] < rotate1[i][j - 1] - 180)
762           rotate1[i][j] += 360;
763       }
764     }
765   }
766 
767   for(int k = 0; k < 2; k++)
768     for(int j = 0; j < numframes; j++) {
769       for(int i = 0; i < testskeleton.num_muscles; i++) {
770         if(testskeleton.muscles[i].visible) {
771           if(j != 0 && mrotate3[i][j] > mrotate3[i][j - 1] + 180)
772             mrotate3[i][j] -= 360;
773           if(j != 0 && mrotate3[i][j] < mrotate3[i][j - 1] - 180)
774             mrotate3[i][j] += 360;
775           if(j != 0 && mrotate2[i][j] > mrotate2[i][j - 1] + 180)
776             mrotate2[i][j] -= 360;
777           if(j != 0 && mrotate2[i][j] < mrotate2[i][j - 1] - 180)
778             mrotate2[i][j] += 360;
779           if(j != 0 && mrotate1[i][j] > mrotate1[i][j - 1] + 180)
780             mrotate1[i][j] -= 360;
781           if(j != 0 && mrotate1[i][j] < mrotate1[i][j - 1] - 180)
782             mrotate1[i][j] += 360;
783 
784           if(j == 0 && mrotate3[i][j] > mrotate3[i][numframes - 1] + 180)
785             mrotate3[i][j] -= 360;
786           if(j == 0 && mrotate3[i][j] < mrotate3[i][numframes - 1] - 180)
787             mrotate3[i][j] += 360;
788           if(j == 0 && mrotate2[i][j] > mrotate2[i][numframes - 1] + 180)
789             mrotate2[i][j] -= 360;
790           if(j == 0 && mrotate2[i][j] < mrotate2[i][numframes - 1] - 180)
791             mrotate2[i][j] += 360;
792           if(j == 0 && mrotate1[i][j] > mrotate1[i][numframes - 1] + 180)
793             mrotate1[i][j] -= 360;
794           if(j == 0 && mrotate1[i][j] < mrotate1[i][numframes - 1] - 180)
795             mrotate1[i][j] += 360;
796         }
797       }
798       for(int i = 0; i < testskeleton.num_joints; i++) {
799         if(testskeleton.joints[i].hasparent && testskeleton.joints[i].visible) {
800           if(j != 0 && rotate3[i][j] > rotate3[i][j - 1] + 180)
801             rotate3[i][j] -= 360;
802           if(j != 0 && rotate3[i][j] < rotate3[i][j - 1] - 180)
803             rotate3[i][j] += 360;
804           if(j != 0 && rotate2[i][j] > rotate2[i][j - 1] + 180)
805             rotate2[i][j] -= 360;
806           if(j != 0 && rotate2[i][j] < rotate2[i][j - 1] - 180)
807             rotate2[i][j] += 360;
808           if(j != 0 && rotate1[i][j] > rotate1[i][j - 1] + 180)
809             rotate1[i][j] -= 360;
810           if(j != 0 && rotate1[i][j] < rotate1[i][j - 1] - 180)
811             rotate1[i][j] += 360;
812 
813           if(j == 0 && rotate3[i][j] > rotate3[i][numframes - 1] + 180)
814             rotate3[i][j] -= 360;
815           if(j == 0 && rotate3[i][j] < rotate3[i][numframes - 1] - 180)
816             rotate3[i][j] += 360;
817           if(j == 0 && rotate2[i][j] > rotate2[i][numframes - 1] + 180)
818             rotate2[i][j] -= 360;
819           if(j == 0 && rotate2[i][j] < rotate2[i][numframes - 1] - 180)
820             rotate2[i][j] += 360;
821           if(j == 0 && rotate1[i][j] > rotate1[i][numframes - 1] + 180)
822             rotate1[i][j] -= 360;
823           if(j == 0 && rotate1[i][j] < rotate1[i][numframes - 1] - 180)
824             rotate1[i][j] += 360;
825         }
826       }
827     }
828 }
829 
Load(char * fileName,float rotate)830 void Animation::Load(char *fileName, float rotate)
831 {
832   files.OpenFile((unsigned char *)fileName);
833   if(files.sFile) {
834     ReadInt(files.sFile, 1, &numframes);
835     for(int i = 0; i < numframes; i++) {
836       for(int j = 0; j < max_joints; j++) {
837         ReadXYZ(files.sFile, 1, &position[j][i]);
838         position[j][i] = DoRotation(position[j][i], 0, rotate, 0);
839       }
840       for(int j = 0; j < max_joints; j++) {
841         ReadFloat(files.sFile, 1, &twist[j][i]);
842       }
843       for(int j = 0; j < max_joints; j++) {
844         ReadBool(files.sFile, 1, &onground[j][i]);
845       }
846       ReadFloat(files.sFile, 1, &speed[i]);
847       ReadFloat(files.sFile, 1, &gunrotation[i]);
848     }
849     for(int i = 0; i < numframes; i++) {
850       for(int j = 0; j < max_joints; j++) {
851         ReadFloat(files.sFile, 1, &twist2[j][i]);
852       }
853     }
854   }
855   files.EndLoad();
856 
857   for(int j = 0; j < numframes; j++) {
858     for(int i = 0; i < testskeleton.num_joints; i++) {
859       testskeleton.joints[i].position = position[i][j];
860     }
861     //Find forward vectors
862     CrossProduct(testskeleton.joints[testskeleton.forwardjoints[1]].position -
863                  testskeleton.joints[testskeleton.forwardjoints[0]].position,
864                  testskeleton.joints[testskeleton.forwardjoints[2]].position -
865                  testskeleton.joints[testskeleton.forwardjoints[0]].position,
866                  &testskeleton.forward);
867     Normalise(&testskeleton.forward);
868 
869     CrossProduct(testskeleton.joints[testskeleton.lowforwardjoints[1]].
870                  position -
871                  testskeleton.joints[testskeleton.lowforwardjoints[0]].position,
872                  testskeleton.joints[testskeleton.lowforwardjoints[2]].
873                  position -
874                  testskeleton.joints[testskeleton.lowforwardjoints[0]].position,
875                  &testskeleton.lowforward);
876     Normalise(&testskeleton.lowforward);
877 
878     //Special forwards
879     testskeleton.specialforward[0] = testskeleton.forward;
880 
881     testskeleton.specialforward[1] =
882         testskeleton.joints[testskeleton.jointlabels[rightshoulder]].position +
883         testskeleton.joints[testskeleton.jointlabels[rightwrist]].position;
884     testskeleton.specialforward[1] =
885         testskeleton.joints[testskeleton.jointlabels[rightelbow]].position -
886         testskeleton.specialforward[1] / 2;
887     testskeleton.specialforward[1] += testskeleton.forward * .2;
888     Normalise(&testskeleton.specialforward[1]);
889     testskeleton.specialforward[2] =
890         testskeleton.joints[testskeleton.jointlabels[leftshoulder]].position +
891         testskeleton.joints[testskeleton.jointlabels[leftwrist]].position;
892     testskeleton.specialforward[2] =
893         testskeleton.joints[testskeleton.jointlabels[leftelbow]].position -
894         testskeleton.specialforward[2] / 2;
895     testskeleton.specialforward[2] += testskeleton.forward * .2;
896     Normalise(&testskeleton.specialforward[2]);
897 
898     testskeleton.specialforward[3] =
899         testskeleton.joints[testskeleton.jointlabels[righthip]].position +
900         testskeleton.joints[testskeleton.jointlabels[rightankle]].position;
901     testskeleton.specialforward[3] =
902         testskeleton.specialforward[3] / 2 -
903         testskeleton.joints[testskeleton.jointlabels[rightknee]].position;
904     testskeleton.specialforward[3] += testskeleton.lowforward * .2;
905     Normalise(&testskeleton.specialforward[3]);
906     testskeleton.specialforward[4] =
907         testskeleton.joints[testskeleton.jointlabels[lefthip]].position +
908         testskeleton.joints[testskeleton.jointlabels[leftankle]].position;
909     testskeleton.specialforward[4] =
910         testskeleton.specialforward[4] / 2 -
911         testskeleton.joints[testskeleton.jointlabels[leftknee]].position;
912     testskeleton.specialforward[4] += testskeleton.lowforward * .2;
913     Normalise(&testskeleton.specialforward[4]);
914 
915     //Find joint rotations
916     for(int i = 0; i < testskeleton.num_joints; i++) {
917       if(testskeleton.joints[i].hasparent && testskeleton.joints[i].visible) {
918         testskeleton.FindRotationJoint(i);
919       }
920     }
921     for(int i = 0; i < testskeleton.num_muscles; i++) {
922       if(testskeleton.muscles[i].visible) {
923         testskeleton.FindRotationMuscle(i);
924       }
925     }
926     for(int i = 0; i < testskeleton.num_muscles; i++) {
927       if(testskeleton.muscles[i].visible) {
928         mrotate1[i][j] = testskeleton.muscles[i].rotate1;
929         mrotate2[i][j] = testskeleton.muscles[i].rotate2;
930         mrotate3[i][j] = testskeleton.muscles[i].rotate3;
931         if(j != 0 && mrotate3[i][j] > mrotate3[i][j - 1] + 180)
932           mrotate3[i][j] -= 360;
933         if(j != 0 && mrotate3[i][j] < mrotate3[i][j - 1] - 180)
934           mrotate3[i][j] += 360;
935         if(j != 0 && mrotate2[i][j] > mrotate2[i][j - 1] + 180)
936           mrotate2[i][j] -= 360;
937         if(j != 0 && mrotate2[i][j] < mrotate2[i][j - 1] - 180)
938           mrotate2[i][j] += 360;
939         if(j != 0 && mrotate1[i][j] > mrotate1[i][j - 1] + 180)
940           mrotate1[i][j] -= 360;
941         if(j != 0 && mrotate1[i][j] < mrotate1[i][j - 1] - 180)
942           mrotate1[i][j] += 360;
943       }
944     }
945     for(int i = 0; i < testskeleton.num_joints; i++) {
946       if(testskeleton.joints[i].hasparent && testskeleton.joints[i].visible) {
947         rotate1[i][j] = testskeleton.joints[i].rotate1;
948         rotate2[i][j] = testskeleton.joints[i].rotate2;
949         rotate3[i][j] = testskeleton.joints[i].rotate3;
950         if(j != 0 && rotate3[i][j] > rotate3[i][j - 1] + 180)
951           rotate3[i][j] -= 360;
952         if(j != 0 && rotate3[i][j] < rotate3[i][j - 1] - 180)
953           rotate3[i][j] += 360;
954         if(j != 0 && rotate2[i][j] > rotate2[i][j - 1] + 180)
955           rotate2[i][j] -= 360;
956         if(j != 0 && rotate2[i][j] < rotate2[i][j - 1] - 180)
957           rotate2[i][j] += 360;
958         if(j != 0 && rotate1[i][j] > rotate1[i][j - 1] + 180)
959           rotate1[i][j] -= 360;
960         if(j != 0 && rotate1[i][j] < rotate1[i][j - 1] - 180)
961           rotate1[i][j] += 360;
962       }
963     }
964   }
965 
966   for(int k = 0; k < 2; k++)
967     for(int j = 0; j < numframes; j++) {
968       for(int i = 0; i < testskeleton.num_muscles; i++) {
969         if(testskeleton.muscles[i].visible) {
970           if(j != 0 && mrotate3[i][j] > mrotate3[i][j - 1] + 180)
971             mrotate3[i][j] -= 360;
972           if(j != 0 && mrotate3[i][j] < mrotate3[i][j - 1] - 180)
973             mrotate3[i][j] += 360;
974           if(j != 0 && mrotate2[i][j] > mrotate2[i][j - 1] + 180)
975             mrotate2[i][j] -= 360;
976           if(j != 0 && mrotate2[i][j] < mrotate2[i][j - 1] - 180)
977             mrotate2[i][j] += 360;
978           if(j != 0 && mrotate1[i][j] > mrotate1[i][j - 1] + 180)
979             mrotate1[i][j] -= 360;
980           if(j != 0 && mrotate1[i][j] < mrotate1[i][j - 1] - 180)
981             mrotate1[i][j] += 360;
982 
983           if(j == 0 && mrotate3[i][j] > mrotate3[i][numframes - 1] + 180)
984             mrotate3[i][j] -= 360;
985           if(j == 0 && mrotate3[i][j] < mrotate3[i][numframes - 1] - 180)
986             mrotate3[i][j] += 360;
987           if(j == 0 && mrotate2[i][j] > mrotate2[i][numframes - 1] + 180)
988             mrotate2[i][j] -= 360;
989           if(j == 0 && mrotate2[i][j] < mrotate2[i][numframes - 1] - 180)
990             mrotate2[i][j] += 360;
991           if(j == 0 && mrotate1[i][j] > mrotate1[i][numframes - 1] + 180)
992             mrotate1[i][j] -= 360;
993           if(j == 0 && mrotate1[i][j] < mrotate1[i][numframes - 1] - 180)
994             mrotate1[i][j] += 360;
995         }
996       }
997       for(int i = 0; i < testskeleton.num_joints; i++) {
998         if(testskeleton.joints[i].hasparent && testskeleton.joints[i].visible) {
999           if(j != 0 && rotate3[i][j] > rotate3[i][j - 1] + 180)
1000             rotate3[i][j] -= 360;
1001           if(j != 0 && rotate3[i][j] < rotate3[i][j - 1] - 180)
1002             rotate3[i][j] += 360;
1003           if(j != 0 && rotate2[i][j] > rotate2[i][j - 1] + 180)
1004             rotate2[i][j] -= 360;
1005           if(j != 0 && rotate2[i][j] < rotate2[i][j - 1] - 180)
1006             rotate2[i][j] += 360;
1007           if(j != 0 && rotate1[i][j] > rotate1[i][j - 1] + 180)
1008             rotate1[i][j] -= 360;
1009           if(j != 0 && rotate1[i][j] < rotate1[i][j - 1] - 180)
1010             rotate1[i][j] += 360;
1011 
1012           if(j == 0 && rotate3[i][j] > rotate3[i][numframes - 1] + 180)
1013             rotate3[i][j] -= 360;
1014           if(j == 0 && rotate3[i][j] < rotate3[i][numframes - 1] - 180)
1015             rotate3[i][j] += 360;
1016           if(j == 0 && rotate2[i][j] > rotate2[i][numframes - 1] + 180)
1017             rotate2[i][j] -= 360;
1018           if(j == 0 && rotate2[i][j] < rotate2[i][numframes - 1] - 180)
1019             rotate2[i][j] += 360;
1020           if(j == 0 && rotate1[i][j] > rotate1[i][numframes - 1] + 180)
1021             rotate1[i][j] -= 360;
1022           if(j == 0 && rotate1[i][j] < rotate1[i][numframes - 1] - 180)
1023             rotate1[i][j] += 360;
1024         }
1025       }
1026     }
1027 }
1028 
Load(char * fileName)1029 void Skeleton::Load(char *fileName)
1030 {
1031   int parentID;
1032   bool what;
1033   files.OpenFile((unsigned char *)fileName);
1034   if(files.sFile) {
1035     ReadInt(files.sFile, 1, &num_joints);
1036     for(int i = 0; i < num_joints; i++) {
1037       ReadXYZ(files.sFile, 1, &joints[i].position);
1038       ReadFloat(files.sFile, 1, &joints[i].length);
1039       ReadFloat(files.sFile, 1, &joints[i].mass);
1040       ReadBool(files.sFile, 1, &joints[i].hasparent);
1041       ReadBool(files.sFile, 1, &joints[i].locked);
1042       ReadInt(files.sFile, 1, &joints[i].modelnum);
1043       ReadBool(files.sFile, 1, &joints[i].visible);
1044       ReadBool(files.sFile, 1, &what);
1045       ReadInt(files.sFile, 1, &joints[i].label);
1046       ReadInt(files.sFile, 1, &joints[i].hasgun);
1047       ReadBool(files.sFile, 1, &joints[i].lower);
1048       ReadInt(files.sFile, 1, &parentID);
1049       if(joints[i].hasparent)
1050         joints[i].parent = &joints[parentID];
1051       joints[i].velocity = 0;
1052       joints[i].oldposition = joints[i].position;
1053       joints[i].existing = 1;
1054     }
1055 
1056     ReadInt(files.sFile, 1, &num_muscles);
1057     for(int i = 0; i < num_muscles; i++) {
1058       ReadFloat(files.sFile, 1, &muscles[i].length);
1059       ReadFloat(files.sFile, 1, &muscles[i].targetlength);
1060       ReadFloat(files.sFile, 1, &muscles[i].minlength);
1061       ReadFloat(files.sFile, 1, &muscles[i].maxlength);
1062       ReadFloat(files.sFile, 1, &muscles[i].strength);
1063       ReadInt(files.sFile, 1, &muscles[i].type);
1064       ReadBool(files.sFile, 1, &muscles[i].visible);
1065       ReadInt(files.sFile, 1, &parentID);
1066       muscles[i].parent1 = &joints[parentID];
1067       ReadInt(files.sFile, 1, &parentID);
1068       muscles[i].parent2 = &joints[parentID];
1069     }
1070 
1071     for(int j = 0; j < 3; j++) {
1072       ReadInt(files.sFile, 1, &forwardjoints[j]);
1073     }
1074     for(int j = 0; j < 3; j++) {
1075       ReadInt(files.sFile, 1, &lowforwardjoints[j]);
1076     }
1077   }
1078   files.EndLoad();
1079 
1080   for(int i = 0; i < num_joints; i++) {
1081     for(int j = 0; j < num_joints; j++) {
1082       if(joints[i].label == j)
1083         jointlabels[j] = i;
1084     }
1085   }
1086 
1087   broken = 0;
1088 }
1089