• Advertisement
Sign in to follow this  

[C#] Looking to go object-orientated with this class and would like some advice.

This topic is 2811 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

When models are loaded I store any information about them in a ModelData class:

public class ModelData
private string effectName;
private CD_AABB minAABB;
private CD_BoundingSphere minBoundingSphere;
private Model model;
private List<Texture2D> originalTextures;
private Matrix[] originalTransforms;
private int texture; // Index of texture list (useful for batch drawing by texture)
private Matrix[] transforms;
private List<CD_Triangle> triangles; // Model triangles in local space coordinates
private Matrix worldTransform;

At the moment all the data is calculated by calling the GetModel method which then returns the processed model:

public class ModelManager
Game1 game;

// Cache of ModelManagerModel classes (and parameters) which can be found using their Model Name (assetName)
Dictionary<string, ModelData> modelCache = new Dictionary<string, ModelData>();

public ModelManager(Game1 game)
this.game = game;

private void ExtractData(ref Model model, ref List<Texture2D> originalTextures, ref List<CD_Triangle> triangles, ref List<Vector3> vertices)
for (int i = 0; i < model.Meshes.Count; ++i)
Matrix m = GetAbsoluteTransform(model.Meshes.ParentBone);
ExtractModelMeshData(model.Meshes, ref m, ref originalTextures, ref triangles, ref vertices);

private void ExtractModelMeshData(ModelMesh mesh, ref Matrix transform, ref List<Texture2D> originalTextures, ref List<CD_Triangle> triangles, ref List<Vector3> vertices)
foreach (ModelMeshPart meshPart in mesh.MeshParts)
// Allow model to use custom effects
BasicEffect oldEffect = meshPart.Effect as BasicEffect; // Invalid Cast Exception comes from loading the exact same model more than once

if (oldEffect != null && oldEffect.Texture != null) // != null stops Invalid Cast Exception
originalTextures.Add(oldEffect.Texture); // Add model textures to texture list

meshPart.Effect = game.Effects["Default"].Clone(game.graphics_Device);

// Extract the vertices from the mesh parts
ExtractModelMeshPartData(mesh, meshPart, ref transform, ref triangles, ref vertices);

private void ExtractModelMeshPartData(ModelMesh mesh, ModelMeshPart meshPart, ref Matrix transform, ref List<CD_Triangle> triangles, ref List<Vector3> vertices)
int offset = vertices.Count;
Vector3[] a = new Vector3[meshPart.NumVertices];

meshPart.StreamOffset + meshPart.BaseVertex * meshPart.VertexStride,

for (int i = 0; i != a.Length; ++i)
a = Vector3.Transform(a, transform);


if (mesh.IndexBuffer.IndexElementSize != IndexElementSize.SixteenBits)
throw new Exception(String.Format("Model uses 32-bit indices, which are not supported."));

// 3 indices per triangle
short[] s = new short[meshPart.PrimitiveCount * 3];

meshPart.StartIndex * 2,
meshPart.PrimitiveCount * 3

for (int i = 0; i != meshPart.PrimitiveCount; ++i)
// Indices for one triangle primitive
int i0 = s[i * 3 + 0] + offset;
int i1 = s[i * 3 + 1] + offset;
int i2 = s[i * 3 + 2] + offset;

// Model triangles are wound CW make triangle winding CCW
triangles.Add(new CD_Triangle(vertices[i0], vertices[i2], vertices[i1]));

private Matrix GetAbsoluteTransform(ModelBone bone)
return bone == null ? Matrix.Identity : bone.Transform * GetAbsoluteTransform(bone.Parent);

public ModelData GetModel(string assetName)
// Instance of Model and its parameters
ModelData result = null;

// If the Dictionary already contains the model name then don't run the following
if (!modelCache.ContainsKey(assetName))
result = LoadModel(assetName);
modelCache.Add(assetName, result);
result = modelCache[assetName];

return result;

// Clone the meshes to apply new textures to them from the _Default.fx file (this is because the model comes with the BasicEffect.fx by default)
private ModelData LoadModel(string assetName)
Model model = game.Content.Load<Model>(assetName);
Matrix[] transforms = TransformModel(model);
List<Texture2D> originalTextures = new List<Texture2D>(16);
List<CD_Triangle> triangles = new List<CD_Triangle>();
List<Vector3> vertices = new List<Vector3>();

// Extract all the required remaining data from the model
ExtractData(ref model, ref originalTextures, ref triangles, ref vertices);

// Create minimum bounding box from model vertices
CD_AABB minAABB = CD_AABB.CreateFromPoints(vertices.ToArray());

return new ModelData(minAABB, model, originalTextures, transforms, triangles);

private Matrix[] TransformModel(Model model)
Matrix[] modelTransforms = new Matrix[model.Bones.Count];
return modelTransforms;

As this is not object-orientated in the slightest, I would like some help in breaking this down and making it more so.

Should I start by creating a new ModelData class:

ModelData myModel = new ModelData()

then getting the wanted parameters using separate methods:

myModel.OriginalTextures = ModelUtils.ExtractOriginalTextures();
myModel.OriginalTransforms = ModelUtils.TransformModel(model);

or should I approach this in an entirely different manner?

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement