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