private static QuadTreeNode FindNeighborWest(ref QuadTreeNode node) { if (node.ID == -1) { return(null); } if (node.ID == (int)NodeDirection.NORTH_EAST) { return(node.Parent.NW); } if (node.ID == (int)NodeDirection.SOUTH_EAST) { return(node.Parent.SW); } QuadTreeNode tempNode = FindNeighborWest(ref node.Parent); if ((tempNode == null) || (!tempNode.HasChilds())) { return(tempNode); } else if (node.ID == (int)NodeDirection.NORTH_WEST) { return(tempNode.NE); } return(tempNode.SE); }
private void RecuDestroy(QuadTreeNode mainNode) { if (mainNode.HasChilds()) { for (int i = 1; i <= 4; i++) { QuadTreeNode node = mainNode.GetChild(i); RecuDestroy(node); } } mainNode.Destroy(); }
public void Render(ref Frustum frustum) { Frustum.InFrustumCheck nodeInFrustum = frustum.CubeInFrustum(mainNode.BoundingBox3D); if (((nodeInFrustum != Frustum.InFrustumCheck.OUT) && (mainNode.HasChilds()))) { bool checkFrustum = true; // if all boundingbox corner where inside the frustum, there is no need to check the childs too if (nodeInFrustum == Frustum.InFrustumCheck.IN) { checkFrustum = false; } Core.pushState(); //GL.Scale(terrainRef.scale); //GL.Translate(terrainRef.position); GL.Disable(EnableCap.Lighting); GL.Color4(1.0, 1.0, 1.0, 0); GL.EnableClientState(ArrayCap.VertexArray); GL.EnableClientState(ArrayCap.TextureCoordArray); if (terrainRef.TextureID != -1) { Texture.Bind(terrainRef.TextureID); GL.Enable(EnableCap.Texture2D); } CheckNodeInsideFrustum(ref frustum, ref mainNode, checkFrustum); if (terrainRef.TextureID != -1) { GL.Disable(EnableCap.Texture2D); } GL.DisableClientState(ArrayCap.TextureCoordArray); GL.DisableClientState(ArrayCap.VertexArray); Core.popState(); } return; }
private void CheckNodeInsideFrustum(ref Frustum frustum, ref QuadTreeNode mainNode, bool checkFrustum = true) { Frustum.InFrustumCheck nodeInFrustum; bool checkChildFrustum = true; // if the node has childs, check if nodes childs are in or outside the frustum if (mainNode.HasChilds()) { for (int i = 1; i <= 4; i++) { QuadTreeNode node = mainNode.GetChild(i); if (checkFrustum) { if (node.HasChilds()) { nodeInFrustum = frustum.CubeInFrustum(node.BoundingBox3D); } else { nodeInFrustum = frustum.CubeInFrustum(node.Patch); } if (nodeInFrustum == Frustum.InFrustumCheck.OUT) { continue; } if (nodeInFrustum == Frustum.InFrustumCheck.IN) { checkChildFrustum = false; } } CheckNodeInsideFrustum(ref frustum, ref node, checkChildFrustum); } } // if it don't, it's a leaf and the terrain patch can be rendered else { int maxLODLevels = terrainRef.LODLEVELS; int patchResolution = mainNode.Patch.GetResolution(maxLODLevels); int mainPatchIndexBuffer = terrainRef.IndexBuffer[patchResolution]; List <int> defaultBridgeIndexBuffer = new List <int>(); List <int> lowerBridgeIndexBuffer = new List <int>(); if (mainNode.Neighbor_N != null) { // check north neighbor patch resolution if (mainNode.Neighbor_N.Patch.GetResolution(maxLODLevels) > patchResolution) { lowerBridgeIndexBuffer.Add(terrainRef.BridgeIndexBuffer[patchResolution, 4]); } else { defaultBridgeIndexBuffer.Add(terrainRef.BridgeIndexBuffer[patchResolution, 0]); } } else { defaultBridgeIndexBuffer.Add(terrainRef.BridgeIndexBuffer[patchResolution, 0]); } if (mainNode.Neighbor_E != null) { // check east neighbor patch resolution if (mainNode.Neighbor_E.Patch.GetResolution(maxLODLevels) > patchResolution) { lowerBridgeIndexBuffer.Add(terrainRef.BridgeIndexBuffer[patchResolution, 5]); } else { defaultBridgeIndexBuffer.Add(terrainRef.BridgeIndexBuffer[patchResolution, 1]); } } else { defaultBridgeIndexBuffer.Add(terrainRef.BridgeIndexBuffer[patchResolution, 1]); } if (mainNode.Neighbor_S != null) { /* * Cube cube = new Cube(1); * cube.setPosition(new Vector3(mainNode.Patch.CenterVertex)); * cube.setColor(new ColorRGBA(1.0f, 0.0f, 0.0f, 1.0f)); * cube.render(ref frustum); * */ // check south neighbor patch resolution if (mainNode.Neighbor_S.Patch.GetResolution(maxLODLevels) > patchResolution) { lowerBridgeIndexBuffer.Add(terrainRef.BridgeIndexBuffer[patchResolution, 6]); } else { defaultBridgeIndexBuffer.Add(terrainRef.BridgeIndexBuffer[patchResolution, 2]); } } else { defaultBridgeIndexBuffer.Add(terrainRef.BridgeIndexBuffer[patchResolution, 2]); } if (mainNode.Neighbor_W != null) { // check west neighbor patch resolution if (mainNode.Neighbor_W.Patch.GetResolution(maxLODLevels) > patchResolution) { lowerBridgeIndexBuffer.Add(terrainRef.BridgeIndexBuffer[patchResolution, 7]); } else { defaultBridgeIndexBuffer.Add(terrainRef.BridgeIndexBuffer[patchResolution, 3]); } } else { defaultBridgeIndexBuffer.Add(terrainRef.BridgeIndexBuffer[patchResolution, 3]); } int[] indicesCount = new int[3]; indicesCount[0] = terrainRef.IndicesCount[patchResolution]; // main patch indices count indicesCount[1] = terrainRef.BridgeIndicesCount[0, patchResolution]; // default bridge indices count indicesCount[2] = terrainRef.BridgeIndicesCount[1, patchResolution]; // lower bridge indices count mainNode.Patch.Render(mainPatchIndexBuffer, defaultBridgeIndexBuffer.ToArray(), lowerBridgeIndexBuffer.ToArray(), indicesCount); } return; }
private void CheckNodeInsideFrustum(ref Frustum frustum, ref QuadTreeNode mainNode, bool checkFrustum = true) { Frustum.InFrustumCheck nodeInFrustum; bool checkChildFrustum = true; // if the node has childs, check if nodes childs are in or outside the frustum if (mainNode.HasChilds()) { for (int i = 1; i <= 4; i++) { QuadTreeNode node = mainNode.GetChild(i); if (checkFrustum) { if (node.HasChilds()) { nodeInFrustum = frustum.CubeInFrustum(node.BoundingBox3D); } else { nodeInFrustum = frustum.CubeInFrustum(node.Patch); } if (nodeInFrustum == Frustum.InFrustumCheck.OUT) { continue; } if (nodeInFrustum == Frustum.InFrustumCheck.IN) { checkChildFrustum = false; } } CheckNodeInsideFrustum(ref frustum, ref node, checkChildFrustum); } } // if it don't, it's a leaf and the terrain patch can be rendered else { int maxLODLevels = terrainRef.LODLEVELS; int patchResolution = mainNode.Patch.GetResolution(maxLODLevels); int mainPatchIndexBuffer = terrainRef.IndexBuffer[patchResolution]; List<int> defaultBridgeIndexBuffer = new List<int>(); List<int> lowerBridgeIndexBuffer = new List<int>(); if (mainNode.Neighbor_N != null) { // check north neighbor patch resolution if (mainNode.Neighbor_N.Patch.GetResolution(maxLODLevels) > patchResolution) lowerBridgeIndexBuffer.Add(terrainRef.BridgeIndexBuffer[patchResolution, 4]); else defaultBridgeIndexBuffer.Add(terrainRef.BridgeIndexBuffer[patchResolution, 0]); } else defaultBridgeIndexBuffer.Add(terrainRef.BridgeIndexBuffer[patchResolution, 0]); if (mainNode.Neighbor_E != null) { // check east neighbor patch resolution if (mainNode.Neighbor_E.Patch.GetResolution(maxLODLevels) > patchResolution) lowerBridgeIndexBuffer.Add(terrainRef.BridgeIndexBuffer[patchResolution, 5]); else defaultBridgeIndexBuffer.Add(terrainRef.BridgeIndexBuffer[patchResolution, 1]); } else defaultBridgeIndexBuffer.Add(terrainRef.BridgeIndexBuffer[patchResolution, 1]); if (mainNode.Neighbor_S != null) { /* Cube cube = new Cube(1); cube.setPosition(new Vector3(mainNode.Patch.CenterVertex)); cube.setColor(new ColorRGBA(1.0f, 0.0f, 0.0f, 1.0f)); cube.render(ref frustum); * */ // check south neighbor patch resolution if (mainNode.Neighbor_S.Patch.GetResolution(maxLODLevels) > patchResolution) lowerBridgeIndexBuffer.Add(terrainRef.BridgeIndexBuffer[patchResolution, 6]); else defaultBridgeIndexBuffer.Add(terrainRef.BridgeIndexBuffer[patchResolution, 2]); } else defaultBridgeIndexBuffer.Add(terrainRef.BridgeIndexBuffer[patchResolution, 2]); if (mainNode.Neighbor_W != null) { // check west neighbor patch resolution if (mainNode.Neighbor_W.Patch.GetResolution(maxLODLevels) > patchResolution) lowerBridgeIndexBuffer.Add(terrainRef.BridgeIndexBuffer[patchResolution, 7]); else defaultBridgeIndexBuffer.Add(terrainRef.BridgeIndexBuffer[patchResolution, 3]); } else defaultBridgeIndexBuffer.Add(terrainRef.BridgeIndexBuffer[patchResolution, 3]); int[] indicesCount = new int[3]; indicesCount[0] = terrainRef.IndicesCount[patchResolution]; // main patch indices count indicesCount[1] = terrainRef.BridgeIndicesCount[0, patchResolution]; // default bridge indices count indicesCount[2] = terrainRef.BridgeIndicesCount[1, patchResolution]; // lower bridge indices count mainNode.Patch.Render(mainPatchIndexBuffer, defaultBridgeIndexBuffer.ToArray(), lowerBridgeIndexBuffer.ToArray(), indicesCount); } return; }