// -------------------------------------------------- // 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); }
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); }
// ----------------------------------------------------------------------------------------------------// // 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); }
public static void DrawHierarchicalVolumeGrid(VolumeData data, VolumeData activeVolume = null) { if (data == null) { return; } DrawHierarchicalVolumeGridRecursive(data, activeVolume); }
// -------------------------------------------------- // 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); }
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); }
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(); } } }
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); } }
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()); }
private void ClearVolumeData() { m_VolumeData = null; }
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); } }