/* * Executes the redirection according to the chosen curve and path by * calculating a position and orientation for the virtual camera. * */ private void doRedirection() { // Set offset transforms (virtual position/orientation is set to zero) orientationOffset.localRotation = Quaternion.Inverse(UnityEngine.VR.InputTracking.GetLocalRotation(UnityEngine.VR.VRNode.Head)); positionOffset.localPosition = -UnityEngine.VR.InputTracking.GetLocalPosition(UnityEngine.VR.VRNode.Head); // Get current position and rotation (data from tracking system) Vector2 realWorldCurrentPosition = switchDimensions(Camera.main.transform.localPosition); Quaternion realWorldCurrentRotation = Camera.main.transform.localRotation; //Debug.Log("Current: " + realWorldCurrentPosition); int pathIndex = data.getPathIndex(currentJoint, currentCurve); // Calculate distance between real world current position and real world circle center point float distance = Vector2.Distance(realWorldCurrentPosition, switchDimensions(currentCurve.getCircleCenter())); //Debug.Log("Distance: " + distance); // Calculate angle between start and current position //float angleWalkedOnRealCircle = Vector2.Angle(switchDimensions(switchDimensions(currentJoint.getPosition() + redirectionDirection*data.calculateOffset(currentJoint.getPosition(), currentCurve.getCircleCenter()) - currentCurve.getCircleCenter())), realWorldCurrentPosition - switchDimensions(currentCurve.getCircleCenter())); Vector3 realWalkingStartPosition = currentJoint.getWalkingStartPosition(pathIndex); angleWalkedOnRealCircle = Mathf.Acos((Vector2.Dot((switchDimensions(currentCurve.getCircleCenter()) - switchDimensions(realWalkingStartPosition)), (switchDimensions(currentCurve.getCircleCenter()) - realWorldCurrentPosition))) / ((switchDimensions(currentCurve.getCircleCenter()) - switchDimensions(realWalkingStartPosition)).magnitude * (switchDimensions(currentCurve.getCircleCenter()) - realWorldCurrentPosition).magnitude)); //Debug.Log("angleWalkedOnRealCircle: " + angleWalkedOnRealCircle); // Multiply angle and radius = walked distance float walkedDistance = angleWalkedOnRealCircle * currentCurve.getRadius(); //Debug.Log("Walked: " + walkedDistance); // Calculate side drift: d-r float sideDrift = distance - currentCurve.getRadius(); //Debug.Log("Side: " + sideDrift); // Calculate angle on virtual circle angleWalkedOnVirtualCircle = walkedDistance / currentPath.getRadius(); //Debug.Log("angleWalkedOnVirtualCircle: " + angleWalkedOnVirtualCircle); // Calculate direction from virtual circle center to intersection // - redirectionDirection*data.calculateOffset(currentIntersection.getPosition(), currentPath.getCircleCenter()) Vector3 virtualWalkingStartPosition = currentIntersection.getWalkingStartPosition(pathIndex); Vector2 directionToIntersection = switchDimensions(virtualWalkingStartPosition - currentPath.getCircleCenter()).normalized; //Debug.Log("directionToIntersection: " + directionToIntersection); // Calculate direction to virtual position by rotating direction by angle walked Vector3 directionToVirtualPosition = Quaternion.AngleAxis(redirectionDirection * angleWalkedOnVirtualCircle * Mathf.Rad2Deg, Vector3.up) * new Vector3(directionToIntersection.x, 0, directionToIntersection.y); // Multiply direction by radius + side drift directionToVirtualPosition = directionToVirtualPosition * (currentPath.getRadius() + sideDrift); //Debug.Log("virtualPosition: " + virtualPosition); // Calculate and set virtual position this.transform.position = new Vector3(currentPath.getCircleCenter().x + directionToVirtualPosition.x, Camera.main.transform.localPosition.y, currentPath.getCircleCenter().z + directionToVirtualPosition.z); //Debug.Log(this.transform.position); // Calculate and set virtual rotation: redirection + current camera rotation + old rotation float redirection = Mathf.Rad2Deg * -redirectionDirection * (angleWalkedOnRealCircle - angleWalkedOnVirtualCircle); float y = redirection + realWorldCurrentRotation.eulerAngles.y + oldRotation; Quaternion virtualRotation = Quaternion.Euler(realWorldCurrentRotation.eulerAngles.x, y, realWorldCurrentRotation.eulerAngles.z); this.transform.rotation = virtualRotation; }