Mesh and Resource Manager

Started by
6 comments, last by Schrompf 14 years, 11 months ago
I have a Mesh class and inherits the resource. I also have a resource manager that will handle the mesh, script and material resources. But my problem lies in the mesh class. It only support md2 file right now but I want to support other format also like 3ds, md3 and x formats. So I need to write a new mesh class. I have an idea right now. Here's how it looks like.

class Mesh : public Resource
{
public:
Mesh( char *name, char *path ) :  Resource< Mesh >( name, path )
{}
private:
//Data

};

class AnimatedMeshMD2 : public Mesh
{
public:
AnimatedMeshMD2();
void	SetAnim( int type );

private:
void	Interpolate( vector3d *vertices );
MD2	header;


};

class AnimatedMeshMD3 : public Mesh
{

};

class AnimatedMesh3DS : public Mesh
{

};


What do you think? Is it fine? I never tested it yet. Can anyone here help me design my class.
Advertisement
Your question is about serialization, not meshes.

A mesh is a mesh. It has vertices and other data, but it doesn't care where it comes from. Unless you introduce this abstraction, you will need to write one renderer per mesh type.

A useful and simple way to solve this problem is via factory. Define your mesh once:
struct Mesh : Resource<Mesh> {  std::vector<vector3d> vertices;  size_t m, n;  // anything else};
Mesh class knows nothing at all about different formats, about headers or file structure. It holds only the data needed to render the mesh.

Mesh class may be tied to renderer, so that it creates vertex buffers or similar structures, and it may include rendering code, but it cannot be tied to specific file format if multiple formats are to be supported.

Then, provide a way to create such mesh from any source:
Mesh * loadMesh(const char * path) {  if (isMD2(path)) {    return loadMD2Mesh(path);  }  if (isMD3(path)) {    return loadMD3Mesh(path);  }  if (isX(path)) {    return loadXMesh(path);  }  return NULL; // unknown};


Then implement the loadXXXXMesh() functions to open the file, load the vertices and other data, and put it in common mesh.

The reason different formats exist is so that the data on disk can be stored in such way that it reflects application's internal data structures.
Why not something like this:

class Mesh : public Resource{public:Mesh();virtual ~Mesh();float GetSize();//whatevervirtual bool SetAnim(int id) = 0;virtual bool Load(const char *filename) = 0;protected://basic mesh variables here,//like vertices etc...};class MeshMD2 : public Mesh{public:MeshMD2();~MeshMD2();bool SetAnim(int id);bool Load(const char *filename);};class MeshMD3 : public Mesh{public:MeshMD3();~MeshMD3();bool SetAnim(int id)bool Load(const char *filename);};


This way you can store the Mesh* variables in a manager, and call virtual functions to acchieve anything you want. Just add a constant type return if you want to know which kind of meshes are in your manager.
Thanks for the help guys but I'm having a big problem with my resource manager. My resource manager is the same with this

I don't know on where to call the MeshMD2/MeshMD3 classes?

Mesh::Mesh( char *name, char *path ) :  Resource< Mesh >( name, path ){ }SceneManager::SceneManager(){m_meshManager = new ResourceManager< Mesh >;}void SceneManager::LoadScene( char *name, char *path ){	Script *script = new Script( name, path );        //This one calls the Mesh constructor already so I need to do everything that it needs to do on the Mesh constructor already.	m_mesh = GetMeshManager()->Add( script->GetStringData( "mesh" ), script->GetStringData( "mesh_path" ) ); // Mesh *m_mesh;       /*I'm thinking to have a m_md2Manager = new ResourceManager< MD2 >;m_md2Manager = new ResourceManager< MD3 >; for each format but that would be really messy. */}


I want to have separate for each format in class. I know that the easiest solution is to do everything on the mesh constructor already but I think it would be messy and that's not my plan.

Mesh::Mesh( char *name, char *path ) :  Resource< Mesh >( name, path ){ if md2 loadmd2() else if md3 loadmd3() and so on....}


I've used the resource manager on my script, and materials so far but this mesh class really gives me a headache.

m3rk
you do not even want everything to happen in the constructor. because if you do, how do you let the creator of the mesh know loading of the mesh file failed? it would be better to create a initialize-function of some sort with a boolean or enumerated return type. furthermore, find the model file format before you create the mesh. this will enable you to create just one manager for all types of meshes, by storing the mesh* types.
good luck with your managers and meshes, they are a pain ;-)
Anything else?
Ok, no one is replying here. So, I think I'll just do the one that looks right. lol

m3rk
Separate loading from data. Your mesh contains always the same, equal what format it was loaded from. You might want to separate mesh classes for different purposes, maybe instance collections, skinned or static meshes... but you definitely don't want to separate by source file format.
----------
Gonna try that "Indie" stuff I keep hearing about. Let's start with Splatter.

This topic is closed to new replies.

Advertisement