private void _loadManual( Mesh mesh, MeshBuildParams mbp )
{
SubMesh subMesh = mesh.CreateSubMesh();
// Set up vertex data
// Use a single shared buffer
mesh.SharedVertexData = new VertexData();
VertexData vertexData = mesh.SharedVertexData;
// Set up Vertex Declaration
VertexDeclaration decl = vertexData.vertexDeclaration;
int currOffset = 0;
// add position data
// We always need positions
decl.AddElement( 0, currOffset, VertexElementType.Float3, VertexElementSemantic.Position );
currOffset += VertexElement.GetTypeSize( VertexElementType.Float3 );
// normals are optional
if ( mbp.Normals )
{
decl.AddElement( 0, currOffset, VertexElementType.Float3, VertexElementSemantic.Normal );
currOffset += VertexElement.GetTypeSize( VertexElementType.Float3 );
}
// add texture coords
for ( ushort i = 0; i < mbp.TexCoordSetCount; i++ )
{
decl.AddElement( 0, currOffset, VertexElementType.Float2, VertexElementSemantic.TexCoords, i );
currOffset += VertexElement.GetTypeSize( VertexElementType.Float2 );
}
vertexData.vertexCount = ( mbp.XSegments + 1 ) * ( mbp.YSegments + 1 );
// create a new vertex buffer (based on current API)
HardwareVertexBuffer vbuf = HardwareBufferManager.Instance.CreateVertexBuffer( decl.Clone( 0 ), vertexData.vertexCount, mbp.VertexBufferUsage, mbp.VertexShadowBuffer );
// get a reference to the vertex buffer binding
VertexBufferBinding binding = vertexData.vertexBufferBinding;
// bind the first vertex buffer
binding.SetBinding( 0, vbuf );
// transform the plane based on its plane def
Matrix4 translate = Matrix4.Identity;
Matrix4 transform = Matrix4.Zero;
Matrix4 rotation = Matrix4.Identity;
Matrix3 rot3x3 = Matrix3.Zero;
Vector3 xAxis, yAxis, zAxis;
zAxis = mbp.Plane.Normal;
zAxis.Normalize();
yAxis = mbp.UpVector;
yAxis.Normalize();
xAxis = yAxis.Cross( zAxis );
if ( xAxis.Length == 0 )
{
throw new AxiomException( "The up vector for a plane cannot be parallel to the planes normal." );
}
rot3x3.FromAxes( xAxis, yAxis, zAxis );
rotation = rot3x3;
// set up transform from origin
translate.Translation = mbp.Plane.Normal * -mbp.Plane.D;
transform = translate * rotation;
float xSpace = mbp.Width / mbp.XSegments;
float ySpace = mbp.Height / mbp.YSegments;
float halfWidth = mbp.Width / 2;
float halfHeight = mbp.Height / 2;
float xTexCoord = ( 1.0f * mbp.XTile ) / mbp.XSegments;
float yTexCoord = ( 1.0f * mbp.YTile ) / mbp.YSegments;
Vector3 vec = Vector3.Zero;
Vector3 min = Vector3.Zero;
Vector3 max = Vector3.Zero;
float maxSquaredLength = 0;
bool firstTime = true;
// generate vertex data
switch ( mbp.Type )
{
case MeshBuildType.Plane:
_generatePlaneVertexData( vbuf, mbp.YSegments, mbp.XSegments, xSpace, halfWidth, ySpace, halfHeight, transform, firstTime, mbp.Normals, rotation, mbp.TexCoordSetCount, xTexCoord, yTexCoord, subMesh, ref min, ref max, ref maxSquaredLength );
break;
case MeshBuildType.CurvedPlane:
_generateCurvedPlaneVertexData( vbuf, mbp.YSegments, mbp.XSegments, xSpace, halfWidth, ySpace, halfHeight, transform, firstTime, mbp.Normals, rotation, mbp.Curvature, mbp.TexCoordSetCount, xTexCoord, yTexCoord, subMesh, ref min, ref max, ref maxSquaredLength );
break;
case MeshBuildType.CurvedIllusionPlane:
_generateCurvedIllusionPlaneVertexData( vbuf, mbp.YSegments, mbp.XSegments, xSpace, halfWidth, ySpace, halfHeight, transform, firstTime, mbp.Normals, mbp.Orientation, mbp.Curvature, xTexCoord, yTexCoord, mbp.TexCoordSetCount, ref min, ref max, ref maxSquaredLength );
break;
default:
throw new Exception( "" );
}
// generate face list
_tesselate2DMesh( subMesh, mbp.XSegments + 1, mbp.YSegments + 1, false, mbp.IndexBufferUsage, mbp.IndexShadowBuffer );
// generate bounds for the mesh
mesh.BoundingBox = new AxisAlignedBox( min, max );
mesh.BoundingSphereRadius = Utility.Sqrt( maxSquaredLength );
}