Axiom.Demos.WaterMesh.WaterMesh C# (CSharp) Méthode

WaterMesh() public méthode

public WaterMesh ( String meshName, float planeSize, int cmplx ) : System
meshName String
planeSize float
cmplx int
Résultat System
		public WaterMesh( String meshName, float planeSize, int cmplx )
		{ // najak R-F
			// Assign Fields to the Initializer values
			this.meshName = meshName;
			this.size = planeSize;
			this.cmplx = cmplx;  // Number of Rows/Columns in the Water Grid representation
			cmplxAdj = (float)System.Math.Pow( ( cmplx / 64f ), 1.4f ) * 2;
			numFaces = 2 * (int)System.Math.Pow( cmplx, 2 );  // Each square is split into 2 triangles.
			numVertices = (int)System.Math.Pow( ( cmplx + 1 ), 2 ); // Vertex grid is (Complexity+1) squared

			// Allocate and initialize space for calculated Normals
			vNorms = new Vector3[ cmplx + 1, cmplx + 1 ]; // vertex Normals for each grid point
			fNorms = new Vector3[ cmplx, cmplx, 2 ]; // face Normals for each triangle

			// Create mesh and submesh to represent the Water
			mesh = (Mesh)MeshManager.Instance.CreateManual( meshName, ResourceGroupManager.DefaultResourceGroupName, null );
			subMesh = mesh.CreateSubMesh();
			subMesh.useSharedVertices = false;

			// Construct metadata to describe the buffers associated with the water submesh
			subMesh.vertexData = new VertexData();
			subMesh.vertexData.vertexStart = 0;
			subMesh.vertexData.vertexCount = numVertices;

			// Define local variables to point to the VertexData Properties
			VertexDeclaration vdecl = subMesh.vertexData.vertexDeclaration;  // najak: seems like metadata
			VertexBufferBinding vbind = subMesh.vertexData.vertexBufferBinding; // najak: pointer to actual buffer

			//najak: Set metadata to describe the three vertex buffers that will be accessed.
			vdecl.AddElement( 0, 0, VertexElementType.Float3, VertexElementSemantic.Position );
			vdecl.AddElement( 1, 0, VertexElementType.Float3, VertexElementSemantic.Normal );
			vdecl.AddElement( 2, 0, VertexElementType.Float2, VertexElementSemantic.TexCoords );

			// Prepare buffer for positions - todo: first attempt, slow
			// Create the Position Vertex Buffer and Bind it index 0 - Write Only
			posVBuf = HwBufMgr.CreateVertexBuffer( vdecl.Clone(0), numVertices, BufferUsage.DynamicWriteOnly );
			vbind.SetBinding( 0, posVBuf );

			// Prepare buffer for normals - write only
			// Create the Normals Buffer and Bind it to index 1 - Write only
			normVBuf = HwBufMgr.CreateVertexBuffer( vdecl.Clone(1), numVertices, BufferUsage.DynamicWriteOnly );
			vbind.SetBinding( 1, normVBuf );

			// Prepare Texture Coordinates buffer (static, written only once)
			// Creates a 2D buffer of 2D coordinates: (Complexity X Complexity), pairs.
			//    Each pair indicates the normalized coordinates of the texture to map to.
			//    (0,1.00), (0.02, 1.00), (0.04, 1.00), ... (1.00,1.00)
			//    (0,0.98), (0.02, 0.98), (0.04, 1.00), ... (1.00,0.98)
			//    ...
			//    (0,0.00), (0.02, 0.00), (0.04, 0.00), ... (1.00,0.00)
			// This construct is simple and is used to calculate the Texture map.
			// Todo: Write directly to the buffer, when Axiom supports this in safe manner
			float[ , , ] tcBufDat = new float[ cmplx + 1, cmplx + 1, 2 ];
			for ( int i = 0; i <= cmplx; i++ )
			{
				// 2D column iterator for texture map
				for ( int j = 0; j <= cmplx; j++ )
				{
					// 2D row iterator for texture map
					// Define the normalized(0..1) X/Y-coordinates for this element of the 2D grid
					tcBufDat[ i, j, 0 ] = (float)i / cmplx;
					tcBufDat[ i, j, 1 ] = 1.0f - ( (float)j / ( cmplx ) );
				}
			}

			// Now Create the actual hardware buffer to contain the Texture Coordinate 2d map.
			//   and Bind it to buffer index 2
			tcVBuf = HwBufMgr.CreateVertexBuffer( vdecl.Clone(2), numVertices, BufferUsage.StaticWriteOnly );
			tcVBuf.WriteData( 0, tcVBuf.Size, tcBufDat, true );
			vbind.SetBinding( 2, tcVBuf );

			// Create a Graphics Buffer on non-shared vertex indices (3 points for each triangle).
			//  Since the water grid consist of [Complexity x Complexity] squares, each square is
			//  split into 2 right triangles 45-90-45.  That is how the water mesh is constructed.
			//  Therefore the number of faces = 2 * Complexity * Complexity
			ushort[ , , ] idxBuf = new ushort[ cmplx, cmplx, 6 ];
			for ( int i = 0; i < cmplx; i++ )
			{ // iterate the rows
				for ( int j = 0; j < cmplx; j++ )
				{ // iterate the columns
					// Define 4 corners of each grid
					ushort p0 = (ushort)( i * ( cmplx + 1 ) + j ); // top left point on square
					ushort p1 = (ushort)( i * ( cmplx + 1 ) + j + 1 ); // top right
					ushort p2 = (ushort)( ( i + 1 ) * ( cmplx + 1 ) + j ); // bottom left
					ushort p3 = (ushort)( ( i + 1 ) * ( cmplx + 1 ) + j + 1 ); // bottom right

					// Split Square Grid element into 2 adjacent triangles.
					idxBuf[ i, j, 0 ] = p2;
					idxBuf[ i, j, 1 ] = p1;
					idxBuf[ i, j, 2 ] = p0; // top-left triangle
					idxBuf[ i, j, 3 ] = p2;
					idxBuf[ i, j, 4 ] = p3;
					idxBuf[ i, j, 5 ] = p1; // bottom-right triangle
				}
			}
			// Copy Index Buffer to the Hardware Index Buffer
			HardwareIndexBuffer hdwrIdxBuf = HwBufMgr.CreateIndexBuffer( IndexType.Size16, 3 * numFaces, BufferUsage.StaticWriteOnly, true );
			hdwrIdxBuf.WriteData( 0, numFaces * 3 * 2, idxBuf, true );

			// Set index buffer for this submesh
			subMesh.indexData.indexBuffer = hdwrIdxBuf;
			subMesh.indexData.indexStart = 0;
			subMesh.indexData.indexCount = 3 * numFaces;

			//Prepare Vertex Position Buffers (Note: make 3, since each frame is function of previous two)
			vBufs = new Vector3[ 3 ][ , ];
			for ( int b = 0; b < 3; b++ )
			{
				vBufs[ b ] = new Vector3[ cmplx + 1, cmplx + 1 ];
				for ( int y = 0; y <= cmplx; y++ )
				{
					for ( int x = 0; x <= cmplx; x++ )
					{
						vBufs[ b ][ y, x ].x = (float)( x ) / (float)( cmplx ) * (float)size;
						vBufs[ b ][ y, x ].y = 0;
						vBufs[ b ][ y, x ].z = (float)( y ) / (float)( cmplx ) * (float)size;
					}
				}
			}

			curBufNum = 0;
			vBuf = vBufs[ curBufNum ];
			posVBuf.WriteData( 0, posVBuf.Size, vBufs[ 0 ], true );

			AxisAlignedBox meshBounds = new AxisAlignedBox( new Vector3( 0, 0, 0 ), new Vector3( size, 0, size ) );
			mesh.BoundingBox = meshBounds;  //	mesh->_setBounds(meshBounds); // najak: can't find _setBounds()

			mesh.Load();
			mesh.Touch();

		} // end WaterMesh Constructor