// =============================================================================
    // METHODS STATIC --------------------------------------------------------------
    public static void SetVanishingPoint( Camera cam, float offset, ClientCameraScreen screen )
    {
        Transform t = cam.transform;
        NearPlane plane = new NearPlane();

        Vector3 nearCenter = t.position + t.forward*cam.nearClipPlane;
        Plane nearPlane = new Plane ( -t.forward, nearCenter );
        float distance = 0f;
        Vector3 direction;
        Ray ray;

        Vector3 screenTL = t.TransformPoint ( new Vector3 ( ( -screen.Width/2.0f ) + offset, screen.Height/2.0f, screen.Distance ) );
        direction = ( screenTL - t.position ).normalized;
        ray = new Ray ( t.position, direction );
        nearPlane.Raycast ( ray, out distance );
        Vector3 nearTL = -( t.InverseTransformPoint ( nearCenter ) - t.InverseTransformPoint ( ( t.position + direction*distance ) ) );

        Vector3 screenBR = t.TransformPoint ( new Vector3 ( ( screen.Width/2.0f ) + offset, -screen.Height/2.0f, screen.Distance ) );
        direction = ( screenBR - t.position ).normalized;
        ray = new Ray ( t.position, direction );
        nearPlane.Raycast ( ray, out distance );
        Vector3 nearBR = -( t.InverseTransformPoint ( nearCenter ) - t.InverseTransformPoint ( ( t.position + direction*distance ) ) );

        plane.left = nearTL.x;
        plane.top = nearTL.y;
        plane.right = nearBR.x;
        plane.bottom = nearBR.y;
        plane.near = cam.nearClipPlane;
        plane.far = cam.farClipPlane;
        cam.projectionMatrix = PerspectiveOffCenter ( plane );
    }
    private static Matrix4x4 PerspectiveOffCenter( NearPlane plane )
    {
        float x = ( 2.0f*plane.near )/( plane.right - plane.left );
        float y = ( 2.0f*plane.near )/( plane.top - plane.bottom );
        float a = ( plane.right + plane.left )/( plane.right - plane.left );
        float b = ( plane.top + plane.bottom )/( plane.top - plane.bottom );
        float c = -( plane.far + plane.near )/( plane.far - plane.near );
        float d = -( 2.0f*plane.far*plane.near )/( plane.far - plane.near );
        float e = -1.0f;
        Matrix4x4 m = new Matrix4x4 ();

        m[0, 0] = x;
        m[0, 1] = 0.0f;
        m[0, 2] = a;
        m[0, 3] = 0.0f;
        m[1, 0] = 0.0f;
        m[1, 1] = y;
        m[1, 2] = b;
        m[1, 3] = 0.0f;
        m[2, 0] = 0.0f;
        m[2, 1] = 0.0f;
        m[2, 2] = c;
        m[2, 3] = d;
        m[3, 0] = 0.0f;
        m[3, 1] = 0.0f;
        m[3, 2] = e;
        m[3, 3] = 0.0f;

        return m;
    }
Beispiel #3
0
    private static Matrix4x4 PerspectiveOffCenter(NearPlane plane)
    {
        float     x = (2.0f * plane.near) / (plane.right - plane.left);
        float     y = (2.0f * plane.near) / (plane.top - plane.bottom);
        float     a = (plane.right + plane.left) / (plane.right - plane.left);
        float     b = (plane.top + plane.bottom) / (plane.top - plane.bottom);
        float     c = -(plane.far + plane.near) / (plane.far - plane.near);
        float     d = -(2.0f * plane.far * plane.near) / (plane.far - plane.near);
        float     e = -1.0f;
        Matrix4x4 m = new Matrix4x4();

        m[0, 0] = x;
        m[0, 1] = 0.0f;
        m[0, 2] = a;
        m[0, 3] = 0.0f;
        m[1, 0] = 0.0f;
        m[1, 1] = y;
        m[1, 2] = b;
        m[1, 3] = 0.0f;
        m[2, 0] = 0.0f;
        m[2, 1] = 0.0f;
        m[2, 2] = c;
        m[2, 3] = d;
        m[3, 0] = 0.0f;
        m[3, 1] = 0.0f;
        m[3, 2] = e;
        m[3, 3] = 0.0f;

        return(m);
    }
Beispiel #4
0
    /// <summary>
    /// Calculate a projection matrix from a given near plane.
    /// </summary>
    /// <param name="np">
    /// A <see cref="NearPlane"/>
    /// The NearPlane that defines the projection.
    /// </param>
    /// <returns>
    /// A <see cref="Matrix4x4"/>
    /// The projection matrix.
    /// </returns>
    Matrix4x4 PerspectiveOffCenter(NearPlane np)
    {
        float x = (2.0f * np.near) / (np.right - np.left);
        float y = (2.0f * np.near) / (np.top - np.bottom);
        float a = (np.right + np.left) / (np.right - np.left);
        float b = (np.top + np.bottom) / (np.top - np.bottom);
        float c = -(np.far + np.near) / (np.far - np.near);
        float d = -(2.0f * np.far * np.near) / (np.far - np.near);
        float e = -1.0f;

        Matrix4x4 m = new Matrix4x4();

        m[0, 0] = x;
        m[0, 1] = 0;
        m[0, 2] = a;
        m[0, 3] = 0;
        m[1, 0] = 0;
        m[1, 1] = y;
        m[1, 2] = b;
        m[1, 3] = 0;
        m[2, 0] = 0;
        m[2, 1] = 0;
        m[2, 2] = c;
        m[2, 3] = d;
        m[3, 0] = 0;
        m[3, 1] = 0;
        m[3, 2] = e;
        m[3, 3] = 0;

        return(m);
    }
Beispiel #5
0
    // =============================================================================
    // METHODS STATIC --------------------------------------------------------------

    public static void SetVanishingPoint(Camera cam, float offset, ClientCameraScreen screen)
    {
        Transform t     = cam.transform;
        NearPlane plane = new NearPlane();

        Vector3 nearCenter = t.position + t.forward * cam.nearClipPlane;
        Plane   nearPlane  = new Plane(-t.forward, nearCenter);
        float   distance   = 0f;
        Vector3 direction;
        Ray     ray;

        Vector3 screenTL = t.TransformPoint(new Vector3((-screen.Width / 2.0f) + offset, screen.Height / 2.0f, screen.Distance));

        direction = (screenTL - t.position).normalized;
        ray       = new Ray(t.position, direction);
        nearPlane.Raycast(ray, out distance);
        Vector3 nearTL = -(t.InverseTransformPoint(nearCenter) - t.InverseTransformPoint((t.position + direction * distance)));

        Vector3 screenBR = t.TransformPoint(new Vector3((screen.Width / 2.0f) + offset, -screen.Height / 2.0f, screen.Distance));

        direction = (screenBR - t.position).normalized;
        ray       = new Ray(t.position, direction);
        nearPlane.Raycast(ray, out distance);
        Vector3 nearBR = -(t.InverseTransformPoint(nearCenter) - t.InverseTransformPoint((t.position + direction * distance)));

        plane.left           = nearTL.x;
        plane.top            = nearTL.y;
        plane.right          = nearBR.x;
        plane.bottom         = nearBR.y;
        plane.near           = cam.nearClipPlane;
        plane.far            = cam.farClipPlane;
        cam.projectionMatrix = PerspectiveOffCenter(plane);
    }
    void OnPreCull()
    {
        //cam = camera;

        // update screen (if defined)
        // this must be called manually to ensure the correct order of execution
        if (screen != null)
        {
            screen.SetSize(3.0f, 3.0f);
            screen.UpdateCorners();
        }
        else
        {
            cam.ResetProjectionMatrix();
        }

        // calculate off-center projection
        if (projectionMode == ProjectionMode.Async || ProjectionMode == ProjectionMode.ObliqueAsync)
        {
            NearPlane plane = CalculateNearPlane(screen, cam, transform);
            mp = PerspectiveOffCenter(plane);
        }

        // choose the correct projection matrix
        switch (projectionMode)
        {
        case ProjectionMode.Standard:
            cam.ResetProjectionMatrix();
            //	Debug.Log("Standard");
            break;

        case ProjectionMode.Oblique:
            cam.projectionMatrix = bimberMatrix * origProjMatrix;
            //	Debug.Log("Oblique");
            break;

        case ProjectionMode.Async:
            cam.projectionMatrix = mp;
            //	Debug.Log("Async");
            break;

        case ProjectionMode.ObliqueAsync:
            cam.projectionMatrix = bimberMatrix * mp;
            //	Debug.Log("ObliqueAsync");
            break;
        }
    }
Beispiel #7
0
    /// <summary>
    /// Calculate a near plane that defines a projection looking through a virtual window/screen.
    /// </summary>
    /// <param name="window">
    /// A <see cref="VirtualScreen"/>
    /// The virtual window the frustum should be locked to.
    /// </param>
    /// <param name="cam">
    /// A <see cref="Camera"/>
    /// The camera for which the projection is calculated.
    /// </param>
    /// <param name="t">
    /// A <see cref="Transform"/>
    ///
    /// </param>
    /// <returns>
    /// A <see cref="NearPlane"/>
    /// </returns>
    NearPlane CalculateNearPlane(VirtualScreen window, Camera cam, Transform t)
    {
        Profiler.BeginSample("CalcNearPlane");

        // align camera with window
        t.rotation = window.transform.rotation;

        // get top left and bottom right coordinates
        Vector3 wtl = window.tl;
        Vector3 wbr = window.br;

        NearPlane plane = new NearPlane();

        // construct nearPlane
        Vector3 nearCenter = t.position + t.forward * cam.nearClipPlane;
        Plane   nearPlane  = new Plane(-t.forward, nearCenter);

        // calculate top left for near plane
        float   dist      = 0;
        Vector3 direction = (wtl - t.position).normalized;
        Ray     ray       = new Ray(t.position, direction);

        nearPlane.Raycast(ray, out dist);
        Vector3 ntl = -(t.InverseTransformPoint(nearCenter) - t.InverseTransformPoint((t.position + direction * dist)));

        plane.left = ntl.x;
        plane.top  = ntl.y;


        // calculate bottom right for near plane
        direction = (wbr - t.position).normalized;
        ray       = new Ray(t.position, direction);
        nearPlane.Raycast(ray, out dist);
        Vector3 nbr = -(t.InverseTransformPoint(nearCenter) - t.InverseTransformPoint((t.position + direction * dist)));

        plane.right  = nbr.x;
        plane.bottom = nbr.y;
        plane.near   = cam.nearClipPlane;
        plane.far    = cam.farClipPlane;

        Profiler.EndSample();

        return(plane);
    }
Beispiel #8
0
            /// <summary>
            /// Creats a NearPlane based on the given VirtualScreen and transform.
            /// This function comes from the old CAVE Asset.
            /// </summary>
            /// <param name="window">VirtualScreen</param>
            /// <param name="targetTransform">Transform</param>
            /// <returns></returns>
            private NearPlane CalculateNearPlane(VirtualScreen window, Transform targetTransform)
            {
                NearPlane nearPlane = new NearPlane();

                Vector3 nearCenter = targetTransform.position + targetTransform.forward * cam.nearClipPlane;
                Plane   plane      = new Plane(-targetTransform.forward, nearCenter);
                float   distance   = 0.0f;
                Vector3 direction;
                Ray     ray;

                // calculate top left for nearPlane
                direction = (window.topLeft - targetTransform.position).normalized;
                ray       = new Ray(targetTransform.position, direction);
                plane.Raycast(ray, out distance);

                Vector3 nearTopLeft = -(targetTransform.InverseTransformPoint(nearCenter) - targetTransform.InverseTransformPoint((targetTransform.position + direction * distance)));

                nearPlane.left = nearTopLeft.x;
                nearPlane.top  = nearTopLeft.y;

                // calculate bottom right for nearPlane
                direction = (window.bottomRight - targetTransform.position).normalized;
                ray       = new Ray(targetTransform.position, direction);
                plane.Raycast(ray, out distance);

                Vector3 nearBottomRight = -(targetTransform.InverseTransformPoint(nearCenter) - targetTransform.InverseTransformPoint((targetTransform.position + direction * distance)));

                nearPlane.right  = nearBottomRight.x;
                nearPlane.bottom = nearBottomRight.y;

                // near and far clipPlane for nearPlane
                nearPlane.near = cam.nearClipPlane;
                nearPlane.far  = cam.farClipPlane;

                return(nearPlane);
            }
Beispiel #9
0
    /// <summary>
    /// Calculate a projection matrix from a given near plane.
    /// </summary>
    /// <param name="np">
    /// A <see cref="NearPlane"/>
    /// The NearPlane that defines the projection.
    /// </param>
    /// <returns>
    /// A <see cref="Matrix4x4"/>
    /// The projection matrix.
    /// </returns>
    Matrix4x4 PerspectiveOffCenter(NearPlane np)
    {
        float x = (2.0f * np.near) / (np.right - np.left);
        float y = (2.0f * np.near) / (np.top - np.bottom);
        float a = (np.right + np.left) / (np.right - np.left);
        float b = (np.top + np.bottom) / (np.top - np.bottom);
        float c = -(np.far + np.near) / (np.far - np.near);
        float d = -(2.0f * np.far * np.near) / (np.far - np.near);
        float e = -1.0f;

        Matrix4x4 m = new Matrix4x4();

        m[0, 0] = x;
        m[0, 1] = 0;
        m[0, 2] = a;
        m[0, 3] = 0;
        m[1, 0] = 0;
        m[1, 1] = y;
        m[1, 2] = b;
        m[1, 3] = 0;
        m[2, 0] = 0;
        m[2, 1] = 0;
        m[2, 2] = c;
        m[2, 3] = d;
        m[3, 0] = 0;
        m[3, 1] = 0;
        m[3, 2] = e;
        m[3, 3] = 0;

        return m;
    }
Beispiel #10
0
    /// <summary>
    /// Calculate a near plane that defines a projection looking through a virtual window/screen.
    /// </summary>
    /// <param name="window">
    /// A <see cref="VirtualScreen"/>
    /// The virtual window the frustum should be locked to.
    /// </param>
    /// <param name="cam">
    /// A <see cref="Camera"/>
    /// The camera for which the projection is calculated.
    /// </param>
    /// <param name="t">
    /// A <see cref="Transform"/>
    ///
    /// </param>
    /// <returns>
    /// A <see cref="NearPlane"/>
    /// </returns>
    NearPlane CalculateNearPlane(VirtualScreen window, Camera cam, Transform t)
    {
        Profiler.BeginSample("CalcNearPlane");

        // align camera with window
        t.rotation = window.transform.rotation;

        // get top left and bottom right coordinates
        Vector3 wtl = window.tl;
        Vector3 wbr = window.br;

        NearPlane plane = new NearPlane();

        // construct nearPlane
        Vector3 nearCenter = t.position + t.forward * cam.nearClipPlane;
        Plane nearPlane = new Plane(-t.forward, nearCenter);

        // calculate top left for near plane
        float dist = 0;
        Vector3 direction = (wtl - t.position).normalized;
        Ray ray = new Ray(t.position, direction);
        nearPlane.Raycast(ray, out dist);
        Vector3 ntl = -(t.InverseTransformPoint(nearCenter) - t.InverseTransformPoint((t.position + direction * dist)));
        plane.left = ntl.x;
        plane.top = ntl.y;

        // calculate bottom right for near plane
        direction = (wbr - t.position).normalized;
        ray = new Ray(t.position, direction);
        nearPlane.Raycast(ray, out dist);
        Vector3 nbr = -(t.InverseTransformPoint(nearCenter) - t.InverseTransformPoint((t.position + direction * dist)));
        plane.right = nbr.x;
        plane.bottom = nbr.y;
        plane.near = cam.nearClipPlane;
        plane.far = cam.farClipPlane;

        Profiler.EndSample();

        return plane;
    }