Beispiel #1
0
        /// <summary>
        /// Allows the motor to process any specific bone logic after
        /// a bone has been added
        /// </summary>
        /// <param name="rIndex">Index position of the new bone</param>
        /// <param name="rBone">New bone that was added</param>
        public override void AddBone(BoneControllerBone rBone, bool rIncludeChildren)
        {
            base.AddBone(rBone, rIncludeChildren);

            RotationBone lBoneInfo = new RotationBone();

            if (rBone != null)
            {
                lBoneInfo.Euler = (rBone._Transform.rotation * rBone._ToBoneForwardInv).eulerAngles;
            }

            _BoneInfo.Insert(mBones.IndexOf(rBone), lBoneInfo);
        }
Beispiel #2
0
        /// <summary>
        /// Renders out bone details specific to the motor
        /// </summary>
        /// <param name="rIndex"></param>
        /// <param name="rBone"></param>
        /// <returns></returns>
        protected override bool RenderBone(int rIndex, BoneControllerBone rBone)
        {
            bool lIsDirty = false;

#if UNITY_EDITOR
            while (rIndex >= _BoneInfo.Count)
            {
                RotationBone lBoneInfo = new RotationBone();
                _BoneInfo.Insert(mBones.IndexOf(rBone), lBoneInfo);
            }

            float lNewWeight = EditorGUILayout.FloatField(new GUIContent("Motor Weight", "Determines how much the motor effects vs. currently animated rotation."), _BoneInfo[rIndex].Weight);
            if (lNewWeight != _BoneInfo[rIndex].Weight)
            {
                lIsDirty = true;
                _BoneInfo[rIndex].Weight = lNewWeight;
            }

            float lNewRotationLerp = EditorGUILayout.FloatField(new GUIContent("Rotation Lerp", "Determines how quickly we rotate to the target when using fixed updates."), _BoneInfo[rIndex].RotationLerp);
            if (lNewRotationLerp != _BoneInfo[rIndex].RotationLerp)
            {
                lIsDirty = true;
                _BoneInfo[rIndex].RotationLerp = lNewRotationLerp;
            }

            int lNewRotationAxis = EditorGUILayout.Popup("Rotation Space", _BoneInfo[rIndex].RotationAxis, EnumIKBoneRotationAxis.Names);
            if (lNewRotationAxis != _BoneInfo[rIndex].RotationAxis)
            {
                lIsDirty = true;
                _BoneInfo[rIndex].RotationAxis = lNewRotationAxis;
            }

            Vector3 lNewRotationSpeed = EditorGUILayout.Vector3Field(new GUIContent("Rotation Speed", "Degrees per second to rotate around the axis"), _BoneInfo[rIndex].RotationSpeed);
            if (lNewRotationSpeed != _BoneInfo[rIndex].RotationSpeed)
            {
                lIsDirty = true;
                _BoneInfo[rIndex].RotationSpeed = lNewRotationSpeed;
            }
#endif

            return(lIsDirty);
        }
Beispiel #3
0
        /// <summary>
        /// Process the motor each frame so that it can update the bone rotations.
        /// This is the function that should be overridden in each motor
        /// </summary>
        /// <param name="rDeltaTime">Delta time to use for the update</param>
        /// <param name="rUpdate">Determines if it is officially time to do the update</param>
        protected override void Update(float rDeltaTime, bool rUpdate)
        {
            if (mBones.Count == 0)
            {
                return;
            }

            // Process the motor info at start up
            if (!mIsInitialized)
            {
                // Ensure we have the correct amount of bone infos... we should
                while (_BoneInfo.Count < mBones.Count)
                {
                    RotationBone lBoneInfo = new RotationBone();
                    _BoneInfo.Add(lBoneInfo);
                }

                // Initialize the euler angles that are our base
                for (int i = 0; i < mBones.Count; i++)
                {
                    _BoneInfo[i].Euler        = Vector3.zero;
                    _BoneInfo[i].BaseRotation = mBones[i]._Transform.rotation;

                    //_BoneInfo[i].Euler = mBones[i]._Transform.rotation.eulerAngles;
                }

                // Flag that we've initialized
                mIsInitialized = true;
            }

            // If it's time to update, determine the positions we need to be
            // at and lerp towards them.
            if (rUpdate)
            {
                // Process each bone
                for (int i = 0; i < mBones.Count; i++)
                {
                    BoneControllerBone lBone     = mBones[i];
                    RotationBone       lBoneInfo = _BoneInfo[i];

                    // The current rotation we will lerp from. We remove the trailing rotation offset because we'll add it later
                    Quaternion lCurrentRotation = lBone.Transform.rotation * lBone.ToBoneForward;

                    // Rotation we're moving towards
                    Quaternion lTargetRotation = lBone._Transform.rotation;

                    // Speed this frame
                    Vector3 lRotationSpeed = lBoneInfo.RotationSpeed * rDeltaTime;

                    // Update the angles we're rotating to
                    lBoneInfo.Euler += lRotationSpeed;

                    // Rotate based on the axis
                    if (lBoneInfo.RotationAxis == EnumIKBoneRotationAxis.BONE)
                    {
                        lTargetRotation = _BoneInfo[i].BaseRotation * Quaternion.Euler(lBoneInfo.Euler);
                    }
                    else if (lBoneInfo.RotationAxis == EnumIKBoneRotationAxis.MODEL)
                    {
                        lTargetRotation = _BoneInfo[i].BaseRotation * Quaternion.Euler(lBoneInfo.Euler) * lBone._ToBoneForward;
                    }
                    else
                    {
                        lTargetRotation = lTargetRotation * lBone._ToBoneForward;
                    }

                    // Rotation as determined by the target
                    lBoneInfo.RotationTarget = Quaternion.Lerp(lCurrentRotation, lTargetRotation, _Weight * lBoneInfo.Weight);

                    // Slowly move towards the rotation we determined
                    lBoneInfo.Rotation = Quaternion.Lerp(lBoneInfo.Rotation, lBoneInfo.RotationTarget, (_IsFixedUpdateEnabled && !mIsFirstUpdate ? lBoneInfo.RotationLerp : 1f));

                    // Set the world rotation
                    lBone.SetWorldRotation(lBoneInfo.Rotation, Quaternion.identity, _BoneWeight);
                }
            }
            // If it's not on a consistant update, we just want to reset the
            // last rotations that we found.
            else
            {
                for (int i = 0; i < mBones.Count; i++)
                {
                    BoneControllerBone lBone = mBones[i];
                    if (lBone == null)
                    {
                        continue;
                    }

                    lBone.SetWorldRotation(_BoneInfo[i].Rotation, Quaternion.identity, _BoneWeight);
                }
            }
        }