Commit Description:
Various UI improvements.
Commit Description:
Various UI improvements.
File last commit:
Show/Diff file:
Action:
FNA/src/Content/ContentReaders/ModelReader.cs
189 lines | 4.4 KiB | text/x-csharp | CSharpLexer
#region License
/* FNA - XNA4 Reimplementation for Desktop Platforms
* Copyright 2009-2020 Ethan Lee and the MonoGame Team
*
* Released under the Microsoft Public License.
* See LICENSE for details.
*/
#endregion
#region Using Statements
using System.Collections.Generic;
using Microsoft.Xna.Framework.Graphics;
#endregion
namespace Microsoft.Xna.Framework.Content
{
internal class ModelReader : ContentTypeReader<Model>
{
#region Public Constructor
public ModelReader()
{
}
#endregion
#region Private Bone Helper Method
private static int ReadBoneReference(ContentReader reader, uint boneCount)
{
uint boneId;
// Read the bone ID, which may be encoded as either an 8 or 32 bit value.
if (boneCount < 255)
{
boneId = reader.ReadByte();
}
else
{
boneId = reader.ReadUInt32();
}
if (boneId != 0)
{
return (int) (boneId - 1);
}
return -1;
}
#endregion
#region Protected Read Method
protected internal override Model Read(ContentReader reader, Model existingInstance)
{
// Read the bone names and transforms.
uint boneCount = reader.ReadUInt32();
List<ModelBone> bones = new List<ModelBone>((int) boneCount);
for (uint i = 0; i < boneCount; i += 1)
{
string name = reader.ReadObject<string>();
Matrix matrix = reader.ReadMatrix();
ModelBone bone = new ModelBone {
Transform = matrix,
Index = (int) i,
Name = name
};
bones.Add(bone);
}
// Read the bone hierarchy.
for (int i = 0; i < boneCount; i += 1)
{
ModelBone bone = bones[i];
// Read the parent bone reference.
int parentIndex = ReadBoneReference(reader, boneCount);
if (parentIndex != -1)
{
bone.Parent = bones[parentIndex];
}
// Read the child bone references.
uint childCount = reader.ReadUInt32();
if (childCount != 0)
{
for (uint j = 0; j < childCount; j += 1)
{
int childIndex = ReadBoneReference(reader, boneCount);
if (childIndex != -1)
{
bone.AddChild(bones[childIndex]);
}
}
}
}
List<ModelMesh> meshes = new List<ModelMesh>();
// Read the mesh data.
int meshCount = reader.ReadInt32();
GraphicsDevice device = reader.ContentManager.GetGraphicsDevice();
for (int i = 0; i < meshCount; i += 1)
{
string name = reader.ReadObject<string>();
int parentBoneIndex = ReadBoneReference(reader, boneCount);
BoundingSphere boundingSphere = reader.ReadBoundingSphere();
// Tag
object meshTag = reader.ReadObject<object>();
// Read the mesh part data.
int partCount = reader.ReadInt32();
List<ModelMeshPart> parts = new List<ModelMeshPart>(partCount);
for (uint j = 0; j < partCount; j += 1)
{
ModelMeshPart part;
if (existingInstance != null)
{
part = existingInstance.Meshes[i].MeshParts[(int) j];
}
else
{
part = new ModelMeshPart();
}
part.VertexOffset = reader.ReadInt32();
part.NumVertices = reader.ReadInt32();
part.StartIndex = reader.ReadInt32();
part.PrimitiveCount = reader.ReadInt32();
// Tag
part.Tag = reader.ReadObject<object>();
parts.Add(part);
int jj = (int) j;
reader.ReadSharedResource<VertexBuffer>(
delegate (VertexBuffer v)
{
parts[jj].VertexBuffer = v;
}
);
reader.ReadSharedResource<IndexBuffer>(
delegate (IndexBuffer v)
{
parts[jj].IndexBuffer = v;
}
);
reader.ReadSharedResource<Effect>(
delegate (Effect v)
{
parts[jj].Effect = v;
}
);
}
if (existingInstance != null)
{
continue;
}
ModelMesh mesh = new ModelMesh(device, parts);
mesh.Tag = meshTag;
mesh.Name = name;
mesh.ParentBone = bones[parentBoneIndex];
mesh.ParentBone.AddMesh(mesh);
mesh.BoundingSphere = boundingSphere;
meshes.Add(mesh);
}
if (existingInstance != null)
{
// Read past remaining data and return existing instance
ReadBoneReference(reader, boneCount);
reader.ReadObject<object>();
return existingInstance;
}
// Read the final pieces of model data.
int rootBoneIndex = ReadBoneReference(reader, boneCount);
Model model = new Model(device, bones, meshes);
model.Root = bones[rootBoneIndex];
model.BuildHierarchy();
// Tag?
model.Tag = reader.ReadObject<object>();
return model;
}
#endregion
}
}