public void Creates_root_node_with_no_leafs_at_zero_depth()
        {
            var sut = new ChunkedLodTreeFactory();
            var expectedBounds = new Box3D(new Vector3d(-1, -2, -3), new Vector3d(1, 2, 3));

            var result = sut.Create(expectedBounds, 0);

            Assert.AreEqual(expectedBounds, result.Bounds);
            Assert.AreEqual(1, result.GeometricError);
            Assert.IsEmpty(result.Nodes);
        }
        public void Creates_root_node_with_four_children_at_depth_one()
        {
            var sut = new ChunkedLodTreeFactory();
            var expectedBounds = new Box3D(new Vector3d(-1, -1, -1), new Vector3d(1, 1, 1));

            var result = sut.Create(expectedBounds, 1);

            Assert.AreEqual(expectedBounds, result.Bounds);
            Assert.AreEqual(2, result.GeometricError);
            Assert.AreEqual(4, result.Nodes.Length);
        }
        public void Creates_children_with_correct_bounds_and_are_leafs_at_depth_one()
        {
            var sut = new ChunkedLodTreeFactory();
            var expectedBounds = new Box3D(new Vector3d(-1, -1, -1), new Vector3d(1, 1, 1));

            var result = sut.Create(expectedBounds, 1);

            AssertLeaf(new Box3D(new Vector3d(-1, -1, -1), new Vector3d(0, 0, 1)), result.Nodes[0]);
            AssertLeaf(new Box3D(new Vector3d(0, -1, -1), new Vector3d(1, 0, 1)), result.Nodes[1]);
            AssertLeaf(new Box3D(new Vector3d(-1, 0, -1), new Vector3d(0, 1, 1)), result.Nodes[2]);
            AssertLeaf(new Box3D(new Vector3d(0, 0, -1), new Vector3d(1, 1, 1)), result.Nodes[3]);
        }
        public void Creates_tree_for_depth_of_two()
        {
            var sut = new ChunkedLodTreeFactory();
            var expectedBounds = new Box3D(new Vector3d(-1, -1, -1), new Vector3d(1, 1, 1));

            var result = sut.Create(expectedBounds, 2);
            Assert.AreEqual(4, result.GeometricError);
            var leafs = result.Nodes.SelectMany(x => x.Nodes);

            Assert.AreEqual(16, leafs.Count());
            foreach (var leaf in leafs)
            {
                Assert.IsEmpty(leaf.Nodes);
            }
        }
        private Node CreateNode(Box3D bounds, int level, EntityManager entityManager)
        {
            var mesh = MeshCreator.CreateXZGrid(10, 10);
            var staticMesh = new StaticMesh
            {
                Color = new Vector4(0f, 0f, 1f, 1f),
                ModelMatrix = Matrix4.Identity,
            };

            var size = bounds.Max - bounds.Min;
            var mesh3V3N = mesh.Transformed(Matrix4.CreateScale((float)size.X, 1, (float)size.Z) * Matrix4.CreateTranslation((Vector3)bounds.Center));
            var improvedPerlinNoise = new ImprovedPerlinNoise(4711);
            for (int i = 0; i < mesh3V3N.Vertices.Length; i++)
            {
                var vertex = mesh3V3N.Vertices[i];
                var height = improvedPerlinNoise.Noise(vertex.Position.X, vertex.Position.Z) * 0.2;
                mesh3V3N.Vertices[i] = new Vertex3V3N
                {
                    Normal = new Vector3(0, 1, 0),
                    Position = new Vector3(vertex.Position.X, (float)height, vertex.Position.Z)
                };
            }

            staticMesh.Update(mesh3V3N);

            var entity = new Entity(Guid.NewGuid().ToString());
            entityManager.Add(entity);
            entityManager.AddComponentToEntity(entity, staticMesh);

            if (level == 0)
            {
                return new Node(bounds, new Node[] { }, entity, 1);
            }

            var min = bounds.Min;
            var max = bounds.Max;
            var center = bounds.Center;

            return new Node(bounds,
                new[]
                {
                    CreateNode(new Box3D(bounds.Min, center), level -1, entityManager),
                    CreateNode(new Box3D(new Vector3d(center.X, 0, min.Z), new Vector3d(max.X, 0, center.Z)), level -1, entityManager),
                    CreateNode(new Box3D(new Vector3d(min.X, 0, center.Z), new Vector3d(center.X, 0, max.Z)), level - 1, entityManager),
                    CreateNode(new Box3D(center, max), level - 1, entityManager)
                }, entity, Math.Pow(2, level));
        }
        public RenderableMesh GetRenderable(Box3D bounds)
        {
            RenderableMesh mesh;
            var result = _cache.TryGetValue(bounds, out mesh);
            if (result)
            {
                return mesh;
            }

            if (!_jobs.Contains(bounds))
            {
                _jobs.Add(bounds);
                JobDispatcher.Instance.Enqueue(() =>
                {
                    var terrainChunk = _terrainChunkFactory.Create(bounds);
                    var renderableMesh = _resourceAllocator.AllocateResourceFor(terrainChunk);
                    _cache[bounds] = renderableMesh;
                    _jobs.Remove(bounds);
                });
            }

            return null;
        }
示例#7
0
            public ImplicitChunkHeightMap(Box3D bounds, int columns, int rows, INoiseGenerator noiseGenerator)
            {
                _noiseGenerator = noiseGenerator;
                _rows = rows;
                _columns = columns;
                _bounds = bounds;

                var origin = CalculatePosition(0, 0);
                var position = CalculatePosition(1, 1);

                _dx = 1 / (position.X - origin.X);
                _dy = 1 / (position.Y - origin.Y);
            }
示例#8
0
 public Mesh3V3N Create(Box3D bounds)
 {
     var meshDimensions = 128;
     var implicintHeightMap = new ImplicitChunkHeightMap(bounds, meshDimensions, meshDimensions, new ScaledNoiseGenerator());
     return MeshCreator.CreateFromHeightMap(meshDimensions, meshDimensions, implicintHeightMap);
 }
示例#9
0
        private static ChunkedLodTreeFactory.ChunkedLodTreeNode CreateTree()
        {
            var chunkedLodTreeFactory = new ChunkedLodTreeFactory();

            var bounds = new Box3D(
                new Vector3d(-4096, -4096, 0),
                new Vector3d(4096, 4096, 0));

            var levels = Math.Log((8192 / 128), 2);

            //calculate depth so that one square is one meter as maximum resolution
            return chunkedLodTreeFactory.Create(bounds, (int)8);
        }
 public Node(Box3D bounds, Node[] leafNodes, Entity entity, double geometricError)
 {
     Entity = entity;
     GeometricError = geometricError;
     Bounds = bounds;
     Leafs = leafNodes;
 }
 private void AssertLeaf(Box3D expected, ChunkedLodTreeFactory.ChunkedLodTreeNode actual)
 {
     Assert.IsEmpty(actual.Nodes);
     Assert.AreEqual(1, actual.GeometricError);
     Assert.AreEqual(expected, actual.Bounds);
 }
 public bool Equals(Box3D other)
 {
     return(Min.Equals(other.Min) && Max.Equals(other.Max));
 }
 public bool Equals(Box3D other)
 {
     return Min.Equals(other.Min) && Max.Equals(other.Max);
 }