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"
26 #include "Animation.h"
28 extern float multiplier;
30 extern Skeleton testskeleton;
31 extern Terrain terrain;
32 extern int channels[100];
33 extern Objects objects;
34 extern int environment;
35 extern float terraindetail;
36 extern float camerashake;
39 extern XYZ envsound[30];
40 extern float envsoundvol[30];
41 extern int numenvsounds;
42 extern float envsoundlife[30];
43 extern int tutoriallevel;
45 extern int whichjointstartarray[26];
46 extern int whichjointendarray[26];
49 extern bool visibleloading;
50 extern "C" void PlaySoundEx(int channel, OPENAL_SAMPLE *sptr, OPENAL_DSPUNIT *dsp, signed char startpaused);
52 void dealloc2(void* param){
57 void Muscle::DoConstraint(bool spinny)
61 static XYZ newpoint1,newpoint2;
63 static float oldlength;
64 static float relaxlength;
68 if(type!=boneconnect)relaxlength=findDistance(&parent1->position,&parent2->position);
70 if(type==boneconnect)strength=1;
71 if(type==constraint)strength=0;
73 if(strength<0)strength=0;
74 if(strength>1)strength=1;
76 length-=(length-relaxlength)*(1-strength)*multiplier*10000;
77 length-=(length-targetlength)*(strength)*multiplier*10000;
78 if(strength==0)length=relaxlength;
80 if((relaxlength-length>0&&relaxlength-oldlength<0)||(relaxlength-length<0&&relaxlength-oldlength>0))length=relaxlength;
83 if(length<minlength)length=minlength;
84 if(length>maxlength)length=maxlength;
88 if(length<minlength*.6)length=minlength*.6;
89 if(length>maxlength*1.4)length=maxlength*1.4;
92 if(length==relaxlength)return;
95 midp=(parent1->position*parent1->mass+parent2->position*parent2->mass)/(parent1->mass+parent2->mass);
96 //Find vector from midpoint to second vector
97 vel=parent2->position-midp;
98 //Change to unit vector
100 //Apply velocity change
101 newpoint1=midp-vel*length*(parent2->mass/(parent1->mass+parent2->mass));
102 newpoint2=midp+vel*length*(parent1->mass/(parent1->mass+parent2->mass));
104 parent1->velocity=parent1->velocity+(newpoint1-parent1->position)/multiplier/4;
105 parent2->velocity=parent2->velocity+(newpoint2-parent2->position)/multiplier/4;
109 parent1->velocity=parent1->velocity+(newpoint1-parent1->position);
110 parent2->velocity=parent2->velocity+(newpoint2-parent2->position);
112 //Move child point to within certain distance of parent point
113 parent1->position=newpoint1;
114 parent2->position=newpoint2;
117 void Skeleton::FindForwardsfirst()
119 //Find forward vectors
120 CrossProduct(joints[forwardjoints[1]].position-joints[forwardjoints[0]].position,joints[forwardjoints[2]].position-joints[forwardjoints[0]].position,&forward);
123 CrossProduct(joints[lowforwardjoints[1]].position-joints[lowforwardjoints[0]].position,joints[lowforwardjoints[2]].position-joints[lowforwardjoints[0]].position,&lowforward);
124 Normalise(&lowforward);
127 specialforward[0]=forward;
128 specialforward[1]=forward;
129 specialforward[2]=forward;
130 specialforward[3]=forward;
131 specialforward[4]=forward;
134 void Skeleton::FindForwards()
136 //Find forward vectors
137 CrossProduct(joints[forwardjoints[1]].position-joints[forwardjoints[0]].position,joints[forwardjoints[2]].position-joints[forwardjoints[0]].position,&forward);
140 CrossProduct(joints[lowforwardjoints[1]].position-joints[lowforwardjoints[0]].position,joints[lowforwardjoints[2]].position-joints[lowforwardjoints[0]].position,&lowforward);
141 Normalise(&lowforward);
144 specialforward[0]=forward;
146 specialforward[1]=joints[jointlabels[rightshoulder]].position+joints[jointlabels[rightwrist]].position;
147 specialforward[1]=joints[jointlabels[rightelbow]].position-specialforward[1]/2;
148 specialforward[1]+=forward*.4;
149 Normalise(&specialforward[1]);
150 specialforward[2]=joints[jointlabels[leftshoulder]].position+joints[jointlabels[leftwrist]].position;
151 specialforward[2]=joints[jointlabels[leftelbow]].position-specialforward[2]/2;
152 specialforward[2]+=forward*.4;
153 Normalise(&specialforward[2]);
155 specialforward[3]=joints[jointlabels[righthip]].position+joints[jointlabels[rightankle]].position;
156 specialforward[3]=specialforward[3]/2-joints[jointlabels[rightknee]].position;
157 specialforward[3]+=lowforward*.4;
158 Normalise(&specialforward[3]);
159 specialforward[4]=joints[jointlabels[lefthip]].position+joints[jointlabels[leftankle]].position;
160 specialforward[4]=specialforward[4]/2-joints[jointlabels[leftknee]].position;
161 specialforward[4]+=lowforward*.4;
162 Normalise(&specialforward[4]);
165 float Skeleton::DoConstraints(XYZ *coords,float *scale)
167 static float friction=1.5;
168 static float elasticity=.3;
169 static XYZ bounceness;
170 static XYZ oldpos[100];
171 static int numrepeats=3;
172 static float groundlevel=.15;
173 static float soundvolume;
174 static int i,j,k,l,m;
175 static XYZ temp,start,end;
176 static XYZ terrainnormal;
180 //static int whichjointstart,whichjointend;
181 static float distance;
182 static float frictionness;
183 static XYZ terrainlight;
184 static int whichpatchx;
185 static int whichpatchz;
188 static float tempmult;
189 static bool breaking;
195 freetime+=multiplier;
197 whichpatchx=coords->x/(terrain.size/subdivision*terrain.scale*terraindetail);
198 whichpatchz=coords->z/(terrain.size/subdivision*terrain.scale*terraindetail);
200 terrainlight=*coords;
201 objects.SphereCheckPossible(&terrainlight, 1);
203 for(i=0; i<num_joints; i++){
204 oldpos[i]=joints[i].position;
208 for(i=0; i<num_joints; i++){
209 //if(!isnormal(joints[i].velocity.x)||!isnormal(joints[i].velocity.y)||!isnormal(joints[i].velocity.z))joints[i].velocity=0;
210 joints[i].position=joints[i].position+joints[i].velocity*multiplier;
212 if(joints[i].label==head)groundlevel=.8;
213 if(joints[i].label==righthand||joints[i].label==rightwrist||joints[i].label==rightelbow)groundlevel=.2;
214 if(joints[i].label==lefthand||joints[i].label==leftwrist||joints[i].label==leftelbow)groundlevel=.2;
215 joints[i].position.y-=groundlevel;
216 //if(!joints[i].locked&&!broken)joints[i].velocity+=joints[i].velchange*multiplier*10*(500-longdead)/500;
217 joints[i].oldvelocity=joints[i].velocity;
220 //multiplier/=numrepeats;
221 for(j=0; j<numrepeats; j++){
222 if(!joints[jointlabels[rightknee]].locked&&!joints[jointlabels[righthip]].locked){
223 temp=joints[jointlabels[rightknee]].position-(joints[jointlabels[righthip]].position+joints[jointlabels[rightankle]].position)/2;
224 while(normaldotproduct(temp,lowforward)>-.1&&!sphere_line_intersection(&joints[jointlabels[righthip]].position,&joints[jointlabels[rightankle]].position,&joints[jointlabels[rightknee]].position,&r)){
225 joints[jointlabels[rightknee]].position-=lowforward*.05;
226 if(spinny)joints[jointlabels[rightknee]].velocity-=lowforward*.05/multiplier/4;
227 else joints[jointlabels[rightknee]].velocity-=lowforward*.05;
228 joints[jointlabels[rightankle]].position+=lowforward*.025;
229 if(spinny)joints[jointlabels[rightankle]].velocity+=lowforward*.025/multiplier/4;
230 else joints[jointlabels[rightankle]].velocity+=lowforward*.25;
231 joints[jointlabels[righthip]].position+=lowforward*.025;
232 if(spinny)joints[jointlabels[righthip]].velocity+=lowforward*.025/multiplier/4;
233 else joints[jointlabels[righthip]].velocity+=lowforward*.025;
234 temp=joints[jointlabels[rightknee]].position-(joints[jointlabels[righthip]].position+joints[jointlabels[rightankle]].position)/2;
237 if(!joints[jointlabels[leftknee]].locked&&!joints[jointlabels[righthip]].locked){
238 temp=joints[jointlabels[leftknee]].position-(joints[jointlabels[lefthip]].position+joints[jointlabels[leftankle]].position)/2;
239 while(normaldotproduct(temp,lowforward)>-.1&&!sphere_line_intersection(&joints[jointlabels[lefthip]].position,&joints[jointlabels[leftankle]].position,&joints[jointlabels[leftknee]].position,&r)){
240 joints[jointlabels[leftknee]].position-=lowforward*.05;
241 if(spinny)joints[jointlabels[leftknee]].velocity-=lowforward*.05/multiplier/4;
242 else joints[jointlabels[leftknee]].velocity-=lowforward*.05;
243 joints[jointlabels[leftankle]].position+=lowforward*.025;
244 if(spinny)joints[jointlabels[leftankle]].velocity+=lowforward*.025/multiplier/4;
245 else joints[jointlabels[leftankle]].velocity+=lowforward*.25;
246 joints[jointlabels[lefthip]].position+=lowforward*.025;
247 if(spinny)joints[jointlabels[lefthip]].velocity+=lowforward*.025/multiplier/4;
248 else joints[jointlabels[lefthip]].velocity+=lowforward*.025;
249 temp=joints[jointlabels[leftknee]].position-(joints[jointlabels[lefthip]].position+joints[jointlabels[leftankle]].position)/2;
253 if(terrain.patchobjectnum[whichpatchx][whichpatchz])
254 for(m=0;m<terrain.patchobjectnum[whichpatchx][whichpatchz];m++){
255 k=terrain.patchobjects[whichpatchx][whichpatchz][m];
256 if(k<objects.numobjects&&k>=0)
257 if(objects.possible[k]){
258 temp=joints[jointlabels[head]].position*(*scale)+*coords;
259 if(objects.model[k].SphereCheck(&temp, 0.06, &start, &objects.position[k], &objects.rotation[k])!=-1){
260 //temp=(joints[jointlabels[head]].position*(*scale)+*coords)-start;
262 //joints[jointlabels[head]].position=((temp*.2+start)-*coords)/(*scale);
263 joints[jointlabels[head]].position=(temp-*coords)/(*scale);
271 startheadpos=joints[jointlabels[head]].position;
273 headpos=joints[jointlabels[head]].position+(joints[jointlabels[head]].position-joints[jointlabels[neck]].position);
274 if(terrain.patchobjectnum[whichpatchx][whichpatchz])
275 for(m=0;m<terrain.patchobjectnum[whichpatchx][whichpatchz];m++){
276 k=terrain.patchobjects[whichpatchx][whichpatchz][m];
277 if(k<objects.numobjects&&k>=0)
278 if(objects.possible[k]){
279 friction=objects.friction[k];
280 start=joints[jointlabels[head]].position*(*scale)+*coords;
281 end=(headpos)*(*scale)+*coords;
282 whichhit=objects.model[k].LineCheckPossible(&start,&end,&temp,&objects.position[k],&objects.rotation[k]);
284 if(joints[jointlabels[head]].label==groin&&!joints[jointlabels[head]].locked&&joints[jointlabels[head]].delay<=0){
285 joints[jointlabels[head]].locked=1;
286 joints[jointlabels[head]].delay=1;
287 static float gLoc[3];
289 gLoc[0]=headpos.x*(*scale)+coords->x;
290 gLoc[1]=headpos.y*(*scale)+coords->y;
291 gLoc[2]=headpos.z*(*scale)+coords->z;
292 vel[0]=joints[jointlabels[head]].velocity.x;
293 vel[1]=joints[jointlabels[head]].velocity.y;
294 vel[2]=joints[jointlabels[head]].velocity.z;
295 PlaySoundEx( landsound1, samp[landsound1], NULL, true);
296 OPENAL_3D_SetAttributes(channels[landsound1], gLoc, vel);
297 OPENAL_SetVolume(channels[landsound1], 128);
298 OPENAL_SetPaused(channels[landsound1], false);
303 if(joints[jointlabels[head]].label==head&&!joints[jointlabels[head]].locked&&joints[jointlabels[head]].delay<=0){
304 joints[jointlabels[head]].locked=1;
305 joints[jointlabels[head]].delay=1;
306 static float gLoc[3];
308 gLoc[0]=headpos.x*(*scale)+coords->x;
309 gLoc[1]=headpos.y*(*scale)+coords->y;
310 gLoc[2]=headpos.z*(*scale)+coords->z;
311 vel[0]=joints[jointlabels[head]].velocity.x;
312 vel[1]=joints[jointlabels[head]].velocity.y;
313 vel[2]=joints[jointlabels[head]].velocity.z;
314 PlaySoundEx( landsound2, samp[landsound2], NULL, true);
315 OPENAL_3D_SetAttributes(channels[landsound2], gLoc, vel);
316 OPENAL_SetVolume(channels[landsound2], 128);
317 OPENAL_SetPaused(channels[landsound2], false);
320 terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0)*-1;
321 if(terrainnormal.y>.8)freefall=0;
322 bounceness=terrainnormal*findLength(&joints[jointlabels[head]].velocity)*(abs(normaldotproduct(joints[jointlabels[head]].velocity,terrainnormal)));
323 if(findLengthfast(&joints[jointlabels[head]].velocity)>findLengthfast(&joints[jointlabels[head]].oldvelocity)){
325 joints[jointlabels[head]].velocity=joints[jointlabels[head]].oldvelocity;
327 if(findLengthfast(&bounceness)>4000&&breaking){
328 objects.model[k].MakeDecal(breakdecal,DoRotation(temp-objects.position[k],0,-objects.rotation[k],0),.4,.5,Random()%360);
329 Sprite::MakeSprite(cloudsprite, headpos*(*scale)+*coords,joints[jointlabels[head]].velocity*.06, 1,1,1, 4, .2);
333 static float gLoc[3];
335 gLoc[0]=headpos.x*(*scale)+coords->x;
336 gLoc[1]=headpos.y*(*scale)+coords->y;
337 gLoc[2]=headpos.z*(*scale)+coords->z;
338 vel[0]=joints[jointlabels[head]].velocity.x;
339 vel[1]=joints[jointlabels[head]].velocity.y;
340 vel[2]=joints[jointlabels[head]].velocity.z;
341 PlaySoundEx( breaksound2, samp[breaksound2], NULL, true);
342 OPENAL_3D_SetAttributes(channels[breaksound2], gLoc, vel);
343 OPENAL_SetVolume(channels[breaksound2], 300);
344 OPENAL_SetPaused(channels[breaksound2], false);
346 envsound[numenvsounds]=*coords;
347 envsoundvol[numenvsounds]=64;
348 envsoundlife[numenvsounds]=.4;
351 if(objects.type[k]==treetrunktype){
352 objects.rotx[k]+=joints[jointlabels[head]].velocity.x*multiplier*.4;
353 objects.roty[k]+=joints[jointlabels[head]].velocity.z*multiplier*.4;
354 objects.rotx[k+1]+=joints[jointlabels[head]].velocity.x*multiplier*.4;
355 objects.roty[k+1]+=joints[jointlabels[head]].velocity.z*multiplier*.4;
357 if(!joints[jointlabels[head]].locked)damage+=findLengthfast(&bounceness)/2500;
358 ReflectVector(&joints[jointlabels[head]].velocity,&terrainnormal);
359 frictionness=abs(normaldotproduct(joints[jointlabels[head]].velocity,terrainnormal));//findLength(&bounceness)/findLength(&joints[jointlabels[head]].velocity);
360 joints[jointlabels[head]].velocity-=bounceness;
361 if(1-friction*frictionness>0)joints[jointlabels[head]].velocity*=1-friction*frictionness;
362 else joints[jointlabels[head]].velocity=0;
363 if(findLengthfast(&bounceness)>2500){
364 Normalise(&bounceness);
365 bounceness=bounceness*50;
367 joints[jointlabels[head]].velocity+=bounceness*elasticity;
370 if(!joints[jointlabels[head]].locked)
371 if(findLengthfast(&joints[jointlabels[head]].velocity)<1){
372 joints[jointlabels[head]].locked=1;
373 //joints[jointlabels[head]].velocity*=3;
375 if(findLengthfast(&bounceness)>500)Sprite::MakeSprite(cloudsprite, headpos*(*scale)+*coords,joints[jointlabels[head]].velocity*.06, 1,1,1, .5, .2);
376 joints[jointlabels[head]].position=(temp-*coords)/(*scale)+(startheadpos-headpos)+terrainnormal*.005;
377 if(longdead>100)broken=1;
383 for(i=0; i<num_joints; i++){
384 //joints[i].delay-=multiplier/1.5;
386 if(!spinny)if(findLengthfast(&joints[i].velocity)>320)joints[i].locked=0;
387 if(spinny)if(findLengthfast(&joints[i].velocity)>600)joints[i].locked=0;
388 if(joints[i].delay>0){
390 for(j=0;j<num_joints;j++){
391 if(joints[j].locked)freely=0;
393 if(freely)joints[i].delay-=multiplier*3;
395 //if(joints[i].delay>0)
396 //if(findLengthfast(&joints[i].velocity)>700&&joints[i].label!=head)joints[i].delay-=multiplier;
400 for(i=0; i<num_muscles; i++){
402 //muscles[i].DoConstraint(broken);
403 muscles[i].DoConstraint(spinny);
406 for(i=0; i<num_joints; i++){
407 //joints[i].delay-=multiplier/1.5;
411 if(joints[i].position.y*(*scale)+coords->y<terrain.getHeight(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z)+groundlevel){
414 if(joints[i].label==groin&&!joints[i].locked&&joints[i].delay<=0){
417 if(tutoriallevel!=1||id==0){
418 emit_sound_at(landsound1, joints[i].position*(*scale)+*coords, 128.);
423 if(joints[i].label==head&&!joints[i].locked&&joints[i].delay<=0){
426 if(tutoriallevel!=1||id==0){
427 emit_sound_at(landsound2, joints[i].position*(*scale)+*coords, 128.);
431 terrainnormal=terrain.getNormal(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z);
432 ReflectVector(&joints[i].velocity,&terrainnormal);
433 bounceness=terrainnormal*findLength(&joints[i].velocity)*(abs(normaldotproduct(joints[i].velocity,terrainnormal)));
434 if(!joints[i].locked)damage+=findLengthfast(&bounceness)/4000;
435 if(findLengthfast(&joints[i].velocity)<findLengthfast(&bounceness))bounceness=0;
436 frictionness=abs(normaldotproduct(joints[i].velocity,terrainnormal));//findLength(&bounceness)/findLength(&joints[i].velocity);
437 joints[i].velocity-=bounceness;
438 if(1-friction*frictionness>0)joints[i].velocity*=1-friction*frictionness;
439 else joints[i].velocity=0;
441 if(tutoriallevel!=1||id==0)
442 if(findLengthfast(&bounceness)>8000&&breaking){
443 objects.model[k].MakeDecal(breakdecal,DoRotation(temp-objects.position[k],0,-objects.rotation[k],0),.4,.5,Random()%360);
444 Sprite::MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, 1,1,1, 4, .2);
445 //Sprite::MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, 1,1,1, 1, .2);
449 emit_sound_at(breaksound2, joints[i].position*(*scale)+*coords);
451 envsound[numenvsounds]=*coords;
452 envsoundvol[numenvsounds]=64;
453 envsoundlife[numenvsounds]=.4;
457 if(findLengthfast(&bounceness)>2500){
458 Normalise(&bounceness);
459 bounceness=bounceness*50;
462 joints[i].velocity+=bounceness*elasticity;
464 if(findLengthfast(&joints[i].velocity)>findLengthfast(&joints[i].oldvelocity)){
466 joints[i].velocity=joints[i].oldvelocity;
470 if(joints[i].locked==0)
471 if(findLengthfast(&joints[i].velocity)<1)joints[i].locked=1;
473 if(environment==snowyenvironment&&findLengthfast(&bounceness)>500&&terrain.getOpacity(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z)<.2){
474 terrainlight=terrain.getLighting(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z);
475 Sprite::MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, terrainlight.x,terrainlight.y,terrainlight.z, .5, .7);
476 if(detail==2)terrain.MakeDecal(bodyprintdecal, joints[i].position*(*scale)+*coords,.4,.4,0);
478 else if(environment==desertenvironment&&findLengthfast(&bounceness)>500&&terrain.getOpacity(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z)<.2){
479 terrainlight=terrain.getLighting(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z);
480 Sprite::MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, terrainlight.x*190/255,terrainlight.y*170/255,terrainlight.z*108/255, .5, .7);
483 else if(environment==grassyenvironment&&findLengthfast(&bounceness)>500&&terrain.getOpacity(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z)<.2){
484 terrainlight=terrain.getLighting(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z);
485 Sprite::MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, terrainlight.x*90/255,terrainlight.y*70/255,terrainlight.z*8/255, .5, .5);
487 else if(findLengthfast(&bounceness)>500)Sprite::MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, terrainlight.x,terrainlight.y,terrainlight.z, .5, .2);
490 joints[i].position.y=(terrain.getHeight(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z)+groundlevel-coords->y)/(*scale);
491 if(longdead>100)broken=1;
493 if(terrain.patchobjectnum[whichpatchx][whichpatchz])
494 for(m=0;m<terrain.patchobjectnum[whichpatchx][whichpatchz];m++){
495 k=terrain.patchobjects[whichpatchx][whichpatchz][m];
496 if(k<objects.numobjects&&k>=0)
497 if(objects.possible[k]){
498 friction=objects.friction[k];
499 start=joints[i].realoldposition;
500 end=joints[i].position*(*scale)+*coords;
501 whichhit=objects.model[k].LineCheckPossible(&start,&end,&temp,&objects.position[k],&objects.rotation[k]);
503 if(joints[i].label==groin&&!joints[i].locked&&joints[i].delay<=0){
506 if(tutoriallevel!=1||id==0){
507 emit_sound_at(landsound1, joints[i].position*(*scale)+*coords, 128.);
512 if(joints[i].label==head&&!joints[i].locked&&joints[i].delay<=0){
515 if(tutoriallevel!=1||id==0){
516 emit_sound_at(landsound2, joints[i].position*(*scale)+*coords, 128.);
520 terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.rotation[k],0)*-1;
521 if(terrainnormal.y>.8)freefall=0;
522 bounceness=terrainnormal*findLength(&joints[i].velocity)*(abs(normaldotproduct(joints[i].velocity,terrainnormal)));
523 if(findLengthfast(&joints[i].velocity)>findLengthfast(&joints[i].oldvelocity)){
525 joints[i].velocity=joints[i].oldvelocity;
527 if(tutoriallevel!=1||id==0)
528 if(findLengthfast(&bounceness)>4000&&breaking){
529 objects.model[k].MakeDecal(breakdecal,DoRotation(temp-objects.position[k],0,-objects.rotation[k],0),.4,.5,Random()%360);
530 Sprite::MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, 1,1,1, 4, .2);
534 emit_sound_at(breaksound2, joints[i].position*(*scale)+*coords);
536 envsound[numenvsounds]=*coords;
537 envsoundvol[numenvsounds]=64;
538 envsoundlife[numenvsounds]=.4;
541 if(objects.type[k]==treetrunktype){
542 //if(objects.rotx[k]==0||objects.roty[k]==0){
546 if(environment==grassyenvironment)howmany=findLength(&joints[i].velocity)*4/10;
547 if(environment==snowyenvironment)howmany=findLength(&joints[i].velocity)*1/10;
548 if(environment!=desertenvironment)
549 for(j=0;j<howmany;j++){
550 tempvel.x=float(abs(Random()%100)-50)/20;
551 tempvel.y=float(abs(Random()%100)-50)/20;
552 tempvel.z=float(abs(Random()%100)-50)/20;
553 pos=objects.position[k];
554 pos.y+=objects.scale[k]*15;
555 pos.x+=float(abs(Random()%100)-50)/100*objects.scale[k]*5;
556 pos.y+=float(abs(Random()%100)-50)/100*objects.scale[k]*15;
557 pos.z+=float(abs(Random()%100)-50)/100*objects.scale[k]*5;
558 Sprite::MakeSprite(splintersprite, pos,tempvel*.5, 165/255+float(abs(Random()%100)-50)/400,0,0, .2+float(abs(Random()%100)-50)/1300, 1);
559 Sprite::special[Sprite::numsprites-1]=1;
561 objects.rotx[k]+=joints[i].velocity.x*multiplier*.4;
562 objects.roty[k]+=joints[i].velocity.z*multiplier*.4;
563 objects.rotx[k+1]+=joints[i].velocity.x*multiplier*.4;
564 objects.roty[k+1]+=joints[i].velocity.z*multiplier*.4;
566 if(!joints[i].locked)damage+=findLengthfast(&bounceness)/2500;
567 ReflectVector(&joints[i].velocity,&terrainnormal);
568 frictionness=abs(normaldotproduct(joints[i].velocity,terrainnormal));//findLength(&bounceness)/findLength(&joints[i].velocity);
569 joints[i].velocity-=bounceness;
570 if(1-friction*frictionness>0)joints[i].velocity*=1-friction*frictionness;
571 else joints[i].velocity=0;
572 if(findLengthfast(&bounceness)>2500){
573 Normalise(&bounceness);
574 bounceness=bounceness*50;
576 joints[i].velocity+=bounceness*elasticity;
579 if(!joints[i].locked)
580 if(findLengthfast(&joints[i].velocity)<1){
582 //joints[i].velocity*=3;
584 if(findLengthfast(&bounceness)>500)Sprite::MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, 1,1,1, .5, .2);
585 joints[i].position=(temp-*coords)/(*scale)+terrainnormal*.005;
586 if(longdead>100)broken=1;
590 joints[i].realoldposition=joints[i].position*(*scale)+*coords;
596 if(terrain.patchobjectnum[whichpatchx][whichpatchz])
597 for(m=0;m<terrain.patchobjectnum[whichpatchx][whichpatchz];m++){
598 k=terrain.patchobjects[whichpatchx][whichpatchz][m];
599 if(objects.possible[k]){
601 //Make this less stupid
602 start=joints[jointlabels[whichjointstartarray[i]]].position*(*scale)+*coords;
603 end=joints[jointlabels[whichjointendarray[i]]].position*(*scale)+*coords;
604 whichhit=objects.model[k].LineCheckSlidePossible(&start,&end,&temp,&objects.position[k],&objects.rotation[k]);
606 joints[jointlabels[whichjointendarray[i]]].position=(end-*coords)/(*scale);
607 for(j=0; j<num_muscles; j++){
608 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]))
609 muscles[j].DoConstraint(spinny);
616 for(i=0; i<num_joints; i++){
618 if(joints[i].label==head)groundlevel=.8;
619 if(joints[i].label==righthand||joints[i].label==rightwrist||joints[i].label==rightelbow)groundlevel=.2;
620 if(joints[i].label==lefthand||joints[i].label==leftwrist||joints[i].label==leftelbow)groundlevel=.2;
621 joints[i].position.y+=groundlevel;
623 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;
624 if(joints[i].locked){
632 for(i=0; i<num_muscles; i++){
633 if(muscles[i].type==boneconnect)
634 muscles[i].DoConstraint(0);
640 void Skeleton::DoGravity(float *scale)
643 for(i=0; i<num_joints; i++){
644 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);
648 void Skeleton::Draw(int muscleview)
650 static float jointcolor[4];
665 //Calc motionblur-ness
666 for(int i=0; i<num_joints; i++){
667 joints[i].oldposition=joints[i].position;
668 joints[i].blurred=findDistance(&joints[i].position,&joints[i].oldposition)*100;
669 if(joints[i].blurred<1)joints[i].blurred=1;
675 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
677 for(int i=0; i<num_joints; i++){
678 if(joints[i].hasparent){
679 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].blurred);
680 glVertex3f(joints[i].position.x,joints[i].position.y,joints[i].position.z);
681 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].parent->blurred);
682 glVertex3f(joints[i].parent->position.x,joints[i].parent->position.y,joints[i].parent->position.z);
683 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].parent->blurred);
684 glVertex3f(joints[i].parent->oldposition.x,joints[i].parent->oldposition.y,joints[i].parent->oldposition.z);
685 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].blurred);
686 glVertex3f(joints[i].oldposition.x,joints[i].oldposition.y,joints[i].oldposition.z);
689 for(int i=0; i<num_muscles; i++){
690 if(muscles[i].type==boneconnect){
691 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent2->blurred);
692 glVertex3f(muscles[i].parent1->position.x,muscles[i].parent1->position.y,muscles[i].parent1->position.z);
693 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent2->blurred);
694 glVertex3f(muscles[i].parent2->position.x,muscles[i].parent2->position.y,muscles[i].parent2->position.z);
695 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent2->blurred);
696 glVertex3f(muscles[i].parent2->oldposition.x,muscles[i].parent2->oldposition.y,muscles[i].parent2->oldposition.z);
697 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent1->blurred);
698 glVertex3f(muscles[i].parent1->oldposition.x,muscles[i].parent1->oldposition.y,muscles[i].parent1->oldposition.z);
704 for(int i=0; i<num_joints; i++){
705 if(joints[i].hasparent){
706 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].blurred);
707 glVertex3f(joints[i].position.x,joints[i].position.y,joints[i].position.z);
708 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].parent->blurred);
709 glVertex3f(joints[i].parent->position.x,joints[i].parent->position.y,joints[i].parent->position.z);
712 /*for(int i=0; i<num_joints; i++){
713 if(joints[i].hasparent){
714 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],1);
715 glVertex3f(joints[i].position.x,joints[i].position.y,joints[i].position.z);
716 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],1);
717 glVertex3f(joints[i].position.x+forward.x,joints[i].position.y+forward.y,joints[i].position.z+forward.z);
720 for(int i=0; i<num_muscles; i++){
721 if(muscles[i].type==boneconnect){
722 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent1->blurred);
723 glVertex3f(muscles[i].parent1->position.x,muscles[i].parent1->position.y,muscles[i].parent1->position.z);
724 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent2->blurred);
725 glVertex3f(muscles[i].parent2->position.x,muscles[i].parent2->position.y,muscles[i].parent2->position.z);
730 for(int i=0; i<num_muscles; i++){
731 if(muscles[i].type!=boneconnect){
732 glVertex3f(muscles[i].parent1->position.x,muscles[i].parent1->position.y,muscles[i].parent1->position.z);
733 glVertex3f(muscles[i].parent2->position.x,muscles[i].parent2->position.y,muscles[i].parent2->position.z);
741 for(int i=0; i<num_joints; i++){
742 if(i!=selected)glColor4f(0,0,.5,1);
743 if(i==selected)glColor4f(1,1,0,1);
744 if(joints[i].locked&&i!=selected)glColor4f(1,0,0,1);
745 glVertex3f(joints[i].position.x,joints[i].position.y,joints[i].position.z);
750 //Set old position to current position
752 for(int i=0; i<num_joints; i++){
753 joints[i].oldposition=joints[i].position;
758 void Skeleton::AddJoint(float x, float y, float z, int which)
760 if(num_joints<max_joints-1){
761 joints[num_joints].velocity=0;
762 joints[num_joints].position.x=x;
763 joints[num_joints].position.y=y;
764 joints[num_joints].position.z=z;
765 joints[num_joints].mass=1;
766 joints[num_joints].locked=0;
768 /*if(which>=num_joints||which<0)*/joints[num_joints].hasparent=0;
769 /*if(which<num_joints&&which>=0){
770 joints[num_joints].parent=&joints[which];
771 joints[num_joints].hasparent=1;
772 joints[num_joints].length=findDistance(joints[num_joints].position,joints[num_joints].parent->position);
775 if(which<num_joints&&which>=0)AddMuscle(num_joints-1,which,0,10,boneconnect);
779 void Skeleton::DeleteJoint(int whichjoint)
781 if(whichjoint<num_joints&&whichjoint>=0){
782 joints[whichjoint].velocity=joints[num_joints-1].velocity;
783 joints[whichjoint].position=joints[num_joints-1].position;
784 joints[whichjoint].oldposition=joints[num_joints-1].oldposition;
785 joints[whichjoint].hasparent=joints[num_joints-1].hasparent;
786 joints[whichjoint].parent=joints[num_joints-1].parent;
787 joints[whichjoint].length=joints[num_joints-1].length;
788 joints[whichjoint].locked=joints[num_joints-1].locked;
789 joints[whichjoint].modelnum=joints[num_joints-1].modelnum;
790 joints[whichjoint].visible=joints[num_joints-1].visible;
792 for(int i=0;i<num_muscles;i++){
793 while(muscles[i].parent1==&joints[whichjoint]&&i<num_muscles)DeleteMuscle(i);
794 while(muscles[i].parent2==&joints[whichjoint]&&i<num_muscles)DeleteMuscle(i);
796 for(int i=0;i<num_muscles;i++){
797 while(muscles[i].parent1==&joints[num_joints-1]&&i<num_muscles)muscles[i].parent1=&joints[whichjoint];
798 while(muscles[i].parent2==&joints[num_joints-1]&&i<num_muscles)muscles[i].parent2=&joints[whichjoint];
800 for(int i=0;i<num_joints;i++){
801 if(joints[i].parent==&joints[whichjoint])joints[i].hasparent=0;
803 for(int i=0;i<num_joints;i++){
804 if(joints[i].parent==&joints[num_joints-1])joints[i].parent=&joints[whichjoint];
811 void Skeleton::DeleteMuscle(int whichmuscle)
813 if(whichmuscle<num_muscles){
814 muscles[whichmuscle].minlength=muscles[num_muscles-1].minlength;
815 muscles[whichmuscle].maxlength=muscles[num_muscles-1].maxlength;
816 muscles[whichmuscle].strength=muscles[num_muscles-1].strength;
817 muscles[whichmuscle].parent1=muscles[num_muscles-1].parent1;
818 muscles[whichmuscle].parent2=muscles[num_muscles-1].parent2;
819 muscles[whichmuscle].length=muscles[num_muscles-1].length;
820 muscles[whichmuscle].visible=muscles[num_muscles-1].visible;
821 muscles[whichmuscle].type=muscles[num_muscles-1].type;
822 muscles[whichmuscle].targetlength=muscles[num_muscles-1].targetlength;
828 void Skeleton::SetJoint(float x, float y, float z, int which, int whichjoint)
830 if(whichjoint<num_joints){
831 joints[whichjoint].velocity=0;
832 joints[whichjoint].position.x=x;
833 joints[whichjoint].position.y=y;
834 joints[whichjoint].position.z=z;
836 if(which>=num_joints||which<0)joints[whichjoint].hasparent=0;
837 if(which<num_joints&&which>=0){
838 joints[whichjoint].parent=&joints[which];
839 joints[whichjoint].hasparent=1;
840 joints[whichjoint].length=findDistance(&joints[whichjoint].position,&joints[whichjoint].parent->position);
845 void Skeleton::AddMuscle(int attach1,int attach2,float minlength,float maxlength,int type)
847 if(num_muscles<max_muscles-1&&attach1<num_joints&&attach1>=0&&attach2<num_joints&&attach2>=0&&attach1!=attach2){
848 muscles[num_muscles].parent1=&joints[attach1];
849 muscles[num_muscles].parent2=&joints[attach2];
850 muscles[num_muscles].length=findDistance(&muscles[num_muscles].parent1->position,&muscles[num_muscles].parent2->position);
851 muscles[num_muscles].targetlength=findDistance(&muscles[num_muscles].parent1->position,&muscles[num_muscles].parent2->position);
852 muscles[num_muscles].strength=.7;
853 muscles[num_muscles].type=type;
854 muscles[num_muscles].minlength=minlength;
855 muscles[num_muscles].maxlength=maxlength;
861 void Skeleton::MusclesSet()
863 for(int i=0;i<num_muscles;i++){
864 muscles[i].length=findDistance(&muscles[i].parent1->position,&muscles[i].parent2->position);
868 void Skeleton::DoBalance()
871 newpoint=joints[0].position;
872 newpoint.x=(joints[2].position.x+joints[4].position.x)/2;
873 newpoint.z=(joints[2].position.z+joints[4].position.z)/2;
874 joints[0].velocity=joints[0].velocity+(newpoint-joints[0].position);
875 //Move child point to within certain distance of parent point
876 joints[0].position=newpoint;
881 void Skeleton::FindRotationMuscle(int which, int animation)
883 static XYZ temppoint1,temppoint2,tempforward;
884 static float distance;
886 temppoint1=muscles[which].parent1->position;
887 temppoint2=muscles[which].parent2->position;
888 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));
889 if((temppoint1.y-temppoint2.y)<=distance)muscles[which].rotate2=asin((temppoint1.y-temppoint2.y)/distance);
890 if((temppoint1.y-temppoint2.y)>distance)muscles[which].rotate2=asin(1.f);
891 muscles[which].rotate2*=360/6.28;
894 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));
895 if((temppoint1.z-temppoint2.z)<=distance)muscles[which].rotate1=acos((temppoint1.z-temppoint2.z)/distance);
896 if((temppoint1.z-temppoint2.z)>distance)muscles[which].rotate1=acos(1.f);
897 muscles[which].rotate1*=360/6.28;
898 if(temppoint1.x>temppoint2.x)muscles[which].rotate1=360-muscles[which].rotate1;
899 if(!isnormal(muscles[which].rotate1))muscles[which].rotate1=0;
900 if(!isnormal(muscles[which].rotate2))muscles[which].rotate2=0;
902 if(muscles[which].parent1->label==head)tempforward=specialforward[0];
903 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];
904 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];
905 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];
906 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];
907 else if(!muscles[which].parent1->lower)tempforward=forward;
908 else if(muscles[which].parent1->lower)tempforward=lowforward;
910 if(animation==hanganim){
911 if(muscles[which].parent1->label==righthand||muscles[which].parent2->label==righthand){
915 if(muscles[which].parent1->label==lefthand||muscles[which].parent2->label==lefthand){
922 if(muscles[which].parent1->label==rightfoot||muscles[which].parent2->label==rightfoot){
925 if(muscles[which].parent1->label==leftfoot||muscles[which].parent2->label==leftfoot){
931 tempforward=DoRotation(tempforward,0,muscles[which].rotate1-90,0);
932 tempforward=DoRotation(tempforward,0,0,muscles[which].rotate2-90);
934 tempforward/=sqrt(tempforward.x*tempforward.x+tempforward.y*tempforward.y+tempforward.z*tempforward.z);
935 if(tempforward.z<=1&&tempforward.z>=-1)muscles[which].rotate3=acos(0-tempforward.z);
936 else muscles[which].rotate3=acos(-1.f);
937 muscles[which].rotate3*=360/6.28;
938 if(0>tempforward.x)muscles[which].rotate3=360-muscles[which].rotate3;
939 if(!isnormal(muscles[which].rotate3))muscles[which].rotate3=0;
942 void Animation::Load(const char *filename, int aheight, int aattack)
946 static XYZ startoffset,endoffset;
949 static const char *anim_prefix = ":Data:Animations:";
954 int len = strlen(anim_prefix) + strlen(filename);
955 char *buf = new char[len + 1];
956 snprintf(buf, len + 1, "%s%s", anim_prefix, filename);
957 // Changing the filename into something the OS can understand
958 char *fixedFN = ConvertFileName(buf);
961 LOG(std::string("Loading animation...") + fixedFN);
968 if(visibleloading)pgame->LoadingScreen();
970 tfile=fopen( fixedFN, "rb" );
972 funpackf(tfile, "Bi Bi", &numframes, &joints);
974 for(i = 0; i < joints; i++){
975 if(position[i])dealloc2(position[i]);
976 if(twist[i])dealloc2(twist[i]);
977 if(twist2[i])dealloc2(twist2[i]);
978 if(onground[i])dealloc2(onground[i]);
981 if(position)dealloc2(position);
982 if(twist)dealloc2(twist);
983 if(twist2)dealloc2(twist2);
984 if(speed)dealloc2(speed);
985 if(onground)dealloc2(onground);
986 if(forward)dealloc2(forward);
987 if(weapontarget)dealloc2(weapontarget);
988 if(label)dealloc2(label);*/
990 position=(XYZ**)malloc(sizeof(XYZ*)*joints);
991 for(i = 0; i < joints; i++)
992 position[i] = (XYZ*)malloc(sizeof(XYZ)*numframes);
994 twist=(float**)malloc(sizeof(float*)*joints);
995 for(i = 0; i < joints; i++)
996 twist[i] = (float*)malloc(sizeof(float)*numframes);
998 twist2=(float**)malloc(sizeof(float*)*joints);
999 for(i = 0; i < joints; i++)
1000 twist2[i] = (float*)malloc(sizeof(float)*numframes);
1002 speed = (float*)malloc(sizeof(float)*numframes);
1004 onground=(bool**)malloc(sizeof(bool*)*joints);
1005 for(i = 0; i < joints; i++)
1006 onground[i] =(bool*)malloc(sizeof(bool)*numframes);
1008 forward = (XYZ*)malloc(sizeof(XYZ)*numframes);
1009 weapontarget = (XYZ*)malloc(sizeof(XYZ)*numframes);
1010 label = (int*)malloc(sizeof(int)*numframes);
1012 /*position = new XYZ[joints][numframes];
1013 twist = new float[joints][numframes];
1014 twist2 = new float[joints][numframes];
1015 speed = new float[numframes];
1016 onground = new bool[joints][numframes];
1017 forward = new XYZ[numframes];
1018 label = new int[numframes];*/
1020 for(i=0;i<numframes;i++){
1021 for(j=0;j<joints;j++){
1022 funpackf(tfile, "Bf Bf Bf", &position[j][i].x,&position[j][i].y,&position[j][i].z);
1024 for(j=0;j<joints;j++){
1025 funpackf(tfile, "Bf", &twist[j][i]);
1027 for(j=0;j<joints;j++){
1029 funpackf(tfile, "Bb", &uch);
1030 onground[j][i] = (uch != 0);
1032 funpackf(tfile, "Bf", &speed[i]);
1034 for(i=0;i<numframes;i++){
1035 for(j=0;j<joints;j++){
1036 funpackf(tfile, "Bf", &twist2[j][i]);
1039 for(i=0;i<numframes;i++){
1040 funpackf(tfile, "Bf", &label[i]);
1042 funpackf(tfile, "Bi", &weapontargetnum);
1043 for(i=0;i<numframes;i++){
1044 funpackf(tfile, "Bf Bf Bf", &weapontarget[i].x,&weapontarget[i].y,&weapontarget[i].z);
1053 for(j=0;j<joints;j++){
1054 if(position[j][0].y<1)
1055 startoffset+=position[j][0];
1056 if(position[j][numframes-1].y<1)
1057 endoffset+=position[j][numframes-1];
1060 startoffset/=howmany;
1067 void Animation::Move(XYZ how)
1069 static int i,j,joints;
1070 for(i=0;i<numframes;i++){
1071 for(j=0;j<joints;j++){
1077 void Skeleton::Load(const char *filename, const char *lowfilename, const char *clothesfilename,
1078 const char *modelfilename, const char *model2filename,
1079 const char *model3filename, const char *model4filename,
1080 const char *model5filename, const char *model6filename,
1081 const char *model7filename, const char *modellowfilename,
1082 const char *modelclothesfilename, bool aclothes)
1084 static GLfloat M[16];
1085 static int parentID;
1088 static int i,j,tempmuscle;
1101 for(i=0;i<num_models;i++){
1102 if(i==0)model[i].loadnotex(modelfilename);
1103 if(i==1)model[i].loadnotex(model2filename);
1104 if(i==2)model[i].loadnotex(model3filename);
1105 if(i==3)model[i].loadnotex(model4filename);
1106 if(i==4)model[i].loadnotex(model5filename);
1107 if(i==5)model[i].loadnotex(model6filename);
1108 if(i==6)model[i].loadnotex(model7filename);
1109 model[i].Rotate(180,0,0);
1110 model[i].Scale(.04,.04,.04);
1111 model[i].CalculateNormals(0);
1114 drawmodel.load(modelfilename,0);
1115 drawmodel.Rotate(180,0,0);
1116 drawmodel.Scale(.04,.04,.04);
1117 drawmodel.FlipTexCoords();
1118 if(tutoriallevel==1&&id!=0)drawmodel.UniformTexCoords();
1119 if(tutoriallevel==1&&id!=0)drawmodel.ScaleTexCoords(0.1);
1120 drawmodel.CalculateNormals(0);
1122 modellow.loadnotex(modellowfilename);
1123 modellow.Rotate(180,0,0);
1124 modellow.Scale(.04,.04,.04);
1125 modellow.CalculateNormals(0);
1127 drawmodellow.load(modellowfilename,0);
1128 drawmodellow.Rotate(180,0,0);
1129 drawmodellow.Scale(.04,.04,.04);
1130 drawmodellow.FlipTexCoords();
1131 if(tutoriallevel==1&&id!=0)drawmodellow.UniformTexCoords();
1132 if(tutoriallevel==1&&id!=0)drawmodellow.ScaleTexCoords(0.1);
1133 drawmodellow.CalculateNormals(0);
1136 modelclothes.loadnotex(modelclothesfilename);
1137 modelclothes.Rotate(180,0,0);
1138 modelclothes.Scale(.041,.04,.041);
1139 modelclothes.CalculateNormals(0);
1141 drawmodelclothes.load(modelclothesfilename,0);
1142 drawmodelclothes.Rotate(180,0,0);
1143 drawmodelclothes.Scale(.04,.04,.04);
1144 drawmodelclothes.FlipTexCoords();
1145 drawmodelclothes.CalculateNormals(0);
1148 tfile=fopen( ConvertFileName(filename), "rb" );
1150 funpackf(tfile, "Bi", &num_joints);
1151 //joints.resize(num_joints);
1152 if(joints) delete [] joints; //dealloc2(joints);
1153 joints=(Joint*)new Joint[num_joints]; //malloc(sizeof(Joint)*num_joints);
1155 for(i=0;i<num_joints;i++){
1156 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);
1157 funpackf(tfile, "Bb Bb", &joints[i].hasparent,&joints[i].locked);
1158 funpackf(tfile, "Bi", &joints[i].modelnum);
1159 funpackf(tfile, "Bb Bb", &joints[i].visible,&joints[i].sametwist);
1160 funpackf(tfile, "Bi Bi", &joints[i].label,&joints[i].hasgun);
1161 funpackf(tfile, "Bb", &joints[i].lower);
1162 funpackf(tfile, "Bi", &parentID);
1163 if(joints[i].hasparent)joints[i].parent=&joints[parentID];
1164 joints[i].velocity=0;
1165 joints[i].oldposition=joints[i].position;
1167 tempmuscle=num_muscles;
1168 funpackf(tfile, "Bi", &num_muscles);
1170 if(muscles) delete [] muscles; //dealloc2(muscles);
1171 muscles=(Muscle*)new Muscle[num_muscles]; //malloc(sizeof(Muscle)*num_muscles);
1173 for(i=0;i<num_muscles;i++){
1174 tempmuscle=muscles[i].numvertices;
1175 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);
1176 //muscles[i].vertices.clear();
1177 //muscles[i].vertices.resize(muscles[i].numvertices);
1178 //if(muscles[i].vertices)dealloc2(muscles[i].vertices);
1179 muscles[i].vertices=(int*)malloc(sizeof(int)*muscles[i].numvertices);
1182 for(j=0;j<muscles[i].numvertices-edit;j++){
1183 funpackf(tfile, "Bi", &muscles[i].vertices[j+edit]);
1184 if(muscles[i].vertices[j+edit]>=model[0].vertexNum){
1185 muscles[i].numvertices--;
1189 funpackf(tfile, "Bb Bi", &muscles[i].visible, &parentID);
1190 muscles[i].parent1=&joints[parentID];
1191 funpackf(tfile, "Bi", &parentID);
1192 muscles[i].parent2=&joints[parentID];
1195 funpackf(tfile, "Bi", &forwardjoints[j]);
1198 funpackf(tfile, "Bi", &lowforwardjoints[j]);
1200 for(j=0;j<num_muscles;j++){
1201 for(i=0;i<muscles[j].numvertices;i++){
1202 for(int k=0;k<num_models;k++){
1203 if(muscles[j].numvertices&&muscles[j].vertices[i]<model[k].vertexNum)model[k].owner[muscles[j].vertices[i]]=j;
1208 for(i=0;i<num_joints;i++){
1209 joints[i].startpos=joints[i].position;
1211 for(i=0;i<num_muscles;i++){
1212 FindRotationMuscle(i,-1);
1214 for(int k=0;k<num_models;k++){
1215 for(i=0;i<model[k].vertexNum;i++){
1216 model[k].vertex[i]=model[k].vertex[i]-(muscles[model[k].owner[i]].parent1->position+muscles[model[k].owner[i]].parent2->position)/2;
1217 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
1220 glRotatef(muscles[model[k].owner[i]].rotate3,0,1,0);
1221 glRotatef(muscles[model[k].owner[i]].rotate2-90,0,0,1);
1222 glRotatef(muscles[model[k].owner[i]].rotate1-90,0,1,0);
1223 glTranslatef(model[k].vertex[i].x,model[k].vertex[i].y,model[k].vertex[i].z);
1224 glGetFloatv(GL_MODELVIEW_MATRIX,M);
1225 model[k].vertex[i].x=M[12]*1;
1226 model[k].vertex[i].y=M[13]*1;
1227 model[k].vertex[i].z=M[14]*1;
1230 model[k].CalculateNormals(0);
1235 tfile=fopen( ConvertFileName(lowfilename), "rb" );
1237 lSize=sizeof(num_joints);
1238 fseek ( tfile, lSize, SEEK_CUR);
1239 //joints = new Joint[num_joints];
1240 //jointlabels = new int[num_joints];
1241 for(i=0;i<num_joints;i++){
1243 fseek ( tfile, lSize, SEEK_CUR);
1244 lSize=sizeof(float);
1245 fseek ( tfile, lSize, SEEK_CUR);
1246 lSize=sizeof(float);
1247 fseek ( tfile, lSize, SEEK_CUR);
1248 lSize=1;//sizeof(bool);
1249 fseek ( tfile, lSize, SEEK_CUR);
1250 lSize=1;//sizeof(bool);
1251 fseek ( tfile, lSize, SEEK_CUR);
1253 fseek ( tfile, lSize, SEEK_CUR);
1254 lSize=1;//sizeof(bool);
1255 fseek ( tfile, lSize, SEEK_CUR);
1256 lSize=1;//sizeof(bool);
1257 fseek ( tfile, lSize, SEEK_CUR);
1259 fseek ( tfile, lSize, SEEK_CUR);
1261 fseek ( tfile, lSize, SEEK_CUR);
1262 lSize=1;//sizeof(bool);
1263 fseek ( tfile, lSize, SEEK_CUR);
1265 fseek ( tfile, lSize, SEEK_CUR);
1266 if(joints[i].hasparent)joints[i].parent=&joints[parentID];
1267 joints[i].velocity=0;
1268 joints[i].oldposition=joints[i].position;
1270 funpackf(tfile, "Bi", &num_muscles);
1271 //muscles = new Muscle[num_muscles];
1272 for(i=0;i<num_muscles;i++){
1273 lSize=sizeof(float);
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=sizeof(float);
1280 fseek ( tfile, lSize, SEEK_CUR);
1281 lSize=sizeof(float);
1282 fseek ( tfile, lSize, SEEK_CUR);
1284 fseek ( tfile, lSize, SEEK_CUR);
1285 tempmuscle=muscles[i].numverticeslow;
1286 funpackf(tfile, "Bi", &muscles[i].numverticeslow);
1287 if(muscles[i].numverticeslow){
1288 //muscles[i].verticeslow.clear();
1289 //muscles[i].verticeslow.resize(muscles[i].numverticeslow);
1290 //if(muscles[i].verticeslow)dealloc2(muscles[i].verticeslow);
1291 muscles[i].verticeslow=(int*)malloc(sizeof(int)*muscles[i].numverticeslow);
1293 for(j=0;j<muscles[i].numverticeslow-edit;j++){
1294 funpackf(tfile, "Bi", &muscles[i].verticeslow[j+edit]);
1295 if(muscles[i].verticeslow[j+edit]>=modellow.vertexNum){
1296 muscles[i].numverticeslow--;
1303 lSize=1;//sizeof(bool);
1304 fseek ( tfile, lSize, SEEK_CUR);
1306 fseek ( tfile, lSize, SEEK_CUR);
1307 fseek ( tfile, lSize, SEEK_CUR);
1310 for(j=0;j<num_muscles;j++){
1311 for(i=0;i<muscles[j].numverticeslow;i++){
1312 if(muscles[j].numverticeslow&&muscles[j].verticeslow[i]<modellow.vertexNum)modellow.owner[muscles[j].verticeslow[i]]=j;
1316 for(i=0;i<num_joints;i++){
1317 joints[i].startpos=joints[i].position;
1319 for(i=0;i<num_muscles;i++){
1320 FindRotationMuscle(i,-1);
1322 for(i=0;i<modellow.vertexNum;i++){
1323 modellow.vertex[i]=modellow.vertex[i]-(muscles[modellow.owner[i]].parent1->position+muscles[modellow.owner[i]].parent2->position)/2;
1324 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
1327 glRotatef(muscles[modellow.owner[i]].rotate3,0,1,0);
1328 glRotatef(muscles[modellow.owner[i]].rotate2-90,0,0,1);
1329 glRotatef(muscles[modellow.owner[i]].rotate1-90,0,1,0);
1330 glTranslatef(modellow.vertex[i].x,modellow.vertex[i].y,modellow.vertex[i].z);
1331 glGetFloatv(GL_MODELVIEW_MATRIX,M);
1332 modellow.vertex[i].x=M[12];
1333 modellow.vertex[i].y=M[13];
1334 modellow.vertex[i].z=M[14];
1337 modellow.CalculateNormals(0);
1341 tfile=fopen( ConvertFileName(clothesfilename), "rb" );
1342 lSize=sizeof(num_joints);
1343 fseek ( tfile, lSize, SEEK_CUR);
1344 //joints = new Joint[num_joints];
1345 //jointlabels = new int[num_joints];
1346 for(i=0;i<num_joints;i++){
1348 fseek ( tfile, lSize, SEEK_CUR);
1349 lSize=sizeof(float);
1350 fseek ( tfile, lSize, SEEK_CUR);
1351 lSize=sizeof(float);
1352 fseek ( tfile, lSize, SEEK_CUR);
1353 lSize=1;//sizeof(bool);
1354 fseek ( tfile, lSize, SEEK_CUR);
1355 lSize=1;//sizeof(bool);
1356 fseek ( tfile, lSize, SEEK_CUR);
1358 fseek ( tfile, lSize, SEEK_CUR);
1359 lSize=1;//sizeof(bool);
1360 fseek ( tfile, lSize, SEEK_CUR);
1361 lSize=1;//sizeof(bool);
1362 fseek ( tfile, lSize, SEEK_CUR);
1364 fseek ( tfile, lSize, SEEK_CUR);
1366 fseek ( tfile, lSize, SEEK_CUR);
1367 lSize=1;//sizeof(bool);
1368 fseek ( tfile, lSize, SEEK_CUR);
1370 fseek ( tfile, lSize, SEEK_CUR);
1371 if(joints[i].hasparent)joints[i].parent=&joints[parentID];
1372 joints[i].velocity=0;
1373 joints[i].oldposition=joints[i].position;
1375 funpackf(tfile, "Bi", &num_muscles);
1376 //muscles = new Muscle[num_muscles];
1377 for(i=0;i<num_muscles;i++){
1378 lSize=sizeof(float);
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=sizeof(float);
1385 fseek ( tfile, lSize, SEEK_CUR);
1386 lSize=sizeof(float);
1387 fseek ( tfile, lSize, SEEK_CUR);
1389 fseek ( tfile, lSize, SEEK_CUR);
1390 tempmuscle=muscles[i].numverticesclothes;
1391 funpackf(tfile, "Bi", &muscles[i].numverticesclothes);
1392 if(muscles[i].numverticesclothes){
1393 //muscles[i].verticesclothes.clear();
1394 //muscles[i].verticesclothes.resize(muscles[i].numverticesclothes);
1395 //if(muscles[i].verticesclothes)dealloc2(muscles[i].verticesclothes);
1396 muscles[i].verticesclothes=(int*)malloc(sizeof(int)*muscles[i].numverticesclothes);
1398 for(j=0;j<muscles[i].numverticesclothes-edit;j++){
1399 funpackf(tfile, "Bi", &muscles[i].verticesclothes[j+edit]);
1400 if(muscles[i].verticesclothes[j+edit]>=modelclothes.vertexNum){
1401 muscles[i].numverticesclothes--;
1406 lSize=1;//sizeof(bool);
1407 fseek ( tfile, lSize, SEEK_CUR);
1409 fseek ( tfile, lSize, SEEK_CUR);
1410 fseek ( tfile, lSize, SEEK_CUR);
1413 for(j=0;j<num_muscles;j++){
1414 for(i=0;i<muscles[j].numverticesclothes;i++){
1415 if(muscles[j].numverticesclothes&&muscles[j].verticesclothes[i]<modelclothes.vertexNum)modelclothes.owner[muscles[j].verticesclothes[i]]=j;
1419 for(i=0;i<num_joints;i++){
1420 joints[i].startpos=joints[i].position;
1422 for(i=0;i<num_muscles;i++){
1423 FindRotationMuscle(i,-1);
1425 for(i=0;i<modelclothes.vertexNum;i++){
1426 modelclothes.vertex[i]=modelclothes.vertex[i]-(muscles[modelclothes.owner[i]].parent1->position+muscles[modelclothes.owner[i]].parent2->position)/2;
1427 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
1430 glRotatef(muscles[modelclothes.owner[i]].rotate3,0,1,0);
1431 glRotatef(muscles[modelclothes.owner[i]].rotate2-90,0,0,1);
1432 glRotatef(muscles[modelclothes.owner[i]].rotate1-90,0,1,0);
1433 glTranslatef(modelclothes.vertex[i].x,modelclothes.vertex[i].y,modelclothes.vertex[i].z);
1434 glGetFloatv(GL_MODELVIEW_MATRIX,M);
1435 modelclothes.vertex[i].x=M[12];
1436 modelclothes.vertex[i].y=M[13];
1437 modelclothes.vertex[i].z=M[14];
1440 modelclothes.CalculateNormals(0);
1444 for(i=0;i<num_joints;i++){
1445 for(j=0;j<num_joints;j++){
1446 if(joints[i].label==j)jointlabels[j]=i;
1453 Animation::Animation()
1459 weapontargetnum = 0;
1471 Animation::~Animation()
1476 void Animation::deallocate()
1482 for(i = 0; i < joints; i++)
1483 dealloc2(position[i]);
1491 for(i = 0; i < joints; i++)
1500 for(i = 0; i < joints; i++)
1501 dealloc2(twist2[i]);
1509 for(i = 0; i < joints; i++)
1510 dealloc2(onground[i]);
1516 if(speed)dealloc2(speed);
1519 if(forward)dealloc2(forward);
1522 if(weapontarget)dealloc2(weapontarget);
1525 if(label)dealloc2(label);
1531 Skeleton::Skeleton()
1539 memset(forwardjoints, 0, sizeof(forwardjoints));
1544 memset(lowforwardjoints, 0, sizeof(lowforwardjoints));
1547 // XYZ specialforward[5];
1548 memset(jointlabels, 0, sizeof(jointlabels));
1552 // Model modelclothes;
1556 // Model drawmodellow;
1557 // Model drawmodelclothes;
1562 memset(skinText, 0, sizeof(skinText));
1579 Skeleton::~Skeleton()
1602 numverticesclothes = 0;
1611 rotate1 = 0,rotate2 = 0,rotate3 = 0;
1612 lastrotate1 = 0,lastrotate2 = 0,lastrotate3 = 0;
1613 oldrotate1 = 0,oldrotate2 = 0,oldrotate3 = 0;
1614 newrotate1 = 0,newrotate2 = 0,newrotate3 = 0;
1622 dealloc2(verticeslow);
1623 dealloc2(verticesclothes);
1626 Animation & Animation::operator = (const Animation & ani)
1630 bool allocate = true;
1632 allocate = ((ani.numframes != numframes) || (ani.joints != joints));
1634 if (allocate) deallocate();
1636 numframes = ani.numframes;
1637 height = ani.height;
1638 attack = ani.attack;
1639 joints = ani.joints;
1640 weapontargetnum = ani.weapontargetnum;
1642 if (allocate) position=(XYZ**)malloc(sizeof(XYZ*)*ani.joints);
1643 for(i = 0; i < ani.joints; i++)
1645 if (allocate) position[i] = (XYZ*)malloc(sizeof(XYZ)*ani.numframes);
1646 memcpy(position[i], ani.position[i], sizeof(XYZ)*ani.numframes);
1649 if (allocate) twist=(float**)malloc(sizeof(float*)*ani.joints);
1650 for(i = 0; i < ani.joints; i++)
1652 if (allocate) twist[i] = (float*)malloc(sizeof(float)*ani.numframes);
1653 memcpy(twist[i], ani.twist[i], sizeof(float)*ani.numframes);
1656 if (allocate) twist2=(float**)malloc(sizeof(float*)*ani.joints);
1657 for(i = 0; i < ani.joints; i++)
1659 if (allocate) twist2[i] = (float*)malloc(sizeof(float)*ani.numframes);
1660 memcpy(twist2[i], ani.twist2[i], sizeof(float)*ani.numframes);
1663 if (allocate) speed = (float*)malloc(sizeof(float)*ani.numframes);
1664 memcpy(speed, ani.speed, sizeof(float)*ani.numframes);
1666 if (allocate) onground=(bool**)malloc(sizeof(bool*)*ani.joints);
1667 for(i = 0; i < ani.joints; i++)
1669 if (allocate) onground[i] =(bool*)malloc(sizeof(bool)*ani.numframes);
1670 memcpy(onground[i], ani.onground[i], sizeof(bool)*ani.numframes);
1673 if (allocate) forward = (XYZ*)malloc(sizeof(XYZ)*ani.numframes);
1674 memcpy(forward, ani.forward, sizeof(XYZ)*ani.numframes);
1676 if (allocate) weapontarget = (XYZ*)malloc(sizeof(XYZ)*ani.numframes);
1677 memcpy(weapontarget, ani.weapontarget, sizeof(XYZ)*ani.numframes);
1679 if (allocate) label = (int*)malloc(sizeof(int)*ani.numframes);
1680 memcpy(label, ani.label, sizeof(int)*ani.numframes);