/// <summary> /// Given two points and the transform that they are in, set position, rotation, and scale of a cylinder transform to connect it between the two points /// </summary> /// <param name="endPointSpace"></param> /// <param name="a">One end point in the space of endPointSpace</param> /// <param name="b">Other end point in the space of endPointSpace</param> /// <param name="cylTransform">transform for the cylinder primitive to connect</param> public static void ConnectCylinderBetweenPoints(Transform endPointSpace, Vector3 a, Vector3 b, Transform cylTransform) { cylTransform.localPosition = MathUtils.TransformPointFromTo(endPointSpace, cylTransform.parent, 0.5f * (a + b)); Vector3 dir = MathUtils.TransformDirectionFromTo(endPointSpace, cylTransform.parent, (b - a).normalized); cylTransform.localRotation = Quaternion.LookRotation(dir) * Quaternion.FromToRotation(Vector3.up, Vector3.forward); Vector3 scale = cylTransform.localScale; scale.y = (a - b).magnitude * 0.5f; cylTransform.localScale = scale; }
/// <summary> /// Returns if a point will be rendered on the screen in either eye /// </summary> /// <param name="position"></param> /// <returns></returns> public static bool IsInFOV(Vector3 position) { float verticalFovHalf = Camera.main.fieldOfView / 2; float horizontalFovHalf = GetHorizontalFieldOfViewRadians() * Mathf.Rad2Deg / 2; Vector3 deltaPos = position - Camera.main.transform.position; Vector3 headDeltaPos = MathUtils.TransformDirectionFromTo(null, Camera.main.transform, deltaPos).normalized; float yaw = Mathf.Asin(headDeltaPos.x) * Mathf.Rad2Deg; float pitch = Mathf.Asin(headDeltaPos.y) * Mathf.Rad2Deg; return(Mathf.Abs(yaw) < horizontalFovHalf && Mathf.Abs(pitch) < verticalFovHalf); }
/// <summary> /// Position transform along the gaze direction and orient yaw to match, with the specified offset /// </summary> /// <param name="stageTransform">transform of higher-level space where 0,1,0 is up</param> /// <param name="tran">transform to be repositioned</param> /// <param name="offset">translation offset, Z is forward</param> /// <param name="yawOffset">yaw offset</param> public static void MoveObjectInFrontOfUser(Transform stageTransform, Transform tran, Vector3 offset, float yawOffset) { // have obj track head position with translation offset Vector3 stageHeadPos = MathUtils.TransformPointFromTo(null, stageTransform, Camera.main.transform.transform.position); Vector3 stageHeadDir = MathUtils.TransformDirectionFromTo(null, stageTransform, Camera.main.transform.transform.forward); stageHeadDir.y = 0.0f; // ignore head pitch - use head position to set height stageHeadDir.Normalize(); Vector3 sideDir = Vector3.Cross(stageHeadDir, Vector3.up).normalized; Vector3 stageNewPos = stageHeadPos + stageHeadDir * offset.z + Vector3.up * offset.y + sideDir * offset.x; tran.localPosition = MathUtils.TransformPointFromTo(stageTransform, tran.parent, stageNewPos); // also track head yaw Vector3 toDir = MathUtils.TransformDirectionFromTo(stageTransform, tran.parent, stageHeadDir); Quaternion rot = Quaternion.FromToRotation(Vector3.forward, toDir.normalized) * Quaternion.Euler(0.0f, yawOffset, 0.0f); tran.localRotation = rot; }