private void recursiveFrustumCheck(SubGrid node, Camera camera) { //game.LineManager3D.AddBox( new BoundingBox( node.box.min, node.box.max ), Color.Red ); //game.LineManager3D.AddViewFrustum( new BoundingFrustum( camera.ViewProj ), Color.Green ); if (!camera.IsBoundingBoxVisible(new BoundingBox(node.box.min, node.box.max))) { return; } if (node.IsLeaf) { node.camPos = camera.Position; mVisibleSubgrids.Add(node); } for (int i = 0; i < 4; i++) { if (node.children[i] != null) { recursiveFrustumCheck(node.children[i], camera); } } }
private void buildSubGridMesh(Rectangle R, WaterDMapVertex[] gridVerts, bool buildMesh, SubGrid subGrid) { VertexElement[] elems = WaterDMapVertex.CreateVertexElements(); //Mesh subMesh = new Mesh( subGrid.NumTris, subGrid.NumVerts, MeshFlags.Managed | MeshFlags.Use32Bit, elems, mGDevice ); Mesh subMesh = new Mesh(game, subGrid.NumTris, subGrid.NumVerts, WaterDMapVertex.StrideSize , Graphics.AttributeSystem.CreateVertexDeclaration(game.GraphicsDevice, typeof(WaterDMapVertex))); #region set subgrid verts & generate the bounding box WaterDMapVertex[] v = new WaterDMapVertex[subMesh.NumberVertices]; Vector3[] positions = new Vector3[subMesh.NumberVertices]; //use a stream so we can pass it to computeBoundingBox //GraphicsStream vertexStream = subMesh.LockVertexBuffer( LockFlags.None ); int k = 0; for (int i = R.Top; i <= R.Bottom; i++) { for (int j = R.Left; j <= R.Right; j++) { v[k] = gridVerts[i * mInfo.vertCols + j]; positions[k] = gridVerts[i * mInfo.vertCols + j].pos; k++; } } //vertexStream.Write( v ); Utils.BoundingBox bndBox = new Utils.BoundingBox(); subMesh.SetVertexBufferData(v); BoundingBox bb = BoundingBox.CreateFromPoints(positions); bndBox.min = bb.Min; bndBox.max = bb.Max; //Geometry.ComputeBoundingBox( vertexStream, subMesh.NumberVertices, subMesh.VertexFormat, out bndBox.min, out bndBox.max ); //subMesh.UnlockVertexBuffer(); subGrid.box = bndBox; if (buildMesh == false) { subMesh.Dispose(); subMesh = null; return; } #endregion #region generate Indices for the subgrid and Optimize Vector3[] tempVerts; int[] tempIndices; Utils.GenTriGrid(subGrid.NumRows, subGrid.NumCols, mInfo.dx, mInfo.dz, new Vector3(0, 0, 0), out tempVerts, out tempIndices); /*int[] attributes = subMesh.LockAttributeBufferArray( LockFlags.None ); * for ( int i = 0; i < subGrid.NumTris; i++ ) * { * attributes[ i ] = 0; // All in subset 0. * } * * subMesh.UnlockAttributeBuffer();*/ subMesh.SetIndexBufferData(tempIndices); int[] adjacency = new int[subMesh.NumberFaces * 3]; subMesh.GenerateAdjacency(.001f, adjacency); //subMesh.OptimizeInPlace( MeshFlags.OptimizeVertexCache | MeshFlags.OptimizeAttributeSort, adjacency ); subMesh.OptimizeInPlace(0, adjacency); #endregion subGrid.mesh = subMesh; }
private void recursiveTerrainBuild(SubGrid node, Rectangle R, WaterDMapVertex[] gridVerts) { if (R.Width <= 32) { numLeaves++; buildSubGridMesh(R, gridVerts, true, node); node.IsLeaf = true; int[] indices = new int[node.NumTris * 3]; int k = 0; for (int i = R.Top; i < R.Bottom; i++) { for (int j = R.Left; j < R.Right; j++) { indices[k] = (i * mInfo.vertCols + j); indices[k + 1] = (i * mInfo.vertCols + j + 1); indices[k + 2] = ((i + 1) * mInfo.vertCols + j); indices[k + 3] = ((i + 1) * mInfo.vertCols + j); indices[k + 4] = (i * mInfo.vertCols + j + 1); indices[k + 5] = ((i + 1) * mInfo.vertCols + j + 1); // next quad k += 6; } } return; } buildSubGridMesh(R, gridVerts, false, node); int newWidth = R.Width / 2; int newHeight = R.Height / 2; int newSubRows = R.Width / newWidth; int newSubCols = R.Height / newHeight; int index = 0; /// SubGrid r | c /// Top-Left : 0 0 /// Top-Right : 0 1 /// Bottom-Left : 1 0 /// Bottom-Right: 1 1 /// for (int r = 0; r < newSubRows; r++) { for (int c = 0; c < newSubCols; c++) { Rectangle rec = new Rectangle( R.Left + c * (newWidth), R.Top + r * (newHeight), (newWidth), (newHeight)); node.children[index] = new SubGrid(newWidth + 1, newHeight + 1); recursiveTerrainBuild(node.children[index], rec, gridVerts); index++; } } }
private void buildGeometryHeirarchy() { //VertexElement[] elems = WaterDMapVertex.Decleration.GetDeclaration(); /*Mesh systemMesh = new Mesh( (int)mNumTris, (int)mNumVertices, MeshFlags.SystemMemory | MeshFlags.Use32Bit, * elems, mGDevice );*/ Vector3[] vertices; int[] indices; Utils.GenTriGrid((int)mInfo.vertRows, (int)mInfo.vertCols, mInfo.dx, mInfo.dz, new Vector3(0, 0, 0), out vertices, out indices); #region get data for the vertices WaterDMapVertex[] verts = new WaterDMapVertex[mNumVertices]; for (int i = 0; i < mInfo.vertRows; ++i) { for (int j = 0; j < mInfo.vertCols; ++j) { int index = i * mInfo.vertCols + j; verts[index].pos = vertices[index]; verts[index].scaledTexC = new Vector2((float)j / mInfo.vertCols, (float)i / mInfo.vertRows) * mInfo.texScale; verts[index].normalizedTexC = new Vector2((float)j / mInfo.vertCols, (float)i / mInfo.vertRows); } } #endregion /*#region mesh index data, compute normals, optimize * //write the vertex data * systemMesh.SetVertexBufferData( verts, LockFlags.None ); * * //write the index data * systemMesh.SetIndexBufferData( indices, LockFlags.None ); * * int[] adjacency = new int[ systemMesh.NumberFaces * 3 ]; * systemMesh.GenerateAdjacency( .001f, adjacency ); * systemMesh.OptimizeInPlace( MeshFlags.OptimizeVertexCache | MeshFlags.OptimizeAttributeSort, adjacency ); #endregion*/ /*mVertexBuffer = new VertexBuffer( mGDevice, * mNumVertices * CustomVertex.PositionNormalTextured.StrideSize * 4, * Usage.WriteOnly, * CustomVertex.PositionNormalTextured.Format, * Pool.Managed );*/ mVertexBuffer = new VertexBuffer(mGDevice, typeof(VertexPositionNormalTexture), mNumVertices, BufferUsage.WriteOnly); mVertexBuffer.SetData(verts); Rectangle Rec = new Rectangle( 0, 0, (mInfo.vertCols - 1), (mInfo.vertRows - 1)); mRootSubGrid = new SubGrid(mInfo.vertRows, mInfo.vertCols); recursiveTerrainBuild(mRootSubGrid, Rec, verts); /*systemMesh.Dispose(); * systemMesh = null;*/ }