/**> HEADER FILES <**/ #include "Skeleton.h" #include "Serialize.h" extern float multiplier; extern unsigned int gSourceID[100]; extern unsigned int gSampleSet[100]; extern int visions; extern float rad2deg; extern Camera camera; extern float soundscalefactor; extern XYZ vel; extern XYZ midp; extern XYZ newpoint1,newpoint2; extern float oldlength; extern float relaxlength; extern float friction; extern int numrepeats; extern float groundlevel; extern float offset; extern XYZ impact; extern XYZ overpoint; extern XYZ underpoint; extern int whichtri; extern XYZ normalrotated; extern bool groundish; void Joint::DoConstraint() { if(hasparent){ //Find midpoint midp=(position+parent->position)/2; //Find vector from midpoint to second vector vel=parent->position-midp; //Change to unit vector Normalise(&vel); //Apply velocity change velocity+=((midp-vel*length/2)-position); parent->velocity+=((midp+vel*length/2)-parent->position); //Move child point to within certain distance of parent point if(!locked)position=midp-vel*length/2; if(!parent->locked)parent->position=midp+vel*length/2; } } void Muscle::DoConstraint(int broken) { oldlength=length; relaxlength=findDistance(parent1->position,parent2->position); if(type==boneconnect)strength=1; if(type==constraint)strength=0; if(strength<0)strength=0; if(strength>1)strength=1; length-=(length-relaxlength)*(1-strength)*multiplier*multiplier*10000; length-=(length-targetlength)*(strength)*multiplier*multiplier*10000; if(strength==0)length=relaxlength; if((relaxlength-length>0&&relaxlength-oldlength<0)||(relaxlength-length<0&&relaxlength-oldlength>0))length=relaxlength; if(lengthmaxlength&&!broken)length=maxlength; //Find midpoint midp=(parent1->position+parent2->position)/2; //Find vector from midpoint to second vector vel=parent2->position-midp; //Change to unit vector Normalise(&vel); //Apply velocity change newpoint1=midp-vel*length/2; newpoint2=midp+vel*length/2; parent1->velocity+=(newpoint1-parent1->position); parent2->velocity+=(newpoint2-parent2->position); //Move child point to within certain distance of parent point if(!parent1->locked)parent1->position=newpoint1; if(!parent2->locked)parent2->position=newpoint2; } void Skeleton::DoConstraints() { numrepeats=3; for(int j=0; jy += 0.35; groundlevel = 0; numrepeats = 2; for (int j = 0; j < numrepeats; j++) { for (int i = 0; i < num_joints; i++) { if (!joints[i].existing && i != jointlabels[lefthand] && i != jointlabels[righthand]) continue; // Length constraints joints[i].DoConstraint(); // Ground constraint auto& pos = joints[i].position; overpoint = pos; overpoint.y += 10; underpoint = pos; underpoint.y -= offset = 0; whichtri = collide->LineCheck2(overpoint, underpoint, &impact, *move, rotation); if (whichtri == -1 || collide->normals[whichtri].y <= 0.8) whichtri = collide->LineCheck2( joints[i].realoldposition, pos, &impact, *move, rotation); if (pos.y <= groundlevel + offset || whichtri != -1) { if (whichtri == -1 || collide->normals[whichtri].y > 0.8) { if (whichtri == -1) { pos.y = groundlevel + offset; } else { pos = impact; pos.y += offset; } joints[i].velocity.y *= -0.3; joints[i].velocity.x *= 0.3; joints[i].velocity.z *= 0.3; } offset = 0.2; if (whichtri != -1 && collide->normals[whichtri].y <= 0.8) { normalrotated = DoRotation(collide->normals[whichtri], 0, rotation, 0); pos = impact + normalrotated * offset; ReflectVector(&joints[i].velocity, &normalrotated); joints[i].velocity *= 0.3; } if (broken > 1) continue; XYZ avgvelocity {0}; for (int k = 0; k < num_joints; k++) avgvelocity += joints[k].velocity; avgvelocity /= num_joints; int landsound = -1; switch (joints[i].label) { case head: landsound = headlandsound; break; case abdomen: landsound = bodylandsound; break; } ALint playing = AL_PLAYING; if (landsound >= 0) alGetSourcei(gSourceID[landsound], AL_SOURCE_STATE, &playing); if (playing != AL_PLAYING && (findLengthfast(joints[i].velocity) > 2 || findLengthfast(avgvelocity) > 2)) { ALfloat gain = findLengthfast(avgvelocity + joints[i].velocity) / findDistancefast(pos, camera.position) * soundscalefactor * 4; alSourcef(gSourceID[landsound], AL_MIN_GAIN, gain); alSourcef(gSourceID[landsound], AL_MAX_GAIN, gain); float gLoc[] { pos.x / soundscalefactor, pos.y / soundscalefactor, pos.z / soundscalefactor, }; alSourcefv(gSourceID[landsound], AL_POSITION, gLoc); alSourcePlay(gSourceID[landsound]); } } } for (int i = 0; i < num_muscles; i++) //Length constraints muscles[i].DoConstraint(broken); } for (int i = 0; i < num_joints; i++) { joints[i].realoldposition = joints[i].position; //Add velocity if (joints[i].existing || i == jointlabels[lefthand] || i == jointlabels[righthand]) joints[i].position += joints[i].velocity * multiplier; } } void Skeleton::DoGravity() { for(int i=0; iblurred); glVertex3f(joints[i].parent->position.x,joints[i].parent->position.y,joints[i].parent->position.z); glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].parent->blurred); glVertex3f(joints[i].parent->oldposition.x,joints[i].parent->oldposition.y,joints[i].parent->oldposition.z); glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].blurred); glVertex3f(joints[i].oldposition.x,joints[i].oldposition.y,joints[i].oldposition.z); } } for(int i=0; iblurred); glVertex3f(muscles[i].parent1->position.x,muscles[i].parent1->position.y,muscles[i].parent1->position.z); glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent2->blurred); glVertex3f(muscles[i].parent2->position.x,muscles[i].parent2->position.y,muscles[i].parent2->position.z); glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent2->blurred); glVertex3f(muscles[i].parent2->oldposition.x,muscles[i].parent2->oldposition.y,muscles[i].parent2->oldposition.z); glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent1->blurred); glVertex3f(muscles[i].parent1->oldposition.x,muscles[i].parent1->oldposition.y,muscles[i].parent1->oldposition.z); } } glEnd(); glBegin(GL_LINES); for(int i=0; iblurred); glVertex3f(joints[i].parent->position.x,joints[i].parent->position.y,joints[i].parent->position.z); } } for(int i=0; iblurred); glVertex3f(muscles[i].parent1->position.x,muscles[i].parent1->position.y,muscles[i].parent1->position.z); glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent2->blurred); glVertex3f(muscles[i].parent2->position.x,muscles[i].parent2->position.y,muscles[i].parent2->position.z); } } glColor3f(.6,.6,0); if(muscleview==1) for(int i=0; iposition.x,muscles[i].parent1->position.y,muscles[i].parent1->position.z); glVertex3f(muscles[i].parent2->position.x,muscles[i].parent2->position.y,muscles[i].parent2->position.z); } } glEnd(); if(muscleview!=2){ glPointSize(3); glBegin(GL_POINTS); for(int i=0; i=num_joints||which<0)joints[num_joints].hasparent=0; if(which=0){ joints[num_joints].parent=&joints[which]; joints[num_joints].hasparent=1; joints[num_joints].length=findDistance(joints[num_joints].position,joints[num_joints].parent->position); } num_joints++; } } void Skeleton::DeleteJoint(int whichjoint) { if(whichjoint=0){ for(int i=0;i=num_joints||which<0)joints[whichjoint].hasparent=0; if(which=0){ joints[whichjoint].parent=&joints[which]; joints[whichjoint].hasparent=1; joints[whichjoint].length=findDistance(joints[whichjoint].position,joints[whichjoint].parent->position); } } } void Skeleton::AddMuscle(int attach1,int attach2,float minlength,float maxlength,int type) { if (num_muscles < max_muscles - 1 && attach1 != attach2 && attach1 < num_joints && attach1 >= 0 && attach2 < num_joints && attach2 >= 0) { muscles[num_muscles].parent1=&joints[attach1]; muscles[num_muscles].parent2=&joints[attach2]; muscles[num_muscles].length=findDistance(muscles[num_muscles].parent1->position,muscles[num_muscles].parent2->position); muscles[num_muscles].targetlength=findDistance(muscles[num_muscles].parent1->position,muscles[num_muscles].parent2->position); muscles[num_muscles].strength=.7; muscles[num_muscles].type=type; muscles[num_muscles].minlength=minlength; muscles[num_muscles].maxlength=maxlength; num_muscles++; } } void Skeleton::MusclesSet() { for(int i=0;iposition,muscles[i].parent2->position); } } void Skeleton::FindRotationJoint(int which) { XYZ temppoint1,temppoint2,tempforward; float distance; temppoint1=joints[which].position; temppoint2=joints[which].parent->position; distance=findDistance(temppoint1,temppoint2); joints[which].rotate2=asin((temppoint1.y-temppoint2.y)/distance)*rad2deg; temppoint1.y=0; temppoint2.y=0; joints[which].rotate1=acos((temppoint1.z-temppoint2.z)/findDistance(temppoint1,temppoint2))*rad2deg; if(temppoint1.x>temppoint2.x)joints[which].rotate1=360-joints[which].rotate1; if(joints[which].label==head)tempforward=specialforward[0]; else if(joints[which].label==rightshoulder||joints[which].label==rightelbow||joints[which].label==rightwrist||joints[which].label==righthand)tempforward=specialforward[1]; else if(joints[which].label==leftshoulder||joints[which].label==leftelbow||joints[which].label==leftwrist||joints[which].label==lefthand)tempforward=specialforward[2]; else if(joints[which].label==righthip||joints[which].label==rightknee||joints[which].label==rightankle)tempforward=specialforward[3]; else if(joints[which].label==lefthip||joints[which].label==leftknee||joints[which].label==leftankle)tempforward=specialforward[4]; else if(!joints[which].lower)tempforward=forward; else if(joints[which].lower)tempforward=lowforward; tempforward=DoRotation(tempforward,0,joints[which].rotate1-90,0); tempforward=DoRotation(tempforward,0,0,joints[which].rotate2-90); tempforward.y=0; Normalise(&tempforward); joints[which].rotate3=acos(0-tempforward.z)*rad2deg; if(0>tempforward.x)joints[which].rotate3=360-joints[which].rotate3; } void Skeleton::FindRotationMuscle(int which) { XYZ temppoint1,temppoint2,tempforward; float distance; temppoint1=muscles[which].parent1->position; temppoint2=muscles[which].parent2->position; distance=findDistance(temppoint1,temppoint2); muscles[which].rotate2=asin((temppoint1.y-temppoint2.y)/distance)*rad2deg; temppoint1.y=0; temppoint2.y=0; muscles[which].rotate1=acos((temppoint1.z-temppoint2.z)/findDistance(temppoint1,temppoint2)); muscles[which].rotate1*=360/6.28; if(temppoint1.x>temppoint2.x)muscles[which].rotate1=360-muscles[which].rotate1; if(muscles[which].parent1->label==head)tempforward=specialforward[0]; else if(muscles[which].parent1->label==rightshoulder||muscles[which].parent1->label==rightelbow||muscles[which].parent1->label==rightwrist)tempforward=specialforward[1]; else if(muscles[which].parent1->label==leftshoulder||muscles[which].parent1->label==leftelbow||muscles[which].parent1->label==leftwrist)tempforward=specialforward[2]; else if(muscles[which].parent1->label==righthip||muscles[which].parent1->label==rightknee||muscles[which].parent1->label==rightankle)tempforward=specialforward[3]; else if(muscles[which].parent1->label==lefthip||muscles[which].parent1->label==leftknee||muscles[which].parent1->label==leftankle)tempforward=specialforward[4]; else if(!muscles[which].parent1->lower)tempforward=forward; else if(muscles[which].parent1->lower)tempforward=lowforward; tempforward=DoRotation(tempforward,0,muscles[which].rotate1-90,0); tempforward=DoRotation(tempforward,0,0,muscles[which].rotate2-90); tempforward.y=0; Normalise(&tempforward); muscles[which].rotate3=acos(0-tempforward.z)*rad2deg; for(int i=0;itempforward.x)muscles[which].rotate3=360-muscles[which].rotate3; } extern Skeleton testskeleton; void Animation::Load(char *fileName) { files.OpenFile(fileName); if(files.sFile){ ReadInt(files.sFile, 1, &numframes); for(int i=0;imrotate3[i][j-1]+180)mrotate3[i][j]-=360; if(j!=0&&mrotate3[i][j]mrotate2[i][j-1]+180)mrotate2[i][j]-=360; if(j!=0&&mrotate2[i][j]mrotate1[i][j-1]+180)mrotate1[i][j]-=360; if(j!=0&&mrotate1[i][j]rotate3[i][j-1]+180)rotate3[i][j]-=360; if(j!=0&&rotate3[i][j]rotate2[i][j-1]+180)rotate2[i][j]-=360; if(j!=0&&rotate2[i][j]rotate1[i][j-1]+180)rotate1[i][j]-=360; if(j!=0&&rotate1[i][j]mrotate3[i][j-1]+180)mrotate3[i][j]-=360; if(j!=0&&mrotate3[i][j]mrotate2[i][j-1]+180)mrotate2[i][j]-=360; if(j!=0&&mrotate2[i][j]mrotate1[i][j-1]+180)mrotate1[i][j]-=360; if(j!=0&&mrotate1[i][j]mrotate3[i][numframes-1]+180)mrotate3[i][j]-=360; if(j==0&&mrotate3[i][j]mrotate2[i][numframes-1]+180)mrotate2[i][j]-=360; if(j==0&&mrotate2[i][j]mrotate1[i][numframes-1]+180)mrotate1[i][j]-=360; if(j==0&&mrotate1[i][j]rotate3[i][j-1]+180)rotate3[i][j]-=360; if(j!=0&&rotate3[i][j]rotate2[i][j-1]+180)rotate2[i][j]-=360; if(j!=0&&rotate2[i][j]rotate1[i][j-1]+180)rotate1[i][j]-=360; if(j!=0&&rotate1[i][j]rotate3[i][numframes-1]+180)rotate3[i][j]-=360; if(j==0&&rotate3[i][j]rotate2[i][numframes-1]+180)rotate2[i][j]-=360; if(j==0&&rotate2[i][j]rotate1[i][numframes-1]+180)rotate1[i][j]-=360; if(j==0&&rotate1[i][j]mrotate3[i][j-1]+180)mrotate3[i][j]-=360; if(j!=0&&mrotate3[i][j]mrotate2[i][j-1]+180)mrotate2[i][j]-=360; if(j!=0&&mrotate2[i][j]mrotate1[i][j-1]+180)mrotate1[i][j]-=360; if(j!=0&&mrotate1[i][j]rotate3[i][j-1]+180)rotate3[i][j]-=360; if(j!=0&&rotate3[i][j]rotate2[i][j-1]+180)rotate2[i][j]-=360; if(j!=0&&rotate2[i][j]rotate1[i][j-1]+180)rotate1[i][j]-=360; if(j!=0&&rotate1[i][j]mrotate3[i][j-1]+180)mrotate3[i][j]-=360; if(j!=0&&mrotate3[i][j]mrotate2[i][j-1]+180)mrotate2[i][j]-=360; if(j!=0&&mrotate2[i][j]mrotate1[i][j-1]+180)mrotate1[i][j]-=360; if(j!=0&&mrotate1[i][j]mrotate3[i][numframes-1]+180)mrotate3[i][j]-=360; if(j==0&&mrotate3[i][j]mrotate2[i][numframes-1]+180)mrotate2[i][j]-=360; if(j==0&&mrotate2[i][j]mrotate1[i][numframes-1]+180)mrotate1[i][j]-=360; if(j==0&&mrotate1[i][j]rotate3[i][j-1]+180)rotate3[i][j]-=360; if(j!=0&&rotate3[i][j]rotate2[i][j-1]+180)rotate2[i][j]-=360; if(j!=0&&rotate2[i][j]rotate1[i][j-1]+180)rotate1[i][j]-=360; if(j!=0&&rotate1[i][j]rotate3[i][numframes-1]+180)rotate3[i][j]-=360; if(j==0&&rotate3[i][j]rotate2[i][numframes-1]+180)rotate2[i][j]-=360; if(j==0&&rotate2[i][j]rotate1[i][numframes-1]+180)rotate1[i][j]-=360; if(j==0&&rotate1[i][j]