void Skeleton::update( const float &time, bool updateAnim) { if( updateAnim ) { // update all bones local values (rotation fcurves) int c = 0; for(int i=0; i<m_bones.size(); ++i ) { //float rx = getBone(i)->localEulerRotation.x; //float ry = getBone(i)->localEulerRotation.y; //float rz = getBone(i)->localEulerRotation.z; //if( ((FCurve*)m_localEulerRotationAnims.m_data[c])->m_numKeys > 0 ) // rx = math::degToRad(((FCurve*)m_localEulerRotationAnims.m_data[c])->eval(time)); //if( ((FCurve*)m_localEulerRotationAnims.m_data[c+1])->m_numKeys > 0 ) // ry = math::degToRad(((FCurve*)m_localEulerRotationAnims.m_data[c+1])->eval(time)); //if( ((FCurve*)m_localEulerRotationAnims.m_data[c+2])->m_numKeys > 0 ) // rz = math::degToRad(((FCurve*)m_localEulerRotationAnims.m_data[c+2])->eval(time)); getBone(i)->localEulerRotation = math::Vec3f( math::degToRad(((FCurve*)m_localEulerRotationAnims.m_data[c])->eval(time)), math::degToRad(((FCurve *)m_localEulerRotationAnims.m_data[c+1])->eval(time)), math::degToRad(((FCurve*)m_localEulerRotationAnims.m_data[c+2])->eval(time)) ); //getBone(i)->localEulerRotation = math::Vec3f( rx, ry, rz ); c+=3; } } // update global transforms (depends on hierarchy) //updateBone(time, m_root, math::Matrix44f::Identity(), 0.0f); updateBone(time, m_root, math::Matrix44f::ScaleMatrix(0.1f,0.1f,0.1f), 0.0f); // update uniform which goes via geometry into the shader for( int j=0; j<m_bones.size(); ++j ) m_boneMatricesUniform->setElement( j, &getBone(j)->vertexTransform ); }
void SGModel::updateSkeleton() { if (isActionRunning()) { int64_t current = DateTime::currentMSecsSinceEpoch(); int64_t time = current - mStartTime; T3D_LOG_INFO("time : %lld", time); updateBone(time, mModel->getSkeletonData()); mSkeleton->updateVertices(); } }
void Skeleton::updateBone( const float &time, Bone *bone, const math::Matrix44f &parentTransform, float parentLength ) { // do global transform by concatenating local with parent transform // TODO: decide order of rotation! X/Y/Z or Z/Y/X bone->globalTransform = math::Matrix44f::RotationMatrixX(bone->localEulerRotation.x)*math::Matrix44f::RotationMatrixY(bone->localEulerRotation.y)*math::Matrix44f::RotationMatrixZ(bone->localEulerRotation.z)*math::Matrix44f::TranslationMatrix(0.0f, parentLength, 0.0f)*parentTransform; // works // the matrix which will be used to transform vertices bone->vertexTransform = bone->bindPoseInv*math::Matrix44f::RotationMatrixX(bone->localEulerRotation.x)*math::Matrix44f::RotationMatrixY(bone->localEulerRotation.y)*math::Matrix44f::RotationMatrixZ(bone->localEulerRotation.z)*math::Matrix44f::TranslationMatrix(0.0f, parentLength, 0.0f)*parentTransform; //bone->vertexTransform = math::Matrix44f::RotationMatrixZ(bone->localEulerRotation.z)*math::Matrix44f::RotationMatrixY(bone->localEulerRotation.y)*bone->bindPoseInv*math::Matrix44f::RotationMatrixX(bone->localEulerRotation.x)*math::Matrix44f::TranslationMatrix(0.0f, parentLength, 0.0f)*parentTransform; // now update all childbones for( int i=0; i<bone->childBones.size();++i ) updateBone( time, (Bone *)bone->childBones.m_data[i], bone->globalTransform, bone->length); }
/* PMDModel::setPhysicsControl switch bone control by physics simulation */ void PMDModel::setPhysicsControl(bool flag) { unsigned long i; unsigned short j; if(flag == m_enableSimulation) return; m_enableSimulation = flag; /* when true, align all rigid bodies to corresponding bone by setting Kinematics flag */ /* when false, all rigid bodies will have their own motion states according to the model definition */ for (i = 0; i < m_numRigidBody; i++) m_rigidBodyList[i].setKinematic(!flag); if (flag == false) { /* save the current bone transform with no physics as a start transform for later resuming */ updateBone(); for (j = 0; j < m_numBone; j++) m_boneList[j].saveTrans(); } }
void SGModel::updateBone(int64_t time, ObjectPtr skeleton) { BonePtr bone = smart_pointer_cast<Bone>(skeleton); ActionDataPtr actionData = smart_pointer_cast<ActionData>(mCurActionData); KeyFrameDataPtr kf1, kf2; // 平移变换数据 Vector3 translation; auto itrT = actionData->mBonesTranslation.find(bone->getName()); if (itrT != actionData->mBonesTranslation.end()) { ActionData::KeyFrames &keyframesT = itrT->second; if (searchKeyframe(keyframesT, time, actionData->mDuration, mCurKeyFrameT, kf1, kf2, mIsLoop)) { KeyFrameDataTPtr keyframe1 = smart_pointer_cast<KeyFrameDataT>(kf1); KeyFrameDataTPtr keyframe2 = smart_pointer_cast<KeyFrameDataT>(kf2); double t = double(time - keyframe1->mTimestamp) / double(keyframe2->mTimestamp - keyframe1->mTimestamp); Vector3 &base = keyframe1->mTranslation; translation = (base + (keyframe2->mTranslation - base) * t); T3D_LOG_INFO("Keyframe #1 T(%f, %f, %f)", keyframe1->mTranslation[0], keyframe1->mTranslation[1], keyframe1->mTranslation[2]); T3D_LOG_INFO("Keyframe #2 T(%f, %f, %f)", keyframe2->mTranslation[0], keyframe2->mTranslation[1], keyframe2->mTranslation[2]); T3D_LOG_INFO("Bone : %s [%f], T(%f, %f, %f)", bone->getName().c_str(), t, translation[0], translation[1], translation[2]); bone->setTranslation(translation); } } // 旋转变换数据 Quaternion orientation; auto itrR = actionData->mBonesRotation.find(bone->getName()); if (itrR != actionData->mBonesRotation.end()) { ActionData::KeyFrames &keyframesR = itrR->second; if (searchKeyframe(keyframesR, time, actionData->mDuration, mCurKeyFrameR, kf1, kf2, mIsLoop)) { KeyFrameDataRPtr keyframe1 = smart_pointer_cast<KeyFrameDataR>(kf1); KeyFrameDataRPtr keyframe2 = smart_pointer_cast<KeyFrameDataR>(kf2); double t = double(time - keyframe1->mTimestamp) / double(keyframe2->mTimestamp - keyframe1->mTimestamp); orientation.lerp(keyframe1->mOrientation, keyframe2->mOrientation, t/* / 1000*/); T3D_LOG_INFO("Keyframe #1 R(%f, %f, %f, %f)", keyframe1->mOrientation[0], keyframe1->mOrientation[1], keyframe1->mOrientation[2], keyframe1->mOrientation[3]); T3D_LOG_INFO("Keyframe #2 R(%f, %f, %f, %f)", keyframe2->mOrientation[0], keyframe2->mOrientation[1], keyframe2->mOrientation[2], keyframe2->mOrientation[3]); Degree deg; Vector3 axis; orientation.toAngleAxis(deg, axis); T3D_LOG_INFO("Bone : %s [%d], R(%f, %f, %f, %f), deg=%f, Axis(%f, %f, %f)", bone->getName().c_str(), time, orientation[0], orientation[1], orientation[2], orientation[3], deg.valueDegrees(), axis[0], axis[1], axis[2]); bone->setOrientation(orientation); } } // 缩放变换数据 Vector3 scaling; auto itrS = actionData->mBonesScaling.find(bone->getName()); if (itrS != actionData->mBonesScaling.end()) { ActionData::KeyFrames &keyframesS = itrS->second; if (searchKeyframe(keyframesS, time, actionData->mDuration, mCurKeyFrameS, kf1, kf2, mIsLoop)) { KeyFrameDataSPtr keyframe1 = smart_pointer_cast<KeyFrameDataS>(kf1); KeyFrameDataSPtr keyframe2 = smart_pointer_cast<KeyFrameDataS>(kf2); double t = double(time - keyframe1->mTimestamp) / double(keyframe2->mTimestamp - keyframe1->mTimestamp); Vector3 &base = keyframe1->mScaling; scaling = (base * (keyframe2->mScaling - base) * t); T3D_LOG_INFO("Keyframe #1 S(%f, %f, %f)", keyframe1->mScaling[0], keyframe1->mScaling[1], keyframe1->mScaling[2]); T3D_LOG_INFO("Keyframe #2 S(%f, %f, %f)", keyframe2->mScaling[0], keyframe2->mScaling[1], keyframe2->mScaling[2]); T3D_LOG_INFO("Bone : %s [%f], S(%f, %f, %f)", bone->getName().c_str(), t, scaling[0], scaling[1], scaling[2]); bone->setScaling(scaling); } } bone->updateBone(); auto itr = bone->getChildren().begin(); while (itr != bone->getChildren().end()) { updateBone(time, *itr); ++itr; } }