Jump to content
  • Advertisement
Sign in to follow this  
Spa8nky

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

This topic is 2991 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];

mesh.VertexBuffer.GetData<Vector3>(
meshPart.StreamOffset + meshPart.BaseVertex * meshPart.VertexStride,
a,
0,
meshPart.NumVertices,
meshPart.VertexStride
);

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

vertices.AddRange(a);

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];

mesh.IndexBuffer.GetData<short>(
meshPart.StartIndex * 2,
s,
0,
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);
}
else
{
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];
model.CopyAbsoluteBoneTransformsTo(modelTransforms);
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
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

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

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!