Пример #1
0
        public void UpdateQuadtreeClipmaps(LodOctreeNode node, Vector3 cameraPosition, int minNodeSize)
        {
            var center = (Vector3)node.LowerLeft.ToVector3() + new Vector3(1) * node.size * 0.5f;
            var dist   = Vector3.Distance(cameraPosition, center);

            // Should take into account the fact that if minNodeSize changes, the quality of far away nodes changes so the threshold maybe should change too
            if (dist > node.size * 1.2f)
            {
                // This is a valid node size at this distance, so remove all children
                Merge(node);
            }
            else
            {
                if (node.Children == null)
                {
                    Split(node, false, minNodeSize);
                }

                if (node.Children == null)
                {
                    return;                        // Minlevel
                }
                for (int i = 0; i < 8; i++)
                {
                    UpdateQuadtreeClipmaps(node.Children[i], cameraPosition, minNodeSize);
                }
            }
        }
        public void UpdateCanRenderWithoutHoles(LodOctreeNode node)
        {
            if (node.Children == null)
            {
                node.CanRenderWithoutHoles = node.Mesh != null;
                /*if (!node.CanRenderWithoutHoles)
                {
                    TW.Graphics.LineManager3D.WorldMatrix = Matrix.Identity;
                    tree.DrawSingleNode(node, TW.Graphics.LineManager3D, Color.Orange);

                }*/
                return;
            }

            var canRenderChildrenWithoutHoles = true;
            for (int i = 0; i < 8; i++)
            {
                var child = node.Children[i];
                UpdateCanRenderWithoutHoles(child);
                if (!child.CanRenderWithoutHoles)
                    canRenderChildrenWithoutHoles = false;
            }
            // only render when children cant and i have mesh
            node.CanRenderWithoutHoles = canRenderChildrenWithoutHoles || node.Mesh != null;

        }
        public DeferredMeshElement CreateRenderElementForNode(LodOctreeNode node, int minNodeSize, IMesh mesh)
        {
            var   el       = TW.Graphics.AcquireRenderer().CreateMeshElement(mesh);
            float setApart = 1.1f;

            setApart       = 1; // Disable spacing between cells
            el.WorldMatrix = Matrix.Scaling(new Vector3(node.size / minNodeSize)) *
                             Matrix.Translation(node.LowerLeft.ToVector3() * setApart);
            return(el);
        }
        private void DestroyMeshElementRecursive(LodOctreeNode node)
        {
            DestroyMeshElement(node);

            if (node.Children == null) return;
            for (int i = 0; i < 8; i++)
            {
                DestroyMeshElementRecursive(node.Children[i]);
            }
        }
Пример #5
0
        public LodOctreeNode Create(int size, int leafCellSize, int depth = 0, Point3 pos = new Point3())
        {
            var ret = new LodOctreeNode(size, depth, pos);

            if (size <= leafCellSize)
            {
                return(ret);                      // Finest detail
            }
            Split(ret, true, leafCellSize);

            return(ret);
        }
Пример #6
0
 public void DrawLines(LodOctreeNode node, LineManager3D lm)
 {
     DrawSingleNode(node, lm, Color.Black);
     if (node.Children == null)
     {
         return;
     }
     for (int i = 0; i < 8; i++)
     {
         DrawLines(node.Children[i], lm);
     }
 }
Пример #7
0
 public void Merge(LodOctreeNode node)
 {
     if (node.Children == null)
     {
         return;
     }
     for (int i = 0; i < 8; i++)
     {
         node.Children[i].Destroy();
     }
     node.Children = null;
 }
Пример #8
0
 public void VisitDepthFirst(LodOctreeNode rootNode, Action <LodOctreeNode> action)
 {
     action(rootNode);
     if (rootNode.Children == null)
     {
         return;
     }
     for (int i = 0; i < 8; i++)
     {
         VisitDepthFirst(rootNode.Children[i], action);
     }
 }
 private void ensureMeshElementCreated(LodOctreeNode node)
 {
     visibleMeshes++;
     /*TW.Graphics.LineManager3D.WorldMatrix = Matrix.Identity;
     tree.DrawSingleNode(node, TW.Graphics.LineManager3D, Color.Red);*/
     var mesh = node.Mesh;
     if (mesh == null) throw new InvalidOperationException("Cannot ensure!");
     if (node.RenderElement == null)
     {
         node.RenderElement = meshBuilder.CreateRenderElementForNode(node, minNodeSize, mesh);
         node.RenderElement.WorldMatrix = (Matrix)node.RenderElement.WorldMatrix * Matrix.Scaling(new Vector3(globalScaling));
     }
 }
        public IMesh CalculateNodeMesh(LodOctreeNode node, int minNodeSize, Func <Vector3, float> density)
        {
            var grid = getGrid(node, minNodeSize, density);

            var mesh = meshBuilder.buildMesh(grid);

            if (mesh.GetCoreData().Parts.Count > 0)
            {
                mesh.GetCoreData().Parts[0].MeshMaterial = new MeshCoreData.Material()
                {
                    ColoredMaterial = true, DiffuseColor = colors[node.depth % colors.Length].xna()
                }
            }
            ;
            return(mesh);
        }
        public void ListMeshLessNodes(LodOctreeNode n, List <LodOctreeNode> list)
        {
            if (n.Mesh == null)
            {
                list.Add(n);
            }

            if (n.Children == null)
            {
                return;
            }
            for (int i = 0; i < 8; i++)
            {
                ListMeshLessNodes(n.Children[i], list);
            }
        }
Пример #12
0
        public void DrawLines(LodOctreeNode node, LineManager3D lm, Func <LodOctreeNode, bool> isVisible, Func <LodOctreeNode, Color> getColor)
        {
            if (isVisible(node))
            {
                DrawSingleNode(node, lm, getColor(node));
            }

            if (node.Children == null)
            {
                return;
            }
            for (int i = 0; i < 8; i++)
            {
                DrawLines(node.Children[i], lm, isVisible, getColor);
            }
        }
        public void UpdateMeshElements(LodOctreeNode node)
        {
            if (node.Children == null)
            {
                if (node.Mesh != null)
                    ensureMeshElementCreated(node);
                return;
            }
            if (node.CanRenderWithoutHoles)
            {
                var canRenderChildrenWithoutHoles = true;
                for (int i = 0; i < 8; i++)
                {
                    var child = node.Children[i];
                    UpdateCanRenderWithoutHoles(child);
                    if (!child.CanRenderWithoutHoles)
                        canRenderChildrenWithoutHoles = false;
                }
                if (canRenderChildrenWithoutHoles)
                {
                    //Render children
                    DestroyMeshElement(node);
                    for (int i = 0; i < 8; i++)
                    {
                        UpdateMeshElements(node.Children[i]);
                    }
                }
                else
                {
                    ensureMeshElementCreated(node);
                    if (node.Children != null)
                        for (int i = 0; i < 8; i++) DestroyMeshElementRecursive(node.Children[i]);
                }
            }
            else
            {
                DestroyMeshElementRecursive(node);
                /*DestroyMeshElement(node);
                if (node.Children != null)
                    for (int i = 0; i < 8; i++) UpdateMeshElements(node.Children[i]);*/
            }


        }
Пример #14
0
        public void Split(LodOctreeNode ret, bool recurse = false, int minSize = 1)
        {
            if (ret.Children != null)
            {
                throw new InvalidOperationException();
            }

            var childSize = ret.size / 2;

            if (childSize < minSize)
            {
                return;
            }

            ret.Children = new LodOctreeNode[8];

            for (int i = 0; i < 8; i++)
            {
                ret.Children[i] = new LodOctreeNode(childSize, ret.depth + 1, ret.LowerLeft + ChildOffsets[i] * childSize);
            }
        }
        private HermiteDataGrid getGrid(LodOctreeNode node, int minNodeSize, Func <Vector3, float> density)
        {
            var nId = new NodeIdentifier(node);

            if (cachedGrids.ContainsKey(nId))
            {
                return(cachedGrids[nId]);
            }
            var currScaling = node.size / minNodeSize;

            // Then we add another +1 to be able to connect the gaps between the hermite grids
            //TODO: do lod stitching here
            var gridSize = minNodeSize + 1;


            var grid = HermiteDataGrid.CopyGrid(
                new DensityFunctionHermiteGrid(v => density(v * currScaling + (Vector3)node.LowerLeft.ToVector3()),
                                               new Point3(gridSize, gridSize, gridSize)));

            cachedGrids[nId] = grid;
            return(grid);
        }
        public TerrainLodEnvironment()
        {

            tree = new LodOctree();

            var size = 32 * (1 << 10);
            rootNode = tree.Create(size, size);

            //octreeOffset = new Vector3(0, size, 0);
            octreeOffset = new Vector3(0, 0, 0);


            density = VoxelTerrainGenerationTest.createDensityFunction5Perlin(17, size / 2);
            //density = v => DensityHermiteGridTest.SineXzDensityFunction(v, 1/5f, size/2, 3);
            density = densityFunction;
            densityGrid = new DensityFunctionHermiteGrid(density, new Point3(size, size, size));
            minNodeSize = 32;




        }
 public NodeIdentifier(LodOctreeNode node)
 {
     this.Pos  = node.LowerLeft;
     this.Size = node.size;
 }
Пример #18
0
 public void DrawSingleNode(LodOctreeNode node, LineManager3D lm, Color col)
 {
     lm.AddBox(new BoundingBox(node.LowerLeft.ToVector3(), (Vector3)node.LowerLeft.ToVector3() + node.size * new Vector3(1)),
               col);
 }
 private static void DestroyMeshElement(LodOctreeNode node)
 {
     if (node.RenderElement != null) node.RenderElement.Delete();
     node.RenderElement = null;
 }