9 template< typename Vec3f, typename Quat1f ,typename Mat4f>
10 __global__ void updateLocalMatrix(//需要把原始绑定算进来
11 DArray<Vec3f> translation,
13 DArray<Quat1f> rotation,
14 DArray<Mat4f> localMatrix,
18 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
19 if (pId >= jointIds.size()) return;
21 int joint = jointIds[pId];
23 Mat4f r = rotation[joint].toMatrix4x4();
25 (scale[joint][0], 0, 0, 0,
26 0, scale[joint][1], 0, 0,
27 0, 0, scale[joint][2], 0,
31 (1, 0, 0, translation[joint][0],
32 0, 1, 0, translation[joint][1],
33 0, 0, 1, translation[joint][2],
36 localMatrix[joint] = t * s * r;
38 Mat4f c = localMatrix[joint];
40 //printf("********** joint : %d ***********\n%f,%f,%f,%f\n%f,%f,%f,%f\n%f,%f,%f,%f\n%f,%f,%f,%f\n ***********************\nQuat : %f,%f,%f,%f\nScale : %f,%f,%f\nTrans : %f,%f,%f\n***********************\n",
42 // c(0,0), c(0, 1), c(0, 2), c(0, 3),
43 // c(1, 0), c(1, 1), c(1, 2), c(1, 3),
44 // c(2, 0), c(2, 1), c(2, 2), c(2, 3),
45 // c(3, 0), c(3, 1), c(3, 2), c(3, 3),
47 // rotation[joint].x, rotation[joint].y, rotation[joint].z, rotation[joint].w,
48 // scale[joint][0], scale[joint][1], scale[joint][2],
49 // translation[joint][0], translation[joint][1], translation[joint][2]
56 void JointInfo::updateWorldMatrixByTransform()
59 jointIds.assign(mAllJoints);
61 cuExecute(mAllJoints.size(),
71 std::vector<Mat4f> c_joint_Mat4f;
72 c_joint_Mat4f.resize(mMaxJointID + 1);
74 CArray<Mat4f> c_JointLocalMatrix;
75 c_JointLocalMatrix.assign(mJointLocalMatrix);
77 for (size_t i = 0; i < mAllJoints.size(); i++)
79 joint jointId = mAllJoints[i];
80 const std::vector<int>& jD = getJointDirByJointIndex(jointId, mJointDir);
83 Mat4f tempMatrix = Mat4f::identityMatrix();
85 for (int k = jD.size() - 1; k >= 0; k--)
88 tempMatrix *= c_JointLocalMatrix[select]; //
90 c_joint_Mat4f[jointId] = tempMatrix;
94 mJointWorldMatrix.assign(c_joint_Mat4f);
96 //CArray<Mat4f> c_JointMatrix;
97 //c_JointMatrix.assign(mJointWorldMatrix);
99 //for (size_t i = 0; i < c_JointMatrix.size(); i++)
101 // auto c = c_JointMatrix[i];
103 // printf("%f,%f,%f,%f\n%f,%f,%f,%f\n%f,%f,%f,%f\n%f,%f,%f,%f\n",
104 // c(0,0), c(0, 1), c(0, 2), c(0, 3),
105 // c(1, 0), c(1, 1), c(1, 2), c(1, 3),
106 // c(2, 0), c(2, 1), c(2, 2), c(2, 3),
107 // c(3, 0), c(3, 1), c(3, 2), c(3, 3)
114 void JointInfo::updateCurrentPose(std::map<joint, Vec3f> t, std::map<joint, Vec3f> s, std::map<joint, Quat1f> r)
123 void JointInfo::setJoint(const JointInfo& j)
125 mJointInverseBindMatrix.assign(j.mJointInverseBindMatrix);
126 mJointLocalMatrix.assign(j.mJointLocalMatrix);
127 mJointWorldMatrix.assign(j.mJointWorldMatrix);
128 mAllJoints = j.mAllJoints;
129 mJointDir = j.mJointDir;
130 mMaxJointID = j.mMaxJointID;
131 mBindPoseTranslation = j.mBindPoseTranslation;
132 mBindPoseScale = j.mBindPoseScale;
133 mBindPoseRotation = j.mBindPoseRotation;
135 mCurrentTranslation.assign(j.mCurrentTranslation);
136 mCurrentRotation.assign(j.mCurrentRotation);
137 mCurrentScale.assign(j.mCurrentScale);
139 mJointName = j.mJointName;
142 bool JointInfo::isEmpty()
144 if (mJointInverseBindMatrix.isEmpty() || mJointLocalMatrix.isEmpty() || mJointWorldMatrix.isEmpty())
148 void JointInfo::UpdateJointInfo(
149 DArray<Mat4f>& InverseBindMatrix,
150 DArray<Mat4f>& LocalMatrix,
151 DArray<Mat4f>& WorldMatrix,
152 std::vector<int>& allJoints,
153 std::map<joint, std::vector<joint>>& jointDir,
154 std::map<joint, Vec3f>& bindPoseTranslation,
155 std::map<joint, Vec3f>& bindPoseScale,
156 std::map<joint, Quat1f>& bindPoseRotation
159 mJointInverseBindMatrix.assign(InverseBindMatrix);
160 mJointLocalMatrix.assign(LocalMatrix);
161 mJointWorldMatrix.assign(WorldMatrix);
162 mAllJoints = allJoints;
163 mJointDir = jointDir;
164 if (mAllJoints.size())
165 mMaxJointID = *(std::max_element(allJoints.begin(), allJoints.end()));
167 std::vector<Vec3f> tempT;
168 std::vector<Vec3f> tempS;
169 std::vector<Quat1f> tempR;
171 mBindPoseTranslation.resize(mMaxJointID + 1);
172 mBindPoseScale.resize(mMaxJointID + 1);
173 mBindPoseRotation.resize(mMaxJointID + 1);
175 for (auto it : mAllJoints)
177 auto iterT = bindPoseTranslation.find(it);
178 if (iterT != bindPoseTranslation.end())
179 mBindPoseTranslation[it] = bindPoseTranslation[it];
181 mBindPoseTranslation[it] = Vec3f(0.0f);
183 auto iterS = bindPoseScale.find(it);
184 if (iterS != bindPoseScale.end())
185 mBindPoseScale[it] = bindPoseScale[it];
187 mBindPoseScale[it] = Vec3f(1.0f);
189 auto iterR = bindPoseRotation.find(it);
190 if (iterR != bindPoseRotation.end())
191 mBindPoseRotation[it] = bindPoseRotation[it];
193 mBindPoseRotation[it] = Quat1f();
199 JointInfo::~JointInfo()
201 mJointInverseBindMatrix.clear();
202 mJointInverseBindMatrix.clear();
203 mJointLocalMatrix.clear();
204 mJointWorldMatrix.clear();
206 mBindPoseTranslation.clear();
207 mBindPoseScale.clear();
208 mBindPoseRotation.clear();
210 mCurrentTranslation.clear();
211 mCurrentRotation.clear();
212 mCurrentScale.clear();
219 JointInfo::JointInfo(
220 DArray<Mat4f>& InverseBindMatrix,
221 DArray<Mat4f>& LocalMatrix,
222 DArray<Mat4f>& WorldMatrix,
223 std::vector<int>& allJoints,
224 std::map<joint, std::vector<joint>>& jointDir,
225 std::map<joint, Vec3f>& bindPoseTranslation,
226 std::map<joint, Vec3f>& bindPoseScale,
227 std::map<joint, Quat1f>& bindPoseRotation
230 UpdateJointInfo(InverseBindMatrix,
242 void JointAnimationInfo::setAnimationData(
243 std::map<joint, std::vector<Vec3f>>& jointTranslation,
244 std::map<joint, std::vector<Real>>& jointTimeCodeTranslation,
245 std::map<joint, std::vector<Vec3f>>& jointScale,
246 std::map<joint, std::vector<Real>>& jointIndexTimeCodeScale,
247 std::map<joint, std::vector<Quat1f>>& jointRotation,
248 std::map<joint, std::vector<Real>>& jointIndexRotation,
249 std::shared_ptr<JointInfo> skeleton
253 mJoint_Index_Translation = jointTranslation;
254 mJoint_Index_TimeCode_Translation = jointTimeCodeTranslation;
256 mJoint_Index_Scale = jointScale;
257 mJoint_Index_TimeCode_Scale = jointIndexTimeCodeScale;
259 mJoint_Index_Rotation = jointRotation;
260 mJoint_Index_TimeCode_Rotation = jointIndexRotation;
261 mSkeleton = skeleton;
263 mTranslation.resize(mSkeleton->mMaxJointID + 1);
264 mScale.resize(mSkeleton->mMaxJointID + 1);
265 mRotation.resize(mSkeleton->mMaxJointID + 1);
271 for (auto it : mJoint_Index_TimeCode_Rotation )
274 float tempMin = *std::min_element(it.second.begin(), it.second.end());
279 startR = startR < tempMin ? startR : tempMin;
283 float tempMax = *std::max_element(it.second.begin(), it.second.end());
288 endR = endR > tempMax ? endR : tempMax;
294 for (auto it : mJoint_Index_TimeCode_Translation)
297 float tempMin = *std::min_element(it.second.begin(), it.second.end());
302 startT = startT < tempMin ? startT : tempMin;
306 float tempMax = *std::max_element(it.second.begin(), it.second.end());
311 endT = endT > tempMax ? endT : tempMax;
317 for (auto it : mJoint_Index_TimeCode_Scale)
320 float tempMin = *std::min_element(it.second.begin(), it.second.end());
325 startS = startS < tempMin ? startS : tempMin;
329 float tempMax = *std::max_element(it.second.begin(), it.second.end());
334 endS = endS > tempMax ? endS : tempMax;
338 float timeMin = (startT < startR ? startT : startR) < startS ? (startT < startR ? startT : startR) : startS;
339 float timeMax = (endT > endR ? endT : endR) > endS ? (endT > endR ? endT : endR) : endS;
341 this->mTotalTime = timeMax - timeMin;
342 printf("mTotalTime : %f\n", mTotalTime);
343 // Offset TimeCode to "0 - mTotalTime"
346 for (auto it : mJoint_Index_TimeCode_Rotation)
347 for (size_t i = 0; i < it.second.size(); i++)
349 it.second[i] = it.second[i] - timeMin;
351 for (auto it : mJoint_Index_TimeCode_Translation)
352 for (size_t i = 0; i < it.second.size(); i++)
354 it.second[i] = it.second[i] - timeMin;
356 for (auto it : mJoint_Index_TimeCode_Scale)
357 for (size_t i = 0; i < it.second.size(); i++)
359 it.second[i] = it.second[i] - timeMin;
364 printf("*******************\nAnimation Time : \nT:%f - %f \nS:%f - %f \nR:%f - %f \n*******************\n", startT, endT, startS, endS, startR, endR);
368 void JointAnimationInfo::updateJointsTransform(float time)
370 if (currentTime == time * mPlayRate)
373 currentTime = time * mPlayRate;
376 if (mSkeleton != NULL)
378 for (size_t i = 0; i < mSkeleton->mAllJoints.size(); i++)
380 joint select = mSkeleton->mAllJoints[i];
381 updateTransform(select ,time);
387 Transform3f JointAnimationInfo::updateTransform(joint select, float time) //时间插值
389 auto iterR = mJoint_Index_Rotation.find(select);
390 if (iterR == mJoint_Index_Rotation.end())
391 mRotation[select] = mSkeleton->mBindPoseRotation[select];
394 if (iterR != mJoint_Index_Rotation.end())
396 const std::vector<Quat1f>& all_R = mJoint_Index_Rotation[select];
397 const std::vector<Real>& tTimeCode = mJoint_Index_TimeCode_Rotation[select];
399 int tId = findMaxSmallerIndex(tTimeCode, time);
401 if (tId >= all_R.size() - 1) // [size-1]<=[tId]
403 mRotation[select] = all_R[all_R.size() - 1];
407 float weight = (time - tTimeCode[tId]) / (tTimeCode[tId + 1] - tTimeCode[tId]);
408 mRotation[select] = nlerp(all_R[tId], all_R[tId + 1], weight);
416 auto iterT = mJoint_Index_Translation.find(select);
417 if (iterT == mJoint_Index_Translation.end())
418 mTranslation[select] = mSkeleton->mBindPoseTranslation[select];
421 if (iterT != mJoint_Index_Translation.end())
423 const std::vector<Vec3f>& all_T = mJoint_Index_Translation[select];
424 const std::vector<Real>& tTimeCode = mJoint_Index_TimeCode_Translation[select];
426 int tId = findMaxSmallerIndex(tTimeCode, time);
429 if (tId >= all_T.size() - 1) // [size-1]<=[tId]
431 mTranslation[select] = all_T[all_T.size() - 1];
435 float weight = (time - tTimeCode[tId]) / (tTimeCode[tId + 1] - tTimeCode[tId]);
436 mTranslation[select] = lerp(all_T[tId], all_T[tId + 1], weight);
443 auto iterS = mJoint_Index_Scale.find(select);
444 if (iterS == mJoint_Index_Scale.end())
445 mScale[select] = mSkeleton->mBindPoseScale[select];
449 if (iterS != mJoint_Index_Scale.end())
451 const std::vector<Vec3f>& all_S = mJoint_Index_Scale[select];
452 const std::vector<Real>& tTimeCode = mJoint_Index_TimeCode_Scale[select];
454 int tId = findMaxSmallerIndex(tTimeCode, time);
457 if (tId >= all_S.size() - 1) // [size-1]<=[tId]
459 mScale[select] = all_S[all_S.size() - 1];
463 float weight = (time - tTimeCode[tId]) / (tTimeCode[tId + 1] - tTimeCode[tId]);
464 mScale[select] = lerp(all_S[tId], all_S[tId + 1], weight);
469 return Transform3f(mTranslation[select], mRotation[select].toMatrix3x3(), mScale[select]);
473 std::vector<Vec3f> JointAnimationInfo::getJointsTranslation(float time)
475 updateJointsTransform(time);
479 std::vector<Quat1f> JointAnimationInfo::getJointsRotation(float time)
481 updateJointsTransform(time);
485 std::vector<Vec3f> JointAnimationInfo::getJointsScale(float time)
487 updateJointsTransform(time);
491 int JointAnimationInfo::findMaxSmallerIndex(const std::vector<float>& arr, float v) {
493 int right = arr.size() - 1;
501 if (arr[arr.size() - 1] < v)
502 return arr.size() - 1;
505 while (left <= right) {
506 int mid = left + (right - left) / 2;
522 Quat<Real> JointAnimationInfo::nlerp(const Quat<Real>& q1, const Quat<Real>& q2, float weight)
526 if (q1.x * q2.x < 0 && q1.y * q2.y < 0 && q1.z * q2.z < 0 && q1.w * q2.w < 0)
538 Quat<Real> result = (1 - weight) * q1 + weight * tempQ;
540 if (result.norm() < 0.001)
548 Quat<Real> JointAnimationInfo::slerp(const Quat<Real>& q1, const Quat<Real>& q2, float t)
552 double cosTheta = q1.w * q2.w + q1.x * q2.x + q1.y * q2.y + q1.z * q2.z;
555 if (abs(cosTheta) >= 1.0)
565 // 如果内积为负,取反q2,确保选择最短路径
566 Quat<Real> q2Adjusted = q2;
568 q2Adjusted.w = -q2.w;
569 q2Adjusted.x = -q2.x;
570 q2Adjusted.y = -q2.y;
571 q2Adjusted.z = -q2.z;
572 cosTheta = -cosTheta;
576 double theta = std::acos(cosTheta);
577 double sinTheta = std::sin(theta);
578 double weight1 = std::sin((1 - t) * theta) / sinTheta;
579 double weight2 = std::sin(t * theta) / sinTheta;
582 result.w = q1.w * weight1 + q2Adjusted.w * weight2;
583 result.x = q1.x * weight1 + q2Adjusted.x * weight2;
584 result.y = q1.y * weight1 + q2Adjusted.y * weight2;
585 result.z = q1.z * weight1 + q2Adjusted.z * weight2;
588 if (result.norm() < 0.001)
597 std::vector<int> JointAnimationInfo::getJointDir(int Index, std::map<int, std::vector<int>> joint_Dir)
599 std::map<int, std::vector<int>>::const_iterator iter = joint_Dir.find(Index);
600 if (iter == joint_Dir.end())
602 std::cout << "Error: not found JointIndex \n";
604 std::vector<int> empty;
610 Pose JointAnimationInfo::getPose(float inTime)
617 time = fmod(time, mTotalTime);
618 //printf("Loop Clamp : %f\n", time);
620 printf("total: %f\n",mTotalTime);
621 printf("time: %f\n",inTime);
622 printf("clampTime: %f\n", time);
623 auto t = this->getJointsTranslation(time);
624 auto s = this->getJointsScale(time);
625 auto r = this->getJointsRotation(time);
627 return Pose(t, s, r);
631 Quat<Real> JointAnimationInfo::normalize(const Quat<Real>& q)
633 Real norm = sqrt(q.w * q.w + q.x * q.x + q.y * q.y + q.z * q.z);
634 return { q.w / norm, q.x / norm, q.y / norm, q.z / norm };
638 Vec3f JointAnimationInfo::lerp(Vec3f v0, Vec3f v1, float weight)
640 return v0 + (v1 - v0) * weight;
643 JointAnimationInfo::~JointAnimationInfo()
645 mJoint_Index_Translation.clear();
646 mJoint_Index_TimeCode_Translation.clear();
647 mJoint_Index_Scale.clear();
648 mJoint_Index_TimeCode_Scale.clear();
649 mJoint_Index_Rotation.clear();
650 mJoint_Index_TimeCode_Rotation.clear();
651 mTranslation.clear();
654 mJointWorldMatrix.clear();