Esempio n. 1
0
    public bool ShouldCameraRender(Camera cam, ScreenPoatalArea spa)
    {
        var planes = GeometryUtility.CalculateFrustumPlanes(cam);

        var   mySpa = GetPortalRect(cam);
        float xMin  = Mathf.Max(mySpa.scrrenRect.xMin, spa.scrrenRect.xMin);
        float xMax  = Mathf.Min(mySpa.scrrenRect.xMax, spa.scrrenRect.xMax);
        float yMin  = Mathf.Max(mySpa.scrrenRect.yMin, spa.scrrenRect.yMin);
        float yMax  = Mathf.Min(mySpa.scrrenRect.yMax, spa.scrrenRect.yMax);

        if (cam.gameObject.name == "Main Camera" && gameObject.name == "Quad2")
        {
            Debug.Log("MySpa:  " + mySpa);
            Debug.Log("plan: " + (xMin < xMax && yMin < yMax));
            Debug.Log("Rec: xmin:" + xMin + " xmax:" + xMax + " ymin:" + yMin + " ymax:" + yMax);
            Debug.Log("Dep: " + (mySpa.maxDeep > spa.minDeep));
            //Debug.Log(Vector3.Dot(portalPlaneRenderer.transform.position - cam.transform.position, portalForward) < 0);
        }


        return((motherPair != null && motherPair.portalA != null && motherPair.portalB != null &&
                //GeometryUtility.TestPlanesAABB(planes, portalBounds) &&
                xMin < xMax && yMin < yMax && mySpa.maxDeep > spa.minDeep &&
                Vector3.Dot(portalPlaneRenderer.transform.position - cam.transform.position, portalForward) < 0) ||
               (portalPlaneRenderer.transform.position - cam.transform.position).sqrMagnitude < SizeX * SizeY);
    }
Esempio n. 2
0
    private void BuildPortalViewTree(PortalNode p, int lastDepth)
    {
        if (lastDepth >= maxLayer)
        {
            return;
        }

        lastDepth++;

        Camera currentCam = p.thisPortal == null ? rootCamera : p.thisPortal.portalCamera;

        if (p.thisPortal != null)
        {
            currentCam.transform.position = p.position;
            currentCam.transform.rotation = p.rotation;
            currentCam.projectionMatrix   = p.projMat;
            currentCam.targetTexture      = p.rt;
        }

        ScreenPoatalArea portalRect = p.thisPortal == null ?
                                      new ScreenPoatalArea()
        {
            scrrenRect = new Rect(0, 0, 1, 1), minDeep = 0, maxDeep = currentCam.nearClipPlane
        }
            : p.thisPortal.otherPortal.GetPortalRect(currentCam);

        foreach (var pair in PortalPair.portalPairs)
        {
            if (pair.portalA != null && pair.portalA.ShouldCameraRender(currentCam, portalRect))
            {
                p.nextPairs.Add(PortalNode.QueryNode(pair.portalA, lastDepth - 1));
            }

            if (pair.portalB != null && pair.portalB.ShouldCameraRender(currentCam, portalRect))
            {
                p.nextPairs.Add(PortalNode.QueryNode(pair.portalB, lastDepth - 1));
            }
        }

        foreach (var node in p.nextPairs)
        {
            if (p.thisPortal != null)
            {
                currentCam.transform.position = p.position;
                currentCam.transform.rotation = p.rotation;
                currentCam.projectionMatrix   = p.projMat;
                currentCam.targetTexture      = p.rt;
            }
            Transform Source       = node.thisPortal.portalPlaneTransform;
            Transform Destination  = node.thisPortal.otherPortal.portalPlaneTransform;
            Camera    portalCamera = node.thisPortal.portalCamera;

            // Rotate Source 180 degrees so PortalCamera is mirror image of MainCamera
            Matrix4x4 destinationFlipRotation = Matrix4x4.TRS(ZeroV3, Quaternion.AngleAxis(180.0f, Vector3.up), OneV3);
            Matrix4x4 sourceInvMat            = destinationFlipRotation * Source.worldToLocalMatrix;

            // Calculate translation and rotation of MainCamera in Source space
            Vector3    cameraPositionInSourceSpace = ToV3(sourceInvMat * PosToV4(currentCam.transform.position));
            Quaternion cameraRotationInSourceSpace = Quaternion.AngleAxis(180, Vector3.up) * Quaternion.Inverse(Source.rotation) * currentCam.transform.rotation;

            // Transform Portal Camera to World Space relative to Destination transform,
            // matching the Main Camera position/orientation
            portalCamera.transform.position = Destination.TransformPoint(cameraPositionInSourceSpace);
            portalCamera.transform.rotation = Destination.rotation * cameraRotationInSourceSpace;

            node.position = Destination.TransformPoint(cameraPositionInSourceSpace);
            node.rotation = Destination.rotation * cameraRotationInSourceSpace;

            // Calculate clip plane for portal (for culling of objects inbetween destination camera and portal)
            Vector4 clipPlaneWorldSpace = new Vector4(node.thisPortal.otherPortal.portalForward.x, node.thisPortal.otherPortal.portalForward.y,
                                                      node.thisPortal.otherPortal.portalForward.z, Vector3.Dot(Destination.position, -node.thisPortal.otherPortal.portalForward));
            Vector4 clipPlaneCameraSpace = Matrix4x4.Transpose(Matrix4x4.Inverse(portalCamera.worldToCameraMatrix)) * clipPlaneWorldSpace;

            // Update projection based on new clip plane
            // Note: http://aras-p.info/texts/obliqueortho.html and http://www.terathon.com/lengyel/Lengyel-Oblique.pdf
            //portalCamera.projectionMatrix = rootCamera.CalculateObliqueMatrix(clipPlaneCameraSpace);
            node.projMat = rootCamera.CalculateObliqueMatrix(clipPlaneCameraSpace);
            BuildPortalViewTree(node, lastDepth);
        }
    }