Sign in to follow this  
Teldan

[C#] How to copy/clone a (mesh) object? (performance problem)

Recommended Posts

Hi, i have the following performance problem: Imagine a little asteroid field generator. For storing the asteroids I'm using a List<zype>. Now i'm filling this List with new asteroid objects all the time. In this objects all data are stored for a single asteroid: mesh, texture, position and other relevant data. Now everytime when I generate a new asteroid and adding it to the list the game makes a short pause while loading the mesh and texture file. But every asteroid uses the exact same files. So it would be very more perfomant if I could create one object for all asteroid so that the PC does not have to load the files over and over again. So i tried to create 1 object and adding it to the list with altered parameters. But that does not work because the added object seems to be only an reference to that single object. So i have a list full of references to that single object and only one asteroid is rendered (because there is only one object at all). Now i'm looking for a more perfomant way to implement that asteroid field. My idea would be a way to clone the single object so that the pc has only to copy the data in memory instead loading all data from the harddisc. But I haven't found such a function up to now. Has anybody an idea how I can implement that asteroid field with better performance? Thanks in advance.

Share this post


Link to post
Share on other sites
So all the asteroids use the same mesh? In that case you could make the mesh static and load it with the first asteroid:


public class Asteroid
{

private static Direct3D.Mesh Mesh = null;

public Asteroid( /*parameters*/ )
{
if( Mesh == null )
{
Mesh = new Mesh( /*parameters*/ );
}
// other stuff
return;
}

}



Share this post


Link to post
Share on other sites
The problem is that the same class is used for other objects too (like spaceships). So not every instance of that class uses the same mesh.

Share this post


Link to post
Share on other sites
I don't see why you have to have a copy for each and every asteroid. You should be able to store the location/rotation for each and then perform operations on the same object. It should be this way for all objects where you store once and instantiate many time.

I realize that doesn't answer the actual question of copying an object. You could use something similar to a factory method. A factory method does nothing more than return a "new" instance of the same type. A copy method would take that same operation one step further by passing all of it's contents to the new object. This could be done using a copy constructor which accepts all the necessary parameters.


class Asteroid :public Mesh {
public:
Asteroid (/*initialization data here*/);

Mesh Copy ();
};

Asteroid::Asteroid (/*initialization data here*/) {
//Initialization;
}

Mesh Asteroid::Copy () {
return new Asteroid (/*Pass this objects data*/);
}



So, Copy() for the source object gets called and that creates the destination object and calls it's copy constructor.

Share this post


Link to post
Share on other sites
Quote:
Original post by coderx75
I don't see why you have to have a copy for each and every asteroid. You should be able to store the location/rotation for each and then perform operations on the same object. It should be this way for all objects where you store once and instantiate many time.


Exacl that is what I have tried with the following code

private void AddAsteroid()
{
....
if (asteroid == null)
{
asteroid = new gModel("asteroid.x", "asteroid.bmp", new Vector3(x, y, 0.0f), 0.005f);
}
else
{
asteroid.Position = new Vector3(x, y, 0.0f);
}
asteroidList.Add(asteroid);
}

But with this i only get a list full of references to the one asteroid object and the game renders only one asteroid at all.

Share this post


Link to post
Share on other sites
You shouldn't have a separate gModel with its own mesh for every asteroid! Have one asteroid mesh that's shared by all asteroids and draw the same mesh with different transformations for each asteroid object.

One way to do this is to use a Dictionary<string, Mesh> to hold your meshes. In your gModel class, keep a static dictionary with all the meshes. In the constructor, check if the mesh's name ("asteroid.x") is in the dictionary. If it is, use a reference to the mesh object that's already loaded. If it isn't, load it and add it to the dictionary. That way, you only load each mesh once.

Share this post


Link to post
Share on other sites
Quote:
Original post by Teldan
But with this i only get a list full of references to the one asteroid object and the game renders only one asteroid at all.

Right, if you want to copy an object, the code I showed you would work, but as I was saying that's not what you want to be doing in this situation. You have your asteroid, mesh and even your bitmap all tightly coupled. You want to break this relationship.

Seperate the data that is specific to an individual asteroid from the mesh that is shared by all asteroids. Each individual asteroid would hold a pointer to the mesh it uses rather than a whole new instantiation.

Share this post


Link to post
Share on other sites
Take a look at Chad's implementation of Mesh, and MeshInstance.

http://www.c-unit.com/tutorials/mdirectx/?t=40

He uses a separate class for a MeshInstance so you can re-use the same mesh and save memory.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this