Пример #1
0
    /*
     * Returns the circle center position of the new path that starts at given intersection and uses given curve and radius.
     * */
    private Vector3 calculateCircleCenterOfPath(VirtualIntersection startIntersection, Curve curve, float radius)
    {
        int newPathIndex = this.getPathIndex(startIntersection.getJoint(), curve);

        Vector3 directionToCurveCircleCenter = (curve.getCircleCenter() - startIntersection.getJoint().getWalkingStartPosition(newPathIndex)).normalized;
        Vector3 directionToPathCircleCenter  = new Vector3();

        // Check which paths are connected to the intersection and pick one (first) for calculation.
        // New path circle center can be calculated by using the direction to the curve circle center and rotating it.
        for (int i = 0; i < 4; i++)
        {
            if (startIntersection.getPath(i) != null)
            {
                Vector3 directionToStartWalkingPosOnPath  = (startIntersection.getWalkingStartPosition(i) - startIntersection.getPosition()).normalized;
                Vector3 directionToStartWalkingPosOnCurve = (startIntersection.getJoint().getWalkingStartPosition(i) - startIntersection.getJoint().getPosition()).normalized;
                float   angle = -angle360(directionToStartWalkingPosOnPath, directionToStartWalkingPosOnCurve);
                directionToPathCircleCenter = Quaternion.AngleAxis(angle, Vector3.up) * directionToCurveCircleCenter;
                break;
            }
            if (i == 3)
            {
                // If no case was chosen this is the start joint. Then,
                // we can use the curve circle center for calculating the path circle center without rotating.
                directionToPathCircleCenter = directionToCurveCircleCenter;
            }
        }

        Vector3 result = startIntersection.getWalkingStartPosition(newPathIndex) + directionToPathCircleCenter.normalized * radius;

        return(result);
    }
Пример #2
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;
    }
Пример #3
0
    /*
     * Creates a new path and the corresponding intersection at the end.
     * */
    public void createPathAndIntersection(VirtualIntersection startIntersection, Curve curve, float gain)
    {
        // Calculate radius of virtual path
        float radius = curve.getRadius() * gain;
        // Calculate length of curve
        float length = Mathf.Deg2Rad * curve.getAngle() * curve.getRadius();
        // Calculate angle of virtual path
        float angle = Mathf.Rad2Deg * (length / radius);

        int newPathIndex = this.getPathIndex(startIntersection.getJoint(), curve);

        // Calculate end joint point
        JointPoint endJointPoint = getCorrespondingEndJointPoint(startIntersection, curve);

        // Calculate the circle center of the new path
        Vector3 circleCenter = calculateCircleCenterOfPath(startIntersection, curve, radius);

        // Calculate (nomralized) direction vector from circle center to start intersection
        Vector3 directionToStartPath = (startIntersection.getWalkingStartPosition(newPathIndex) - circleCenter).normalized;

        // Calculate direction vector from circle center to end intersection by:
        // 1. rotating the direction vector to start intersection (around angle of path and angle of walking zone)
        // 2. extending the vector by the virtual radius
        float   angleOfWalkingZone = Mathf.Rad2Deg * startIntersection.getJoint().getWalkingZoneRadius() / radius;
        Vector3 directionToEndPath = Quaternion.AngleAxis(this.getSignOfCurve(startIntersection.getJoint(), endJointPoint) * angle, Vector3.up) * directionToStartPath;

        directionToEndPath = directionToEndPath * radius;

        Vector3 directionToEndIntersection = Quaternion.AngleAxis(this.getSignOfCurve(startIntersection.getJoint(), endJointPoint) * angleOfWalkingZone, Vector3.up) * directionToEndPath;

        // Calculate position of new end intersection
        Vector3 positionEndIntersection = circleCenter + directionToEndIntersection;

        VirtualIntersection endIntersection = CreateInstance <VirtualIntersection>();

        endIntersection.init(positionEndIntersection, endJointPoint, "" + intersections.Count);

        List <VirtualIntersection> endPoints = new List <VirtualIntersection>();

        endPoints.Add(startIntersection);
        endPoints.Add(endIntersection);

        VirtualPath path = CreateInstance <VirtualPath>();

        path.init(circleCenter, gain, curve, endPoints, radius, angle);

        intersections.Add(endIntersection);
        paths.Add(path);

        startIntersection.addPath(path, this.getPathIndex(startIntersection.getJoint(), curve));
        endIntersection.addPath(path, this.getPathIndex(endJointPoint, curve));

        calculateWalkingStartPositions(this.getPathIndex(endJointPoint, curve), endJointPoint, endIntersection, circleCenter, directionToEndPath);

#if UNITY_EDITOR
        SceneView.RepaintAll();
        AssetDatabase.AddObjectToAsset(endIntersection, this);
        AssetDatabase.AddObjectToAsset(path, this);
        EditorUtility.SetDirty(this);
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
#endif
        Debug.Log("Created new path and intersection");
    }