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