Tanoda
FastIKCCD.cs
Go to the documentation of this file.
1using UnityEngine;
2/*
3public class IKCCD : MonoBehaviour
4{
5 public int ChainLength = 2;
6 public Transform Target;
7 protected Quaternion TargetInitialRotation;
8 protected Quaternion EndInitialRotation;
9 public Transform Pole;
10 protected float CompleteLength;
11
12 public int Iterations = 10;
13 public float Delta = 0.001f;
14
15 protected Transform[] Bones;
16 //protected Quaternion[] InitialRotation;
17
18
19 // Start is called before the first frame update
20 void Awake()
21 {
22 //initial length
23 Bones = new Transform[ChainLength + 1];
24 //InitialRotation = new Quaternion[ChainLength + 1];
25 TargetInitialRotation = Target.rotation;
26 EndInitialRotation = transform.rotation;
27
28 var current = transform;
29 CompleteLength = 0;
30 for (int i = ChainLength - 1; i >= 0; i--)
31 {
32 CompleteLength += (current.position - current.parent.position).magnitude;
33 Bones[i + 1] = current;
34 Bones[i] = current.parent;
35 //InitialRotation[i + 1] = current.rotation;
36 //InitialRotation[i] = current.parent.rotation;
37 current = current.parent;
38 }
39 if (Bones[0] == null)
40 throw new UnityException("The chain value is longer than the ancestor chain!");
41 }
42
43 // Update is called once per frame
44 void LateUpdate()
45 {
46 //CCD
47 var lastBone = Bones[Bones.Length - 1];
48
49 //for (var i = 0; i < Bones.Length; i++)
50 // Bones[i].rotation = InitialRotation[i];
51
52 for (int iteration = 0; iteration < Iterations; iteration++)
53 {
54 for (var i = Bones.Length - 1; i >= 0; i--)
55 {
56 //https://www.youtube.com/watch?v=MA1nT9RAF3k
57
58 if (i == Bones.Length - 1)
59 {
60 Bones[i].rotation = Target.rotation * Quaternion.Inverse(TargetInitialRotation) * EndInitialRotation;
61 }
62 else
63 {
64 Bones[i].rotation = Quaternion.FromToRotation(lastBone.position - Bones[i].position, Target.position - Bones[i].position) * Bones[i].rotation;
65
66 //jitter to solve strait line
67 //if (iteration == 5 && i == 0 && (Target.position - lastBone.position).sqrMagnitude > 0.01f && (Target.position - Bones[i].position).sqrMagnitude < CompleteLength * CompleteLength)
68 // Bones[i].rotation = Quaternion.AngleAxis(10, Vector3.up) * Bones[i].rotation;
69
70 //move towards pole
71 if (Pole != null && i + 2 <= Bones.Length - 1)
72 {
73 var plane = new Plane(Bones[i + 2].position - Bones[i].position, Bones[i].position);
74 var projectedPole = plane.ClosestPointOnPlane(Pole.position);
75 var projectedBone = plane.ClosestPointOnPlane(Bones[i + 1].position);
76 if ((projectedBone - Bones[i].position).sqrMagnitude > 0.01f)
77 {
78 var angle = Vector3.SignedAngle(projectedBone - Bones[i].position, projectedPole - Bones[i].position, plane.normal);
79 Bones[i].rotation = Quaternion.AngleAxis(angle, plane.normal) * Bones[i].rotation;
80 }
81 }
82 }
83
84
85 //close enough?
86 if ((lastBone.position - Target.position).sqrMagnitude < Delta * Delta)
87 break;
88 }
89 }
90
91 }
92
93
94}
95*/