예제 #1
0
        // --------------------------------------------------
        // Manual Volume Grid

        public static IEnumerator BuildManualVolumeGrid(BoxCollider[] manualVolumes, Action <VolumeData> result)
        {
            VolumeData data = null;

            if (manualVolumes.Length == 0)
            {
                result(data);
            }

            Bounds bounds = new Bounds();

            for (int i = 0; i < manualVolumes.Length; i++)
            {
                bounds.Encapsulate(manualVolumes[i].bounds);
            }

            List <VolumeData> volumes = new List <VolumeData>();

            for (int i = 0; i < manualVolumes.Length; i++)
            {
                volumes.Add(new VolumeData(manualVolumes[i].bounds, null, null));
            }

            data = new VolumeData(bounds, volumes.ToArray(), null);
            yield return(null);

            result(data);
        }
예제 #2
0
        private static IEnumerator BuildHierarchicalVolumeGridRecursive(int count, int density, VolumeData data, Action <VolumeData> result, object obj)
        {
            count++;
            VolumeData[] childData = new VolumeData[8];
            for (int i = 0; i < childData.Length; i++)
            {
                Vector3 size     = new Vector3(data.bounds.size.x * 0.5f, data.bounds.size.y * 0.5f, data.bounds.size.z * 0.5f);
                float   signX    = (float)(i + 1) % 2 == 0 ? 1 : -1;
                float   signY    = i == 2 || i == 3 || i == 6 || i == 7 ? 1 : -1;            // TODO - Maths
                float   signZ    = i == 4 || i == 5 || i == 6 || i == 7 ? 1 : -1;            //(float)(i + 1) * 0.5f > 4 ? 1 : -1; // TODO - Maths
                Vector3 position = data.bounds.center + new Vector3(signX * size.x * 0.5f, signY * size.y * 0.5f, signZ * size.z * 0.5f);
                Bounds  bounds   = new Bounds(position, size);
                childData[i] = new VolumeData(bounds, null, null);

                if (count < density)
                {
                    VolumeData childResult = new VolumeData();
                    yield return(EditorCoroutines.StartCoroutine(BuildHierarchicalVolumeGridRecursive(count, density, childData[i], value => childResult = value, obj), obj));

                    childData[i] = childResult;
                }
            }
            data.children = childData;
            result(data);
        }
예제 #3
0
        // ----------------------------------------------------------------------------------------------------//
        //                                              RUNTIME                                                 //
        // ----------------------------------------------------------------------------------------------------//

        public static bool GetActiveVolumeAtPosition(VolumeData volumeData, Vector3 position, out VolumeData activeVolume)
        {
            if (volumeData.bounds.Contains(position))
            {
                // Continue to traverse down the volume hierarchy
                if (volumeData.children != null && volumeData.children.Length > 0)
                {
                    for (int i = 0; i < volumeData.children.Length; i++)
                    {
                        if (GetActiveVolumeAtPosition(volumeData.children[i], position, out activeVolume))
                        {
                            return(true);
                        }
                    }
                }
                // Active volume at final subdivision of volume hierarchy
                else
                {
                    activeVolume = volumeData;
                    return(true);
                }
            }

            activeVolume = null;
            return(false);
        }
예제 #4
0
        public static void DrawHierarchicalVolumeGrid(VolumeData data, VolumeData activeVolume = null)
        {
            if (data == null)
            {
                return;
            }

            DrawHierarchicalVolumeGridRecursive(data, activeVolume);
        }
예제 #5
0
        // --------------------------------------------------
        // Hirarchical Volume Grid

        public static IEnumerator BuildHierarchicalVolumeGrid(Bounds bounds, int density, Action <VolumeData> result, object obj)
        {
            VolumeData data  = new VolumeData(bounds, null, null);
            int        count = 0;

            if (count < density)
            {
                yield return(EditorCoroutines.StartCoroutine(BuildHierarchicalVolumeGridRecursive(count, density, data, value => data = value, obj), obj));
            }
            result(data);
        }
예제 #6
0
        private IEnumerator GenerateOcclusion()
        {
            m_StaticRenderers = Utils.GetStaticRenderers();

            // Generate Occluder Data
            m_BakeState = BakeState.Occluders;
            ClearOccluderData();
            yield return(EditorCoroutines.StartCoroutine(Utils.BuildOccluderProxyGeometry(transform, m_StaticRenderers, value => m_Occluders = value, this, m_OccluderTag), this));

            // Generate Volume Data
            m_BakeState = BakeState.Volumes;
            ClearVolumeData();
            switch (m_VolumeMode)
            {
            case VolumeMode.Automatic:
                // Generate Hierarchical Volume Grid
                Bounds bounds = Utils.GetSceneBounds(m_StaticRenderers);
                yield return(EditorCoroutines.StartCoroutine(Utils.BuildHierarchicalVolumeGrid(bounds, m_VolumeDensity, value => m_VolumeData = value, this), this));

                break;

            case VolumeMode.Manual:
                // Generate Manual Volumes
                yield return(EditorCoroutines.StartCoroutine(Utils.BuildManualVolumeGrid(m_ManualVolumes, value => m_VolumeData = value), this));

                break;
            }

            if (m_VolumeData != null)
            {
                // Generate Occlusion Data
                m_BakeState = BakeState.Occlusion;
                int          volumeDensity   = m_VolumeMode == VolumeMode.Automatic ? m_VolumeDensity : 1;
                VolumeData[] smallestVolumes = Utils.GetLowestSubdivisionVolumes(m_VolumeData, volumeDensity);
                for (int i = 0; i < smallestVolumes.Length; i++)
                {
                    m_Completion   = (float)(i + 1) / (float)smallestVolumes.Length;
                    m_ActiveVolume = smallestVolumes[i];
                    yield return(EditorCoroutines.StartCoroutine(Utils.BuildOcclusionForVolume(smallestVolumes[i].bounds, m_RayDensity, m_StaticRenderers, m_Occluders, value => smallestVolumes[i].renderers = value, this, m_FilterAngle), this));
                }
                m_BakeState = BakeState.Active;
            }
            else
            {
                Debug.LogError("Occlusion Bake Failed. Check Settings.");
                m_BakeState  = BakeState.Empty;
                m_Completion = 0;
            }
            m_ActiveVolume = null;
            yield return(null);
        }
예제 #7
0
        private void Update()
        {
            if (m_VolumeData == null)
            {
                return;
            }

            if (Utils.GetActiveVolumeAtPosition(m_VolumeData, Camera.main.transform.position, out m_ActiveVolume))
            {
                if (m_ActiveVolume != m_PreviousVolume)                // TODO - Disable for runtime optimisation
                {
                    m_PreviousVolume = m_ActiveVolume;
                    UpdateOcclusion();
                }
            }
        }
예제 #8
0
 private static void DrawHierarchicalVolumeGridRecursive(VolumeData data, VolumeData activeVolume)
 {
     if (data.children != null && data.children.Length > 0)
     {
         for (int i = 0; i < data.children.Length; i++)
         {
             DrawHierarchicalVolumeGridRecursive(data.children[i], activeVolume);
         }
     }
     else
     {
         bool isActive = data == activeVolume;
         Gizmos.color = isActive ? DebugColors.volumeActive[0] : DebugColors.volume[0];
         Gizmos.DrawWireCube(data.bounds.center, data.bounds.size);
         Gizmos.color = isActive ? DebugColors.volumeActive[1] : DebugColors.volume[1];
         Gizmos.DrawCube(data.bounds.center, data.bounds.size);
     }
 }
예제 #9
0
        public static VolumeData[] GetLowestSubdivisionVolumes(VolumeData data, int density)
        {
            int finalSubdivisionVolumeCount  = (int)Mathf.Pow(density, 8);
            List <VolumeData> dataCollection = new List <VolumeData>();

            int count = 0;

            if (count < density)
            {
                for (int i = 0; i < data.children.Length; i++)
                {
                    GetLowestSubdivisionVolumesRecursive(count, density, data.children[i], ref dataCollection);
                }
            }
            else
            {
                dataCollection.Add(data);
            }
            return(dataCollection.ToArray());
        }
예제 #10
0
 private void ClearVolumeData()
 {
     m_VolumeData = null;
 }
예제 #11
0
 private static void GetLowestSubdivisionVolumesRecursive(int count, int density, VolumeData volume, ref List <VolumeData> dataCollection)
 {
     count++;
     if (count < density)
     {
         for (int i = 0; i < volume.children.Length; i++)
         {
             GetLowestSubdivisionVolumesRecursive(count, density, volume.children[i], ref dataCollection);
         }
     }
     else
     {
         dataCollection.Add(volume);
     }
 }