public void TestDensityBasedLOD()
        {
            TW.Graphics.SpectaterCamera.FarClip = 5000;

            var maxSampleSize = 64;
            var skipLevels    = 1;


            var density     = createDensityFunction5Perlin(19, maxSampleSize / 2);
            var meshBuilder = new DualContouringMeshBuilder();



            var size = maxSampleSize * (int)(Math.Pow(2, skipLevels));

            var minSize = skipLevels;
            var maxSize = Math.Log(size) / Math.Log(2);

            for (int i = minSize; i < maxSize; i++)
            {
                var currI      = i;
                var multiplier = (int)(Math.Pow(2, i));
                var resolution = size / multiplier;

                var grid = HermiteDataGrid.CopyGrid(new DensityFunctionHermiteGrid(v => density(v * multiplier), new Point3(resolution, resolution, resolution)));
                var mesh = meshBuilder.buildMesh(grid);

                var el = TW.Graphics.AcquireRenderer().CreateMeshElement(mesh);
                el.WorldMatrix = Matrix.Scaling(new Vector3(multiplier)) * Matrix.Translation((size * 1.1f) * (i - skipLevels), 0, 0);
            }

            EngineFactory.CreateEngine().AddSimulator(new WorldRenderingSimulator());
        }
Beispiel #2
0
        private void initDefaultWorld()
        {
            chunks = new Array3D <Chunk>(NumChunks);

            var totalTime = new TimeSpan(0);
            var i         = 0;

            chunks.ForEach((c, p) =>
            {
                i++;
                totalTime.Add(PerformanceHelper.Measure(() =>
                {
                    var grid = HermiteDataGrid.CopyGrid(new DensityFunctionHermiteGrid(v =>
                    {
                        v += (Vector3)p.ToVector3() * chunkSize;
                        return(20 - v.Y);
                    }, new Point3(chunkSize + 1, chunkSize + 1, chunkSize + 1)));

                    var chunk = new Chunk(p);
                    chunk.SetGrid(grid);
                    chunk.UpdateSurface(surfaceRenderer);
                    chunks[p] = chunk;
                }));
            });
            totalTime.Multiply(1f / i);
        }
        public void TestSaveGeneratedTerrain()
        {
            var dens     = createDensityFunction5Perlin(11, 10);
            var grid     = (AbstractHermiteGrid) new DensityFunctionHermiteGrid(dens, new Point3(64, 64, 64));
            var dataGrid = HermiteDataGrid.CopyGrid(grid);

            dataGrid.Save(TWDir.Test.CreateSubdirectory("DualContouring").CreateFile("TerrainHermite64.txt"));
        }
Beispiel #4
0
 private void tryPlaceObject()
 {
     if (!TW.Graphics.Mouse.LeftMouseJustPressed)
     {
         return;
     }
     Grid = new UnionGrid(grid, HermiteDataGrid.FromIntersectableGeometry(10, 20, Matrix.Translation(RaycastedPoint), PlaceableObjectGrid));
     Grid = HermiteDataGrid.CopyGrid(grid);
 }
        private void testDensityFunction(Func <Vector3, float> densityFunction, Point3 dimensions)
        {
            AbstractHermiteGrid grid = null;

            grid = createGridFromDensityFunction(densityFunction, dimensions);
            grid = HermiteDataGrid.CopyGrid(grid);


            showGrid(grid);
        }
        public void TestLoadGeneratedTerrain()
        {
            var grid =
                HermiteDataGrid.LoadFromFile(
                    TWDir.Test.CreateSubdirectory("DualContouring").CreateFile("TerrainHermite64.txt"));

            var testEnv = new DualContouringTestEnvironment();

            testEnv.Grid = grid;
            testEnv.AddToEngine(EngineFactory.CreateEngine());
        }
        public void TestHermiteCopyingAllEdges()
        {
            int size    = 32;
            var srcGrid = new DelegateHermiteGrid(p => p.X % 2 == 0 || p.Y % 2 == 0 || p.Z % 2 == 0, (p, i) => new Vector4(), new Point3(size, size, size));
            int times   = 100;

            Console.WriteLine(PerformanceHelper.Measure(() =>
            {
                for (int i = 0; i < times; i++)
                {
                    HermiteDataGrid.CopyGrid(srcGrid);
                }
            }).Multiply(1f / times).PrettyPrint());
        }
Beispiel #8
0
        public void RemoveFromWorld(HermiteDataGrid source, Point3 offset)
        {
            var bb = new BoundingBox(offset.ToVector3() * BuilderConfiguration.VoxelSize, (offset + source.Dimensions).ToVector3() * BuilderConfiguration.VoxelSize);

            /*var c = chunks[new Point3()];
             * //c.SetGrid(source);
             * c.SetGrid(HermiteDataGrid.CopyGrid(new UnionGrid(c.Grid, source, offset)));
             * c.UpdateSurface(surfaceRenderer);*/
            chunks.ForEach((c, p) =>
            {
                if (c.Box.xna().Contains(bb.xna()) == ContainmentType.Disjoint)
                {
                    return;
                }
                c.SetGrid(HermiteDataGrid.CopyGrid(new DifferenceGrid(c.Grid, source, offset - c.ChunkCoord * BuilderConfiguration.ChunkNumVoxels)));
                c.UpdateSurface(surfaceRenderer);
            });
        }
        public void TestGenerateTerrain([Values(16, 32, 64)] int size)
        {
            var dens        = VoxelTerrainGenerationTest.createDensityFunction5Perlin(11, 10);
            var densityGrid = (AbstractHermiteGrid) new DensityFunctionHermiteGrid(dens, new Point3(size, size, size));

            var times = 10;
            var s     = new Stopwatch();

            s.Start();

            for (int i = 0; i < times; i++)
            {
                var grid = HermiteDataGrid.CopyGrid(densityGrid);
            }
            s.Stop();
            Console.WriteLine("Time per copy:" + s.Elapsed.Multiply(1f / times).PrettyPrint());
            Console.WriteLine("Time per cell: " + s.Elapsed.Multiply(1f / times / (size * size * size)).PrettyPrint());
        }
        public void TestCountDensLookups20()
        {
            var dens = VoxelTerrainGenerationTest.createDensityFunction5Perlin(11, 10);


            var numLookups = 0;
            var newDens    = new Func <Vector3, float>(v =>
            {
                numLookups++;
                return(dens(v));
            });

            int size = 20;
            var grid = (AbstractHermiteGrid) new DensityFunctionHermiteGrid(newDens, new Point3(size, size, size));


            grid = HermiteDataGrid.CopyGrid(grid);

            Console.WriteLine("Density lookups: " + numLookups);
            Console.WriteLine("Lookups per cell: {0:#0.00}", (float)numLookups / (size * size * size));
        }
        private void testDensityFunction(Func <Vector3, float> densityFunction, Point3 dimensions)
        {
            AbstractHermiteGrid grid = null;

            grid = new DensityFunctionHermiteGrid(densityFunction, dimensions);
            var terrGen = PerformanceHelper.Measure(() =>
            {
                grid = HermiteDataGrid.CopyGrid(grid);
            });



            var testEnv = new DualContouringTestEnvironment();

            testEnv.Grid = grid;

            testEnv.AdditionalText = "Terrain to Hermite: " + terrGen.PrettyPrint();


            testEnv.AddToEngine(EngineFactory.CreateEngine());
        }
        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);
        }
        private static void testExtractSurface(DelegateHermiteGrid srcGrid)
        {
            var grid  = HermiteDataGrid.CopyGrid(srcGrid);
            int times = 40;

            var vertices  = new List <Vector3>(10 * 1000 * 1000);
            var indices   = new List <int>(10 * 1000 * 1000);
            var extractor = new DualContouringAlgorithm();

            var time = PerformanceHelper.Measure(() =>
            {
                for (int i = 0; i < times; i++)
                {
                    vertices.Clear();
                    indices.Clear();
                    extractor.GenerateSurface(vertices, indices, srcGrid);
                }
            });

            Console.WriteLine("Time: " + time.Multiply(1f / times).PrettyPrint());
            Console.WriteLine("{0:#.0}x{0:#.0}x{0:#.0} grid per second", Math.Pow(srcGrid.Dimensions.X * srcGrid.Dimensions.Y * srcGrid.Dimensions.Z / (time.TotalSeconds / times), 1 / 3f));
        }
        public void TestToHermiteGrid()
        {
            var size    = 128;
            var offset  = new Vector3(0, 0, 0);
            var scaling = new Vector3(1, 1, 1);
            var density = "20-v.y";
            var target  = new GPUHermiteCalculator(TW.Graphics);

            var signsTex = target.CreateDensitySignsTexture(size);

            target.WriteHermiteSigns(size, offset, scaling, density, signsTex);

            var intersectionsTex = target.CreateIntersectionsTexture(size);
            var normals1Tex      = target.CreateNormalsTexture(size);
            var normals2Tex      = target.CreateNormalsTexture(size);
            var normals3Tex      = target.CreateNormalsTexture(size);

            target.WriteHermiteIntersections(size, signsTex, intersectionsTex, normals1Tex, normals2Tex, normals3Tex);

            signsTex.SaveToImageSlices(TW.Graphics, TWDir.Test.CreateSubdirectory("DualContouring.GPU/ToHermite/Signs"));
            intersectionsTex.SaveToImageSlices(TW.Graphics, TWDir.Test.CreateSubdirectory("DualContouring.GPU/ToHermite/Intersections"));
            normals1Tex.SaveToImageSlices(TW.Graphics, TWDir.Test.CreateSubdirectory("DualContouring.GPU/ToHermite/Normals1"));
            normals2Tex.SaveToImageSlices(TW.Graphics, TWDir.Test.CreateSubdirectory("DualContouring.GPU/ToHermite/Normals2"));
            normals3Tex.SaveToImageSlices(TW.Graphics, TWDir.Test.CreateSubdirectory("DualContouring.GPU/ToHermite/Normals3"));

            var signs         = target.ReadDataThroughStageBuffer(signsTex);
            var intersections = target.ReadDataThroughStageBuffer(intersectionsTex);
            var normals1      = target.ReadDataThroughStageBuffer(normals1Tex);
            var normals2      = target.ReadDataThroughStageBuffer(normals2Tex);
            var normals3      = target.ReadDataThroughStageBuffer(normals3Tex);

            TW.Graphics.Device.ImmediateContext.ClearState();
            TW.Graphics.SetBackbuffer();

            var grid = HermiteDataGrid.CopyGrid(new DelegateHermiteGrid(
                                                    delegate(Point3 p)
            {
                p.Y = size - 1 - p.Y;
                return                                         //(p.X >= size || p.Y >= size || p.Z >= size)
                ((p.X >= size || p.Y < 0 || p.Z >= size)
                                                                   ? false
                                                                   : signs[(p.X + size * (p.Y + size * p.Z)) * 4] == 0);
            },
                                                    delegate(Point3 p, int edge)
            {
                p.Y = size - 1 - p.Y;
                if (edge < 0 || edge > 2)
                {
                    throw new InvalidOperationException();
                }
                // Assume edges 0,1,2 are 0+x,0+y,0+z
                int bufferOffset = (p.X + size * (p.Y + size * p.Z)) * 4;

                var norm       = new Vector3();
                byte[] nBuffer = null;
                switch (edge)
                {
                case 0:
                    nBuffer = normals1;
                    break;

                case 1:
                    nBuffer = normals2;
                    break;

                case 2:
                    nBuffer = normals3;
                    break;
                }

                norm.X = nBuffer[bufferOffset + 0] / 255f;
                norm.Y = nBuffer[bufferOffset + 1] / 255f;
                norm.Z = nBuffer[bufferOffset + 2] / 255f;
                norm   = (norm - new Vector3(0.5f)) * 2;


                /*
                 * // packing code with z removal, for later use maybe
                 * var sign = (normals2[bufferOffset + 2] & (1 << edge)) > 0 ? 1 : -1;
                 * var xsqysq = norm.X * norm.X + norm.Y * norm.Y;
                 * if (xsqysq > 1) xsqysq = 1;
                 * if (xsqysq < 0) xsqysq = 0;
                 * norm.Z = sign * (float)Math.Sqrt(1 - xsqysq);*/

                //if (Math.Abs(norm.Length() - 1) > 0.01) throw new InvalidOperationException();

                float intersection = intersections[bufferOffset + edge] / 255f;
                return(new Vector4(norm, intersection));
            },
                                                    new Point3(size, size, size)));



            var env = new DualContouringTestEnvironment();

            env.CameraLightSimulator.Light.LightRadius    = 300;
            env.CameraLightSimulator.Light.LightIntensity = 1;
            env.Grid = grid;
            env.AddToEngine(EngineFactory.CreateEngine());
        }
 public void TestUnionDifferentSizeOffset()
 {
     env.Grid = HermiteDataGrid.CopyGrid(new UnionGrid(HermiteDataGrid.Empty(new Point3(3, 3, 3)), builder.CreateCube(1), new Point3(1, 1, 1)));
 }
 public void TestUnionEqualSize()
 {
     env.Grid = HermiteDataGrid.CopyGrid(new UnionGrid(HermiteDataGrid.Empty(new Point3(2, 2, 2)), builder.CreateCube(1)));
 }
Beispiel #17
0
 public void SetGrid(HermiteDataGrid grid)
 {
     this.Grid    = grid;
     SurfaceDirty = true;
 }
 private AbstractHermiteGrid createSphereGrid()
 {
     return(HermiteDataGrid.CopyGrid(new DensityFunctionHermiteGrid(
                                         v => DensityHermiteGridTest.SphereDensityFunction(v, 7, new Vector3(10, 10, 10)), new Point3(20, 20, 20))));
 }