fna-workbench

fna-workbench Git Source Tree


Root/src/Content/ContentReaders/ModelReader.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#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.08456s using 11 queries.