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