4 extern float multiplier;
6 extern Skeleton testskeleton;
7 extern Terrain terrain;
8 extern FSOUND_SAMPLE *samp[100];
9 extern int channels[100];
10 extern Objects objects;
11 extern Sprites sprites;
12 extern int environment;
13 extern float terraindetail;
14 extern float camerashake;
17 extern XYZ envsound[30];
18 extern float envsoundvol[30];
19 extern int numenvsounds;
20 extern float envsoundlife[30];
22 extern float bonustime;
23 extern int tutoriallevel;
25 extern int whichjointstartarray[26];
26 extern int whichjointendarray[26];
30 extern bool visibleloading;
31 extern "C" void PlaySoundEx(int channel, FSOUND_SAMPLE *sptr, FSOUND_DSPUNIT *dsp, signed char startpaused);
33 void dealloc2(void* param){
38 void Muscle::DoConstraint(bool spinny)
42 static XYZ newpoint1,newpoint2;
44 static float oldlength;
45 static float relaxlength;
49 if(type!=boneconnect)relaxlength=findDistance(&parent1->position,&parent2->position);
51 if(type==boneconnect)strength=1;
52 if(type==constraint)strength=0;
54 if(strength<0)strength=0;
55 if(strength>1)strength=1;
57 length-=(length-relaxlength)*(1-strength)*multiplier*10000;
58 length-=(length-targetlength)*(strength)*multiplier*10000;
59 if(strength==0)length=relaxlength;
61 if((relaxlength-length>0&&relaxlength-oldlength<0)||(relaxlength-length<0&&relaxlength-oldlength>0))length=relaxlength;
64 if(length<minlength)length=minlength;
65 if(length>maxlength)length=maxlength;
69 if(length<minlength*.6)length=minlength*.6;
70 if(length>maxlength*1.4)length=maxlength*1.4;
73 if(length==relaxlength)return;
76 midp=(parent1->position*parent1->mass+parent2->position*parent2->mass)/(parent1->mass+parent2->mass);
77 //Find vector from midpoint to second vector
78 vel=parent2->position-midp;
79 //Change to unit vector
81 //Apply velocity change
82 newpoint1=midp-vel*length*(parent2->mass/(parent1->mass+parent2->mass));
83 newpoint2=midp+vel*length*(parent1->mass/(parent1->mass+parent2->mass));
85 parent1->velocity=parent1->velocity+(newpoint1-parent1->position)/multiplier/4;
86 parent2->velocity=parent2->velocity+(newpoint2-parent2->position)/multiplier/4;
90 parent1->velocity=parent1->velocity+(newpoint1-parent1->position);
91 parent2->velocity=parent2->velocity+(newpoint2-parent2->position);
93 //Move child point to within certain distance of parent point
94 parent1->position=newpoint1;
95 parent2->position=newpoint2;
98 void Skeleton::FindForwardsfirst()
100 //Find forward vectors
101 CrossProduct(joints[forwardjoints[1]].position-joints[forwardjoints[0]].position,joints[forwardjoints[2]].position-joints[forwardjoints[0]].position,&forward);
104 CrossProduct(joints[lowforwardjoints[1]].position-joints[lowforwardjoints[0]].position,joints[lowforwardjoints[2]].position-joints[lowforwardjoints[0]].position,&lowforward);
105 Normalise(&lowforward);
108 specialforward[0]=forward;
109 specialforward[1]=forward;
110 specialforward[2]=forward;
111 specialforward[3]=forward;
112 specialforward[4]=forward;
115 void Skeleton::FindForwards()
117 //Find forward vectors
118 CrossProduct(joints[forwardjoints[1]].position-joints[forwardjoints[0]].position,joints[forwardjoints[2]].position-joints[forwardjoints[0]].position,&forward);
121 CrossProduct(joints[lowforwardjoints[1]].position-joints[lowforwardjoints[0]].position,joints[lowforwardjoints[2]].position-joints[lowforwardjoints[0]].position,&lowforward);
122 Normalise(&lowforward);
125 specialforward[0]=forward;
127 specialforward[1]=joints[jointlabels[rightshoulder]].position+joints[jointlabels[rightwrist]].position;
128 specialforward[1]=joints[jointlabels[rightelbow]].position-specialforward[1]/2;
129 specialforward[1]+=forward*.4;
130 Normalise(&specialforward[1]);
131 specialforward[2]=joints[jointlabels[leftshoulder]].position+joints[jointlabels[leftwrist]].position;
132 specialforward[2]=joints[jointlabels[leftelbow]].position-specialforward[2]/2;
133 specialforward[2]+=forward*.4;
134 Normalise(&specialforward[2]);
136 specialforward[3]=joints[jointlabels[righthip]].position+joints[jointlabels[rightankle]].position;
137 specialforward[3]=specialforward[3]/2-joints[jointlabels[rightknee]].position;
138 specialforward[3]+=lowforward*.4;
139 Normalise(&specialforward[3]);
140 specialforward[4]=joints[jointlabels[lefthip]].position+joints[jointlabels[leftankle]].position;
141 specialforward[4]=specialforward[4]/2-joints[jointlabels[leftknee]].position;
142 specialforward[4]+=lowforward*.4;
143 Normalise(&specialforward[4]);
146 float Skeleton::DoConstraints(XYZ *coords,float *scale)
148 static float friction=1.5;
149 static float elasticity=.3;
150 static XYZ bounceness;
151 static XYZ oldpos[100];
152 static int numrepeats=3;
153 static float groundlevel=.15;
154 static float soundvolume;
155 static int i,j,k,l,m;
156 static XYZ temp,start,end;
157 static XYZ terrainnormal;
161 //static int whichjointstart,whichjointend;
162 static float distance;
163 static float frictionness;
164 static XYZ terrainlight;
165 static int whichpatchx;
166 static int whichpatchz;
169 static float tempmult;
170 static bool breaking;
176 freetime+=multiplier;
178 whichpatchx=coords->x/(terrain.size/subdivision*terrain.scale*terraindetail);
179 whichpatchz=coords->z/(terrain.size/subdivision*terrain.scale*terraindetail);
181 terrainlight=*coords;
182 objects.SphereCheckPossible(&terrainlight, 1);
184 for(i=0; i<num_joints; i++){
185 oldpos[i]=joints[i].position;
189 for(i=0; i<num_joints; i++){
190 //if(!isnormal(joints[i].velocity.x)||!isnormal(joints[i].velocity.y)||!isnormal(joints[i].velocity.z))joints[i].velocity=0;
191 joints[i].position=joints[i].position+joints[i].velocity*multiplier;
193 if(joints[i].label==head)groundlevel=.8;
194 if(joints[i].label==righthand||joints[i].label==rightwrist||joints[i].label==rightelbow)groundlevel=.2;
195 if(joints[i].label==lefthand||joints[i].label==leftwrist||joints[i].label==leftelbow)groundlevel=.2;
196 joints[i].position.y-=groundlevel;
197 //if(!joints[i].locked&&!broken)joints[i].velocity+=joints[i].velchange*multiplier*10*(500-longdead)/500;
198 joints[i].oldvelocity=joints[i].velocity;
201 //multiplier/=numrepeats;
202 for(j=0; j<numrepeats; j++){
203 if(!joints[jointlabels[rightknee]].locked&&!joints[jointlabels[righthip]].locked){
204 temp=joints[jointlabels[rightknee]].position-(joints[jointlabels[righthip]].position+joints[jointlabels[rightankle]].position)/2;
205 while(normaldotproduct(temp,lowforward)>-.1&&!sphere_line_intersection(&joints[jointlabels[righthip]].position,&joints[jointlabels[rightankle]].position,&joints[jointlabels[rightknee]].position,&r)){
206 joints[jointlabels[rightknee]].position-=lowforward*.05;
207 if(spinny)joints[jointlabels[rightknee]].velocity-=lowforward*.05/multiplier/4;
208 else joints[jointlabels[rightknee]].velocity-=lowforward*.05;
209 joints[jointlabels[rightankle]].position+=lowforward*.025;
210 if(spinny)joints[jointlabels[rightankle]].velocity+=lowforward*.025/multiplier/4;
211 else joints[jointlabels[rightankle]].velocity+=lowforward*.25;
212 joints[jointlabels[righthip]].position+=lowforward*.025;
213 if(spinny)joints[jointlabels[righthip]].velocity+=lowforward*.025/multiplier/4;
214 else joints[jointlabels[righthip]].velocity+=lowforward*.025;
215 temp=joints[jointlabels[rightknee]].position-(joints[jointlabels[righthip]].position+joints[jointlabels[rightankle]].position)/2;
218 if(!joints[jointlabels[leftknee]].locked&&!joints[jointlabels[righthip]].locked){
219 temp=joints[jointlabels[leftknee]].position-(joints[jointlabels[lefthip]].position+joints[jointlabels[leftankle]].position)/2;
220 while(normaldotproduct(temp,lowforward)>-.1&&!sphere_line_intersection(&joints[jointlabels[lefthip]].position,&joints[jointlabels[leftankle]].position,&joints[jointlabels[leftknee]].position,&r)){
221 joints[jointlabels[leftknee]].position-=lowforward*.05;
222 if(spinny)joints[jointlabels[leftknee]].velocity-=lowforward*.05/multiplier/4;
223 else joints[jointlabels[leftknee]].velocity-=lowforward*.05;
224 joints[jointlabels[leftankle]].position+=lowforward*.025;
225 if(spinny)joints[jointlabels[leftankle]].velocity+=lowforward*.025/multiplier/4;
226 else joints[jointlabels[leftankle]].velocity+=lowforward*.25;
227 joints[jointlabels[lefthip]].position+=lowforward*.025;
228 if(spinny)joints[jointlabels[lefthip]].velocity+=lowforward*.025/multiplier/4;
229 else joints[jointlabels[lefthip]].velocity+=lowforward*.025;
230 temp=joints[jointlabels[leftknee]].position-(joints[jointlabels[lefthip]].position+joints[jointlabels[leftankle]].position)/2;
234 if(terrain.patchobjectnum[whichpatchx][whichpatchz])
235 for(m=0;m<terrain.patchobjectnum[whichpatchx][whichpatchz];m++){
236 k=terrain.patchobjects[whichpatchx][whichpatchz][m];
237 if(k<objects.numobjects&&k>=0)
238 if(objects.possible[k]){
239 temp=joints[jointlabels[head]].position*(*scale)+*coords;
240 if(objects.model[k].SphereCheck(&temp, 0.06, &start, &objects.position[k], &objects.rotation[k])!=-1){
241 //temp=(joints[jointlabels[head]].position*(*scale)+*coords)-start;
243 //joints[jointlabels[head]].position=((temp*.2+start)-*coords)/(*scale);
244 joints[jointlabels[head]].position=(temp-*coords)/(*scale);
252 startheadpos=joints[jointlabels[head]].position;
254 headpos=joints[jointlabels[head]].position+(joints[jointlabels[head]].position-joints[jointlabels[neck]].position);
255 if(terrain.patchobjectnum[whichpatchx][whichpatchz])
256 for(m=0;m<terrain.patchobjectnum[whichpatchx][whichpatchz];m++){
257 k=terrain.patchobjects[whichpatchx][whichpatchz][m];
258 if(k<objects.numobjects&&k>=0)
259 if(objects.possible[k]){
260 friction=objects.friction[k];
261 start=joints[jointlabels[head]].position*(*scale)+*coords;
262 end=(headpos)*(*scale)+*coords;
263 whichhit=objects.model[k].LineCheckPossible(&start,&end,&temp,&objects.position[k],&objects.rotation[k]);
265 if(joints[jointlabels[head]].label==groin&&!joints[jointlabels[head]].locked&&joints[jointlabels[head]].delay<=0){
266 joints[jointlabels[head]].locked=1;
267 joints[jointlabels[head]].delay=1;
268 static float gLoc[3];
270 gLoc[0]=headpos.x*(*scale)+coords->x;
271 gLoc[1]=headpos.y*(*scale)+coords->y;
272 gLoc[2]=headpos.z*(*scale)+coords->z;
273 vel[0]=joints[jointlabels[head]].velocity.x;
274 vel[1]=joints[jointlabels[head]].velocity.y;
275 vel[2]=joints[jointlabels[head]].velocity.z;
276 PlaySoundEx( landsound1, samp[landsound1], NULL, TRUE);
277 FSOUND_3D_SetAttributes(channels[landsound1], gLoc, vel);
278 FSOUND_SetVolume(channels[landsound1], 128);
279 FSOUND_SetPaused(channels[landsound1], FALSE);
284 if(joints[jointlabels[head]].label==head&&!joints[jointlabels[head]].locked&&joints[jointlabels[head]].delay<=0){
285 joints[jointlabels[head]].locked=1;
286 joints[jointlabels[head]].delay=1;
287 static float gLoc[3];
289 gLoc[0]=headpos.x*(*scale)+coords->x;
290 gLoc[1]=headpos.y*(*scale)+coords->y;
291 gLoc[2]=headpos.z*(*scale)+coords->z;
292 vel[0]=joints[jointlabels[head]].velocity.x;
293 vel[1]=joints[jointlabels[head]].velocity.y;
294 vel[2]=joints[jointlabels[head]].velocity.z;
295 PlaySoundEx( landsound2, samp[landsound2], NULL, TRUE);
296 FSOUND_3D_SetAttributes(channels[landsound2], gLoc, vel);
297 FSOUND_SetVolume(channels[landsound2], 128);
298 FSOUND_SetPaused(channels[landsound2], FALSE);
301 terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0)*-1;
302 if(terrainnormal.y>.8)freefall=0;
303 bounceness=terrainnormal*findLength(&joints[jointlabels[head]].velocity)*(abs(normaldotproduct(joints[jointlabels[head]].velocity,terrainnormal)));
304 if(findLengthfast(&joints[jointlabels[head]].velocity)>findLengthfast(&joints[jointlabels[head]].oldvelocity)){
306 joints[jointlabels[head]].velocity=joints[jointlabels[head]].oldvelocity;
308 if(findLengthfast(&bounceness)>4000&&breaking){
309 objects.model[k].MakeDecal(breakdecal,DoRotation(temp-objects.position[k],0,-objects.rotation[k],0),.4,.5,Random()%360);
310 sprites.MakeSprite(cloudsprite, headpos*(*scale)+*coords,joints[jointlabels[head]].velocity*.06, 1,1,1, 4, .2);
314 static float gLoc[3];
316 gLoc[0]=headpos.x*(*scale)+coords->x;
317 gLoc[1]=headpos.y*(*scale)+coords->y;
318 gLoc[2]=headpos.z*(*scale)+coords->z;
319 vel[0]=joints[jointlabels[head]].velocity.x;
320 vel[1]=joints[jointlabels[head]].velocity.y;
321 vel[2]=joints[jointlabels[head]].velocity.z;
322 PlaySoundEx( breaksound2, samp[breaksound2], NULL, TRUE);
323 FSOUND_3D_SetAttributes(channels[breaksound2], gLoc, vel);
324 FSOUND_SetVolume(channels[breaksound2], 300);
325 FSOUND_SetPaused(channels[breaksound2], FALSE);
327 envsound[numenvsounds]=*coords;
328 envsoundvol[numenvsounds]=64;
329 envsoundlife[numenvsounds]=.4;
332 if(objects.type[k]==treetrunktype){
333 objects.rotx[k]+=joints[jointlabels[head]].velocity.x*multiplier*.4;
334 objects.roty[k]+=joints[jointlabels[head]].velocity.z*multiplier*.4;
335 objects.rotx[k+1]+=joints[jointlabels[head]].velocity.x*multiplier*.4;
336 objects.roty[k+1]+=joints[jointlabels[head]].velocity.z*multiplier*.4;
338 if(!joints[jointlabels[head]].locked)damage+=findLengthfast(&bounceness)/2500;
339 ReflectVector(&joints[jointlabels[head]].velocity,&terrainnormal);
340 frictionness=abs(normaldotproduct(joints[jointlabels[head]].velocity,terrainnormal));//findLength(&bounceness)/findLength(&joints[jointlabels[head]].velocity);
341 joints[jointlabels[head]].velocity-=bounceness;
342 if(1-friction*frictionness>0)joints[jointlabels[head]].velocity*=1-friction*frictionness;
343 else joints[jointlabels[head]].velocity=0;
344 if(findLengthfast(&bounceness)>2500){
345 Normalise(&bounceness);
346 bounceness=bounceness*50;
348 joints[jointlabels[head]].velocity+=bounceness*elasticity;
351 if(!joints[jointlabels[head]].locked)
352 if(findLengthfast(&joints[jointlabels[head]].velocity)<1){
353 joints[jointlabels[head]].locked=1;
354 //joints[jointlabels[head]].velocity*=3;
356 if(findLengthfast(&bounceness)>500)sprites.MakeSprite(cloudsprite, headpos*(*scale)+*coords,joints[jointlabels[head]].velocity*.06, 1,1,1, .5, .2);
357 joints[jointlabels[head]].position=(temp-*coords)/(*scale)+(startheadpos-headpos)+terrainnormal*.005;
358 if(longdead>100)broken=1;
364 for(i=0; i<num_joints; i++){
365 //joints[i].delay-=multiplier/1.5;
367 if(!spinny)if(findLengthfast(&joints[i].velocity)>320)joints[i].locked=0;
368 if(spinny)if(findLengthfast(&joints[i].velocity)>600)joints[i].locked=0;
369 if(joints[i].delay>0){
371 for(j=0;j<num_joints;j++){
372 if(joints[j].locked)freely=0;
374 if(freely)joints[i].delay-=multiplier*3;
376 //if(joints[i].delay>0)
377 //if(findLengthfast(&joints[i].velocity)>700&&joints[i].label!=head)joints[i].delay-=multiplier;
381 for(i=0; i<num_muscles; i++){
383 //muscles[i].DoConstraint(broken);
384 muscles[i].DoConstraint(spinny);
387 for(i=0; i<num_joints; i++){
388 //joints[i].delay-=multiplier/1.5;
392 if(joints[i].position.y*(*scale)+coords->y<terrain.getHeight(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z)+groundlevel){
395 if(joints[i].label==groin&&!joints[i].locked&&joints[i].delay<=0){
398 static float gLoc[3];
400 gLoc[0]=joints[i].position.x*(*scale)+coords->x;
401 gLoc[1]=joints[i].position.y*(*scale)+coords->y;
402 gLoc[2]=joints[i].position.z*(*scale)+coords->z;
403 vel[0]=joints[i].velocity.x;
404 vel[1]=joints[i].velocity.y;
405 vel[2]=joints[i].velocity.z;
406 if(tutoriallevel!=1||id==0){
407 PlaySoundEx( landsound1, samp[landsound1], NULL, TRUE);
408 FSOUND_3D_SetAttributes(channels[landsound1], gLoc, vel);
409 FSOUND_SetVolume(channels[landsound1], 128);
410 FSOUND_SetPaused(channels[landsound1], FALSE);
415 if(joints[i].label==head&&!joints[i].locked&&joints[i].delay<=0){
418 static float gLoc[3];
420 gLoc[0]=joints[i].position.x*(*scale)+coords->x;
421 gLoc[1]=joints[i].position.y*(*scale)+coords->y;
422 gLoc[2]=joints[i].position.z*(*scale)+coords->z;
423 vel[0]=joints[i].velocity.x;
424 vel[1]=joints[i].velocity.y;
425 vel[2]=joints[i].velocity.z;
426 if(tutoriallevel!=1||id==0){
427 PlaySoundEx( landsound2, samp[landsound2], NULL, TRUE);
428 FSOUND_3D_SetAttributes(channels[landsound2], gLoc, vel);
429 FSOUND_SetVolume(channels[landsound2], 128);
430 FSOUND_SetPaused(channels[landsound2], FALSE);
434 terrainnormal=terrain.getNormal(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z);
435 ReflectVector(&joints[i].velocity,&terrainnormal);
436 bounceness=terrainnormal*findLength(&joints[i].velocity)*(abs(normaldotproduct(joints[i].velocity,terrainnormal)));
437 if(!joints[i].locked)damage+=findLengthfast(&bounceness)/4000;
438 if(findLengthfast(&joints[i].velocity)<findLengthfast(&bounceness))bounceness=0;
439 frictionness=abs(normaldotproduct(joints[i].velocity,terrainnormal));//findLength(&bounceness)/findLength(&joints[i].velocity);
440 joints[i].velocity-=bounceness;
441 if(1-friction*frictionness>0)joints[i].velocity*=1-friction*frictionness;
442 else joints[i].velocity=0;
444 if(tutoriallevel!=1||id==0)
445 if(findLengthfast(&bounceness)>8000&&breaking){
446 objects.model[k].MakeDecal(breakdecal,DoRotation(temp-objects.position[k],0,-objects.rotation[k],0),.4,.5,Random()%360);
447 sprites.MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, 1,1,1, 4, .2);
448 //sprites.MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, 1,1,1, 1, .2);
452 static float gLoc[3];
454 gLoc[0]=joints[i].position.x*(*scale)+coords->x;
455 gLoc[1]=joints[i].position.y*(*scale)+coords->y;
456 gLoc[2]=joints[i].position.z*(*scale)+coords->z;
457 vel[0]=joints[i].velocity.x;
458 vel[1]=joints[i].velocity.y;
459 vel[2]=joints[i].velocity.z;
460 PlaySoundEx( breaksound2, samp[breaksound2], NULL, TRUE);
461 FSOUND_3D_SetAttributes(channels[breaksound2], gLoc, vel);
462 FSOUND_SetVolume(channels[breaksound2], 300);
463 FSOUND_SetPaused(channels[breaksound2], FALSE);
465 envsound[numenvsounds]=*coords;
466 envsoundvol[numenvsounds]=64;
467 envsoundlife[numenvsounds]=.4;
471 if(findLengthfast(&bounceness)>2500){
472 Normalise(&bounceness);
473 bounceness=bounceness*50;
476 joints[i].velocity+=bounceness*elasticity;
478 if(findLengthfast(&joints[i].velocity)>findLengthfast(&joints[i].oldvelocity)){
480 joints[i].velocity=joints[i].oldvelocity;
484 if(joints[i].locked==0)
485 if(findLengthfast(&joints[i].velocity)<1)joints[i].locked=1;
487 if(environment==snowyenvironment&&findLengthfast(&bounceness)>500&&terrain.getOpacity(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z)<.2){
488 terrainlight=terrain.getLighting(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z);
489 sprites.MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, terrainlight.x,terrainlight.y,terrainlight.z, .5, .7);
490 if(detail==2)terrain.MakeDecal(bodyprintdecal, joints[i].position*(*scale)+*coords,.4,.4,0);
492 else if(environment==desertenvironment&&findLengthfast(&bounceness)>500&&terrain.getOpacity(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z)<.2){
493 terrainlight=terrain.getLighting(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z);
494 sprites.MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, terrainlight.x*190/255,terrainlight.y*170/255,terrainlight.z*108/255, .5, .7);
497 else if(environment==grassyenvironment&&findLengthfast(&bounceness)>500&&terrain.getOpacity(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z)<.2){
498 terrainlight=terrain.getLighting(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z);
499 sprites.MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, terrainlight.x*90/255,terrainlight.y*70/255,terrainlight.z*8/255, .5, .5);
501 else if(findLengthfast(&bounceness)>500)sprites.MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, terrainlight.x,terrainlight.y,terrainlight.z, .5, .2);
504 joints[i].position.y=(terrain.getHeight(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z)+groundlevel-coords->y)/(*scale);
505 if(longdead>100)broken=1;
507 if(terrain.patchobjectnum[whichpatchx][whichpatchz])
508 for(m=0;m<terrain.patchobjectnum[whichpatchx][whichpatchz];m++){
509 k=terrain.patchobjects[whichpatchx][whichpatchz][m];
510 if(k<objects.numobjects&&k>=0)
511 if(objects.possible[k]){
512 friction=objects.friction[k];
513 start=joints[i].realoldposition;
514 end=joints[i].position*(*scale)+*coords;
515 whichhit=objects.model[k].LineCheckPossible(&start,&end,&temp,&objects.position[k],&objects.rotation[k]);
517 if(joints[i].label==groin&&!joints[i].locked&&joints[i].delay<=0){
520 static float gLoc[3];
522 gLoc[0]=joints[i].position.x*(*scale)+coords->x;
523 gLoc[1]=joints[i].position.y*(*scale)+coords->y;
524 gLoc[2]=joints[i].position.z*(*scale)+coords->z;
525 vel[0]=joints[i].velocity.x;
526 vel[1]=joints[i].velocity.y;
527 vel[2]=joints[i].velocity.z;
528 if(tutoriallevel!=1||id==0){
529 PlaySoundEx( landsound1, samp[landsound1], NULL, TRUE);
530 FSOUND_3D_SetAttributes(channels[landsound1], gLoc, vel);
531 FSOUND_SetVolume(channels[landsound1], 128);
532 FSOUND_SetPaused(channels[landsound1], FALSE);
537 if(joints[i].label==head&&!joints[i].locked&&joints[i].delay<=0){
540 static float gLoc[3];
542 gLoc[0]=joints[i].position.x*(*scale)+coords->x;
543 gLoc[1]=joints[i].position.y*(*scale)+coords->y;
544 gLoc[2]=joints[i].position.z*(*scale)+coords->z;
545 vel[0]=joints[i].velocity.x;
546 vel[1]=joints[i].velocity.y;
547 vel[2]=joints[i].velocity.z;
548 if(tutoriallevel!=1||id==0){
549 PlaySoundEx( landsound2, samp[landsound2], NULL, TRUE);
550 FSOUND_3D_SetAttributes(channels[landsound2], gLoc, vel);
551 FSOUND_SetVolume(channels[landsound2], 128);
552 FSOUND_SetPaused(channels[landsound2], FALSE);
556 terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0)*-1;
557 if(terrainnormal.y>.8)freefall=0;
558 bounceness=terrainnormal*findLength(&joints[i].velocity)*(abs(normaldotproduct(joints[i].velocity,terrainnormal)));
559 if(findLengthfast(&joints[i].velocity)>findLengthfast(&joints[i].oldvelocity)){
561 joints[i].velocity=joints[i].oldvelocity;
563 if(tutoriallevel!=1||id==0)
564 if(findLengthfast(&bounceness)>4000&&breaking){
565 objects.model[k].MakeDecal(breakdecal,DoRotation(temp-objects.position[k],0,-objects.rotation[k],0),.4,.5,Random()%360);
566 sprites.MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, 1,1,1, 4, .2);
570 static float gLoc[3];
572 gLoc[0]=joints[i].position.x*(*scale)+coords->x;
573 gLoc[1]=joints[i].position.y*(*scale)+coords->y;
574 gLoc[2]=joints[i].position.z*(*scale)+coords->z;
575 vel[0]=joints[i].velocity.x;
576 vel[1]=joints[i].velocity.y;
577 vel[2]=joints[i].velocity.z;
578 PlaySoundEx( breaksound2, samp[breaksound2], NULL, TRUE);
579 FSOUND_3D_SetAttributes(channels[breaksound2], gLoc, vel);
580 FSOUND_SetVolume(channels[breaksound2], 300);
581 FSOUND_SetPaused(channels[breaksound2], FALSE);
583 envsound[numenvsounds]=*coords;
584 envsoundvol[numenvsounds]=64;
585 envsoundlife[numenvsounds]=.4;
588 if(objects.type[k]==treetrunktype){
589 //if(objects.rotx[k]==0||objects.roty[k]==0){
593 if(environment==grassyenvironment)howmany=findLength(&joints[i].velocity)*4/10;
594 if(environment==snowyenvironment)howmany=findLength(&joints[i].velocity)*1/10;
595 if(environment!=desertenvironment)
596 for(j=0;j<howmany;j++){
597 tempvel.x=float(abs(Random()%100)-50)/20;
598 tempvel.y=float(abs(Random()%100)-50)/20;
599 tempvel.z=float(abs(Random()%100)-50)/20;
600 pos=objects.position[k];
601 pos.y+=objects.scale[k]*15;
602 pos.x+=float(abs(Random()%100)-50)/100*objects.scale[k]*5;
603 pos.y+=float(abs(Random()%100)-50)/100*objects.scale[k]*15;
604 pos.z+=float(abs(Random()%100)-50)/100*objects.scale[k]*5;
605 sprites.MakeSprite(splintersprite, pos,tempvel*.5, 165/255+float(abs(Random()%100)-50)/400,0,0, .2+float(abs(Random()%100)-50)/1300, 1);
606 sprites.special[sprites.numsprites-1]=1;
608 objects.rotx[k]+=joints[i].velocity.x*multiplier*.4;
609 objects.roty[k]+=joints[i].velocity.z*multiplier*.4;
610 objects.rotx[k+1]+=joints[i].velocity.x*multiplier*.4;
611 objects.roty[k+1]+=joints[i].velocity.z*multiplier*.4;
613 if(!joints[i].locked)damage+=findLengthfast(&bounceness)/2500;
614 ReflectVector(&joints[i].velocity,&terrainnormal);
615 frictionness=abs(normaldotproduct(joints[i].velocity,terrainnormal));//findLength(&bounceness)/findLength(&joints[i].velocity);
616 joints[i].velocity-=bounceness;
617 if(1-friction*frictionness>0)joints[i].velocity*=1-friction*frictionness;
618 else joints[i].velocity=0;
619 if(findLengthfast(&bounceness)>2500){
620 Normalise(&bounceness);
621 bounceness=bounceness*50;
623 joints[i].velocity+=bounceness*elasticity;
626 if(!joints[i].locked)
627 if(findLengthfast(&joints[i].velocity)<1){
629 //joints[i].velocity*=3;
631 if(findLengthfast(&bounceness)>500)sprites.MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, 1,1,1, .5, .2);
632 joints[i].position=(temp-*coords)/(*scale)+terrainnormal*.005;
633 if(longdead>100)broken=1;
637 joints[i].realoldposition=joints[i].position*(*scale)+*coords;
643 if(terrain.patchobjectnum[whichpatchx][whichpatchz])
644 for(m=0;m<terrain.patchobjectnum[whichpatchx][whichpatchz];m++){
645 k=terrain.patchobjects[whichpatchx][whichpatchz][m];
646 if(objects.possible[k]){
648 //Make this less stupid
649 start=joints[jointlabels[whichjointstartarray[i]]].position*(*scale)+*coords;
650 end=joints[jointlabels[whichjointendarray[i]]].position*(*scale)+*coords;
651 whichhit=objects.model[k].LineCheckSlidePossible(&start,&end,&temp,&objects.position[k],&objects.rotation[k]);
653 joints[jointlabels[whichjointendarray[i]]].position=(end-*coords)/(*scale);
654 for(j=0; j<num_muscles; j++){
655 if((muscles[j].parent1->label==whichjointstartarray[i]&&muscles[j].parent2->label==whichjointendarray[i])||(muscles[j].parent2->label==whichjointstartarray[i]&&muscles[j].parent1->label==whichjointendarray[i]))
656 muscles[j].DoConstraint(spinny);
663 for(i=0; i<num_joints; i++){
665 if(joints[i].label==head)groundlevel=.8;
666 if(joints[i].label==righthand||joints[i].label==rightwrist||joints[i].label==rightelbow)groundlevel=.2;
667 if(joints[i].label==lefthand||joints[i].label==leftwrist||joints[i].label==leftelbow)groundlevel=.2;
668 joints[i].position.y+=groundlevel;
670 if(joints[i].label==lefthip||joints[i].label==leftknee||joints[i].label==leftankle||joints[i].label==righthip||joints[i].label==rightknee||joints[i].label==rightankle)joints[i].mass=2;
671 if(joints[i].locked){
679 for(i=0; i<num_muscles; i++){
680 if(muscles[i].type==boneconnect)
681 muscles[i].DoConstraint(0);
687 void Skeleton::DoGravity(float *scale)
690 for(i=0; i<num_joints; i++){
691 if(((joints[i].label!=leftknee&&joints[i].label!=rightknee)||lowforward.y>-.1||joints[i].mass<5)&&((joints[i].label!=rightelbow&&joints[i].label!=rightelbow)||forward.y<.3))joints[i].velocity.y+=gravity*multiplier/(*scale);
695 void Skeleton::Draw(int muscleview)
697 static float jointcolor[4];
712 //Calc motionblur-ness
713 for(int i=0; i<num_joints; i++){
714 joints[i].oldposition=joints[i].position;
715 joints[i].blurred=findDistance(&joints[i].position,&joints[i].oldposition)*100;
716 if(joints[i].blurred<1)joints[i].blurred=1;
722 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
724 for(int i=0; i<num_joints; i++){
725 if(joints[i].hasparent){
726 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].blurred);
727 glVertex3f(joints[i].position.x,joints[i].position.y,joints[i].position.z);
728 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].parent->blurred);
729 glVertex3f(joints[i].parent->position.x,joints[i].parent->position.y,joints[i].parent->position.z);
730 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].parent->blurred);
731 glVertex3f(joints[i].parent->oldposition.x,joints[i].parent->oldposition.y,joints[i].parent->oldposition.z);
732 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].blurred);
733 glVertex3f(joints[i].oldposition.x,joints[i].oldposition.y,joints[i].oldposition.z);
736 for(int i=0; i<num_muscles; i++){
737 if(muscles[i].type==boneconnect){
738 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent2->blurred);
739 glVertex3f(muscles[i].parent1->position.x,muscles[i].parent1->position.y,muscles[i].parent1->position.z);
740 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent2->blurred);
741 glVertex3f(muscles[i].parent2->position.x,muscles[i].parent2->position.y,muscles[i].parent2->position.z);
742 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent2->blurred);
743 glVertex3f(muscles[i].parent2->oldposition.x,muscles[i].parent2->oldposition.y,muscles[i].parent2->oldposition.z);
744 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent1->blurred);
745 glVertex3f(muscles[i].parent1->oldposition.x,muscles[i].parent1->oldposition.y,muscles[i].parent1->oldposition.z);
751 for(int i=0; i<num_joints; i++){
752 if(joints[i].hasparent){
753 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].blurred);
754 glVertex3f(joints[i].position.x,joints[i].position.y,joints[i].position.z);
755 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].parent->blurred);
756 glVertex3f(joints[i].parent->position.x,joints[i].parent->position.y,joints[i].parent->position.z);
759 /*for(int i=0; i<num_joints; i++){
760 if(joints[i].hasparent){
761 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],1);
762 glVertex3f(joints[i].position.x,joints[i].position.y,joints[i].position.z);
763 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],1);
764 glVertex3f(joints[i].position.x+forward.x,joints[i].position.y+forward.y,joints[i].position.z+forward.z);
767 for(int i=0; i<num_muscles; i++){
768 if(muscles[i].type==boneconnect){
769 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent1->blurred);
770 glVertex3f(muscles[i].parent1->position.x,muscles[i].parent1->position.y,muscles[i].parent1->position.z);
771 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent2->blurred);
772 glVertex3f(muscles[i].parent2->position.x,muscles[i].parent2->position.y,muscles[i].parent2->position.z);
777 for(int i=0; i<num_muscles; i++){
778 if(muscles[i].type!=boneconnect){
779 glVertex3f(muscles[i].parent1->position.x,muscles[i].parent1->position.y,muscles[i].parent1->position.z);
780 glVertex3f(muscles[i].parent2->position.x,muscles[i].parent2->position.y,muscles[i].parent2->position.z);
788 for(int i=0; i<num_joints; i++){
789 if(i!=selected)glColor4f(0,0,.5,1);
790 if(i==selected)glColor4f(1,1,0,1);
791 if(joints[i].locked&&i!=selected)glColor4f(1,0,0,1);
792 glVertex3f(joints[i].position.x,joints[i].position.y,joints[i].position.z);
797 //Set old position to current position
799 for(int i=0; i<num_joints; i++){
800 joints[i].oldposition=joints[i].position;
805 void Skeleton::AddJoint(float x, float y, float z, int which)
807 if(num_joints<max_joints-1){
808 joints[num_joints].velocity=0;
809 joints[num_joints].position.x=x;
810 joints[num_joints].position.y=y;
811 joints[num_joints].position.z=z;
812 joints[num_joints].mass=1;
813 joints[num_joints].locked=0;
815 /*if(which>=num_joints||which<0)*/joints[num_joints].hasparent=0;
816 /*if(which<num_joints&&which>=0){
817 joints[num_joints].parent=&joints[which];
818 joints[num_joints].hasparent=1;
819 joints[num_joints].length=findDistance(joints[num_joints].position,joints[num_joints].parent->position);
822 if(which<num_joints&&which>=0)AddMuscle(num_joints-1,which,0,10,boneconnect);
826 void Skeleton::DeleteJoint(int whichjoint)
828 if(whichjoint<num_joints&&whichjoint>=0){
829 joints[whichjoint].velocity=joints[num_joints-1].velocity;
830 joints[whichjoint].position=joints[num_joints-1].position;
831 joints[whichjoint].oldposition=joints[num_joints-1].oldposition;
832 joints[whichjoint].hasparent=joints[num_joints-1].hasparent;
833 joints[whichjoint].parent=joints[num_joints-1].parent;
834 joints[whichjoint].length=joints[num_joints-1].length;
835 joints[whichjoint].locked=joints[num_joints-1].locked;
836 joints[whichjoint].modelnum=joints[num_joints-1].modelnum;
837 joints[whichjoint].visible=joints[num_joints-1].visible;
839 for(int i=0;i<num_muscles;i++){
840 while(muscles[i].parent1==&joints[whichjoint]&&i<num_muscles)DeleteMuscle(i);
841 while(muscles[i].parent2==&joints[whichjoint]&&i<num_muscles)DeleteMuscle(i);
843 for(int i=0;i<num_muscles;i++){
844 while(muscles[i].parent1==&joints[num_joints-1]&&i<num_muscles)muscles[i].parent1=&joints[whichjoint];
845 while(muscles[i].parent2==&joints[num_joints-1]&&i<num_muscles)muscles[i].parent2=&joints[whichjoint];
847 for(int i=0;i<num_joints;i++){
848 if(joints[i].parent==&joints[whichjoint])joints[i].hasparent=0;
850 for(int i=0;i<num_joints;i++){
851 if(joints[i].parent==&joints[num_joints-1])joints[i].parent=&joints[whichjoint];
858 void Skeleton::DeleteMuscle(int whichmuscle)
860 if(whichmuscle<num_muscles){
861 muscles[whichmuscle].minlength=muscles[num_muscles-1].minlength;
862 muscles[whichmuscle].maxlength=muscles[num_muscles-1].maxlength;
863 muscles[whichmuscle].strength=muscles[num_muscles-1].strength;
864 muscles[whichmuscle].parent1=muscles[num_muscles-1].parent1;
865 muscles[whichmuscle].parent2=muscles[num_muscles-1].parent2;
866 muscles[whichmuscle].length=muscles[num_muscles-1].length;
867 muscles[whichmuscle].visible=muscles[num_muscles-1].visible;
868 muscles[whichmuscle].type=muscles[num_muscles-1].type;
869 muscles[whichmuscle].targetlength=muscles[num_muscles-1].targetlength;
875 void Skeleton::SetJoint(float x, float y, float z, int which, int whichjoint)
877 if(whichjoint<num_joints){
878 joints[whichjoint].velocity=0;
879 joints[whichjoint].position.x=x;
880 joints[whichjoint].position.y=y;
881 joints[whichjoint].position.z=z;
883 if(which>=num_joints||which<0)joints[whichjoint].hasparent=0;
884 if(which<num_joints&&which>=0){
885 joints[whichjoint].parent=&joints[which];
886 joints[whichjoint].hasparent=1;
887 joints[whichjoint].length=findDistance(&joints[whichjoint].position,&joints[whichjoint].parent->position);
892 void Skeleton::AddMuscle(int attach1,int attach2,float minlength,float maxlength,int type)
894 if(num_muscles<max_muscles-1&&attach1<num_joints&&attach1>=0&&attach2<num_joints&&attach2>=0&&attach1!=attach2){
895 muscles[num_muscles].parent1=&joints[attach1];
896 muscles[num_muscles].parent2=&joints[attach2];
897 muscles[num_muscles].length=findDistance(&muscles[num_muscles].parent1->position,&muscles[num_muscles].parent2->position);
898 muscles[num_muscles].targetlength=findDistance(&muscles[num_muscles].parent1->position,&muscles[num_muscles].parent2->position);
899 muscles[num_muscles].strength=.7;
900 muscles[num_muscles].type=type;
901 muscles[num_muscles].minlength=minlength;
902 muscles[num_muscles].maxlength=maxlength;
908 void Skeleton::MusclesSet()
910 for(int i=0;i<num_muscles;i++){
911 muscles[i].length=findDistance(&muscles[i].parent1->position,&muscles[i].parent2->position);
915 void Skeleton::DoBalance()
918 newpoint=joints[0].position;
919 newpoint.x=(joints[2].position.x+joints[4].position.x)/2;
920 newpoint.z=(joints[2].position.z+joints[4].position.z)/2;
921 joints[0].velocity=joints[0].velocity+(newpoint-joints[0].position);
922 //Move child point to within certain distance of parent point
923 joints[0].position=newpoint;
928 void Skeleton::FindRotationMuscle(int which, int animation)
930 static XYZ temppoint1,temppoint2,tempforward;
931 static float distance;
933 temppoint1=muscles[which].parent1->position;
934 temppoint2=muscles[which].parent2->position;
935 distance=sqrt((temppoint1.x-temppoint2.x)*(temppoint1.x-temppoint2.x)+(temppoint1.y-temppoint2.y)*(temppoint1.y-temppoint2.y)+(temppoint1.z-temppoint2.z)*(temppoint1.z-temppoint2.z));
936 if((temppoint1.y-temppoint2.y)<=distance)muscles[which].rotate2=asin((temppoint1.y-temppoint2.y)/distance);
937 if((temppoint1.y-temppoint2.y)>distance)muscles[which].rotate2=asin(1.f);
938 muscles[which].rotate2*=360/6.28;
941 distance=sqrt((temppoint1.x-temppoint2.x)*(temppoint1.x-temppoint2.x)+(temppoint1.y-temppoint2.y)*(temppoint1.y-temppoint2.y)+(temppoint1.z-temppoint2.z)*(temppoint1.z-temppoint2.z));
942 if((temppoint1.z-temppoint2.z)<=distance)muscles[which].rotate1=acos((temppoint1.z-temppoint2.z)/distance);
943 if((temppoint1.z-temppoint2.z)>distance)muscles[which].rotate1=acos(1.f);
944 muscles[which].rotate1*=360/6.28;
945 if(temppoint1.x>temppoint2.x)muscles[which].rotate1=360-muscles[which].rotate1;
946 if(!isnormal(muscles[which].rotate1))muscles[which].rotate1=0;
947 if(!isnormal(muscles[which].rotate2))muscles[which].rotate2=0;
949 if(muscles[which].parent1->label==head)tempforward=specialforward[0];
950 else if(muscles[which].parent1->label==rightshoulder||muscles[which].parent1->label==rightelbow||muscles[which].parent1->label==rightwrist||muscles[which].parent1->label==righthand)tempforward=specialforward[1];
951 else if(muscles[which].parent1->label==leftshoulder||muscles[which].parent1->label==leftelbow||muscles[which].parent1->label==leftwrist||muscles[which].parent1->label==lefthand)tempforward=specialforward[2];
952 else if(muscles[which].parent1->label==righthip||muscles[which].parent1->label==rightknee||muscles[which].parent1->label==rightankle||muscles[which].parent1->label==rightfoot)tempforward=specialforward[3];
953 else if(muscles[which].parent1->label==lefthip||muscles[which].parent1->label==leftknee||muscles[which].parent1->label==leftankle||muscles[which].parent1->label==leftfoot)tempforward=specialforward[4];
954 else if(!muscles[which].parent1->lower)tempforward=forward;
955 else if(muscles[which].parent1->lower)tempforward=lowforward;
957 if(animation==hanganim){
958 if(muscles[which].parent1->label==righthand||muscles[which].parent2->label==righthand){
962 if(muscles[which].parent1->label==lefthand||muscles[which].parent2->label==lefthand){
969 if(muscles[which].parent1->label==rightfoot||muscles[which].parent2->label==rightfoot){
972 if(muscles[which].parent1->label==leftfoot||muscles[which].parent2->label==leftfoot){
978 tempforward=DoRotation(tempforward,0,muscles[which].rotate1-90,0);
979 tempforward=DoRotation(tempforward,0,0,muscles[which].rotate2-90);
981 tempforward/=sqrt(tempforward.x*tempforward.x+tempforward.y*tempforward.y+tempforward.z*tempforward.z);
982 if(tempforward.z<=1&&tempforward.z>=-1)muscles[which].rotate3=acos(0-tempforward.z);
983 else muscles[which].rotate3=acos(-1.f);
984 muscles[which].rotate3*=360/6.28;
985 if(0>tempforward.x)muscles[which].rotate3=360-muscles[which].rotate3;
986 if(!isnormal(muscles[which].rotate3))muscles[which].rotate3=0;
989 void Animation::Load(char *filename, int aheight, int aattack)
993 static XYZ startoffset,endoffset;
998 LOG(std::string("Loading animation...") + filename);
1005 if(visibleloading)pgame->LoadingScreen();
1007 tfile=fopen( filename, "rb" );
1009 funpackf(tfile, "Bi Bi", &numframes, &joints);
1011 for(i = 0; i < joints; i++){
1012 if(position[i])dealloc2(position[i]);
1013 if(twist[i])dealloc2(twist[i]);
1014 if(twist2[i])dealloc2(twist2[i]);
1015 if(onground[i])dealloc2(onground[i]);
1018 if(position)dealloc2(position);
1019 if(twist)dealloc2(twist);
1020 if(twist2)dealloc2(twist2);
1021 if(speed)dealloc2(speed);
1022 if(onground)dealloc2(onground);
1023 if(forward)dealloc2(forward);
1024 if(weapontarget)dealloc2(weapontarget);
1025 if(label)dealloc2(label);*/
1027 position=(XYZ**)malloc(sizeof(XYZ*)*joints);
1028 for(i = 0; i < joints; i++)
1029 position[i] = (XYZ*)malloc(sizeof(XYZ)*numframes);
1031 twist=(float**)malloc(sizeof(float*)*joints);
1032 for(i = 0; i < joints; i++)
1033 twist[i] = (float*)malloc(sizeof(float)*numframes);
1035 twist2=(float**)malloc(sizeof(float*)*joints);
1036 for(i = 0; i < joints; i++)
1037 twist2[i] = (float*)malloc(sizeof(float)*numframes);
1039 speed = (float*)malloc(sizeof(float)*numframes);
1041 onground=(bool**)malloc(sizeof(bool*)*joints);
1042 for(i = 0; i < joints; i++)
1043 onground[i] =(bool*)malloc(sizeof(bool)*numframes);
1045 forward = (XYZ*)malloc(sizeof(XYZ)*numframes);
1046 weapontarget = (XYZ*)malloc(sizeof(XYZ)*numframes);
1047 label = (int*)malloc(sizeof(int)*numframes);
1049 /*position = new XYZ[joints][numframes];
1050 twist = new float[joints][numframes];
1051 twist2 = new float[joints][numframes];
1052 speed = new float[numframes];
1053 onground = new bool[joints][numframes];
1054 forward = new XYZ[numframes];
1055 label = new int[numframes];*/
1057 for(i=0;i<numframes;i++){
1058 for(j=0;j<joints;j++){
1059 funpackf(tfile, "Bf Bf Bf", &position[j][i].x,&position[j][i].y,&position[j][i].z);
1061 for(j=0;j<joints;j++){
1062 funpackf(tfile, "Bf", &twist[j][i]);
1064 for(j=0;j<joints;j++){
1066 funpackf(tfile, "Bb", &uch);
1067 onground[j][i] = (uch != 0);
1069 funpackf(tfile, "Bf", &speed[i]);
1071 for(i=0;i<numframes;i++){
1072 for(j=0;j<joints;j++){
1073 funpackf(tfile, "Bf", &twist2[j][i]);
1076 for(i=0;i<numframes;i++){
1077 funpackf(tfile, "Bf", &label[i]);
1079 funpackf(tfile, "Bi", &weapontargetnum);
1080 for(i=0;i<numframes;i++){
1081 funpackf(tfile, "Bf Bf Bf", &weapontarget[i].x,&weapontarget[i].y,&weapontarget[i].z);
1090 for(j=0;j<joints;j++){
1091 if(position[j][0].y<1)
1092 startoffset+=position[j][0];
1093 if(position[j][numframes-1].y<1)
1094 endoffset+=position[j][numframes-1];
1097 startoffset/=howmany;
1104 void Animation::Move(XYZ how)
1106 static int i,j,joints;
1107 for(i=0;i<numframes;i++){
1108 for(j=0;j<joints;j++){
1114 void Skeleton::Load(char *filename,char *lowfilename,char *clothesfilename, char *modelfilename, char *model2filename, char *model3filename, char *model4filename, char *model5filename, char *model6filename, char *model7filename, char *modellowfilename, char *modelclothesfilename, bool aclothes)
1116 static GLfloat M[16];
1117 static int parentID;
1120 static int i,j,tempmuscle;
1132 for(i=0;i<num_models;i++){
1133 if(i==0)model[i].loadnotex(modelfilename);
1134 if(i==1)model[i].loadnotex(model2filename);
1135 if(i==2)model[i].loadnotex(model3filename);
1136 if(i==3)model[i].loadnotex(model4filename);
1137 if(i==4)model[i].loadnotex(model5filename);
1138 if(i==5)model[i].loadnotex(model6filename);
1139 if(i==6)model[i].loadnotex(model7filename);
1140 model[i].Rotate(180,0,0);
1141 model[i].Scale(.04,.04,.04);
1142 model[i].CalculateNormals(0);
1145 drawmodel.load(modelfilename,0);
1146 drawmodel.Rotate(180,0,0);
1147 drawmodel.Scale(.04,.04,.04);
1148 drawmodel.FlipTexCoords();
1149 if(tutoriallevel==1&&id!=0)drawmodel.UniformTexCoords();
1150 if(tutoriallevel==1&&id!=0)drawmodel.ScaleTexCoords(0.1);
1151 drawmodel.CalculateNormals(0);
1153 modellow.loadnotex(modellowfilename);
1154 modellow.Rotate(180,0,0);
1155 modellow.Scale(.04,.04,.04);
1156 modellow.CalculateNormals(0);
1158 drawmodellow.load(modellowfilename,0);
1159 drawmodellow.Rotate(180,0,0);
1160 drawmodellow.Scale(.04,.04,.04);
1161 drawmodellow.FlipTexCoords();
1162 if(tutoriallevel==1&&id!=0)drawmodellow.UniformTexCoords();
1163 if(tutoriallevel==1&&id!=0)drawmodellow.ScaleTexCoords(0.1);
1164 drawmodellow.CalculateNormals(0);
1167 modelclothes.loadnotex(modelclothesfilename);
1168 modelclothes.Rotate(180,0,0);
1169 modelclothes.Scale(.041,.04,.041);
1170 modelclothes.CalculateNormals(0);
1172 drawmodelclothes.load(modelclothesfilename,0);
1173 drawmodelclothes.Rotate(180,0,0);
1174 drawmodelclothes.Scale(.04,.04,.04);
1175 drawmodelclothes.FlipTexCoords();
1176 drawmodelclothes.CalculateNormals(0);
1179 tfile=fopen( filename, "rb" );
1181 funpackf(tfile, "Bi", &num_joints);
1182 //joints.resize(num_joints);
1183 if(joints) delete [] joints; //dealloc2(joints);
1184 joints=(Joint*)new Joint[num_joints]; //malloc(sizeof(Joint)*num_joints);
1186 for(i=0;i<num_joints;i++){
1187 funpackf(tfile, "Bf Bf Bf Bf Bf", &joints[i].position.x, &joints[i].position.y, &joints[i].position.z, &joints[i].length,&joints[i].mass);
1188 funpackf(tfile, "Bb Bb", &joints[i].hasparent,&joints[i].locked);
1189 funpackf(tfile, "Bi", &joints[i].modelnum);
1190 funpackf(tfile, "Bb Bb", &joints[i].visible,&joints[i].sametwist);
1191 funpackf(tfile, "Bi Bi", &joints[i].label,&joints[i].hasgun);
1192 funpackf(tfile, "Bb", &joints[i].lower);
1193 funpackf(tfile, "Bi", &parentID);
1194 if(joints[i].hasparent)joints[i].parent=&joints[parentID];
1195 joints[i].velocity=0;
1196 joints[i].oldposition=joints[i].position;
1198 tempmuscle=num_muscles;
1199 funpackf(tfile, "Bi", &num_muscles);
1201 if(muscles) delete [] muscles; //dealloc2(muscles);
1202 muscles=(Muscle*)new Muscle[num_muscles]; //malloc(sizeof(Muscle)*num_muscles);
1204 for(i=0;i<num_muscles;i++){
1205 tempmuscle=muscles[i].numvertices;
1206 funpackf(tfile, "Bf Bf Bf Bf Bf Bi Bi", &muscles[i].length, &muscles[i].targetlength,&muscles[i].minlength, &muscles[i].maxlength,&muscles[i].strength,&muscles[i].type,&muscles[i].numvertices);
1207 //muscles[i].vertices.clear();
1208 //muscles[i].vertices.resize(muscles[i].numvertices);
1209 //if(muscles[i].vertices)dealloc2(muscles[i].vertices);
1210 muscles[i].vertices=(int*)malloc(sizeof(int)*muscles[i].numvertices);
1213 for(j=0;j<muscles[i].numvertices-edit;j++){
1214 funpackf(tfile, "Bi", &muscles[i].vertices[j+edit]);
1215 if(muscles[i].vertices[j+edit]>=model[0].vertexNum){
1216 muscles[i].numvertices--;
1220 funpackf(tfile, "Bb Bi", &muscles[i].visible, &parentID);
1221 muscles[i].parent1=&joints[parentID];
1222 funpackf(tfile, "Bi", &parentID);
1223 muscles[i].parent2=&joints[parentID];
1226 funpackf(tfile, "Bi", &forwardjoints[j]);
1229 funpackf(tfile, "Bi", &lowforwardjoints[j]);
1231 for(j=0;j<num_muscles;j++){
1232 for(i=0;i<muscles[j].numvertices;i++){
1233 for(int k=0;k<num_models;k++){
1234 if(muscles[j].numvertices&&muscles[j].vertices[i]<model[k].vertexNum)model[k].owner[muscles[j].vertices[i]]=j;
1239 for(i=0;i<num_joints;i++){
1240 joints[i].startpos=joints[i].position;
1242 for(i=0;i<num_muscles;i++){
1243 FindRotationMuscle(i,-1);
1245 for(int k=0;k<num_models;k++){
1246 for(i=0;i<model[k].vertexNum;i++){
1247 model[k].vertex[i]=model[k].vertex[i]-(muscles[model[k].owner[i]].parent1->position+muscles[model[k].owner[i]].parent2->position)/2;
1248 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
1251 glRotatef(muscles[model[k].owner[i]].rotate3,0,1,0);
1252 glRotatef(muscles[model[k].owner[i]].rotate2-90,0,0,1);
1253 glRotatef(muscles[model[k].owner[i]].rotate1-90,0,1,0);
1254 glTranslatef(model[k].vertex[i].x,model[k].vertex[i].y,model[k].vertex[i].z);
1255 glGetFloatv(GL_MODELVIEW_MATRIX,M);
1256 model[k].vertex[i].x=M[12]*1;
1257 model[k].vertex[i].y=M[13]*1;
1258 model[k].vertex[i].z=M[14]*1;
1261 model[k].CalculateNormals(0);
1266 tfile=fopen( lowfilename, "rb" );
1268 lSize=sizeof(num_joints);
1269 fseek ( tfile, lSize, SEEK_CUR);
1270 //joints = new Joint[num_joints];
1271 //jointlabels = new int[num_joints];
1272 for(i=0;i<num_joints;i++){
1274 fseek ( tfile, lSize, SEEK_CUR);
1275 lSize=sizeof(float);
1276 fseek ( tfile, lSize, SEEK_CUR);
1277 lSize=sizeof(float);
1278 fseek ( tfile, lSize, SEEK_CUR);
1279 lSize=1;//sizeof(bool);
1280 fseek ( tfile, lSize, SEEK_CUR);
1281 lSize=1;//sizeof(bool);
1282 fseek ( tfile, lSize, SEEK_CUR);
1284 fseek ( tfile, lSize, SEEK_CUR);
1285 lSize=1;//sizeof(bool);
1286 fseek ( tfile, lSize, SEEK_CUR);
1287 lSize=1;//sizeof(bool);
1288 fseek ( tfile, lSize, SEEK_CUR);
1290 fseek ( tfile, lSize, SEEK_CUR);
1292 fseek ( tfile, lSize, SEEK_CUR);
1293 lSize=1;//sizeof(bool);
1294 fseek ( tfile, lSize, SEEK_CUR);
1296 fseek ( tfile, lSize, SEEK_CUR);
1297 if(joints[i].hasparent)joints[i].parent=&joints[parentID];
1298 joints[i].velocity=0;
1299 joints[i].oldposition=joints[i].position;
1301 funpackf(tfile, "Bi", &num_muscles);
1302 //muscles = new Muscle[num_muscles];
1303 for(i=0;i<num_muscles;i++){
1304 lSize=sizeof(float);
1305 fseek ( tfile, lSize, SEEK_CUR);
1306 lSize=sizeof(float);
1307 fseek ( tfile, lSize, SEEK_CUR);
1308 lSize=sizeof(float);
1309 fseek ( tfile, lSize, SEEK_CUR);
1310 lSize=sizeof(float);
1311 fseek ( tfile, lSize, SEEK_CUR);
1312 lSize=sizeof(float);
1313 fseek ( tfile, lSize, SEEK_CUR);
1315 fseek ( tfile, lSize, SEEK_CUR);
1316 tempmuscle=muscles[i].numverticeslow;
1317 funpackf(tfile, "Bi", &muscles[i].numverticeslow);
1318 if(muscles[i].numverticeslow){
1319 //muscles[i].verticeslow.clear();
1320 //muscles[i].verticeslow.resize(muscles[i].numverticeslow);
1321 //if(muscles[i].verticeslow)dealloc2(muscles[i].verticeslow);
1322 muscles[i].verticeslow=(int*)malloc(sizeof(int)*muscles[i].numverticeslow);
1324 for(j=0;j<muscles[i].numverticeslow-edit;j++){
1325 funpackf(tfile, "Bi", &muscles[i].verticeslow[j+edit]);
1326 if(muscles[i].verticeslow[j+edit]>=modellow.vertexNum){
1327 muscles[i].numverticeslow--;
1334 lSize=1;//sizeof(bool);
1335 fseek ( tfile, lSize, SEEK_CUR);
1337 fseek ( tfile, lSize, SEEK_CUR);
1338 fseek ( tfile, lSize, SEEK_CUR);
1341 for(j=0;j<num_muscles;j++){
1342 for(i=0;i<muscles[j].numverticeslow;i++){
1343 if(muscles[j].numverticeslow&&muscles[j].verticeslow[i]<modellow.vertexNum)modellow.owner[muscles[j].verticeslow[i]]=j;
1347 for(i=0;i<num_joints;i++){
1348 joints[i].startpos=joints[i].position;
1350 for(i=0;i<num_muscles;i++){
1351 FindRotationMuscle(i,-1);
1353 for(i=0;i<modellow.vertexNum;i++){
1354 modellow.vertex[i]=modellow.vertex[i]-(muscles[modellow.owner[i]].parent1->position+muscles[modellow.owner[i]].parent2->position)/2;
1355 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
1358 glRotatef(muscles[modellow.owner[i]].rotate3,0,1,0);
1359 glRotatef(muscles[modellow.owner[i]].rotate2-90,0,0,1);
1360 glRotatef(muscles[modellow.owner[i]].rotate1-90,0,1,0);
1361 glTranslatef(modellow.vertex[i].x,modellow.vertex[i].y,modellow.vertex[i].z);
1362 glGetFloatv(GL_MODELVIEW_MATRIX,M);
1363 modellow.vertex[i].x=M[12];
1364 modellow.vertex[i].y=M[13];
1365 modellow.vertex[i].z=M[14];
1368 modellow.CalculateNormals(0);
1372 tfile=fopen( clothesfilename, "rb" );
1373 lSize=sizeof(num_joints);
1374 fseek ( tfile, lSize, SEEK_CUR);
1375 //joints = new Joint[num_joints];
1376 //jointlabels = new int[num_joints];
1377 for(i=0;i<num_joints;i++){
1379 fseek ( tfile, lSize, SEEK_CUR);
1380 lSize=sizeof(float);
1381 fseek ( tfile, lSize, SEEK_CUR);
1382 lSize=sizeof(float);
1383 fseek ( tfile, lSize, SEEK_CUR);
1384 lSize=1;//sizeof(bool);
1385 fseek ( tfile, lSize, SEEK_CUR);
1386 lSize=1;//sizeof(bool);
1387 fseek ( tfile, lSize, SEEK_CUR);
1389 fseek ( tfile, lSize, SEEK_CUR);
1390 lSize=1;//sizeof(bool);
1391 fseek ( tfile, lSize, SEEK_CUR);
1392 lSize=1;//sizeof(bool);
1393 fseek ( tfile, lSize, SEEK_CUR);
1395 fseek ( tfile, lSize, SEEK_CUR);
1397 fseek ( tfile, lSize, SEEK_CUR);
1398 lSize=1;//sizeof(bool);
1399 fseek ( tfile, lSize, SEEK_CUR);
1401 fseek ( tfile, lSize, SEEK_CUR);
1402 if(joints[i].hasparent)joints[i].parent=&joints[parentID];
1403 joints[i].velocity=0;
1404 joints[i].oldposition=joints[i].position;
1406 funpackf(tfile, "Bi", &num_muscles);
1407 //muscles = new Muscle[num_muscles];
1408 for(i=0;i<num_muscles;i++){
1409 lSize=sizeof(float);
1410 fseek ( tfile, lSize, SEEK_CUR);
1411 lSize=sizeof(float);
1412 fseek ( tfile, lSize, SEEK_CUR);
1413 lSize=sizeof(float);
1414 fseek ( tfile, lSize, SEEK_CUR);
1415 lSize=sizeof(float);
1416 fseek ( tfile, lSize, SEEK_CUR);
1417 lSize=sizeof(float);
1418 fseek ( tfile, lSize, SEEK_CUR);
1420 fseek ( tfile, lSize, SEEK_CUR);
1421 tempmuscle=muscles[i].numverticesclothes;
1422 funpackf(tfile, "Bi", &muscles[i].numverticesclothes);
1423 if(muscles[i].numverticesclothes){
1424 //muscles[i].verticesclothes.clear();
1425 //muscles[i].verticesclothes.resize(muscles[i].numverticesclothes);
1426 //if(muscles[i].verticesclothes)dealloc2(muscles[i].verticesclothes);
1427 muscles[i].verticesclothes=(int*)malloc(sizeof(int)*muscles[i].numverticesclothes);
1429 for(j=0;j<muscles[i].numverticesclothes-edit;j++){
1430 funpackf(tfile, "Bi", &muscles[i].verticesclothes[j+edit]);
1431 if(muscles[i].verticesclothes[j+edit]>=modelclothes.vertexNum){
1432 muscles[i].numverticesclothes--;
1437 lSize=1;//sizeof(bool);
1438 fseek ( tfile, lSize, SEEK_CUR);
1440 fseek ( tfile, lSize, SEEK_CUR);
1441 fseek ( tfile, lSize, SEEK_CUR);
1444 for(j=0;j<num_muscles;j++){
1445 for(i=0;i<muscles[j].numverticesclothes;i++){
1446 if(muscles[j].numverticesclothes&&muscles[j].verticesclothes[i]<modelclothes.vertexNum)modelclothes.owner[muscles[j].verticesclothes[i]]=j;
1450 for(i=0;i<num_joints;i++){
1451 joints[i].startpos=joints[i].position;
1453 for(i=0;i<num_muscles;i++){
1454 FindRotationMuscle(i,-1);
1456 for(i=0;i<modelclothes.vertexNum;i++){
1457 modelclothes.vertex[i]=modelclothes.vertex[i]-(muscles[modelclothes.owner[i]].parent1->position+muscles[modelclothes.owner[i]].parent2->position)/2;
1458 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
1461 glRotatef(muscles[modelclothes.owner[i]].rotate3,0,1,0);
1462 glRotatef(muscles[modelclothes.owner[i]].rotate2-90,0,0,1);
1463 glRotatef(muscles[modelclothes.owner[i]].rotate1-90,0,1,0);
1464 glTranslatef(modelclothes.vertex[i].x,modelclothes.vertex[i].y,modelclothes.vertex[i].z);
1465 glGetFloatv(GL_MODELVIEW_MATRIX,M);
1466 modelclothes.vertex[i].x=M[12];
1467 modelclothes.vertex[i].y=M[13];
1468 modelclothes.vertex[i].z=M[14];
1471 modelclothes.CalculateNormals(0);
1475 for(i=0;i<num_joints;i++){
1476 for(j=0;j<num_joints;j++){
1477 if(joints[i].label==j)jointlabels[j]=i;
1484 Animation::Animation()
1490 weapontargetnum = 0;
1502 Animation::~Animation()
1507 void Animation::deallocate()
1513 for(i = 0; i < joints; i++)
1514 dealloc2(position[i]);
1522 for(i = 0; i < joints; i++)
1531 for(i = 0; i < joints; i++)
1532 dealloc2(twist2[i]);
1540 for(i = 0; i < joints; i++)
1541 dealloc2(onground[i]);
1547 if(speed)dealloc2(speed);
1550 if(forward)dealloc2(forward);
1553 if(weapontarget)dealloc2(weapontarget);
1556 if(label)dealloc2(label);
1562 Skeleton::Skeleton()
1570 memset(forwardjoints, 0, sizeof(forwardjoints));
1575 memset(lowforwardjoints, 0, sizeof(lowforwardjoints));
1578 // XYZ specialforward[5];
1579 memset(jointlabels, 0, sizeof(jointlabels));
1583 // Model modelclothes;
1587 // Model drawmodellow;
1588 // Model drawmodelclothes;
1593 memset(skinText, 0, sizeof(skinText));
1610 Skeleton::~Skeleton()
1633 numverticesclothes = 0;
1642 rotate1 = 0,rotate2 = 0,rotate3 = 0;
1643 lastrotate1 = 0,lastrotate2 = 0,lastrotate3 = 0;
1644 oldrotate1 = 0,oldrotate2 = 0,oldrotate3 = 0;
1645 newrotate1 = 0,newrotate2 = 0,newrotate3 = 0;
1653 dealloc2(verticeslow);
1654 dealloc2(verticesclothes);
1657 Animation & Animation::operator = (const Animation & ani)
1661 bool allocate = true;
1663 allocate = ((ani.numframes != numframes) || (ani.joints != joints));
1665 if (allocate) deallocate();
1667 numframes = ani.numframes;
1668 height = ani.height;
1669 attack = ani.attack;
1670 joints = ani.joints;
1671 weapontargetnum = ani.weapontargetnum;
1673 if (allocate) position=(XYZ**)malloc(sizeof(XYZ*)*ani.joints);
1674 for(i = 0; i < ani.joints; i++)
1676 if (allocate) position[i] = (XYZ*)malloc(sizeof(XYZ)*ani.numframes);
1677 memcpy(position[i], ani.position[i], sizeof(XYZ)*ani.numframes);
1680 if (allocate) twist=(float**)malloc(sizeof(float*)*ani.joints);
1681 for(i = 0; i < ani.joints; i++)
1683 if (allocate) twist[i] = (float*)malloc(sizeof(float)*ani.numframes);
1684 memcpy(twist[i], ani.twist[i], sizeof(float)*ani.numframes);
1687 if (allocate) twist2=(float**)malloc(sizeof(float*)*ani.joints);
1688 for(i = 0; i < ani.joints; i++)
1690 if (allocate) twist2[i] = (float*)malloc(sizeof(float)*ani.numframes);
1691 memcpy(twist2[i], ani.twist2[i], sizeof(float)*ani.numframes);
1694 if (allocate) speed = (float*)malloc(sizeof(float)*ani.numframes);
1695 memcpy(speed, ani.speed, sizeof(float)*ani.numframes);
1697 if (allocate) onground=(bool**)malloc(sizeof(bool*)*ani.joints);
1698 for(i = 0; i < ani.joints; i++)
1700 if (allocate) onground[i] =(bool*)malloc(sizeof(bool)*ani.numframes);
1701 memcpy(onground[i], ani.onground[i], sizeof(bool)*ani.numframes);
1704 if (allocate) forward = (XYZ*)malloc(sizeof(XYZ)*ani.numframes);
1705 memcpy(forward, ani.forward, sizeof(XYZ)*ani.numframes);
1707 if (allocate) weapontarget = (XYZ*)malloc(sizeof(XYZ)*ani.numframes);
1708 memcpy(weapontarget, ani.weapontarget, sizeof(XYZ)*ani.numframes);
1710 if (allocate) label = (int*)malloc(sizeof(int)*ani.numframes);
1711 memcpy(label, ani.label, sizeof(int)*ani.numframes);