Пример #1
0
        /// <summary>
        /// Perform an iteration of IK
        /// </summary>
        private void UpdateIK()
        {
            int numBones = Bones.Count;

            if (numBones == 0)
            {
                return;
            }

            // calculate the bone angles
            List <Bone_2D_ConstraintRelaxation> relaxBones = new List <Bone_2D_ConstraintRelaxation> ();

            for (int boneIdx = 0; boneIdx < numBones; ++boneIdx)
            {
                Bone_2D_ConstraintRelaxation newRelaxBone = new Bone_2D_ConstraintRelaxation();
                newRelaxBone.angle  = Bones [boneIdx].Radians;
                newRelaxBone.length = Bones [boneIdx].Length;
                newRelaxBone.weight = Bones [boneIdx].Weight;
                relaxBones.Add(newRelaxBone);
            }

            // convert to worldspace bones
            List <Bone_2D_ConstraintRelaxation_World> worldBones;

            CalcIK_2D_ConstraintRelaxation_ConvertToWorld(out worldBones, relaxBones);

            // iterate IK
            for (int itrCount = 0; itrCount < IterationsPerUpdate; ++itrCount)
            {
                CalcIK_2D_ConstraintRelaxation(ref worldBones, TargetPosX, TargetPosY);
            }

            // convert bones back to local space
            CalcIK_2D_ConstraintRelaxation_ConvertToLocal(ref relaxBones, worldBones, TargetPosX, TargetPosY);

            // extract the new bone data from the results
            for (int boneIdx = 0; boneIdx < numBones; ++boneIdx)
            {
                Bones [boneIdx].Radians  = relaxBones [boneIdx].angle;
                Bones [boneIdx].RelaxedX = worldBones [boneIdx].x;
                Bones [boneIdx].RelaxedY = worldBones [boneIdx].y;
            }

            // track the target position we used for relaxation (this prevents the relaxed bone display from changing while paused)
            m_relaxedTargetX = TargetPosX;
            m_relaxedTargetY = TargetPosY;
        }
Пример #2
0
        ///***************************************************************************************
        /// CalcIK_2D_ConstraintRelaxation_ConvertToWorld
        /// This is a helper function to generate a world space bone chain for relaxation given
        /// a local space bone chain.
        ///***************************************************************************************
        public static void CalcIK_2D_ConstraintRelaxation_ConvertToWorld
        (
            out List <Bone_2D_ConstraintRelaxation_World> worldBones,            // Output world space bones
            List <Bone_2D_ConstraintRelaxation> localBones                       // Input local space bones
        )
        {
            int numBones = localBones.Count;

            //Debug.Assert (numBones > 0);

            // create the list to output
            worldBones = new List <Bone_2D_ConstraintRelaxation_World> ();

            // Start with the root bone.
            Bone_2D_ConstraintRelaxation_World rootWorldBone
                = new Bone_2D_ConstraintRelaxation_World();

            rootWorldBone.x      = 0;
            rootWorldBone.y      = 0;
            rootWorldBone.length = localBones [0].length;
            rootWorldBone.weight = localBones [0].weight;
            worldBones.Add(rootWorldBone);

            double prevAngle    = localBones [0].angle;
            double prevAngleCos = Math.Cos(prevAngle);
            double prevAngleSin = Math.Sin(prevAngle);

            // Convert child bones to world space.
            for (int boneIdx = 1; boneIdx < numBones; ++boneIdx)
            {
                Bone_2D_ConstraintRelaxation_World prevWorldBone = worldBones [boneIdx - 1];
                Bone_2D_ConstraintRelaxation       prevLocalBone = localBones [boneIdx - 1];

                Bone_2D_ConstraintRelaxation_World newWorldBone
                                    = new Bone_2D_ConstraintRelaxation_World();
                newWorldBone.x      = prevWorldBone.x + prevAngleCos * prevLocalBone.length;
                newWorldBone.y      = prevWorldBone.y + prevAngleSin * prevLocalBone.length;
                newWorldBone.length = localBones [boneIdx].length;
                newWorldBone.weight = localBones [boneIdx].weight;
                worldBones.Add(newWorldBone);

                prevAngle    = prevAngle + localBones [boneIdx].angle;
                prevAngleCos = Math.Cos(prevAngle);
                prevAngleSin = Math.Sin(prevAngle);
            }
        }
Пример #3
0
        /// <summary>
        /// Perform an iteration of IK
        /// </summary>
        private void UpdateIK()
        {
            int numBones = Bones.Count;

            if (numBones == 0)
                return;

            // calculate the bone angles
            List< Bone_2D_ConstraintRelaxation > relaxBones = new List< Bone_2D_ConstraintRelaxation > ();
            for (int boneIdx = 0; boneIdx < numBones; ++boneIdx) {
                Bone_2D_ConstraintRelaxation newRelaxBone = new Bone_2D_ConstraintRelaxation ();
                newRelaxBone.angle = Bones [boneIdx].Radians;
                newRelaxBone.length = Bones [boneIdx].Length;
                newRelaxBone.weight = Bones [boneIdx].Weight;
                relaxBones.Add (newRelaxBone);
            }

            // convert to worldspace bones
            List< Bone_2D_ConstraintRelaxation_World > worldBones;
            CalcIK_2D_ConstraintRelaxation_ConvertToWorld (out worldBones, relaxBones);

            // iterate IK
            for (int itrCount = 0; itrCount < IterationsPerUpdate; ++itrCount) {
                CalcIK_2D_ConstraintRelaxation (ref worldBones, TargetPosX, TargetPosY);
            }

            // convert bones back to local space
            CalcIK_2D_ConstraintRelaxation_ConvertToLocal (ref relaxBones, worldBones, TargetPosX, TargetPosY);

            // extract the new bone data from the results
            for (int boneIdx = 0; boneIdx < numBones; ++boneIdx) {
                Bones [boneIdx].Radians = relaxBones [boneIdx].angle;
                Bones [boneIdx].RelaxedX = worldBones [boneIdx].x;
                Bones [boneIdx].RelaxedY = worldBones [boneIdx].y;
            }

            // track the target position we used for relaxation (this prevents the relaxed bone display from changing while paused)
            m_relaxedTargetX = TargetPosX;
            m_relaxedTargetY = TargetPosY;
        }