]> git.jsancho.org Git - lugaru.git/blob - Source/Skeleton.cpp
13366888df63f9d837d72c9cf89df4c51fbcfaa6
[lugaru.git] / Source / Skeleton.cpp
1 /**> HEADER FILES <**/
2 #include "Skeleton.h"
3
4 extern float multiplier;
5 extern float gravity;
6 extern Skeleton testskeleton;
7 extern Terrain terrain;
8 extern FSOUND_SAMPLE    *samp[100];
9 extern int channels[100];
10 extern Objects objects;
11 extern Sprites sprites;
12 extern int environment;
13 extern float terraindetail;
14 extern float camerashake;
15 extern bool freeze;
16 extern int detail;
17 extern XYZ envsound[30];
18 extern float envsoundvol[30];
19 extern int numenvsounds;
20 extern float envsoundlife[30];
21 extern int bonus;
22 extern float bonustime;
23 extern int tutoriallevel;
24
25 extern int whichjointstartarray[26];
26 extern int whichjointendarray[26];
27
28 #include "Game.h"
29 extern Game * pgame;
30 extern bool visibleloading;
31 extern "C"      void PlaySoundEx(int channel, FSOUND_SAMPLE *sptr, FSOUND_DSPUNIT *dsp, signed char startpaused);
32
33 void dealloc2(void* param){
34         free(param);
35         param=0;
36 }
37
38 void Muscle::DoConstraint(bool spinny)
39 {
40         static XYZ vel;
41         static XYZ midp;
42         static XYZ newpoint1,newpoint2;
43
44         static float oldlength;
45         static float relaxlength;
46
47         oldlength=length;
48
49         if(type!=boneconnect)relaxlength=findDistance(&parent1->position,&parent2->position);
50
51         if(type==boneconnect)strength=1;
52         if(type==constraint)strength=0;
53
54         if(strength<0)strength=0;
55         if(strength>1)strength=1;
56
57         length-=(length-relaxlength)*(1-strength)*multiplier*10000;
58         length-=(length-targetlength)*(strength)*multiplier*10000;
59         if(strength==0)length=relaxlength;
60
61         if((relaxlength-length>0&&relaxlength-oldlength<0)||(relaxlength-length<0&&relaxlength-oldlength>0))length=relaxlength;
62
63         //if(!broken){
64         if(length<minlength)length=minlength;
65         if(length>maxlength)length=maxlength;
66         //}
67         /*
68         if(broken){
69         if(length<minlength*.6)length=minlength*.6;
70         if(length>maxlength*1.4)length=maxlength*1.4;
71         }
72         */
73         if(length==relaxlength)return;
74
75         //Find midpoint
76         midp=(parent1->position*parent1->mass+parent2->position*parent2->mass)/(parent1->mass+parent2->mass);
77         //Find vector from midpoint to second vector
78         vel=parent2->position-midp;
79         //Change to unit vector
80         Normalise(&vel);
81         //Apply velocity change
82         newpoint1=midp-vel*length*(parent2->mass/(parent1->mass+parent2->mass));
83         newpoint2=midp+vel*length*(parent1->mass/(parent1->mass+parent2->mass));
84         if(!freeze&&spinny){
85                 parent1->velocity=parent1->velocity+(newpoint1-parent1->position)/multiplier/4;
86                 parent2->velocity=parent2->velocity+(newpoint2-parent2->position)/multiplier/4;
87         }
88         else
89         {
90                 parent1->velocity=parent1->velocity+(newpoint1-parent1->position);
91                 parent2->velocity=parent2->velocity+(newpoint2-parent2->position);
92         }
93         //Move child point to within certain distance of parent point
94         parent1->position=newpoint1;
95         parent2->position=newpoint2;
96 }
97
98 void Skeleton::FindForwardsfirst()
99 {
100         //Find forward vectors
101         CrossProduct(joints[forwardjoints[1]].position-joints[forwardjoints[0]].position,joints[forwardjoints[2]].position-joints[forwardjoints[0]].position,&forward);
102         Normalise(&forward);
103
104         CrossProduct(joints[lowforwardjoints[1]].position-joints[lowforwardjoints[0]].position,joints[lowforwardjoints[2]].position-joints[lowforwardjoints[0]].position,&lowforward);
105         Normalise(&lowforward);
106
107         //Special forwards
108         specialforward[0]=forward;
109         specialforward[1]=forward;
110         specialforward[2]=forward;
111         specialforward[3]=forward;
112         specialforward[4]=forward;
113
114 }
115 void Skeleton::FindForwards()
116 {
117         //Find forward vectors
118         CrossProduct(joints[forwardjoints[1]].position-joints[forwardjoints[0]].position,joints[forwardjoints[2]].position-joints[forwardjoints[0]].position,&forward);
119         Normalise(&forward);
120
121         CrossProduct(joints[lowforwardjoints[1]].position-joints[lowforwardjoints[0]].position,joints[lowforwardjoints[2]].position-joints[lowforwardjoints[0]].position,&lowforward);
122         Normalise(&lowforward);
123
124         //Special forwards
125         specialforward[0]=forward;
126
127         specialforward[1]=joints[jointlabels[rightshoulder]].position+joints[jointlabels[rightwrist]].position;
128         specialforward[1]=joints[jointlabels[rightelbow]].position-specialforward[1]/2;
129         specialforward[1]+=forward*.4;
130         Normalise(&specialforward[1]);
131         specialforward[2]=joints[jointlabels[leftshoulder]].position+joints[jointlabels[leftwrist]].position;
132         specialforward[2]=joints[jointlabels[leftelbow]].position-specialforward[2]/2;
133         specialforward[2]+=forward*.4;
134         Normalise(&specialforward[2]);
135
136         specialforward[3]=joints[jointlabels[righthip]].position+joints[jointlabels[rightankle]].position;
137         specialforward[3]=specialforward[3]/2-joints[jointlabels[rightknee]].position;
138         specialforward[3]+=lowforward*.4;
139         Normalise(&specialforward[3]);
140         specialforward[4]=joints[jointlabels[lefthip]].position+joints[jointlabels[leftankle]].position;
141         specialforward[4]=specialforward[4]/2-joints[jointlabels[leftknee]].position;
142         specialforward[4]+=lowforward*.4;
143         Normalise(&specialforward[4]);
144 }
145
146 float Skeleton::DoConstraints(XYZ *coords,float *scale)
147 {
148         static float friction=1.5;
149         static float elasticity=.3;
150         static XYZ bounceness;
151         static XYZ oldpos[100];
152         static int numrepeats=3;
153         static float groundlevel=.15;
154         static float soundvolume;
155         static int i,j,k,l,m;
156         static XYZ temp,start,end;
157         static XYZ terrainnormal;
158         static float r=.05;
159         static float r2=.08;
160         static int whichhit;
161         //static int whichjointstart,whichjointend;
162         static float distance;
163         static float frictionness;
164         static XYZ terrainlight;
165         static int whichpatchx;
166         static int whichpatchz;
167         static float damage;
168         static bool freely;
169         static float tempmult;
170         static bool breaking;
171         breaking=0;
172
173         damage=0;
174
175         if(free){
176                 freetime+=multiplier;
177
178                 whichpatchx=coords->x/(terrain.size/subdivision*terrain.scale*terraindetail);
179                 whichpatchz=coords->z/(terrain.size/subdivision*terrain.scale*terraindetail);
180
181                 terrainlight=*coords;
182                 objects.SphereCheckPossible(&terrainlight, 1);
183                 /*
184                 for(i=0; i<num_joints; i++){
185                 oldpos[i]=joints[i].position;           
186                 }*/
187
188                 //Add velocity
189                 for(i=0; i<num_joints; i++){
190                         //if(!isnormal(joints[i].velocity.x)||!isnormal(joints[i].velocity.y)||!isnormal(joints[i].velocity.z))joints[i].velocity=0;
191                         joints[i].position=joints[i].position+joints[i].velocity*multiplier;
192                         groundlevel=.15;
193                         if(joints[i].label==head)groundlevel=.8;        
194                         if(joints[i].label==righthand||joints[i].label==rightwrist||joints[i].label==rightelbow)groundlevel=.2; 
195                         if(joints[i].label==lefthand||joints[i].label==leftwrist||joints[i].label==leftelbow)groundlevel=.2;                    
196                         joints[i].position.y-=groundlevel;
197                         //if(!joints[i].locked&&!broken)joints[i].velocity+=joints[i].velchange*multiplier*10*(500-longdead)/500;
198                         joints[i].oldvelocity=joints[i].velocity;
199                 }
200                 tempmult=multiplier;
201                 //multiplier/=numrepeats;
202                 for(j=0; j<numrepeats; j++){
203                         if(!joints[jointlabels[rightknee]].locked&&!joints[jointlabels[righthip]].locked){
204                                 temp=joints[jointlabels[rightknee]].position-(joints[jointlabels[righthip]].position+joints[jointlabels[rightankle]].position)/2;
205                                 while(normaldotproduct(temp,lowforward)>-.1&&!sphere_line_intersection(&joints[jointlabels[righthip]].position,&joints[jointlabels[rightankle]].position,&joints[jointlabels[rightknee]].position,&r)){
206                                         joints[jointlabels[rightknee]].position-=lowforward*.05;
207                                         if(spinny)joints[jointlabels[rightknee]].velocity-=lowforward*.05/multiplier/4;
208                                         else joints[jointlabels[rightknee]].velocity-=lowforward*.05;
209                                         joints[jointlabels[rightankle]].position+=lowforward*.025;
210                                         if(spinny)joints[jointlabels[rightankle]].velocity+=lowforward*.025/multiplier/4;
211                                         else joints[jointlabels[rightankle]].velocity+=lowforward*.25;
212                                         joints[jointlabels[righthip]].position+=lowforward*.025;
213                                         if(spinny)joints[jointlabels[righthip]].velocity+=lowforward*.025/multiplier/4;
214                                         else joints[jointlabels[righthip]].velocity+=lowforward*.025;
215                                         temp=joints[jointlabels[rightknee]].position-(joints[jointlabels[righthip]].position+joints[jointlabels[rightankle]].position)/2;
216                                 }
217                         }
218                         if(!joints[jointlabels[leftknee]].locked&&!joints[jointlabels[righthip]].locked){
219                                 temp=joints[jointlabels[leftknee]].position-(joints[jointlabels[lefthip]].position+joints[jointlabels[leftankle]].position)/2;
220                                 while(normaldotproduct(temp,lowforward)>-.1&&!sphere_line_intersection(&joints[jointlabels[lefthip]].position,&joints[jointlabels[leftankle]].position,&joints[jointlabels[leftknee]].position,&r)){
221                                         joints[jointlabels[leftknee]].position-=lowforward*.05;
222                                         if(spinny)joints[jointlabels[leftknee]].velocity-=lowforward*.05/multiplier/4;
223                                         else joints[jointlabels[leftknee]].velocity-=lowforward*.05;
224                                         joints[jointlabels[leftankle]].position+=lowforward*.025;
225                                         if(spinny)joints[jointlabels[leftankle]].velocity+=lowforward*.025/multiplier/4;
226                                         else joints[jointlabels[leftankle]].velocity+=lowforward*.25;
227                                         joints[jointlabels[lefthip]].position+=lowforward*.025;
228                                         if(spinny)joints[jointlabels[lefthip]].velocity+=lowforward*.025/multiplier/4;
229                                         else joints[jointlabels[lefthip]].velocity+=lowforward*.025;
230                                         temp=joints[jointlabels[leftknee]].position-(joints[jointlabels[lefthip]].position+joints[jointlabels[leftankle]].position)/2;
231                                 }
232                         }
233                         /*
234                         if(terrain.patchobjectnum[whichpatchx][whichpatchz])
235                         for(m=0;m<terrain.patchobjectnum[whichpatchx][whichpatchz];m++){
236                         k=terrain.patchobjects[whichpatchx][whichpatchz][m];
237                         if(k<objects.numobjects&&k>=0)
238                         if(objects.possible[k]){
239                         temp=joints[jointlabels[head]].position*(*scale)+*coords;
240                         if(objects.model[k].SphereCheck(&temp, 0.06, &start, &objects.position[k], &objects.rotation[k])!=-1){
241                         //temp=(joints[jointlabels[head]].position*(*scale)+*coords)-start;
242                         //Normalise(&temp);
243                         //joints[jointlabels[head]].position=((temp*.2+start)-*coords)/(*scale);
244                         joints[jointlabels[head]].position=(temp-*coords)/(*scale);
245                         }
246                         }
247                         }       */
248
249
250                         //Ears check
251                         /*XYZ startheadpos;
252                         startheadpos=joints[jointlabels[head]].position;
253                         XYZ headpos;
254                         headpos=joints[jointlabels[head]].position+(joints[jointlabels[head]].position-joints[jointlabels[neck]].position);
255                         if(terrain.patchobjectnum[whichpatchx][whichpatchz])
256                         for(m=0;m<terrain.patchobjectnum[whichpatchx][whichpatchz];m++){
257                         k=terrain.patchobjects[whichpatchx][whichpatchz][m];
258                         if(k<objects.numobjects&&k>=0)
259                         if(objects.possible[k]){
260                         friction=objects.friction[k];
261                         start=joints[jointlabels[head]].position*(*scale)+*coords;
262                         end=(headpos)*(*scale)+*coords;
263                         whichhit=objects.model[k].LineCheckPossible(&start,&end,&temp,&objects.position[k],&objects.rotation[k]);
264                         if(whichhit!=-1){
265                         if(joints[jointlabels[head]].label==groin&&!joints[jointlabels[head]].locked&&joints[jointlabels[head]].delay<=0){
266                         joints[jointlabels[head]].locked=1;
267                         joints[jointlabels[head]].delay=1;
268                         static float gLoc[3];
269                         static float vel[3];
270                         gLoc[0]=headpos.x*(*scale)+coords->x;
271                         gLoc[1]=headpos.y*(*scale)+coords->y;
272                         gLoc[2]=headpos.z*(*scale)+coords->z;
273                         vel[0]=joints[jointlabels[head]].velocity.x;
274                         vel[1]=joints[jointlabels[head]].velocity.y;
275                         vel[2]=joints[jointlabels[head]].velocity.z;
276                         PlaySoundEx( landsound1, samp[landsound1], NULL, TRUE);
277                         FSOUND_3D_SetAttributes(channels[landsound1], gLoc, vel);
278                         FSOUND_SetVolume(channels[landsound1], 128);
279                         FSOUND_SetPaused(channels[landsound1], FALSE);
280
281                         breaking=1;
282                         }
283
284                         if(joints[jointlabels[head]].label==head&&!joints[jointlabels[head]].locked&&joints[jointlabels[head]].delay<=0){
285                         joints[jointlabels[head]].locked=1;
286                         joints[jointlabels[head]].delay=1;
287                         static float gLoc[3];
288                         static float vel[3];
289                         gLoc[0]=headpos.x*(*scale)+coords->x;
290                         gLoc[1]=headpos.y*(*scale)+coords->y;
291                         gLoc[2]=headpos.z*(*scale)+coords->z;
292                         vel[0]=joints[jointlabels[head]].velocity.x;
293                         vel[1]=joints[jointlabels[head]].velocity.y;
294                         vel[2]=joints[jointlabels[head]].velocity.z;
295                         PlaySoundEx( landsound2, samp[landsound2], NULL, TRUE);
296                         FSOUND_3D_SetAttributes(channels[landsound2], gLoc, vel);
297                         FSOUND_SetVolume(channels[landsound2], 128);
298                         FSOUND_SetPaused(channels[landsound2], FALSE);
299                         }
300
301                         terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0)*-1;
302                         if(terrainnormal.y>.8)freefall=0;
303                         bounceness=terrainnormal*findLength(&joints[jointlabels[head]].velocity)*(abs(normaldotproduct(joints[jointlabels[head]].velocity,terrainnormal)));
304                         if(findLengthfast(&joints[jointlabels[head]].velocity)>findLengthfast(&joints[jointlabels[head]].oldvelocity)){
305                         bounceness=0;
306                         joints[jointlabels[head]].velocity=joints[jointlabels[head]].oldvelocity;
307                         }
308                         if(findLengthfast(&bounceness)>4000&&breaking){
309                         objects.model[k].MakeDecal(breakdecal,DoRotation(temp-objects.position[k],0,-objects.rotation[k],0),.4,.5,Random()%360);
310                         sprites.MakeSprite(cloudsprite, headpos*(*scale)+*coords,joints[jointlabels[head]].velocity*.06, 1,1,1, 4, .2);
311                         breaking=0;
312                         camerashake+=.6;
313
314                         static float gLoc[3];
315                         static float vel[3];
316                         gLoc[0]=headpos.x*(*scale)+coords->x;
317                         gLoc[1]=headpos.y*(*scale)+coords->y;
318                         gLoc[2]=headpos.z*(*scale)+coords->z;
319                         vel[0]=joints[jointlabels[head]].velocity.x;
320                         vel[1]=joints[jointlabels[head]].velocity.y;
321                         vel[2]=joints[jointlabels[head]].velocity.z;
322                         PlaySoundEx( breaksound2, samp[breaksound2], NULL, TRUE);
323                         FSOUND_3D_SetAttributes(channels[breaksound2], gLoc, vel);
324                         FSOUND_SetVolume(channels[breaksound2], 300);
325                         FSOUND_SetPaused(channels[breaksound2], FALSE);
326
327                         envsound[numenvsounds]=*coords;
328                         envsoundvol[numenvsounds]=64;
329                         envsoundlife[numenvsounds]=.4;
330                         numenvsounds++;
331                         }
332                         if(objects.type[k]==treetrunktype){
333                         objects.rotx[k]+=joints[jointlabels[head]].velocity.x*multiplier*.4;
334                         objects.roty[k]+=joints[jointlabels[head]].velocity.z*multiplier*.4;
335                         objects.rotx[k+1]+=joints[jointlabels[head]].velocity.x*multiplier*.4;
336                         objects.roty[k+1]+=joints[jointlabels[head]].velocity.z*multiplier*.4;
337                         }
338                         if(!joints[jointlabels[head]].locked)damage+=findLengthfast(&bounceness)/2500;
339                         ReflectVector(&joints[jointlabels[head]].velocity,&terrainnormal);
340                         frictionness=abs(normaldotproduct(joints[jointlabels[head]].velocity,terrainnormal));//findLength(&bounceness)/findLength(&joints[jointlabels[head]].velocity);
341                         joints[jointlabels[head]].velocity-=bounceness;
342                         if(1-friction*frictionness>0)joints[jointlabels[head]].velocity*=1-friction*frictionness;
343                         else joints[jointlabels[head]].velocity=0;
344                         if(findLengthfast(&bounceness)>2500){
345                         Normalise(&bounceness);
346                         bounceness=bounceness*50;
347                         }
348                         joints[jointlabels[head]].velocity+=bounceness*elasticity;
349
350
351                         if(!joints[jointlabels[head]].locked)
352                         if(findLengthfast(&joints[jointlabels[head]].velocity)<1){
353                         joints[jointlabels[head]].locked=1;
354                         //joints[jointlabels[head]].velocity*=3;
355                         }
356                         if(findLengthfast(&bounceness)>500)sprites.MakeSprite(cloudsprite, headpos*(*scale)+*coords,joints[jointlabels[head]].velocity*.06, 1,1,1, .5, .2);
357                         joints[jointlabels[head]].position=(temp-*coords)/(*scale)+(startheadpos-headpos)+terrainnormal*.005;
358                         if(longdead>100)broken=1;
359                         }
360                         }
361                         }
362                         */
363
364                         for(i=0; i<num_joints; i++){
365                                 //joints[i].delay-=multiplier/1.5;
366                                 if(joints[i].locked)
367                                         if(!spinny)if(findLengthfast(&joints[i].velocity)>320)joints[i].locked=0;
368                                 if(spinny)if(findLengthfast(&joints[i].velocity)>600)joints[i].locked=0;
369                                 if(joints[i].delay>0){
370                                         freely=1;
371                                         for(j=0;j<num_joints;j++){
372                                                 if(joints[j].locked)freely=0;
373                                         }
374                                         if(freely)joints[i].delay-=multiplier*3;
375                                 }
376                                 //if(joints[i].delay>0)
377                                 //if(findLengthfast(&joints[i].velocity)>700&&joints[i].label!=head)joints[i].delay-=multiplier;
378                         }
379
380                         if(num_muscles)
381                                 for(i=0; i<num_muscles; i++){
382                                         //Length constraints
383                                         //muscles[i].DoConstraint(broken);
384                                         muscles[i].DoConstraint(spinny);
385                                 }
386
387                                 for(i=0; i<num_joints; i++){
388                                         //joints[i].delay-=multiplier/1.5;
389                                         //Length constraints
390                                         //Ground constraint
391                                         groundlevel=0;
392                                         if(joints[i].position.y*(*scale)+coords->y<terrain.getHeight(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z)+groundlevel){
393                                                 freefall=0;
394                                                 friction=1.5;
395                                                 if(joints[i].label==groin&&!joints[i].locked&&joints[i].delay<=0){
396                                                         joints[i].locked=1;
397                                                         joints[i].delay=1;
398                                                         static float gLoc[3];
399                                                         static float vel[3];
400                                                         gLoc[0]=joints[i].position.x*(*scale)+coords->x;
401                                                         gLoc[1]=joints[i].position.y*(*scale)+coords->y;
402                                                         gLoc[2]=joints[i].position.z*(*scale)+coords->z;
403                                                         vel[0]=joints[i].velocity.x;
404                                                         vel[1]=joints[i].velocity.y;
405                                                         vel[2]=joints[i].velocity.z;
406                                                         if(tutoriallevel!=1||id==0){
407                                                                 PlaySoundEx( landsound1, samp[landsound1], NULL, TRUE);
408                                                                 FSOUND_3D_SetAttributes(channels[landsound1], gLoc, vel);
409                                                                 FSOUND_SetVolume(channels[landsound1], 128);
410                                                                 FSOUND_SetPaused(channels[landsound1], FALSE);
411                                                         }
412                                                         breaking=1;
413                                                 }
414
415                                                 if(joints[i].label==head&&!joints[i].locked&&joints[i].delay<=0){
416                                                         joints[i].locked=1;
417                                                         joints[i].delay=1;
418                                                         static float gLoc[3];
419                                                         static float vel[3];
420                                                         gLoc[0]=joints[i].position.x*(*scale)+coords->x;
421                                                         gLoc[1]=joints[i].position.y*(*scale)+coords->y;
422                                                         gLoc[2]=joints[i].position.z*(*scale)+coords->z;
423                                                         vel[0]=joints[i].velocity.x;
424                                                         vel[1]=joints[i].velocity.y;
425                                                         vel[2]=joints[i].velocity.z;
426                                                         if(tutoriallevel!=1||id==0){
427                                                                 PlaySoundEx( landsound2, samp[landsound2], NULL, TRUE);
428                                                                 FSOUND_3D_SetAttributes(channels[landsound2], gLoc, vel);
429                                                                 FSOUND_SetVolume(channels[landsound2], 128);
430                                                                 FSOUND_SetPaused(channels[landsound2], FALSE);
431                                                         }
432                                                 }
433
434                                                 terrainnormal=terrain.getNormal(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z);
435                                                 ReflectVector(&joints[i].velocity,&terrainnormal);
436                                                 bounceness=terrainnormal*findLength(&joints[i].velocity)*(abs(normaldotproduct(joints[i].velocity,terrainnormal)));
437                                                 if(!joints[i].locked)damage+=findLengthfast(&bounceness)/4000;
438                                                 if(findLengthfast(&joints[i].velocity)<findLengthfast(&bounceness))bounceness=0;
439                                                 frictionness=abs(normaldotproduct(joints[i].velocity,terrainnormal));//findLength(&bounceness)/findLength(&joints[i].velocity);
440                                                 joints[i].velocity-=bounceness;
441                                                 if(1-friction*frictionness>0)joints[i].velocity*=1-friction*frictionness;
442                                                 else joints[i].velocity=0;
443
444                                                 if(tutoriallevel!=1||id==0)
445                                                         if(findLengthfast(&bounceness)>8000&&breaking){
446                                                                 objects.model[k].MakeDecal(breakdecal,DoRotation(temp-objects.position[k],0,-objects.rotation[k],0),.4,.5,Random()%360);
447                                                                 sprites.MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, 1,1,1, 4, .2);
448                                                                 //sprites.MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, 1,1,1, 1, .2);
449                                                                 breaking=0;
450                                                                 camerashake+=.6;
451
452                                                                 static float gLoc[3];
453                                                                 static float vel[3];
454                                                                 gLoc[0]=joints[i].position.x*(*scale)+coords->x;
455                                                                 gLoc[1]=joints[i].position.y*(*scale)+coords->y;
456                                                                 gLoc[2]=joints[i].position.z*(*scale)+coords->z;
457                                                                 vel[0]=joints[i].velocity.x;
458                                                                 vel[1]=joints[i].velocity.y;
459                                                                 vel[2]=joints[i].velocity.z;
460                                                                 PlaySoundEx( breaksound2, samp[breaksound2], NULL, TRUE);
461                                                                 FSOUND_3D_SetAttributes(channels[breaksound2], gLoc, vel);
462                                                                 FSOUND_SetVolume(channels[breaksound2], 300);
463                                                                 FSOUND_SetPaused(channels[breaksound2], FALSE);
464
465                                                                 envsound[numenvsounds]=*coords;
466                                                                 envsoundvol[numenvsounds]=64;
467                                                                 envsoundlife[numenvsounds]=.4;
468                                                                 numenvsounds++;
469                                                         }
470
471                                                         if(findLengthfast(&bounceness)>2500){
472                                                                 Normalise(&bounceness);
473                                                                 bounceness=bounceness*50;
474                                                         }       
475
476                                                         joints[i].velocity+=bounceness*elasticity;
477
478                                                         if(findLengthfast(&joints[i].velocity)>findLengthfast(&joints[i].oldvelocity)){
479                                                                 bounceness=0;
480                                                                 joints[i].velocity=joints[i].oldvelocity;
481                                                         }
482
483
484                                                         if(joints[i].locked==0)
485                                                                 if(findLengthfast(&joints[i].velocity)<1)joints[i].locked=1;
486
487                                                         if(environment==snowyenvironment&&findLengthfast(&bounceness)>500&&terrain.getOpacity(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z)<.2){
488                                                                 terrainlight=terrain.getLighting(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z);
489                                                                 sprites.MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, terrainlight.x,terrainlight.y,terrainlight.z, .5, .7);
490                                                                 if(detail==2)terrain.MakeDecal(bodyprintdecal, joints[i].position*(*scale)+*coords,.4,.4,0);
491                                                         }
492                                                         else if(environment==desertenvironment&&findLengthfast(&bounceness)>500&&terrain.getOpacity(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z)<.2){
493                                                                 terrainlight=terrain.getLighting(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z);
494                                                                 sprites.MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, terrainlight.x*190/255,terrainlight.y*170/255,terrainlight.z*108/255, .5, .7);
495                                                         }
496
497                                                         else if(environment==grassyenvironment&&findLengthfast(&bounceness)>500&&terrain.getOpacity(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z)<.2){
498                                                                 terrainlight=terrain.getLighting(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z);
499                                                                 sprites.MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, terrainlight.x*90/255,terrainlight.y*70/255,terrainlight.z*8/255, .5, .5);
500                                                         }
501                                                         else if(findLengthfast(&bounceness)>500)sprites.MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, terrainlight.x,terrainlight.y,terrainlight.z, .5, .2);
502
503
504                                                         joints[i].position.y=(terrain.getHeight(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z)+groundlevel-coords->y)/(*scale);
505                                                         if(longdead>100)broken=1;
506                                         }
507                                         if(terrain.patchobjectnum[whichpatchx][whichpatchz])
508                                                 for(m=0;m<terrain.patchobjectnum[whichpatchx][whichpatchz];m++){
509                                                         k=terrain.patchobjects[whichpatchx][whichpatchz][m];
510                                                         if(k<objects.numobjects&&k>=0)
511                                                                 if(objects.possible[k]){
512                                                                         friction=objects.friction[k];
513                                                                         start=joints[i].realoldposition;
514                                                                         end=joints[i].position*(*scale)+*coords;
515                                                                         whichhit=objects.model[k].LineCheckPossible(&start,&end,&temp,&objects.position[k],&objects.rotation[k]);
516                                                                         if(whichhit!=-1){
517                                                                                 if(joints[i].label==groin&&!joints[i].locked&&joints[i].delay<=0){
518                                                                                         joints[i].locked=1;
519                                                                                         joints[i].delay=1;
520                                                                                         static float gLoc[3];
521                                                                                         static float vel[3];
522                                                                                         gLoc[0]=joints[i].position.x*(*scale)+coords->x;
523                                                                                         gLoc[1]=joints[i].position.y*(*scale)+coords->y;
524                                                                                         gLoc[2]=joints[i].position.z*(*scale)+coords->z;
525                                                                                         vel[0]=joints[i].velocity.x;
526                                                                                         vel[1]=joints[i].velocity.y;
527                                                                                         vel[2]=joints[i].velocity.z;
528                                                                                         if(tutoriallevel!=1||id==0){
529                                                                                                 PlaySoundEx( landsound1, samp[landsound1], NULL, TRUE);
530                                                                                                 FSOUND_3D_SetAttributes(channels[landsound1], gLoc, vel);
531                                                                                                 FSOUND_SetVolume(channels[landsound1], 128);
532                                                                                                 FSOUND_SetPaused(channels[landsound1], FALSE);
533                                                                                         }
534                                                                                         breaking=1;
535                                                                                 }
536
537                                                                                 if(joints[i].label==head&&!joints[i].locked&&joints[i].delay<=0){
538                                                                                         joints[i].locked=1;
539                                                                                         joints[i].delay=1;
540                                                                                         static float gLoc[3];
541                                                                                         static float vel[3];
542                                                                                         gLoc[0]=joints[i].position.x*(*scale)+coords->x;
543                                                                                         gLoc[1]=joints[i].position.y*(*scale)+coords->y;
544                                                                                         gLoc[2]=joints[i].position.z*(*scale)+coords->z;
545                                                                                         vel[0]=joints[i].velocity.x;
546                                                                                         vel[1]=joints[i].velocity.y;
547                                                                                         vel[2]=joints[i].velocity.z;
548                                                                                         if(tutoriallevel!=1||id==0){
549                                                                                                 PlaySoundEx( landsound2, samp[landsound2], NULL, TRUE);
550                                                                                                 FSOUND_3D_SetAttributes(channels[landsound2], gLoc, vel);
551                                                                                                 FSOUND_SetVolume(channels[landsound2], 128);
552                                                                                                 FSOUND_SetPaused(channels[landsound2], FALSE);
553                                                                                         }
554                                                                                 }
555
556                                                                                 terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0)*-1;
557                                                                                 if(terrainnormal.y>.8)freefall=0;
558                                                                                 bounceness=terrainnormal*findLength(&joints[i].velocity)*(abs(normaldotproduct(joints[i].velocity,terrainnormal)));
559                                                                                 if(findLengthfast(&joints[i].velocity)>findLengthfast(&joints[i].oldvelocity)){
560                                                                                         bounceness=0;
561                                                                                         joints[i].velocity=joints[i].oldvelocity;
562                                                                                 }
563                                                                                 if(tutoriallevel!=1||id==0)
564                                                                                         if(findLengthfast(&bounceness)>4000&&breaking){
565                                                                                                 objects.model[k].MakeDecal(breakdecal,DoRotation(temp-objects.position[k],0,-objects.rotation[k],0),.4,.5,Random()%360);
566                                                                                                 sprites.MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, 1,1,1, 4, .2);
567                                                                                                 breaking=0;
568                                                                                                 camerashake+=.6;
569
570                                                                                                 static float gLoc[3];
571                                                                                                 static float vel[3];
572                                                                                                 gLoc[0]=joints[i].position.x*(*scale)+coords->x;
573                                                                                                 gLoc[1]=joints[i].position.y*(*scale)+coords->y;
574                                                                                                 gLoc[2]=joints[i].position.z*(*scale)+coords->z;
575                                                                                                 vel[0]=joints[i].velocity.x;
576                                                                                                 vel[1]=joints[i].velocity.y;
577                                                                                                 vel[2]=joints[i].velocity.z;
578                                                                                                 PlaySoundEx( breaksound2, samp[breaksound2], NULL, TRUE);
579                                                                                                 FSOUND_3D_SetAttributes(channels[breaksound2], gLoc, vel);
580                                                                                                 FSOUND_SetVolume(channels[breaksound2], 300);
581                                                                                                 FSOUND_SetPaused(channels[breaksound2], FALSE);
582
583                                                                                                 envsound[numenvsounds]=*coords;
584                                                                                                 envsoundvol[numenvsounds]=64;
585                                                                                                 envsoundlife[numenvsounds]=.4;
586                                                                                                 numenvsounds++;
587                                                                                         }
588                                                                                         if(objects.type[k]==treetrunktype){
589                                                                                                 //if(objects.rotx[k]==0||objects.roty[k]==0){
590                                                                                                 /*int howmany;
591                                                                                                 XYZ tempvel;
592                                                                                                 XYZ pos;
593                                                                                                 if(environment==grassyenvironment)howmany=findLength(&joints[i].velocity)*4/10;
594                                                                                                 if(environment==snowyenvironment)howmany=findLength(&joints[i].velocity)*1/10;
595                                                                                                 if(environment!=desertenvironment)
596                                                                                                 for(j=0;j<howmany;j++){
597                                                                                                 tempvel.x=float(abs(Random()%100)-50)/20;
598                                                                                                 tempvel.y=float(abs(Random()%100)-50)/20;
599                                                                                                 tempvel.z=float(abs(Random()%100)-50)/20;
600                                                                                                 pos=objects.position[k];
601                                                                                                 pos.y+=objects.scale[k]*15;
602                                                                                                 pos.x+=float(abs(Random()%100)-50)/100*objects.scale[k]*5;
603                                                                                                 pos.y+=float(abs(Random()%100)-50)/100*objects.scale[k]*15;
604                                                                                                 pos.z+=float(abs(Random()%100)-50)/100*objects.scale[k]*5;
605                                                                                                 sprites.MakeSprite(splintersprite, pos,tempvel*.5, 165/255+float(abs(Random()%100)-50)/400,0,0, .2+float(abs(Random()%100)-50)/1300, 1);
606                                                                                                 sprites.special[sprites.numsprites-1]=1;
607                                                                                                 }*/
608                                                                                                 objects.rotx[k]+=joints[i].velocity.x*multiplier*.4;
609                                                                                                 objects.roty[k]+=joints[i].velocity.z*multiplier*.4;
610                                                                                                 objects.rotx[k+1]+=joints[i].velocity.x*multiplier*.4;
611                                                                                                 objects.roty[k+1]+=joints[i].velocity.z*multiplier*.4;
612                                                                                         }
613                                                                                         if(!joints[i].locked)damage+=findLengthfast(&bounceness)/2500;
614                                                                                         ReflectVector(&joints[i].velocity,&terrainnormal);
615                                                                                         frictionness=abs(normaldotproduct(joints[i].velocity,terrainnormal));//findLength(&bounceness)/findLength(&joints[i].velocity);
616                                                                                         joints[i].velocity-=bounceness;
617                                                                                         if(1-friction*frictionness>0)joints[i].velocity*=1-friction*frictionness;
618                                                                                         else joints[i].velocity=0;
619                                                                                         if(findLengthfast(&bounceness)>2500){
620                                                                                                 Normalise(&bounceness);
621                                                                                                 bounceness=bounceness*50;
622                                                                                         }
623                                                                                         joints[i].velocity+=bounceness*elasticity;
624
625
626                                                                                         if(!joints[i].locked)
627                                                                                                 if(findLengthfast(&joints[i].velocity)<1){
628                                                                                                         joints[i].locked=1;
629                                                                                                         //joints[i].velocity*=3;
630                                                                                                 }
631                                                                                                 if(findLengthfast(&bounceness)>500)sprites.MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, 1,1,1, .5, .2);
632                                                                                                 joints[i].position=(temp-*coords)/(*scale)+terrainnormal*.005;
633                                                                                                 if(longdead>100)broken=1;
634                                                                         }
635                                                                 }
636                                                 }
637                                                 joints[i].realoldposition=joints[i].position*(*scale)+*coords;
638                                 }
639                 }
640                 multiplier=tempmult;
641
642
643                 if(terrain.patchobjectnum[whichpatchx][whichpatchz])
644                         for(m=0;m<terrain.patchobjectnum[whichpatchx][whichpatchz];m++){
645                                 k=terrain.patchobjects[whichpatchx][whichpatchz][m];
646                                 if(objects.possible[k]){
647                                         for(i=0;i<26;i++){
648                                                 //Make this less stupid
649                                                 start=joints[jointlabels[whichjointstartarray[i]]].position*(*scale)+*coords;
650                                                 end=joints[jointlabels[whichjointendarray[i]]].position*(*scale)+*coords;
651                                                 whichhit=objects.model[k].LineCheckSlidePossible(&start,&end,&temp,&objects.position[k],&objects.rotation[k]);
652                                                 if(whichhit!=-1){
653                                                         joints[jointlabels[whichjointendarray[i]]].position=(end-*coords)/(*scale);
654                                                         for(j=0; j<num_muscles; j++){
655                                                                 if((muscles[j].parent1->label==whichjointstartarray[i]&&muscles[j].parent2->label==whichjointendarray[i])||(muscles[j].parent2->label==whichjointstartarray[i]&&muscles[j].parent1->label==whichjointendarray[i]))
656                                                                         muscles[j].DoConstraint(spinny);
657                                                         }
658                                                 }
659                                         }
660                                 }
661                         }
662
663                         for(i=0; i<num_joints; i++){
664                                 groundlevel=.15;
665                                 if(joints[i].label==head)groundlevel=.8;        
666                                 if(joints[i].label==righthand||joints[i].label==rightwrist||joints[i].label==rightelbow)groundlevel=.2; 
667                                 if(joints[i].label==lefthand||joints[i].label==leftwrist||joints[i].label==leftelbow)groundlevel=.2;                    
668                                 joints[i].position.y+=groundlevel;
669                                 joints[i].mass=1;
670                                 if(joints[i].label==lefthip||joints[i].label==leftknee||joints[i].label==leftankle||joints[i].label==righthip||joints[i].label==rightknee||joints[i].label==rightankle)joints[i].mass=2;
671                                 if(joints[i].locked){
672                                         joints[i].mass=4;
673                                 }
674                         }
675
676                         return damage;
677         }
678         if(!free){
679                 for(i=0; i<num_muscles; i++){
680                         if(muscles[i].type==boneconnect)
681                                 muscles[i].DoConstraint(0);
682                 }
683         }
684         return 0;
685 }
686
687 void Skeleton::DoGravity(float *scale)
688 {
689         static int i;
690         for(i=0; i<num_joints; i++){
691                 if(((joints[i].label!=leftknee&&joints[i].label!=rightknee)||lowforward.y>-.1||joints[i].mass<5)&&((joints[i].label!=rightelbow&&joints[i].label!=rightelbow)||forward.y<.3))joints[i].velocity.y+=gravity*multiplier/(*scale);
692         }
693 }
694
695 void Skeleton::Draw(int  muscleview)
696 {
697         static float jointcolor[4];
698
699         if(muscleview!=2){
700                 jointcolor[0]=0;
701                 jointcolor[1]=0;
702                 jointcolor[2]=.5;
703                 jointcolor[3]=1;
704         }
705
706         if(muscleview==2){
707                 jointcolor[0]=0;
708                 jointcolor[1]=0;
709                 jointcolor[2]=0;
710                 jointcolor[3]=.5;
711         }
712         //Calc motionblur-ness
713         for(int i=0; i<num_joints; i++){
714                 joints[i].oldposition=joints[i].position;
715                 joints[i].blurred=findDistance(&joints[i].position,&joints[i].oldposition)*100;
716                 if(joints[i].blurred<1)joints[i].blurred=1;
717         }
718
719         //Do Motionblur
720         glDepthMask(0);
721         glEnable(GL_BLEND);
722         glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
723         glBegin(GL_QUADS);
724         for(int i=0; i<num_joints; i++){
725                 if(joints[i].hasparent){
726                         glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].blurred);
727                         glVertex3f(joints[i].position.x,joints[i].position.y,joints[i].position.z);
728                         glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].parent->blurred);
729                         glVertex3f(joints[i].parent->position.x,joints[i].parent->position.y,joints[i].parent->position.z);
730                         glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].parent->blurred);
731                         glVertex3f(joints[i].parent->oldposition.x,joints[i].parent->oldposition.y,joints[i].parent->oldposition.z);
732                         glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].blurred);
733                         glVertex3f(joints[i].oldposition.x,joints[i].oldposition.y,joints[i].oldposition.z);
734                 }
735         }
736         for(int i=0; i<num_muscles; i++){
737                 if(muscles[i].type==boneconnect){
738                         glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent2->blurred);
739                         glVertex3f(muscles[i].parent1->position.x,muscles[i].parent1->position.y,muscles[i].parent1->position.z);
740                         glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent2->blurred);
741                         glVertex3f(muscles[i].parent2->position.x,muscles[i].parent2->position.y,muscles[i].parent2->position.z);
742                         glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent2->blurred);
743                         glVertex3f(muscles[i].parent2->oldposition.x,muscles[i].parent2->oldposition.y,muscles[i].parent2->oldposition.z);
744                         glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent1->blurred);
745                         glVertex3f(muscles[i].parent1->oldposition.x,muscles[i].parent1->oldposition.y,muscles[i].parent1->oldposition.z);
746                 }
747         }
748         glEnd();
749
750         glBegin(GL_LINES);
751         for(int i=0; i<num_joints; i++){
752                 if(joints[i].hasparent){
753                         glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].blurred);
754                         glVertex3f(joints[i].position.x,joints[i].position.y,joints[i].position.z);
755                         glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].parent->blurred);
756                         glVertex3f(joints[i].parent->position.x,joints[i].parent->position.y,joints[i].parent->position.z);
757                 }
758         }
759         /*for(int i=0; i<num_joints; i++){
760         if(joints[i].hasparent){
761         glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],1);
762         glVertex3f(joints[i].position.x,joints[i].position.y,joints[i].position.z);
763         glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],1);
764         glVertex3f(joints[i].position.x+forward.x,joints[i].position.y+forward.y,joints[i].position.z+forward.z);
765         }
766         }*/
767         for(int i=0; i<num_muscles; i++){
768                 if(muscles[i].type==boneconnect){
769                         glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent1->blurred);
770                         glVertex3f(muscles[i].parent1->position.x,muscles[i].parent1->position.y,muscles[i].parent1->position.z);
771                         glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent2->blurred);
772                         glVertex3f(muscles[i].parent2->position.x,muscles[i].parent2->position.y,muscles[i].parent2->position.z);
773                 }
774         }
775         glColor3f(.6,.6,0);
776         if(muscleview==1)
777                 for(int i=0; i<num_muscles; i++){
778                         if(muscles[i].type!=boneconnect){
779                                 glVertex3f(muscles[i].parent1->position.x,muscles[i].parent1->position.y,muscles[i].parent1->position.z);
780                                 glVertex3f(muscles[i].parent2->position.x,muscles[i].parent2->position.y,muscles[i].parent2->position.z);
781                         }
782                 }       
783                 glEnd();
784
785                 if(muscleview!=2){
786                         glPointSize(3);
787                         glBegin(GL_POINTS);
788                         for(int i=0; i<num_joints; i++){
789                                 if(i!=selected)glColor4f(0,0,.5,1);
790                                 if(i==selected)glColor4f(1,1,0,1);
791                                 if(joints[i].locked&&i!=selected)glColor4f(1,0,0,1);
792                                 glVertex3f(joints[i].position.x,joints[i].position.y,joints[i].position.z);
793                         }
794                         glEnd();
795                 }
796
797                 //Set old position to current position
798                 if(muscleview==2)
799                         for(int i=0; i<num_joints; i++){
800                                 joints[i].oldposition=joints[i].position;
801                         }
802                         glDepthMask(1);
803 }
804
805 void Skeleton::AddJoint(float x, float y, float z, int which)
806 {
807         if(num_joints<max_joints-1){
808                 joints[num_joints].velocity=0;
809                 joints[num_joints].position.x=x;
810                 joints[num_joints].position.y=y;
811                 joints[num_joints].position.z=z;
812                 joints[num_joints].mass=1;
813                 joints[num_joints].locked=0;
814
815                 /*if(which>=num_joints||which<0)*/joints[num_joints].hasparent=0;
816                 /*if(which<num_joints&&which>=0){
817                 joints[num_joints].parent=&joints[which];
818                 joints[num_joints].hasparent=1;
819                 joints[num_joints].length=findDistance(joints[num_joints].position,joints[num_joints].parent->position);
820                 }*/
821                 num_joints++;
822                 if(which<num_joints&&which>=0)AddMuscle(num_joints-1,which,0,10,boneconnect);
823         }
824 }
825
826 void Skeleton::DeleteJoint(int whichjoint)
827 {
828         if(whichjoint<num_joints&&whichjoint>=0){
829                 joints[whichjoint].velocity=joints[num_joints-1].velocity;
830                 joints[whichjoint].position=joints[num_joints-1].position;
831                 joints[whichjoint].oldposition=joints[num_joints-1].oldposition;
832                 joints[whichjoint].hasparent=joints[num_joints-1].hasparent;
833                 joints[whichjoint].parent=joints[num_joints-1].parent;
834                 joints[whichjoint].length=joints[num_joints-1].length;
835                 joints[whichjoint].locked=joints[num_joints-1].locked;
836                 joints[whichjoint].modelnum=joints[num_joints-1].modelnum;
837                 joints[whichjoint].visible=joints[num_joints-1].visible;
838
839                 for(int i=0;i<num_muscles;i++){
840                         while(muscles[i].parent1==&joints[whichjoint]&&i<num_muscles)DeleteMuscle(i);
841                         while(muscles[i].parent2==&joints[whichjoint]&&i<num_muscles)DeleteMuscle(i);
842                 }
843                 for(int i=0;i<num_muscles;i++){
844                         while(muscles[i].parent1==&joints[num_joints-1]&&i<num_muscles)muscles[i].parent1=&joints[whichjoint];
845                         while(muscles[i].parent2==&joints[num_joints-1]&&i<num_muscles)muscles[i].parent2=&joints[whichjoint];
846                 }
847                 for(int i=0;i<num_joints;i++){
848                         if(joints[i].parent==&joints[whichjoint])joints[i].hasparent=0;
849                 }
850                 for(int i=0;i<num_joints;i++){
851                         if(joints[i].parent==&joints[num_joints-1])joints[i].parent=&joints[whichjoint];
852                 }
853
854                 num_joints--;
855         }
856 }
857
858 void Skeleton::DeleteMuscle(int whichmuscle)
859 {
860         if(whichmuscle<num_muscles){
861                 muscles[whichmuscle].minlength=muscles[num_muscles-1].minlength;
862                 muscles[whichmuscle].maxlength=muscles[num_muscles-1].maxlength;
863                 muscles[whichmuscle].strength=muscles[num_muscles-1].strength;
864                 muscles[whichmuscle].parent1=muscles[num_muscles-1].parent1;
865                 muscles[whichmuscle].parent2=muscles[num_muscles-1].parent2;
866                 muscles[whichmuscle].length=muscles[num_muscles-1].length;
867                 muscles[whichmuscle].visible=muscles[num_muscles-1].visible;
868                 muscles[whichmuscle].type=muscles[num_muscles-1].type;
869                 muscles[whichmuscle].targetlength=muscles[num_muscles-1].targetlength;
870
871                 num_muscles--;
872         }
873 }
874
875 void Skeleton::SetJoint(float x, float y, float z, int which, int whichjoint)
876 {
877         if(whichjoint<num_joints){
878                 joints[whichjoint].velocity=0;
879                 joints[whichjoint].position.x=x;
880                 joints[whichjoint].position.y=y;
881                 joints[whichjoint].position.z=z;
882
883                 if(which>=num_joints||which<0)joints[whichjoint].hasparent=0;
884                 if(which<num_joints&&which>=0){
885                         joints[whichjoint].parent=&joints[which];
886                         joints[whichjoint].hasparent=1;
887                         joints[whichjoint].length=findDistance(&joints[whichjoint].position,&joints[whichjoint].parent->position);
888                 }       
889         }
890 }
891
892 void Skeleton::AddMuscle(int attach1,int attach2,float minlength,float maxlength,int type)
893 {
894         if(num_muscles<max_muscles-1&&attach1<num_joints&&attach1>=0&&attach2<num_joints&&attach2>=0&&attach1!=attach2){
895                 muscles[num_muscles].parent1=&joints[attach1];
896                 muscles[num_muscles].parent2=&joints[attach2];
897                 muscles[num_muscles].length=findDistance(&muscles[num_muscles].parent1->position,&muscles[num_muscles].parent2->position);
898                 muscles[num_muscles].targetlength=findDistance(&muscles[num_muscles].parent1->position,&muscles[num_muscles].parent2->position);
899                 muscles[num_muscles].strength=.7;
900                 muscles[num_muscles].type=type;
901                 muscles[num_muscles].minlength=minlength;
902                 muscles[num_muscles].maxlength=maxlength;
903
904                 num_muscles++;
905         }
906 }
907
908 void Skeleton::MusclesSet()
909 {
910         for(int i=0;i<num_muscles;i++){
911                 muscles[i].length=findDistance(&muscles[i].parent1->position,&muscles[i].parent2->position);
912         }
913 }
914
915 void Skeleton::DoBalance()
916 {
917         /*XYZ newpoint;
918         newpoint=joints[0].position;
919         newpoint.x=(joints[2].position.x+joints[4].position.x)/2;
920         newpoint.z=(joints[2].position.z+joints[4].position.z)/2;
921         joints[0].velocity=joints[0].velocity+(newpoint-joints[0].position);
922         //Move child point to within certain distance of parent point
923         joints[0].position=newpoint;
924
925         MusclesSet();*/
926 }
927
928 void Skeleton::FindRotationMuscle(int which, int animation)
929 {
930         static XYZ temppoint1,temppoint2,tempforward;
931         static float distance;
932
933         temppoint1=muscles[which].parent1->position;
934         temppoint2=muscles[which].parent2->position;
935         distance=sqrt((temppoint1.x-temppoint2.x)*(temppoint1.x-temppoint2.x)+(temppoint1.y-temppoint2.y)*(temppoint1.y-temppoint2.y)+(temppoint1.z-temppoint2.z)*(temppoint1.z-temppoint2.z));
936         if((temppoint1.y-temppoint2.y)<=distance)muscles[which].rotate2=asin((temppoint1.y-temppoint2.y)/distance);
937         if((temppoint1.y-temppoint2.y)>distance)muscles[which].rotate2=asin(1.f);
938         muscles[which].rotate2*=360/6.28;
939         temppoint1.y=0;
940         temppoint2.y=0;
941         distance=sqrt((temppoint1.x-temppoint2.x)*(temppoint1.x-temppoint2.x)+(temppoint1.y-temppoint2.y)*(temppoint1.y-temppoint2.y)+(temppoint1.z-temppoint2.z)*(temppoint1.z-temppoint2.z));
942         if((temppoint1.z-temppoint2.z)<=distance)muscles[which].rotate1=acos((temppoint1.z-temppoint2.z)/distance);
943         if((temppoint1.z-temppoint2.z)>distance)muscles[which].rotate1=acos(1.f);
944         muscles[which].rotate1*=360/6.28;
945         if(temppoint1.x>temppoint2.x)muscles[which].rotate1=360-muscles[which].rotate1;
946         if(!isnormal(muscles[which].rotate1))muscles[which].rotate1=0;
947         if(!isnormal(muscles[which].rotate2))muscles[which].rotate2=0;
948
949         if(muscles[which].parent1->label==head)tempforward=specialforward[0];
950         else if(muscles[which].parent1->label==rightshoulder||muscles[which].parent1->label==rightelbow||muscles[which].parent1->label==rightwrist||muscles[which].parent1->label==righthand)tempforward=specialforward[1];
951         else if(muscles[which].parent1->label==leftshoulder||muscles[which].parent1->label==leftelbow||muscles[which].parent1->label==leftwrist||muscles[which].parent1->label==lefthand)tempforward=specialforward[2];
952         else if(muscles[which].parent1->label==righthip||muscles[which].parent1->label==rightknee||muscles[which].parent1->label==rightankle||muscles[which].parent1->label==rightfoot)tempforward=specialforward[3];
953         else if(muscles[which].parent1->label==lefthip||muscles[which].parent1->label==leftknee||muscles[which].parent1->label==leftankle||muscles[which].parent1->label==leftfoot)tempforward=specialforward[4];
954         else if(!muscles[which].parent1->lower)tempforward=forward;
955         else if(muscles[which].parent1->lower)tempforward=lowforward;
956
957         if(animation==hanganim){
958                 if(muscles[which].parent1->label==righthand||muscles[which].parent2->label==righthand){
959                         tempforward=0;
960                         tempforward.x=-1;
961                 }
962                 if(muscles[which].parent1->label==lefthand||muscles[which].parent2->label==lefthand){
963                         tempforward=0;
964                         tempforward.x=1;
965                 }
966         }
967
968         if(free==0){
969                 if(muscles[which].parent1->label==rightfoot||muscles[which].parent2->label==rightfoot){
970                         tempforward.y-=.3;
971                 }
972                 if(muscles[which].parent1->label==leftfoot||muscles[which].parent2->label==leftfoot){
973                         tempforward.y-=.3;
974                 }
975         }
976
977
978         tempforward=DoRotation(tempforward,0,muscles[which].rotate1-90,0);
979         tempforward=DoRotation(tempforward,0,0,muscles[which].rotate2-90);
980         tempforward.y=0;
981         tempforward/=sqrt(tempforward.x*tempforward.x+tempforward.y*tempforward.y+tempforward.z*tempforward.z);
982         if(tempforward.z<=1&&tempforward.z>=-1)muscles[which].rotate3=acos(0-tempforward.z);
983         else muscles[which].rotate3=acos(-1.f);
984         muscles[which].rotate3*=360/6.28;
985         if(0>tempforward.x)muscles[which].rotate3=360-muscles[which].rotate3;
986         if(!isnormal(muscles[which].rotate3))muscles[which].rotate3=0;
987 }
988
989 void Animation::Load(char *filename, int aheight, int aattack)
990 {
991         static FILE *tfile;
992         static int i,j;
993         static XYZ startoffset,endoffset;
994         static int howmany;
995
996         LOGFUNC;
997
998         LOG(std::string("Loading animation...") + filename);
999
1000         deallocate();
1001
1002         height=aheight;
1003         attack=aattack;
1004
1005         if(visibleloading)pgame->LoadingScreen();
1006
1007         tfile=fopen( filename, "rb" );
1008         if(tfile){
1009                 funpackf(tfile, "Bi Bi", &numframes, &joints);
1010                 /*
1011                 for(i = 0; i < joints; i++){
1012                 if(position[i])dealloc2(position[i]);
1013                 if(twist[i])dealloc2(twist[i]);
1014                 if(twist2[i])dealloc2(twist2[i]);
1015                 if(onground[i])dealloc2(onground[i]);
1016                 }*/
1017                 /*
1018                 if(position)dealloc2(position);
1019                 if(twist)dealloc2(twist);
1020                 if(twist2)dealloc2(twist2);
1021                 if(speed)dealloc2(speed);
1022                 if(onground)dealloc2(onground);
1023                 if(forward)dealloc2(forward);
1024                 if(weapontarget)dealloc2(weapontarget);
1025                 if(label)dealloc2(label);*/
1026
1027                 position=(XYZ**)malloc(sizeof(XYZ*)*joints);
1028                 for(i = 0; i < joints; i++)
1029                         position[i] = (XYZ*)malloc(sizeof(XYZ)*numframes);
1030
1031                 twist=(float**)malloc(sizeof(float*)*joints);
1032                 for(i = 0; i < joints; i++)
1033                         twist[i] = (float*)malloc(sizeof(float)*numframes);
1034
1035                 twist2=(float**)malloc(sizeof(float*)*joints);
1036                 for(i = 0; i < joints; i++)
1037                         twist2[i] = (float*)malloc(sizeof(float)*numframes);
1038
1039                 speed = (float*)malloc(sizeof(float)*numframes);
1040
1041                 onground=(bool**)malloc(sizeof(bool*)*joints);
1042                 for(i = 0; i < joints; i++)
1043                         onground[i] =(bool*)malloc(sizeof(bool)*numframes);
1044
1045                 forward = (XYZ*)malloc(sizeof(XYZ)*numframes);
1046                 weapontarget = (XYZ*)malloc(sizeof(XYZ)*numframes);
1047                 label = (int*)malloc(sizeof(int)*numframes);
1048
1049                 /*position = new XYZ[joints][numframes];
1050                 twist = new float[joints][numframes];
1051                 twist2 = new float[joints][numframes];
1052                 speed = new float[numframes];
1053                 onground = new bool[joints][numframes];
1054                 forward = new XYZ[numframes];
1055                 label = new int[numframes];*/
1056
1057                 for(i=0;i<numframes;i++){
1058                         for(j=0;j<joints;j++){
1059                                 funpackf(tfile, "Bf Bf Bf", &position[j][i].x,&position[j][i].y,&position[j][i].z);
1060                         }
1061                         for(j=0;j<joints;j++){
1062                                 funpackf(tfile, "Bf", &twist[j][i]);
1063                         }
1064                         for(j=0;j<joints;j++){
1065                                 unsigned char uch;
1066                                 funpackf(tfile, "Bb", &uch);
1067                                 onground[j][i] = (uch != 0);
1068                         }
1069                         funpackf(tfile, "Bf", &speed[i]);
1070                 }
1071                 for(i=0;i<numframes;i++){
1072                         for(j=0;j<joints;j++){
1073                                 funpackf(tfile, "Bf", &twist2[j][i]);
1074                         }
1075                 }
1076                 for(i=0;i<numframes;i++){
1077                         funpackf(tfile, "Bf", &label[i]);
1078                 }
1079                 funpackf(tfile, "Bi", &weapontargetnum);
1080                 for(i=0;i<numframes;i++){
1081                         funpackf(tfile, "Bf Bf Bf", &weapontarget[i].x,&weapontarget[i].y,&weapontarget[i].z);
1082                 }
1083
1084                 fclose(tfile);  
1085         }
1086
1087         startoffset=0;
1088         endoffset=0;
1089         howmany=0;
1090         for(j=0;j<joints;j++){
1091                 if(position[j][0].y<1)
1092                         startoffset+=position[j][0];
1093                 if(position[j][numframes-1].y<1)
1094                         endoffset+=position[j][numframes-1];
1095                 howmany++;
1096         }
1097         startoffset/=howmany;
1098         endoffset/=howmany;
1099         offset=endoffset;
1100         offset.y=0;
1101 }
1102
1103
1104 void Animation::Move(XYZ how)
1105 {
1106         static int i,j,joints;
1107         for(i=0;i<numframes;i++){
1108                 for(j=0;j<joints;j++){
1109                         position[j][i]=0;
1110                 }
1111         }
1112 }
1113
1114 void Skeleton::Load(char *filename,char *lowfilename,char *clothesfilename, char *modelfilename, char *model2filename, char *model3filename, char *model4filename, char *model5filename, char *model6filename, char *model7filename, char *modellowfilename, char *modelclothesfilename, bool aclothes)
1115 {
1116         static GLfloat M[16];
1117         static int parentID;
1118         static FILE *tfile;
1119         static float lSize;
1120         static int i,j,tempmuscle;
1121         int newload;
1122         int edit;
1123
1124         LOGFUNC;
1125
1126         newload=0;
1127
1128         num_models=7;
1129
1130         clothes=aclothes;
1131
1132         for(i=0;i<num_models;i++){
1133                 if(i==0)model[i].loadnotex(modelfilename);
1134                 if(i==1)model[i].loadnotex(model2filename);
1135                 if(i==2)model[i].loadnotex(model3filename);
1136                 if(i==3)model[i].loadnotex(model4filename);
1137                 if(i==4)model[i].loadnotex(model5filename);
1138                 if(i==5)model[i].loadnotex(model6filename);
1139                 if(i==6)model[i].loadnotex(model7filename);
1140                 model[i].Rotate(180,0,0);
1141                 model[i].Scale(.04,.04,.04);
1142                 model[i].CalculateNormals(0);
1143         }
1144
1145         drawmodel.load(modelfilename,0);
1146         drawmodel.Rotate(180,0,0);
1147         drawmodel.Scale(.04,.04,.04);
1148         drawmodel.FlipTexCoords();
1149         if(tutoriallevel==1&&id!=0)drawmodel.UniformTexCoords();
1150         if(tutoriallevel==1&&id!=0)drawmodel.ScaleTexCoords(0.1);
1151         drawmodel.CalculateNormals(0);
1152
1153         modellow.loadnotex(modellowfilename);
1154         modellow.Rotate(180,0,0);
1155         modellow.Scale(.04,.04,.04);
1156         modellow.CalculateNormals(0);
1157
1158         drawmodellow.load(modellowfilename,0);
1159         drawmodellow.Rotate(180,0,0);
1160         drawmodellow.Scale(.04,.04,.04);
1161         drawmodellow.FlipTexCoords();
1162         if(tutoriallevel==1&&id!=0)drawmodellow.UniformTexCoords();
1163         if(tutoriallevel==1&&id!=0)drawmodellow.ScaleTexCoords(0.1);
1164         drawmodellow.CalculateNormals(0);
1165
1166         if(clothes){
1167                 modelclothes.loadnotex(modelclothesfilename);
1168                 modelclothes.Rotate(180,0,0);
1169                 modelclothes.Scale(.041,.04,.041);
1170                 modelclothes.CalculateNormals(0);
1171
1172                 drawmodelclothes.load(modelclothesfilename,0);
1173                 drawmodelclothes.Rotate(180,0,0);
1174                 drawmodelclothes.Scale(.04,.04,.04);
1175                 drawmodelclothes.FlipTexCoords();
1176                 drawmodelclothes.CalculateNormals(0);
1177         }
1178
1179         tfile=fopen( filename, "rb" );
1180         if(1){
1181                 funpackf(tfile, "Bi", &num_joints);
1182                 //joints.resize(num_joints);
1183                 if(joints) delete [] joints; //dealloc2(joints);
1184                 joints=(Joint*)new Joint[num_joints]; //malloc(sizeof(Joint)*num_joints);
1185
1186                 for(i=0;i<num_joints;i++){
1187                         funpackf(tfile, "Bf Bf Bf Bf Bf", &joints[i].position.x, &joints[i].position.y, &joints[i].position.z, &joints[i].length,&joints[i].mass);
1188                         funpackf(tfile, "Bb Bb", &joints[i].hasparent,&joints[i].locked);
1189                         funpackf(tfile, "Bi", &joints[i].modelnum);
1190                         funpackf(tfile, "Bb Bb", &joints[i].visible,&joints[i].sametwist);
1191                         funpackf(tfile, "Bi Bi", &joints[i].label,&joints[i].hasgun);
1192                         funpackf(tfile, "Bb", &joints[i].lower);
1193                         funpackf(tfile, "Bi", &parentID);
1194                         if(joints[i].hasparent)joints[i].parent=&joints[parentID];
1195                         joints[i].velocity=0;
1196                         joints[i].oldposition=joints[i].position;
1197                 }
1198                 tempmuscle=num_muscles;
1199                 funpackf(tfile, "Bi", &num_muscles);
1200                 //muscles.clear();
1201                 if(muscles) delete [] muscles; //dealloc2(muscles);
1202                 muscles=(Muscle*)new Muscle[num_muscles]; //malloc(sizeof(Muscle)*num_muscles);
1203                 newload=1;
1204                 for(i=0;i<num_muscles;i++){
1205                         tempmuscle=muscles[i].numvertices;
1206                         funpackf(tfile, "Bf Bf Bf Bf Bf Bi Bi", &muscles[i].length, &muscles[i].targetlength,&muscles[i].minlength, &muscles[i].maxlength,&muscles[i].strength,&muscles[i].type,&muscles[i].numvertices);
1207                         //muscles[i].vertices.clear();
1208                         //muscles[i].vertices.resize(muscles[i].numvertices);
1209                         //if(muscles[i].vertices)dealloc2(muscles[i].vertices);
1210                         muscles[i].vertices=(int*)malloc(sizeof(int)*muscles[i].numvertices);
1211
1212                         edit=0;
1213                         for(j=0;j<muscles[i].numvertices-edit;j++){
1214                                 funpackf(tfile, "Bi", &muscles[i].vertices[j+edit]);
1215                                 if(muscles[i].vertices[j+edit]>=model[0].vertexNum){
1216                                         muscles[i].numvertices--;
1217                                         edit--;
1218                                 }
1219                         }
1220                         funpackf(tfile, "Bb Bi", &muscles[i].visible, &parentID);
1221                         muscles[i].parent1=&joints[parentID];
1222                         funpackf(tfile, "Bi", &parentID);
1223                         muscles[i].parent2=&joints[parentID];
1224                 }
1225                 for(j=0;j<3;j++){
1226                         funpackf(tfile, "Bi", &forwardjoints[j]);
1227                 }
1228                 for(j=0;j<3;j++){
1229                         funpackf(tfile, "Bi", &lowforwardjoints[j]);
1230                 }
1231                 for(j=0;j<num_muscles;j++){
1232                         for(i=0;i<muscles[j].numvertices;i++){  
1233                                 for(int k=0;k<num_models;k++){                                          
1234                                         if(muscles[j].numvertices&&muscles[j].vertices[i]<model[k].vertexNum)model[k].owner[muscles[j].vertices[i]]=j;
1235                                 }
1236                         }
1237                 }
1238                 FindForwards();
1239                 for(i=0;i<num_joints;i++){
1240                         joints[i].startpos=joints[i].position;
1241                 }
1242                 for(i=0;i<num_muscles;i++){
1243                         FindRotationMuscle(i,-1);
1244                 }
1245                 for(int k=0;k<num_models;k++){
1246                         for(i=0;i<model[k].vertexNum;i++){
1247                                 model[k].vertex[i]=model[k].vertex[i]-(muscles[model[k].owner[i]].parent1->position+muscles[model[k].owner[i]].parent2->position)/2;
1248                                 glMatrixMode(GL_MODELVIEW);                                                     // Select The Modelview Matrix
1249                                 glPushMatrix();
1250                                         glLoadIdentity();
1251                                         glRotatef(muscles[model[k].owner[i]].rotate3,0,1,0);
1252                                         glRotatef(muscles[model[k].owner[i]].rotate2-90,0,0,1);
1253                                         glRotatef(muscles[model[k].owner[i]].rotate1-90,0,1,0);
1254                                         glTranslatef(model[k].vertex[i].x,model[k].vertex[i].y,model[k].vertex[i].z);
1255                                         glGetFloatv(GL_MODELVIEW_MATRIX,M);
1256                                         model[k].vertex[i].x=M[12]*1;
1257                                         model[k].vertex[i].y=M[13]*1;
1258                                         model[k].vertex[i].z=M[14]*1;
1259                                 glPopMatrix();
1260                         }
1261                         model[k].CalculateNormals(0);
1262                 }
1263         }
1264         fclose(tfile);          
1265
1266         tfile=fopen( lowfilename, "rb" );
1267         if(1){
1268                 lSize=sizeof(num_joints);
1269                 fseek ( tfile, lSize, SEEK_CUR);
1270                 //joints = new Joint[num_joints];
1271                 //jointlabels = new int[num_joints];
1272                 for(i=0;i<num_joints;i++){
1273                         lSize=sizeof(XYZ);
1274                         fseek ( tfile, lSize, SEEK_CUR);
1275                         lSize=sizeof(float);
1276                         fseek ( tfile, lSize, SEEK_CUR);
1277                         lSize=sizeof(float);
1278                         fseek ( tfile, lSize, SEEK_CUR);
1279                         lSize=1;//sizeof(bool);
1280                         fseek ( tfile, lSize, SEEK_CUR);
1281                         lSize=1;//sizeof(bool);
1282                         fseek ( tfile, lSize, SEEK_CUR);
1283                         lSize=sizeof(int);
1284                         fseek ( tfile, lSize, SEEK_CUR);
1285                         lSize=1;//sizeof(bool);
1286                         fseek ( tfile, lSize, SEEK_CUR);
1287                         lSize=1;//sizeof(bool);
1288                         fseek ( tfile, lSize, SEEK_CUR);
1289                         lSize=sizeof(int);
1290                         fseek ( tfile, lSize, SEEK_CUR);
1291                         lSize=sizeof(int);
1292                         fseek ( tfile, lSize, SEEK_CUR);
1293                         lSize=1;//sizeof(bool);
1294                         fseek ( tfile, lSize, SEEK_CUR);
1295                         lSize=sizeof(int);
1296                         fseek ( tfile, lSize, SEEK_CUR);
1297                         if(joints[i].hasparent)joints[i].parent=&joints[parentID];
1298                         joints[i].velocity=0;
1299                         joints[i].oldposition=joints[i].position;
1300                 }
1301                 funpackf(tfile, "Bi", &num_muscles);
1302                 //muscles = new Muscle[num_muscles];
1303                 for(i=0;i<num_muscles;i++){
1304                         lSize=sizeof(float);
1305                         fseek ( tfile, lSize, SEEK_CUR);
1306                         lSize=sizeof(float);
1307                         fseek ( tfile, lSize, SEEK_CUR);
1308                         lSize=sizeof(float);
1309                         fseek ( tfile, lSize, SEEK_CUR);
1310                         lSize=sizeof(float);
1311                         fseek ( tfile, lSize, SEEK_CUR);
1312                         lSize=sizeof(float);
1313                         fseek ( tfile, lSize, SEEK_CUR);
1314                         lSize=sizeof(int);
1315                         fseek ( tfile, lSize, SEEK_CUR);
1316                         tempmuscle=muscles[i].numverticeslow;
1317                         funpackf(tfile, "Bi", &muscles[i].numverticeslow);
1318                         if(muscles[i].numverticeslow){
1319                                 //muscles[i].verticeslow.clear();
1320                                 //muscles[i].verticeslow.resize(muscles[i].numverticeslow);
1321                                 //if(muscles[i].verticeslow)dealloc2(muscles[i].verticeslow);
1322                                 muscles[i].verticeslow=(int*)malloc(sizeof(int)*muscles[i].numverticeslow);
1323                                 edit=0;
1324                                 for(j=0;j<muscles[i].numverticeslow-edit;j++){
1325                                         funpackf(tfile, "Bi", &muscles[i].verticeslow[j+edit]);
1326                                         if(muscles[i].verticeslow[j+edit]>=modellow.vertexNum){
1327                                                 muscles[i].numverticeslow--;
1328                                                 edit--;
1329                                         }
1330                                 }
1331
1332
1333                         }
1334                         lSize=1;//sizeof(bool);
1335                         fseek ( tfile, lSize, SEEK_CUR);
1336                         lSize=sizeof(int);
1337                         fseek ( tfile, lSize, SEEK_CUR);
1338                         fseek ( tfile, lSize, SEEK_CUR);
1339                 }
1340                 lSize=sizeof(int);
1341                 for(j=0;j<num_muscles;j++){
1342                         for(i=0;i<muscles[j].numverticeslow;i++){       
1343                                 if(muscles[j].numverticeslow&&muscles[j].verticeslow[i]<modellow.vertexNum)modellow.owner[muscles[j].verticeslow[i]]=j;
1344                         }
1345                 }
1346                 /*FindForwards();
1347                 for(i=0;i<num_joints;i++){
1348                 joints[i].startpos=joints[i].position;
1349                 }
1350                 for(i=0;i<num_muscles;i++){
1351                 FindRotationMuscle(i,-1);
1352                 }*/
1353                 for(i=0;i<modellow.vertexNum;i++){
1354                         modellow.vertex[i]=modellow.vertex[i]-(muscles[modellow.owner[i]].parent1->position+muscles[modellow.owner[i]].parent2->position)/2;
1355                         glMatrixMode(GL_MODELVIEW);                                                     // Select The Modelview Matrix
1356                         glPushMatrix();
1357                                 glLoadIdentity();
1358                                 glRotatef(muscles[modellow.owner[i]].rotate3,0,1,0);
1359                                 glRotatef(muscles[modellow.owner[i]].rotate2-90,0,0,1);
1360                                 glRotatef(muscles[modellow.owner[i]].rotate1-90,0,1,0);
1361                                 glTranslatef(modellow.vertex[i].x,modellow.vertex[i].y,modellow.vertex[i].z);
1362                                 glGetFloatv(GL_MODELVIEW_MATRIX,M);
1363                                 modellow.vertex[i].x=M[12];
1364                                 modellow.vertex[i].y=M[13];
1365                                 modellow.vertex[i].z=M[14];
1366                         glPopMatrix();
1367                 }
1368                 modellow.CalculateNormals(0);
1369         }
1370
1371         if(clothes){
1372                 tfile=fopen( clothesfilename, "rb" );
1373                 lSize=sizeof(num_joints);
1374                 fseek ( tfile, lSize, SEEK_CUR);
1375                 //joints = new Joint[num_joints];
1376                 //jointlabels = new int[num_joints];
1377                 for(i=0;i<num_joints;i++){
1378                         lSize=sizeof(XYZ);
1379                         fseek ( tfile, lSize, SEEK_CUR);
1380                         lSize=sizeof(float);
1381                         fseek ( tfile, lSize, SEEK_CUR);
1382                         lSize=sizeof(float);
1383                         fseek ( tfile, lSize, SEEK_CUR);
1384                         lSize=1;//sizeof(bool);
1385                         fseek ( tfile, lSize, SEEK_CUR);
1386                         lSize=1;//sizeof(bool);
1387                         fseek ( tfile, lSize, SEEK_CUR);
1388                         lSize=sizeof(int);
1389                         fseek ( tfile, lSize, SEEK_CUR);
1390                         lSize=1;//sizeof(bool);
1391                         fseek ( tfile, lSize, SEEK_CUR);
1392                         lSize=1;//sizeof(bool);
1393                         fseek ( tfile, lSize, SEEK_CUR);
1394                         lSize=sizeof(int);
1395                         fseek ( tfile, lSize, SEEK_CUR);
1396                         lSize=sizeof(int);
1397                         fseek ( tfile, lSize, SEEK_CUR);
1398                         lSize=1;//sizeof(bool);
1399                         fseek ( tfile, lSize, SEEK_CUR);
1400                         lSize=sizeof(int);
1401                         fseek ( tfile, lSize, SEEK_CUR);
1402                         if(joints[i].hasparent)joints[i].parent=&joints[parentID];
1403                         joints[i].velocity=0;
1404                         joints[i].oldposition=joints[i].position;
1405                 }
1406                 funpackf(tfile, "Bi", &num_muscles);
1407                 //muscles = new Muscle[num_muscles];
1408                 for(i=0;i<num_muscles;i++){
1409                         lSize=sizeof(float);
1410                         fseek ( tfile, lSize, SEEK_CUR);
1411                         lSize=sizeof(float);
1412                         fseek ( tfile, lSize, SEEK_CUR);
1413                         lSize=sizeof(float);
1414                         fseek ( tfile, lSize, SEEK_CUR);
1415                         lSize=sizeof(float);
1416                         fseek ( tfile, lSize, SEEK_CUR);
1417                         lSize=sizeof(float);
1418                         fseek ( tfile, lSize, SEEK_CUR);
1419                         lSize=sizeof(int);
1420                         fseek ( tfile, lSize, SEEK_CUR);
1421                         tempmuscle=muscles[i].numverticesclothes;
1422                         funpackf(tfile, "Bi", &muscles[i].numverticesclothes);
1423                         if(muscles[i].numverticesclothes){
1424                                 //muscles[i].verticesclothes.clear();
1425                                 //muscles[i].verticesclothes.resize(muscles[i].numverticesclothes);
1426                                 //if(muscles[i].verticesclothes)dealloc2(muscles[i].verticesclothes);
1427                                 muscles[i].verticesclothes=(int*)malloc(sizeof(int)*muscles[i].numverticesclothes);
1428                                 edit=0;
1429                                 for(j=0;j<muscles[i].numverticesclothes-edit;j++){
1430                                         funpackf(tfile, "Bi", &muscles[i].verticesclothes[j+edit]);
1431                                         if(muscles[i].verticesclothes[j+edit]>=modelclothes.vertexNum){
1432                                                 muscles[i].numverticesclothes--;
1433                                                 edit--;
1434                                         }
1435                                 }
1436                         }
1437                         lSize=1;//sizeof(bool);
1438                         fseek ( tfile, lSize, SEEK_CUR);
1439                         lSize=sizeof(int);
1440                         fseek ( tfile, lSize, SEEK_CUR);
1441                         fseek ( tfile, lSize, SEEK_CUR);
1442                 }
1443                 lSize=sizeof(int);
1444                 for(j=0;j<num_muscles;j++){
1445                         for(i=0;i<muscles[j].numverticesclothes;i++){   
1446                                 if(muscles[j].numverticesclothes&&muscles[j].verticesclothes[i]<modelclothes.vertexNum)modelclothes.owner[muscles[j].verticesclothes[i]]=j;
1447                         }
1448                 }
1449                 /*FindForwards();
1450                 for(i=0;i<num_joints;i++){
1451                 joints[i].startpos=joints[i].position;
1452                 }
1453                 for(i=0;i<num_muscles;i++){
1454                 FindRotationMuscle(i,-1);
1455                 }*/
1456                 for(i=0;i<modelclothes.vertexNum;i++){
1457                         modelclothes.vertex[i]=modelclothes.vertex[i]-(muscles[modelclothes.owner[i]].parent1->position+muscles[modelclothes.owner[i]].parent2->position)/2;
1458                         glMatrixMode(GL_MODELVIEW);                                                     // Select The Modelview Matrix
1459                         glPushMatrix();
1460                                 glLoadIdentity();
1461                                 glRotatef(muscles[modelclothes.owner[i]].rotate3,0,1,0);
1462                                 glRotatef(muscles[modelclothes.owner[i]].rotate2-90,0,0,1);
1463                                 glRotatef(muscles[modelclothes.owner[i]].rotate1-90,0,1,0);
1464                                 glTranslatef(modelclothes.vertex[i].x,modelclothes.vertex[i].y,modelclothes.vertex[i].z);
1465                                 glGetFloatv(GL_MODELVIEW_MATRIX,M);
1466                                 modelclothes.vertex[i].x=M[12];
1467                                 modelclothes.vertex[i].y=M[13];
1468                                 modelclothes.vertex[i].z=M[14];
1469                         glPopMatrix();
1470                 }
1471                 modelclothes.CalculateNormals(0);
1472         }
1473         fclose(tfile);          
1474
1475         for(i=0;i<num_joints;i++){
1476                 for(j=0;j<num_joints;j++){
1477                         if(joints[i].label==j)jointlabels[j]=i;
1478                 }
1479         }
1480
1481         free=0;
1482 }
1483
1484 Animation::Animation()
1485 {
1486         numframes = 0;
1487         height = 0;
1488         attack = 0;
1489         joints = 0;
1490         weapontargetnum = 0;
1491
1492         position=0;
1493         twist=0;
1494         twist2=0;
1495         speed=0;
1496         onground=0;
1497         forward=0;
1498         label=0;
1499         weapontarget=0;
1500 }
1501
1502 Animation::~Animation()
1503 {
1504         deallocate();
1505 }
1506
1507 void Animation::deallocate()
1508 {
1509         int i = 0;
1510
1511         if(position)
1512         {
1513                 for(i = 0; i < joints; i++)
1514                         dealloc2(position[i]);
1515
1516                 dealloc2(position);
1517         }
1518         position = 0;
1519
1520         if(twist)
1521         {
1522                 for(i = 0; i < joints; i++)
1523                         dealloc2(twist[i]);
1524
1525                 dealloc2(twist);
1526         }
1527         twist = 0;
1528
1529         if(twist2)
1530         {
1531                 for(i = 0; i < joints; i++)
1532                         dealloc2(twist2[i]);
1533
1534                 dealloc2(twist2);
1535         }
1536         twist2 = 0;
1537
1538         if(onground)
1539         {
1540                 for(i = 0; i < joints; i++)
1541                         dealloc2(onground[i]);
1542
1543                 dealloc2(onground);
1544         }
1545         onground = 0;
1546
1547         if(speed)dealloc2(speed);
1548         speed = 0;
1549
1550         if(forward)dealloc2(forward);
1551         forward = 0;
1552
1553         if(weapontarget)dealloc2(weapontarget);
1554         weapontarget = 0;
1555
1556         if(label)dealloc2(label);
1557         label = 0;
1558
1559         joints = 0;
1560 }
1561
1562 Skeleton::Skeleton()
1563 {
1564         num_joints = 0;
1565
1566         num_muscles = 0;
1567
1568         selected = 0;
1569
1570         memset(forwardjoints, 0, sizeof(forwardjoints));
1571         //              XYZ forward;
1572
1573         id = 0;
1574
1575         memset(lowforwardjoints, 0, sizeof(lowforwardjoints));
1576         //              XYZ lowforward;
1577
1578         //              XYZ specialforward[5];
1579         memset(jointlabels, 0, sizeof(jointlabels));
1580
1581         //              Model model[7];
1582         //              Model modellow;
1583         //              Model modelclothes;
1584         num_models = 0;
1585
1586         //              Model drawmodel;
1587         //              Model drawmodellow;
1588         //              Model drawmodelclothes;
1589
1590         clothes = 0;
1591         spinny = 0;
1592
1593         memset(skinText, 0, sizeof(skinText));
1594         skinsize = 0;
1595
1596         checkdelay = 0;
1597
1598         longdead = 0;
1599         broken = 0;
1600
1601         free = 0;
1602         oldfree = 0;
1603         freetime = 0;
1604         freefall = 0;
1605
1606         joints=0;
1607         muscles=0;
1608 }
1609
1610 Skeleton::~Skeleton()
1611 {
1612         if (muscles)
1613         {
1614                 delete [] muscles;
1615         }
1616         muscles = 0;
1617
1618         if (joints)
1619         {
1620                 delete [] joints;
1621         }
1622         joints = 0;
1623 }
1624
1625 Muscle::Muscle()
1626 {
1627         vertices=0;
1628         verticeslow=0;
1629         verticesclothes=0;
1630
1631         numvertices = 0;
1632         numverticeslow = 0;
1633         numverticesclothes = 0;
1634         length = 0;
1635         targetlength = 0;
1636         parent1 = 0;
1637         parent2 = 0;
1638         maxlength = 0;
1639         minlength = 0;
1640         type = 0;
1641         visible = 0;
1642         rotate1 = 0,rotate2 = 0,rotate3 = 0;
1643         lastrotate1 = 0,lastrotate2 = 0,lastrotate3 = 0;
1644         oldrotate1 = 0,oldrotate2 = 0,oldrotate3 = 0;
1645         newrotate1 = 0,newrotate2 = 0,newrotate3 = 0;
1646
1647         strength = 0;
1648 }
1649
1650 Muscle::~Muscle()
1651 {
1652         dealloc2(vertices);
1653         dealloc2(verticeslow);
1654         dealloc2(verticesclothes);
1655 }
1656
1657 Animation & Animation::operator = (const Animation & ani)
1658 {
1659         int i = 0;
1660
1661         bool allocate = true;
1662
1663         allocate = ((ani.numframes != numframes) || (ani.joints != joints));
1664
1665         if (allocate) deallocate();
1666
1667         numframes = ani.numframes;
1668         height = ani.height;
1669         attack = ani.attack;
1670         joints = ani.joints;
1671         weapontargetnum = ani.weapontargetnum;
1672
1673         if (allocate) position=(XYZ**)malloc(sizeof(XYZ*)*ani.joints);
1674         for(i = 0; i < ani.joints; i++)
1675         {
1676                 if (allocate) position[i] = (XYZ*)malloc(sizeof(XYZ)*ani.numframes);
1677                 memcpy(position[i], ani.position[i], sizeof(XYZ)*ani.numframes);
1678         }
1679
1680         if (allocate) twist=(float**)malloc(sizeof(float*)*ani.joints);
1681         for(i = 0; i < ani.joints; i++)
1682         {
1683                 if (allocate) twist[i] = (float*)malloc(sizeof(float)*ani.numframes);
1684                 memcpy(twist[i], ani.twist[i], sizeof(float)*ani.numframes);
1685         }
1686
1687         if (allocate) twist2=(float**)malloc(sizeof(float*)*ani.joints);
1688         for(i = 0; i < ani.joints; i++)
1689         {
1690                 if (allocate) twist2[i] = (float*)malloc(sizeof(float)*ani.numframes);
1691                 memcpy(twist2[i], ani.twist2[i], sizeof(float)*ani.numframes);
1692         }
1693
1694         if (allocate) speed = (float*)malloc(sizeof(float)*ani.numframes);
1695         memcpy(speed, ani.speed, sizeof(float)*ani.numframes);
1696
1697         if (allocate) onground=(bool**)malloc(sizeof(bool*)*ani.joints);
1698         for(i = 0; i < ani.joints; i++)
1699         {
1700                 if (allocate) onground[i] =(bool*)malloc(sizeof(bool)*ani.numframes);
1701                 memcpy(onground[i], ani.onground[i], sizeof(bool)*ani.numframes);
1702         }
1703
1704         if (allocate) forward = (XYZ*)malloc(sizeof(XYZ)*ani.numframes);
1705         memcpy(forward, ani.forward, sizeof(XYZ)*ani.numframes);
1706
1707         if (allocate) weapontarget = (XYZ*)malloc(sizeof(XYZ)*ani.numframes);
1708         memcpy(weapontarget, ani.weapontarget, sizeof(XYZ)*ani.numframes);
1709
1710         if (allocate) label = (int*)malloc(sizeof(int)*ani.numframes);
1711         memcpy(label, ani.label, sizeof(int)*ani.numframes);
1712
1713         return (*this);
1714 }
1715