FinalIK 中 CCDIK 算法解析

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_28474981/article/details/89764273


在这里插入图片描述

1.算法分析

CCD(Cyclic Coordinate Descent),中文翻译是循环坐标下降

1.1 骨骼位置演算

(1)从倒二个骨骼节点开始,不断递减,传入下一个步骤
(2)计算该骨骼节点与最后一个骨骼节点连成的方向向量与当前骨骼节点到目标点的方向向量的夹角
(3)将该骨骼节点旋转(2)求得的角度
(4)多次重复(1)迭代靠近目标位置

在这里插入图片描述

2.实现

2.1 逻辑流

在这里插入图片描述
在Update中触发初始化,如果未初始化,则调用IKSolver.Initiate->IKSolverCCD.OnInitiate->IKSolverHeuristic.InitiateBones,主要初始化数据;初始化完成后,将会调用IKSolverCCD.OnUpdate->IKSolverCCD.Solve,做下面骨骼演算

2.2 核心代码

2.2.1 骨骼演算核心代码

for (int i = bones.Length - 2; i > -1; i--) {
	// Slerp if weight is < 0
	//CCD tends to overemphasise the rotations of the bones closer to the target position. Reducing bone weight down the hierarchy will compensate for this effect.
	float w = bones[i].weight * IKPositionWeight;

	if (w > 0f) {
		Vector3 toLastBone = bones[bones.Length - 1].transform.position - bones[i].transform.position;
		Vector3 toTarget = targetPosition - bones[i].transform.position;
						
		// Get the rotation to direct the last bone to the target
		Quaternion targetRotation = Quaternion.FromToRotation(toLastBone, toTarget) * bones[i].transform.rotation;
						
         if (w >= 1) bones[i].transform.rotation = targetRotation;
			else bones[i].transform.rotation = Quaternion.Lerp(bones[i].transform.rotation, targetRotation, w);
		}
}

猜你喜欢

转载自blog.csdn.net/qq_28474981/article/details/89764273