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 Objects objects;
33 extern int environment;
34 extern float camerashake;
37 extern XYZ envsound[30];
38 extern float envsoundvol[30];
39 extern int numenvsounds;
40 extern float envsoundlife[30];
41 extern int tutoriallevel;
43 extern int whichjointstartarray[26];
44 extern int whichjointendarray[26];
46 extern bool visibleloading;
48 void dealloc2(void* param){
53 enum {boneconnect, constraint, muscle};
55 void Muscle::DoConstraint(bool spinny)
59 static XYZ newpoint1,newpoint2;
61 static float oldlength;
62 static float relaxlength;
66 if(type!=boneconnect)relaxlength=findDistance(&parent1->position,&parent2->position);
68 if(type==boneconnect)strength=1;
69 if(type==constraint)strength=0;
71 if(strength<0)strength=0;
72 if(strength>1)strength=1;
74 length-=(length-relaxlength)*(1-strength)*multiplier*10000;
75 length-=(length-targetlength)*(strength)*multiplier*10000;
76 if(strength==0)length=relaxlength;
78 if((relaxlength-length>0&&relaxlength-oldlength<0)||(relaxlength-length<0&&relaxlength-oldlength>0))length=relaxlength;
81 if(length<minlength)length=minlength;
82 if(length>maxlength)length=maxlength;
86 if(length<minlength*.6)length=minlength*.6;
87 if(length>maxlength*1.4)length=maxlength*1.4;
90 if(length==relaxlength)return;
93 midp=(parent1->position*parent1->mass+parent2->position*parent2->mass)/(parent1->mass+parent2->mass);
94 //Find vector from midpoint to second vector
95 vel=parent2->position-midp;
96 //Change to unit vector
98 //Apply velocity change
99 newpoint1=midp-vel*length*(parent2->mass/(parent1->mass+parent2->mass));
100 newpoint2=midp+vel*length*(parent1->mass/(parent1->mass+parent2->mass));
102 parent1->velocity=parent1->velocity+(newpoint1-parent1->position)/multiplier/4;
103 parent2->velocity=parent2->velocity+(newpoint2-parent2->position)/multiplier/4;
107 parent1->velocity=parent1->velocity+(newpoint1-parent1->position);
108 parent2->velocity=parent2->velocity+(newpoint2-parent2->position);
110 //Move child point to within certain distance of parent point
111 parent1->position=newpoint1;
112 parent2->position=newpoint2;
115 void Skeleton::FindForwardsfirst()
117 //Find forward vectors
118 CrossProduct(joints[forwardjoints[1]].position-joints[forwardjoints[0]].position,joints[forwardjoints[2]].position-joints[forwardjoints[0]].position,&forward);
121 CrossProduct(joints[lowforwardjoints[1]].position-joints[lowforwardjoints[0]].position,joints[lowforwardjoints[2]].position-joints[lowforwardjoints[0]].position,&lowforward);
122 Normalise(&lowforward);
125 specialforward[0]=forward;
126 specialforward[1]=forward;
127 specialforward[2]=forward;
128 specialforward[3]=forward;
129 specialforward[4]=forward;
132 void Skeleton::FindForwards()
134 //Find forward vectors
135 CrossProduct(joints[forwardjoints[1]].position-joints[forwardjoints[0]].position,joints[forwardjoints[2]].position-joints[forwardjoints[0]].position,&forward);
138 CrossProduct(joints[lowforwardjoints[1]].position-joints[lowforwardjoints[0]].position,joints[lowforwardjoints[2]].position-joints[lowforwardjoints[0]].position,&lowforward);
139 Normalise(&lowforward);
142 specialforward[0]=forward;
144 specialforward[1]=joints[jointlabels[rightshoulder]].position+joints[jointlabels[rightwrist]].position;
145 specialforward[1]=joints[jointlabels[rightelbow]].position-specialforward[1]/2;
146 specialforward[1]+=forward*.4;
147 Normalise(&specialforward[1]);
148 specialforward[2]=joints[jointlabels[leftshoulder]].position+joints[jointlabels[leftwrist]].position;
149 specialforward[2]=joints[jointlabels[leftelbow]].position-specialforward[2]/2;
150 specialforward[2]+=forward*.4;
151 Normalise(&specialforward[2]);
153 specialforward[3]=joints[jointlabels[righthip]].position+joints[jointlabels[rightankle]].position;
154 specialforward[3]=specialforward[3]/2-joints[jointlabels[rightknee]].position;
155 specialforward[3]+=lowforward*.4;
156 Normalise(&specialforward[3]);
157 specialforward[4]=joints[jointlabels[lefthip]].position+joints[jointlabels[leftankle]].position;
158 specialforward[4]=specialforward[4]/2-joints[jointlabels[leftknee]].position;
159 specialforward[4]+=lowforward*.4;
160 Normalise(&specialforward[4]);
163 float Skeleton::DoConstraints(XYZ *coords,float *scale)
165 static float friction=1.5;
166 static float elasticity=.3;
167 static XYZ bounceness;
168 static XYZ oldpos[100];
169 static int numrepeats=3;
170 static float groundlevel=.15;
171 static float soundvolume;
172 static int i,j,k,l,m;
173 static XYZ temp,start,end;
174 static XYZ terrainnormal;
178 //static int whichjointstart,whichjointend;
179 static float distance;
180 static float frictionness;
181 static XYZ terrainlight;
182 static int whichpatchx;
183 static int whichpatchz;
186 static float tempmult;
187 static bool breaking;
193 freetime+=multiplier;
195 whichpatchx=coords->x/(terrain.size/subdivision*terrain.scale);
196 whichpatchz=coords->z/(terrain.size/subdivision*terrain.scale);
198 terrainlight=*coords;
199 objects.SphereCheckPossible(&terrainlight, 1);
201 for(i=0; i<num_joints; i++){
202 oldpos[i]=joints[i].position;
206 for(i=0; i<num_joints; i++){
207 //if(!isnormal(joints[i].velocity.x)||!isnormal(joints[i].velocity.y)||!isnormal(joints[i].velocity.z))joints[i].velocity=0;
208 joints[i].position=joints[i].position+joints[i].velocity*multiplier;
210 if(joints[i].label==head)groundlevel=.8;
211 if(joints[i].label==righthand||joints[i].label==rightwrist||joints[i].label==rightelbow)groundlevel=.2;
212 if(joints[i].label==lefthand||joints[i].label==leftwrist||joints[i].label==leftelbow)groundlevel=.2;
213 joints[i].position.y-=groundlevel;
214 //if(!joints[i].locked&&!broken)joints[i].velocity+=joints[i].velchange*multiplier*10*(500-longdead)/500;
215 joints[i].oldvelocity=joints[i].velocity;
218 //multiplier/=numrepeats;
219 for(j=0; j<numrepeats; j++){
220 if(!joints[jointlabels[rightknee]].locked&&!joints[jointlabels[righthip]].locked){
221 temp=joints[jointlabels[rightknee]].position-(joints[jointlabels[righthip]].position+joints[jointlabels[rightankle]].position)/2;
222 while(normaldotproduct(temp,lowforward)>-.1&&!sphere_line_intersection(&joints[jointlabels[righthip]].position,&joints[jointlabels[rightankle]].position,&joints[jointlabels[rightknee]].position,&r)){
223 joints[jointlabels[rightknee]].position-=lowforward*.05;
224 if(spinny)joints[jointlabels[rightknee]].velocity-=lowforward*.05/multiplier/4;
225 else joints[jointlabels[rightknee]].velocity-=lowforward*.05;
226 joints[jointlabels[rightankle]].position+=lowforward*.025;
227 if(spinny)joints[jointlabels[rightankle]].velocity+=lowforward*.025/multiplier/4;
228 else joints[jointlabels[rightankle]].velocity+=lowforward*.25;
229 joints[jointlabels[righthip]].position+=lowforward*.025;
230 if(spinny)joints[jointlabels[righthip]].velocity+=lowforward*.025/multiplier/4;
231 else joints[jointlabels[righthip]].velocity+=lowforward*.025;
232 temp=joints[jointlabels[rightknee]].position-(joints[jointlabels[righthip]].position+joints[jointlabels[rightankle]].position)/2;
235 if(!joints[jointlabels[leftknee]].locked&&!joints[jointlabels[righthip]].locked){
236 temp=joints[jointlabels[leftknee]].position-(joints[jointlabels[lefthip]].position+joints[jointlabels[leftankle]].position)/2;
237 while(normaldotproduct(temp,lowforward)>-.1&&!sphere_line_intersection(&joints[jointlabels[lefthip]].position,&joints[jointlabels[leftankle]].position,&joints[jointlabels[leftknee]].position,&r)){
238 joints[jointlabels[leftknee]].position-=lowforward*.05;
239 if(spinny)joints[jointlabels[leftknee]].velocity-=lowforward*.05/multiplier/4;
240 else joints[jointlabels[leftknee]].velocity-=lowforward*.05;
241 joints[jointlabels[leftankle]].position+=lowforward*.025;
242 if(spinny)joints[jointlabels[leftankle]].velocity+=lowforward*.025/multiplier/4;
243 else joints[jointlabels[leftankle]].velocity+=lowforward*.25;
244 joints[jointlabels[lefthip]].position+=lowforward*.025;
245 if(spinny)joints[jointlabels[lefthip]].velocity+=lowforward*.025/multiplier/4;
246 else joints[jointlabels[lefthip]].velocity+=lowforward*.025;
247 temp=joints[jointlabels[leftknee]].position-(joints[jointlabels[lefthip]].position+joints[jointlabels[leftankle]].position)/2;
251 for(i=0; i<num_joints; i++){
252 //joints[i].delay-=multiplier/1.5;
254 if(!spinny)if(findLengthfast(&joints[i].velocity)>320)joints[i].locked=0;
255 if(spinny)if(findLengthfast(&joints[i].velocity)>600)joints[i].locked=0;
256 if(joints[i].delay>0){
258 for(j=0;j<num_joints;j++){
259 if(joints[j].locked)freely=0;
261 if(freely)joints[i].delay-=multiplier*3;
263 //if(joints[i].delay>0)
264 //if(findLengthfast(&joints[i].velocity)>700&&joints[i].label!=head)joints[i].delay-=multiplier;
268 for(i=0; i<num_muscles; i++){
270 //muscles[i].DoConstraint(broken);
271 muscles[i].DoConstraint(spinny);
274 for(i=0; i<num_joints; i++){
275 //joints[i].delay-=multiplier/1.5;
279 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){
282 if(joints[i].label==groin&&!joints[i].locked&&joints[i].delay<=0){
285 if(tutoriallevel!=1||id==0){
286 emit_sound_at(landsound1, joints[i].position*(*scale)+*coords, 128.);
291 if(joints[i].label==head&&!joints[i].locked&&joints[i].delay<=0){
294 if(tutoriallevel!=1||id==0){
295 emit_sound_at(landsound2, joints[i].position*(*scale)+*coords, 128.);
299 terrainnormal=terrain.getNormal(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z);
300 ReflectVector(&joints[i].velocity,&terrainnormal);
301 bounceness=terrainnormal*findLength(&joints[i].velocity)*(abs(normaldotproduct(joints[i].velocity,terrainnormal)));
302 if(!joints[i].locked)damage+=findLengthfast(&bounceness)/4000;
303 if(findLengthfast(&joints[i].velocity)<findLengthfast(&bounceness))bounceness=0;
304 frictionness=abs(normaldotproduct(joints[i].velocity,terrainnormal));//findLength(&bounceness)/findLength(&joints[i].velocity);
305 joints[i].velocity-=bounceness;
306 if(1-friction*frictionness>0)joints[i].velocity*=1-friction*frictionness;
307 else joints[i].velocity=0;
309 if(tutoriallevel!=1||id==0)
310 if(findLengthfast(&bounceness)>8000&&breaking){
311 objects.model[k].MakeDecal(breakdecal,DoRotation(temp-objects.position[k],0,-objects.yaw[k],0),.4,.5,Random()%360);
312 Sprite::MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, 1,1,1, 4, .2);
313 //Sprite::MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, 1,1,1, 1, .2);
317 emit_sound_at(breaksound2, joints[i].position*(*scale)+*coords);
319 envsound[numenvsounds]=*coords;
320 envsoundvol[numenvsounds]=64;
321 envsoundlife[numenvsounds]=.4;
325 if(findLengthfast(&bounceness)>2500){
326 Normalise(&bounceness);
327 bounceness=bounceness*50;
330 joints[i].velocity+=bounceness*elasticity;
332 if(findLengthfast(&joints[i].velocity)>findLengthfast(&joints[i].oldvelocity)){
334 joints[i].velocity=joints[i].oldvelocity;
338 if(joints[i].locked==0)
339 if(findLengthfast(&joints[i].velocity)<1)joints[i].locked=1;
341 if(environment==snowyenvironment&&findLengthfast(&bounceness)>500&&terrain.getOpacity(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z)<.2){
342 terrainlight=terrain.getLighting(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z);
343 Sprite::MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, terrainlight.x,terrainlight.y,terrainlight.z, .5, .7);
344 if(detail==2)terrain.MakeDecal(bodyprintdecal, joints[i].position*(*scale)+*coords,.4,.4,0);
346 else if(environment==desertenvironment&&findLengthfast(&bounceness)>500&&terrain.getOpacity(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z)<.2){
347 terrainlight=terrain.getLighting(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z);
348 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);
351 else if(environment==grassyenvironment&&findLengthfast(&bounceness)>500&&terrain.getOpacity(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z)<.2){
352 terrainlight=terrain.getLighting(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z);
353 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);
355 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);
358 joints[i].position.y=(terrain.getHeight(joints[i].position.x*(*scale)+coords->x,joints[i].position.z*(*scale)+coords->z)+groundlevel-coords->y)/(*scale);
359 if(longdead>100)broken=1;
361 if(terrain.patchobjectnum[whichpatchx][whichpatchz])
362 for(m=0;m<terrain.patchobjectnum[whichpatchx][whichpatchz];m++){
363 k=terrain.patchobjects[whichpatchx][whichpatchz][m];
364 if(k<objects.numobjects&&k>=0)
365 if(objects.possible[k]){
366 friction=objects.friction[k];
367 start=joints[i].realoldposition;
368 end=joints[i].position*(*scale)+*coords;
369 whichhit=objects.model[k].LineCheckPossible(&start,&end,&temp,&objects.position[k],&objects.yaw[k]);
371 if(joints[i].label==groin&&!joints[i].locked&&joints[i].delay<=0){
374 if(tutoriallevel!=1||id==0){
375 emit_sound_at(landsound1, joints[i].position*(*scale)+*coords, 128.);
380 if(joints[i].label==head&&!joints[i].locked&&joints[i].delay<=0){
383 if(tutoriallevel!=1||id==0){
384 emit_sound_at(landsound2, joints[i].position*(*scale)+*coords, 128.);
388 terrainnormal=DoRotation(objects.model[k].facenormals[whichhit],0,objects.yaw[k],0)*-1;
389 if(terrainnormal.y>.8)freefall=0;
390 bounceness=terrainnormal*findLength(&joints[i].velocity)*(abs(normaldotproduct(joints[i].velocity,terrainnormal)));
391 if(findLengthfast(&joints[i].velocity)>findLengthfast(&joints[i].oldvelocity)){
393 joints[i].velocity=joints[i].oldvelocity;
395 if(tutoriallevel!=1||id==0)
396 if(findLengthfast(&bounceness)>4000&&breaking){
397 objects.model[k].MakeDecal(breakdecal,DoRotation(temp-objects.position[k],0,-objects.yaw[k],0),.4,.5,Random()%360);
398 Sprite::MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, 1,1,1, 4, .2);
402 emit_sound_at(breaksound2, joints[i].position*(*scale)+*coords);
404 envsound[numenvsounds]=*coords;
405 envsoundvol[numenvsounds]=64;
406 envsoundlife[numenvsounds]=.4;
409 if(objects.type[k]==treetrunktype){
410 //if(objects.rotx[k]==0||objects.roty[k]==0){
414 if(environment==grassyenvironment)howmany=findLength(&joints[i].velocity)*4/10;
415 if(environment==snowyenvironment)howmany=findLength(&joints[i].velocity)*1/10;
416 if(environment!=desertenvironment)
417 for(j=0;j<howmany;j++){
418 tempvel.x=float(abs(Random()%100)-50)/20;
419 tempvel.y=float(abs(Random()%100)-50)/20;
420 tempvel.z=float(abs(Random()%100)-50)/20;
421 pos=objects.position[k];
422 pos.y+=objects.scale[k]*15;
423 pos.x+=float(abs(Random()%100)-50)/100*objects.scale[k]*5;
424 pos.y+=float(abs(Random()%100)-50)/100*objects.scale[k]*15;
425 pos.z+=float(abs(Random()%100)-50)/100*objects.scale[k]*5;
426 Sprite::MakeSprite(splintersprite, pos,tempvel*.5, 165/255+float(abs(Random()%100)-50)/400,0,0, .2+float(abs(Random()%100)-50)/1300, 1);
427 Sprite::special[Sprite::numsprites-1]=1;
429 objects.rotx[k]+=joints[i].velocity.x*multiplier*.4;
430 objects.roty[k]+=joints[i].velocity.z*multiplier*.4;
431 objects.rotx[k+1]+=joints[i].velocity.x*multiplier*.4;
432 objects.roty[k+1]+=joints[i].velocity.z*multiplier*.4;
434 if(!joints[i].locked)damage+=findLengthfast(&bounceness)/2500;
435 ReflectVector(&joints[i].velocity,&terrainnormal);
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;
440 if(findLengthfast(&bounceness)>2500){
441 Normalise(&bounceness);
442 bounceness=bounceness*50;
444 joints[i].velocity+=bounceness*elasticity;
447 if(!joints[i].locked)
448 if(findLengthfast(&joints[i].velocity)<1){
450 //joints[i].velocity*=3;
452 if(findLengthfast(&bounceness)>500)Sprite::MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, 1,1,1, .5, .2);
453 joints[i].position=(temp-*coords)/(*scale)+terrainnormal*.005;
454 if(longdead>100)broken=1;
458 joints[i].realoldposition=joints[i].position*(*scale)+*coords;
464 if(terrain.patchobjectnum[whichpatchx][whichpatchz])
465 for(m=0;m<terrain.patchobjectnum[whichpatchx][whichpatchz];m++){
466 k=terrain.patchobjects[whichpatchx][whichpatchz][m];
467 if(objects.possible[k]){
469 //Make this less stupid
470 start=joints[jointlabels[whichjointstartarray[i]]].position*(*scale)+*coords;
471 end=joints[jointlabels[whichjointendarray[i]]].position*(*scale)+*coords;
472 whichhit=objects.model[k].LineCheckSlidePossible(&start,&end,&temp,&objects.position[k],&objects.yaw[k]);
474 joints[jointlabels[whichjointendarray[i]]].position=(end-*coords)/(*scale);
475 for(j=0; j<num_muscles; j++){
476 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]))
477 muscles[j].DoConstraint(spinny);
484 for(i=0; i<num_joints; i++){
486 if(joints[i].label==head)groundlevel=.8;
487 if(joints[i].label==righthand||joints[i].label==rightwrist||joints[i].label==rightelbow)groundlevel=.2;
488 if(joints[i].label==lefthand||joints[i].label==leftwrist||joints[i].label==leftelbow)groundlevel=.2;
489 joints[i].position.y+=groundlevel;
491 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;
492 if(joints[i].locked){
500 for(i=0; i<num_muscles; i++){
501 if(muscles[i].type==boneconnect)
502 muscles[i].DoConstraint(0);
508 void Skeleton::DoGravity(float *scale)
511 for(i=0; i<num_joints; i++){
512 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);
516 void Skeleton::Draw(int muscleview)
518 static float jointcolor[4];
533 //Calc motionblur-ness
534 for(int i=0; i<num_joints; i++){
535 joints[i].oldposition=joints[i].position;
536 joints[i].blurred=findDistance(&joints[i].position,&joints[i].oldposition)*100;
537 if(joints[i].blurred<1)joints[i].blurred=1;
543 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
545 for(int i=0; i<num_joints; i++){
546 if(joints[i].hasparent){
547 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].blurred);
548 glVertex3f(joints[i].position.x,joints[i].position.y,joints[i].position.z);
549 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].parent->blurred);
550 glVertex3f(joints[i].parent->position.x,joints[i].parent->position.y,joints[i].parent->position.z);
551 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].parent->blurred);
552 glVertex3f(joints[i].parent->oldposition.x,joints[i].parent->oldposition.y,joints[i].parent->oldposition.z);
553 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].blurred);
554 glVertex3f(joints[i].oldposition.x,joints[i].oldposition.y,joints[i].oldposition.z);
557 for(int i=0; i<num_muscles; i++){
558 if(muscles[i].type==boneconnect){
559 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent2->blurred);
560 glVertex3f(muscles[i].parent1->position.x,muscles[i].parent1->position.y,muscles[i].parent1->position.z);
561 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent2->blurred);
562 glVertex3f(muscles[i].parent2->position.x,muscles[i].parent2->position.y,muscles[i].parent2->position.z);
563 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent2->blurred);
564 glVertex3f(muscles[i].parent2->oldposition.x,muscles[i].parent2->oldposition.y,muscles[i].parent2->oldposition.z);
565 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent1->blurred);
566 glVertex3f(muscles[i].parent1->oldposition.x,muscles[i].parent1->oldposition.y,muscles[i].parent1->oldposition.z);
572 for(int i=0; i<num_joints; i++){
573 if(joints[i].hasparent){
574 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].blurred);
575 glVertex3f(joints[i].position.x,joints[i].position.y,joints[i].position.z);
576 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].parent->blurred);
577 glVertex3f(joints[i].parent->position.x,joints[i].parent->position.y,joints[i].parent->position.z);
580 /*for(int i=0; i<num_joints; i++){
581 if(joints[i].hasparent){
582 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],1);
583 glVertex3f(joints[i].position.x,joints[i].position.y,joints[i].position.z);
584 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],1);
585 glVertex3f(joints[i].position.x+forward.x,joints[i].position.y+forward.y,joints[i].position.z+forward.z);
588 for(int i=0; i<num_muscles; i++){
589 if(muscles[i].type==boneconnect){
590 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent1->blurred);
591 glVertex3f(muscles[i].parent1->position.x,muscles[i].parent1->position.y,muscles[i].parent1->position.z);
592 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent2->blurred);
593 glVertex3f(muscles[i].parent2->position.x,muscles[i].parent2->position.y,muscles[i].parent2->position.z);
598 for(int i=0; i<num_muscles; i++){
599 if(muscles[i].type!=boneconnect){
600 glVertex3f(muscles[i].parent1->position.x,muscles[i].parent1->position.y,muscles[i].parent1->position.z);
601 glVertex3f(muscles[i].parent2->position.x,muscles[i].parent2->position.y,muscles[i].parent2->position.z);
609 for(int i=0; i<num_joints; i++){
610 if(i!=selected)glColor4f(0,0,.5,1);
611 if(i==selected)glColor4f(1,1,0,1);
612 if(joints[i].locked&&i!=selected)glColor4f(1,0,0,1);
613 glVertex3f(joints[i].position.x,joints[i].position.y,joints[i].position.z);
618 //Set old position to current position
620 for(int i=0; i<num_joints; i++){
621 joints[i].oldposition=joints[i].position;
626 void Skeleton::AddJoint(float x, float y, float z, int which)
628 if(num_joints<max_joints-1){
629 joints[num_joints].velocity=0;
630 joints[num_joints].position.x=x;
631 joints[num_joints].position.y=y;
632 joints[num_joints].position.z=z;
633 joints[num_joints].mass=1;
634 joints[num_joints].locked=0;
636 /*if(which>=num_joints||which<0)*/joints[num_joints].hasparent=0;
637 /*if(which<num_joints&&which>=0){
638 joints[num_joints].parent=&joints[which];
639 joints[num_joints].hasparent=1;
640 joints[num_joints].length=findDistance(joints[num_joints].position,joints[num_joints].parent->position);
643 if(which<num_joints&&which>=0)AddMuscle(num_joints-1,which,0,10,boneconnect);
647 void Skeleton::DeleteJoint(int whichjoint)
649 if(whichjoint<num_joints&&whichjoint>=0){
650 joints[whichjoint].velocity=joints[num_joints-1].velocity;
651 joints[whichjoint].position=joints[num_joints-1].position;
652 joints[whichjoint].oldposition=joints[num_joints-1].oldposition;
653 joints[whichjoint].hasparent=joints[num_joints-1].hasparent;
654 joints[whichjoint].parent=joints[num_joints-1].parent;
655 joints[whichjoint].length=joints[num_joints-1].length;
656 joints[whichjoint].locked=joints[num_joints-1].locked;
657 joints[whichjoint].modelnum=joints[num_joints-1].modelnum;
658 joints[whichjoint].visible=joints[num_joints-1].visible;
660 for(int i=0;i<num_muscles;i++){
661 while(muscles[i].parent1==&joints[whichjoint]&&i<num_muscles)DeleteMuscle(i);
662 while(muscles[i].parent2==&joints[whichjoint]&&i<num_muscles)DeleteMuscle(i);
664 for(int i=0;i<num_muscles;i++){
665 while(muscles[i].parent1==&joints[num_joints-1]&&i<num_muscles)muscles[i].parent1=&joints[whichjoint];
666 while(muscles[i].parent2==&joints[num_joints-1]&&i<num_muscles)muscles[i].parent2=&joints[whichjoint];
668 for(int i=0;i<num_joints;i++){
669 if(joints[i].parent==&joints[whichjoint])joints[i].hasparent=0;
671 for(int i=0;i<num_joints;i++){
672 if(joints[i].parent==&joints[num_joints-1])joints[i].parent=&joints[whichjoint];
679 void Skeleton::DeleteMuscle(int whichmuscle)
681 if(whichmuscle<num_muscles){
682 muscles[whichmuscle].minlength=muscles[num_muscles-1].minlength;
683 muscles[whichmuscle].maxlength=muscles[num_muscles-1].maxlength;
684 muscles[whichmuscle].strength=muscles[num_muscles-1].strength;
685 muscles[whichmuscle].parent1=muscles[num_muscles-1].parent1;
686 muscles[whichmuscle].parent2=muscles[num_muscles-1].parent2;
687 muscles[whichmuscle].length=muscles[num_muscles-1].length;
688 muscles[whichmuscle].visible=muscles[num_muscles-1].visible;
689 muscles[whichmuscle].type=muscles[num_muscles-1].type;
690 muscles[whichmuscle].targetlength=muscles[num_muscles-1].targetlength;
696 void Skeleton::SetJoint(float x, float y, float z, int which, int whichjoint)
698 if(whichjoint<num_joints){
699 joints[whichjoint].velocity=0;
700 joints[whichjoint].position.x=x;
701 joints[whichjoint].position.y=y;
702 joints[whichjoint].position.z=z;
704 if(which>=num_joints||which<0)joints[whichjoint].hasparent=0;
705 if(which<num_joints&&which>=0){
706 joints[whichjoint].parent=&joints[which];
707 joints[whichjoint].hasparent=1;
708 joints[whichjoint].length=findDistance(&joints[whichjoint].position,&joints[whichjoint].parent->position);
713 void Skeleton::AddMuscle(int attach1,int attach2,float minlength,float maxlength,int type)
715 const int max_muscles = 100; // FIXME: Probably can be dropped
716 if(num_muscles<max_muscles-1&&attach1<num_joints&&attach1>=0&&attach2<num_joints&&attach2>=0&&attach1!=attach2){
717 muscles[num_muscles].parent1=&joints[attach1];
718 muscles[num_muscles].parent2=&joints[attach2];
719 muscles[num_muscles].length=findDistance(&muscles[num_muscles].parent1->position,&muscles[num_muscles].parent2->position);
720 muscles[num_muscles].targetlength=findDistance(&muscles[num_muscles].parent1->position,&muscles[num_muscles].parent2->position);
721 muscles[num_muscles].strength=.7;
722 muscles[num_muscles].type=type;
723 muscles[num_muscles].minlength=minlength;
724 muscles[num_muscles].maxlength=maxlength;
730 void Skeleton::MusclesSet()
732 for(int i=0;i<num_muscles;i++){
733 muscles[i].length=findDistance(&muscles[i].parent1->position,&muscles[i].parent2->position);
737 void Skeleton::DoBalance()
740 newpoint=joints[0].position;
741 newpoint.x=(joints[2].position.x+joints[4].position.x)/2;
742 newpoint.z=(joints[2].position.z+joints[4].position.z)/2;
743 joints[0].velocity=joints[0].velocity+(newpoint-joints[0].position);
744 //Move child point to within certain distance of parent point
745 joints[0].position=newpoint;
750 void Skeleton::FindRotationMuscle(int which, int animation)
752 static XYZ temppoint1,temppoint2,tempforward;
753 static float distance;
755 temppoint1=muscles[which].parent1->position;
756 temppoint2=muscles[which].parent2->position;
757 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));
758 if((temppoint1.y-temppoint2.y)<=distance)muscles[which].rotate2=asin((temppoint1.y-temppoint2.y)/distance);
759 if((temppoint1.y-temppoint2.y)>distance)muscles[which].rotate2=asin(1.f);
760 muscles[which].rotate2*=360/6.28;
763 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));
764 if((temppoint1.z-temppoint2.z)<=distance)muscles[which].rotate1=acos((temppoint1.z-temppoint2.z)/distance);
765 if((temppoint1.z-temppoint2.z)>distance)muscles[which].rotate1=acos(1.f);
766 muscles[which].rotate1*=360/6.28;
767 if(temppoint1.x>temppoint2.x)muscles[which].rotate1=360-muscles[which].rotate1;
768 if(!isnormal(muscles[which].rotate1))muscles[which].rotate1=0;
769 if(!isnormal(muscles[which].rotate2))muscles[which].rotate2=0;
771 if(muscles[which].parent1->label==head)tempforward=specialforward[0];
772 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];
773 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];
774 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];
775 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];
776 else if(!muscles[which].parent1->lower)tempforward=forward;
777 else if(muscles[which].parent1->lower)tempforward=lowforward;
779 if(animation==hanganim){
780 if(muscles[which].parent1->label==righthand||muscles[which].parent2->label==righthand){
784 if(muscles[which].parent1->label==lefthand||muscles[which].parent2->label==lefthand){
791 if(muscles[which].parent1->label==rightfoot||muscles[which].parent2->label==rightfoot){
794 if(muscles[which].parent1->label==leftfoot||muscles[which].parent2->label==leftfoot){
800 tempforward=DoRotation(tempforward,0,muscles[which].rotate1-90,0);
801 tempforward=DoRotation(tempforward,0,0,muscles[which].rotate2-90);
803 tempforward/=sqrt(tempforward.x*tempforward.x+tempforward.y*tempforward.y+tempforward.z*tempforward.z);
804 if(tempforward.z<=1&&tempforward.z>=-1)muscles[which].rotate3=acos(0-tempforward.z);
805 else muscles[which].rotate3=acos(-1.f);
806 muscles[which].rotate3*=360/6.28;
807 if(0>tempforward.x)muscles[which].rotate3=360-muscles[which].rotate3;
808 if(!isnormal(muscles[which].rotate3))muscles[which].rotate3=0;
811 void Animation::Load(const char *filename, int aheight, int aattack)
815 static XYZ startoffset,endoffset;
818 static const char *anim_prefix = ":Data:Animations:";
823 int len = strlen(anim_prefix) + strlen(filename);
824 char *buf = new char[len + 1];
825 snprintf(buf, len + 1, "%s%s", anim_prefix, filename);
826 // Changing the filename into something the OS can understand
827 char *fixedFN = ConvertFileName(buf);
830 LOG(std::string("Loading animation...") + fixedFN);
837 if(visibleloading) Game::LoadingScreen();
839 tfile=fopen( fixedFN, "rb" );
841 funpackf(tfile, "Bi Bi", &numframes, &joints);
843 for(i = 0; i < joints; i++){
844 if(position[i])dealloc2(position[i]);
845 if(twist[i])dealloc2(twist[i]);
846 if(twist2[i])dealloc2(twist2[i]);
847 if(onground[i])dealloc2(onground[i]);
850 if(position)dealloc2(position);
851 if(twist)dealloc2(twist);
852 if(twist2)dealloc2(twist2);
853 if(speed)dealloc2(speed);
854 if(onground)dealloc2(onground);
855 if(forward)dealloc2(forward);
856 if(weapontarget)dealloc2(weapontarget);
857 if(label)dealloc2(label);*/
859 position=(XYZ**)malloc(sizeof(XYZ*)*joints);
860 for(i = 0; i < joints; i++)
861 position[i] = (XYZ*)malloc(sizeof(XYZ)*numframes);
863 twist=(float**)malloc(sizeof(float*)*joints);
864 for(i = 0; i < joints; i++)
865 twist[i] = (float*)malloc(sizeof(float)*numframes);
867 twist2=(float**)malloc(sizeof(float*)*joints);
868 for(i = 0; i < joints; i++)
869 twist2[i] = (float*)malloc(sizeof(float)*numframes);
871 speed = (float*)malloc(sizeof(float)*numframes);
873 onground=(bool**)malloc(sizeof(bool*)*joints);
874 for(i = 0; i < joints; i++)
875 onground[i] =(bool*)malloc(sizeof(bool)*numframes);
877 forward = (XYZ*)malloc(sizeof(XYZ)*numframes);
878 weapontarget = (XYZ*)malloc(sizeof(XYZ)*numframes);
879 label = (int*)malloc(sizeof(int)*numframes);
881 /*position = new XYZ[joints][numframes];
882 twist = new float[joints][numframes];
883 twist2 = new float[joints][numframes];
884 speed = new float[numframes];
885 onground = new bool[joints][numframes];
886 forward = new XYZ[numframes];
887 label = new int[numframes];*/
889 for(i=0;i<numframes;i++){
890 for(j=0;j<joints;j++){
891 funpackf(tfile, "Bf Bf Bf", &position[j][i].x,&position[j][i].y,&position[j][i].z);
893 for(j=0;j<joints;j++){
894 funpackf(tfile, "Bf", &twist[j][i]);
896 for(j=0;j<joints;j++){
898 funpackf(tfile, "Bb", &uch);
899 onground[j][i] = (uch != 0);
901 funpackf(tfile, "Bf", &speed[i]);
903 for(i=0;i<numframes;i++){
904 for(j=0;j<joints;j++){
905 funpackf(tfile, "Bf", &twist2[j][i]);
908 for(i=0;i<numframes;i++){
909 funpackf(tfile, "Bf", &label[i]);
911 funpackf(tfile, "Bi", &weapontargetnum);
912 for(i=0;i<numframes;i++){
913 funpackf(tfile, "Bf Bf Bf", &weapontarget[i].x,&weapontarget[i].y,&weapontarget[i].z);
922 for(j=0;j<joints;j++){
923 if(position[j][0].y<1)
924 startoffset+=position[j][0];
925 if(position[j][numframes-1].y<1)
926 endoffset+=position[j][numframes-1];
929 startoffset/=howmany;
936 void Animation::Move(XYZ how)
938 static int i,j,joints;
939 for(i=0;i<numframes;i++){
940 for(j=0;j<joints;j++){
946 void Skeleton::Load(const char *filename, const char *lowfilename, const char *clothesfilename,
947 const char *modelfilename, const char *model2filename,
948 const char *model3filename, const char *model4filename,
949 const char *model5filename, const char *model6filename,
950 const char *model7filename, const char *modellowfilename,
951 const char *modelclothesfilename, bool aclothes)
953 static GLfloat M[16];
957 static int i,j,tempmuscle;
970 for(i=0;i<num_models;i++){
971 if(i==0)model[i].loadnotex(modelfilename);
972 if(i==1)model[i].loadnotex(model2filename);
973 if(i==2)model[i].loadnotex(model3filename);
974 if(i==3)model[i].loadnotex(model4filename);
975 if(i==4)model[i].loadnotex(model5filename);
976 if(i==5)model[i].loadnotex(model6filename);
977 if(i==6)model[i].loadnotex(model7filename);
978 model[i].Rotate(180,0,0);
979 model[i].Scale(.04,.04,.04);
980 model[i].CalculateNormals(0);
983 drawmodel.load(modelfilename,0);
984 drawmodel.Rotate(180,0,0);
985 drawmodel.Scale(.04,.04,.04);
986 drawmodel.FlipTexCoords();
987 if(tutoriallevel==1&&id!=0)drawmodel.UniformTexCoords();
988 if(tutoriallevel==1&&id!=0)drawmodel.ScaleTexCoords(0.1);
989 drawmodel.CalculateNormals(0);
991 modellow.loadnotex(modellowfilename);
992 modellow.Rotate(180,0,0);
993 modellow.Scale(.04,.04,.04);
994 modellow.CalculateNormals(0);
996 drawmodellow.load(modellowfilename,0);
997 drawmodellow.Rotate(180,0,0);
998 drawmodellow.Scale(.04,.04,.04);
999 drawmodellow.FlipTexCoords();
1000 if(tutoriallevel==1&&id!=0)drawmodellow.UniformTexCoords();
1001 if(tutoriallevel==1&&id!=0)drawmodellow.ScaleTexCoords(0.1);
1002 drawmodellow.CalculateNormals(0);
1005 modelclothes.loadnotex(modelclothesfilename);
1006 modelclothes.Rotate(180,0,0);
1007 modelclothes.Scale(.041,.04,.041);
1008 modelclothes.CalculateNormals(0);
1010 drawmodelclothes.load(modelclothesfilename,0);
1011 drawmodelclothes.Rotate(180,0,0);
1012 drawmodelclothes.Scale(.04,.04,.04);
1013 drawmodelclothes.FlipTexCoords();
1014 drawmodelclothes.CalculateNormals(0);
1017 tfile=fopen( ConvertFileName(filename), "rb" );
1019 funpackf(tfile, "Bi", &num_joints);
1020 //joints.resize(num_joints);
1021 if(joints) delete [] joints; //dealloc2(joints);
1022 joints=(Joint*)new Joint[num_joints]; //malloc(sizeof(Joint)*num_joints);
1024 for(i=0;i<num_joints;i++){
1025 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);
1026 funpackf(tfile, "Bb Bb", &joints[i].hasparent,&joints[i].locked);
1027 funpackf(tfile, "Bi", &joints[i].modelnum);
1028 funpackf(tfile, "Bb Bb", &joints[i].visible,&joints[i].sametwist);
1029 funpackf(tfile, "Bi Bi", &joints[i].label,&joints[i].hasgun);
1030 funpackf(tfile, "Bb", &joints[i].lower);
1031 funpackf(tfile, "Bi", &parentID);
1032 if(joints[i].hasparent)joints[i].parent=&joints[parentID];
1033 joints[i].velocity=0;
1034 joints[i].oldposition=joints[i].position;
1036 tempmuscle=num_muscles;
1037 funpackf(tfile, "Bi", &num_muscles);
1039 if(muscles) delete [] muscles; //dealloc2(muscles);
1040 muscles=(Muscle*)new Muscle[num_muscles]; //malloc(sizeof(Muscle)*num_muscles);
1042 for(i=0;i<num_muscles;i++){
1043 tempmuscle=muscles[i].numvertices;
1044 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);
1045 //muscles[i].vertices.clear();
1046 //muscles[i].vertices.resize(muscles[i].numvertices);
1047 //if(muscles[i].vertices)dealloc2(muscles[i].vertices);
1048 muscles[i].vertices=(int*)malloc(sizeof(int)*muscles[i].numvertices);
1051 for(j=0;j<muscles[i].numvertices-edit;j++){
1052 funpackf(tfile, "Bi", &muscles[i].vertices[j+edit]);
1053 if(muscles[i].vertices[j+edit]>=model[0].vertexNum){
1054 muscles[i].numvertices--;
1058 funpackf(tfile, "Bb Bi", &muscles[i].visible, &parentID);
1059 muscles[i].parent1=&joints[parentID];
1060 funpackf(tfile, "Bi", &parentID);
1061 muscles[i].parent2=&joints[parentID];
1064 funpackf(tfile, "Bi", &forwardjoints[j]);
1067 funpackf(tfile, "Bi", &lowforwardjoints[j]);
1069 for(j=0;j<num_muscles;j++){
1070 for(i=0;i<muscles[j].numvertices;i++){
1071 for(int k=0;k<num_models;k++){
1072 if(muscles[j].numvertices&&muscles[j].vertices[i]<model[k].vertexNum)model[k].owner[muscles[j].vertices[i]]=j;
1077 for(i=0;i<num_joints;i++){
1078 joints[i].startpos=joints[i].position;
1080 for(i=0;i<num_muscles;i++){
1081 FindRotationMuscle(i,-1);
1083 for(int k=0;k<num_models;k++){
1084 for(i=0;i<model[k].vertexNum;i++){
1085 model[k].vertex[i]=model[k].vertex[i]-(muscles[model[k].owner[i]].parent1->position+muscles[model[k].owner[i]].parent2->position)/2;
1086 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
1089 glRotatef(muscles[model[k].owner[i]].rotate3,0,1,0);
1090 glRotatef(muscles[model[k].owner[i]].rotate2-90,0,0,1);
1091 glRotatef(muscles[model[k].owner[i]].rotate1-90,0,1,0);
1092 glTranslatef(model[k].vertex[i].x,model[k].vertex[i].y,model[k].vertex[i].z);
1093 glGetFloatv(GL_MODELVIEW_MATRIX,M);
1094 model[k].vertex[i].x=M[12]*1;
1095 model[k].vertex[i].y=M[13]*1;
1096 model[k].vertex[i].z=M[14]*1;
1099 model[k].CalculateNormals(0);
1104 tfile=fopen( ConvertFileName(lowfilename), "rb" );
1106 lSize=sizeof(num_joints);
1107 fseek ( tfile, lSize, SEEK_CUR);
1108 //joints = new Joint[num_joints];
1109 //jointlabels = new int[num_joints];
1110 for(i=0;i<num_joints;i++){
1112 fseek ( tfile, lSize, SEEK_CUR);
1113 lSize=sizeof(float);
1114 fseek ( tfile, lSize, SEEK_CUR);
1115 lSize=sizeof(float);
1116 fseek ( tfile, lSize, SEEK_CUR);
1117 lSize=1;//sizeof(bool);
1118 fseek ( tfile, lSize, SEEK_CUR);
1119 lSize=1;//sizeof(bool);
1120 fseek ( tfile, lSize, SEEK_CUR);
1122 fseek ( tfile, lSize, SEEK_CUR);
1123 lSize=1;//sizeof(bool);
1124 fseek ( tfile, lSize, SEEK_CUR);
1125 lSize=1;//sizeof(bool);
1126 fseek ( tfile, lSize, SEEK_CUR);
1128 fseek ( tfile, lSize, SEEK_CUR);
1130 fseek ( tfile, lSize, SEEK_CUR);
1131 lSize=1;//sizeof(bool);
1132 fseek ( tfile, lSize, SEEK_CUR);
1134 fseek ( tfile, lSize, SEEK_CUR);
1135 if(joints[i].hasparent)joints[i].parent=&joints[parentID];
1136 joints[i].velocity=0;
1137 joints[i].oldposition=joints[i].position;
1139 funpackf(tfile, "Bi", &num_muscles);
1140 //muscles = new Muscle[num_muscles];
1141 for(i=0;i<num_muscles;i++){
1142 lSize=sizeof(float);
1143 fseek ( tfile, lSize, SEEK_CUR);
1144 lSize=sizeof(float);
1145 fseek ( tfile, lSize, SEEK_CUR);
1146 lSize=sizeof(float);
1147 fseek ( tfile, lSize, SEEK_CUR);
1148 lSize=sizeof(float);
1149 fseek ( tfile, lSize, SEEK_CUR);
1150 lSize=sizeof(float);
1151 fseek ( tfile, lSize, SEEK_CUR);
1153 fseek ( tfile, lSize, SEEK_CUR);
1154 tempmuscle=muscles[i].numverticeslow;
1155 funpackf(tfile, "Bi", &muscles[i].numverticeslow);
1156 if(muscles[i].numverticeslow){
1157 //muscles[i].verticeslow.clear();
1158 //muscles[i].verticeslow.resize(muscles[i].numverticeslow);
1159 //if(muscles[i].verticeslow)dealloc2(muscles[i].verticeslow);
1160 muscles[i].verticeslow=(int*)malloc(sizeof(int)*muscles[i].numverticeslow);
1162 for(j=0;j<muscles[i].numverticeslow-edit;j++){
1163 funpackf(tfile, "Bi", &muscles[i].verticeslow[j+edit]);
1164 if(muscles[i].verticeslow[j+edit]>=modellow.vertexNum){
1165 muscles[i].numverticeslow--;
1172 lSize=1;//sizeof(bool);
1173 fseek ( tfile, lSize, SEEK_CUR);
1175 fseek ( tfile, lSize, SEEK_CUR);
1176 fseek ( tfile, lSize, SEEK_CUR);
1179 for(j=0;j<num_muscles;j++){
1180 for(i=0;i<muscles[j].numverticeslow;i++){
1181 if(muscles[j].numverticeslow&&muscles[j].verticeslow[i]<modellow.vertexNum)modellow.owner[muscles[j].verticeslow[i]]=j;
1185 for(i=0;i<num_joints;i++){
1186 joints[i].startpos=joints[i].position;
1188 for(i=0;i<num_muscles;i++){
1189 FindRotationMuscle(i,-1);
1191 for(i=0;i<modellow.vertexNum;i++){
1192 modellow.vertex[i]=modellow.vertex[i]-(muscles[modellow.owner[i]].parent1->position+muscles[modellow.owner[i]].parent2->position)/2;
1193 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
1196 glRotatef(muscles[modellow.owner[i]].rotate3,0,1,0);
1197 glRotatef(muscles[modellow.owner[i]].rotate2-90,0,0,1);
1198 glRotatef(muscles[modellow.owner[i]].rotate1-90,0,1,0);
1199 glTranslatef(modellow.vertex[i].x,modellow.vertex[i].y,modellow.vertex[i].z);
1200 glGetFloatv(GL_MODELVIEW_MATRIX,M);
1201 modellow.vertex[i].x=M[12];
1202 modellow.vertex[i].y=M[13];
1203 modellow.vertex[i].z=M[14];
1206 modellow.CalculateNormals(0);
1210 tfile=fopen( ConvertFileName(clothesfilename), "rb" );
1211 lSize=sizeof(num_joints);
1212 fseek ( tfile, lSize, SEEK_CUR);
1213 //joints = new Joint[num_joints];
1214 //jointlabels = new int[num_joints];
1215 for(i=0;i<num_joints;i++){
1217 fseek ( tfile, lSize, SEEK_CUR);
1218 lSize=sizeof(float);
1219 fseek ( tfile, lSize, SEEK_CUR);
1220 lSize=sizeof(float);
1221 fseek ( tfile, lSize, SEEK_CUR);
1222 lSize=1;//sizeof(bool);
1223 fseek ( tfile, lSize, SEEK_CUR);
1224 lSize=1;//sizeof(bool);
1225 fseek ( tfile, lSize, SEEK_CUR);
1227 fseek ( tfile, lSize, SEEK_CUR);
1228 lSize=1;//sizeof(bool);
1229 fseek ( tfile, lSize, SEEK_CUR);
1230 lSize=1;//sizeof(bool);
1231 fseek ( tfile, lSize, SEEK_CUR);
1233 fseek ( tfile, lSize, SEEK_CUR);
1235 fseek ( tfile, lSize, SEEK_CUR);
1236 lSize=1;//sizeof(bool);
1237 fseek ( tfile, lSize, SEEK_CUR);
1239 fseek ( tfile, lSize, SEEK_CUR);
1240 if(joints[i].hasparent)joints[i].parent=&joints[parentID];
1241 joints[i].velocity=0;
1242 joints[i].oldposition=joints[i].position;
1244 funpackf(tfile, "Bi", &num_muscles);
1245 //muscles = new Muscle[num_muscles];
1246 for(i=0;i<num_muscles;i++){
1247 lSize=sizeof(float);
1248 fseek ( tfile, lSize, SEEK_CUR);
1249 lSize=sizeof(float);
1250 fseek ( tfile, lSize, SEEK_CUR);
1251 lSize=sizeof(float);
1252 fseek ( tfile, lSize, SEEK_CUR);
1253 lSize=sizeof(float);
1254 fseek ( tfile, lSize, SEEK_CUR);
1255 lSize=sizeof(float);
1256 fseek ( tfile, lSize, SEEK_CUR);
1258 fseek ( tfile, lSize, SEEK_CUR);
1259 tempmuscle=muscles[i].numverticesclothes;
1260 funpackf(tfile, "Bi", &muscles[i].numverticesclothes);
1261 if(muscles[i].numverticesclothes){
1262 //muscles[i].verticesclothes.clear();
1263 //muscles[i].verticesclothes.resize(muscles[i].numverticesclothes);
1264 //if(muscles[i].verticesclothes)dealloc2(muscles[i].verticesclothes);
1265 muscles[i].verticesclothes=(int*)malloc(sizeof(int)*muscles[i].numverticesclothes);
1267 for(j=0;j<muscles[i].numverticesclothes-edit;j++){
1268 funpackf(tfile, "Bi", &muscles[i].verticesclothes[j+edit]);
1269 if(muscles[i].verticesclothes[j+edit]>=modelclothes.vertexNum){
1270 muscles[i].numverticesclothes--;
1275 lSize=1;//sizeof(bool);
1276 fseek ( tfile, lSize, SEEK_CUR);
1278 fseek ( tfile, lSize, SEEK_CUR);
1279 fseek ( tfile, lSize, SEEK_CUR);
1282 for(j=0;j<num_muscles;j++){
1283 for(i=0;i<muscles[j].numverticesclothes;i++){
1284 if(muscles[j].numverticesclothes&&muscles[j].verticesclothes[i]<modelclothes.vertexNum)modelclothes.owner[muscles[j].verticesclothes[i]]=j;
1288 for(i=0;i<num_joints;i++){
1289 joints[i].startpos=joints[i].position;
1291 for(i=0;i<num_muscles;i++){
1292 FindRotationMuscle(i,-1);
1294 for(i=0;i<modelclothes.vertexNum;i++){
1295 modelclothes.vertex[i]=modelclothes.vertex[i]-(muscles[modelclothes.owner[i]].parent1->position+muscles[modelclothes.owner[i]].parent2->position)/2;
1296 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
1299 glRotatef(muscles[modelclothes.owner[i]].rotate3,0,1,0);
1300 glRotatef(muscles[modelclothes.owner[i]].rotate2-90,0,0,1);
1301 glRotatef(muscles[modelclothes.owner[i]].rotate1-90,0,1,0);
1302 glTranslatef(modelclothes.vertex[i].x,modelclothes.vertex[i].y,modelclothes.vertex[i].z);
1303 glGetFloatv(GL_MODELVIEW_MATRIX,M);
1304 modelclothes.vertex[i].x=M[12];
1305 modelclothes.vertex[i].y=M[13];
1306 modelclothes.vertex[i].z=M[14];
1309 modelclothes.CalculateNormals(0);
1313 for(i=0;i<num_joints;i++){
1314 for(j=0;j<num_joints;j++){
1315 if(joints[i].label==j)jointlabels[j]=i;
1322 Animation::Animation()
1328 weapontargetnum = 0;
1340 Animation::~Animation()
1345 void Animation::deallocate()
1351 for(i = 0; i < joints; i++)
1352 dealloc2(position[i]);
1360 for(i = 0; i < joints; i++)
1369 for(i = 0; i < joints; i++)
1370 dealloc2(twist2[i]);
1378 for(i = 0; i < joints; i++)
1379 dealloc2(onground[i]);
1385 if(speed)dealloc2(speed);
1388 if(forward)dealloc2(forward);
1391 if(weapontarget)dealloc2(weapontarget);
1394 if(label)dealloc2(label);
1400 Skeleton::Skeleton()
1408 memset(forwardjoints, 0, sizeof(forwardjoints));
1413 memset(lowforwardjoints, 0, sizeof(lowforwardjoints));
1416 // XYZ specialforward[5];
1417 memset(jointlabels, 0, sizeof(jointlabels));
1421 // Model modelclothes;
1425 // Model drawmodellow;
1426 // Model drawmodelclothes;
1431 memset(skinText, 0, sizeof(skinText));
1448 Skeleton::~Skeleton()
1471 numverticesclothes = 0;
1480 rotate1 = 0,rotate2 = 0,rotate3 = 0;
1481 lastrotate1 = 0,lastrotate2 = 0,lastrotate3 = 0;
1482 oldrotate1 = 0,oldrotate2 = 0,oldrotate3 = 0;
1483 newrotate1 = 0,newrotate2 = 0,newrotate3 = 0;
1491 dealloc2(verticeslow);
1492 dealloc2(verticesclothes);
1495 Animation & Animation::operator = (const Animation & ani)
1499 bool allocate = true;
1501 allocate = ((ani.numframes != numframes) || (ani.joints != joints));
1503 if (allocate) deallocate();
1505 numframes = ani.numframes;
1506 height = ani.height;
1507 attack = ani.attack;
1508 joints = ani.joints;
1509 weapontargetnum = ani.weapontargetnum;
1511 if (allocate) position=(XYZ**)malloc(sizeof(XYZ*)*ani.joints);
1512 for(i = 0; i < ani.joints; i++)
1514 if (allocate) position[i] = (XYZ*)malloc(sizeof(XYZ)*ani.numframes);
1515 memcpy(position[i], ani.position[i], sizeof(XYZ)*ani.numframes);
1518 if (allocate) twist=(float**)malloc(sizeof(float*)*ani.joints);
1519 for(i = 0; i < ani.joints; i++)
1521 if (allocate) twist[i] = (float*)malloc(sizeof(float)*ani.numframes);
1522 memcpy(twist[i], ani.twist[i], sizeof(float)*ani.numframes);
1525 if (allocate) twist2=(float**)malloc(sizeof(float*)*ani.joints);
1526 for(i = 0; i < ani.joints; i++)
1528 if (allocate) twist2[i] = (float*)malloc(sizeof(float)*ani.numframes);
1529 memcpy(twist2[i], ani.twist2[i], sizeof(float)*ani.numframes);
1532 if (allocate) speed = (float*)malloc(sizeof(float)*ani.numframes);
1533 memcpy(speed, ani.speed, sizeof(float)*ani.numframes);
1535 if (allocate) onground=(bool**)malloc(sizeof(bool*)*ani.joints);
1536 for(i = 0; i < ani.joints; i++)
1538 if (allocate) onground[i] =(bool*)malloc(sizeof(bool)*ani.numframes);
1539 memcpy(onground[i], ani.onground[i], sizeof(bool)*ani.numframes);
1542 if (allocate) forward = (XYZ*)malloc(sizeof(XYZ)*ani.numframes);
1543 memcpy(forward, ani.forward, sizeof(XYZ)*ani.numframes);
1545 if (allocate) weapontarget = (XYZ*)malloc(sizeof(XYZ)*ani.numframes);
1546 memcpy(weapontarget, ani.weapontarget, sizeof(XYZ)*ani.numframes);
1548 if (allocate) label = (int*)malloc(sizeof(int)*ani.numframes);
1549 memcpy(label, ani.label, sizeof(int)*ani.numframes);