/**> HEADER FILES <**/ #include "Camera.h" #include "Skeleton.h" #include "misc.h" extern float multiplier; extern unsigned int gSourceID[37]; 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 i = 0; i < numrepeats; ++i) for (auto& joint : joints) joint.DoConstraint(); } void Skeleton::DoConstraints(Model *collide, XYZ *move, float rotation) { friction = 20; move->y += 0.35; groundlevel = 0; numrepeats = 2; for (int j = 0; j < numrepeats; j++) { for (int i = 0; i < max_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 = true; 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 < max_joints; k++) avgvelocity += joints[k].velocity; avgvelocity /= max_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)) { auto soundpos = pos - camera.position; playSound(gSourceID[landsound], soundpos.x, soundpos.y, soundpos.z); } } } for (int i = 0; i < num_muscles; i++) //Length constraints muscles[i].DoConstraint(broken); } for (int i = 0; i < max_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 (auto& joint : joints) joint.velocity.y += gravity * multiplier; } void Skeleton::Draw(int muscleview) { float jointcolor[4]; if(muscleview!=2){ jointcolor[0]=0; jointcolor[1]=0; jointcolor[2]=.5; jointcolor[3]=1; } if(muscleview==2){ jointcolor[0]=0; jointcolor[1]=0; jointcolor[2]=0; jointcolor[3]=.5; } //Calc motionblur-ness 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= 0) { for(int i=0;iposition; 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 (auto& joint : joints) if (&joint == muscles[which].parent1) { joint.rotate1=muscles[which].rotate1; joint.rotate2=muscles[which].rotate2; joint.rotate3=muscles[which].rotate3; } if(0>tempforward.x)muscles[which].rotate3=360-muscles[which].rotate3; } extern Skeleton testskeleton; void Animation::load(const char* name) { auto data = loadAnimation(name); numframes = data.len; for (size_t i = 0; i < numframes; ++i) { for (size_t j = 0; j < max_joints; ++j) { position[j][i].x = data.ptr[i].joints[j].x; position[j][i].y = data.ptr[i].joints[j].y; position[j][i].z = data.ptr[i].joints[j].z; } speed[i] = data.ptr[i].speed; } free(data.ptr); for(int j=0;jrotate3[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][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]