using SC.XR.Unity.Module_InputSystem; using System.Collections; using System.Collections.Generic; using UnityEngine; public class MoveLogic { private float pointerRefDistance; private bool pointerPosIndependentOfHead = true; private Vector3 pointerLocalGrabPoint; private Vector3 objectLocalGrabPoint; private Vector3 grabToObject; /// /// Setup function /// public void Setup(SCPose pointerCentroidPose, Vector3 grabCentroid, Transform objectPose, Vector3 objectScale) { pointerRefDistance = GetDistanceToBody(pointerCentroidPose); pointerPosIndependentOfHead = pointerRefDistance != 0; Quaternion worldToPointerRotation = Quaternion.Inverse(pointerCentroidPose.rotation); pointerLocalGrabPoint = worldToPointerRotation * (grabCentroid - pointerCentroidPose.position); objectLocalGrabPoint = Quaternion.Inverse(objectPose.rotation) * (grabCentroid - objectPose.position); objectLocalGrabPoint = Vector3.Scale(objectLocalGrabPoint, new Vector3(1f / objectScale.x, 1f / objectScale.y, 1f / objectScale.z)) ; grabToObject = objectPose.position - grabCentroid; } /// /// Update the position based on input. /// /// A Vector3 describing the desired position public Vector3 Update(SCPose pointerCentroidPose, Quaternion objectRotation, Vector3 objectScale, bool usePointerRotation) { float distanceRatio = 1.0f; if (pointerPosIndependentOfHead) { // Compute how far away the object should be based on the ratio of the current to original hand distance float currentHandDistance = GetDistanceToBody(pointerCentroidPose); distanceRatio = currentHandDistance / pointerRefDistance; } if (usePointerRotation) { Vector3 scaledGrabToObject = Vector3.Scale(objectLocalGrabPoint, objectScale); Vector3 adjustedPointerToGrab = (pointerLocalGrabPoint * distanceRatio); adjustedPointerToGrab = pointerCentroidPose.rotation * adjustedPointerToGrab; return adjustedPointerToGrab - objectRotation * scaledGrabToObject + pointerCentroidPose.position; } else { return pointerCentroidPose.position + (pointerCentroidPose.rotation * pointerLocalGrabPoint + grabToObject) * distanceRatio; } } private float GetDistanceToBody(SCPose pointerCentroidPose) { // The body is treated as a ray, parallel to the y-axis, where the start is head position. // This means that moving your hand down such that is the same distance from the body will // not cause the manipulated object to move further away from your hand. However, when you // move your hand upward, away from your head, the manipulated object will be pushed away. if (pointerCentroidPose.position.y > API_GSXR_Slam.SlamManager.head.transform.position.y) { return Vector3.Distance(pointerCentroidPose.position, API_GSXR_Slam.SlamManager.head.transform.position); } else { Vector2 headPosXZ = new Vector2(API_GSXR_Slam.SlamManager.head.transform.position.x, API_GSXR_Slam.SlamManager.head.transform.position.z); Vector2 pointerPosXZ = new Vector2(pointerCentroidPose.position.x, pointerCentroidPose.position.z); return Vector2.Distance(pointerPosXZ, headPosXZ); } } }