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