コード例 #1
0
    /*
     * 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;
    }