public Pose GetPose() { var handleKinematicState = handleKinematicStateProvider.GetKinematicState(); var handlePose = handleKinematicState.pose; var handleToAttachedUIPose = handleAttachmentPoseProvider.GetHandleToAttachmentPose(); var layoutPos = PhysicalInterfaceUtils.LayoutThrownUIPosition2( Camera.main.transform.ToPose(), //handlePose.position, handlePose.Then(handleToAttachedUIPose).position, handleKinematicState.movement.velocity, optimalHeightFromHead: optimalHeightFromHead, optimalDistance: optimalDistance ); if (drawDebug) { DebugPing.Ping(handlePose, LeapColor.red, 0.2f); DebugPing.PingCapsule(handlePose.position, layoutPos, LeapColor.purple, 0.2f); DebugPing.Ping(layoutPos, LeapColor.blue, 0.2f); } var solvedHandlePose = new Pose(layoutPos, Utils.FaceTargetWithoutTwist(layoutPos, Camera.main.transform.position, flip180)).Then(handleToAttachedUIPose.inverse); return(solvedHandlePose); }
public Vector3 GetTargetPosition() { Vector3 layoutPos; if (!uiHandle.wasThrown) { layoutPos = uiHandle.pose.position; if (drawDebug) { DebugPing.Ping(layoutPos, Color.white); } } else { // When the UI is thrown, utilize the static thrown UI util to calculate a decent // final position relative to the user's head given the position and velocity of // the throw. layoutPos = PhysicalInterfaceUtils.LayoutThrownUIPosition2( Camera.main.transform.ToPose(), uiHandle.pose.position, uiHandle.movement.velocity, layoutDistanceMultiplier ); // However, UIs whose central "look" anchor is in a different position than their // grabbed/thrown anchor shouldn't be placed directly at the determined position. // Rather, we need to adjust this position so that the _look anchor,_ not the // thrown handle, winds up in the calculated position from the throw. // Start with the "final" pose as it would currently be calculated. // We need to know the target rotation of the UI based on the target position in // order to adjust the final position properly. Pose finalUIPose = new Pose(layoutPos, GetTargetRotationForPosition(layoutPos)); // We assume the uiAnchorHandle and the uiLookAnchor are rigidly connected. Vector3 curHandleToLookAnchorOffset = (uiLookPositionProvider.GetTargetWorldPosition() - uiHandle.pose.position); // We undo the current rotation of the UI handle and apply that rotation // on the current world-space offset between the handle and the look anchor. // Then we apply the final rotation of the UI to this unrotated offset vector, // giving us the expected final offset between the position that was calculated // by the layout function and the handle. Vector3 finalRotatedLookAnchorOffset = finalUIPose.rotation * (Quaternion.Inverse(uiHandle.pose.rotation) * curHandleToLookAnchorOffset); // We adjust the layout position by this offset, so now the UI should wind up // with its lookAnchor at the calculated location instead of the handle. layoutPos = layoutPos - finalRotatedLookAnchorOffset; // We also adjust any interface positions down a bit. layoutPos += (Camera.main.transform.parent != null ? -Camera.main.transform.parent.up : Vector3.down) * 0.19f; if (drawDebug) { DebugPing.Ping(layoutPos, Color.red); } } return(layoutPos); }