private bool IsDetailedEnough(ChunkedLodTreeFactory.ChunkedLodTreeNode node) { var nodeCenter = new Vector3d(node.Bounds.Center.X, node.Bounds.Center.Y, 0); var distanceToCamera = (nodeCenter - _cameraPosition).Length; var screenSpaceError = (node.GeometricError / distanceToCamera) * _k; return(screenSpaceError <= _allowedScreenSpaceError); }
public Terrain() { _tree = CreateTree(); _chunkedLod = new ChunkedLod(); _simpleMaterial = new SimpleMaterial(); _simpleMaterial.Create(); _normalDebugProgram = new NormalDebugProgram(); _normalDebugProgram.Create(); _cache = new TerrainChunkCache(new TerrainChunkFactory(), new ResourceAllocator(new OpenGlResourceFactory())); }
public Terrain(IChunkedLod chunkedLod) { _tree = CreateTree(); _chunkedLod = chunkedLod; _simpleMaterial = new SimpleMaterial(); _simpleMaterial.Create(); _normalDebugProgram = new NormalDebugProgram(); _normalDebugProgram.Create(); _cache = new TerrainChunkCache(new TerrainChunkFactory(), new ResourceAllocator(new OpenGlResourceFactory())); }
public void Does_not_request_child_unless_all_children_are_cached() { var parent = new ChunkedLodTreeFactory.ChunkedLodTreeNode(new Bounds2D(), null, 0); var firstChild = new ChunkedLodTreeFactory.ChunkedLodTreeNode(new Bounds2D(), parent, 0); var secondChild = new ChunkedLodTreeFactory.ChunkedLodTreeNode(new Bounds2D(), parent, 0); CacheNode(parent); CacheNode(firstChild); var cache = GetCache(); var result = LODCache.getNodesToDrawAndCache(cache, new[] { firstChild, secondChild }); CollectionAssert.AreEqual(new[] { parent }, result.Item1); CollectionAssert.AreEqual(new[] { secondChild }, result.Item2); }
public void All_nodes_are_requested_when_all_are_cached() { var node0 = new ChunkedLodTreeFactory.ChunkedLodTreeNode(new Bounds2D(), null, 0); var node1 = new ChunkedLodTreeFactory.ChunkedLodTreeNode(new Bounds2D(), node0, 0); var node2 = new ChunkedLodTreeFactory.ChunkedLodTreeNode(new Bounds2D(), node1, 0); var node3 = new ChunkedLodTreeFactory.ChunkedLodTreeNode(new Bounds2D(), null, 0); CacheNodes(node0, node1, node2, node3); var cache = GetCache(); var result = LODCache.getNodesToDrawAndCache(cache, new[] { node0, node1, node2, node3 }); CollectionAssert.AreEqual(new[] { node0, node1, node2, node3 }, result.Item1); Assert.IsEmpty(result.Item2); }
public void Do_not_request_descendants_when_the_ancestor_is_also_requested() { var level0 = new ChunkedLodTreeFactory.ChunkedLodTreeNode(new Bounds2D(), null, 0); var level10 = new ChunkedLodTreeFactory.ChunkedLodTreeNode(new Bounds2D(), level0, 0); var level11 = new ChunkedLodTreeFactory.ChunkedLodTreeNode(new Bounds2D(), level0, 0); var level20 = new ChunkedLodTreeFactory.ChunkedLodTreeNode(new Bounds2D(), level10, 0); CacheNode(level0); var cache = GetCache(); var result = LODCache.getNodesToDrawAndCache(cache, new[] { level11, level20 }); CollectionAssert.AreEqual(new[] { level0 }, result.Item1); CollectionAssert.AreEqual(new[] { level11, level20 }, result.Item2); }
private bool IsVisible(ChunkedLodTreeFactory.ChunkedLodTreeNode node) { var center = new Vector3d(node.Bounds.Center.X, node.Bounds.Center.Y, 0); var delta = node.Bounds.Max - node.Bounds.Min; var side = Math.Max(delta.X, delta.Y); var radius = Math.Sqrt(side * side + side * side); for (var i = 0; i < _frustumPlanes.Length; i++) { var sphereIsOutsideOfPlane = PlaneDistance(_frustumPlanes[i], center) < -radius; if (sphereIsOutsideOfPlane) { return(false); } } return(true); }
private void CalculateVisibleNodes(ChunkedLodTreeFactory.ChunkedLodTreeNode node) { if (!IsVisible(node)) { return; } if (IsDetailedEnough(node) || node.IsLeaf()) { _visibleNodes.Add(node); return; } foreach (var child in node.Nodes) { CalculateVisibleNodes(child); } }
public List <ChunkedLodTreeFactory.ChunkedLodTreeNode> Calculate( ChunkedLodTreeFactory.ChunkedLodTreeNode root, double viewportWidth, double horizontalFieldOfView, Vector3d cameraPosition, double allowedScreenSpaceError, Vector4d[] frustumPlanes) { _frustumPlanes = frustumPlanes; _allowedScreenSpaceError = allowedScreenSpaceError; _cameraPosition = cameraPosition; _visibleNodes = new List <ChunkedLodTreeFactory.ChunkedLodTreeNode>(); _k = viewportWidth / (Math.Tan(horizontalFieldOfView / 2)); CalculateVisibleNodes(root); return(_visibleNodes); }
public void No_nodes_are_requested_if_the_root_is_not_cached() { var root = new ChunkedLodTreeFactory.ChunkedLodTreeNode(new Bounds2D(), null, 0); var cache = GetCache(); var result = LODCache.getNodesToDrawAndCache(cache, new ChunkedLodTreeFactory.ChunkedLodTreeNode[] { root }); Assert.IsEmpty(result.Item1); CollectionAssert.AreEqual(new[] { root }, result.Item2); }
public void Requests_nodes_parent_if_originally_requested_node_is_not_cached_but_when_parent_is() { var parent = new ChunkedLodTreeFactory.ChunkedLodTreeNode(new Bounds2D(), null, 0); var child = new ChunkedLodTreeFactory.ChunkedLodTreeNode(new Bounds2D(), parent, 0); CacheNode(parent); var cache = GetCache(); var result = LODCache.getNodesToDrawAndCache(cache, new[] { child }); CollectionAssert.AreEqual(new[] { parent }, result.Item1); CollectionAssert.AreEqual(new[] { child }, result.Item2); }