private bool IsDetailedEnough(ChunkedLodTreeFactory.ChunkedLodTreeNode node) { var distanceToCamera = (node.Bounds.Center - _cameraPosition).Length; var screenSpaceError = (node.GeometricError / distanceToCamera) * _k; return screenSpaceError <= _allowedScreenSpaceError; }
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 static ChunkedLodTreeFactory.ChunkedLodTreeNode CreateTree() { var chunkedLodTreeFactory = new ChunkedLodTreeFactory(); double width = 8192 * 2 * 2; var bounds = new Bounds2D( new Vector2d(-width / 2, -width / 2), new Vector2d(width / 2, width / 2)); var chunkResolution = 32; var depth = (int)Math.Log((width / chunkResolution), 2); return(chunkedLodTreeFactory.Create(bounds, depth)); }
public static ChunkedLodTreeFactory.ChunkedLodTreeNode CreateTree() { var chunkedLodTreeFactory = new ChunkedLodTreeFactory(); double width = 8192 * 2 * 2; var bounds = new Bounds2D( new Vector2d(-width/2, -width/2), new Vector2d(width/2, width/2)); var chunkResolution = 32; var depth = (int)Math.Log((width / chunkResolution), 2); return chunkedLodTreeFactory.Create(bounds, depth); }
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 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); } }
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; }
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; }
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); }
private void CacheNode(ChunkedLodTreeFactory.ChunkedLodTreeNode node) { _cache.Add(node); }
private void AssertLeaf(Box3D expected, ChunkedLodTreeFactory.ChunkedLodTreeNode actual) { Assert.IsEmpty(actual.Nodes); Assert.AreEqual(1, actual.GeometricError); Assert.AreEqual(expected, actual.Bounds); }