示例#1
0
        public Core.Chain BuildChain(HumanPart chain)
        {
            switch (chain)
            {
            case HumanPart.Head:
                Core.Chain head = new Core.Chain();
                head.Joints.Add(Head);
                return(head);

            case HumanPart.RightArm:
                return(RightArmChain());

            case HumanPart.LeftArm:
                return(LeftArmChain());

            case HumanPart.RightLeg:
                return(RightLegChain());

            case HumanPart.LeftLeg:
                return(LeftLegChain());

            case HumanPart.Root:
                Core.Chain root = new Core.Chain();
                root.Joints.Add(Root);
                return(root);
            }

            return(null);
        }
        /// <summary>
        /// Solve the IK for a chain
        /// </summary>
        /// <param name="chain"></param>
        public static bool Process(Core.Chain chain)
        {
            if (chain.Joints.Count <= 0)
            {
                return(false);
            }

            chain.MapVirtualJoints();

            for (int j = 0; j < chain.Iterations; j++)
            {
                for (int i = chain.Joints.Count - 1; i >= 0; i--)
                {
                    float _weight = chain.Weight * chain.Joints[i].weight;  //relative weight

                    //direction vectors
                    Vector3 _v0 = chain.GetIKTarget() - chain.Joints[i].joint.position;
                    Vector3 _v1 = chain.Joints[chain.Joints.Count - 1].joint.position - chain.Joints[i].joint.position;

                    //Weight
                    Quaternion _sourceRotation = chain.Joints[i].joint.rotation;
                    Quaternion _targetRotation = Quaternion.Lerp(Quaternion.identity, GenericMath.RotateFromTo(_v0, _v1), _weight);

                    //Rotation Math
                    chain.Joints[i].rot = Quaternion.Lerp(_sourceRotation, GenericMath.ApplyQuaternion(_targetRotation, _sourceRotation), _weight);
                    chain.Joints[i].ApplyVirtualMap(false, true);
                    chain.Joints[i].ApplyRestrictions();
                }
            }

            return(true);
        }
        public void BuildRig()
        {
            rArm = rigReader.BuildChain(HumanPart.RightArm);
            lArm = rigReader.BuildChain(HumanPart.LeftArm);

            rLeg = rigReader.BuildChain(HumanPart.RightLeg);
            lLeg = rigReader.BuildChain(HumanPart.LeftLeg);
        }
示例#4
0
        /// <summary>
        /// Solve the cain
        /// </summary>
        /// <param name="chain">The chain required</param>
        /// <param name="lookAtAxis">Which axis of the end effector to consider</param>
        /// <param name="virtualEndEffector">Offset the end effector by this Transform (optional)</param>
        public static void Process(Core.Chain chain, Vector3 lookAtAxis, Transform virtualEndEffector)
        {
            Transform offset = virtualEndEffector ?? chain.GetEndEffector();

            for (int i = 0; i < chain.Iterations; i++)
            {
                Solve(chain, offset, lookAtAxis);
            }
        }
        // Token: 0x06003497 RID: 13463 RVA: 0x000E5648 File Offset: 0x000E3848
        public static void Process(Core.Chain chain, Vector3 lookAtAxis, Transform virtualEndEffector)
        {
            Transform endEffector = virtualEndEffector ?? chain.GetEndEffector();

            for (int i = 0; i < chain.iterations; i++)
            {
                DirectionalSwingSolver.Solve(chain, endEffector, lookAtAxis);
            }
        }
 // Token: 0x06003498 RID: 13464 RVA: 0x000E567C File Offset: 0x000E387C
 private static void Solve(Core.Chain chain, Transform endEffector, Vector3 LookAtAxis)
 {
     for (int i = 0; i < chain.joints.Count; i++)
     {
         Vector3    target = GenericMath.TransformVector(LookAtAxis, endEffector.rotation);
         Quaternion b      = GenericMath.RotateFromTo(chain.GetIKtarget() - endEffector.position, target);
         Quaternion qA     = Quaternion.Lerp(Quaternion.identity, b, chain.weight * chain.joints[i].weight);
         chain.joints[i].joint.rotation = GenericMath.ApplyQuaternion(qA, chain.joints[i].joint.rotation);
         chain.joints[i].ApplyRestrictions();
     }
 }
示例#7
0
 // Token: 0x06002752 RID: 10066 RVA: 0x000B64F8 File Offset: 0x000B46F8
 public static void MapSolverOutput(Core.Chain chain)
 {
     for (int i = 0; i < chain.joints.Count - 1; i++)
     {
         Vector3    source = chain.joints[i + 1].pos - chain.joints[i].pos;
         Vector3    target = GenericMath.TransformVector(chain.joints[i].localAxis, chain.joints[i].rot);
         Quaternion qA     = GenericMath.RotateFromTo(source, target);
         chain.joints[i].rot = GenericMath.ApplyQuaternion(qA, chain.joints[i].rot);
         chain.joints[i].ApplyVirtualMap(true, true);
     }
 }
示例#8
0
        /// <summary>
        /// Map the vitual solver's joints onto the physical ones
        /// </summary>
        /// <param name="chain"></param>
        public static void MapSolverOutput(Core.Chain chain)
        {
            for (int i = 0; i < chain.Joints.Count - 1; i++)
            {
                Vector3 _v1 = chain.Joints[i + 1].pos - chain.Joints[i].pos;
                Vector3 _v2 = GenericMath.TransformVector(chain.Joints[i].localAxis, chain.Joints[i].rot);

                Quaternion _offset = GenericMath.RotateFromTo(_v1, _v2);
                chain.Joints[i].rot = GenericMath.ApplyQuaternion(_offset, chain.Joints[i].rot);
                chain.Joints[i].ApplyVirtualMap(true, true);
            }
        }
示例#9
0
 // Token: 0x06002751 RID: 10065 RVA: 0x000B6420 File Offset: 0x000B4620
 public static void SolveOutward(Core.Chain chain)
 {
     chain.joints[0].pos = chain.joints[0].joint.position;
     for (int i = 1; i < chain.joints.Count; i++)
     {
         Vector3 pos    = chain.joints[i - 1].pos;
         Vector3 vector = chain.joints[i].pos - pos;
         vector.Normalize();
         vector *= Vector3.Distance(chain.joints[i - 1].joint.position, chain.joints[i].joint.position);
         chain.joints[i].pos = pos + vector;
     }
 }
示例#10
0
        /// <summary>
        /// Solve the chain to make the offset look at the target
        /// </summary>
        /// <param name="chain"></param>
        /// <param name="endEffector"></param>
        private static void Solve(Core.Chain chain, Transform endEffector, Vector3 LookAtAxis)
        {
            for (int i = 0; i < chain.Joints.Count; i++)
            {
                //Vector3 axis = GenericMath.TransformVector(LookAtAxis, Quaternion.Inverse(offsetObj.rotation));
                Vector3    axis  = GenericMath.TransformVector(LookAtAxis, endEffector.rotation);
                Quaternion delta = GenericMath.RotateFromTo(chain.GetIKTarget() - endEffector.position, axis);
                Quaternion final = Quaternion.Lerp(Quaternion.identity, delta, chain.Weight * chain.Joints[i].weight);

                chain.Joints[i].joint.rotation = GenericMath.ApplyQuaternion(final, chain.Joints[i].joint.rotation);
                chain.Joints[i].ApplyRestrictions();
            }
        }
示例#11
0
        // Token: 0x06002750 RID: 10064 RVA: 0x000B6344 File Offset: 0x000B4544
        public static void SolveInward(Core.Chain chain)
        {
            int count = chain.joints.Count;

            chain.joints[count - 1].pos = Vector3.Lerp(chain.GetVirtualEE(), chain.GetIKtarget(), chain.weight);
            for (int i = count - 2; i >= 0; i--)
            {
                Vector3 pos    = chain.joints[i + 1].pos;
                Vector3 vector = chain.joints[i].pos - pos;
                vector.Normalize();
                vector *= Vector3.Distance(chain.joints[i + 1].joint.position, chain.joints[i].joint.position);
                chain.joints[i].pos = pos + vector;
            }
        }
示例#12
0
        /// <summary>
        /// Find the virtual new solved position of joints in the chain outward
        /// </summary>
        /// <param name="chain"></param>
        public static void SolveOutward(Core.Chain chain)
        {
            chain.Joints[0].pos = chain.Joints[0].joint.position;

            for (int i = 1; i < chain.Joints.Count; i++)
            {
                Vector3 _p = chain.Joints[i - 1].pos;   //point
                Vector3 _d = chain.Joints[i].pos - _p;  //direction

                _d.Normalize();
                _d *= Vector3.Distance(chain.Joints[i - 1].joint.position, chain.Joints[i].joint.position);

                chain.Joints[i].pos = _p + _d;
            }
        }
示例#13
0
        /// <summary>
        /// Process a 2 bones chain with a specific "epsilon" value
        /// </summary>
        /// <param name="chain"></param>
        /// <param name="eps">a specific value, not bounded to the global Epsilon</param>
        public static void Process(Core.Chain chain, float eps)
        {
            if (chain.Initiated == false)
            {
                chain.InitiateJoints();
            }

            if (chain.Joints.Count != 3)
            {
                Debug.LogError("The Analytical Solver only works with 3-joints(2 bones) chain configurations");
                return;
            }

            Core.Joint A = chain.Joints[0];
            Core.Joint B = chain.Joints[1];
            Core.Joint C = chain.Joints[2];
            Vector3    T = chain.GetIKTarget();

            Vector3 AB = Vector3.Normalize(B.joint.position - A.joint.position);
            Vector3 AC = Vector3.Normalize(C.joint.position - A.joint.position);
            Vector3 CB = Vector3.Normalize(B.joint.position - C.joint.position);
            Vector3 TA = A.joint.position - T;

            float l_ab = A.length;
            float l_cb = B.length;
            float l_at = GenericMath.Clamp(TA.magnitude, eps, l_ab + l_cb - eps);

            float kneeCurrent = GenericMath.VectorsAngle(AB, CB);
            float kneeTarget  = GenericMath.CosineRule(A.length, B.length, l_at);
            float kneeDelta   = kneeTarget - kneeCurrent;

            Vector3 axis = GenericMath.TransformVector(Vector3.Normalize(Vector3.Cross(AC, AB)),
                                                       Quaternion.Inverse(B.joint.rotation));
            Quaternion q1 = Quaternion.AngleAxis(kneeDelta, axis);

            Quaternion knee = Quaternion.Lerp(B.joint.rotation, GenericMath.ApplyQuaternion(B.joint.rotation, q1),
                                              chain.Weight);

            B.joint.rotation = knee;

            Quaternion q2    = Quaternion.FromToRotation(A.joint.position - C.joint.position, TA);
            Quaternion thigh = Quaternion.Lerp(A.joint.rotation, GenericMath.ApplyQuaternion(q2, A.joint.rotation),
                                               chain.Weight);

            A.joint.rotation = thigh;
        }
示例#14
0
 // Token: 0x06002772 RID: 10098 RVA: 0x000B70C0 File Offset: 0x000B52C0
 public Core.Chain LeftLegChain()
 {
     if (!this.IsReady())
     {
         return(null);
     }
     if (this.rigType != RigReader.RigType.Humanoid)
     {
         return(null);
     }
     Core.Chain chain = new Core.Chain();
     chain.joints.Add(this.l_lowerbody.upperLeg);
     chain.joints.Add(this.l_lowerbody.lowerLeg);
     chain.joints.Add(this.l_lowerbody.foot);
     chain.InitiateJoints();
     return(chain);
 }
示例#15
0
 // Token: 0x06002770 RID: 10096 RVA: 0x000B6FC8 File Offset: 0x000B51C8
 public Core.Chain LeftArmChain()
 {
     if (!this.IsReady())
     {
         return(null);
     }
     if (this.rigType != RigReader.RigType.Humanoid)
     {
         return(null);
     }
     Core.Chain chain = new Core.Chain();
     chain.joints.Add(this.l_upperbody.shoulder);
     chain.joints.Add(this.l_upperbody.upperArm);
     chain.joints.Add(this.l_upperbody.lowerArm);
     chain.joints.Add(this.l_upperbody.hand);
     chain.InitiateJoints();
     return(chain);
 }
示例#16
0
        private void DrawHumanoidScene(Core.Chain chain)
        {
            if (chain == null)
            {
                return;
            }
            if (chain.Joints.Count <= 0)
            {
                return;
            }

            Color yellow = Color.yellow;
            Color blue   = Color.blue;
            Color green  = Color.green;
            Color red    = Color.red;
            Dictionary <int, Color> colorMap = new Dictionary <int, Color>();

            Action <Vector3> drawSphere     = v => Handles.SphereHandleCap(0, v, Quaternion.identity, 0.04f, EventType.Repaint);
            Action <Vector3> drawCube       = v => Handles.CubeHandleCap(0, v, Quaternion.identity, 0.03f, EventType.Repaint);
            Action <int>     alternateColor = i => Handles.color = colorMap[(int)Mathf.Pow(-1, i)];

            colorMap.Add(1, yellow);
            colorMap.Add(-1, green);

            for (int i = 0; i < chain.Joints.Count - 1; i++)
            {
                if (!chain.Joints[i].joint)
                {
                    break;
                }
                alternateColor(i);
                Handles.DrawLine(chain.Joints[i].joint.position, chain.Joints[i + 1].joint.position);
                alternateColor(i + 1);
                drawSphere(chain.Joints[i].joint.position);
            }

            Func <float, Color> lerpColor = x => Color.Lerp(green, red, x);
            Action <Core.Chain> toTarget  = x => Handles.DrawLine(x.GetEndEffector().position, x.Target && x.Weight > 0 ? x.Target.position : x.GetEndEffector().position);

            Handles.color = lerpColor(chain.Weight);
            toTarget(chain);
            drawCube(chain.GetEndEffector().position);
            drawCube(chain.Target ? chain.Target.position : chain.GetEndEffector().position);
        }
示例#17
0
 // Token: 0x0600274F RID: 10063 RVA: 0x000B62EC File Offset: 0x000B44EC
 public static bool Process(Core.Chain chain)
 {
     if (chain.joints.Count <= 0)
     {
         return(false);
     }
     if (!chain.initiated)
     {
         chain.InitiateJoints();
     }
     chain.MapVirtualJoints();
     for (int i = 0; i < chain.iterations; i++)
     {
         FastReachSolver.SolveInward(chain);
         FastReachSolver.SolveOutward(chain);
     }
     FastReachSolver.MapSolverOutput(chain);
     return(true);
 }
示例#18
0
        /// <summary>
        /// Find the virtual new solved position of joints in the chain inward
        /// </summary>
        /// <param name="chain"></param>
        public static void SolveInward(Core.Chain chain)
        {
            int c = chain.Joints.Count;

            //Use Weight first
            chain.Joints[c - 1].pos = Vector3.Lerp(chain.GetVirtualEE(), chain.GetIKTarget(), chain.Weight);

            //find the joint on the chain's virtual line
            for (int i = c - 2; i >= 0; i--)
            {
                Vector3 _p = chain.Joints[i + 1].pos;   //point
                Vector3 _d = chain.Joints[i].pos - _p;  //direction

                _d.Normalize();
                _d *= Vector3.Distance(chain.Joints[i + 1].joint.position, chain.Joints[i].joint.position);   //all points in a direction along a length

                chain.Joints[i].pos = _p + _d;
            }
        }
示例#19
0
        /// <summary>
        /// Build the right leg chain
        /// </summary>
        /// <returns></returns>
        private Core.Chain LeftLegChain()
        {
            if (!IsReady())
            {
                return(null);
            }
            if (rigType != RigType.Humanoid)
            {
                return(null);
            }
            Core.Chain chain = new Core.Chain();

            chain.Joints.Add(l_lowerbody.upperLeg);
            chain.Joints.Add(l_lowerbody.lowerLeg);
            chain.Joints.Add(l_lowerbody.foot);

            chain.InitiateJoints();

            return(chain);
        }
示例#20
0
        /// <summary>
        /// Build the left arm IK chain
        /// </summary>
        /// <returns></returns>
        private Core.Chain LeftArmChain()
        {
            if (!IsReady())
            {
                return(null);
            }
            if (rigType != RigType.Humanoid)
            {
                return(null);
            }
            Core.Chain chain = new Core.Chain();

            chain.Joints.Add(l_upperbody.shoulder);
            chain.Joints.Add(l_upperbody.upperArm);
            chain.Joints.Add(l_upperbody.lowerArm);
            chain.Joints.Add(l_upperbody.hand);

            chain.InitiateJoints();

            return(chain);
        }
 // Token: 0x0600274B RID: 10059 RVA: 0x000B60A8 File Offset: 0x000B42A8
 public static bool Process(Core.Chain chain)
 {
     if (chain.joints.Count <= 0)
     {
         return(false);
     }
     chain.MapVirtualJoints();
     for (int i = 0; i < chain.iterations; i++)
     {
         for (int j = chain.joints.Count - 1; j >= 0; j--)
         {
             float      t        = chain.weight * chain.joints[j].weight;
             Vector3    source   = chain.GetIKtarget() - chain.joints[j].joint.position;
             Vector3    target   = chain.joints[chain.joints.Count - 1].joint.position - chain.joints[j].joint.position;
             Quaternion rotation = chain.joints[j].joint.rotation;
             Quaternion qA       = Quaternion.Lerp(Quaternion.identity, GenericMath.RotateFromTo(source, target), t);
             chain.joints[j].rot = Quaternion.Lerp(rotation, GenericMath.ApplyQuaternion(qA, rotation), t);
             chain.joints[j].ApplyVirtualMap(false, true);
             chain.joints[j].ApplyRestrictions();
         }
     }
     return(true);
 }
示例#22
0
 /// <summary>
 /// Process a 2 bones chain through the Cosine Rule
 /// </summary>
 /// <param name="chain"></param>
 public static void Process(Core.Chain chain)
 {
     Process(chain, Epsilon);
 }
 // Token: 0x06003496 RID: 13462 RVA: 0x000E5637 File Offset: 0x000E3837
 public static void Process(Core.Chain chain, Vector3 lookAtAxis)
 {
     DirectionalSwingSolver.Process(chain, lookAtAxis, chain.GetEndEffector());
 }
示例#24
0
 /// <summary>
 /// Solve the cain
 /// </summary>
 /// <param name="chain">The chain required</param>
 /// <param name="lookAtAxis">Which axis of the end effector to consider</param>
 public static void Process(Core.Chain chain, Vector3 lookAtAxis)
 {
     Process(chain, lookAtAxis, chain.GetEndEffector());
 }