📄 meshloader.cs
字号:
"Invalid number of attribute ranges: {0}",
numberAttrRanges));
// determine number of index bytes and verify Is16BitIndices
if(is16BitIndices == 1)
bytesIndices = numberIndices*2;
else if(is16BitIndices == 0)
bytesIndices = numberIndices*4;
else
throw new MeshSerializationException(
String.Format(CultureInfo.InvariantCulture,
"Invalid value for is16BitIndices: {0}",
is16BitIndices));
// Managed Direct3D mobile uses different Fvf defines than
// managed Direct3D for the desktop
// when this code is linked against the desktop version
// this will convert the Fvf to match MD3DM constants
// when this code is linked against MD3DM this section will
// not have changed anything.
// determine the necessary Fvf
int sourceFormat = (int)flexibleVertexFormat;
int textureCount;
flexibleVertexFormat = VertexFormats.Position;
if((sourceFormat & md3dmFvfNormal) != 0)
flexibleVertexFormat |= VertexFormats.Normal;
if((sourceFormat & md3dmFvfDiffuse) != 0)
flexibleVertexFormat |= VertexFormats.Diffuse;
if ((sourceFormat & md3dmFvfSpecular) != 0)
flexibleVertexFormat |= VertexFormats.Specular;
// determine number of textures
textureCount = (sourceFormat &
(int)VertexFormats.TextureCountMask)
>> (int)md3dmFvfTextureCountShift;
//limit to 4 textures
if (textureCount > 4)
textureCount = 4;
// continue setting up necessary Fvf
flexibleVertexFormat |= (VertexFormats)(
textureCount << (int)VertexFormats.TextureCountShift);
int bytesVertices =
VertexInformation.GetFormatSize(flexibleVertexFormat) *
numberVertices;
// Verify none of the data regions overlap
// the material section is variable size so we can't check
// that one yet
if(! ((offsetVertex >= sizeofHeader) &&
(offsetIndices >= offsetVertex + bytesVertices) &&
(offsetAttrRange >= offsetIndices + bytesIndices) &&
(offsetMaterial >= offsetAttrRange + numberAttrRanges *
sizeofAttributeRange) &&
(stream.Length >= offsetMaterial + bytesMaterials)))
throw new MeshSerializationException(
"The data regions are not " +
"within the stream or overlap");
// create our data tables
materials = new Material[numberMaterials];
textures = new string[numberMaterials];
attributeRanges = new AttributeRange[numberAttrRanges];
attributeTable = new int[numberIndices / 3];
// move to the attribute range section, propagate up
// any exception
stream.Seek(offsetAttrRange, SeekOrigin.Begin);
// parse attribute ranges
for (int i = 0; i < numberAttrRanges; i++)
{
int attribId;
int faceStart;
int faceCount;
int vertexStart;
int vertexCount;
// read in the attribute range data
stream.Read(rgb, 0, sizeofAttributeRange);
attribId = BitConverter.ToInt32(rgb, 0);
faceStart = BitConverter.ToInt32(rgb, 4);
faceCount = BitConverter.ToInt32(rgb, 8);
vertexStart = BitConverter.ToInt32(rgb, 12);
vertexCount = BitConverter.ToInt32(rgb, 16);
// verify the data
if( (vertexStart < 0 || vertexCount < 0 ||
vertexStart + vertexCount > numberVertices) ||
(faceStart < 0 || faceCount < 0 ||
(faceStart + faceCount)*3 > numberIndices))
throw new ApplicationException(
"Invalid attribute range");
// store the validated data
attributeRanges[i].AttributeId = attribId;
attributeRanges[i].FaceStart = faceStart;
attributeRanges[i].FaceCount = faceCount;
attributeRanges[i].VertexStart = vertexStart;
attributeRanges[i].VertexCount = vertexCount;
for (int j = faceStart; j < faceStart + faceCount; j++)
attributeTable[j] = attribId;
}
// move to the material section
stream.Seek(offsetMaterial, SeekOrigin.Begin);
// parse materials
for (int i = 0; i < numberMaterials; i++)
{
int cbTexture;
// verify that we aren't reading past the end of the stream
// its possible an invalid filename length the
if(stream.Position + sizeofMaterial > stream.Length)
throw new MeshSerializationException(
"Material data region is" +
" corrupt");
// read in the material color data
stream.Read(rgb, 0, sizeofMaterial);
materials[i].DiffuseColor = new ColorValue(
BitConverter.ToSingle(rgb, 0),
BitConverter.ToSingle(rgb, 4),
BitConverter.ToSingle(rgb, 8),
BitConverter.ToSingle(rgb, 12));
materials[i].AmbientColor = new ColorValue(
BitConverter.ToSingle(rgb, 16),
BitConverter.ToSingle(rgb, 20),
BitConverter.ToSingle(rgb, 24),
BitConverter.ToSingle(rgb, 28));
materials[i].SpecularColor = new ColorValue(
BitConverter.ToSingle(rgb, 32),
BitConverter.ToSingle(rgb, 36),
BitConverter.ToSingle(rgb, 40),
BitConverter.ToSingle(rgb, 44));
materials[i].SpecularSharpness =
BitConverter.ToSingle(rgb, 48);
// read in the size of the texture filename
cbTexture = BitConverter.ToInt32(rgb, 52);
// verify that the texture filename has a valid length
if (cbTexture < 0 || stream.Position + cbTexture >
stream.Length)
throw new MeshSerializationException(
"Material data region is corrupt");
// read the texture filename
if (cbTexture > 0)
{
stream.Read(rgb, 0, cbTexture);
textures[i] = Encoding.Unicode.GetString(rgb, 0,
cbTexture);
}
}
// create data buffers
rgbIb = new byte[bytesIndices];
rgbVb = new byte[bytesVertices];
// read in the index data
stream.Seek(offsetIndices, SeekOrigin.Begin);
stream.Read(rgbIb, 0, rgbIb.Length);
// read in the vertex data
stream.Seek(offsetVertex, SeekOrigin.Begin);
stream.Read(rgbVb, 0, rgbVb.Length);
// set the use 32 bit flag appropriately
flags = (flags & ~(MeshFlags.Use32Bit)) |
((is16BitIndices == 0) ? MeshFlags.Use32Bit : 0);
// create a new empty mesh
meshRet = new Mesh(numberIndices / 3, numberVertices,
flags, flexibleVertexFormat, device);
try
{
// create the index and vertex buffer
vb = meshRet.VertexBuffer;
ib = meshRet.IndexBuffer;
// write the vertex data
vb.Lock(0, bytesVertices, LockFlags.None).Write(rgbVb, 0,
bytesVertices);
vb.Unlock();
// write the index data
ib.Lock(0, rgbIb.Length, LockFlags.None).Write(rgbIb, 0,
rgbIb.Length);
ib.Unlock();
// set the attributes
meshRet.LockAttributeBuffer(LockFlags.None);
meshRet.UnlockAttributeBuffer(attributeTable);
meshRet.SetAttributeTable(attributeRanges);
}
catch (DirectXException e)
{
// release the mesh if anything went wrong
meshRet.Dispose();
meshRet = null;
throw e;
}
return(meshRet);
}
/// <summary>
/// Saves a mesh to the custom serialized format
/// </summary>
/// <param name="stream">The stream to which to serialize</param>
/// <param name="mesh">The mesh to be serialized</param>
/// <param name="materials">The materials for subparts of the mesh
/// </param>
/// <param name="textures">The filenames for the textures on
/// subparts of the mesh</param>
public static void SaveMesh(Stream stream, Mesh mesh,
Material [] materials, string [] textures)
{
int flexibleVertexFormat;
int numberVertices;
byte [] vertices;
int numberIndices;
byte [] indices;
AttributeRange [] attributeRanges;
VertexFormats sourceVertexFormat;
VertexFormats sourceFormat;
IDisposable tempMesh;
tempMesh = null;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -