fna-workbench

fna-workbench Git Source Tree


Root/src/Content/ContentReaders/ModelReader.cs

#region License
/* FNA - XNA4 Reimplementation for Desktop Platforms
 * Copyright 2009-2016 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();
 
            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(reader.GraphicsDevice, 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(reader.GraphicsDevice, bones, meshes);
            model.Root = bones[rootBoneIndex];
            model.BuildHierarchy();
            // Tag?
            model.Tag = reader.ReadObject<object>();
            return model;
        }
 
        #endregion
    }
}

Archive Download this file

Branches

Number of commits:
Page rendered in 0.25111s using 11 queries.