private void OnDrawGizmos() { if (Application.isPlaying == false) { return; } //draw select occluder GameObject go = UnityEditor.Selection.activeGameObject; if (go != null) { Occluder occluder = go.GetComponent <Occluder>(); if (occluder != null) { Vector3 viewPos = this.transform.position; Vector3[] contour = occluder.GetContour(viewPos); Gizmos.color = Color.white; foreach (Vector3 v in contour) { Gizmos.DrawRay(viewPos, (v - viewPos) * 100); } } } }
public override bool Remove(Occluder conn) { bool value = true; for (int i = 0; i < Sequence_Remove_Occluder.Early.Count; i++) { try { value = AndOr(value, Sequence_Remove_Occluder.Early[i].Invoke(conn), Sequence_Remove_Occluder.MetaDict[Sequence_Remove_Occluder.Early[i]]); } catch (Exception ex) { Debug.LogError(ex); } } for (int i = 0; i < Sequence_Remove_Occluder.Late.Count; i++) { try { value = AndOr(value, Sequence_Remove_Occluder.Late[i].Invoke(conn), Sequence_Remove_Occluder.MetaDict[Sequence_Remove_Occluder.Late[i]]); } catch (Exception ex) { Debug.LogError(ex); } } //if (value == true) value &= base.Remove(conn); for (int i = 0; i < Sequence_Remove_Occluder.Post.Count; i++) { try { value = AndOr(value, Sequence_Remove_Occluder.Post[i].Invoke(conn), Sequence_Remove_Occluder.MetaDict[Sequence_Remove_Occluder.Post[i]]); } catch (Exception ex) { Debug.LogError(ex); } } return(value); }
protected override bool TestOcclusion(Vector3d aPos, Occluder a, Vector3d bPos, Occluder b, double distance) { bool value = true; for (int i = 0; i < Sequence_TestOcclusion.Early.Count; i++) { try { value = AndOr(value, Sequence_TestOcclusion.Early[i].Invoke(aPos, a, bPos, b, distance), Sequence_TestOcclusion.MetaDict[Sequence_TestOcclusion.Early[i]]); } catch (Exception ex) { Debug.LogError(ex); } } for (int i = 0; i < Sequence_TestOcclusion.Late.Count; i++) { try { value = AndOr(value, Sequence_TestOcclusion.Late[i].Invoke(aPos, a, bPos, b, distance), Sequence_TestOcclusion.MetaDict[Sequence_TestOcclusion.Late[i]]); } catch (Exception ex) { Debug.LogError(ex); } } //if (value == true) value &= base.TestOcclusion(aPos, a, bPos, b, distance); for (int i = 0; i < Sequence_TestOcclusion.Post.Count; i++) { try { value = AndOr(value, Sequence_TestOcclusion.Post[i].Invoke(aPos, a, bPos, b, distance), Sequence_TestOcclusion.MetaDict[Sequence_TestOcclusion.Post[i]]); } catch (Exception ex) { Debug.LogError(ex); } } return(value); }
/// <summary> /// Updates the occluder data. /// </summary> /// <param name="occluder">The occluder.</param> /// <param name="pose">The pose of the <see cref="OccluderNode"/>.</param> /// <param name="scale">The scale of the <see cref="OccluderNode"/>.</param> public void Update(Occluder occluder, Pose pose, Vector3F scale) { Debug.Assert( Vertices.Length == occluder.Vertices.Length && Indices == occluder.Indices, "OccluderData does not match."); Vector3F[] localVertices = occluder.Vertices; if (scale == Vector3F.One) { for (int i = 0; i < Vertices.Length; i++) { Vertices[i] = pose.ToWorldPosition(localVertices[i]); } } else { for (int i = 0; i < Vertices.Length; i++) { Vertices[i] = pose.ToWorldPosition(scale * localVertices[i]); } } // Update of large occluders could be accelerated by using a parallel for-loop. // However, most occluders are small, occluders are already updated in parallel, // and static occluders only need to be updated once. }
public override Occluder Add(Occluder conn) { Occluder value; for (int i = 0; i < Sequence_Add_Occluder.Early.Count; i++) { try { Sequence_Add_Occluder.Early[i].Invoke(conn); } catch (Exception ex) { Debug.LogError(ex); } } for (int i = 0; i < Sequence_Add_Occluder.Late.Count; i++) { try { Sequence_Add_Occluder.Late[i].Invoke(conn); } catch (Exception ex) { Debug.LogError(ex); } } value = base.Add(conn); for (int i = 0; i < Sequence_Add_Occluder.Post.Count; i++) { try { Sequence_Add_Occluder.Post[i].Invoke(conn); } catch (Exception ex) { Debug.LogError(ex); } } return(value); }
public OccluderNode(Occluder occluder) { if (occluder == null) throw new ArgumentNullException("occluder"); Occluder = occluder; }
public void OnGaze(object sender, RoutedEventArgs e) { if (Occluder.GetHasGaze()) { IsChecked = true; NetytarDrawer.getDrawer().netytarButton_OnGaze(this, true); } }
public OccluderNode(Occluder occluder) { if (occluder == null) { throw new ArgumentNullException("occluder"); } Occluder = occluder; }
private static OutlineItem CreateOutlineItem(Occluder occluder) { var item = new OutlineItem { Text = "Occluder", }; return(item); }
public void AddOccluder(Occluder occluder) { if (occluder.ScreenArea < this.minOccluderSceenThreshold) { return; } this.occluders.Add(occluder); }
/// <summary> /// Initializes a new instance of the <see cref="OccluderData"/> class. /// </summary> /// <param name="occluder">The occluder.</param> public OccluderData(Occluder occluder) { // The occluder is given in local space. The vertices need to be transformed // to world space before submitting the vertices to the render batch. Vertices = new Vector3F[occluder.Vertices.Length]; // The indices are copied as is. (Indices are updated on-the-fly when the // values are copied to the render batch.) Indices = occluder.Indices; }
private void Awake() { Instance = this; if (dontDestroyOnLoad) { this.GetOrAddComponent <DontDestroyOnLoad>(); } image = GetComponentInChildren <Image>(); startColor = image.color; }
//List<int> normalFlags = new List<int>(); //normalFlags.Clear(); //foreach (Plane plane in cullPlanes) //{ // normalFlags.Add(plane.normal.x < 0 ? 0 : 1); // normalFlags.Add(plane.normal.y < 0 ? 0 : 1); // normalFlags.Add(plane.normal.z < 0 ? 0 : 1); //} //Vector3[] v = new Vector3[2]; //private bool CullAABB(List<Plane> planes, List<int> normalFlags, Bounds bounds) //{ // v[0] = bounds.min; // v[1] = bounds.max; // int i = 0; // foreach (Plane plane in planes) // { // Vector3 normal = plane.normal; // Vector3 p = new Vector3(this.v[normalFlags[i]].x, this.v[normalFlags[i + 1]].y, this.v[normalFlags[i + 2]].z); // float distance = plane.GetDistanceToPoint(p); // if (distance > 0) // return false; // i += 3; // } // return true; //} //todo //<<Real-time collection detection>> TestOBBPlane //private bool CullOccluder(List<Plane> planes, Occluder occluder) //{ // Vector3 center = occluder.transform.TransformPoint(occluder.center); // //Vector3 extents = occluder.transform.TransformDirection(occluder.extents); // Vector3 extents = occluder.extents; // foreach (Plane plane in planes) // { // float distance = plane.GetDistanceToPoint(center); // if (distance >= 0) // return false; // Vector3 normal = occluder.transform.TransformDirection(plane.normal); // normal.x = Mathf.Abs(normal.x); // normal.y = Mathf.Abs(normal.y); // normal.z = Mathf.Abs(normal.z); // float radius = Vector3.Dot(extents, normal); // //Vector3 normal = plane.normal; // //normal.x = Mathf.Abs(normal.x); // //normal.y = Mathf.Abs(normal.y); // //normal.z = Mathf.Abs(normal.z); // //float radius = Vector3.Dot(extents, normal); // if ((distance + radius) > 0) // return false; // } // return true; //} private bool CullOccluder(List <Plane> planes, Occluder occluder) { Vector3[] corners = occluder.GetCorners(); foreach (Plane plane in planes) { foreach (Vector3 corner in corners) { if (plane.GetDistanceToPoint(corner) > 0) { return(false); } } } return(true); }
void UpdateAttachedObjects() { bool visible = !opened && openDoorOffsetCoefficient == 0; foreach (MapObjectAttachedObject attachedObject in AttachedObjects) { if (attachedObject.Alias == "visibleWhenClosed") { attachedObject.Visible = visible; MapObjectAttachedMapObject attachedMapObject = attachedObject as MapObjectAttachedMapObject; if (attachedMapObject != null) { Occluder occluder = attachedMapObject.MapObject as Occluder; if (occluder != null) { occluder.Enabled = visible; } } } } }
/// <summary> /// Updates the occluder data. /// </summary> /// <param name="occluder">The occluder.</param> /// <param name="pose">The pose of the <see cref="OccluderNode"/>.</param> /// <param name="scale">The scale of the <see cref="OccluderNode"/>.</param> public void Update(Occluder occluder, Pose pose, Vector3F scale) { Debug.Assert( Vertices.Length == occluder.Vertices.Length && Indices == occluder.Indices, "OccluderData does not match."); Vector3F[] localVertices = occluder.Vertices; if (scale == Vector3F.One) { for (int i = 0; i < Vertices.Length; i++) Vertices[i] = pose.ToWorldPosition(localVertices[i]); } else { for (int i = 0; i < Vertices.Length; i++) Vertices[i] = pose.ToWorldPosition(scale * localVertices[i]); } // Update of large occluders could be accelerated by using a parallel for-loop. // However, most occluders are small, occluders are already updated in parallel, // and static occluders only need to be updated once. }
Occluder IPublicCommNet.Add(Occluder conn) { return(this.Add(conn)); }
public virtual VoxelizationOutput Generate(VoxelizationInput input, Action<VoxelizationProgress> progress) { VoxelizationProgress vp = new VoxelizationProgress(); DateTime start = DateTime.Now; vp.Status = "Building voxel field from octree"; progress(vp); VoxelField voxelField = new VoxelField(input.Octree); Byte fillByte = 2; float oldPercent = 1.0f; float newPercent = 1.0f; List<Occluder> occluders = new List<Occluder>(); vp.Status = "Calculating original mesh silhouette coverage"; progress(vp); SilhouetteOcclusionValidator sov = new SilhouetteOcclusionValidator(1024, 1024); long groundSideCoverage, groundTopCoverage; sov.ComputeCoverage(input.OriginalMesh, input.Octree.MeshBounds, out groundSideCoverage, out groundTopCoverage); long totalCoverage = groundSideCoverage + groundTopCoverage; if (totalCoverage == 0) totalCoverage = 1; vp.Status = "Fitting boxes into mesh..."; progress(vp); long oldOcclusion = 0; do { Vector3i densestVoxel = FindHighestDensityVoxel(voxelField); AABBi occluderBounds; if (input.Type == OcclusionType.BoxExpansion) { occluderBounds = ExpandAndFillBox(voxelField, ref densestVoxel, fillByte); } //else if (input.Type == OcclusionType.SimulatedAnnealing) //{ // occluderBounds = SimulatedAnnealingFill(input, sov, voxelField, ref densestVoxel, fillByte, occluders); //} else if (input.Type == OcclusionType.BruteForce) { occluderBounds = BruteForceFill(input, sov, voxelField, densestVoxel, fillByte, occluders); } else { throw new Exception("Unknown occluder generation type!"); } List<AABBi> relevantOccluders = GetRelevantOccluders(input, occluders); relevantOccluders.Add(occluderBounds); long newOcclusion = MeasureOccluderOcclusion(sov, input, relevantOccluders); Occluder occluder = new Occluder(); occluder.Bounds = occluderBounds; occluder.DeltaOcclusion = (newOcclusion - oldOcclusion) / (double)totalCoverage; occluders.Add(occluder); if (occluder.DeltaOcclusion > input.MinimumOcclusion) oldOcclusion = newOcclusion; Debug.WriteLine("Coverage " + occluder.DeltaOcclusion); Debug.WriteLine("Bounds (" + occluder.Bounds.MinX + "x" + occluder.Bounds.MaxX + " " + occluder.Bounds.MinY + "x" + occluder.Bounds.MaxY + " " + occluder.Bounds.MinZ + "x" + occluder.Bounds.MaxZ + ")"); oldPercent = newPercent; newPercent = MeasureUnboxedVoxels(voxelField); Debug.WriteLine("(" + densestVoxel.X + "," + densestVoxel.Y + "," + densestVoxel.Z + ")\tCoverage=" + ((1 - newPercent) * 100) + "%\tDelta=" + ((oldPercent - newPercent) * 100) + "%"); vp.Progress = Math.Min(((1 - newPercent) / input.MinimumVolume), 1.0f); vp.SilhouetteCoverage = oldOcclusion / (double)totalCoverage; vp.VolumeCoverage = 1 - newPercent; vp.Status = String.Format("Occlusion Progress : {0:0.##}%", (100 * vp.Progress)); progress(vp); } while (newPercent > (1 - input.MinimumVolume)); Mesh mesh = BuildMeshFromBoxes(input, GetRelevantOccluders(input, occluders)); VoxelizationOutput output = new VoxelizationOutput(); if (input.Retriangulate) { vp.Status = "Retriangulating occluder mesh"; progress(vp); Mesh triangulatedMesh = MeshOptimizer.Retriangulate(input, mesh, out output.DebugLines); if (triangulatedMesh != null) mesh = triangulatedMesh; } vp.Status = "Filtering polygons"; progress(vp); mesh = PolygonFilter.Filter(input, mesh); vp.Status = "Generating final occlusion mesh"; progress(vp); // Prepare the output output.Octree = input.Octree; output.TimeTaken = DateTime.Now - start; output.VolumeCoverage = 1 - newPercent; output.SilhouetteCoverage = oldOcclusion / (double)totalCoverage; output.OccluderMesh = new RenderableMesh(mesh, true); vp.Status = "Cleanup..."; progress(vp); sov.Dispose(); return output; }
private void OnPreRender() { if (this.occluders.Count == 0) { return; } if (this.rendererNum <= this.minRendererNum) { return; } float fTime = Time.realtimeSinceStartup; for (int i = 0; i < this.occludees.Count; i++) { this.occludeeVisable.Add(true); } for (int i = 0; i < this.occluders.Count; i++) { this.occluderVisable.Add(true); } Vector3 viewPos = this.transform.position; this.occluders.Sort((x, y) => - x.ScreenArea.CompareTo(y.ScreenArea)); int occluderNum = Mathf.Min(this.occluders.Count, this.maxOccluderNum); fTime = Time.realtimeSinceStartup; for (int i = 0; i < occluderNum; i++) { Occluder occluder = this.occluders[i]; if (this.occluderVisable[i] == false) { continue; } List <Plane> cullPlanes = occluder.CalculateCullPlanes(viewPos); for (int occludeeIdx = 0; occludeeIdx < this.occludees.Count; occludeeIdx++) { if (this.occludeeVisable[occludeeIdx] == false) { continue; } Bounds bounds = this.occludees[occludeeIdx].GetBounds(); if (this.CullAABB(cullPlanes, bounds)) { this.occludeeVisable[occludeeIdx] = false; } } for (int j = i + 1; j < occluderNum; j++) { if (this.occluderVisable[j] == false) { continue; } if (this.CullOccluder(cullPlanes, this.occluders[j])) { this.occluderVisable[j] = false; } } } //Debug.Log("Cull cost: " + (Time.realtimeSinceStartup - fTime) * 1000); setVisableTime = 0.0f; fTime = Time.realtimeSinceStartup; for (int i = 0; i < this.occludees.Count; i++) { this.occludees[i].SetVisable(this.occludeeVisable[i]); } setVisableTime += Time.realtimeSinceStartup - fTime; }
void OnGUI() { var settingsSystem = World.DefaultGameObjectInjectionWorld.GetOrCreateSystem <OcclusionSettingsSystem>(); GUILayout.Space(5); GUILayout.Label("Options", EditorStyles.boldLabel); settingsSystem.OcclusionEnabled = GUILayout.Toggle(settingsSystem.OcclusionEnabled, "Enable Occlusion"); settingsSystem.OcclusionParallelEnabled = GUILayout.Toggle(settingsSystem.OcclusionParallelEnabled, "Enable Parallel Work"); #if UNITY_MOC_NATIVE_AVAILABLE GUILayout.Label("Occlusion Mode:"); if (GUILayout.Toggle(OcclusionSettingsSystem.MOCOcclusionMode.Intrinsic == settingsSystem.MocOcclusionMode, "MOC Burst Intrinsics")) { settingsSystem.MocOcclusionMode = OcclusionSettingsSystem.MOCOcclusionMode.Intrinsic; } if (GUILayout.Toggle(OcclusionSettingsSystem.MOCOcclusionMode.Native == settingsSystem.MocOcclusionMode, "MOC Native")) { settingsSystem.MocOcclusionMode = OcclusionSettingsSystem.MOCOcclusionMode.Native; } #endif GUILayout.Space(20); GUILayout.Label("Tools", EditorStyles.boldLabel); GUILayout.Space(5); VisibilityFilter currentVis = _visibilityFilter; if (GUILayout.Toggle(_visibilityFilter == VisibilityFilter.Occluders, "Show Only Ocludders")) { var list = FindObjectsOfType <Occluder>().Select(x => x.gameObject).ToArray(); ScriptableSingleton <SceneVisibilityManager> .instance.Isolate(list, true); _visibilityFilter = VisibilityFilter.Occluders; } else { if (_visibilityFilter == VisibilityFilter.Occluders) { ScriptableSingleton <SceneVisibilityManager> .instance.ExitIsolation(); _visibilityFilter = VisibilityFilter.None; } } if (GUILayout.Toggle(_visibilityFilter == VisibilityFilter.Occludees, "Show Only Occludees")) { var list = FindObjectsOfType <Occludee>().Select(x => x.gameObject).ToArray(); ScriptableSingleton <SceneVisibilityManager> .instance.Isolate(list, true); _visibilityFilter = VisibilityFilter.Occludees; } else { if (_visibilityFilter == VisibilityFilter.Occludees) { ScriptableSingleton <SceneVisibilityManager> .instance.ExitIsolation(); _visibilityFilter = VisibilityFilter.None; } } if (GUILayout.Button("Select Ocludders")) { Selection.objects = FindObjectsOfType <Occluder>().Select(x => x.gameObject).ToArray(); } if (GUILayout.Button("Select Ocluddees")) { Selection.objects = FindObjectsOfType <Occludee>().Select(x => x.gameObject).ToArray(); } if (GUILayout.Button("Add Occluder Volumes to Selected")) { foreach (var selected in Selection.gameObjects) { Bounds bounds = new Bounds(); foreach (Transform transform in selected.transform) { if (transform.gameObject.GetComponent <MeshFilter>() != null) { Mesh mesh = transform.gameObject.GetComponent <MeshFilter>().mesh; bounds.Encapsulate(mesh.bounds.min); bounds.Encapsulate(mesh.bounds.max); } } Occluder occluder = selected.AddComponent <Occluder>(); occluder.Type = Occluder.OccluderType.Volume; OccluderVolume vol = new OccluderVolume(); vol.CreateCube(); occluder.Mesh = vol.CalculateMesh(); occluder.relativePosition = bounds.center; Vector3 boundsScale; boundsScale.x = (bounds.max.x - bounds.min.x); boundsScale.y = (bounds.max.y - bounds.min.y); boundsScale.z = (bounds.max.z - bounds.min.z); occluder.relativeScale = boundsScale; UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(selected.gameObject.scene); } } if (GUILayout.Button("Add Occludees to Selected")) { foreach (var go in Selection.gameObjects) { if (go.GetComponent <MeshRenderer>()) { if (!go.TryGetComponent <Occludee>(out var occludee)) { go.AddComponent <Occludee>(); UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(go.scene); } } } } if (GUILayout.Button("Add Occludees to All Mesh Renderers")) { foreach (var meshRender in FindObjectsOfType <MeshRenderer>()) { var go = meshRender.gameObject; if (go.GetComponent <MeshRenderer>()) { if (!go.TryGetComponent <Occludee>(out var occludee)) { go.AddComponent <Occludee>(); } } } } if (GUILayout.Button("Remove Occluders from Selected")) { foreach (var go in Selection.gameObjects) { foreach (var o in go.GetComponents <Occluder>()) { DestroyImmediate(o); } } } if (GUILayout.Button("Remove Occludees from Selected")) { foreach (var go in Selection.gameObjects) { foreach (var o in go.GetComponents <Occludee>()) { DestroyImmediate(o); } } } GUILayout.Space(20); GUILayout.Label("Debug Modes", EditorStyles.boldLabel); GUILayout.Space(5); var debugSystem = World.DefaultGameObjectInjectionWorld.GetOrCreateSystem <OcclusionDebugRenderSystem>(); if (GUILayout.Toggle(OcclusionDebugRenderSystem.DebugRenderMode.None == debugSystem.m_DebugRenderMode, "Turn off Debug")) { debugSystem.m_DebugRenderMode = OcclusionDebugRenderSystem.DebugRenderMode.None; } if (GUILayout.Toggle(OcclusionDebugRenderSystem.DebugRenderMode.Depth == debugSystem.m_DebugRenderMode, "Show Depth Buffer")) { debugSystem.m_DebugRenderMode = OcclusionDebugRenderSystem.DebugRenderMode.Depth; } if (GUILayout.Toggle(OcclusionDebugRenderSystem.DebugRenderMode.Test == debugSystem.m_DebugRenderMode, "Show Depth Test")) { debugSystem.m_DebugRenderMode = OcclusionDebugRenderSystem.DebugRenderMode.Test; } if (OcclusionDebugRenderSystem.DebugRenderMode.Depth == debugSystem.m_DebugRenderMode || OcclusionDebugRenderSystem.DebugRenderMode.Test == debugSystem.m_DebugRenderMode) { debugSystem.WantedOcclusionDraw = EditorGUILayout.IntSlider(debugSystem.WantedOcclusionDraw, 1, debugSystem.TotalOcclusionDrawPerFrame); } if (GUILayout.Toggle(OcclusionDebugRenderSystem.DebugRenderMode.Mesh == debugSystem.m_DebugRenderMode, "Show Occluder Meshes")) { debugSystem.m_DebugRenderMode = OcclusionDebugRenderSystem.DebugRenderMode.Mesh; } if (GUILayout.Toggle(OcclusionDebugRenderSystem.DebugRenderMode.Bounds == debugSystem.m_DebugRenderMode, "Show Occludee Bounds")) { debugSystem.m_DebugRenderMode = OcclusionDebugRenderSystem.DebugRenderMode.Bounds; } settingsSystem.DisplayOccluded = GUILayout.Toggle(settingsSystem.DisplayOccluded, "Display Occluded"); }
bool IPublicCommNet.Remove(Occluder conn) { return(this.Remove(conn)); }
bool IPublicCommNet.TestOcclusion(Vector3d aPos, Occluder a, Vector3d bPos, Occluder b, double distance) { return(this.TestOcclusion(aPos, a, bPos, b, distance)); }
public virtual VoxelizationOutput Generate(VoxelizationInput input, Action <VoxelizationProgress> progress) { VoxelizationProgress vp = new VoxelizationProgress(); DateTime start = DateTime.Now; vp.Status = "Building voxel field from octree"; progress(vp); VoxelField voxelField = new VoxelField(input.Octree); Byte fillByte = 2; float oldPercent = 1.0f; float newPercent = 1.0f; List <Occluder> occluders = new List <Occluder>(); vp.Status = "Calculating original mesh silhouette coverage"; progress(vp); SilhouetteOcclusionValidator sov = new SilhouetteOcclusionValidator(1024, 1024); long groundSideCoverage, groundTopCoverage; sov.ComputeCoverage(input.OriginalMesh, input.Octree.MeshBounds, out groundSideCoverage, out groundTopCoverage); long totalCoverage = groundSideCoverage + groundTopCoverage; if (totalCoverage == 0) { totalCoverage = 1; } vp.Status = "Fitting boxes into mesh..."; progress(vp); long oldOcclusion = 0; do { Vector3i densestVoxel = FindHighestDensityVoxel(voxelField); AABBi occluderBounds; if (input.Type == OcclusionType.BoxExpansion) { occluderBounds = ExpandAndFillBox(voxelField, ref densestVoxel, fillByte); } //else if (input.Type == OcclusionType.SimulatedAnnealing) //{ // occluderBounds = SimulatedAnnealingFill(input, sov, voxelField, ref densestVoxel, fillByte, occluders); //} else if (input.Type == OcclusionType.BruteForce) { occluderBounds = BruteForceFill(input, sov, voxelField, densestVoxel, fillByte, occluders); } else { throw new Exception("Unknown occluder generation type!"); } List <AABBi> relevantOccluders = GetRelevantOccluders(input, occluders); relevantOccluders.Add(occluderBounds); long newOcclusion = MeasureOccluderOcclusion(sov, input, relevantOccluders); Occluder occluder = new Occluder(); occluder.Bounds = occluderBounds; occluder.DeltaOcclusion = (newOcclusion - oldOcclusion) / (double)totalCoverage; occluders.Add(occluder); if (occluder.DeltaOcclusion > input.MinimumOcclusion) { oldOcclusion = newOcclusion; } Debug.WriteLine("Coverage " + occluder.DeltaOcclusion); Debug.WriteLine("Bounds (" + occluder.Bounds.MinX + "x" + occluder.Bounds.MaxX + " " + occluder.Bounds.MinY + "x" + occluder.Bounds.MaxY + " " + occluder.Bounds.MinZ + "x" + occluder.Bounds.MaxZ + ")"); oldPercent = newPercent; newPercent = MeasureUnboxedVoxels(voxelField); Debug.WriteLine("(" + densestVoxel.X + "," + densestVoxel.Y + "," + densestVoxel.Z + ")\tCoverage=" + ((1 - newPercent) * 100) + "%\tDelta=" + ((oldPercent - newPercent) * 100) + "%"); vp.Progress = Math.Min(((1 - newPercent) / input.MinimumVolume), 1.0f); vp.SilhouetteCoverage = oldOcclusion / (double)totalCoverage; vp.VolumeCoverage = 1 - newPercent; vp.Status = String.Format("Occlusion Progress : {0:0.##}%", (100 * vp.Progress)); progress(vp); } while (newPercent > (1 - input.MinimumVolume)); Mesh mesh = BuildMeshFromBoxes(input, GetRelevantOccluders(input, occluders)); VoxelizationOutput output = new VoxelizationOutput(); if (input.Retriangulate) { vp.Status = "Retriangulating occluder mesh"; progress(vp); Mesh triangulatedMesh = MeshOptimizer.Retriangulate(input, mesh, out output.DebugLines); if (triangulatedMesh != null) { mesh = triangulatedMesh; } } vp.Status = "Filtering polygons"; progress(vp); mesh = PolygonFilter.Filter(input, mesh); vp.Status = "Generating final occlusion mesh"; progress(vp); // Prepare the output output.Octree = input.Octree; output.TimeTaken = DateTime.Now - start; output.VolumeCoverage = 1 - newPercent; output.SilhouetteCoverage = oldOcclusion / (double)totalCoverage; output.OccluderMesh = new RenderableMesh(mesh, true); vp.Status = "Cleanup..."; progress(vp); sov.Dispose(); return(output); }