CalSpringSystem::CalSpringSystem() : m_pModel(0) { m_vGravity = CalVector(0.0f, 0.0f, -98.1f); // We add this force to simulate some movement m_vForce = CalVector(0.0f, 0.5f, 0.0f); }
CalSpringSystem::CalSpringSystem(CalModel* pModel) { assert(pModel); m_pModel = pModel; m_vGravity = CalVector(0.0f, 0.0f, -98.1f); // We add this force to simulate some movement m_vForce = CalVector(0.0f, 0.5f, 0.0f); m_collision=false; }
void CalCoreBone::initBoundingBox() { CalQuaternion rot; rot=m_rotationBoneSpace; rot.invert(); CalVector dir = CalVector(1.0f,0.0f,0.0f); dir*=rot; m_boundingBox.plane[0].setNormal(dir); dir = CalVector(-1.0f,0.0f,0.0f); dir*=rot; m_boundingBox.plane[1].setNormal(dir); dir = CalVector(0.0f,1.0f,0.0f); dir*=rot; m_boundingBox.plane[2].setNormal(dir); dir = CalVector(0.0f,-1.0f,0.0f); dir*=rot; m_boundingBox.plane[3].setNormal(dir); dir = CalVector(0.0f,0.0f,1.0f); dir*=rot; m_boundingBox.plane[4].setNormal(dir); dir = CalVector(0.0f,0.0f,-1.0f); dir*=rot; m_boundingBox.plane[5].setNormal(dir); }
///////////////////////////////////// // Purpose: set the relative translation // of the given bone // Output: bone moved // Return: none ///////////////////////////////////// void IgfxObject::BoneSetTrans(s32 boneID, const Vec3D & loc) { if(m_pCalModel) { Vec3D trans; BoneGetTrans(boneID, &trans); CalSkeleton *pSkel = m_pCalModel->getSkeleton(); CalBone *pBone = pSkel->getBone(boneID); if(pBone) { pBone->setTranslation(CalVector(trans.x+loc.x, trans.y+loc.y, trans.z+loc.z)); pBone->calculateState(); } } }
void CalBone::calculateBoundingBox() { if(!getCoreBone()->isBoundingBoxPrecomputed()) return; CalVector dir = CalVector(1.0f,0.0f,0.0f); dir*=getTransformMatrix(); m_boundingBox.plane[0].setNormal(dir); dir = CalVector(-1.0f,0.0f,0.0f); dir*=getTransformMatrix(); m_boundingBox.plane[1].setNormal(dir); dir = CalVector(0.0f,1.0f,0.0f); dir*=getTransformMatrix(); m_boundingBox.plane[2].setNormal(dir); dir = CalVector(0.0f,-1.0f,0.0f); dir*=getTransformMatrix(); m_boundingBox.plane[3].setNormal(dir); dir = CalVector(0.0f,0.0f,1.0f); dir*=getTransformMatrix(); m_boundingBox.plane[4].setNormal(dir); dir = CalVector(0.0f,0.0f,-1.0f); dir*=getTransformMatrix(); m_boundingBox.plane[5].setNormal(dir); int i; for(i=0;i< 6; i++) { CalVector position; getCoreBone()->getBoundingData(i,position); position*=getTransformMatrix(); position+=getTranslationBoneSpace(); int planeId; for(planeId = 0; planeId < 6; ++planeId) { if(m_boundingBox.plane[planeId].eval(position) < 0.0f) { m_boundingBox.plane[planeId].setPosition(position); } } } }
CalVector CalPhysique::calculateVertex(CalSubmesh *pSubmesh, int vertexId) { // get bone vector of the skeleton std::vector<CalBone *>& vectorBone = m_pModel->getSkeleton()->getVectorBone(); // get vertex of the core submesh std::vector<CalCoreSubmesh::Vertex>& vectorVertex = pSubmesh->getCoreSubmesh()->getVectorVertex(); // get physical property vector of the core submesh //std::vector<CalCoreSubmesh::PhysicalProperty>& vectorPhysicalProperty = pSubmesh->getCoreSubmesh()->getVectorPhysicalProperty(); // get the sub morph target vector from the core sub mesh std::vector<CalCoreSubMorphTarget*>& vectorSubMorphTarget = pSubmesh->getCoreSubmesh()->getVectorCoreSubMorphTarget(); // get the number of morph targets int morphTargetCount = pSubmesh->getMorphTargetWeightCount(); // get the vertex CalCoreSubmesh::Vertex& vertex = vectorVertex[vertexId]; // blend the morph targets CalVector position=vertex.position; { int morphTargetId; for(morphTargetId=0; morphTargetId < morphTargetCount;++morphTargetId) { CalCoreSubMorphTarget::BlendVertex blendVertex; vectorSubMorphTarget[morphTargetId]->getBlendVertex(vertexId, blendVertex); float currentWeight = pSubmesh->getMorphTargetWeight(morphTargetId); position.x += currentWeight*blendVertex.position.x; position.y += currentWeight*blendVertex.position.y; position.z += currentWeight*blendVertex.position.z; } } // initialize vertex float x, y, z; x = 0.0f; y = 0.0f; z = 0.0f; // blend together all vertex influences int influenceId; int influenceCount=(int)vertex.vectorInfluence.size(); if(influenceCount == 0) { x = position.x; y = position.y; z = position.z; } else { for(influenceId = 0; influenceId < influenceCount; ++influenceId) { // get the influence CalCoreSubmesh::Influence& influence = vertex.vectorInfluence[influenceId]; // get the bone of the influence vertex CalBone *pBone; pBone = vectorBone[influence.boneId]; // transform vertex with current state of the bone CalVector v(position); v *= pBone->getTransformMatrix(); v += pBone->getTranslationBoneSpace(); x += influence.weight * v.x; y += influence.weight * v.y; z += influence.weight * v.z; } } /* // save vertex position if(pSubmesh->getCoreSubmesh()->getSpringCount() > 0 && pSubmesh->hasInternalData()) { // get the pgysical property of the vertex CalCoreSubmesh::PhysicalProperty& physicalProperty = vectorPhysicalProperty[vertexId]; // assign new vertex position if there is no vertex weight if(physicalProperty.weight == 0.0f) { pVertexBuffer[0] = x; pVertexBuffer[1] = y; pVertexBuffer[2] = z; } } else { pVertexBuffer[0] = x; pVertexBuffer[1] = y; pVertexBuffer[2] = z; } */ // return the vertex //return CalVector(x, y, z); return CalVector(x*m_axisFactorX,y*m_axisFactorY,z*m_axisFactorZ); }
void CalSpringSystem::calculateVertices(CalSubmesh *pSubmesh, float deltaTime) { // get the vertex vector of the submesh std::vector<CalVector>& vectorVertex = pSubmesh->getVectorVertex(); // get the physical property vector of the submesh std::vector<CalSubmesh::PhysicalProperty>& vectorPhysicalProperty = pSubmesh->getVectorPhysicalProperty(); // get the physical property vector of the core submesh std::vector<CalCoreSubmesh::PhysicalProperty>& vectorCorePhysicalProperty = pSubmesh->getCoreSubmesh()->getVectorPhysicalProperty(); // loop through all the vertices int vertexId; for(vertexId = 0; vertexId < (int)vectorVertex.size(); ++vertexId) { // get the vertex CalVector& vertex = vectorVertex[vertexId]; // get the physical property of the vertex CalSubmesh::PhysicalProperty& physicalProperty = vectorPhysicalProperty[vertexId]; // get the physical property of the core vertex CalCoreSubmesh::PhysicalProperty& corePhysicalProperty = vectorCorePhysicalProperty[vertexId]; // store current position for later use CalVector position; position = physicalProperty.position; // only take vertices with a weight > 0 into account if(corePhysicalProperty.weight > 0.0f) { // do the Verlet step physicalProperty.position += (position - physicalProperty.positionOld) * 0.99f + physicalProperty.force / corePhysicalProperty.weight * deltaTime * deltaTime; CalSkeleton *pSkeleton = m_pModel->getSkeleton(); if(m_collision) { std::vector<CalBone *> &m_vectorbone = pSkeleton->getVectorBone(); unsigned long boneId; for(boneId=0; boneId < m_vectorbone.size(); boneId++) { CalBoundingBox p = m_vectorbone[boneId]->getBoundingBox(); bool in=true; float min=1e10; int index=-1; int faceId; for(faceId=0; faceId < 6 ; faceId++) { if(p.plane[faceId].eval(physicalProperty.position)<=0) { in=false; } else { float dist=p.plane[faceId].dist(physicalProperty.position); if(dist<min) { index=faceId; min=dist; } } } if(in && index!=-1) { CalVector normal = CalVector(p.plane[index].a,p.plane[index].b,normal.z = p.plane[index].c); normal.normalize(); physicalProperty.position = physicalProperty.position - min*normal; } in=true; for(faceId=0; faceId < 6 ; faceId++) { if(p.plane[faceId].eval(physicalProperty.position) < 0 ) { in=false; } } if(in) { physicalProperty.position = vectorVertex[vertexId]; } } } } else { physicalProperty.position = vectorVertex[vertexId]; } // make the current position the old one physicalProperty.positionOld = position; // set the new position of the vertex vertex = physicalProperty.position; // clear the accumulated force on the vertex physicalProperty.force.clear(); } // get the spring vector of the core submesh std::vector<CalCoreSubmesh::Spring>& vectorSpring = pSubmesh->getCoreSubmesh()->getVectorSpring(); // iterate a few times to relax the constraints int iterationCount; #define ITERATION_COUNT 2 for(iterationCount = 0; iterationCount < ITERATION_COUNT; ++iterationCount) { // loop through all the springs std::vector<CalCoreSubmesh::Spring>::iterator iteratorSpring; for(iteratorSpring = vectorSpring.begin(); iteratorSpring != vectorSpring.end(); ++iteratorSpring) { // get the spring CalCoreSubmesh::Spring& spring = *iteratorSpring; // compute the difference between the two spring vertices CalVector distance; distance = vectorVertex[spring.vertexId[1]] - vectorVertex[spring.vertexId[0]]; // get the current length of the spring float length; length = distance.length(); if(length > 0.0f) { /*if (spring.springCoefficient == 0) { vectorVertex[spring.vertexId[1]] = vectorVertex[spring.vertexId[0]]; vectorPhysicalProperty[spring.vertexId[1]].position = vectorVertex[spring.vertexId[0]]; } else {*/ float factor[2]; factor[0] = (length - spring.idleLength) / length; factor[1] = factor[0]; if(vectorCorePhysicalProperty[spring.vertexId[0]].weight > 0.0f) { factor[0] /= 2.0f; factor[1] /= 2.0f; } else { factor[0] = 0.0f; } if(vectorCorePhysicalProperty[spring.vertexId[1]].weight <= 0.0f) { factor[0] *= 2.0f; factor[1] = 0.0f; } vectorVertex[spring.vertexId[0]] += distance * factor[0]; vectorPhysicalProperty[spring.vertexId[0]].position = vectorVertex[spring.vertexId[0]]; vectorVertex[spring.vertexId[1]] -= distance * factor[1]; vectorPhysicalProperty[spring.vertexId[1]].position = vectorVertex[spring.vertexId[1]]; //} } } } /* DEBUG-CODE ******************** CalVector spherePosition(Sphere.x, Sphere.y, Sphere.z); float sphereRadius = Sphere.radius; // loop through all the vertices for(vertexId = 0; vertexId < (int)vectorVertex.size(); ++vertexId) { // get the vertex CalVector& vertex = vectorVertex[vertexId]; // get the physical property of the vertex CalSubmesh::PhysicalProperty& physicalProperty = vectorPhysicalProperty[vertexId]; // get the physical property of the core vertex CalCoreSubmesh::PhysicalProperty& corePhysicalProperty = vectorCorePhysicalProperty[vertexId]; // only take vertices with a weight > 0 into account if(corePhysicalProperty.weight > 0.0f) { CalVector position; position = physicalProperty.position; position -= spherePosition; float length; length = position.normalize(); if(length < sphereRadius) { position *= sphereRadius; position += spherePosition; physicalProperty.position = position; physicalProperty.positionOld = position; vertex = physicalProperty.position; } } } *********************************/ }
static void generateTangentAndHandednessBuffer( osgCal::MeshData* m, const CalIndex* indexBuffer ) { if ( !m->texCoordBuffer.valid() ) { return; } int vertexCount = m->vertexBuffer->size(); int faceCount = m->getIndicesCount() / 3; m->tangentAndHandednessBuffer = new TangentAndHandednessBuffer( vertexCount ); CalVector* tan1 = new CalVector[vertexCount]; CalVector* tan2 = new CalVector[vertexCount]; const GLfloat* texCoordBufferData = (GLfloat*) m->texCoordBuffer->getDataPointer(); const GLfloat* vb = (GLfloat*) m->vertexBuffer->getDataPointer(); #ifdef OSG_CAL_BYTE_BUFFERS GLfloat* thb = new GLfloat[ vertexCount*4 ]; const GLfloat* nb = floatNormalBuffer; #else GLfloat* thb = (GLfloat*) m->tangentAndHandednessBuffer->getDataPointer(); // GLshort* thb = (GLshort*) m->tangentAndHandednessBuffer->getDataPointer(); const GLfloat* nb = (GLfloat*) m->normalBuffer->getDataPointer(); #endif for ( int face = 0; face < faceCount; face++ ) { for ( int j = 0; j < 3; j++ ) { // there seems to be no visual difference in calculating // tangent per vertex (as is tan1[i1] += spos(j=0,1,2)) // or per face (tan1[i1,i2,i3] += spos) CalIndex i1 = indexBuffer[face*3+(j+0)%3]; CalIndex i2 = indexBuffer[face*3+(j+1)%3]; CalIndex i3 = indexBuffer[face*3+(j+2)%3]; const float* v1 = &vb[i1*3]; const float* v2 = &vb[i2*3]; const float* v3 = &vb[i3*3]; const float* w1 = &texCoordBufferData[i1*2]; const float* w2 = &texCoordBufferData[i2*2]; const float* w3 = &texCoordBufferData[i3*2]; #define x(_a) (_a[0]) #define y(_a) (_a[1]) #define z(_a) (_a[2]) float x1 = x(v2) - x(v1); float x2 = x(v3) - x(v1); float y1 = y(v2) - y(v1); float y2 = y(v3) - y(v1); float z1 = z(v2) - z(v1); float z2 = z(v3) - z(v1); float s1 = x(w2) - x(w1); float s2 = x(w3) - x(w1); float t1 = y(w2) - y(w1); float t2 = y(w3) - y(w1); #undef x #undef y #undef z //float r = 1.0F / (s1 * t2 - s2 * t1); float r = (s1 * t2 - s2 * t1) < 0 ? -1.0 : 1.0; CalVector sdir((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r); CalVector tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r); // sdir & tdir can be 0 (when UV unwrap doesn't exists // or has errors like coincide points) // we ignore them if ( sdir.length() > 0 ) { sdir.normalize(); tan1[i1] += sdir; //tan1[i2] += sdir; //tan1[i3] += sdir; } if ( tdir.length() > 0 ) { tdir.normalize(); tan2[i1] += tdir; //tan2[i2] += tdir; //tan2[i3] += tdir; } } } for (long a = 0; a < vertexCount; a++) { CalVector tangent; CalVector binormal; CalVector t = tan1[a]; CalVector b = tan2[a]; CalVector n = CalVector( nb[a*3+0], nb[a*3+1], nb[a*3+2] ); // tangent & bitangent can be zero when UV unwrap doesn't exists // or has errors like coincide points if ( t.length() > 0 ) { t.normalize(); // Gram-Schmidt orthogonalize tangent = t - n * (n*t); tangent.normalize(); // Calculate handedness binormal = CalVector(n % tangent) * ((((n % t) * b) < 0.0F) ? -1.0f : 1.0f); binormal.normalize(); } else if ( b.length() > 0 ) { b.normalize(); // Gram-Schmidt orthogonalize binormal = b - n * (n*b); binormal.normalize(); // Calculate handedness tangent = CalVector(n % binormal) * ((((n % b) * t) < 0.0F) ? -1.0f : 1.0f); tangent.normalize(); } // std::cout << "t = " << tangent.x << '\t' << tangent.y << '\t' << tangent.z << '\n'; // std::cout << "b = " << binormal.x << '\t' << binormal.y << '\t' << binormal.z << '\n'; // std::cout << "n = " << n.x << '\t' << n.y << '\t' << n.z << '\n'; // thb[a*4+0] = floatToHalf( tangent.x ); //tangent.x * 0x7FFF; // thb[a*4+1] = floatToHalf( tangent.y ); //tangent.y * 0x7FFF; // thb[a*4+2] = floatToHalf( tangent.z ); //tangent.z * 0x7FFF; // thb[a*4+3] = floatToHalf((((n % tangent) * binormal) > 0.0F) ? -1.0f : 1.0f); // handedness thb[a*4+0] = tangent.x; thb[a*4+1] = tangent.y; thb[a*4+2] = tangent.z; thb[a*4+3] = ((((n % tangent) * binormal) > 0.0F) ? -1.0f : 1.0f); // handedness } delete[] tan1; delete[] tan2; #ifdef OSG_CAL_BYTE_BUFFERS GLbyte* tangents = (GLbyte*) tangentBuffer->getDataPointer(); GLbyte* binormals = (GLbyte*) binormalBuffer->getDataPointer(); for ( int i = 0; i < vertexCount*3; i++ ) { tangents[i] = static_cast< GLbyte >( tangentBuffer[i]*127.0 ); binormals[i] = static_cast< GLbyte >( binormalBuffer[i]*127.0 ); //std::cout << (int)tangents[i] << '\n'; } delete[] tangentBuffer; delete[] binormalBuffer; #endif }
bool CPhysxSkeleton::AddSphericalJoint(CXMLTreeNode _XMLObjects) { string l_szActor1, l_szActor2, l_szDirection; l_szActor1 = _XMLObjects.GetAttribute<std::string>("Actor1" , ""); l_szActor2 = _XMLObjects.GetAttribute<std::string>("Actor2" , ""); l_szDirection = _XMLObjects.GetAttribute<std::string>("Direction" , ""); SSphericalLimitInfo l_pJointInfo = GetJointParameterInfo(_XMLObjects); CPhysxBone* l_pBone1 = GetPhysxBoneByName(l_szActor1); CPhysxBone* l_pBone2 = GetPhysxBoneByName(l_szActor2); CPhysicActor* l_pActor1 = 0; CPhysicActor* l_pActor2 = 0; l_pActor1 = l_pBone1->GetPhysxActor(); CPhysicSphericalJoint* l_pSphericalJoint = 0; l_pSphericalJoint = new CPhysicSphericalJoint(); CalVector l_vCalVect = l_pBone1->GetCalBone()->getTranslationAbsolute(); Math::Vect3f l_vJointPoint(-l_vCalVect.x, l_vCalVect.y, l_vCalVect.z); l_vJointPoint = m_mTransform * l_vJointPoint; Math::Vect3f l_vAxis; CalVector l_vVect; //MES PROVES if (l_szDirection == "Out") { if (l_pBone1->GetChildList().size() > 0) { int l_pChildId = l_pBone1->GetChildList()[0]; string l_szNameChild = m_pCalSkeleton->getBone(l_pChildId)->getCoreBone()->getName(); CPhysxBone* l_pPhysChild = GetPhysxBoneByName(l_szNameChild); l_vVect = l_pPhysChild->GetCalBone()->getTranslationAbsolute(); l_vVect.x = -l_vVect.x; /* l_vAxis = Math::Vect3f(l_vVect.x-l_vJointPoint.x,l_vVect.y-l_vJointPoint.y,l_vVect.z-l_vJointPoint.z); l_vAxis.Normalize();*/ } else { Math::Vect3f l_vMiddle = l_pBone1->GetMiddlePoint(); l_vVect = CalVector(l_vMiddle.x, l_vMiddle.y, l_vMiddle.z); /* l_vAxis(l_vMiddle.x-l_vJointPoint.x,l_vMiddle.y-l_vJointPoint.y,l_vMiddle.z-l_vJointPoint.z); l_vAxis.Normalize();*/ } } else if (l_szDirection == "In") { /* if (!l_pBone1->IsBoneRoot()) { int l_pParentID = l_pBone1->GetParentID(); string l_szNameParent = m_pCalSkeleton->getBone(l_pParentID)->getCoreBone()->getName(); CPhysxBone* l_pPhysParent = GetPhysxBoneByName(l_szNameParent); CalVector l_vVect = l_pPhysParent->GetCalBone()->getTranslationAbsolute(); l_vVect.x = -l_vVect.x; /* l_vAxis = Math::Vect3f(l_vVect.x-l_vJointPoint.x,l_vVect.y-l_vJointPoint.y,l_vVect.z-l_vJointPoint.z); l_vAxis.Normalize(); } */ } Math::Vect3f l_vAxisAux(l_vVect.x, l_vVect.y, l_vVect.z); l_vAxisAux = m_mTransform * l_vAxisAux; l_vAxis = Math::Vect3f(l_vAxisAux.x - l_vJointPoint.x, l_vAxisAux.y - l_vJointPoint.y, l_vAxisAux.z - l_vJointPoint.z); l_vAxis.Normalize(); l_pJointInfo.m_vAnchor = l_vJointPoint; l_pJointInfo.m_vAxis = l_vAxis; if (l_szActor2 == "NULL") { //l_pSphericalJoint->SetInfoComplete(l_vJointPoint,l_vAxis,l_pActor1); l_pSphericalJoint->SetInfoRagdoll(l_pJointInfo, l_pActor1); } else { l_pActor2 = l_pBone2->GetPhysxActor(); //l_pSphericalJoint->SetInfoComplete(l_vJointPoint,l_vAxis,l_pActor1,l_pActor2); l_pSphericalJoint->SetInfoRagdoll(l_pJointInfo, l_pActor1, l_pActor2); } PhysXMInstance->AddPhysicSphericalJoint(l_pSphericalJoint); m_vSphericalJoints.push_back(l_pSphericalJoint); return true; }
void IKTagger::update( float elapsed ) { bool do_ik = false; float ik_fade_speed = 1.0f; bool sidestep_allowed = false; model.updateAnimation( elapsed ); switch( state ) { case TS_WAITING: break; case TS_WALKON: { // check for walk cycle CalVector loop_root_pos; if ( model.animationDidLoop( "walk", &loop_root_pos ) ) { printf("-- walk looped\n"); root_pos += (loop_root_pos)-model.getRootBonePosition(); if ( fabsf(root_pos.x-tag_start_x) < fabsf(walk_cycle_dx) ) { // stop the walk model.stopCycle( WALK_ANIM ); model.startCycle( IDLE_ANIM ); model.doAction( WALK_TO_TURN_ANIM ); // turning state = TS_WALK_TO_TURN; printf(" --> turning\n"); } } } break; case TS_WALK_TO_TURN: { do_ik = false; ik_target_weight = 1.0f; ik_fade_speed = 0.33f; if ( model.actionDidFinish( WALK_TO_TURN_ANIM ) ) { // animation finished: update root position from animation displacement setRootPosition( root_pos+walk_to_turn_root_displacement ); // now tagging state = TS_TAGGING; printf(" --> tagging\n"); } } break; case TS_TAGGING: { do_ik = true; if ( ik_weight > 0.9f ) sidestep_allowed = true; ik_target_weight = 1.0f; // check for sidestep // if finished, update root position from sidestep displacement if ( sidestep_running && model.actionDidFinish( SIDESTEP_L_ANIM ) ) { printf("sidestep l finished\n"); sidestep_running = false; setRootPosition( root_pos+sidestep_l_root_displacement ); } if ( sidestep_running && model.actionDidFinish( SIDESTEP_R_ANIM ) ) { printf("sidestep r finished\n"); sidestep_running = false; setRootPosition( root_pos+sidestep_r_root_displacement ); } if ( sidestep_running && model.actionDidFinish( SIDESTEP_BIG_L_ANIM ) ) { printf("sidestep big l finished\n"); sidestep_running = false; setRootPosition( root_pos+sidestep_big_l_root_displacement ); } if ( sidestep_running && model.actionDidFinish( SIDESTEP_BIG_R_ANIM ) ) { printf("sidestep big r finished\n"); sidestep_running = false; setRootPosition( root_pos+sidestep_big_r_root_displacement ); } // wait for sidesteps to finish if ( !sidestep_running && should_walk_off ) { state = TS_TURN_TO_WALK; model.doAction( TURN_TO_WALK_ANIM ); sidestep_allowed = false; printf(" --> turn_to_walk\n") ; } } break; case TS_TURN_TO_WALK: { do_ik = true; ik_target_weight = 0.0f; // check if turn is finished the walkoff if ( model.actionDidFinish( TURN_TO_WALK_ANIM ) ) { setRootPosition( root_pos+turn_to_walk_root_displacement ); model.stopCycle( IDLE_ANIM ); model.startCycle( WALK_ANIM ); // push through the new cycle immediately model.updateAnimation( 0.000001f ); state = TS_WALKOFF; do_ik = false; printf(" --> walkoff\n"); } } break; case TS_WALKOFF: { if ( model.animationDidLoop( "walk" ) ) { printf("-- walk looped\n"); setRootPosition( root_pos + walk_root_displacement ); if ( root_pos.x < SCREEN_VISIBLE_RIGHT ) { state = TS_FINISHED; model.stopCycle( WALK_ANIM ); } } } break; case TS_FINISHED: break; default: break; } if ( do_ik ) { // update ik weight float inc = elapsed*ik_fade_speed; if ( ik_weight > ik_target_weight ) ik_weight -= min(inc,ik_weight-ik_target_weight); else ik_weight += min(inc,ik_target_weight-ik_weight); // ease in/out float ik_weight_eased = 0.5f+0.5f*cosf((1.0f-ik_weight)*PI); //printf("ik weight: target %7.5f, curr %7.5f\n", ik_target_weight, ik_weight ); //ik_weight += (ik_target_weight-ik_weight)*speed; character.pullFromModel(); character.solve( 2 ); character.pushToModel( true, ik_weight_eased ); model.updateMesh(); CalVector arm_actual_position = model.getBonePosition( tag_arm ); ofxVec3f arm_target = character.getTarget(tag_arm); CalVector bone_target_delta = CalVector(arm_target.x,arm_target.y,arm_target.z)-arm_actual_position; // vertical distance has less effect bone_target_delta.y *= 0.5f; float distance = bone_target_delta.length(); float discomfort = distance/COMFORT_DISTANCE_THRESH; if ( discomfort > 1.0f && !sidestep_running && sidestep_allowed ) { // need to move feet string anim; if ( bone_target_delta.x < 0 ) { if (bone_target_delta.x < -0.75f ) anim = SIDESTEP_BIG_L_ANIM; else anim = SIDESTEP_L_ANIM; } else { if (bone_target_delta.x > 0.75f ) anim = SIDESTEP_BIG_R_ANIM; else anim = SIDESTEP_R_ANIM; } printf("starting %s, target delta is %f, discomfort %f\n", anim.c_str(), bone_target_delta.x, discomfort ); model.doAction( anim, 1.0f ); sidestep_running = true; } last_discomfort = discomfort; } else last_discomfort = 100.0f; }
void CalCoreBone::calculateBoundingBox(CalCoreModel * pCoreModel) { int boneId = m_pCoreSkeleton->getCoreBoneId(m_strName); bool bBoundsComputed=false; int planeId; CalQuaternion rot; rot=m_rotationBoneSpace; rot.invert(); CalVector dir = CalVector(1.0f,0.0f,0.0f); dir*=rot; m_boundingBox.plane[0].setNormal(dir); dir = CalVector(-1.0f,0.0f,0.0f); dir*=rot; m_boundingBox.plane[1].setNormal(dir); dir = CalVector(0.0f,1.0f,0.0f); dir*=rot; m_boundingBox.plane[2].setNormal(dir); dir = CalVector(0.0f,-1.0f,0.0f); dir*=rot; m_boundingBox.plane[3].setNormal(dir); dir = CalVector(0.0f,0.0f,1.0f); dir*=rot; m_boundingBox.plane[4].setNormal(dir); dir = CalVector(0.0f,0.0f,-1.0f); dir*=rot; m_boundingBox.plane[5].setNormal(dir); int meshId; for(meshId=0; meshId < pCoreModel->getCoreMeshCount(); ++meshId) { CalCoreMesh * pCoreMesh = pCoreModel->getCoreMesh(meshId); int submeshId; for(submeshId=0;submeshId<pCoreMesh->getCoreSubmeshCount();submeshId++) { CalCoreSubmesh *pCoreSubmesh = pCoreMesh->getCoreSubmesh(submeshId); if(pCoreSubmesh->getSpringCount()==0) { std::vector<CalCoreSubmesh::Vertex>& vectorVertex = pCoreSubmesh->getVectorVertex(); for(size_t vertexId=0;vertexId <vectorVertex.size(); ++vertexId) { for(size_t influenceId=0;influenceId<vectorVertex[vertexId].vectorInfluence.size();++influenceId) { if(vectorVertex[vertexId].vectorInfluence[influenceId].boneId == boneId && vectorVertex[vertexId].vectorInfluence[influenceId].weight > 0.5f) { for(planeId = 0; planeId < 6; ++planeId) { if(m_boundingBox.plane[planeId].eval(vectorVertex[vertexId].position) < 0.0f) { m_boundingBox.plane[planeId].setPosition(vectorVertex[vertexId].position); m_boundingPosition[planeId]=vectorVertex[vertexId].position; bBoundsComputed=true; } } } } } } } } // To handle bones with no vertices assigned if(!bBoundsComputed) { for(planeId = 0; planeId < 6; ++planeId) { m_boundingBox.plane[planeId].setPosition(m_translation); m_boundingPosition[planeId] = m_translation; } } m_boundingBoxPrecomputed = true; }
void CalCoreSkeleton::rotate(CalQuaternion &rot) { cal3d::RotateTranslate rt(rot, CalVector(0, 0, 0)); rotateTranslate(rt); }