XNA Creators Club Online
Page 1 of 1 (6 items)
Sort Posts: Previous Next

Model Instancing

Last post 09-09-2008 1:07 AM by Roonda. 5 replies.
  • 09-07-2008 10:11 PM

    Model Instancing

    I'm not talking about the InstancedModel technique here.

    I have a problem overriding my model's effects as per several good examples out there.
    I have a class that contains my model data; this class has a .Load() method that loads the model from the content pipeline, storing it as a member variable, then overriding the effect with a custom effect for use later on in the Draw() method.

    A have several instances of this class in an ArrayList and I call each of the Load() methods for the classes. This performs the following code:

    1     public class ModelContainer  
    2     {          
    3         Model model;  
    4  
    5         public void Load(ContentManager content, string path)  
    6         {              
    7             model = content.Load<Model>(path);  
    8  
    9                 //Some code here to load the custom effect, and set up my meshTextures Array.  
    10  
    11                 //Now to store the old texture and override the old Effect.  
    12                 int texIndex = 0;  
    13                 foreach (ModelMesh mesh in model.Meshes)  
    14                 {  
    15                     foreach (ModelMeshPart meshPart in mesh.MeshParts)  
    16                     {  
    17                         BasicEffect tmpBEffect = (BasicEffect)meshPart.Effect;  
    18                         meshTextures[texIndex] = tmpBEffect.Texture;  
    19                         meshPart.Effect = customEffect.Clone(graphics.GraphicsDevice);  
    20                         texIndex++;  
    21                     }  
    22                 }  
    23          }  
    24               
    25      } 

    The problem arises when the array contains two instances of the same model.
    My loading the content from the content pipeline, it seems that the changes I make to the Effect object in each meshpart is somehow cached. The next time I load the model, the effect is already set (even though it's a new instance of my class) thus the code to cast Effect as BasicEffect crashes (you can't do this) - Line 17 above.

    I know there's an obvious optimisation to not load the same model for every instance, but I want to understand this behaviour of Content.Load<T>() and if this a common problem to solve with a standard piece of game code.
    Any suggestions here?

  • 09-08-2008 6:13 AM In reply to

    Re: Model Instancing

    I believe the first time it is loaded, you get a reference to it.  If you load the same model again, you just get a reference to the original load of it (only one copy of the model exists).  So, anything you do to model 1 will be the same for each instance of it,

    Best

    Byron


    ..shaders make you feel... powerful, or very very stupid.
    http://drjbn.spaces.live.com/
  • 09-08-2008 6:39 AM In reply to

    Re: Model Instancing

    Instead of typing this:

    BasicEffect tmpBEffect = (BasicEffect)meshPart.Effect;  

    Use this:

    BasicEffect tmpBEffect = meshPart.Effect as BasicEffect;

    This will attempt to convert and, if it fails, set tmpBEffect to null. So you can test if (tmpBEffect == null) before continuing to use it.

  • 09-08-2008 7:16 AM In reply to

    Re: Model Instancing

    MrLeebo:
    So you can test if (tmpBEffect == null) before continuing to use it.

    But he only casts it to a BasicEffect so he can grab the texture reference, and if the cast fails, there will be no way to get the correct texture. A better way might be to leave the MeshPart.Effect as it is and hold an array of Effects, similar to how you hold an array of textures (meshTextures). You would then need to modify the Draw to use your custom effect.

  • 09-08-2008 6:29 PM In reply to

    Re: Model Instancing

    I've actually already tried to hold the Effects in an array, but that results in the same problem.
    That is, when I come to load my 2nd instance of my model, the effect is already set to my custom one and I've lost the reference to the texture (as this is only captured and stored in the scope of the previous class).

    I think the implementation is flawed - or rather the concept I'm using. Which is why i'm here on the algorithm section.
    I've decided to go back to the drawing board on this one (urgh), and looks at extending the content processor for models. I feel that the Model class clearly isn't flexible enough for what I'm trying to do and in fact, looking at some stuff like the Custom Model processing samples, I can clearly see that this is exactly what's recommended.

     

  • 09-09-2008 1:07 AM In reply to

    Re: Model Instancing


    Deviruchi:
    when I come to load my 2nd instance of my model, the effect is already set to my custom

    I can't see how that happens unless you set the ModelMeshPart.Effect somewhere.

    I have done this myself, and it worked without a hitch. Rather than take the custom processor approach (which could also be a good way to go), I created a Material class which holds an Effect and a list of EffectParameter and value pairs. I also created a class which mirrors ModelMeshPart to hold my Material class.

    Deviruchi:
    I feel that the Model class clearly isn't flexible enough for what I'm trying to do

    I hear ya! This has been a common complaint.

Page 1 of 1 (6 items) Previous Next