2 Copyright (C) 2003, 2010 - Wolfire Games
4 This file is part of Lugaru.
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.
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.
15 See the GNU General Public License for more details.
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.
22 /**> HEADER FILES <**/
25 #include "openal_wrapper.h"
27 extern float multiplier;
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 Sprites sprites;
35 extern int environment;
36 extern float terraindetail;
37 extern float camerashake;
40 extern XYZ envsound[30];
41 extern float envsoundvol[30];
42 extern int numenvsounds;
43 extern float envsoundlife[30];
45 extern float bonustime;
46 extern int tutoriallevel;
48 extern int whichjointstartarray[26];
49 extern int whichjointendarray[26];
52 extern bool visibleloading;
53 extern "C" void PlaySoundEx(int channel, OPENAL_SAMPLE *sptr, OPENAL_DSPUNIT *dsp, signed char startpaused);
55 void dealloc2(void* param){
60 void Muscle::DoConstraint(bool spinny)
64 static XYZ newpoint1,newpoint2;
66 static float oldlength;
67 static float relaxlength;
71 if(type!=boneconnect)relaxlength=findDistance(&parent1->position,&parent2->position);
73 if(type==boneconnect)strength=1;
74 if(type==constraint)strength=0;
76 if(strength<0)strength=0;
77 if(strength>1)strength=1;
79 length-=(length-relaxlength)*(1-strength)*multiplier*10000;
80 length-=(length-targetlength)*(strength)*multiplier*10000;
81 if(strength==0)length=relaxlength;
83 if((relaxlength-length>0&&relaxlength-oldlength<0)||(relaxlength-length<0&&relaxlength-oldlength>0))length=relaxlength;
86 if(length<minlength)length=minlength;
87 if(length>maxlength)length=maxlength;
91 if(length<minlength*.6)length=minlength*.6;
92 if(length>maxlength*1.4)length=maxlength*1.4;
95 if(length==relaxlength)return;
98 midp=(parent1->position*parent1->mass+parent2->position*parent2->mass)/(parent1->mass+parent2->mass);
99 //Find vector from midpoint to second vector
100 vel=parent2->position-midp;
101 //Change to unit vector
103 //Apply velocity change
104 newpoint1=midp-vel*length*(parent2->mass/(parent1->mass+parent2->mass));
105 newpoint2=midp+vel*length*(parent1->mass/(parent1->mass+parent2->mass));
107 parent1->velocity=parent1->velocity+(newpoint1-parent1->position)/multiplier/4;
108 parent2->velocity=parent2->velocity+(newpoint2-parent2->position)/multiplier/4;
112 parent1->velocity=parent1->velocity+(newpoint1-parent1->position);
113 parent2->velocity=parent2->velocity+(newpoint2-parent2->position);
115 //Move child point to within certain distance of parent point
116 parent1->position=newpoint1;
117 parent2->position=newpoint2;
120 void Skeleton::FindForwardsfirst()
122 //Find forward vectors
123 CrossProduct(joints[forwardjoints[1]].position-joints[forwardjoints[0]].position,joints[forwardjoints[2]].position-joints[forwardjoints[0]].position,&forward);
126 CrossProduct(joints[lowforwardjoints[1]].position-joints[lowforwardjoints[0]].position,joints[lowforwardjoints[2]].position-joints[lowforwardjoints[0]].position,&lowforward);
127 Normalise(&lowforward);
130 specialforward[0]=forward;
131 specialforward[1]=forward;
132 specialforward[2]=forward;
133 specialforward[3]=forward;
134 specialforward[4]=forward;
137 void Skeleton::FindForwards()
139 //Find forward vectors
140 CrossProduct(joints[forwardjoints[1]].position-joints[forwardjoints[0]].position,joints[forwardjoints[2]].position-joints[forwardjoints[0]].position,&forward);
143 CrossProduct(joints[lowforwardjoints[1]].position-joints[lowforwardjoints[0]].position,joints[lowforwardjoints[2]].position-joints[lowforwardjoints[0]].position,&lowforward);
144 Normalise(&lowforward);
147 specialforward[0]=forward;
149 specialforward[1]=joints[jointlabels[rightshoulder]].position+joints[jointlabels[rightwrist]].position;
150 specialforward[1]=joints[jointlabels[rightelbow]].position-specialforward[1]/2;
151 specialforward[1]+=forward*.4;
152 Normalise(&specialforward[1]);
153 specialforward[2]=joints[jointlabels[leftshoulder]].position+joints[jointlabels[leftwrist]].position;
154 specialforward[2]=joints[jointlabels[leftelbow]].position-specialforward[2]/2;
155 specialforward[2]+=forward*.4;
156 Normalise(&specialforward[2]);
158 specialforward[3]=joints[jointlabels[righthip]].position+joints[jointlabels[rightankle]].position;
159 specialforward[3]=specialforward[3]/2-joints[jointlabels[rightknee]].position;
160 specialforward[3]+=lowforward*.4;
161 Normalise(&specialforward[3]);
162 specialforward[4]=joints[jointlabels[lefthip]].position+joints[jointlabels[leftankle]].position;
163 specialforward[4]=specialforward[4]/2-joints[jointlabels[leftknee]].position;
164 specialforward[4]+=lowforward*.4;
165 Normalise(&specialforward[4]);
168 float Skeleton::DoConstraints(XYZ *coords,float *scale)
170 static float friction=1.5;
171 static float elasticity=.3;
172 static XYZ bounceness;
173 static XYZ oldpos[100];
174 static int numrepeats=3;
175 static float groundlevel=.15;
176 static float soundvolume;
177 static int i,j,k,l,m;
178 static XYZ temp,start,end;
179 static XYZ terrainnormal;
183 //static int whichjointstart,whichjointend;
184 static float distance;
185 static float frictionness;
186 static XYZ terrainlight;
187 static int whichpatchx;
188 static int whichpatchz;
191 static float tempmult;
192 static bool breaking;
198 freetime+=multiplier;
200 whichpatchx=coords->x/(terrain.size/subdivision*terrain.scale*terraindetail);
201 whichpatchz=coords->z/(terrain.size/subdivision*terrain.scale*terraindetail);
203 terrainlight=*coords;
204 objects.SphereCheckPossible(&terrainlight, 1);
206 for(i=0; i<num_joints; i++){
207 oldpos[i]=joints[i].position;
211 for(i=0; i<num_joints; i++){
212 //if(!isnormal(joints[i].velocity.x)||!isnormal(joints[i].velocity.y)||!isnormal(joints[i].velocity.z))joints[i].velocity=0;
213 joints[i].position=joints[i].position+joints[i].velocity*multiplier;
215 if(joints[i].label==head)groundlevel=.8;
216 if(joints[i].label==righthand||joints[i].label==rightwrist||joints[i].label==rightelbow)groundlevel=.2;
217 if(joints[i].label==lefthand||joints[i].label==leftwrist||joints[i].label==leftelbow)groundlevel=.2;
218 joints[i].position.y-=groundlevel;
219 //if(!joints[i].locked&&!broken)joints[i].velocity+=joints[i].velchange*multiplier*10*(500-longdead)/500;
220 joints[i].oldvelocity=joints[i].velocity;
223 //multiplier/=numrepeats;
224 for(j=0; j<numrepeats; j++){
225 if(!joints[jointlabels[rightknee]].locked&&!joints[jointlabels[righthip]].locked){
226 temp=joints[jointlabels[rightknee]].position-(joints[jointlabels[righthip]].position+joints[jointlabels[rightankle]].position)/2;
227 while(normaldotproduct(temp,lowforward)>-.1&&!sphere_line_intersection(&joints[jointlabels[righthip]].position,&joints[jointlabels[rightankle]].position,&joints[jointlabels[rightknee]].position,&r)){
228 joints[jointlabels[rightknee]].position-=lowforward*.05;
229 if(spinny)joints[jointlabels[rightknee]].velocity-=lowforward*.05/multiplier/4;
230 else joints[jointlabels[rightknee]].velocity-=lowforward*.05;
231 joints[jointlabels[rightankle]].position+=lowforward*.025;
232 if(spinny)joints[jointlabels[rightankle]].velocity+=lowforward*.025/multiplier/4;
233 else joints[jointlabels[rightankle]].velocity+=lowforward*.25;
234 joints[jointlabels[righthip]].position+=lowforward*.025;
235 if(spinny)joints[jointlabels[righthip]].velocity+=lowforward*.025/multiplier/4;
236 else joints[jointlabels[righthip]].velocity+=lowforward*.025;
237 temp=joints[jointlabels[rightknee]].position-(joints[jointlabels[righthip]].position+joints[jointlabels[rightankle]].position)/2;
240 if(!joints[jointlabels[leftknee]].locked&&!joints[jointlabels[righthip]].locked){
241 temp=joints[jointlabels[leftknee]].position-(joints[jointlabels[lefthip]].position+joints[jointlabels[leftankle]].position)/2;
242 while(normaldotproduct(temp,lowforward)>-.1&&!sphere_line_intersection(&joints[jointlabels[lefthip]].position,&joints[jointlabels[leftankle]].position,&joints[jointlabels[leftknee]].position,&r)){
243 joints[jointlabels[leftknee]].position-=lowforward*.05;
244 if(spinny)joints[jointlabels[leftknee]].velocity-=lowforward*.05/multiplier/4;
245 else joints[jointlabels[leftknee]].velocity-=lowforward*.05;
246 joints[jointlabels[leftankle]].position+=lowforward*.025;
247 if(spinny)joints[jointlabels[leftankle]].velocity+=lowforward*.025/multiplier/4;
248 else joints[jointlabels[leftankle]].velocity+=lowforward*.25;
249 joints[jointlabels[lefthip]].position+=lowforward*.025;
250 if(spinny)joints[jointlabels[lefthip]].velocity+=lowforward*.025/multiplier/4;
251 else joints[jointlabels[lefthip]].velocity+=lowforward*.025;
252 temp=joints[jointlabels[leftknee]].position-(joints[jointlabels[lefthip]].position+joints[jointlabels[leftankle]].position)/2;
256 if(terrain.patchobjectnum[whichpatchx][whichpatchz])
257 for(m=0;m<terrain.patchobjectnum[whichpatchx][whichpatchz];m++){
258 k=terrain.patchobjects[whichpatchx][whichpatchz][m];
259 if(k<objects.numobjects&&k>=0)
260 if(objects.possible[k]){
261 temp=joints[jointlabels[head]].position*(*scale)+*coords;
262 if(objects.model[k].SphereCheck(&temp, 0.06, &start, &objects.position[k], &objects.rotation[k])!=-1){
263 //temp=(joints[jointlabels[head]].position*(*scale)+*coords)-start;
265 //joints[jointlabels[head]].position=((temp*.2+start)-*coords)/(*scale);
266 joints[jointlabels[head]].position=(temp-*coords)/(*scale);
274 startheadpos=joints[jointlabels[head]].position;
276 headpos=joints[jointlabels[head]].position+(joints[jointlabels[head]].position-joints[jointlabels[neck]].position);
277 if(terrain.patchobjectnum[whichpatchx][whichpatchz])
278 for(m=0;m<terrain.patchobjectnum[whichpatchx][whichpatchz];m++){
279 k=terrain.patchobjects[whichpatchx][whichpatchz][m];
280 if(k<objects.numobjects&&k>=0)
281 if(objects.possible[k]){
282 friction=objects.friction[k];
283 start=joints[jointlabels[head]].position*(*scale)+*coords;
284 end=(headpos)*(*scale)+*coords;
285 whichhit=objects.model[k].LineCheckPossible(&start,&end,&temp,&objects.position[k],&objects.rotation[k]);
287 if(joints[jointlabels[head]].label==groin&&!joints[jointlabels[head]].locked&&joints[jointlabels[head]].delay<=0){
288 joints[jointlabels[head]].locked=1;
289 joints[jointlabels[head]].delay=1;
290 static float gLoc[3];
292 gLoc[0]=headpos.x*(*scale)+coords->x;
293 gLoc[1]=headpos.y*(*scale)+coords->y;
294 gLoc[2]=headpos.z*(*scale)+coords->z;
295 vel[0]=joints[jointlabels[head]].velocity.x;
296 vel[1]=joints[jointlabels[head]].velocity.y;
297 vel[2]=joints[jointlabels[head]].velocity.z;
298 PlaySoundEx( landsound1, samp[landsound1], NULL, true);
299 OPENAL_3D_SetAttributes(channels[landsound1], gLoc, vel);
300 OPENAL_SetVolume(channels[landsound1], 128);
301 OPENAL_SetPaused(channels[landsound1], false);
306 if(joints[jointlabels[head]].label==head&&!joints[jointlabels[head]].locked&&joints[jointlabels[head]].delay<=0){
307 joints[jointlabels[head]].locked=1;
308 joints[jointlabels[head]].delay=1;
309 static float gLoc[3];
311 gLoc[0]=headpos.x*(*scale)+coords->x;
312 gLoc[1]=headpos.y*(*scale)+coords->y;
313 gLoc[2]=headpos.z*(*scale)+coords->z;
314 vel[0]=joints[jointlabels[head]].velocity.x;
315 vel[1]=joints[jointlabels[head]].velocity.y;
316 vel[2]=joints[jointlabels[head]].velocity.z;
317 PlaySoundEx( landsound2, samp[landsound2], NULL, true);
318 OPENAL_3D_SetAttributes(channels[landsound2], gLoc, vel);
319 OPENAL_SetVolume(channels[landsound2], 128);
320 OPENAL_SetPaused(channels[landsound2], false);
323 terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0)*-1;
324 if(terrainnormal.y>.8)freefall=0;
325 bounceness=terrainnormal*findLength(&joints[jointlabels[head]].velocity)*(abs(normaldotproduct(joints[jointlabels[head]].velocity,terrainnormal)));
326 if(findLengthfast(&joints[jointlabels[head]].velocity)>findLengthfast(&joints[jointlabels[head]].oldvelocity)){
328 joints[jointlabels[head]].velocity=joints[jointlabels[head]].oldvelocity;
330 if(findLengthfast(&bounceness)>4000&&breaking){
331 objects.model[k].MakeDecal(breakdecal,DoRotation(temp-objects.position[k],0,-objects.rotation[k],0),.4,.5,Random()%360);
332 sprites.MakeSprite(cloudsprite, headpos*(*scale)+*coords,joints[jointlabels[head]].velocity*.06, 1,1,1, 4, .2);
336 static float gLoc[3];
338 gLoc[0]=headpos.x*(*scale)+coords->x;
339 gLoc[1]=headpos.y*(*scale)+coords->y;
340 gLoc[2]=headpos.z*(*scale)+coords->z;
341 vel[0]=joints[jointlabels[head]].velocity.x;
342 vel[1]=joints[jointlabels[head]].velocity.y;
343 vel[2]=joints[jointlabels[head]].velocity.z;
344 PlaySoundEx( breaksound2, samp[breaksound2], NULL, true);
345 OPENAL_3D_SetAttributes(channels[breaksound2], gLoc, vel);
346 OPENAL_SetVolume(channels[breaksound2], 300);
347 OPENAL_SetPaused(channels[breaksound2], false);
349 envsound[numenvsounds]=*coords;
350 envsoundvol[numenvsounds]=64;
351 envsoundlife[numenvsounds]=.4;
354 if(objects.type[k]==treetrunktype){
355 objects.rotx[k]+=joints[jointlabels[head]].velocity.x*multiplier*.4;
356 objects.roty[k]+=joints[jointlabels[head]].velocity.z*multiplier*.4;
357 objects.rotx[k+1]+=joints[jointlabels[head]].velocity.x*multiplier*.4;
358 objects.roty[k+1]+=joints[jointlabels[head]].velocity.z*multiplier*.4;
360 if(!joints[jointlabels[head]].locked)damage+=findLengthfast(&bounceness)/2500;
361 ReflectVector(&joints[jointlabels[head]].velocity,&terrainnormal);
362 frictionness=abs(normaldotproduct(joints[jointlabels[head]].velocity,terrainnormal));//findLength(&bounceness)/findLength(&joints[jointlabels[head]].velocity);
363 joints[jointlabels[head]].velocity-=bounceness;
364 if(1-friction*frictionness>0)joints[jointlabels[head]].velocity*=1-friction*frictionness;
365 else joints[jointlabels[head]].velocity=0;
366 if(findLengthfast(&bounceness)>2500){
367 Normalise(&bounceness);
368 bounceness=bounceness*50;
370 joints[jointlabels[head]].velocity+=bounceness*elasticity;
373 if(!joints[jointlabels[head]].locked)
374 if(findLengthfast(&joints[jointlabels[head]].velocity)<1){
375 joints[jointlabels[head]].locked=1;
376 //joints[jointlabels[head]].velocity*=3;
378 if(findLengthfast(&bounceness)>500)sprites.MakeSprite(cloudsprite, headpos*(*scale)+*coords,joints[jointlabels[head]].velocity*.06, 1,1,1, .5, .2);
379 joints[jointlabels[head]].position=(temp-*coords)/(*scale)+(startheadpos-headpos)+terrainnormal*.005;
380 if(longdead>100)broken=1;
386 for(i=0; i<num_joints; i++){
387 //joints[i].delay-=multiplier/1.5;
389 if(!spinny)if(findLengthfast(&joints[i].velocity)>320)joints[i].locked=0;
390 if(spinny)if(findLengthfast(&joints[i].velocity)>600)joints[i].locked=0;
391 if(joints[i].delay>0){
393 for(j=0;j<num_joints;j++){
394 if(joints[j].locked)freely=0;
396 if(freely)joints[i].delay-=multiplier*3;
398 //if(joints[i].delay>0)
399 //if(findLengthfast(&joints[i].velocity)>700&&joints[i].label!=head)joints[i].delay-=multiplier;
403 for(i=0; i<num_muscles; i++){
405 //muscles[i].DoConstraint(broken);
406 muscles[i].DoConstraint(spinny);
409 for(i=0; i<num_joints; i++){
410 //joints[i].delay-=multiplier/1.5;
414 if(joints[i].position.y*(*scale)+coords->y<terrain.getHeight(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z)+groundlevel){
417 if(joints[i].label==groin&&!joints[i].locked&&joints[i].delay<=0){
420 static float gLoc[3];
422 gLoc[0]=joints[i].position.x*(*scale)+coords->x;
423 gLoc[1]=joints[i].position.y*(*scale)+coords->y;
424 gLoc[2]=joints[i].position.z*(*scale)+coords->z;
425 vel[0]=joints[i].velocity.x;
426 vel[1]=joints[i].velocity.y;
427 vel[2]=joints[i].velocity.z;
428 if(tutoriallevel!=1||id==0){
429 PlaySoundEx( landsound1, samp[landsound1], NULL, true);
430 OPENAL_3D_SetAttributes(channels[landsound1], gLoc, vel);
431 OPENAL_SetVolume(channels[landsound1], 128);
432 OPENAL_SetPaused(channels[landsound1], false);
437 if(joints[i].label==head&&!joints[i].locked&&joints[i].delay<=0){
440 static float gLoc[3];
442 gLoc[0]=joints[i].position.x*(*scale)+coords->x;
443 gLoc[1]=joints[i].position.y*(*scale)+coords->y;
444 gLoc[2]=joints[i].position.z*(*scale)+coords->z;
445 vel[0]=joints[i].velocity.x;
446 vel[1]=joints[i].velocity.y;
447 vel[2]=joints[i].velocity.z;
448 if(tutoriallevel!=1||id==0){
449 PlaySoundEx( landsound2, samp[landsound2], NULL, true);
450 OPENAL_3D_SetAttributes(channels[landsound2], gLoc, vel);
451 OPENAL_SetVolume(channels[landsound2], 128);
452 OPENAL_SetPaused(channels[landsound2], false);
456 terrainnormal=terrain.getNormal(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z);
457 ReflectVector(&joints[i].velocity,&terrainnormal);
458 bounceness=terrainnormal*findLength(&joints[i].velocity)*(abs(normaldotproduct(joints[i].velocity,terrainnormal)));
459 if(!joints[i].locked)damage+=findLengthfast(&bounceness)/4000;
460 if(findLengthfast(&joints[i].velocity)<findLengthfast(&bounceness))bounceness=0;
461 frictionness=abs(normaldotproduct(joints[i].velocity,terrainnormal));//findLength(&bounceness)/findLength(&joints[i].velocity);
462 joints[i].velocity-=bounceness;
463 if(1-friction*frictionness>0)joints[i].velocity*=1-friction*frictionness;
464 else joints[i].velocity=0;
466 if(tutoriallevel!=1||id==0)
467 if(findLengthfast(&bounceness)>8000&&breaking){
468 objects.model[k].MakeDecal(breakdecal,DoRotation(temp-objects.position[k],0,-objects.rotation[k],0),.4,.5,Random()%360);
469 sprites.MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, 1,1,1, 4, .2);
470 //sprites.MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, 1,1,1, 1, .2);
474 static float gLoc[3];
476 gLoc[0]=joints[i].position.x*(*scale)+coords->x;
477 gLoc[1]=joints[i].position.y*(*scale)+coords->y;
478 gLoc[2]=joints[i].position.z*(*scale)+coords->z;
479 vel[0]=joints[i].velocity.x;
480 vel[1]=joints[i].velocity.y;
481 vel[2]=joints[i].velocity.z;
482 PlaySoundEx( breaksound2, samp[breaksound2], NULL, true);
483 OPENAL_3D_SetAttributes(channels[breaksound2], gLoc, vel);
484 OPENAL_SetVolume(channels[breaksound2], 300);
485 OPENAL_SetPaused(channels[breaksound2], false);
487 envsound[numenvsounds]=*coords;
488 envsoundvol[numenvsounds]=64;
489 envsoundlife[numenvsounds]=.4;
493 if(findLengthfast(&bounceness)>2500){
494 Normalise(&bounceness);
495 bounceness=bounceness*50;
498 joints[i].velocity+=bounceness*elasticity;
500 if(findLengthfast(&joints[i].velocity)>findLengthfast(&joints[i].oldvelocity)){
502 joints[i].velocity=joints[i].oldvelocity;
506 if(joints[i].locked==0)
507 if(findLengthfast(&joints[i].velocity)<1)joints[i].locked=1;
509 if(environment==snowyenvironment&&findLengthfast(&bounceness)>500&&terrain.getOpacity(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z)<.2){
510 terrainlight=terrain.getLighting(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z);
511 sprites.MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, terrainlight.x,terrainlight.y,terrainlight.z, .5, .7);
512 if(detail==2)terrain.MakeDecal(bodyprintdecal, joints[i].position*(*scale)+*coords,.4,.4,0);
514 else if(environment==desertenvironment&&findLengthfast(&bounceness)>500&&terrain.getOpacity(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z)<.2){
515 terrainlight=terrain.getLighting(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z);
516 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);
519 else if(environment==grassyenvironment&&findLengthfast(&bounceness)>500&&terrain.getOpacity(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z)<.2){
520 terrainlight=terrain.getLighting(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z);
521 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);
523 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);
526 joints[i].position.y=(terrain.getHeight(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z)+groundlevel-coords->y)/(*scale);
527 if(longdead>100)broken=1;
529 if(terrain.patchobjectnum[whichpatchx][whichpatchz])
530 for(m=0;m<terrain.patchobjectnum[whichpatchx][whichpatchz];m++){
531 k=terrain.patchobjects[whichpatchx][whichpatchz][m];
532 if(k<objects.numobjects&&k>=0)
533 if(objects.possible[k]){
534 friction=objects.friction[k];
535 start=joints[i].realoldposition;
536 end=joints[i].position*(*scale)+*coords;
537 whichhit=objects.model[k].LineCheckPossible(&start,&end,&temp,&objects.position[k],&objects.rotation[k]);
539 if(joints[i].label==groin&&!joints[i].locked&&joints[i].delay<=0){
542 static float gLoc[3];
544 gLoc[0]=joints[i].position.x*(*scale)+coords->x;
545 gLoc[1]=joints[i].position.y*(*scale)+coords->y;
546 gLoc[2]=joints[i].position.z*(*scale)+coords->z;
547 vel[0]=joints[i].velocity.x;
548 vel[1]=joints[i].velocity.y;
549 vel[2]=joints[i].velocity.z;
550 if(tutoriallevel!=1||id==0){
551 PlaySoundEx( landsound1, samp[landsound1], NULL, true);
552 OPENAL_3D_SetAttributes(channels[landsound1], gLoc, vel);
553 OPENAL_SetVolume(channels[landsound1], 128);
554 OPENAL_SetPaused(channels[landsound1], false);
559 if(joints[i].label==head&&!joints[i].locked&&joints[i].delay<=0){
562 static float gLoc[3];
564 gLoc[0]=joints[i].position.x*(*scale)+coords->x;
565 gLoc[1]=joints[i].position.y*(*scale)+coords->y;
566 gLoc[2]=joints[i].position.z*(*scale)+coords->z;
567 vel[0]=joints[i].velocity.x;
568 vel[1]=joints[i].velocity.y;
569 vel[2]=joints[i].velocity.z;
570 if(tutoriallevel!=1||id==0){
571 PlaySoundEx( landsound2, samp[landsound2], NULL, true);
572 OPENAL_3D_SetAttributes(channels[landsound2], gLoc, vel);
573 OPENAL_SetVolume(channels[landsound2], 128);
574 OPENAL_SetPaused(channels[landsound2], false);
578 terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0)*-1;
579 if(terrainnormal.y>.8)freefall=0;
580 bounceness=terrainnormal*findLength(&joints[i].velocity)*(abs(normaldotproduct(joints[i].velocity,terrainnormal)));
581 if(findLengthfast(&joints[i].velocity)>findLengthfast(&joints[i].oldvelocity)){
583 joints[i].velocity=joints[i].oldvelocity;
585 if(tutoriallevel!=1||id==0)
586 if(findLengthfast(&bounceness)>4000&&breaking){
587 objects.model[k].MakeDecal(breakdecal,DoRotation(temp-objects.position[k],0,-objects.rotation[k],0),.4,.5,Random()%360);
588 sprites.MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, 1,1,1, 4, .2);
592 static float gLoc[3];
594 gLoc[0]=joints[i].position.x*(*scale)+coords->x;
595 gLoc[1]=joints[i].position.y*(*scale)+coords->y;
596 gLoc[2]=joints[i].position.z*(*scale)+coords->z;
597 vel[0]=joints[i].velocity.x;
598 vel[1]=joints[i].velocity.y;
599 vel[2]=joints[i].velocity.z;
600 PlaySoundEx( breaksound2, samp[breaksound2], NULL, true);
601 OPENAL_3D_SetAttributes(channels[breaksound2], gLoc, vel);
602 OPENAL_SetVolume(channels[breaksound2], 300);
603 OPENAL_SetPaused(channels[breaksound2], false);
605 envsound[numenvsounds]=*coords;
606 envsoundvol[numenvsounds]=64;
607 envsoundlife[numenvsounds]=.4;
610 if(objects.type[k]==treetrunktype){
611 //if(objects.rotx[k]==0||objects.roty[k]==0){
615 if(environment==grassyenvironment)howmany=findLength(&joints[i].velocity)*4/10;
616 if(environment==snowyenvironment)howmany=findLength(&joints[i].velocity)*1/10;
617 if(environment!=desertenvironment)
618 for(j=0;j<howmany;j++){
619 tempvel.x=float(abs(Random()%100)-50)/20;
620 tempvel.y=float(abs(Random()%100)-50)/20;
621 tempvel.z=float(abs(Random()%100)-50)/20;
622 pos=objects.position[k];
623 pos.y+=objects.scale[k]*15;
624 pos.x+=float(abs(Random()%100)-50)/100*objects.scale[k]*5;
625 pos.y+=float(abs(Random()%100)-50)/100*objects.scale[k]*15;
626 pos.z+=float(abs(Random()%100)-50)/100*objects.scale[k]*5;
627 sprites.MakeSprite(splintersprite, pos,tempvel*.5, 165/255+float(abs(Random()%100)-50)/400,0,0, .2+float(abs(Random()%100)-50)/1300, 1);
628 sprites.special[sprites.numsprites-1]=1;
630 objects.rotx[k]+=joints[i].velocity.x*multiplier*.4;
631 objects.roty[k]+=joints[i].velocity.z*multiplier*.4;
632 objects.rotx[k+1]+=joints[i].velocity.x*multiplier*.4;
633 objects.roty[k+1]+=joints[i].velocity.z*multiplier*.4;
635 if(!joints[i].locked)damage+=findLengthfast(&bounceness)/2500;
636 ReflectVector(&joints[i].velocity,&terrainnormal);
637 frictionness=abs(normaldotproduct(joints[i].velocity,terrainnormal));//findLength(&bounceness)/findLength(&joints[i].velocity);
638 joints[i].velocity-=bounceness;
639 if(1-friction*frictionness>0)joints[i].velocity*=1-friction*frictionness;
640 else joints[i].velocity=0;
641 if(findLengthfast(&bounceness)>2500){
642 Normalise(&bounceness);
643 bounceness=bounceness*50;
645 joints[i].velocity+=bounceness*elasticity;
648 if(!joints[i].locked)
649 if(findLengthfast(&joints[i].velocity)<1){
651 //joints[i].velocity*=3;
653 if(findLengthfast(&bounceness)>500)sprites.MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, 1,1,1, .5, .2);
654 joints[i].position=(temp-*coords)/(*scale)+terrainnormal*.005;
655 if(longdead>100)broken=1;
659 joints[i].realoldposition=joints[i].position*(*scale)+*coords;
665 if(terrain.patchobjectnum[whichpatchx][whichpatchz])
666 for(m=0;m<terrain.patchobjectnum[whichpatchx][whichpatchz];m++){
667 k=terrain.patchobjects[whichpatchx][whichpatchz][m];
668 if(objects.possible[k]){
670 //Make this less stupid
671 start=joints[jointlabels[whichjointstartarray[i]]].position*(*scale)+*coords;
672 end=joints[jointlabels[whichjointendarray[i]]].position*(*scale)+*coords;
673 whichhit=objects.model[k].LineCheckSlidePossible(&start,&end,&temp,&objects.position[k],&objects.rotation[k]);
675 joints[jointlabels[whichjointendarray[i]]].position=(end-*coords)/(*scale);
676 for(j=0; j<num_muscles; j++){
677 if((muscles[j].parent1->label==whichjointstartarray[i]&&muscles[j].parent2->label==whichjointendarray[i])||(muscles[j].parent2->label==whichjointstartarray[i]&&muscles[j].parent1->label==whichjointendarray[i]))
678 muscles[j].DoConstraint(spinny);
685 for(i=0; i<num_joints; i++){
687 if(joints[i].label==head)groundlevel=.8;
688 if(joints[i].label==righthand||joints[i].label==rightwrist||joints[i].label==rightelbow)groundlevel=.2;
689 if(joints[i].label==lefthand||joints[i].label==leftwrist||joints[i].label==leftelbow)groundlevel=.2;
690 joints[i].position.y+=groundlevel;
692 if(joints[i].label==lefthip||joints[i].label==leftknee||joints[i].label==leftankle||joints[i].label==righthip||joints[i].label==rightknee||joints[i].label==rightankle)joints[i].mass=2;
693 if(joints[i].locked){
701 for(i=0; i<num_muscles; i++){
702 if(muscles[i].type==boneconnect)
703 muscles[i].DoConstraint(0);
709 void Skeleton::DoGravity(float *scale)
712 for(i=0; i<num_joints; i++){
713 if(((joints[i].label!=leftknee&&joints[i].label!=rightknee)||lowforward.y>-.1||joints[i].mass<5)&&((joints[i].label!=rightelbow&&joints[i].label!=rightelbow)||forward.y<.3))joints[i].velocity.y+=gravity*multiplier/(*scale);
717 void Skeleton::Draw(int muscleview)
719 static float jointcolor[4];
734 //Calc motionblur-ness
735 for(int i=0; i<num_joints; i++){
736 joints[i].oldposition=joints[i].position;
737 joints[i].blurred=findDistance(&joints[i].position,&joints[i].oldposition)*100;
738 if(joints[i].blurred<1)joints[i].blurred=1;
744 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
746 for(int i=0; i<num_joints; i++){
747 if(joints[i].hasparent){
748 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].blurred);
749 glVertex3f(joints[i].position.x,joints[i].position.y,joints[i].position.z);
750 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].parent->blurred);
751 glVertex3f(joints[i].parent->position.x,joints[i].parent->position.y,joints[i].parent->position.z);
752 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].parent->blurred);
753 glVertex3f(joints[i].parent->oldposition.x,joints[i].parent->oldposition.y,joints[i].parent->oldposition.z);
754 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].blurred);
755 glVertex3f(joints[i].oldposition.x,joints[i].oldposition.y,joints[i].oldposition.z);
758 for(int i=0; i<num_muscles; i++){
759 if(muscles[i].type==boneconnect){
760 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent2->blurred);
761 glVertex3f(muscles[i].parent1->position.x,muscles[i].parent1->position.y,muscles[i].parent1->position.z);
762 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent2->blurred);
763 glVertex3f(muscles[i].parent2->position.x,muscles[i].parent2->position.y,muscles[i].parent2->position.z);
764 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent2->blurred);
765 glVertex3f(muscles[i].parent2->oldposition.x,muscles[i].parent2->oldposition.y,muscles[i].parent2->oldposition.z);
766 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent1->blurred);
767 glVertex3f(muscles[i].parent1->oldposition.x,muscles[i].parent1->oldposition.y,muscles[i].parent1->oldposition.z);
773 for(int i=0; i<num_joints; i++){
774 if(joints[i].hasparent){
775 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].blurred);
776 glVertex3f(joints[i].position.x,joints[i].position.y,joints[i].position.z);
777 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].parent->blurred);
778 glVertex3f(joints[i].parent->position.x,joints[i].parent->position.y,joints[i].parent->position.z);
781 /*for(int i=0; i<num_joints; i++){
782 if(joints[i].hasparent){
783 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],1);
784 glVertex3f(joints[i].position.x,joints[i].position.y,joints[i].position.z);
785 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],1);
786 glVertex3f(joints[i].position.x+forward.x,joints[i].position.y+forward.y,joints[i].position.z+forward.z);
789 for(int i=0; i<num_muscles; i++){
790 if(muscles[i].type==boneconnect){
791 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent1->blurred);
792 glVertex3f(muscles[i].parent1->position.x,muscles[i].parent1->position.y,muscles[i].parent1->position.z);
793 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent2->blurred);
794 glVertex3f(muscles[i].parent2->position.x,muscles[i].parent2->position.y,muscles[i].parent2->position.z);
799 for(int i=0; i<num_muscles; i++){
800 if(muscles[i].type!=boneconnect){
801 glVertex3f(muscles[i].parent1->position.x,muscles[i].parent1->position.y,muscles[i].parent1->position.z);
802 glVertex3f(muscles[i].parent2->position.x,muscles[i].parent2->position.y,muscles[i].parent2->position.z);
810 for(int i=0; i<num_joints; i++){
811 if(i!=selected)glColor4f(0,0,.5,1);
812 if(i==selected)glColor4f(1,1,0,1);
813 if(joints[i].locked&&i!=selected)glColor4f(1,0,0,1);
814 glVertex3f(joints[i].position.x,joints[i].position.y,joints[i].position.z);
819 //Set old position to current position
821 for(int i=0; i<num_joints; i++){
822 joints[i].oldposition=joints[i].position;
827 void Skeleton::AddJoint(float x, float y, float z, int which)
829 if(num_joints<max_joints-1){
830 joints[num_joints].velocity=0;
831 joints[num_joints].position.x=x;
832 joints[num_joints].position.y=y;
833 joints[num_joints].position.z=z;
834 joints[num_joints].mass=1;
835 joints[num_joints].locked=0;
837 /*if(which>=num_joints||which<0)*/joints[num_joints].hasparent=0;
838 /*if(which<num_joints&&which>=0){
839 joints[num_joints].parent=&joints[which];
840 joints[num_joints].hasparent=1;
841 joints[num_joints].length=findDistance(joints[num_joints].position,joints[num_joints].parent->position);
844 if(which<num_joints&&which>=0)AddMuscle(num_joints-1,which,0,10,boneconnect);
848 void Skeleton::DeleteJoint(int whichjoint)
850 if(whichjoint<num_joints&&whichjoint>=0){
851 joints[whichjoint].velocity=joints[num_joints-1].velocity;
852 joints[whichjoint].position=joints[num_joints-1].position;
853 joints[whichjoint].oldposition=joints[num_joints-1].oldposition;
854 joints[whichjoint].hasparent=joints[num_joints-1].hasparent;
855 joints[whichjoint].parent=joints[num_joints-1].parent;
856 joints[whichjoint].length=joints[num_joints-1].length;
857 joints[whichjoint].locked=joints[num_joints-1].locked;
858 joints[whichjoint].modelnum=joints[num_joints-1].modelnum;
859 joints[whichjoint].visible=joints[num_joints-1].visible;
861 for(int i=0;i<num_muscles;i++){
862 while(muscles[i].parent1==&joints[whichjoint]&&i<num_muscles)DeleteMuscle(i);
863 while(muscles[i].parent2==&joints[whichjoint]&&i<num_muscles)DeleteMuscle(i);
865 for(int i=0;i<num_muscles;i++){
866 while(muscles[i].parent1==&joints[num_joints-1]&&i<num_muscles)muscles[i].parent1=&joints[whichjoint];
867 while(muscles[i].parent2==&joints[num_joints-1]&&i<num_muscles)muscles[i].parent2=&joints[whichjoint];
869 for(int i=0;i<num_joints;i++){
870 if(joints[i].parent==&joints[whichjoint])joints[i].hasparent=0;
872 for(int i=0;i<num_joints;i++){
873 if(joints[i].parent==&joints[num_joints-1])joints[i].parent=&joints[whichjoint];
880 void Skeleton::DeleteMuscle(int whichmuscle)
882 if(whichmuscle<num_muscles){
883 muscles[whichmuscle].minlength=muscles[num_muscles-1].minlength;
884 muscles[whichmuscle].maxlength=muscles[num_muscles-1].maxlength;
885 muscles[whichmuscle].strength=muscles[num_muscles-1].strength;
886 muscles[whichmuscle].parent1=muscles[num_muscles-1].parent1;
887 muscles[whichmuscle].parent2=muscles[num_muscles-1].parent2;
888 muscles[whichmuscle].length=muscles[num_muscles-1].length;
889 muscles[whichmuscle].visible=muscles[num_muscles-1].visible;
890 muscles[whichmuscle].type=muscles[num_muscles-1].type;
891 muscles[whichmuscle].targetlength=muscles[num_muscles-1].targetlength;
897 void Skeleton::SetJoint(float x, float y, float z, int which, int whichjoint)
899 if(whichjoint<num_joints){
900 joints[whichjoint].velocity=0;
901 joints[whichjoint].position.x=x;
902 joints[whichjoint].position.y=y;
903 joints[whichjoint].position.z=z;
905 if(which>=num_joints||which<0)joints[whichjoint].hasparent=0;
906 if(which<num_joints&&which>=0){
907 joints[whichjoint].parent=&joints[which];
908 joints[whichjoint].hasparent=1;
909 joints[whichjoint].length=findDistance(&joints[whichjoint].position,&joints[whichjoint].parent->position);
914 void Skeleton::AddMuscle(int attach1,int attach2,float minlength,float maxlength,int type)
916 if(num_muscles<max_muscles-1&&attach1<num_joints&&attach1>=0&&attach2<num_joints&&attach2>=0&&attach1!=attach2){
917 muscles[num_muscles].parent1=&joints[attach1];
918 muscles[num_muscles].parent2=&joints[attach2];
919 muscles[num_muscles].length=findDistance(&muscles[num_muscles].parent1->position,&muscles[num_muscles].parent2->position);
920 muscles[num_muscles].targetlength=findDistance(&muscles[num_muscles].parent1->position,&muscles[num_muscles].parent2->position);
921 muscles[num_muscles].strength=.7;
922 muscles[num_muscles].type=type;
923 muscles[num_muscles].minlength=minlength;
924 muscles[num_muscles].maxlength=maxlength;
930 void Skeleton::MusclesSet()
932 for(int i=0;i<num_muscles;i++){
933 muscles[i].length=findDistance(&muscles[i].parent1->position,&muscles[i].parent2->position);
937 void Skeleton::DoBalance()
940 newpoint=joints[0].position;
941 newpoint.x=(joints[2].position.x+joints[4].position.x)/2;
942 newpoint.z=(joints[2].position.z+joints[4].position.z)/2;
943 joints[0].velocity=joints[0].velocity+(newpoint-joints[0].position);
944 //Move child point to within certain distance of parent point
945 joints[0].position=newpoint;
950 void Skeleton::FindRotationMuscle(int which, int animation)
952 static XYZ temppoint1,temppoint2,tempforward;
953 static float distance;
955 temppoint1=muscles[which].parent1->position;
956 temppoint2=muscles[which].parent2->position;
957 distance=sqrt((temppoint1.x-temppoint2.x)*(temppoint1.x-temppoint2.x)+(temppoint1.y-temppoint2.y)*(temppoint1.y-temppoint2.y)+(temppoint1.z-temppoint2.z)*(temppoint1.z-temppoint2.z));
958 if((temppoint1.y-temppoint2.y)<=distance)muscles[which].rotate2=asin((temppoint1.y-temppoint2.y)/distance);
959 if((temppoint1.y-temppoint2.y)>distance)muscles[which].rotate2=asin(1.f);
960 muscles[which].rotate2*=360/6.28;
963 distance=sqrt((temppoint1.x-temppoint2.x)*(temppoint1.x-temppoint2.x)+(temppoint1.y-temppoint2.y)*(temppoint1.y-temppoint2.y)+(temppoint1.z-temppoint2.z)*(temppoint1.z-temppoint2.z));
964 if((temppoint1.z-temppoint2.z)<=distance)muscles[which].rotate1=acos((temppoint1.z-temppoint2.z)/distance);
965 if((temppoint1.z-temppoint2.z)>distance)muscles[which].rotate1=acos(1.f);
966 muscles[which].rotate1*=360/6.28;
967 if(temppoint1.x>temppoint2.x)muscles[which].rotate1=360-muscles[which].rotate1;
968 if(!isnormal(muscles[which].rotate1))muscles[which].rotate1=0;
969 if(!isnormal(muscles[which].rotate2))muscles[which].rotate2=0;
971 if(muscles[which].parent1->label==head)tempforward=specialforward[0];
972 else if(muscles[which].parent1->label==rightshoulder||muscles[which].parent1->label==rightelbow||muscles[which].parent1->label==rightwrist||muscles[which].parent1->label==righthand)tempforward=specialforward[1];
973 else if(muscles[which].parent1->label==leftshoulder||muscles[which].parent1->label==leftelbow||muscles[which].parent1->label==leftwrist||muscles[which].parent1->label==lefthand)tempforward=specialforward[2];
974 else if(muscles[which].parent1->label==righthip||muscles[which].parent1->label==rightknee||muscles[which].parent1->label==rightankle||muscles[which].parent1->label==rightfoot)tempforward=specialforward[3];
975 else if(muscles[which].parent1->label==lefthip||muscles[which].parent1->label==leftknee||muscles[which].parent1->label==leftankle||muscles[which].parent1->label==leftfoot)tempforward=specialforward[4];
976 else if(!muscles[which].parent1->lower)tempforward=forward;
977 else if(muscles[which].parent1->lower)tempforward=lowforward;
979 if(animation==hanganim){
980 if(muscles[which].parent1->label==righthand||muscles[which].parent2->label==righthand){
984 if(muscles[which].parent1->label==lefthand||muscles[which].parent2->label==lefthand){
991 if(muscles[which].parent1->label==rightfoot||muscles[which].parent2->label==rightfoot){
994 if(muscles[which].parent1->label==leftfoot||muscles[which].parent2->label==leftfoot){
1000 tempforward=DoRotation(tempforward,0,muscles[which].rotate1-90,0);
1001 tempforward=DoRotation(tempforward,0,0,muscles[which].rotate2-90);
1003 tempforward/=sqrt(tempforward.x*tempforward.x+tempforward.y*tempforward.y+tempforward.z*tempforward.z);
1004 if(tempforward.z<=1&&tempforward.z>=-1)muscles[which].rotate3=acos(0-tempforward.z);
1005 else muscles[which].rotate3=acos(-1.f);
1006 muscles[which].rotate3*=360/6.28;
1007 if(0>tempforward.x)muscles[which].rotate3=360-muscles[which].rotate3;
1008 if(!isnormal(muscles[which].rotate3))muscles[which].rotate3=0;
1011 void Animation::Load(char *filename, int aheight, int aattack)
1015 static XYZ startoffset,endoffset;
1020 LOG(std::string("Loading animation...") + filename);
1027 if(visibleloading)pgame->LoadingScreen();
1029 tfile=fopen( filename, "rb" );
1031 funpackf(tfile, "Bi Bi", &numframes, &joints);
1033 for(i = 0; i < joints; i++){
1034 if(position[i])dealloc2(position[i]);
1035 if(twist[i])dealloc2(twist[i]);
1036 if(twist2[i])dealloc2(twist2[i]);
1037 if(onground[i])dealloc2(onground[i]);
1040 if(position)dealloc2(position);
1041 if(twist)dealloc2(twist);
1042 if(twist2)dealloc2(twist2);
1043 if(speed)dealloc2(speed);
1044 if(onground)dealloc2(onground);
1045 if(forward)dealloc2(forward);
1046 if(weapontarget)dealloc2(weapontarget);
1047 if(label)dealloc2(label);*/
1049 position=(XYZ**)malloc(sizeof(XYZ*)*joints);
1050 for(i = 0; i < joints; i++)
1051 position[i] = (XYZ*)malloc(sizeof(XYZ)*numframes);
1053 twist=(float**)malloc(sizeof(float*)*joints);
1054 for(i = 0; i < joints; i++)
1055 twist[i] = (float*)malloc(sizeof(float)*numframes);
1057 twist2=(float**)malloc(sizeof(float*)*joints);
1058 for(i = 0; i < joints; i++)
1059 twist2[i] = (float*)malloc(sizeof(float)*numframes);
1061 speed = (float*)malloc(sizeof(float)*numframes);
1063 onground=(bool**)malloc(sizeof(bool*)*joints);
1064 for(i = 0; i < joints; i++)
1065 onground[i] =(bool*)malloc(sizeof(bool)*numframes);
1067 forward = (XYZ*)malloc(sizeof(XYZ)*numframes);
1068 weapontarget = (XYZ*)malloc(sizeof(XYZ)*numframes);
1069 label = (int*)malloc(sizeof(int)*numframes);
1071 /*position = new XYZ[joints][numframes];
1072 twist = new float[joints][numframes];
1073 twist2 = new float[joints][numframes];
1074 speed = new float[numframes];
1075 onground = new bool[joints][numframes];
1076 forward = new XYZ[numframes];
1077 label = new int[numframes];*/
1079 for(i=0;i<numframes;i++){
1080 for(j=0;j<joints;j++){
1081 funpackf(tfile, "Bf Bf Bf", &position[j][i].x,&position[j][i].y,&position[j][i].z);
1083 for(j=0;j<joints;j++){
1084 funpackf(tfile, "Bf", &twist[j][i]);
1086 for(j=0;j<joints;j++){
1088 funpackf(tfile, "Bb", &uch);
1089 onground[j][i] = (uch != 0);
1091 funpackf(tfile, "Bf", &speed[i]);
1093 for(i=0;i<numframes;i++){
1094 for(j=0;j<joints;j++){
1095 funpackf(tfile, "Bf", &twist2[j][i]);
1098 for(i=0;i<numframes;i++){
1099 funpackf(tfile, "Bf", &label[i]);
1101 funpackf(tfile, "Bi", &weapontargetnum);
1102 for(i=0;i<numframes;i++){
1103 funpackf(tfile, "Bf Bf Bf", &weapontarget[i].x,&weapontarget[i].y,&weapontarget[i].z);
1112 for(j=0;j<joints;j++){
1113 if(position[j][0].y<1)
1114 startoffset+=position[j][0];
1115 if(position[j][numframes-1].y<1)
1116 endoffset+=position[j][numframes-1];
1119 startoffset/=howmany;
1126 void Animation::Move(XYZ how)
1128 static int i,j,joints;
1129 for(i=0;i<numframes;i++){
1130 for(j=0;j<joints;j++){
1136 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)
1138 static GLfloat M[16];
1139 static int parentID;
1142 static int i,j,tempmuscle;
1154 for(i=0;i<num_models;i++){
1155 if(i==0)model[i].loadnotex(modelfilename);
1156 if(i==1)model[i].loadnotex(model2filename);
1157 if(i==2)model[i].loadnotex(model3filename);
1158 if(i==3)model[i].loadnotex(model4filename);
1159 if(i==4)model[i].loadnotex(model5filename);
1160 if(i==5)model[i].loadnotex(model6filename);
1161 if(i==6)model[i].loadnotex(model7filename);
1162 model[i].Rotate(180,0,0);
1163 model[i].Scale(.04,.04,.04);
1164 model[i].CalculateNormals(0);
1167 drawmodel.load(modelfilename,0);
1168 drawmodel.Rotate(180,0,0);
1169 drawmodel.Scale(.04,.04,.04);
1170 drawmodel.FlipTexCoords();
1171 if(tutoriallevel==1&&id!=0)drawmodel.UniformTexCoords();
1172 if(tutoriallevel==1&&id!=0)drawmodel.ScaleTexCoords(0.1);
1173 drawmodel.CalculateNormals(0);
1175 modellow.loadnotex(modellowfilename);
1176 modellow.Rotate(180,0,0);
1177 modellow.Scale(.04,.04,.04);
1178 modellow.CalculateNormals(0);
1180 drawmodellow.load(modellowfilename,0);
1181 drawmodellow.Rotate(180,0,0);
1182 drawmodellow.Scale(.04,.04,.04);
1183 drawmodellow.FlipTexCoords();
1184 if(tutoriallevel==1&&id!=0)drawmodellow.UniformTexCoords();
1185 if(tutoriallevel==1&&id!=0)drawmodellow.ScaleTexCoords(0.1);
1186 drawmodellow.CalculateNormals(0);
1189 modelclothes.loadnotex(modelclothesfilename);
1190 modelclothes.Rotate(180,0,0);
1191 modelclothes.Scale(.041,.04,.041);
1192 modelclothes.CalculateNormals(0);
1194 drawmodelclothes.load(modelclothesfilename,0);
1195 drawmodelclothes.Rotate(180,0,0);
1196 drawmodelclothes.Scale(.04,.04,.04);
1197 drawmodelclothes.FlipTexCoords();
1198 drawmodelclothes.CalculateNormals(0);
1201 tfile=fopen( filename, "rb" );
1203 funpackf(tfile, "Bi", &num_joints);
1204 //joints.resize(num_joints);
1205 if(joints) delete [] joints; //dealloc2(joints);
1206 joints=(Joint*)new Joint[num_joints]; //malloc(sizeof(Joint)*num_joints);
1208 for(i=0;i<num_joints;i++){
1209 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);
1210 funpackf(tfile, "Bb Bb", &joints[i].hasparent,&joints[i].locked);
1211 funpackf(tfile, "Bi", &joints[i].modelnum);
1212 funpackf(tfile, "Bb Bb", &joints[i].visible,&joints[i].sametwist);
1213 funpackf(tfile, "Bi Bi", &joints[i].label,&joints[i].hasgun);
1214 funpackf(tfile, "Bb", &joints[i].lower);
1215 funpackf(tfile, "Bi", &parentID);
1216 if(joints[i].hasparent)joints[i].parent=&joints[parentID];
1217 joints[i].velocity=0;
1218 joints[i].oldposition=joints[i].position;
1220 tempmuscle=num_muscles;
1221 funpackf(tfile, "Bi", &num_muscles);
1223 if(muscles) delete [] muscles; //dealloc2(muscles);
1224 muscles=(Muscle*)new Muscle[num_muscles]; //malloc(sizeof(Muscle)*num_muscles);
1226 for(i=0;i<num_muscles;i++){
1227 tempmuscle=muscles[i].numvertices;
1228 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);
1229 //muscles[i].vertices.clear();
1230 //muscles[i].vertices.resize(muscles[i].numvertices);
1231 //if(muscles[i].vertices)dealloc2(muscles[i].vertices);
1232 muscles[i].vertices=(int*)malloc(sizeof(int)*muscles[i].numvertices);
1235 for(j=0;j<muscles[i].numvertices-edit;j++){
1236 funpackf(tfile, "Bi", &muscles[i].vertices[j+edit]);
1237 if(muscles[i].vertices[j+edit]>=model[0].vertexNum){
1238 muscles[i].numvertices--;
1242 funpackf(tfile, "Bb Bi", &muscles[i].visible, &parentID);
1243 muscles[i].parent1=&joints[parentID];
1244 funpackf(tfile, "Bi", &parentID);
1245 muscles[i].parent2=&joints[parentID];
1248 funpackf(tfile, "Bi", &forwardjoints[j]);
1251 funpackf(tfile, "Bi", &lowforwardjoints[j]);
1253 for(j=0;j<num_muscles;j++){
1254 for(i=0;i<muscles[j].numvertices;i++){
1255 for(int k=0;k<num_models;k++){
1256 if(muscles[j].numvertices&&muscles[j].vertices[i]<model[k].vertexNum)model[k].owner[muscles[j].vertices[i]]=j;
1261 for(i=0;i<num_joints;i++){
1262 joints[i].startpos=joints[i].position;
1264 for(i=0;i<num_muscles;i++){
1265 FindRotationMuscle(i,-1);
1267 for(int k=0;k<num_models;k++){
1268 for(i=0;i<model[k].vertexNum;i++){
1269 model[k].vertex[i]=model[k].vertex[i]-(muscles[model[k].owner[i]].parent1->position+muscles[model[k].owner[i]].parent2->position)/2;
1270 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
1273 glRotatef(muscles[model[k].owner[i]].rotate3,0,1,0);
1274 glRotatef(muscles[model[k].owner[i]].rotate2-90,0,0,1);
1275 glRotatef(muscles[model[k].owner[i]].rotate1-90,0,1,0);
1276 glTranslatef(model[k].vertex[i].x,model[k].vertex[i].y,model[k].vertex[i].z);
1277 glGetFloatv(GL_MODELVIEW_MATRIX,M);
1278 model[k].vertex[i].x=M[12]*1;
1279 model[k].vertex[i].y=M[13]*1;
1280 model[k].vertex[i].z=M[14]*1;
1283 model[k].CalculateNormals(0);
1288 tfile=fopen( lowfilename, "rb" );
1290 lSize=sizeof(num_joints);
1291 fseek ( tfile, lSize, SEEK_CUR);
1292 //joints = new Joint[num_joints];
1293 //jointlabels = new int[num_joints];
1294 for(i=0;i<num_joints;i++){
1296 fseek ( tfile, lSize, SEEK_CUR);
1297 lSize=sizeof(float);
1298 fseek ( tfile, lSize, SEEK_CUR);
1299 lSize=sizeof(float);
1300 fseek ( tfile, lSize, SEEK_CUR);
1301 lSize=1;//sizeof(bool);
1302 fseek ( tfile, lSize, SEEK_CUR);
1303 lSize=1;//sizeof(bool);
1304 fseek ( tfile, lSize, SEEK_CUR);
1306 fseek ( tfile, lSize, SEEK_CUR);
1307 lSize=1;//sizeof(bool);
1308 fseek ( tfile, lSize, SEEK_CUR);
1309 lSize=1;//sizeof(bool);
1310 fseek ( tfile, lSize, SEEK_CUR);
1312 fseek ( tfile, lSize, SEEK_CUR);
1314 fseek ( tfile, lSize, SEEK_CUR);
1315 lSize=1;//sizeof(bool);
1316 fseek ( tfile, lSize, SEEK_CUR);
1318 fseek ( tfile, lSize, SEEK_CUR);
1319 if(joints[i].hasparent)joints[i].parent=&joints[parentID];
1320 joints[i].velocity=0;
1321 joints[i].oldposition=joints[i].position;
1323 funpackf(tfile, "Bi", &num_muscles);
1324 //muscles = new Muscle[num_muscles];
1325 for(i=0;i<num_muscles;i++){
1326 lSize=sizeof(float);
1327 fseek ( tfile, lSize, SEEK_CUR);
1328 lSize=sizeof(float);
1329 fseek ( tfile, lSize, SEEK_CUR);
1330 lSize=sizeof(float);
1331 fseek ( tfile, lSize, SEEK_CUR);
1332 lSize=sizeof(float);
1333 fseek ( tfile, lSize, SEEK_CUR);
1334 lSize=sizeof(float);
1335 fseek ( tfile, lSize, SEEK_CUR);
1337 fseek ( tfile, lSize, SEEK_CUR);
1338 tempmuscle=muscles[i].numverticeslow;
1339 funpackf(tfile, "Bi", &muscles[i].numverticeslow);
1340 if(muscles[i].numverticeslow){
1341 //muscles[i].verticeslow.clear();
1342 //muscles[i].verticeslow.resize(muscles[i].numverticeslow);
1343 //if(muscles[i].verticeslow)dealloc2(muscles[i].verticeslow);
1344 muscles[i].verticeslow=(int*)malloc(sizeof(int)*muscles[i].numverticeslow);
1346 for(j=0;j<muscles[i].numverticeslow-edit;j++){
1347 funpackf(tfile, "Bi", &muscles[i].verticeslow[j+edit]);
1348 if(muscles[i].verticeslow[j+edit]>=modellow.vertexNum){
1349 muscles[i].numverticeslow--;
1356 lSize=1;//sizeof(bool);
1357 fseek ( tfile, lSize, SEEK_CUR);
1359 fseek ( tfile, lSize, SEEK_CUR);
1360 fseek ( tfile, lSize, SEEK_CUR);
1363 for(j=0;j<num_muscles;j++){
1364 for(i=0;i<muscles[j].numverticeslow;i++){
1365 if(muscles[j].numverticeslow&&muscles[j].verticeslow[i]<modellow.vertexNum)modellow.owner[muscles[j].verticeslow[i]]=j;
1369 for(i=0;i<num_joints;i++){
1370 joints[i].startpos=joints[i].position;
1372 for(i=0;i<num_muscles;i++){
1373 FindRotationMuscle(i,-1);
1375 for(i=0;i<modellow.vertexNum;i++){
1376 modellow.vertex[i]=modellow.vertex[i]-(muscles[modellow.owner[i]].parent1->position+muscles[modellow.owner[i]].parent2->position)/2;
1377 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
1380 glRotatef(muscles[modellow.owner[i]].rotate3,0,1,0);
1381 glRotatef(muscles[modellow.owner[i]].rotate2-90,0,0,1);
1382 glRotatef(muscles[modellow.owner[i]].rotate1-90,0,1,0);
1383 glTranslatef(modellow.vertex[i].x,modellow.vertex[i].y,modellow.vertex[i].z);
1384 glGetFloatv(GL_MODELVIEW_MATRIX,M);
1385 modellow.vertex[i].x=M[12];
1386 modellow.vertex[i].y=M[13];
1387 modellow.vertex[i].z=M[14];
1390 modellow.CalculateNormals(0);
1394 tfile=fopen( clothesfilename, "rb" );
1395 lSize=sizeof(num_joints);
1396 fseek ( tfile, lSize, SEEK_CUR);
1397 //joints = new Joint[num_joints];
1398 //jointlabels = new int[num_joints];
1399 for(i=0;i<num_joints;i++){
1401 fseek ( tfile, lSize, SEEK_CUR);
1402 lSize=sizeof(float);
1403 fseek ( tfile, lSize, SEEK_CUR);
1404 lSize=sizeof(float);
1405 fseek ( tfile, lSize, SEEK_CUR);
1406 lSize=1;//sizeof(bool);
1407 fseek ( tfile, lSize, SEEK_CUR);
1408 lSize=1;//sizeof(bool);
1409 fseek ( tfile, lSize, SEEK_CUR);
1411 fseek ( tfile, lSize, SEEK_CUR);
1412 lSize=1;//sizeof(bool);
1413 fseek ( tfile, lSize, SEEK_CUR);
1414 lSize=1;//sizeof(bool);
1415 fseek ( tfile, lSize, SEEK_CUR);
1417 fseek ( tfile, lSize, SEEK_CUR);
1419 fseek ( tfile, lSize, SEEK_CUR);
1420 lSize=1;//sizeof(bool);
1421 fseek ( tfile, lSize, SEEK_CUR);
1423 fseek ( tfile, lSize, SEEK_CUR);
1424 if(joints[i].hasparent)joints[i].parent=&joints[parentID];
1425 joints[i].velocity=0;
1426 joints[i].oldposition=joints[i].position;
1428 funpackf(tfile, "Bi", &num_muscles);
1429 //muscles = new Muscle[num_muscles];
1430 for(i=0;i<num_muscles;i++){
1431 lSize=sizeof(float);
1432 fseek ( tfile, lSize, SEEK_CUR);
1433 lSize=sizeof(float);
1434 fseek ( tfile, lSize, SEEK_CUR);
1435 lSize=sizeof(float);
1436 fseek ( tfile, lSize, SEEK_CUR);
1437 lSize=sizeof(float);
1438 fseek ( tfile, lSize, SEEK_CUR);
1439 lSize=sizeof(float);
1440 fseek ( tfile, lSize, SEEK_CUR);
1442 fseek ( tfile, lSize, SEEK_CUR);
1443 tempmuscle=muscles[i].numverticesclothes;
1444 funpackf(tfile, "Bi", &muscles[i].numverticesclothes);
1445 if(muscles[i].numverticesclothes){
1446 //muscles[i].verticesclothes.clear();
1447 //muscles[i].verticesclothes.resize(muscles[i].numverticesclothes);
1448 //if(muscles[i].verticesclothes)dealloc2(muscles[i].verticesclothes);
1449 muscles[i].verticesclothes=(int*)malloc(sizeof(int)*muscles[i].numverticesclothes);
1451 for(j=0;j<muscles[i].numverticesclothes-edit;j++){
1452 funpackf(tfile, "Bi", &muscles[i].verticesclothes[j+edit]);
1453 if(muscles[i].verticesclothes[j+edit]>=modelclothes.vertexNum){
1454 muscles[i].numverticesclothes--;
1459 lSize=1;//sizeof(bool);
1460 fseek ( tfile, lSize, SEEK_CUR);
1462 fseek ( tfile, lSize, SEEK_CUR);
1463 fseek ( tfile, lSize, SEEK_CUR);
1466 for(j=0;j<num_muscles;j++){
1467 for(i=0;i<muscles[j].numverticesclothes;i++){
1468 if(muscles[j].numverticesclothes&&muscles[j].verticesclothes[i]<modelclothes.vertexNum)modelclothes.owner[muscles[j].verticesclothes[i]]=j;
1472 for(i=0;i<num_joints;i++){
1473 joints[i].startpos=joints[i].position;
1475 for(i=0;i<num_muscles;i++){
1476 FindRotationMuscle(i,-1);
1478 for(i=0;i<modelclothes.vertexNum;i++){
1479 modelclothes.vertex[i]=modelclothes.vertex[i]-(muscles[modelclothes.owner[i]].parent1->position+muscles[modelclothes.owner[i]].parent2->position)/2;
1480 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
1483 glRotatef(muscles[modelclothes.owner[i]].rotate3,0,1,0);
1484 glRotatef(muscles[modelclothes.owner[i]].rotate2-90,0,0,1);
1485 glRotatef(muscles[modelclothes.owner[i]].rotate1-90,0,1,0);
1486 glTranslatef(modelclothes.vertex[i].x,modelclothes.vertex[i].y,modelclothes.vertex[i].z);
1487 glGetFloatv(GL_MODELVIEW_MATRIX,M);
1488 modelclothes.vertex[i].x=M[12];
1489 modelclothes.vertex[i].y=M[13];
1490 modelclothes.vertex[i].z=M[14];
1493 modelclothes.CalculateNormals(0);
1497 for(i=0;i<num_joints;i++){
1498 for(j=0;j<num_joints;j++){
1499 if(joints[i].label==j)jointlabels[j]=i;
1506 Animation::Animation()
1512 weapontargetnum = 0;
1524 Animation::~Animation()
1529 void Animation::deallocate()
1535 for(i = 0; i < joints; i++)
1536 dealloc2(position[i]);
1544 for(i = 0; i < joints; i++)
1553 for(i = 0; i < joints; i++)
1554 dealloc2(twist2[i]);
1562 for(i = 0; i < joints; i++)
1563 dealloc2(onground[i]);
1569 if(speed)dealloc2(speed);
1572 if(forward)dealloc2(forward);
1575 if(weapontarget)dealloc2(weapontarget);
1578 if(label)dealloc2(label);
1584 Skeleton::Skeleton()
1592 memset(forwardjoints, 0, sizeof(forwardjoints));
1597 memset(lowforwardjoints, 0, sizeof(lowforwardjoints));
1600 // XYZ specialforward[5];
1601 memset(jointlabels, 0, sizeof(jointlabels));
1605 // Model modelclothes;
1609 // Model drawmodellow;
1610 // Model drawmodelclothes;
1615 memset(skinText, 0, sizeof(skinText));
1632 Skeleton::~Skeleton()
1655 numverticesclothes = 0;
1664 rotate1 = 0,rotate2 = 0,rotate3 = 0;
1665 lastrotate1 = 0,lastrotate2 = 0,lastrotate3 = 0;
1666 oldrotate1 = 0,oldrotate2 = 0,oldrotate3 = 0;
1667 newrotate1 = 0,newrotate2 = 0,newrotate3 = 0;
1675 dealloc2(verticeslow);
1676 dealloc2(verticesclothes);
1679 Animation & Animation::operator = (const Animation & ani)
1683 bool allocate = true;
1685 allocate = ((ani.numframes != numframes) || (ani.joints != joints));
1687 if (allocate) deallocate();
1689 numframes = ani.numframes;
1690 height = ani.height;
1691 attack = ani.attack;
1692 joints = ani.joints;
1693 weapontargetnum = ani.weapontargetnum;
1695 if (allocate) position=(XYZ**)malloc(sizeof(XYZ*)*ani.joints);
1696 for(i = 0; i < ani.joints; i++)
1698 if (allocate) position[i] = (XYZ*)malloc(sizeof(XYZ)*ani.numframes);
1699 memcpy(position[i], ani.position[i], sizeof(XYZ)*ani.numframes);
1702 if (allocate) twist=(float**)malloc(sizeof(float*)*ani.joints);
1703 for(i = 0; i < ani.joints; i++)
1705 if (allocate) twist[i] = (float*)malloc(sizeof(float)*ani.numframes);
1706 memcpy(twist[i], ani.twist[i], sizeof(float)*ani.numframes);
1709 if (allocate) twist2=(float**)malloc(sizeof(float*)*ani.joints);
1710 for(i = 0; i < ani.joints; i++)
1712 if (allocate) twist2[i] = (float*)malloc(sizeof(float)*ani.numframes);
1713 memcpy(twist2[i], ani.twist2[i], sizeof(float)*ani.numframes);
1716 if (allocate) speed = (float*)malloc(sizeof(float)*ani.numframes);
1717 memcpy(speed, ani.speed, sizeof(float)*ani.numframes);
1719 if (allocate) onground=(bool**)malloc(sizeof(bool*)*ani.joints);
1720 for(i = 0; i < ani.joints; i++)
1722 if (allocate) onground[i] =(bool*)malloc(sizeof(bool)*ani.numframes);
1723 memcpy(onground[i], ani.onground[i], sizeof(bool)*ani.numframes);
1726 if (allocate) forward = (XYZ*)malloc(sizeof(XYZ)*ani.numframes);
1727 memcpy(forward, ani.forward, sizeof(XYZ)*ani.numframes);
1729 if (allocate) weapontarget = (XYZ*)malloc(sizeof(XYZ)*ani.numframes);
1730 memcpy(weapontarget, ani.weapontarget, sizeof(XYZ)*ani.numframes);
1732 if (allocate) label = (int*)malloc(sizeof(int)*ani.numframes);
1733 memcpy(label, ani.label, sizeof(int)*ani.numframes);