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)
54 enum {boneconnect, constraint, muscle};
56 void Muscle::DoConstraint(bool spinny)
60 static XYZ newpoint1, newpoint2;
62 static float oldlength;
63 static float relaxlength;
67 if (type != boneconnect)
68 relaxlength = findDistance(&parent1->position, &parent2->position);
70 if (type == boneconnect)
72 if (type == constraint)
80 length -= (length - relaxlength) * (1 - strength) * multiplier * 10000;
81 length -= (length - targetlength) * (strength) * multiplier * 10000;
85 if ((relaxlength - length > 0 && relaxlength - oldlength < 0) || (relaxlength - length < 0 && relaxlength - oldlength > 0))
89 if (length < minlength)
91 if (length > maxlength)
96 if(length<minlength*.6)length=minlength*.6;
97 if(length>maxlength*1.4)length=maxlength*1.4;
100 if (length == relaxlength)
104 midp = (parent1->position * parent1->mass + parent2->position * parent2->mass) / (parent1->mass + parent2->mass);
105 //Find vector from midpoint to second vector
106 vel = parent2->position - midp;
107 //Change to unit vector
109 //Apply velocity change
110 newpoint1 = midp - vel * length * (parent2->mass / (parent1->mass + parent2->mass));
111 newpoint2 = midp + vel * length * (parent1->mass / (parent1->mass + parent2->mass));
112 if (!freeze && spinny) {
113 parent1->velocity = parent1->velocity + (newpoint1 - parent1->position) / multiplier / 4;
114 parent2->velocity = parent2->velocity + (newpoint2 - parent2->position) / multiplier / 4;
116 parent1->velocity = parent1->velocity + (newpoint1 - parent1->position);
117 parent2->velocity = parent2->velocity + (newpoint2 - parent2->position);
119 //Move child point to within certain distance of parent point
120 parent1->position = newpoint1;
121 parent2->position = newpoint2;
124 void Skeleton::FindForwardsfirst()
126 //Find forward vectors
127 CrossProduct(joints[forwardjoints[1]].position - joints[forwardjoints[0]].position, joints[forwardjoints[2]].position - joints[forwardjoints[0]].position, &forward);
130 CrossProduct(joints[lowforwardjoints[1]].position - joints[lowforwardjoints[0]].position, joints[lowforwardjoints[2]].position - joints[lowforwardjoints[0]].position, &lowforward);
131 Normalise(&lowforward);
134 specialforward[0] = forward;
135 specialforward[1] = forward;
136 specialforward[2] = forward;
137 specialforward[3] = forward;
138 specialforward[4] = forward;
141 void Skeleton::FindForwards()
143 //Find forward vectors
144 CrossProduct(joints[forwardjoints[1]].position - joints[forwardjoints[0]].position, joints[forwardjoints[2]].position - joints[forwardjoints[0]].position, &forward);
147 CrossProduct(joints[lowforwardjoints[1]].position - joints[lowforwardjoints[0]].position, joints[lowforwardjoints[2]].position - joints[lowforwardjoints[0]].position, &lowforward);
148 Normalise(&lowforward);
151 specialforward[0] = forward;
153 specialforward[1] = joints[jointlabels[rightshoulder]].position + joints[jointlabels[rightwrist]].position;
154 specialforward[1] = joints[jointlabels[rightelbow]].position - specialforward[1] / 2;
155 specialforward[1] += forward * .4;
156 Normalise(&specialforward[1]);
157 specialforward[2] = joints[jointlabels[leftshoulder]].position + joints[jointlabels[leftwrist]].position;
158 specialforward[2] = joints[jointlabels[leftelbow]].position - specialforward[2] / 2;
159 specialforward[2] += forward * .4;
160 Normalise(&specialforward[2]);
162 specialforward[3] = joints[jointlabels[righthip]].position + joints[jointlabels[rightankle]].position;
163 specialforward[3] = specialforward[3] / 2 - joints[jointlabels[rightknee]].position;
164 specialforward[3] += lowforward * .4;
165 Normalise(&specialforward[3]);
166 specialforward[4] = joints[jointlabels[lefthip]].position + joints[jointlabels[leftankle]].position;
167 specialforward[4] = specialforward[4] / 2 - joints[jointlabels[leftknee]].position;
168 specialforward[4] += lowforward * .4;
169 Normalise(&specialforward[4]);
172 float Skeleton::DoConstraints(XYZ *coords, float *scale)
174 static float friction = 1.5;
175 static float elasticity = .3;
176 static XYZ bounceness;
177 static XYZ oldpos[100];
178 static int numrepeats = 3;
179 static float groundlevel = .15;
180 static float soundvolume;
181 static int i, j, k, l, m;
182 static XYZ temp, start, end;
183 static XYZ terrainnormal;
184 static float r = .05;
185 static float r2 = .08;
187 //static int whichjointstart,whichjointend;
188 static float distance;
189 static float frictionness;
190 static XYZ terrainlight;
191 static int whichpatchx;
192 static int whichpatchz;
195 static float tempmult;
196 static bool breaking;
202 freetime += multiplier;
204 whichpatchx = coords->x / (terrain.size / subdivision * terrain.scale);
205 whichpatchz = coords->z / (terrain.size / subdivision * terrain.scale);
207 terrainlight = *coords;
208 objects.SphereCheckPossible(&terrainlight, 1);
210 for(i=0; i<num_joints; i++){
211 oldpos[i]=joints[i].position;
215 for (i = 0; i < num_joints; i++) {
216 //if(!isnormal(joints[i].velocity.x)||!isnormal(joints[i].velocity.y)||!isnormal(joints[i].velocity.z))joints[i].velocity=0;
217 joints[i].position = joints[i].position + joints[i].velocity * multiplier;
219 if (joints[i].label == head)
221 if (joints[i].label == righthand || joints[i].label == rightwrist || joints[i].label == rightelbow)
223 if (joints[i].label == lefthand || joints[i].label == leftwrist || joints[i].label == leftelbow)
225 joints[i].position.y -= groundlevel;
226 //if(!joints[i].locked&&!broken)joints[i].velocity+=joints[i].velchange*multiplier*10*(500-longdead)/500;
227 joints[i].oldvelocity = joints[i].velocity;
229 tempmult = multiplier;
230 //multiplier/=numrepeats;
231 for (j = 0; j < numrepeats; j++) {
232 if (!joints[jointlabels[rightknee]].locked && !joints[jointlabels[righthip]].locked) {
233 temp = joints[jointlabels[rightknee]].position - (joints[jointlabels[righthip]].position + joints[jointlabels[rightankle]].position) / 2;
234 while (normaldotproduct(temp, lowforward) > -.1 && !sphere_line_intersection(&joints[jointlabels[righthip]].position, &joints[jointlabels[rightankle]].position, &joints[jointlabels[rightknee]].position, &r)) {
235 joints[jointlabels[rightknee]].position -= lowforward * .05;
237 joints[jointlabels[rightknee]].velocity -= lowforward * .05 / multiplier / 4;
239 joints[jointlabels[rightknee]].velocity -= lowforward * .05;
240 joints[jointlabels[rightankle]].position += lowforward * .025;
242 joints[jointlabels[rightankle]].velocity += lowforward * .025 / multiplier / 4;
244 joints[jointlabels[rightankle]].velocity += lowforward * .25;
245 joints[jointlabels[righthip]].position += lowforward * .025;
247 joints[jointlabels[righthip]].velocity += lowforward * .025 / multiplier / 4;
249 joints[jointlabels[righthip]].velocity += lowforward * .025;
250 temp = joints[jointlabels[rightknee]].position - (joints[jointlabels[righthip]].position + joints[jointlabels[rightankle]].position) / 2;
253 if (!joints[jointlabels[leftknee]].locked && !joints[jointlabels[righthip]].locked) {
254 temp = joints[jointlabels[leftknee]].position - (joints[jointlabels[lefthip]].position + joints[jointlabels[leftankle]].position) / 2;
255 while (normaldotproduct(temp, lowforward) > -.1 && !sphere_line_intersection(&joints[jointlabels[lefthip]].position, &joints[jointlabels[leftankle]].position, &joints[jointlabels[leftknee]].position, &r)) {
256 joints[jointlabels[leftknee]].position -= lowforward * .05;
258 joints[jointlabels[leftknee]].velocity -= lowforward * .05 / multiplier / 4;
260 joints[jointlabels[leftknee]].velocity -= lowforward * .05;
261 joints[jointlabels[leftankle]].position += lowforward * .025;
263 joints[jointlabels[leftankle]].velocity += lowforward * .025 / multiplier / 4;
265 joints[jointlabels[leftankle]].velocity += lowforward * .25;
266 joints[jointlabels[lefthip]].position += lowforward * .025;
268 joints[jointlabels[lefthip]].velocity += lowforward * .025 / multiplier / 4;
270 joints[jointlabels[lefthip]].velocity += lowforward * .025;
271 temp = joints[jointlabels[leftknee]].position - (joints[jointlabels[lefthip]].position + joints[jointlabels[leftankle]].position) / 2;
275 for (i = 0; i < num_joints; i++) {
276 //joints[i].delay-=multiplier/1.5;
277 if (joints[i].locked)
279 if (findLengthfast(&joints[i].velocity) > 320)
280 joints[i].locked = 0;
282 if (findLengthfast(&joints[i].velocity) > 600)
283 joints[i].locked = 0;
284 if (joints[i].delay > 0) {
286 for (j = 0; j < num_joints; j++) {
287 if (joints[j].locked)
291 joints[i].delay -= multiplier * 3;
293 //if(joints[i].delay>0)
294 //if(findLengthfast(&joints[i].velocity)>700&&joints[i].label!=head)joints[i].delay-=multiplier;
298 for (i = 0; i < num_muscles; i++) {
300 //muscles[i].DoConstraint(broken);
301 muscles[i].DoConstraint(spinny);
304 for (i = 0; i < num_joints; i++) {
305 //joints[i].delay-=multiplier/1.5;
309 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) {
312 if (joints[i].label == groin && !joints[i].locked && joints[i].delay <= 0) {
313 joints[i].locked = 1;
315 if (tutoriallevel != 1 || id == 0) {
316 emit_sound_at(landsound1, joints[i].position * (*scale) + *coords, 128.);
321 if (joints[i].label == head && !joints[i].locked && joints[i].delay <= 0) {
322 joints[i].locked = 1;
324 if (tutoriallevel != 1 || id == 0) {
325 emit_sound_at(landsound2, joints[i].position * (*scale) + *coords, 128.);
329 terrainnormal = terrain.getNormal(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z);
330 ReflectVector(&joints[i].velocity, &terrainnormal);
331 bounceness = terrainnormal * findLength(&joints[i].velocity) * (abs(normaldotproduct(joints[i].velocity, terrainnormal)));
332 if (!joints[i].locked)
333 damage += findLengthfast(&bounceness) / 4000;
334 if (findLengthfast(&joints[i].velocity) < findLengthfast(&bounceness))
336 frictionness = abs(normaldotproduct(joints[i].velocity, terrainnormal)); //findLength(&bounceness)/findLength(&joints[i].velocity);
337 joints[i].velocity -= bounceness;
338 if (1 - friction * frictionness > 0)
339 joints[i].velocity *= 1 - friction * frictionness;
341 joints[i].velocity = 0;
343 if (tutoriallevel != 1 || id == 0)
344 if (findLengthfast(&bounceness) > 8000 && breaking) {
345 objects.model[k].MakeDecal(breakdecal, DoRotation(temp - objects.position[k], 0, -objects.yaw[k], 0), .4, .5, Random() % 360);
346 Sprite::MakeSprite(cloudsprite, joints[i].position * (*scale) + *coords, joints[i].velocity * .06, 1, 1, 1, 4, .2);
347 //Sprite::MakeSprite(cloudsprite, joints[i].position*(*scale)+*coords,joints[i].velocity*.06, 1,1,1, 1, .2);
351 emit_sound_at(breaksound2, joints[i].position * (*scale) + *coords);
353 envsound[numenvsounds] = *coords;
354 envsoundvol[numenvsounds] = 64;
355 envsoundlife[numenvsounds] = .4;
359 if (findLengthfast(&bounceness) > 2500) {
360 Normalise(&bounceness);
361 bounceness = bounceness * 50;
364 joints[i].velocity += bounceness * elasticity;
366 if (findLengthfast(&joints[i].velocity) > findLengthfast(&joints[i].oldvelocity)) {
368 joints[i].velocity = joints[i].oldvelocity;
372 if (joints[i].locked == 0)
373 if (findLengthfast(&joints[i].velocity) < 1)
374 joints[i].locked = 1;
376 if (environment == snowyenvironment && findLengthfast(&bounceness) > 500 && terrain.getOpacity(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z) < .2) {
377 terrainlight = terrain.getLighting(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z);
378 Sprite::MakeSprite(cloudsprite, joints[i].position * (*scale) + *coords, joints[i].velocity * .06, terrainlight.x, terrainlight.y, terrainlight.z, .5, .7);
380 terrain.MakeDecal(bodyprintdecal, joints[i].position * (*scale) + *coords, .4, .4, 0);
381 } else if (environment == desertenvironment && findLengthfast(&bounceness) > 500 && terrain.getOpacity(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z) < .2) {
382 terrainlight = terrain.getLighting(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z);
383 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);
386 else if (environment == grassyenvironment && findLengthfast(&bounceness) > 500 && terrain.getOpacity(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z) < .2) {
387 terrainlight = terrain.getLighting(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z);
388 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);
389 } else if (findLengthfast(&bounceness) > 500)
390 Sprite::MakeSprite(cloudsprite, joints[i].position * (*scale) + *coords, joints[i].velocity * .06, terrainlight.x, terrainlight.y, terrainlight.z, .5, .2);
393 joints[i].position.y = (terrain.getHeight(joints[i].position.x * (*scale) + coords->x, joints[i].position.z * (*scale) + coords->z) + groundlevel - coords->y) / (*scale);
397 if (terrain.patchobjectnum[whichpatchx][whichpatchz])
398 for (m = 0; m < terrain.patchobjectnum[whichpatchx][whichpatchz]; m++) {
399 k = terrain.patchobjects[whichpatchx][whichpatchz][m];
400 if (k < objects.numobjects && k >= 0)
401 if (objects.possible[k]) {
402 friction = objects.friction[k];
403 start = joints[i].realoldposition;
404 end = joints[i].position * (*scale) + *coords;
405 whichhit = objects.model[k].LineCheckPossible(&start, &end, &temp, &objects.position[k], &objects.yaw[k]);
406 if (whichhit != -1) {
407 if (joints[i].label == groin && !joints[i].locked && joints[i].delay <= 0) {
408 joints[i].locked = 1;
410 if (tutoriallevel != 1 || id == 0) {
411 emit_sound_at(landsound1, joints[i].position * (*scale) + *coords, 128.);
416 if (joints[i].label == head && !joints[i].locked && joints[i].delay <= 0) {
417 joints[i].locked = 1;
419 if (tutoriallevel != 1 || id == 0) {
420 emit_sound_at(landsound2, joints[i].position * (*scale) + *coords, 128.);
424 terrainnormal = DoRotation(objects.model[k].facenormals[whichhit], 0, objects.yaw[k], 0) * -1;
425 if (terrainnormal.y > .8)
427 bounceness = terrainnormal * findLength(&joints[i].velocity) * (abs(normaldotproduct(joints[i].velocity, terrainnormal)));
428 if (findLengthfast(&joints[i].velocity) > findLengthfast(&joints[i].oldvelocity)) {
430 joints[i].velocity = joints[i].oldvelocity;
432 if (tutoriallevel != 1 || id == 0)
433 if (findLengthfast(&bounceness) > 4000 && breaking) {
434 objects.model[k].MakeDecal(breakdecal, DoRotation(temp - objects.position[k], 0, -objects.yaw[k], 0), .4, .5, Random() % 360);
435 Sprite::MakeSprite(cloudsprite, joints[i].position * (*scale) + *coords, joints[i].velocity * .06, 1, 1, 1, 4, .2);
439 emit_sound_at(breaksound2, joints[i].position * (*scale) + *coords);
441 envsound[numenvsounds] = *coords;
442 envsoundvol[numenvsounds] = 64;
443 envsoundlife[numenvsounds] = .4;
446 if (objects.type[k] == treetrunktype) {
447 //if(objects.rotx[k]==0||objects.roty[k]==0){
451 if(environment==grassyenvironment)howmany=findLength(&joints[i].velocity)*4/10;
452 if(environment==snowyenvironment)howmany=findLength(&joints[i].velocity)*1/10;
453 if(environment!=desertenvironment)
454 for(j=0;j<howmany;j++){
455 tempvel.x=float(abs(Random()%100)-50)/20;
456 tempvel.y=float(abs(Random()%100)-50)/20;
457 tempvel.z=float(abs(Random()%100)-50)/20;
458 pos=objects.position[k];
459 pos.y+=objects.scale[k]*15;
460 pos.x+=float(abs(Random()%100)-50)/100*objects.scale[k]*5;
461 pos.y+=float(abs(Random()%100)-50)/100*objects.scale[k]*15;
462 pos.z+=float(abs(Random()%100)-50)/100*objects.scale[k]*5;
463 Sprite::MakeSprite(splintersprite, pos,tempvel*.5, 165/255+float(abs(Random()%100)-50)/400,0,0, .2+float(abs(Random()%100)-50)/1300, 1);
464 Sprite::special[Sprite::numsprites-1]=1;
466 objects.rotx[k] += joints[i].velocity.x * multiplier * .4;
467 objects.roty[k] += joints[i].velocity.z * multiplier * .4;
468 objects.rotx[k + 1] += joints[i].velocity.x * multiplier * .4;
469 objects.roty[k + 1] += joints[i].velocity.z * multiplier * .4;
471 if (!joints[i].locked)
472 damage += findLengthfast(&bounceness) / 2500;
473 ReflectVector(&joints[i].velocity, &terrainnormal);
474 frictionness = abs(normaldotproduct(joints[i].velocity, terrainnormal)); //findLength(&bounceness)/findLength(&joints[i].velocity);
475 joints[i].velocity -= bounceness;
476 if (1 - friction * frictionness > 0)
477 joints[i].velocity *= 1 - friction * frictionness;
479 joints[i].velocity = 0;
480 if (findLengthfast(&bounceness) > 2500) {
481 Normalise(&bounceness);
482 bounceness = bounceness * 50;
484 joints[i].velocity += bounceness * elasticity;
487 if (!joints[i].locked)
488 if (findLengthfast(&joints[i].velocity) < 1) {
489 joints[i].locked = 1;
490 //joints[i].velocity*=3;
492 if (findLengthfast(&bounceness) > 500)
493 Sprite::MakeSprite(cloudsprite, joints[i].position * (*scale) + *coords, joints[i].velocity * .06, 1, 1, 1, .5, .2);
494 joints[i].position = (temp - *coords) / (*scale) + terrainnormal * .005;
500 joints[i].realoldposition = joints[i].position * (*scale) + *coords;
503 multiplier = tempmult;
506 if (terrain.patchobjectnum[whichpatchx][whichpatchz])
507 for (m = 0; m < terrain.patchobjectnum[whichpatchx][whichpatchz]; m++) {
508 k = terrain.patchobjects[whichpatchx][whichpatchz][m];
509 if (objects.possible[k]) {
510 for (i = 0; i < 26; i++) {
511 //Make this less stupid
512 start = joints[jointlabels[whichjointstartarray[i]]].position * (*scale) + *coords;
513 end = joints[jointlabels[whichjointendarray[i]]].position * (*scale) + *coords;
514 whichhit = objects.model[k].LineCheckSlidePossible(&start, &end, &temp, &objects.position[k], &objects.yaw[k]);
515 if (whichhit != -1) {
516 joints[jointlabels[whichjointendarray[i]]].position = (end - *coords) / (*scale);
517 for (j = 0; j < num_muscles; j++) {
518 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]))
519 muscles[j].DoConstraint(spinny);
526 for (i = 0; i < num_joints; i++) {
528 if (joints[i].label == head)
530 if (joints[i].label == righthand || joints[i].label == rightwrist || joints[i].label == rightelbow)
532 if (joints[i].label == lefthand || joints[i].label == leftwrist || joints[i].label == leftelbow)
534 joints[i].position.y += groundlevel;
536 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)
538 if (joints[i].locked) {
546 for (i = 0; i < num_muscles; i++) {
547 if (muscles[i].type == boneconnect)
548 muscles[i].DoConstraint(0);
554 void Skeleton::DoGravity(float *scale)
557 for (i = 0; i < num_joints; i++) {
558 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))
559 joints[i].velocity.y += gravity * multiplier / (*scale);
563 void Skeleton::Draw(int muscleview)
565 static float jointcolor[4];
567 if (muscleview != 2) {
574 if (muscleview == 2) {
580 //Calc motionblur-ness
581 for (int i = 0; i < num_joints; i++) {
582 joints[i].oldposition = joints[i].position;
583 joints[i].blurred = findDistance(&joints[i].position, &joints[i].oldposition) * 100;
584 if (joints[i].blurred < 1)
585 joints[i].blurred = 1;
591 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
593 for (int i = 0; i < num_joints; i++) {
594 if (joints[i].hasparent) {
595 glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / joints[i].blurred);
596 glVertex3f(joints[i].position.x, joints[i].position.y, joints[i].position.z);
597 glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / joints[i].parent->blurred);
598 glVertex3f(joints[i].parent->position.x, joints[i].parent->position.y, joints[i].parent->position.z);
599 glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / joints[i].parent->blurred);
600 glVertex3f(joints[i].parent->oldposition.x, joints[i].parent->oldposition.y, joints[i].parent->oldposition.z);
601 glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / joints[i].blurred);
602 glVertex3f(joints[i].oldposition.x, joints[i].oldposition.y, joints[i].oldposition.z);
605 for (int i = 0; i < num_muscles; i++) {
606 if (muscles[i].type == boneconnect) {
607 glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / muscles[i].parent2->blurred);
608 glVertex3f(muscles[i].parent1->position.x, muscles[i].parent1->position.y, muscles[i].parent1->position.z);
609 glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / muscles[i].parent2->blurred);
610 glVertex3f(muscles[i].parent2->position.x, muscles[i].parent2->position.y, muscles[i].parent2->position.z);
611 glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / muscles[i].parent2->blurred);
612 glVertex3f(muscles[i].parent2->oldposition.x, muscles[i].parent2->oldposition.y, muscles[i].parent2->oldposition.z);
613 glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / muscles[i].parent1->blurred);
614 glVertex3f(muscles[i].parent1->oldposition.x, muscles[i].parent1->oldposition.y, muscles[i].parent1->oldposition.z);
620 for (int i = 0; i < num_joints; i++) {
621 if (joints[i].hasparent) {
622 glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / joints[i].blurred);
623 glVertex3f(joints[i].position.x, joints[i].position.y, joints[i].position.z);
624 glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / joints[i].parent->blurred);
625 glVertex3f(joints[i].parent->position.x, joints[i].parent->position.y, joints[i].parent->position.z);
628 /*for(int i=0; i<num_joints; i++){
629 if(joints[i].hasparent){
630 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],1);
631 glVertex3f(joints[i].position.x,joints[i].position.y,joints[i].position.z);
632 glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],1);
633 glVertex3f(joints[i].position.x+forward.x,joints[i].position.y+forward.y,joints[i].position.z+forward.z);
636 for (int i = 0; i < num_muscles; i++) {
637 if (muscles[i].type == boneconnect) {
638 glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / muscles[i].parent1->blurred);
639 glVertex3f(muscles[i].parent1->position.x, muscles[i].parent1->position.y, muscles[i].parent1->position.z);
640 glColor4f(jointcolor[0], jointcolor[1], jointcolor[2], jointcolor[3] / muscles[i].parent2->blurred);
641 glVertex3f(muscles[i].parent2->position.x, muscles[i].parent2->position.y, muscles[i].parent2->position.z);
644 glColor3f(.6, .6, 0);
646 for (int i = 0; i < num_muscles; i++) {
647 if (muscles[i].type != boneconnect) {
648 glVertex3f(muscles[i].parent1->position.x, muscles[i].parent1->position.y, muscles[i].parent1->position.z);
649 glVertex3f(muscles[i].parent2->position.x, muscles[i].parent2->position.y, muscles[i].parent2->position.z);
654 if (muscleview != 2) {
657 for (int i = 0; i < num_joints; i++) {
659 glColor4f(0, 0, .5, 1);
661 glColor4f(1, 1, 0, 1);
662 if (joints[i].locked && i != selected)
663 glColor4f(1, 0, 0, 1);
664 glVertex3f(joints[i].position.x, joints[i].position.y, joints[i].position.z);
669 //Set old position to current position
671 for (int i = 0; i < num_joints; i++) {
672 joints[i].oldposition = joints[i].position;
677 void Skeleton::AddJoint(float x, float y, float z, int which)
679 if (num_joints < max_joints - 1) {
680 joints[num_joints].velocity = 0;
681 joints[num_joints].position.x = x;
682 joints[num_joints].position.y = y;
683 joints[num_joints].position.z = z;
684 joints[num_joints].mass = 1;
685 joints[num_joints].locked = 0;
687 /*if(which>=num_joints||which<0)*/
688 joints[num_joints].hasparent = 0;
689 /*if(which<num_joints&&which>=0){
690 joints[num_joints].parent=&joints[which];
691 joints[num_joints].hasparent=1;
692 joints[num_joints].length=findDistance(joints[num_joints].position,joints[num_joints].parent->position);
695 if (which < num_joints && which >= 0)
696 AddMuscle(num_joints - 1, which, 0, 10, boneconnect);
700 void Skeleton::DeleteJoint(int whichjoint)
702 if (whichjoint < num_joints && whichjoint >= 0) {
703 joints[whichjoint].velocity = joints[num_joints - 1].velocity;
704 joints[whichjoint].position = joints[num_joints - 1].position;
705 joints[whichjoint].oldposition = joints[num_joints - 1].oldposition;
706 joints[whichjoint].hasparent = joints[num_joints - 1].hasparent;
707 joints[whichjoint].parent = joints[num_joints - 1].parent;
708 joints[whichjoint].length = joints[num_joints - 1].length;
709 joints[whichjoint].locked = joints[num_joints - 1].locked;
710 joints[whichjoint].modelnum = joints[num_joints - 1].modelnum;
711 joints[whichjoint].visible = joints[num_joints - 1].visible;
713 for (int i = 0; i < num_muscles; i++) {
714 while (muscles[i].parent1 == &joints[whichjoint] && i < num_muscles)DeleteMuscle(i);
715 while (muscles[i].parent2 == &joints[whichjoint] && i < num_muscles)DeleteMuscle(i);
717 for (int i = 0; i < num_muscles; i++) {
718 while (muscles[i].parent1 == &joints[num_joints - 1] && i < num_muscles)muscles[i].parent1 = &joints[whichjoint];
719 while (muscles[i].parent2 == &joints[num_joints - 1] && i < num_muscles)muscles[i].parent2 = &joints[whichjoint];
721 for (int i = 0; i < num_joints; i++) {
722 if (joints[i].parent == &joints[whichjoint])
723 joints[i].hasparent = 0;
725 for (int i = 0; i < num_joints; i++) {
726 if (joints[i].parent == &joints[num_joints - 1])
727 joints[i].parent = &joints[whichjoint];
734 void Skeleton::DeleteMuscle(int whichmuscle)
736 if (whichmuscle < num_muscles) {
737 muscles[whichmuscle].minlength = muscles[num_muscles - 1].minlength;
738 muscles[whichmuscle].maxlength = muscles[num_muscles - 1].maxlength;
739 muscles[whichmuscle].strength = muscles[num_muscles - 1].strength;
740 muscles[whichmuscle].parent1 = muscles[num_muscles - 1].parent1;
741 muscles[whichmuscle].parent2 = muscles[num_muscles - 1].parent2;
742 muscles[whichmuscle].length = muscles[num_muscles - 1].length;
743 muscles[whichmuscle].visible = muscles[num_muscles - 1].visible;
744 muscles[whichmuscle].type = muscles[num_muscles - 1].type;
745 muscles[whichmuscle].targetlength = muscles[num_muscles - 1].targetlength;
751 void Skeleton::SetJoint(float x, float y, float z, int which, int whichjoint)
753 if (whichjoint < num_joints) {
754 joints[whichjoint].velocity = 0;
755 joints[whichjoint].position.x = x;
756 joints[whichjoint].position.y = y;
757 joints[whichjoint].position.z = z;
759 if (which >= num_joints || which < 0)
760 joints[whichjoint].hasparent = 0;
761 if (which < num_joints && which >= 0) {
762 joints[whichjoint].parent = &joints[which];
763 joints[whichjoint].hasparent = 1;
764 joints[whichjoint].length = findDistance(&joints[whichjoint].position, &joints[whichjoint].parent->position);
769 void Skeleton::AddMuscle(int attach1, int attach2, float minlength, float maxlength, int type)
771 const int max_muscles = 100; // FIXME: Probably can be dropped
772 if (num_muscles < max_muscles - 1 && attach1 < num_joints && attach1 >= 0 && attach2 < num_joints && attach2 >= 0 && attach1 != attach2) {
773 muscles[num_muscles].parent1 = &joints[attach1];
774 muscles[num_muscles].parent2 = &joints[attach2];
775 muscles[num_muscles].length = findDistance(&muscles[num_muscles].parent1->position, &muscles[num_muscles].parent2->position);
776 muscles[num_muscles].targetlength = findDistance(&muscles[num_muscles].parent1->position, &muscles[num_muscles].parent2->position);
777 muscles[num_muscles].strength = .7;
778 muscles[num_muscles].type = type;
779 muscles[num_muscles].minlength = minlength;
780 muscles[num_muscles].maxlength = maxlength;
786 void Skeleton::MusclesSet()
788 for (int i = 0; i < num_muscles; i++) {
789 muscles[i].length = findDistance(&muscles[i].parent1->position, &muscles[i].parent2->position);
793 void Skeleton::DoBalance()
796 newpoint=joints[0].position;
797 newpoint.x=(joints[2].position.x+joints[4].position.x)/2;
798 newpoint.z=(joints[2].position.z+joints[4].position.z)/2;
799 joints[0].velocity=joints[0].velocity+(newpoint-joints[0].position);
800 //Move child point to within certain distance of parent point
801 joints[0].position=newpoint;
806 void Skeleton::FindRotationMuscle(int which, int animation)
808 static XYZ temppoint1, temppoint2, tempforward;
809 static float distance;
811 temppoint1 = muscles[which].parent1->position;
812 temppoint2 = muscles[which].parent2->position;
813 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));
814 if ((temppoint1.y - temppoint2.y) <= distance)
815 muscles[which].rotate2 = asin((temppoint1.y - temppoint2.y) / distance);
816 if ((temppoint1.y - temppoint2.y) > distance)
817 muscles[which].rotate2 = asin(1.f);
818 muscles[which].rotate2 *= 360 / 6.28;
821 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));
822 if ((temppoint1.z - temppoint2.z) <= distance)
823 muscles[which].rotate1 = acos((temppoint1.z - temppoint2.z) / distance);
824 if ((temppoint1.z - temppoint2.z) > distance)
825 muscles[which].rotate1 = acos(1.f);
826 muscles[which].rotate1 *= 360 / 6.28;
827 if (temppoint1.x > temppoint2.x)
828 muscles[which].rotate1 = 360 - muscles[which].rotate1;
829 if (!isnormal(muscles[which].rotate1))
830 muscles[which].rotate1 = 0;
831 if (!isnormal(muscles[which].rotate2))
832 muscles[which].rotate2 = 0;
834 if (muscles[which].parent1->label == head)
835 tempforward = specialforward[0];
836 else if (muscles[which].parent1->label == rightshoulder || muscles[which].parent1->label == rightelbow || muscles[which].parent1->label == rightwrist || muscles[which].parent1->label == righthand)
837 tempforward = specialforward[1];
838 else if (muscles[which].parent1->label == leftshoulder || muscles[which].parent1->label == leftelbow || muscles[which].parent1->label == leftwrist || muscles[which].parent1->label == lefthand)
839 tempforward = specialforward[2];
840 else if (muscles[which].parent1->label == righthip || muscles[which].parent1->label == rightknee || muscles[which].parent1->label == rightankle || muscles[which].parent1->label == rightfoot)
841 tempforward = specialforward[3];
842 else if (muscles[which].parent1->label == lefthip || muscles[which].parent1->label == leftknee || muscles[which].parent1->label == leftankle || muscles[which].parent1->label == leftfoot)
843 tempforward = specialforward[4];
844 else if (!muscles[which].parent1->lower)
845 tempforward = forward;
846 else if (muscles[which].parent1->lower)
847 tempforward = lowforward;
849 if (animation == hanganim) {
850 if (muscles[which].parent1->label == righthand || muscles[which].parent2->label == righthand) {
854 if (muscles[which].parent1->label == lefthand || muscles[which].parent2->label == lefthand) {
861 if (muscles[which].parent1->label == rightfoot || muscles[which].parent2->label == rightfoot) {
864 if (muscles[which].parent1->label == leftfoot || muscles[which].parent2->label == leftfoot) {
870 tempforward = DoRotation(tempforward, 0, muscles[which].rotate1 - 90, 0);
871 tempforward = DoRotation(tempforward, 0, 0, muscles[which].rotate2 - 90);
873 tempforward /= sqrt(tempforward.x * tempforward.x + tempforward.y * tempforward.y + tempforward.z * tempforward.z);
874 if (tempforward.z <= 1 && tempforward.z >= -1)
875 muscles[which].rotate3 = acos(0 - tempforward.z);
877 muscles[which].rotate3 = acos(-1.f);
878 muscles[which].rotate3 *= 360 / 6.28;
879 if (0 > tempforward.x)
880 muscles[which].rotate3 = 360 - muscles[which].rotate3;
881 if (!isnormal(muscles[which].rotate3))
882 muscles[which].rotate3 = 0;
885 void Animation::Load(const char *filename, int aheight, int aattack)
889 static XYZ startoffset, endoffset;
892 static const char *anim_prefix = ":Data:Animations:";
897 int len = strlen(anim_prefix) + strlen(filename);
898 char *buf = new char[len + 1];
899 snprintf(buf, len + 1, "%s%s", anim_prefix, filename);
900 // Changing the filename into something the OS can understand
901 char *fixedFN = ConvertFileName(buf);
904 LOG(std::string("Loading animation...") + fixedFN);
912 Game::LoadingScreen();
914 tfile = fopen( fixedFN, "rb" );
916 funpackf(tfile, "Bi Bi", &numframes, &joints);
918 for(i = 0; i < joints; i++){
919 if(position[i])dealloc2(position[i]);
920 if(twist[i])dealloc2(twist[i]);
921 if(twist2[i])dealloc2(twist2[i]);
922 if(onground[i])dealloc2(onground[i]);
925 if(position)dealloc2(position);
926 if(twist)dealloc2(twist);
927 if(twist2)dealloc2(twist2);
928 if(speed)dealloc2(speed);
929 if(onground)dealloc2(onground);
930 if(forward)dealloc2(forward);
931 if(weapontarget)dealloc2(weapontarget);
932 if(label)dealloc2(label);*/
934 position = (XYZ**)malloc(sizeof(XYZ*)*joints);
935 for (i = 0; i < joints; i++)
936 position[i] = (XYZ*)malloc(sizeof(XYZ) * numframes);
938 twist = (float**)malloc(sizeof(float*)*joints);
939 for (i = 0; i < joints; i++)
940 twist[i] = (float*)malloc(sizeof(float) * numframes);
942 twist2 = (float**)malloc(sizeof(float*)*joints);
943 for (i = 0; i < joints; i++)
944 twist2[i] = (float*)malloc(sizeof(float) * numframes);
946 speed = (float*)malloc(sizeof(float) * numframes);
948 onground = (bool**)malloc(sizeof(bool*)*joints);
949 for (i = 0; i < joints; i++)
950 onground[i] = (bool*)malloc(sizeof(bool) * numframes);
952 forward = (XYZ*)malloc(sizeof(XYZ) * numframes);
953 weapontarget = (XYZ*)malloc(sizeof(XYZ) * numframes);
954 label = (int*)malloc(sizeof(int) * numframes);
956 /*position = new XYZ[joints][numframes];
957 twist = new float[joints][numframes];
958 twist2 = new float[joints][numframes];
959 speed = new float[numframes];
960 onground = new bool[joints][numframes];
961 forward = new XYZ[numframes];
962 label = new int[numframes];*/
964 for (i = 0; i < numframes; i++) {
965 for (j = 0; j < joints; j++) {
966 funpackf(tfile, "Bf Bf Bf", &position[j][i].x, &position[j][i].y, &position[j][i].z);
968 for (j = 0; j < joints; j++) {
969 funpackf(tfile, "Bf", &twist[j][i]);
971 for (j = 0; j < joints; j++) {
973 funpackf(tfile, "Bb", &uch);
974 onground[j][i] = (uch != 0);
976 funpackf(tfile, "Bf", &speed[i]);
978 for (i = 0; i < numframes; i++) {
979 for (j = 0; j < joints; j++) {
980 funpackf(tfile, "Bf", &twist2[j][i]);
983 for (i = 0; i < numframes; i++) {
984 funpackf(tfile, "Bf", &label[i]);
986 funpackf(tfile, "Bi", &weapontargetnum);
987 for (i = 0; i < numframes; i++) {
988 funpackf(tfile, "Bf Bf Bf", &weapontarget[i].x, &weapontarget[i].y, &weapontarget[i].z);
997 for (j = 0; j < joints; j++) {
998 if (position[j][0].y < 1)
999 startoffset += position[j][0];
1000 if (position[j][numframes - 1].y < 1)
1001 endoffset += position[j][numframes - 1];
1004 startoffset /= howmany;
1005 endoffset /= howmany;
1011 void Animation::Move(XYZ how)
1013 static int i, j, joints;
1014 for (i = 0; i < numframes; i++) {
1015 for (j = 0; j < joints; j++) {
1021 void Skeleton::Load(const char *filename, const char *lowfilename, const char *clothesfilename,
1022 const char *modelfilename, const char *model2filename,
1023 const char *model3filename, const char *model4filename,
1024 const char *model5filename, const char *model6filename,
1025 const char *model7filename, const char *modellowfilename,
1026 const char *modelclothesfilename, bool aclothes)
1028 static GLfloat M[16];
1029 static int parentID;
1032 static int i, j, tempmuscle;
1045 for (i = 0; i < num_models; i++) {
1046 if (i == 0) model[i].loadnotex(modelfilename);
1047 if (i == 1) model[i].loadnotex(model2filename);
1048 if (i == 2) model[i].loadnotex(model3filename);
1049 if (i == 3) model[i].loadnotex(model4filename);
1050 if (i == 4) model[i].loadnotex(model5filename);
1051 if (i == 5) model[i].loadnotex(model6filename);
1052 if (i == 6) model[i].loadnotex(model7filename);
1053 model[i].Rotate(180, 0, 0);
1054 model[i].Scale(.04, .04, .04);
1055 model[i].CalculateNormals(0);
1058 drawmodel.load(modelfilename, 0);
1059 drawmodel.Rotate(180, 0, 0);
1060 drawmodel.Scale(.04, .04, .04);
1061 drawmodel.FlipTexCoords();
1062 if (tutoriallevel == 1 && id != 0)
1063 drawmodel.UniformTexCoords();
1064 if (tutoriallevel == 1 && id != 0)
1065 drawmodel.ScaleTexCoords(0.1);
1066 drawmodel.CalculateNormals(0);
1068 modellow.loadnotex(modellowfilename);
1069 modellow.Rotate(180, 0, 0);
1070 modellow.Scale(.04, .04, .04);
1071 modellow.CalculateNormals(0);
1073 drawmodellow.load(modellowfilename, 0);
1074 drawmodellow.Rotate(180, 0, 0);
1075 drawmodellow.Scale(.04, .04, .04);
1076 drawmodellow.FlipTexCoords();
1077 if (tutoriallevel == 1 && id != 0)
1078 drawmodellow.UniformTexCoords();
1079 if (tutoriallevel == 1 && id != 0)
1080 drawmodellow.ScaleTexCoords(0.1);
1081 drawmodellow.CalculateNormals(0);
1084 modelclothes.loadnotex(modelclothesfilename);
1085 modelclothes.Rotate(180, 0, 0);
1086 modelclothes.Scale(.041, .04, .041);
1087 modelclothes.CalculateNormals(0);
1089 drawmodelclothes.load(modelclothesfilename, 0);
1090 drawmodelclothes.Rotate(180, 0, 0);
1091 drawmodelclothes.Scale(.04, .04, .04);
1092 drawmodelclothes.FlipTexCoords();
1093 drawmodelclothes.CalculateNormals(0);
1096 tfile = fopen( ConvertFileName(filename), "rb" );
1098 funpackf(tfile, "Bi", &num_joints);
1099 //joints.resize(num_joints);
1101 delete [] joints; //dealloc2(joints);
1102 joints = (Joint*)new Joint[num_joints]; //malloc(sizeof(Joint)*num_joints);
1104 for (i = 0; i < num_joints; i++) {
1105 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);
1106 funpackf(tfile, "Bb Bb", &joints[i].hasparent, &joints[i].locked);
1107 funpackf(tfile, "Bi", &joints[i].modelnum);
1108 funpackf(tfile, "Bb Bb", &joints[i].visible, &joints[i].sametwist);
1109 funpackf(tfile, "Bi Bi", &joints[i].label, &joints[i].hasgun);
1110 funpackf(tfile, "Bb", &joints[i].lower);
1111 funpackf(tfile, "Bi", &parentID);
1112 if (joints[i].hasparent)
1113 joints[i].parent = &joints[parentID];
1114 joints[i].velocity = 0;
1115 joints[i].oldposition = joints[i].position;
1117 tempmuscle = num_muscles;
1118 funpackf(tfile, "Bi", &num_muscles);
1121 delete [] muscles; //dealloc2(muscles);
1122 muscles = (Muscle*)new Muscle[num_muscles]; //malloc(sizeof(Muscle)*num_muscles);
1124 for (i = 0; i < num_muscles; i++) {
1125 tempmuscle = muscles[i].numvertices;
1126 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);
1127 //muscles[i].vertices.clear();
1128 //muscles[i].vertices.resize(muscles[i].numvertices);
1129 //if(muscles[i].vertices)dealloc2(muscles[i].vertices);
1130 muscles[i].vertices = (int*)malloc(sizeof(int) * muscles[i].numvertices);
1133 for (j = 0; j < muscles[i].numvertices - edit; j++) {
1134 funpackf(tfile, "Bi", &muscles[i].vertices[j + edit]);
1135 if (muscles[i].vertices[j + edit] >= model[0].vertexNum) {
1136 muscles[i].numvertices--;
1140 funpackf(tfile, "Bb Bi", &muscles[i].visible, &parentID);
1141 muscles[i].parent1 = &joints[parentID];
1142 funpackf(tfile, "Bi", &parentID);
1143 muscles[i].parent2 = &joints[parentID];
1145 for (j = 0; j < 3; j++) {
1146 funpackf(tfile, "Bi", &forwardjoints[j]);
1148 for (j = 0; j < 3; j++) {
1149 funpackf(tfile, "Bi", &lowforwardjoints[j]);
1151 for (j = 0; j < num_muscles; j++) {
1152 for (i = 0; i < muscles[j].numvertices; i++) {
1153 for (int k = 0; k < num_models; k++) {
1154 if (muscles[j].numvertices && muscles[j].vertices[i] < model[k].vertexNum)
1155 model[k].owner[muscles[j].vertices[i]] = j;
1160 for (i = 0; i < num_joints; i++) {
1161 joints[i].startpos = joints[i].position;
1163 for (i = 0; i < num_muscles; i++) {
1164 FindRotationMuscle(i, -1);
1166 for (int k = 0; k < num_models; k++) {
1167 for (i = 0; i < model[k].vertexNum; i++) {
1168 model[k].vertex[i] = model[k].vertex[i] - (muscles[model[k].owner[i]].parent1->position + muscles[model[k].owner[i]].parent2->position) / 2;
1169 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
1172 glRotatef(muscles[model[k].owner[i]].rotate3, 0, 1, 0);
1173 glRotatef(muscles[model[k].owner[i]].rotate2 - 90, 0, 0, 1);
1174 glRotatef(muscles[model[k].owner[i]].rotate1 - 90, 0, 1, 0);
1175 glTranslatef(model[k].vertex[i].x, model[k].vertex[i].y, model[k].vertex[i].z);
1176 glGetFloatv(GL_MODELVIEW_MATRIX, M);
1177 model[k].vertex[i].x = M[12] * 1;
1178 model[k].vertex[i].y = M[13] * 1;
1179 model[k].vertex[i].z = M[14] * 1;
1182 model[k].CalculateNormals(0);
1187 tfile = fopen( ConvertFileName(lowfilename), "rb" );
1189 lSize = sizeof(num_joints);
1190 fseek ( tfile, lSize, SEEK_CUR);
1191 //joints = new Joint[num_joints];
1192 //jointlabels = new int[num_joints];
1193 for (i = 0; i < num_joints; i++) {
1194 lSize = sizeof(XYZ);
1195 fseek ( tfile, lSize, SEEK_CUR);
1196 lSize = sizeof(float);
1197 fseek ( tfile, lSize, SEEK_CUR);
1198 lSize = sizeof(float);
1199 fseek ( tfile, lSize, SEEK_CUR);
1200 lSize = 1; //sizeof(bool);
1201 fseek ( tfile, lSize, SEEK_CUR);
1202 lSize = 1; //sizeof(bool);
1203 fseek ( tfile, lSize, SEEK_CUR);
1204 lSize = sizeof(int);
1205 fseek ( tfile, lSize, SEEK_CUR);
1206 lSize = 1; //sizeof(bool);
1207 fseek ( tfile, lSize, SEEK_CUR);
1208 lSize = 1; //sizeof(bool);
1209 fseek ( tfile, lSize, SEEK_CUR);
1210 lSize = sizeof(int);
1211 fseek ( tfile, lSize, SEEK_CUR);
1212 lSize = sizeof(int);
1213 fseek ( tfile, lSize, SEEK_CUR);
1214 lSize = 1; //sizeof(bool);
1215 fseek ( tfile, lSize, SEEK_CUR);
1216 lSize = sizeof(int);
1217 fseek ( tfile, lSize, SEEK_CUR);
1218 if (joints[i].hasparent)
1219 joints[i].parent = &joints[parentID];
1220 joints[i].velocity = 0;
1221 joints[i].oldposition = joints[i].position;
1223 funpackf(tfile, "Bi", &num_muscles);
1224 //muscles = new Muscle[num_muscles];
1225 for (i = 0; i < num_muscles; i++) {
1226 lSize = sizeof(float);
1227 fseek ( tfile, lSize, SEEK_CUR);
1228 lSize = sizeof(float);
1229 fseek ( tfile, lSize, SEEK_CUR);
1230 lSize = sizeof(float);
1231 fseek ( tfile, lSize, SEEK_CUR);
1232 lSize = sizeof(float);
1233 fseek ( tfile, lSize, SEEK_CUR);
1234 lSize = sizeof(float);
1235 fseek ( tfile, lSize, SEEK_CUR);
1236 lSize = sizeof(int);
1237 fseek ( tfile, lSize, SEEK_CUR);
1238 tempmuscle = muscles[i].numverticeslow;
1239 funpackf(tfile, "Bi", &muscles[i].numverticeslow);
1240 if (muscles[i].numverticeslow) {
1241 //muscles[i].verticeslow.clear();
1242 //muscles[i].verticeslow.resize(muscles[i].numverticeslow);
1243 //if(muscles[i].verticeslow)dealloc2(muscles[i].verticeslow);
1244 muscles[i].verticeslow = (int*)malloc(sizeof(int) * muscles[i].numverticeslow);
1246 for (j = 0; j < muscles[i].numverticeslow - edit; j++) {
1247 funpackf(tfile, "Bi", &muscles[i].verticeslow[j + edit]);
1248 if (muscles[i].verticeslow[j + edit] >= modellow.vertexNum) {
1249 muscles[i].numverticeslow--;
1256 lSize = 1; //sizeof(bool);
1257 fseek ( tfile, lSize, SEEK_CUR);
1258 lSize = sizeof(int);
1259 fseek ( tfile, lSize, SEEK_CUR);
1260 fseek ( tfile, lSize, SEEK_CUR);
1262 lSize = sizeof(int);
1263 for (j = 0; j < num_muscles; j++) {
1264 for (i = 0; i < muscles[j].numverticeslow; i++) {
1265 if (muscles[j].numverticeslow && muscles[j].verticeslow[i] < modellow.vertexNum)
1266 modellow.owner[muscles[j].verticeslow[i]] = j;
1270 for(i=0;i<num_joints;i++){
1271 joints[i].startpos=joints[i].position;
1273 for(i=0;i<num_muscles;i++){
1274 FindRotationMuscle(i,-1);
1276 for (i = 0; i < modellow.vertexNum; i++) {
1277 modellow.vertex[i] = modellow.vertex[i] - (muscles[modellow.owner[i]].parent1->position + muscles[modellow.owner[i]].parent2->position) / 2;
1278 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
1281 glRotatef(muscles[modellow.owner[i]].rotate3, 0, 1, 0);
1282 glRotatef(muscles[modellow.owner[i]].rotate2 - 90, 0, 0, 1);
1283 glRotatef(muscles[modellow.owner[i]].rotate1 - 90, 0, 1, 0);
1284 glTranslatef(modellow.vertex[i].x, modellow.vertex[i].y, modellow.vertex[i].z);
1285 glGetFloatv(GL_MODELVIEW_MATRIX, M);
1286 modellow.vertex[i].x = M[12];
1287 modellow.vertex[i].y = M[13];
1288 modellow.vertex[i].z = M[14];
1291 modellow.CalculateNormals(0);
1295 tfile = fopen( ConvertFileName(clothesfilename), "rb" );
1296 lSize = sizeof(num_joints);
1297 fseek ( tfile, lSize, SEEK_CUR);
1298 //joints = new Joint[num_joints];
1299 //jointlabels = new int[num_joints];
1300 for (i = 0; i < num_joints; i++) {
1301 lSize = sizeof(XYZ);
1302 fseek ( tfile, lSize, SEEK_CUR);
1303 lSize = sizeof(float);
1304 fseek ( tfile, lSize, SEEK_CUR);
1305 lSize = sizeof(float);
1306 fseek ( tfile, lSize, SEEK_CUR);
1307 lSize = 1; //sizeof(bool);
1308 fseek ( tfile, lSize, SEEK_CUR);
1309 lSize = 1; //sizeof(bool);
1310 fseek ( tfile, lSize, SEEK_CUR);
1311 lSize = sizeof(int);
1312 fseek ( tfile, lSize, SEEK_CUR);
1313 lSize = 1; //sizeof(bool);
1314 fseek ( tfile, lSize, SEEK_CUR);
1315 lSize = 1; //sizeof(bool);
1316 fseek ( tfile, lSize, SEEK_CUR);
1317 lSize = sizeof(int);
1318 fseek ( tfile, lSize, SEEK_CUR);
1319 lSize = sizeof(int);
1320 fseek ( tfile, lSize, SEEK_CUR);
1321 lSize = 1; //sizeof(bool);
1322 fseek ( tfile, lSize, SEEK_CUR);
1323 lSize = sizeof(int);
1324 fseek ( tfile, lSize, SEEK_CUR);
1325 if (joints[i].hasparent)
1326 joints[i].parent = &joints[parentID];
1327 joints[i].velocity = 0;
1328 joints[i].oldposition = joints[i].position;
1330 funpackf(tfile, "Bi", &num_muscles);
1331 //muscles = new Muscle[num_muscles];
1332 for (i = 0; i < num_muscles; i++) {
1333 lSize = sizeof(float);
1334 fseek ( tfile, lSize, SEEK_CUR);
1335 lSize = sizeof(float);
1336 fseek ( tfile, lSize, SEEK_CUR);
1337 lSize = sizeof(float);
1338 fseek ( tfile, lSize, SEEK_CUR);
1339 lSize = sizeof(float);
1340 fseek ( tfile, lSize, SEEK_CUR);
1341 lSize = sizeof(float);
1342 fseek ( tfile, lSize, SEEK_CUR);
1343 lSize = sizeof(int);
1344 fseek ( tfile, lSize, SEEK_CUR);
1345 tempmuscle = muscles[i].numverticesclothes;
1346 funpackf(tfile, "Bi", &muscles[i].numverticesclothes);
1347 if (muscles[i].numverticesclothes) {
1348 //muscles[i].verticesclothes.clear();
1349 //muscles[i].verticesclothes.resize(muscles[i].numverticesclothes);
1350 //if(muscles[i].verticesclothes)dealloc2(muscles[i].verticesclothes);
1351 muscles[i].verticesclothes = (int*)malloc(sizeof(int) * muscles[i].numverticesclothes);
1353 for (j = 0; j < muscles[i].numverticesclothes - edit; j++) {
1354 funpackf(tfile, "Bi", &muscles[i].verticesclothes[j + edit]);
1355 if (muscles[i].verticesclothes[j + edit] >= modelclothes.vertexNum) {
1356 muscles[i].numverticesclothes--;
1361 lSize = 1; //sizeof(bool);
1362 fseek ( tfile, lSize, SEEK_CUR);
1363 lSize = sizeof(int);
1364 fseek ( tfile, lSize, SEEK_CUR);
1365 fseek ( tfile, lSize, SEEK_CUR);
1367 lSize = sizeof(int);
1368 for (j = 0; j < num_muscles; j++) {
1369 for (i = 0; i < muscles[j].numverticesclothes; i++) {
1370 if (muscles[j].numverticesclothes && muscles[j].verticesclothes[i] < modelclothes.vertexNum)
1371 modelclothes.owner[muscles[j].verticesclothes[i]] = j;
1375 for(i=0;i<num_joints;i++){
1376 joints[i].startpos=joints[i].position;
1378 for(i=0;i<num_muscles;i++){
1379 FindRotationMuscle(i,-1);
1381 for (i = 0; i < modelclothes.vertexNum; i++) {
1382 modelclothes.vertex[i] = modelclothes.vertex[i] - (muscles[modelclothes.owner[i]].parent1->position + muscles[modelclothes.owner[i]].parent2->position) / 2;
1383 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
1386 glRotatef(muscles[modelclothes.owner[i]].rotate3, 0, 1, 0);
1387 glRotatef(muscles[modelclothes.owner[i]].rotate2 - 90, 0, 0, 1);
1388 glRotatef(muscles[modelclothes.owner[i]].rotate1 - 90, 0, 1, 0);
1389 glTranslatef(modelclothes.vertex[i].x, modelclothes.vertex[i].y, modelclothes.vertex[i].z);
1390 glGetFloatv(GL_MODELVIEW_MATRIX, M);
1391 modelclothes.vertex[i].x = M[12];
1392 modelclothes.vertex[i].y = M[13];
1393 modelclothes.vertex[i].z = M[14];
1396 modelclothes.CalculateNormals(0);
1400 for (i = 0; i < num_joints; i++) {
1401 for (j = 0; j < num_joints; j++) {
1402 if (joints[i].label == j)
1410 Animation::Animation()
1416 weapontargetnum = 0;
1428 Animation::~Animation()
1433 void Animation::deallocate()
1438 for (i = 0; i < joints; i++)
1439 dealloc2(position[i]);
1446 for (i = 0; i < joints; i++)
1454 for (i = 0; i < joints; i++)
1455 dealloc2(twist2[i]);
1462 for (i = 0; i < joints; i++)
1463 dealloc2(onground[i]);
1478 dealloc2(weapontarget);
1488 Skeleton::Skeleton()
1496 memset(forwardjoints, 0, sizeof(forwardjoints));
1501 memset(lowforwardjoints, 0, sizeof(lowforwardjoints));
1504 // XYZ specialforward[5];
1505 memset(jointlabels, 0, sizeof(jointlabels));
1509 // Model modelclothes;
1513 // Model drawmodellow;
1514 // Model drawmodelclothes;
1519 memset(skinText, 0, sizeof(skinText));
1536 Skeleton::~Skeleton()
1553 verticesclothes = 0;
1557 numverticesclothes = 0;
1566 rotate1 = 0, rotate2 = 0, rotate3 = 0;
1567 lastrotate1 = 0, lastrotate2 = 0, lastrotate3 = 0;
1568 oldrotate1 = 0, oldrotate2 = 0, oldrotate3 = 0;
1569 newrotate1 = 0, newrotate2 = 0, newrotate3 = 0;
1577 dealloc2(verticeslow);
1578 dealloc2(verticesclothes);
1581 Animation & Animation::operator = (const Animation & ani)
1585 bool allocate = true;
1587 allocate = ((ani.numframes != numframes) || (ani.joints != joints));
1592 numframes = ani.numframes;
1593 height = ani.height;
1594 attack = ani.attack;
1595 joints = ani.joints;
1596 weapontargetnum = ani.weapontargetnum;
1599 position = (XYZ**)malloc(sizeof(XYZ*)*ani.joints);
1600 for (i = 0; i < ani.joints; i++) {
1602 position[i] = (XYZ*)malloc(sizeof(XYZ) * ani.numframes);
1603 memcpy(position[i], ani.position[i], sizeof(XYZ)*ani.numframes);
1607 twist = (float**)malloc(sizeof(float*)*ani.joints);
1608 for (i = 0; i < ani.joints; i++) {
1610 twist[i] = (float*)malloc(sizeof(float) * ani.numframes);
1611 memcpy(twist[i], ani.twist[i], sizeof(float)*ani.numframes);
1615 twist2 = (float**)malloc(sizeof(float*)*ani.joints);
1616 for (i = 0; i < ani.joints; i++) {
1618 twist2[i] = (float*)malloc(sizeof(float) * ani.numframes);
1619 memcpy(twist2[i], ani.twist2[i], sizeof(float)*ani.numframes);
1623 speed = (float*)malloc(sizeof(float) * ani.numframes);
1624 memcpy(speed, ani.speed, sizeof(float)*ani.numframes);
1627 onground = (bool**)malloc(sizeof(bool*)*ani.joints);
1628 for (i = 0; i < ani.joints; i++) {
1630 onground[i] = (bool*)malloc(sizeof(bool) * ani.numframes);
1631 memcpy(onground[i], ani.onground[i], sizeof(bool)*ani.numframes);
1635 forward = (XYZ*)malloc(sizeof(XYZ) * ani.numframes);
1636 memcpy(forward, ani.forward, sizeof(XYZ)*ani.numframes);
1639 weapontarget = (XYZ*)malloc(sizeof(XYZ) * ani.numframes);
1640 memcpy(weapontarget, ani.weapontarget, sizeof(XYZ)*ani.numframes);
1643 label = (int*)malloc(sizeof(int) * ani.numframes);
1644 memcpy(label, ani.label, sizeof(int)*ani.numframes);