Jump to content
  • Advertisement
Sign in to follow this  
trock3155

C# Inheritance Madness

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

Hi,
I am having an issue that probably has something to do with my understanding of inheritance, and I've been wrestling with it for hours, but can't find that simple "thing" that is causing the problem. The issue is simple, really:

A method is operating differently when called explicitly than when it is called from a base array, even though I can see the proper overridden method is getting called in both situations.


I have the following class structure - WorldObject->GameObject->SkeletalObject->Player and NPC (2 classes)


I track all of my drawables in a List of GameObjects. I draw to my gbuffer by iterating through each of the objects (including NPCs and Players) and calling their Draw() method. This works great! Both players and NPCs are using the SkeletalObject Draw() method and all skeletal animations draw to the screen properly.

The problem is in a secondary draw method, StandardDraw(), that I use to draw models with custom effects (in this case shadows). It is NOT working on Player objects when called from the GameObject list, but IS working when called explicitly, while it works properly from the list for NPCs. The issue I see is my Player sporadically (rarely) at the incorrect world position in Tpose.

Now, the crazy thing is, I can SEE that the correct StandardDraw method (from SkeletalObject) is being called both from the GameObject array and explicitly, and when steeping through it the variables look the same.

Please help me figure out what is going on sad.png


Custom Effect Draw Method - Inside SkeletalObject base class. This is NOT working for my Player objects when called from a base class (GameObject) array, but does work for my NPC objects within that same array.

[source lang="csharp"]public override void StandardDraw(ref GraphicsDevice graphics, ref Effect effect)
{
Matrix[] boneTransforms = null;
if (skinnedPlayer != null)
boneTransforms = skinnedPlayer.GetSkinTransforms();
Matrix rootTransform = Matrix.Identity;
if (skinnedRootPlayer != null)
rootTransform = skinnedRootPlayer.GetCurrentTransform();
effect.CurrentTechnique = effect.Techniques["Skinned"];
foreach (ModelMesh mesh in Model.Meshes)
{
if (mesh.Name != "CollisionMesh")
{
//Draw Each ModelMeshPart
foreach (ModelMeshPart part in mesh.MeshParts)
{
if (boneTransforms != null)
SetBoneTransforms(boneTransforms, effect);
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Apply();
//Set Vertex Buffer
graphics.SetVertexBuffer(part.VertexBuffer, part.VertexOffset);
//Set Index Buffer
graphics.Indices = part.IndexBuffer;
effect.Parameters["World"].SetValue(Matrix.CreateTranslation(-offset)
* rootTransform * worldMatrix);
graphics.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0,
part.NumVertices, part.StartIndex, part.PrimitiveCount);
}
}
}
}
}[/source]



Draw method - Inside SkeletalObject base class. This works properly when called from a GameObject array for both NPC and Player)

[source lang="csharp"]public override void Draw(Matrix viewerView, Matrix viewerProjection,
float farClip)
{
Matrix[] boneTransforms = null;
if (skinnedPlayer != null)
boneTransforms = skinnedPlayer.GetSkinTransforms();
Matrix rootTransform = Matrix.Identity;
if (skinnedRootPlayer != null)
rootTransform = skinnedRootPlayer.GetCurrentTransform();
foreach (ModelMesh mesh in Model.Meshes)
{
if (mesh.Name != "CollisionMesh")
{
for (int i = 0; i < mesh.Effects.Count; i++)// (Effect effect in mesh.Effects)
{
//Console.WriteLine(mesh.Effects.Name);
mesh.Effects.CurrentTechnique = mesh.Effects.Techniques["Skinned"];
mesh.Effects.Parameters["farClip"].SetValue(farClip);
mesh.Effects.Parameters["View"].SetValue(viewerView);
mesh.Effects.Parameters["Projection"].SetValue(viewerProjection);

if (boneTransforms != null)
SetBoneTransforms(boneTransforms, mesh.Effects);
mesh.Effects.Parameters["World"].SetValue(Matrix.CreateTranslation(-offset)
* rootTransform * worldMatrix);
//effect.World = Matrix.CreateTranslation(-offset) * rootTransform * worldMatrix ;
//effect.SpecularColor = Vector3.Zero;
}
mesh.Draw();
}
}
}[/source]

Calling method
[source lang="csharp"] public void StandardDraw(GameTime gameTime, ref Effect effect)
{
terrain.StandardDraw(ref graphics, ref effect);

foreach (GameObject gameObject in gameObjects)
{
if (gameObject is Player)
gameObject.isDrawable = true;
if (gameObject.isDrawable)
gameObject.StandardDraw(ref graphics, ref effect);
}
Player1.StandardDraw(ref graphics, ref effect);
}[/source]

Share this post


Link to post
Share on other sites
Advertisement
hi,
try this :
insert this code
[source lang="csharp"]effect.CommitChanges();[/source]
after
[source lang="csharp"]effect.Parameters["World"].SetValue(Matrix.CreateTranslation(-offset)
* rootTransform * worldMatrix);
[/source]

Share this post


Link to post
Share on other sites
Somehow in writing masses of XNA code, I think I missed that EffectPass.Apply() (which in XNA4 encompasses Effect.CommitChanges()) must always be called AFTER the Effect Parameters are set.

In my case, my Player object was being drawn before the other NPCs, and thus it's Effect settings were applying to the NPCs that followed after.

I will try this tonight, but I expect it should work. Thanks a ton! Edited by trock

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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!