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; } } } }
private void ArmDirection() { Vector3 origin = (bone == FinchBone.RightUpperArm) ? Vector3.right : Vector3.left; float y = (FinchCore.GetBoneRotation(bone, false) * origin).y; if (Mathf.Abs(y) < angleBorder) { return; } if (y > 0) { sideAboveZero += y; } else { sideBelowZero -= y; } }
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> /// Returns bone rotation. /// </summary> /// <param name="bone">Certain bone</param> /// <param name="fPose">Use fPose rotation</param> /// <returns>Bone rotation quaternion</returns> public static Quaternion GetBoneRotation(FinchBone bone, bool fPose = true) { return(FinchCore.GetBoneRotation(bone, fPose)); }
/// <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); }