public void SetEnabledLayers(HashSet <string> layers) { foreach (var renderer in AllNodes) { renderer.LayerEnabled = layers.Contains(renderer.LayerName); } StaticOctree.Clear(); DynamicOctree.Clear(); foreach (var node in staticNodes) { if (node.LayerEnabled) { StaticOctree.Insert(node, node.BoundingBox); } } foreach (var node in dynamicNodes) { if (node.LayerEnabled) { DynamicOctree.Insert(node, node.BoundingBox); } } }
public void Add(SceneNode node, bool dynamic) { if (dynamic) { dynamicNodes.Add(node); DynamicOctree.Insert(node, node.BoundingBox); } else { staticNodes.Add(node); StaticOctree.Insert(node, node.BoundingBox); } }
public void RenderWithCamera(Camera camera, Frustum cullFrustum = null) { var allNodes = StaticOctree.Query(cullFrustum ?? camera.ViewFrustum); allNodes.AddRange(DynamicOctree.Query(cullFrustum ?? camera.ViewFrustum)); // Collect mesh calls var opaqueDrawCalls = new List <MeshBatchRenderer.Request>(); var translucentDrawCalls = new List <MeshBatchRenderer.Request>(); var looseNodes = new List <SceneNode>(); foreach (var node in allNodes) { if (node is IRenderableMeshCollection meshCollection) { foreach (var mesh in meshCollection.RenderableMeshes) { foreach (var call in mesh.DrawCallsOpaque) { opaqueDrawCalls.Add(new MeshBatchRenderer.Request { Transform = node.Transform, Mesh = mesh, Call = call, DistanceFromCamera = (node.BoundingBox.Center - camera.Location).LengthSquared(), }); } foreach (var call in mesh.DrawCallsBlended) { translucentDrawCalls.Add(new MeshBatchRenderer.Request { Transform = node.Transform, Mesh = mesh, Call = call, DistanceFromCamera = (node.BoundingBox.Center - camera.Location).LengthSquared(), }); } } } else { looseNodes.Add(node); } } // Sort loose nodes by distance from camera looseNodes.Sort((a, b) => { var aLength = (a.BoundingBox.Center - camera.Location).LengthSquared(); var bLength = (b.BoundingBox.Center - camera.Location).LengthSquared(); return(bLength.CompareTo(aLength)); }); // Opaque render pass var opaqueRenderContext = new RenderContext(camera, RenderPass.Opaque); MeshBatchRenderer.Render(opaqueDrawCalls, opaqueRenderContext); foreach (var node in looseNodes) { node.Render(opaqueRenderContext); } // Translucent render pass, back to front for loose nodes var translucentRenderContext = new RenderContext(camera, RenderPass.Translucent); MeshBatchRenderer.Render(translucentDrawCalls, translucentRenderContext); foreach (var node in Enumerable.Reverse(looseNodes)) { node.Render(translucentRenderContext); } }