예제 #1
0
        private void Iterate(int iteration)
        {
            if (!base.enabled)
            {
                return;
            }
            if (!this.ik.enabled)
            {
                return;
            }
            if (!base.gameObject.activeInHierarchy)
            {
                return;
            }
            if (this.ik.solver.iterations == 0)
            {
                return;
            }
            this.leftShoulderPos  = base.transform.position + (this.leftShoulderPos - base.transform.position).normalized * this.leftShoulderDist;
            this.rightShoulderPos = base.transform.position + (this.rightShoulderPos - base.transform.position).normalized * this.rightShoulderDist;
            this.Solve(ref this.leftShoulderPos, ref this.rightShoulderPos, this.shoulderDist);
            this.LerpSolverPosition(this.ik.solver.leftShoulderEffector, this.leftShoulderPos, this.positionWeight * this.ik.solver.IKPositionWeight, this.ik.solver.leftShoulderEffector.positionOffset);
            this.LerpSolverPosition(this.ik.solver.rightShoulderEffector, this.rightShoulderPos, this.positionWeight * this.ik.solver.IKPositionWeight, this.ik.solver.rightShoulderEffector.positionOffset);
            Quaternion to         = Quaternion.LookRotation(base.transform.position - this.leftShoulderPos, this.rightShoulderPos - this.leftShoulderPos);
            Quaternion quaternion = QuaTools.FromToRotation(this.chestRotation, to);
            Vector3    b          = quaternion * this.headToBody;

            this.LerpSolverPosition(this.ik.solver.bodyEffector, base.transform.position + b, this.positionWeight * this.ik.solver.IKPositionWeight, this.ik.solver.bodyEffector.positionOffset - this.ik.solver.pullBodyOffset);
            Quaternion rotation = Quaternion.Lerp(Quaternion.identity, quaternion, this.thighWeight);
            Vector3    b2       = rotation * this.headToLeftThigh;
            Vector3    b3       = rotation * this.headToRightThigh;

            this.LerpSolverPosition(this.ik.solver.leftThighEffector, base.transform.position + b2, this.positionWeight * this.ik.solver.IKPositionWeight, this.ik.solver.bodyEffector.positionOffset - this.ik.solver.pullBodyOffset + this.ik.solver.leftThighEffector.positionOffset);
            this.LerpSolverPosition(this.ik.solver.rightThighEffector, base.transform.position + b3, this.positionWeight * this.ik.solver.IKPositionWeight, this.ik.solver.bodyEffector.positionOffset - this.ik.solver.pullBodyOffset + this.ik.solver.rightThighEffector.positionOffset);
        }
예제 #2
0
        // Bending the spine to the head effector
        private void SpineBend()
        {
            float w = bendWeight * ik.solver.IKPositionWeight;

            if (w <= 0f)
            {
                return;
            }
            if (bendBones.Length == 0)
            {
                return;
            }

            Quaternion rotation = transform.rotation * Quaternion.Inverse(ik.references.root.rotation * headRotationRelativeToRoot);

            rotation = QuaTools.ClampRotation(rotation, bodyClampWeight, 2);

            float step = 1f / bendBones.Length;

            for (int i = 0; i < bendBones.Length; i++)
            {
                if (bendBones[i].transform != null)
                {
                    bendBones[i].transform.rotation = Quaternion.Lerp(Quaternion.identity, rotation, step * bendBones[i].weight * w) * bendBones[i].transform.rotation;
                }
            }
        }
예제 #3
0
            // Move and rotate the pelvis
            private void TranslatePelvis(Leg[] legs, Vector3 deltaPosition, Quaternion deltaRotation, float scale)
            {
                // Rotation
                Vector3 p = head.solverPosition;

                deltaRotation = QuaTools.ClampRotation(deltaRotation, chestClampWeight, 2);

                Quaternion r = Quaternion.Slerp(Quaternion.identity, deltaRotation, bodyRotStiffness * rotationWeight);

                r = Quaternion.Slerp(r, QuaTools.FromToRotation(pelvis.solverRotation, IKRotationPelvis), pelvisRotationWeight);
                VirtualBone.RotateAroundPoint(bones, 0, pelvis.solverPosition, pelvisRotationOffset * r);

                deltaPosition -= head.solverPosition - p;

                // Position
                // Move the body back when head is moving down
                Vector3 m      = rootRotation * Vector3.forward;
                float   deltaY = V3Tools.ExtractVertical(deltaPosition, rootRotation * Vector3.up, 1f).magnitude;

                if (scale > 0f)
                {
                    deltaY /= scale;
                }
                float backOffset = deltaY * -moveBodyBackWhenCrouching * headHeight;

                deltaPosition += m * backOffset;

                MovePosition(LimitPelvisPosition(legs, pelvis.solverPosition + deltaPosition * bodyPosStiffness * positionWeight, false));
            }
예제 #4
0
        // Called by the FBBIK each time it is finished updating
        private void OnPostUpdate()
        {
            if (!enabled)
            {
                return;
            }
            if (!ik.enabled)
            {
                return;
            }
            if (!gameObject.activeInHierarchy)
            {
                return;
            }

            // Stretching the spine and neck
            PostStretching();

            // Rotate the head bone
            Quaternion headRotation = QuaTools.FromToRotation(ik.references.head.rotation, transform.rotation);

            headRotation = QuaTools.ClampRotation(headRotation, headClampWeight, 2);

            ik.references.head.rotation = Quaternion.Lerp(Quaternion.identity, headRotation, rotationWeight * ik.solver.IKPositionWeight) * ik.references.head.rotation;
        }
예제 #5
0
            // Bending the spine to the head effector
            private void Bend(VirtualBone[] bones, int firstIndex, int lastIndex, Quaternion targetRotation, float clampWeight, bool uniformWeight, float w)
            {
                if (w <= 0f)
                {
                    return;
                }
                if (bones.Length == 0)
                {
                    return;
                }
                int bonesCount = (lastIndex + 1) - firstIndex;

                if (bonesCount < 1)
                {
                    return;
                }

                Quaternion r = QuaTools.FromToRotation(bones[lastIndex].solverRotation, targetRotation);

                r = QuaTools.ClampRotation(r, clampWeight, 2);

                float step = uniformWeight? 1f / bonesCount: 0f;

                for (int i = firstIndex; i < lastIndex + 1; i++)
                {
                    if (!uniformWeight)
                    {
                        step = Mathf.Clamp(((i - firstIndex) + 1) / bonesCount, 0, 1f);
                    }
                    VirtualBone.RotateAroundPoint(bones, i, bones[i].solverPosition, Quaternion.Slerp(Quaternion.identity, r, step * w));
                }
            }
예제 #6
0
        /*
         * Stage 2 of FABRIK algorithm with limited rotations
         * */
        private void BackwardReachLimited(Vector3 position)
        {
            // Move first bone to position
            bones[0].solverPosition = position;

            // Applying rotation limits bone by bone
            for (int i = 0; i < bones.Length - 1; i++)
            {
                // Rotating bone to look at the solved joint position
                Vector3 nextPosition = SolveJoint(bones[i + 1].solverPosition, bones[i].solverPosition, bones[i].length);

                Quaternion swing          = Quaternion.FromToRotation(bones[i].solverRotation * bones[i].axis, nextPosition - bones[i].solverPosition);
                Quaternion targetRotation = swing * bones[i].solverRotation;

                // Rotation Constraints
                if (bones[i].rotationLimit != null)
                {
                    bool changed = false;
                    targetRotation = GetLimitedRotation(i, targetRotation, out changed);
                }

                Quaternion fromTo = QuaTools.FromToRotation(bones[i].solverRotation, targetRotation);
                bones[i].solverRotation = targetRotation;
                SolverRotateChildren(i, fromTo);

                // Positioning the next bone to its default local position
                bones[i + 1].solverPosition = bones[i].solverPosition + bones[i].solverRotation * solverLocalPositions[i + 1];
            }

            // Reconstruct solver rotations to protect from invalid Quaternions
            for (int i = 0; i < bones.Length; i++)
            {
                bones[i].solverRotation = Quaternion.LookRotation(bones[i].solverRotation * Vector3.forward, bones[i].solverRotation * Vector3.up);
            }
        }
예제 #7
0
        private void SpineBend()
        {
            float num = this.bendWeight * this.ik.solver.IKPositionWeight;

            if (num <= 0f)
            {
                return;
            }
            if (this.bendBones.Length == 0)
            {
                return;
            }
            Quaternion quaternion = base.transform.rotation * Quaternion.Inverse(this.ik.references.root.rotation * this.headRotationRelativeToRoot);

            quaternion = QuaTools.ClampRotation(quaternion, this.bodyClampWeight, 2);
            float num2 = 1f / (float)this.bendBones.Length;

            for (int i = 0; i < this.bendBones.Length; i++)
            {
                if (this.bendBones[i].transform != null)
                {
                    this.bendBones[i].transform.rotation = Quaternion.Lerp(Quaternion.identity, quaternion, num2 * this.bendBones[i].weight * num) * this.bendBones[i].transform.rotation;
                }
            }
        }
예제 #8
0
            // Move and rotate the pelvis
            private void TranslatePelvis(Leg[] legs, Vector3 deltaPosition, Quaternion deltaRotation, float w)
            {
                // Rotation
                Vector3 p = head.solverPosition;

                deltaRotation = QuaTools.ClampRotation(deltaRotation, chestClampWeight, 2);
                Quaternion f = w >= 1f? pelvisRotationOffset: Quaternion.Slerp(Quaternion.identity, pelvisRotationOffset, w);

                VirtualBone.RotateAroundPoint(bones, 0, pelvis.solverPosition, f * Quaternion.Slerp(Quaternion.identity, deltaRotation, w * bodyRotStiffness));

                deltaPosition -= head.solverPosition - p;

                // Position
                // Move the body back when head is moving down
                Vector3 m = anchorRotation * Vector3.forward;

                m.y = 0f;
                float backOffset = deltaPosition.y * 0.35f * headHeight;

                deltaPosition += m * backOffset;

                /*
                 * if (backOffset < 0f) {
                 *      foreach (Leg leg in legs) leg.heelPositionOffset += Vector3.up * backOffset * backOffset; // TODO Ignoring root rotation
                 * }
                 */

                MovePosition(LimitPelvisPosition(legs, pelvis.solverPosition + deltaPosition * w * bodyPosStiffness, false));
            }
예제 #9
0
            /*
             * Updates the 3 plane points
             * */
            public void UpdatePlane()
            {
                Quaternion l = lastAnimatedTargetRotation;

                defaultLocalTargetRotation = QuaTools.GetAxisConvert(transform.rotation, l);
                planePosition = Quaternion.Inverse(l) * (transform.position - planeNode1.transform.position);
            }
예제 #10
0
 public void RotateTo(Vector3 position)
 {
     if (this.pivot == null)
     {
         return;
     }
     if (this.pivot != this.lastPivot)
     {
         this.defaultLocalRotation = this.pivot.localRotation;
         this.lastPivot            = this.pivot;
     }
     this.pivot.localRotation = this.defaultLocalRotation;
     if (this.twistWeight > 0f)
     {
         Vector3 fromDirection = base.transform.position - this.pivot.position;
         Vector3 vector        = this.pivot.rotation * this.twistAxis;
         Vector3 vector2       = vector;
         Vector3.OrthoNormalize(ref vector2, ref fromDirection);
         vector2 = vector;
         Vector3 toDirection = position - this.pivot.position;
         Vector3.OrthoNormalize(ref vector2, ref toDirection);
         Quaternion b = QuaTools.FromToAroundAxis(fromDirection, toDirection, vector);
         this.pivot.rotation = Quaternion.Lerp(Quaternion.identity, b, this.twistWeight) * this.pivot.rotation;
     }
     if (this.swingWeight > 0f)
     {
         Quaternion b2 = Quaternion.FromToRotation(base.transform.position - this.pivot.position, position - this.pivot.position);
         this.pivot.rotation = Quaternion.Lerp(Quaternion.identity, b2, this.swingWeight) * this.pivot.rotation;
     }
 }
예제 #11
0
            public void Initiate(Vector3 childPosition, Vector3 bendNormal)
            {
                Quaternion rotation = Quaternion.LookRotation(childPosition - this.transform.position, bendNormal);

                this.targetToLocalSpace     = QuaTools.RotationToLocalSpace(this.transform.rotation, rotation);
                this.defaultLocalBendNormal = Quaternion.Inverse(this.transform.rotation) * bendNormal;
            }
예제 #12
0
        // Called by the FBBIK before each solver iteration
        private void Iterate(int iteration)
        {
            if (ik.solver.iterations == 0)
            {
                return;
            }

            // Shoulders
            leftShoulderPos  = transform.position + (leftShoulderPos - transform.position).normalized * leftShoulderDist;
            rightShoulderPos = transform.position + (rightShoulderPos - transform.position).normalized * rightShoulderDist;

            Solve(ref leftShoulderPos, ref rightShoulderPos, shoulderDist);

            LerpSolverPosition(ik.solver.leftShoulderEffector, leftShoulderPos, positionWeight);
            LerpSolverPosition(ik.solver.rightShoulderEffector, rightShoulderPos, positionWeight);

            // Body
            Quaternion chestRotationSolved = Quaternion.LookRotation(transform.position - leftShoulderPos, rightShoulderPos - leftShoulderPos);
            Quaternion rBody = QuaTools.FromToRotation(chestRotation, chestRotationSolved);

            Vector3 headToBodySolved = rBody * headToBody;

            LerpSolverPosition(ik.solver.bodyEffector, transform.position + headToBodySolved, positionWeight);

            // Thighs
            Quaternion rThighs = Quaternion.Lerp(Quaternion.identity, rBody, thighWeight);

            Vector3 headToLeftThighSolved  = rThighs * headToLeftThigh;
            Vector3 headToRightThighSolved = rThighs * headToRightThigh;

            LerpSolverPosition(ik.solver.leftThighEffector, transform.position + headToLeftThighSolved, positionWeight);
            LerpSolverPosition(ik.solver.rightThighEffector, transform.position + headToRightThighSolved, positionWeight);
        }
예제 #13
0
        private void WriteTransforms()
        {
            for (int i = 0; i < solverTransforms.Length; i++)
            {
                if (solverTransforms[i] != null)
                {
                    bool isRootOrPelvis = i < 2;
                    bool isArm          = i > 5 && i < 14;
                    bool isLeg          = i >= 14;

                    if (isRootOrPelvis)
                    {
                        solverTransforms[i].position = V3Tools.Lerp(solverTransforms[i].position, GetPosition(i), IKPositionWeight);
                    }

                    if (isArm || isLeg)
                    {
                        solverTransforms[i].position = V3Tools.Lerp(solverTransforms[i].position, GetPosition(i), IKPositionWeight);
                    }


                    solverTransforms[i].rotation = QuaTools.Lerp(solverTransforms[i].rotation, GetRotation(i), IKPositionWeight);
                }
            }
        }
예제 #14
0
        // Called by the InteractionSystem when an interaction starts
        private void OnStart(FullBodyBipedEffector effectorType, InteractionObject interactionObject)
        {
            if (effectorType != FullBodyBipedEffector.LeftHand)
            {
                return;
            }

            // Rotate the pivot of the hand targets by 90 degrees so we could grab the box from any direction

            // Get the flat direction towards the character
            Vector3 characterDirection = (interactionSystem.transform.position - pivot.position).normalized;

            characterDirection.y = 0f;

            // Convert the direction to local space of the box
            Vector3 characterDirectionLocal = box.transform.InverseTransformDirection(characterDirection);

            // QuaTools.GetAxis returns a 90 degree ortographic axis for any direction
            Vector3 axis   = QuaTools.GetAxis(characterDirectionLocal);
            Vector3 upAxis = QuaTools.GetAxis(box.transform.InverseTransformDirection(interactionSystem.transform.up));

            // Rotate towards axis and upAxis
            pivot.localRotation = Quaternion.LookRotation(axis, upAxis);

            // Rotate the hold point so it matches the current rotation of the box
            boxHoldPoint.rotation = box.transform.rotation;
        }
예제 #15
0
 public void RecordVelocity()
 {
     this.deltaPosition = this.t.position - this.lastPosition;
     this.lastPosition  = this.t.position;
     this.deltaRotation = QuaTools.FromToRotation(this.lastRotation, this.t.rotation);
     this.lastRotation  = this.t.rotation;
     this.deltaTime     = Time.deltaTime;
 }
예제 #16
0
        /*
         * Applying rotation limit to a bone in stage 1 in a more stable way
         * */
        private void LimitForward(int rotateBone, int limitBone)
        {
            if (!useRotationLimits)
            {
                return;
            }
            if (bones[limitBone].rotationLimit == null)
            {
                return;
            }

            // Storing last bone's position before applying the limit
            Vector3 lastBoneBeforeLimit = bones[bones.Length - 1].solverPosition;

            // Moving and rotating this bone and all its children to their solver positions
            for (int i = rotateBone; i < bones.Length - 1; i++)
            {
                if (limitedBones[i])
                {
                    break;
                }

                Quaternion fromTo = Quaternion.FromToRotation(bones[i].solverRotation * bones[i].axis, bones[i + 1].solverPosition - bones[i].solverPosition);
                SolverRotate(i, fromTo, false);
            }

            // Limit the bone's rotation
            bool       changed    = false;
            Quaternion afterLimit = GetLimitedRotation(limitBone, bones[limitBone].solverRotation, out changed);

            if (changed)
            {
                // Rotating and positioning the hierarchy so that the last bone's position is maintained
                if (limitBone < bones.Length - 1)
                {
                    Quaternion change = QuaTools.FromToRotation(bones[limitBone].solverRotation, afterLimit);
                    bones[limitBone].solverRotation = afterLimit;
                    SolverRotateChildren(limitBone, change);
                    SolverMoveChildrenAroundPoint(limitBone, change);

                    // Rotating to compensate for the limit
                    Quaternion fromTo = Quaternion.FromToRotation(bones[bones.Length - 1].solverPosition - bones[rotateBone].solverPosition, lastBoneBeforeLimit - bones[rotateBone].solverPosition);

                    SolverRotate(rotateBone, fromTo, true);
                    SolverMoveChildrenAroundPoint(rotateBone, fromTo);

                    // Moving the bone so that last bone maintains it's initial position
                    SolverMove(rotateBone, lastBoneBeforeLimit - bones[bones.Length - 1].solverPosition);
                }
                else
                {
                    // last bone
                    bones[limitBone].solverRotation = afterLimit;
                }
            }

            limitedBones[limitBone] = true;
        }
            /*
             * Initiates the bone, precalculates values.
             * */
            public void Initiate(Vector3 childPosition, Vector3 bendNormal)
            {
                // Get default target rotation that looks at child position with bendNormal as up
                Quaternion defaultTargetRotation = Quaternion.LookRotation(childPosition - transform.position, bendNormal);

                // Covert default target rotation to local space
                targetToLocalSpace = QuaTools.RotationToLocalSpace(transform.rotation, defaultTargetRotation);

                defaultLocalBendNormal = Quaternion.Inverse(transform.rotation) * bendNormal;
            }
예제 #18
0
        protected override void RotatePivot()
        {
            Vector3 normalized = (this.pivot.position - this.interactionSystem.transform.position).normalized;

            normalized.y = 0f;
            Vector3 v     = this.obj.transform.InverseTransformDirection(normalized);
            Vector3 axis  = QuaTools.GetAxis(v);
            Vector3 axis2 = QuaTools.GetAxis(this.obj.transform.InverseTransformDirection(this.interactionSystem.transform.up));

            this.pivot.localRotation = Quaternion.LookRotation(axis, axis2);
        }
예제 #19
0
            /*
             * Rotates the bone relative to it's 3 plane nodes
             * */
            public void RotateToPlane(float weight)
            {
                Quaternion r = QuaTools.ConvertAxis(targetRotation, defaultLocalTargetRotation);

                if (weight >= 1f)
                {
                    transform.rotation = r;
                    return;
                }

                transform.rotation = Quaternion.Lerp(transform.rotation, r, weight);
            }
예제 #20
0
            public override void ApplyOffsets()
            {
                headPosition  += headPositionOffset;
                headPosition.y = Math.Max(rootPosition.y + 0.8f, headPosition.y);

                headRotation = headRotationOffset * headRotation;

                headDeltaPosition   = headPosition - head.solverPosition;
                pelvisDeltaRotation = QuaTools.FromToRotation(pelvis.solverRotation, headRotation * pelvisRelativeRotation);

                anchorRotation = headRotation * anchorRelativeToHead;
            }
예제 #21
0
            public void UpdatePlane(bool rotation, bool position)
            {
                Quaternion lastAnimatedTargetRotation = this.lastAnimatedTargetRotation;

                if (rotation)
                {
                    this.defaultLocalTargetRotation = QuaTools.RotationToLocalSpace(this.transform.rotation, lastAnimatedTargetRotation);
                }
                if (position)
                {
                    this.planePosition = Quaternion.Inverse(lastAnimatedTargetRotation) * (this.transform.position - this.planeBone1.position);
                }
            }
예제 #22
0
            /*
             * Updates the 3 plane points
             * */
            public void UpdatePlane(bool rotation, bool position)
            {
                Quaternion t = lastAnimatedTargetRotation;

                if (rotation)
                {
                    defaultLocalTargetRotation = QuaTools.RotationToLocalSpace(transform.rotation, t);
                }
                if (position)
                {
                    planePosition = Quaternion.Inverse(t) * (transform.position - planeBone1.position);
                }
            }
예제 #23
0
            public override void ApplyOffsets(float scale)
            {
                headPosition += headPositionOffset;

                float mHH = minHeadHeight * scale;

                Vector3 rootUp = rootRotation * Vector3.up;

                if (rootUp == Vector3.up)
                {
                    headPosition.y = Math.Max(rootPosition.y + mHH, headPosition.y);
                }
                else
                {
                    Vector3 toHead = headPosition - rootPosition;
                    Vector3 hor    = V3Tools.ExtractHorizontal(toHead, rootUp, 1f);
                    Vector3 ver    = toHead - hor;
                    float   dot    = Vector3.Dot(ver, rootUp);
                    if (dot > 0f)
                    {
                        if (ver.magnitude < mHH)
                        {
                            ver = ver.normalized * mHH;
                        }
                    }
                    else
                    {
                        ver = -ver.normalized * mHH;
                    }

                    headPosition = rootPosition + hor + ver;
                }

                headRotation = headRotationOffset * headRotation;

                headDeltaPosition   = headPosition - head.solverPosition;
                pelvisDeltaRotation = QuaTools.FromToRotation(pelvis.solverRotation, headRotation * pelvisRelativeRotation);

                if (pelvisRotationWeight <= 0f)
                {
                    anchorRotation = headRotation * anchorRelativeToHead;
                }
                else if (pelvisRotationWeight > 0f && pelvisRotationWeight < 1f)
                {
                    anchorRotation = Quaternion.Lerp(headRotation * anchorRelativeToHead, pelvisRotation * anchorRelativeToPelvis, pelvisRotationWeight);
                }
                else if (pelvisRotationWeight >= 1f)
                {
                    anchorRotation = pelvisRotation * anchorRelativeToPelvis;
                }
            }
예제 #24
0
 private void WriteTransforms()
 {
     for (int i = 0; i < solverTransforms.Length; i++)
     {
         if (solverTransforms[i] != null)
         {
             if (i < 2)
             {
                 solverTransforms[i].position = V3Tools.Lerp(solverTransforms[i].position, GetPosition(i), IKPositionWeight);
             }
             solverTransforms[i].rotation = QuaTools.Lerp(solverTransforms[i].rotation, GetRotation(i), IKPositionWeight);
         }
     }
 }
예제 #25
0
            public override void PreSolve()
            {
                if (target != null)
                {
                    IKPosition = target.position;
                    IKRotation = target.rotation;
                }

                position = V3Tools.Lerp(hand.solverPosition, IKPosition, positionWeight);
                rotation = QuaTools.Lerp(hand.solverRotation, IKRotation, rotationWeight);

                shoulder.axis        = shoulder.axis.normalized;
                forearmRelToUpperArm = Quaternion.Inverse(upperArm.solverRotation) * forearm.solverRotation;
            }
예제 #26
0
            public void TranslateRoot(Vector3 newRootPos, Quaternion newRootRot)
            {
                Vector3 deltaPosition = newRootPos - rootPosition;

                rootPosition = newRootPos;
                foreach (VirtualBone bone in bones)
                {
                    bone.solverPosition += deltaPosition;
                }

                Quaternion deltaRotation = QuaTools.FromToRotation(rootRotation, newRootRot);

                rootRotation = newRootRot;
                VirtualBone.RotateAroundPoint(bones, 0, newRootPos, deltaRotation);
            }
예제 #27
0
        // How fast the mapped target is moving? Will be used to set rigidbody velocities when puppet is killed.
        // Rigidbody velocities otherwise might be close to 0 when FixedUpdate called more than once per frame or velocity wrongully changing when mapping weights not 1.
        public void CalculateMappedVelocity()
        {
            float writeDeltaTime = Time.time - lastWriteTime;

            if (writeDeltaTime > 0f)
            {
                mappedVelocity        = (target.position - lastMappedPosition) / writeDeltaTime;
                mappedAngularVelocity = QuaTools.FromToRotation(lastMappedRotation, target.rotation).eulerAngles / writeDeltaTime;

                lastWriteTime = Time.time;
            }

            lastMappedPosition = target.position;
            lastMappedRotation = target.rotation;
        }
예제 #28
0
        /*
         * Apply the bend constraint
         * */
        public void Solve()
        {
            weight = Mathf.Clamp(weight, 0f, 1f);

            // Get the direction to node2 ortho-normalized to the chain direction
            Vector3 directionTangent = OrthoToLimb(rotationOffset * OrthoToLimb(GetDir()));
            Vector3 node2Tangent     = OrthoToLimb(node2.solverPosition - node1.solverPosition);

            // Rotation from the current position to the desired position
            Quaternion fromTo = QuaTools.FromToAroundAxis(node2Tangent, directionTangent, (node3.solverPosition - node1.solverPosition).normalized);

            // Repositioning node2
            Vector3 to2 = node2.solverPosition - node1.solverPosition;

            node2.solverPosition = node1.solverPosition + fromTo * to2;
        }
예제 #29
0
            public override void PreSolve()
            {
                if (headTarget != null)
                {
                    IKPositionHead = headTarget.position;
                    IKRotationHead = headTarget.rotation;
                }

                if (pelvisTarget != null)
                {
                    IKPositionPelvis = pelvisTarget.position;
                }

                headPosition = V3Tools.Lerp(head.solverPosition, IKPositionHead, positionWeight);
                headRotation = QuaTools.Lerp(head.solverRotation, IKRotationHead, rotationWeight);
            }
예제 #30
0
        // Rotate the pivot of the hand targets by 90 degrees so we could grab the object from any direction
        protected override void RotatePivot()
        {
            // Get the flat direction towards the character
            Vector3 characterDirection = (pivot.position - interactionSystem.transform.position).normalized;

            characterDirection.y = 0f;

            // Convert the direction to local space of the object
            Vector3 characterDirectionLocal = obj.transform.InverseTransformDirection(characterDirection);

            // QuaTools.GetAxis returns a 90 degree ortographic axis for any direction
            Vector3 axis   = QuaTools.GetAxis(characterDirectionLocal);
            Vector3 upAxis = QuaTools.GetAxis(obj.transform.InverseTransformDirection(interactionSystem.transform.up));

            // Rotate towards axis and upAxis
            pivot.localRotation = Quaternion.LookRotation(axis, upAxis);
        }