PeriDyno 1.0.0
Loading...
Searching...
No Matches
JointInfo.cu
Go to the documentation of this file.
1
2#include "JointInfo.h"
3#include "GltfFunc.h"
4#include "Matrix.h"
5
6namespace dyno
7{
8
9 template< typename Vec3f, typename Quat1f ,typename Mat4f>
10 __global__ void updateLocalMatrix(//需要把原始绑定算进来
11 DArray<Vec3f> translation,
12 DArray<Vec3f> scale,
13 DArray<Quat1f> rotation,
14 DArray<Mat4f> localMatrix,
15 DArray<int> jointIds
16 )
17 {
18 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
19 if (pId >= jointIds.size()) return;
20
21 int joint = jointIds[pId];
22
23 Mat4f r = rotation[joint].toMatrix4x4();
24 Mat4f s = Mat4f
25 (scale[joint][0], 0, 0, 0,
26 0, scale[joint][1], 0, 0,
27 0, 0, scale[joint][2], 0,
28 0, 0, 0, 1
29 );
30 Mat4f t = Mat4f
31 (1, 0, 0, translation[joint][0],
32 0, 1, 0, translation[joint][1],
33 0, 0, 1, translation[joint][2],
34 0, 0, 0, 1
35 );
36 localMatrix[joint] = t * s * r;
37
38 Mat4f c = localMatrix[joint];
39
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",
41 // joint,
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),
46
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]
50 // );
51
52
53
54 }
55
56 void JointInfo::updateWorldMatrixByTransform()
57 {
58 DArray<int> jointIds;
59 jointIds.assign(mAllJoints);
60
61 cuExecute(mAllJoints.size(),
62 updateLocalMatrix,
63 mCurrentTranslation,
64 mCurrentScale,
65 mCurrentRotation,
66 mJointLocalMatrix,
67 jointIds
68 );
69
70
71 std::vector<Mat4f> c_joint_Mat4f;
72 c_joint_Mat4f.resize(mMaxJointID + 1);
73
74 CArray<Mat4f> c_JointLocalMatrix;
75 c_JointLocalMatrix.assign(mJointLocalMatrix);
76
77 for (size_t i = 0; i < mAllJoints.size(); i++)
78 {
79 joint jointId = mAllJoints[i];
80 const std::vector<int>& jD = getJointDirByJointIndex(jointId, mJointDir);
81
82
83 Mat4f tempMatrix = Mat4f::identityMatrix();
84 //
85 for (int k = jD.size() - 1; k >= 0; k--)
86 {
87 joint select = jD[k];
88 tempMatrix *= c_JointLocalMatrix[select]; //
89 }
90 c_joint_Mat4f[jointId] = tempMatrix;
91
92 }
93
94 mJointWorldMatrix.assign(c_joint_Mat4f);
95
96 //CArray<Mat4f> c_JointMatrix;
97 //c_JointMatrix.assign(mJointWorldMatrix);
98
99 //for (size_t i = 0; i < c_JointMatrix.size(); i++)
100 //{
101 // auto c = c_JointMatrix[i];
102
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)
108 // );
109
110 //}
111 }
112
113
114 void JointInfo::updateCurrentPose(std::map<joint, Vec3f> t, std::map<joint, Vec3f> s, std::map<joint, Quat1f> r)
115 {
116
117
118
119
120
121 }
122
123 void JointInfo::setJoint(const JointInfo& j)
124 {
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;
134
135 mCurrentTranslation.assign(j.mCurrentTranslation);
136 mCurrentRotation.assign(j.mCurrentRotation);
137 mCurrentScale.assign(j.mCurrentScale);
138
139 mJointName = j.mJointName;
140 }
141
142 bool JointInfo::isEmpty()
143 {
144 if (mJointInverseBindMatrix.isEmpty() || mJointLocalMatrix.isEmpty() || mJointWorldMatrix.isEmpty())
145 return true;
146 }
147
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
157 )
158 {
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()));
166
167 std::vector<Vec3f> tempT;
168 std::vector<Vec3f> tempS;
169 std::vector<Quat1f> tempR;
170
171 mBindPoseTranslation.resize(mMaxJointID + 1);
172 mBindPoseScale.resize(mMaxJointID + 1);
173 mBindPoseRotation.resize(mMaxJointID + 1);
174
175 for (auto it : mAllJoints)
176 {
177 auto iterT = bindPoseTranslation.find(it);
178 if (iterT != bindPoseTranslation.end())
179 mBindPoseTranslation[it] = bindPoseTranslation[it];
180 else
181 mBindPoseTranslation[it] = Vec3f(0.0f);
182
183 auto iterS = bindPoseScale.find(it);
184 if (iterS != bindPoseScale.end())
185 mBindPoseScale[it] = bindPoseScale[it];
186 else
187 mBindPoseScale[it] = Vec3f(1.0f);
188
189 auto iterR = bindPoseRotation.find(it);
190 if (iterR != bindPoseRotation.end())
191 mBindPoseRotation[it] = bindPoseRotation[it];
192 else
193 mBindPoseRotation[it] = Quat1f();
194 }
195
196 }
197
198
199 JointInfo::~JointInfo()
200 {
201 mJointInverseBindMatrix.clear();
202 mJointInverseBindMatrix.clear();
203 mJointLocalMatrix.clear();
204 mJointWorldMatrix.clear();
205
206 mBindPoseTranslation.clear();
207 mBindPoseScale.clear();
208 mBindPoseRotation.clear();
209
210 mCurrentTranslation.clear();
211 mCurrentRotation.clear();
212 mCurrentScale.clear();
213
214 mAllJoints.clear();
215 mJointDir.clear();
216
217 };
218
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
228 )
229 {
230 UpdateJointInfo(InverseBindMatrix,
231 LocalMatrix,
232 WorldMatrix,
233 allJoints,
234 jointDir,
235 bindPoseTranslation,
236 bindPoseScale,
237 bindPoseRotation
238 );
239 }
240
241
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
250 )
251 {
252
253 mJoint_Index_Translation = jointTranslation;
254 mJoint_Index_TimeCode_Translation = jointTimeCodeTranslation;
255
256 mJoint_Index_Scale = jointScale;
257 mJoint_Index_TimeCode_Scale = jointIndexTimeCodeScale;
258
259 mJoint_Index_Rotation = jointRotation;
260 mJoint_Index_TimeCode_Rotation = jointIndexRotation;
261 mSkeleton = skeleton;
262
263 mTranslation.resize(mSkeleton->mMaxJointID + 1);
264 mScale.resize(mSkeleton->mMaxJointID + 1);
265 mRotation.resize(mSkeleton->mMaxJointID + 1);
266
267
268
269 float startR = NULL;
270 float endR = NULL;
271 for (auto it : mJoint_Index_TimeCode_Rotation )
272 {
273 {
274 float tempMin = *std::min_element(it.second.begin(), it.second.end());
275
276 if (startR == NULL)
277 startR = tempMin;
278 else
279 startR = startR < tempMin ? startR : tempMin;
280 }
281
282 {
283 float tempMax = *std::max_element(it.second.begin(), it.second.end());
284
285 if (endR == NULL)
286 endR = tempMax;
287 else
288 endR = endR > tempMax ? endR : tempMax;
289 }
290 }
291
292 float startT = NULL;
293 float endT = NULL;
294 for (auto it : mJoint_Index_TimeCode_Translation)
295 {
296 {
297 float tempMin = *std::min_element(it.second.begin(), it.second.end());
298
299 if (startT == NULL)
300 startT = tempMin;
301 else
302 startT = startT < tempMin ? startT : tempMin;
303 }
304
305 {
306 float tempMax = *std::max_element(it.second.begin(), it.second.end());
307
308 if (endT == NULL)
309 endT = tempMax;
310 else
311 endT = endT > tempMax ? endT : tempMax;
312 }
313 }
314
315 float startS = NULL;
316 float endS = NULL;
317 for (auto it : mJoint_Index_TimeCode_Scale)
318 {
319 {
320 float tempMin = *std::min_element(it.second.begin(), it.second.end());
321
322 if (startS == NULL)
323 startS = tempMin;
324 else
325 startS = startS < tempMin ? startS : tempMin;
326 }
327
328 {
329 float tempMax = *std::max_element(it.second.begin(), it.second.end());
330
331 if (endS == NULL)
332 endS = tempMax;
333 else
334 endS = endS > tempMax ? endS : tempMax;
335 }
336 }
337
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;
340
341 this->mTotalTime = timeMax - timeMin;
342 printf("mTotalTime : %f\n", mTotalTime);
343 // Offset TimeCode to "0 - mTotalTime"
344 if (timeMin != 0)
345 {
346 for (auto it : mJoint_Index_TimeCode_Rotation)
347 for (size_t i = 0; i < it.second.size(); i++)
348 {
349 it.second[i] = it.second[i] - timeMin;
350 }
351 for (auto it : mJoint_Index_TimeCode_Translation)
352 for (size_t i = 0; i < it.second.size(); i++)
353 {
354 it.second[i] = it.second[i] - timeMin;
355 }
356 for (auto it : mJoint_Index_TimeCode_Scale)
357 for (size_t i = 0; i < it.second.size(); i++)
358 {
359 it.second[i] = it.second[i] - timeMin;
360 }
361 }
362
363
364 printf("*******************\nAnimation Time : \nT:%f - %f \nS:%f - %f \nR:%f - %f \n*******************\n", startT, endT, startS, endS, startR, endR);
365
366 };
367
368 void JointAnimationInfo::updateJointsTransform(float time)
369 {
370 if (currentTime == time * mPlayRate)
371 return;
372
373 currentTime = time * mPlayRate;
374
375
376 if (mSkeleton != NULL)
377 {
378 for (size_t i = 0; i < mSkeleton->mAllJoints.size(); i++)
379 {
380 joint select = mSkeleton->mAllJoints[i];
381 updateTransform(select ,time);
382 }
383 }
384
385 }
386
387 Transform3f JointAnimationInfo::updateTransform(joint select, float time) //时间插值
388 {
389 auto iterR = mJoint_Index_Rotation.find(select);
390 if (iterR == mJoint_Index_Rotation.end())
391 mRotation[select] = mSkeleton->mBindPoseRotation[select];
392 {
393 //Rotation
394 if (iterR != mJoint_Index_Rotation.end())
395 {
396 const std::vector<Quat1f>& all_R = mJoint_Index_Rotation[select];
397 const std::vector<Real>& tTimeCode = mJoint_Index_TimeCode_Rotation[select];
398
399 int tId = findMaxSmallerIndex(tTimeCode, time);
400
401 if (tId >= all_R.size() - 1) // [size-1]<=[tId]
402 {
403 mRotation[select] = all_R[all_R.size() - 1];
404 }
405 else
406 {
407 float weight = (time - tTimeCode[tId]) / (tTimeCode[tId + 1] - tTimeCode[tId]);
408 mRotation[select] = nlerp(all_R[tId], all_R[tId + 1], weight);
409 }
410 }
411
412 }
413
414
415 //Translation
416 auto iterT = mJoint_Index_Translation.find(select);
417 if (iterT == mJoint_Index_Translation.end())
418 mTranslation[select] = mSkeleton->mBindPoseTranslation[select];
419 {
420 //Translation
421 if (iterT != mJoint_Index_Translation.end())
422 {
423 const std::vector<Vec3f>& all_T = mJoint_Index_Translation[select];
424 const std::vector<Real>& tTimeCode = mJoint_Index_TimeCode_Translation[select];
425
426 int tId = findMaxSmallerIndex(tTimeCode, time);
427
428
429 if (tId >= all_T.size() - 1) // [size-1]<=[tId]
430 {
431 mTranslation[select] = all_T[all_T.size() - 1];
432 }
433 else
434 {
435 float weight = (time - tTimeCode[tId]) / (tTimeCode[tId + 1] - tTimeCode[tId]);
436 mTranslation[select] = lerp(all_T[tId], all_T[tId + 1], weight);
437 }
438 }
439
440 }
441
442 //Scale
443 auto iterS = mJoint_Index_Scale.find(select);
444 if (iterS == mJoint_Index_Scale.end())
445 mScale[select] = mSkeleton->mBindPoseScale[select];
446
447 {
448 //Scale
449 if (iterS != mJoint_Index_Scale.end())
450 {
451 const std::vector<Vec3f>& all_S = mJoint_Index_Scale[select];
452 const std::vector<Real>& tTimeCode = mJoint_Index_TimeCode_Scale[select];
453
454 int tId = findMaxSmallerIndex(tTimeCode, time);
455
456
457 if (tId >= all_S.size() - 1) // [size-1]<=[tId]
458 {
459 mScale[select] = all_S[all_S.size() - 1];
460 }
461 else
462 {
463 float weight = (time - tTimeCode[tId]) / (tTimeCode[tId + 1] - tTimeCode[tId]);
464 mScale[select] = lerp(all_S[tId], all_S[tId + 1], weight);
465 }
466 }
467 }
468
469 return Transform3f(mTranslation[select], mRotation[select].toMatrix3x3(), mScale[select]);
470
471 };
472
473 std::vector<Vec3f> JointAnimationInfo::getJointsTranslation(float time)
474 {
475 updateJointsTransform(time);
476 return mTranslation;
477 }
478
479 std::vector<Quat1f> JointAnimationInfo::getJointsRotation(float time)
480 {
481 updateJointsTransform(time);
482 return mRotation;
483 }
484
485 std::vector<Vec3f> JointAnimationInfo::getJointsScale(float time)
486 {
487 updateJointsTransform(time);
488 return mScale;
489 }
490
491 int JointAnimationInfo::findMaxSmallerIndex(const std::vector<float>& arr, float v) {
492 int left = 0;
493 int right = arr.size() - 1;
494 int maxIndex = -1;
495
496 if (arr.size() >= 1)
497 {
498 if (arr[0] > v)
499 return 0;
500
501 if (arr[arr.size() - 1] < v)
502 return arr.size() - 1;
503 }
504
505 while (left <= right) {
506 int mid = left + (right - left) / 2;
507
508 if (arr[mid] <= v) {
509 maxIndex = mid;
510 left = mid + 1;
511 }
512 else {
513 right = mid - 1;
514 }
515 }
516
517 return maxIndex;
518 }
519
520
521
522 Quat<Real> JointAnimationInfo::nlerp(const Quat<Real>& q1, const Quat<Real>& q2, float weight)
523 {
524 Quat1f tempQ;
525
526 if (q1.x * q2.x < 0 && q1.y * q2.y < 0 && q1.z * q2.z < 0 && q1.w * q2.w < 0)
527 {
528 tempQ.x = -q2.x;
529 tempQ.y = -q2.y;
530 tempQ.z = -q2.z;
531 tempQ.w = -q2.w;
532 }
533 else
534 {
535 tempQ = q2;
536 }
537
538 Quat<Real> result = (1 - weight) * q1 + weight * tempQ;
539 // 归一化结果
540 if (result.norm() < 0.001)
541 result = Quat1f();
542 else
543 result.normalize();
544
545 return result;
546 }
547
548 Quat<Real> JointAnimationInfo::slerp(const Quat<Real>& q1, const Quat<Real>& q2, float t)
549 {
550
551 // 计算内积
552 double cosTheta = q1.w * q2.w + q1.x * q2.x + q1.y * q2.y + q1.z * q2.z;
553 Quat<Real> result;
554
555 if (abs(cosTheta) >= 1.0)
556 {
557 result.w = q1.w;
558 result.x = q1.x;
559 result.y = q1.y;
560 result.z = q1.z;
561
562 return result;
563 }
564
565 // 如果内积为负,取反q2,确保选择最短路径
566 Quat<Real> q2Adjusted = q2;
567 if (cosTheta < 0) {
568 q2Adjusted.w = -q2.w;
569 q2Adjusted.x = -q2.x;
570 q2Adjusted.y = -q2.y;
571 q2Adjusted.z = -q2.z;
572 cosTheta = -cosTheta;
573 }
574
575 // 插值
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;
580
581
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;
586
587 // 归一化结果
588 if (result.norm() < 0.001)
589 result = Quat1f();
590 else
591 result.normalize();
592
593 return result;
594
595 }
596
597 std::vector<int> JointAnimationInfo::getJointDir(int Index, std::map<int, std::vector<int>> joint_Dir)
598 {
599 std::map<int, std::vector<int>>::const_iterator iter = joint_Dir.find(Index);
600 if (iter == joint_Dir.end())
601 {
602 std::cout << "Error: not found JointIndex \n";
603
604 std::vector<int> empty;
605 return empty;
606 }
607 return iter->second;
608 }
609
610 Pose JointAnimationInfo::getPose(float inTime)
611 {
612 {
613 float time = inTime;
614
615 if (this->mLoop)
616 {
617 time = fmod(time, mTotalTime);
618 //printf("Loop Clamp : %f\n", time);
619 }
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);
626
627 return Pose(t, s, r);
628 }
629 }
630
631 Quat<Real> JointAnimationInfo::normalize(const Quat<Real>& q)
632 {
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 };
635 }
636
637
638 Vec3f JointAnimationInfo::lerp(Vec3f v0, Vec3f v1, float weight)
639 {
640 return v0 + (v1 - v0) * weight;
641 }
642
643 JointAnimationInfo::~JointAnimationInfo()
644 {
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();
652 mScale.clear();
653 mRotation.clear();
654 mJointWorldMatrix.clear();
655 mSkeleton = NULL;
656
657 };
658
659
660}