예제 #1
0
        static protected int RenderersToVolumes(ref Renderer[] renderers, ref Volume cellVolume, ref List <Volume> volumes, ref Dictionary <Scene, int> sceneRefs)
        {
            int num = 0;

            foreach (Renderer r in renderers)
            {
                var  flags        = GameObjectUtility.GetStaticEditorFlags(r.gameObject) & StaticEditorFlags.ContributeGI;
                bool contributeGI = (flags & StaticEditorFlags.ContributeGI) != 0;

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

                Volume v = ToVolume(r.bounds);

                if (ProbeVolumePositioning.OBBIntersect(ref cellVolume, ref v))
                {
                    volumes.Add(v);

                    TrackSceneRefs(r.gameObject.scene, ref sceneRefs);

                    num++;
                }
            }

            return(num);
        }
        // converts a volume into bricks, subdivides the bricks and culls subdivided volumes falling outside the original volume
        private void ConvertVolume(Volume volume, SubdivisionDel subdivider, List <Brick> outSortedBricks)
        {
            Profiler.BeginSample("ConvertVolume");
            m_TmpBricks[0].Clear();
            Transform(volume, out Volume vol);
            // rasterize bricks according to the coarsest grid
            Rasterize(vol, m_TmpBricks[0]);

            // iterative subdivision
            while (m_TmpBricks[0].Count > 0)
            {
                m_TmpBricks[1].Clear();
                m_TmpFlags.Clear();
                m_TmpFlags.Capacity = Mathf.Max(m_TmpFlags.Capacity, m_TmpBricks[0].Count);

                Profiler.BeginSample("Subdivider");
                subdivider(m_Transform, m_TmpBricks[0], m_TmpFlags);
                Profiler.EndSample();
                Debug.Assert(m_TmpBricks[0].Count == m_TmpFlags.Count);

                for (int i = 0; i < m_TmpFlags.Count; i++)
                {
                    if (!m_TmpFlags[i].discard)
                    {
                        outSortedBricks.Add(m_TmpBricks[0][i]);
                    }
                    if (m_TmpFlags[i].subdivide)
                    {
                        m_TmpBricks[1].Add(m_TmpBricks[0][i]);
                    }
                }

                m_TmpBricks[0].Clear();
                if (m_TmpBricks[1].Count > 0)
                {
                    //Debug.Log("Calling SubdivideBricks with " + m_TmpBricks[1].Count + " bricks.");
                    SubdivideBricks(m_TmpBricks[1], m_TmpBricks[0]);

                    // Cull out of bounds bricks
                    Profiler.BeginSample("Cull bricks");
                    for (int i = m_TmpBricks[0].Count - 1; i >= 0; i--)
                    {
                        if (!ProbeVolumePositioning.OBBIntersect(ref m_Transform, m_TmpBricks[0][i], ref volume))
                        {
                            m_TmpBricks[0].RemoveAt(i);
                        }
                    }
                    Profiler.EndSample();
                }
            }
            Profiler.EndSample();
        }
예제 #3
0
        internal static bool ShouldKeepBrick(List <Volume> volumes, Volume brick)
        {
            foreach (Volume v in volumes)
            {
                Volume vol = v;
                if (ProbeVolumePositioning.OBBIntersect(ref vol, ref brick))
                {
                    return(true);
                }
            }

            return(false);
        }
예제 #4
0
        static protected void CullVolumes(ref List <Volume> cullees, ref List <Volume> cullers, ref List <Volume> result)
        {
            foreach (Volume v in cullers)
            {
                Volume lv = v;

                foreach (Volume c in cullees)
                {
                    if (result.Contains(c))
                    {
                        continue;
                    }

                    Volume lc = c;

                    if (ProbeVolumePositioning.OBBIntersect(ref lv, ref lc))
                    {
                        result.Add(c);
                    }
                }
            }
        }
예제 #5
0
        static protected int ProbeVolumesToVolumes(ref ProbeVolume[] probeVolumes, ref Volume cellVolume, ref List <Volume> volumes, ref Dictionary <Scene, int> sceneRefs)
        {
            int num = 0;

            foreach (ProbeVolume pv in probeVolumes)
            {
                if (!pv.enabled || !pv.gameObject.activeSelf)
                {
                    continue;
                }

                Volume indicatorVolume = new Volume(Matrix4x4.TRS(pv.transform.position, pv.transform.rotation, pv.GetExtents()));

                if (ProbeVolumePositioning.OBBIntersect(ref cellVolume, ref indicatorVolume))
                {
                    volumes.Add(indicatorVolume);
                    TrackSceneRefs(pv.gameObject.scene, ref sceneRefs);
                    num++;
                }
            }

            return(num);
        }
예제 #6
0
        public static void SubdivisionAlgorithm(Volume cellVolume, List <Volume> probeVolumes, List <Volume> influenceVolumes, RefTrans refTrans, List <Brick> inBricks, List <Flags> outFlags)
        {
            Flags f = new Flags();

            for (int i = 0; i < inBricks.Count; i++)
            {
                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);
                    Volume cellVolumeTrans = new 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);
            }
        }