/// <summary> /// Updates the internal quadtree to make it identical to the given terrain quadtree. /// Collects the tasks necessary to create the missing texture tiles, corresponding to newly created quads. /// </summary> /// <param name="parent">Parent quadtree.</param> /// <param name="tree">Internal quadtree.</param> /// <param name="quad">Quad.</param> protected virtual void GetTiles(QuadTree parent, ref QuadTree tree, TerrainQuad quad) { // If tree not created, create a new tree and check if its tile is needed if (tree == null) { tree = new QuadTree(parent); tree.IsNeedTile = NeedTile(quad); } // If this trees tile is needed get a tile and add its task to the schedular if the task is not already done if (tree.IsNeedTile && tree.Tile == null) { tree.Tile = Producer.GetTile(quad.Level, quad.Tx, quad.Ty); if (!tree.Tile.Task.IsDone) { // If task not done schedule task Schedular.Instance.Add(tree.Tile.Task); } } if (!quad.IsLeaf && Producer.HasChildren(quad.Level, quad.Tx, quad.Ty)) { for (byte i = 0; i < 4; ++i) { GetTiles(tree, ref tree.Children[i], quad.GetChild(i)); } } }
/// <summary> /// Updates the internal quadtree to make it identical to the given terrain quadtree. /// This method releases the texture tiles corresponding to deleted quads. /// </summary> /// <param name="tree">Internal quadtree.</param> /// <param name="quad">Quad.</param> protected virtual void PutTiles(QuadTree tree, TerrainQuad quad) { if (tree == null) { return; } // Check if this tile is needed, if not put tile. tree.IsNeedTile = NeedTile(quad); if (!tree.IsNeedTile && tree.Tile != null) { Producer.PutTile(tree.Tile); tree.Tile = null; } // If this qiad is a leaf then all children of the tree are not needed if (quad.IsLeaf) { if (!tree.IsLeaf) { tree.RecursiveDeleteChildren(this); } } else if (Producer.HasChildren(quad.Level, quad.Tx, quad.Ty)) { for (byte i = 0; i < 4; ++i) { PutTiles(tree.Children[i], quad.GetChild(i)); } } }
private void FindDrawableQuads(TerrainQuad quad, List <TileSampler> samplers) { quad.Drawable = false; if (!quad.IsVisible) { quad.Drawable = true; return; } if (quad.IsLeaf) { if (FindDrawableSamplers(quad, samplers)) { return; } } else { byte drawableCount = 0; for (byte i = 0; i < 4; ++i) { FindDrawableQuads(quad.GetChild(i), samplers); if (quad.GetChild(i).Drawable) { ++drawableCount; } } if (drawableCount < 4) { if (FindDrawableSamplers(quad, samplers)) { return; } } } quad.Drawable = true; }
private void DrawQuad(TerrainNode node, TerrainQuad quad, List <TileSampler> samplers) { if (!quad.IsVisible) { return; } if (!quad.Drawable) { return; } if (quad.IsLeaf) { MPB.Clear(); for (int i = 0; i < samplers.Count; ++i) { // Set the unifroms needed to draw the texture for this sampler samplers[i].SetTile(MPB, quad.Level, quad.Tx, quad.Ty); } // Set the uniforms unique to each quad node.SetPerQuadUniforms(quad, MPB); DrawNode(node); } else { // Draw quads in a order based on distance to camera var order = new byte[4]; var cameraX = node.LocalCameraPosition.x; var cameraY = node.LocalCameraPosition.y; var quadX = quad.Oy + quad.Length / 2.0; var quadY = quad.Oy + quad.Length / 2.0; if (cameraY < quadY) { if (cameraX < quadX) { order[0] = 0; order[1] = 1; order[2] = 2; order[3] = 3; } else { order[0] = 1; order[1] = 0; order[2] = 3; order[3] = 2; } } else { if (cameraX < quadX) { order[0] = 2; order[1] = 0; order[2] = 3; order[3] = 1; } else { order[0] = 3; order[1] = 1; order[2] = 2; order[3] = 0; } } var done = 0; for (byte i = 0; i < 4; ++i) { if (quad.GetChild(order[i]).Visibility == Frustum.VISIBILITY.INVISIBLE) { done |= (1 << order[i]); } else if (quad.GetChild(order[i]).Drawable) { DrawQuad(node, quad.GetChild(order[i]), samplers); done |= (1 << order[i]); } } if (done < 15) { // If the a leaf quad needs to be drawn but its tiles are not ready then this will draw the next parent tile instead that is ready. // Because of the current set up all tiles always have there tasks run on the frame they are generated so this section of code is never reached. MPB.Clear(); for (int i = 0; i < samplers.Count; ++i) { // Set the unifroms needed to draw the texture for this sampler samplers[i].SetTile(MPB, quad.Level, quad.Tx, quad.Ty); } // Set the uniforms unique to each quad node.SetPerQuadUniforms(quad, MPB); DrawNode(node); } } }