Jump to content
  • Advertisement
Sign in to follow this  

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

This topic is 3072 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

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!