private Vector3 GetBoneCoordinate(FinchBone bone)
        {
            switch (bone)
            {
            case FinchBone.LeftUpperArm:
                return(FinchCore.GetBoneCoordinate(FinchBone.LeftUpperArm));

            case FinchBone.LeftLowerArm:
                return(elbowPositions[0]);

            case FinchBone.LeftHandCenter:
                return(wristPositions[0]);

            case FinchBone.LeftHand:
                return(GetHandPositionByControllerPosition(wristPositions[0], wristOrientations[0], Vector3.left, FinchCore.GetBoneLength(FinchBone.LeftHand)));

            case FinchBone.RightUpperArm:
                return(FinchCore.GetBoneCoordinate(FinchBone.RightUpperArm));

            case FinchBone.RightLowerArm:
                return(elbowPositions[1]);

            case FinchBone.RightHand:
                return(GetHandPositionByControllerPosition(wristPositions[1], wristOrientations[1], Vector3.right, FinchCore.GetBoneLength(FinchBone.RightHand)));

            case FinchBone.RightHandCenter:
                return(wristPositions[1]);

            default:
                return(Vector3.zero);
            }
        }
        private void FillControllerState(PlayerState outState)
        {
            for (int index = 0; index < PlayerState.Bones.BoneCount; ++index)
            {
                FinchBone bone = PlayerState.Bones[index];
                switch (bone)
                {
                case FinchBone.LeftUpperArm:
                case FinchBone.LeftLowerArm:
                case FinchBone.LeftHand:
                case FinchBone.LeftHandCenter:
                case FinchBone.RightUpperArm:
                case FinchBone.RightLowerArm:
                case FinchBone.RightHand:
                case FinchBone.RightHandCenter:
                {
                    outState.Rotations[index]    = GetBoneRotation(bone);
                    outState.Positions[index]    = GetBoneCoordinate(bone);
                    outState.Available[index]    = true;
                    outState.BonesLengths[index] = FinchCore.GetBoneLength(bone);
                    break;
                }

                default:
                {
                    outState.Rotations[index]    = FinchCore.GetBoneRotation(bone);
                    outState.Positions[index]    = FinchCore.GetBoneCoordinate(bone);
                    outState.Available[index]    = FinchCore.IsBoneAvailable(bone);
                    outState.BonesLengths[index] = FinchCore.GetBoneLength(bone);
                    break;
                }
                }
            }
        }
Esempio n. 3
0
        public override void ReadState(PlayerState outState)
        {
            base.ReadState(outState);

            for (int i = 0; i < PlayerState.Bones.BoneCount; ++i)
            {
                FinchBone bone = PlayerState.Bones[i];
                outState.Rotations[i]    = FinchCore.GetBoneRotation(bone);
                outState.Positions[i]    = FinchCore.GetBoneCoordinate(bone);
                outState.Available[i]    = FinchCore.IsBoneAvailable(bone);
                outState.BonesLengths[i] = FinchCore.GetBoneLength(bone);
            }

            outState.Positions[PlayerState.Bones[FinchBone.Head]] = outState.Positions[PlayerState.Bones[FinchBone.Neck]]
                                                                    + outState.Rotations[PlayerState.Bones[FinchBone.Hips]] * Vector3.up * outState.BonesLengths[PlayerState.Bones[FinchBone.Neck]];

            outState.Positions[PlayerState.Bones[FinchBone.RightEye]] = outState.Positions[PlayerState.Bones[FinchBone.Head]]
                                                                        + outState.Rotations[PlayerState.Bones[FinchBone.Head]] * Vector3.up * outState.BonesLengths[PlayerState.Bones[FinchBone.Head]]
                                                                        + outState.Rotations[PlayerState.Bones[FinchBone.Head]] * Vector3.forward * eyeForwardShift;
        }
        /// <summary>
        /// Handle calculations of arm transforms. Returns false, if chirality is not corrected.
        /// </summary>
        /// <param name="chirality"></param>
        /// <returns></returns>
        private bool HandleCalculations(FinchChirality chirality)
        {
            int       index    = -1;
            FinchBone handBone = FinchBone.Last;

            // Multiplier for handedness such that 1 = Right, 0 = Center, -1 = left.
            Vector3 handedMultiplier = new Vector3(1, 1, 1);

            if (chirality == FinchChirality.Left)
            {
                index              = 0;
                handBone           = FinchBone.LeftHand;
                handedMultiplier.x = -handedMultiplier.x;
            }
            else if (chirality == FinchChirality.Right)
            {
                index    = 1;
                handBone = FinchBone.RightHand;
            }
            else
            {
                return(false);
            }

            Quaternion fpose = (chirality == FinchChirality.Left) ? FPoseLeft : FPoseRight;

            shoulderOrientations[index] = FinchCore.GetBoneRotation(FinchBone.Chest);
            Quaternion controllerOrientation = FinchCore.GetBoneRotation(handBone) * fpose;

            controllerOrientation = Quaternion.Inverse(shoulderOrientations[index]) * controllerOrientation;

            // Get the relative positions of the joints
            elbowPositions[index] = ElbowPosition + new Vector3(0.0f, addedElbowHeight, addedElbowDepth);
            elbowPositions[index] = Vector3.Scale(elbowPositions[index], handedMultiplier);
            wristPositions[index] = Vector3.Scale(WristPosition, handedMultiplier);
            Vector3 armExtensionOffset = Vector3.Scale(ArmExtensionOffset, handedMultiplier);

            // Extract just the x rotation angle
            Vector3 controllerForward = controllerOrientation * Vector3.forward;
            float   xAngle            = 90.0f - Vector3.Angle(controllerForward, Vector3.up);

            // Remove the z rotation from the controller
            Quaternion xyRotation = Quaternion.FromToRotation(Vector3.forward, controllerForward);

            // Offset the elbow by the extension
            float normalizedAngle = (xAngle - MinExtensionAngle) / (MaxExtensionAngle - MinExtensionAngle);
            float extensionRatio  = Mathf.Clamp(normalizedAngle, 0.0f, 1.0f);

            if (!useAccelerometer)
            {
                elbowPositions[index] += armExtensionOffset * extensionRatio;
            }

            // Calculate the lerp interpolation factor
            float totalAngle     = Quaternion.Angle(xyRotation, Quaternion.identity);
            float lerpSuppresion = 1.0f - Mathf.Pow(totalAngle / 180.0f, 6);
            float lerpValue      = lerpSuppresion * (0.4f + 0.6f * extensionRatio * ExtensionWeight);

            // Apply the absolute rotations to the joints
            Quaternion lerpRotation = Quaternion.Lerp(Quaternion.identity, xyRotation, lerpValue);

            elbowOrientations[index] = shoulderOrientations[index] * Quaternion.Inverse(lerpRotation) * controllerOrientation;
            wristOrientations[index] = shoulderOrientations[index] * controllerOrientation;

            // Determine the relative positions
            elbowPositions[index] = shoulderOrientations[index] * elbowPositions[index];
            wristPositions[index] = elbowPositions[index] + elbowOrientations[index] * wristPositions[index];

            elbowOrientations[index]    = elbowOrientations[index] * Quaternion.Inverse(fpose);
            wristOrientations[index]    = wristOrientations[index] * Quaternion.Inverse(fpose);
            shoulderOrientations[index] = (chirality == FinchChirality.Left ? FinchCore.GetBoneRotation(FinchBone.LeftUpperArm) : FinchCore.GetBoneRotation(FinchBone.RightUpperArm));

            Vector3 headCoords  = FinchCore.GetBoneCoordinate(FinchBone.Head);
            Vector3 chestCoords = FinchCore.GetBoneCoordinate(FinchBone.Chest);
            Vector3 headOffset  = headCoords - chestCoords;

            elbowPositions[index] += headOffset;
            wristPositions[index] += headOffset;

            return(true);
        }