コード例 #1
0
        // TODO: Add subdivision criteria here,
        // currently just keeps subdividing inside probe volumes
        internal static bool ShouldKeepBrick(ref RefTrans refTrans, Brick brick)
        {
            Renderer[] renderers = Object.FindObjectsOfType <Renderer>();
            foreach (Renderer r in renderers)
            {
                var  flags        = GameObjectUtility.GetStaticEditorFlags(r.gameObject) & StaticEditorFlags.ContributeGI;
                bool contributeGI = (flags & StaticEditorFlags.ContributeGI) != 0;

                if (!r.enabled || !contributeGI)
                {
                    continue;
                }

                ProbeReferenceVolume.Volume v = new ProbeReferenceVolume.Volume();
                v.corner = r.bounds.center - r.bounds.size * 0.5f;
                v.X      = new Vector3(r.bounds.size.x, 0, 0);
                v.Y      = new Vector3(0, r.bounds.size.y, 0);
                v.Z      = new Vector3(0, 0, r.bounds.size.z);

                if (OBBIntersect(ref refTrans, brick, ref v))
                {
                    return(true);
                }
            }

            return(false);
        }
コード例 #2
0
        // TODO: Take refvol translation and rotation into account
        public static ProbeReferenceVolume.Volume CalculateBrickVolume(ref RefTrans refTrans, Brick brick)
        {
            float   scaledSize = Mathf.Pow(3, brick.size);
            Vector3 scaledPos  = refTrans.refSpaceToWS.MultiplyPoint(brick.position);

            ProbeReferenceVolume.Volume bounds;
            bounds.corner = scaledPos;
            bounds.X      = refTrans.refSpaceToWS.GetColumn(0) * scaledSize;
            bounds.Y      = refTrans.refSpaceToWS.GetColumn(1) * scaledSize;
            bounds.Z      = refTrans.refSpaceToWS.GetColumn(2) * scaledSize;

            return(bounds);
        }
コード例 #3
0
        // TODO: Take refvol translation and rotation into account
        public static ProbeReferenceVolume.Volume CalculateBrickVolume(ref RefTrans refTrans, Brick brick)
        {
            float   scaledSize = Mathf.Pow(3, brick.subdivisionLevel);
            Vector3 scaledPos  = refTrans.refSpaceToWS.MultiplyPoint(brick.position);

            var bounds = new ProbeReferenceVolume.Volume(
                scaledPos,
                refTrans.refSpaceToWS.GetColumn(0) * scaledSize,
                refTrans.refSpaceToWS.GetColumn(1) * scaledSize,
                refTrans.refSpaceToWS.GetColumn(2) * scaledSize
                );

            return(bounds);
        }
コード例 #4
0
        public static void SubdivisionAlgorithm(RefTrans refTrans, List <Brick> inBricks, List <Flags> outFlags)
        {
            Flags f = new Flags();

            for (int i = 0; i < inBricks.Count; i++)
            {
                if (ShouldKeepBrick(ref refTrans, inBricks[i]))
                {
                    f.discard   = false;
                    f.subdivide = true;
                }
                else
                {
                    f.discard   = true;
                    f.subdivide = false;
                }
                outFlags.Add(f);
            }
        }
コード例 #5
0
        public static bool OBBIntersect(ref RefTrans refTrans, Brick brick, ref ProbeReferenceVolume.Volume volume)
        {
            var transformed = CalculateBrickVolume(ref refTrans, brick);

            return(OBBIntersect(ref transformed, ref volume));
        }
コード例 #6
0
        public static void SubdivisionAlgorithm(ProbeReferenceVolume.Volume cellVolume, List <ProbeReferenceVolume.Volume> probeVolumes, List <ProbeReferenceVolume.Volume> influenceVolumes, RefTrans refTrans, List <Brick> inBricks, int subdivisionLevel, List <Flags> outFlags)
        {
            Flags f = new Flags();

            for (int i = 0; i < inBricks.Count; i++)
            {
                ProbeReferenceVolume.Volume brickVolume = ProbeVolumePositioning.CalculateBrickVolume(ref refTrans, inBricks[i]);

                // Find the local max from all overlapping probe volumes:
                float localMaxSubdiv = 0;
                float localMinSubdiv = 0;
                bool  overlap        = false;
                foreach (ProbeReferenceVolume.Volume v in probeVolumes)
                {
                    ProbeReferenceVolume.Volume vol = v;
                    if (ProbeVolumePositioning.OBBIntersect(ref vol, ref brickVolume))
                    {
                        overlap        = true;
                        localMaxSubdiv = Mathf.Max(localMaxSubdiv, vol.maxSubdivisionMultiplier);
                        // Do we use max for min subdiv too?
                        localMinSubdiv = Mathf.Max(localMinSubdiv, vol.minSubdivisionMultiplier);
                    }
                }

                bool belowMaxSubdiv = subdivisionLevel <= ProbeReferenceVolume.instance.GetMaxSubdivision(localMaxSubdiv);
                bool belowMinSubdiv = subdivisionLevel <= ProbeReferenceVolume.instance.GetMaxSubdivision(localMinSubdiv);

                // Keep bricks that overlap at least one probe volume, and at least one influencer (mesh)
                if ((belowMinSubdiv && overlap) || (belowMaxSubdiv && ShouldKeepBrick(probeVolumes, brickVolume) && ShouldKeepBrick(influenceVolumes, brickVolume)))
                {
                    f.subdivide = true;

                    // Transform into refvol space
                    brickVolume.Transform(refTrans.refSpaceToWS.inverse);
                    ProbeReferenceVolume.Volume cellVolumeTrans = new ProbeReferenceVolume.Volume(cellVolume);
                    cellVolumeTrans.Transform(refTrans.refSpaceToWS.inverse);
                    cellVolumeTrans.maxSubdivisionMultiplier = localMaxSubdiv;

                    // Discard parent brick if it extends outside of the cell, to prevent duplicates
                    var brickVolumeMax = brickVolume.corner + brickVolume.X + brickVolume.Y + brickVolume.Z;
                    var cellVolumeMax  = cellVolumeTrans.corner + cellVolumeTrans.X + cellVolumeTrans.Y + cellVolumeTrans.Z;

                    f.discard = brickVolumeMax.x > cellVolumeMax.x ||
                                brickVolumeMax.y > cellVolumeMax.y ||
                                brickVolumeMax.z > cellVolumeMax.z ||
                                brickVolume.corner.x < cellVolumeTrans.corner.x ||
                                brickVolume.corner.y < cellVolumeTrans.corner.y ||
                                brickVolume.corner.z < cellVolumeTrans.corner.z;
                }
                else
                {
                    f.discard   = true;
                    f.subdivide = false;
                }
                outFlags.Add(f);
            }
        }
コード例 #7
0
        public static void SubdivisionAlgorithm(ProbeReferenceVolume.Volume cellVolume, List <ProbeReferenceVolume.Volume> probeVolumes, List <ProbeReferenceVolume.Volume> influenceVolumes, RefTrans refTrans, List <Brick> inBricks, List <Flags> outFlags)
        {
            Flags f = new Flags();

            for (int i = 0; i < inBricks.Count; i++)
            {
                ProbeReferenceVolume.Volume brickVolume = ProbeVolumePositioning.CalculateBrickVolume(ref refTrans, inBricks[i]);

                // Keep bricks that overlap at least one probe volume, and at least one influencer (mesh)
                if (ShouldKeepBrick(probeVolumes, brickVolume) && ShouldKeepBrick(influenceVolumes, brickVolume))
                {
                    f.subdivide = true;

                    // Transform into refvol space
                    brickVolume.Transform(refTrans.refSpaceToWS.inverse);
                    ProbeReferenceVolume.Volume cellVolumeTrans = new ProbeReferenceVolume.Volume(cellVolume);
                    cellVolumeTrans.Transform(refTrans.refSpaceToWS.inverse);

                    // Discard parent brick if it extends outside of the cell, to prevent duplicates
                    var brickVolumeMax = brickVolume.corner + brickVolume.X + brickVolume.Y + brickVolume.Z;
                    var cellVolumeMax  = cellVolumeTrans.corner + cellVolumeTrans.X + cellVolumeTrans.Y + cellVolumeTrans.Z;

                    f.discard = brickVolumeMax.x > cellVolumeMax.x ||
                                brickVolumeMax.y > cellVolumeMax.y ||
                                brickVolumeMax.z > cellVolumeMax.z ||
                                brickVolume.corner.x < cellVolumeTrans.corner.x ||
                                brickVolume.corner.y < cellVolumeTrans.corner.y ||
                                brickVolume.corner.z < cellVolumeTrans.corner.z;
                }
                else
                {
                    f.discard   = true;
                    f.subdivide = false;
                }
                outFlags.Add(f);
            }
        }