Model drawing

Jan 22, 2010 at 1:18 AM
Edited Jan 22, 2010 at 1:24 AM

Hi!

First of all, I just have to say extremely good work with this engine, it really is awsome, and saves me alot of time.
So far It's been very easy to work with, and I constantly find nice and helpful features ;)

 

But i do have issues with drawing some of my models that i'd hope someone could help me with.

 

1.

When trying to draw my "Dwarf", (the model is taken from DirectX sample models), The textures get all "see throw", and turned backwards. I do believe its becuse iam using wrong culling mode.

But how do i go about to change this?


My guess is that i should use this statement just before drawing it, 

               Ox.Engine.Utility.GraphicsDeviceExtension.BeginFaceMode(Engine.GraphicsDevice, Ox.Engine.GeometryNamespace.FaceMode.BackFaces);
Ox.Engine.Utility.GraphicsDeviceExtension.BeginFaceMode(Engine.GraphicsDevice, Ox.Engine.GeometryNamespace.FaceMode.BackFaces);
but how do I override the draw function from a ComponentScript?

 

2.

I also have some models with bone issues, but when trying this:

 GetSurface(Model.Meshes.Count, Model.Bones.Count);

I get the following error:
"BasicModel is missing a surface for a ModelMeshPart" 

I've tried with different models, so my guess is that iam missing/doing something wrong here :))

 

3.
What is the difference between "StandardModel" and "BasicModel"? 

 

//Torshall

 

 

 

Coordinator
Jan 22, 2010 at 1:43 AM

hi!

1 - Scene components don't actually do any drawing. Instead, they delegate drawing to their surface subcomponents. What you would do is either set the FaceMode property via the property grid in the editor, or set it by writing something like Component.GetSurface(?, ?).FaceMode = DrawMode.Something in the script's constructor.

2 - Try this - GetSurface(Model.Meshes.Count - 1, Model.Bones.Count - 1); ICollection.Count is always one higher than the last index.

3 - StandardModel uses Ox's slightly more advanced drawing techniques. BasicModel just uses XNA's BasicEffect drawing technique.

cheers~~!

Coordinator
Jan 22, 2010 at 1:48 AM

Oh, actually, don't use Model.Bones.Count - 1... Bones have nothing to do with surfaces :)

Instead, just read up on XNA's Model documentation to figure out how to work with it in detail. I think you want to head more in the direction of Mode.Bones.Something or maybe Mode.Root.Something.

Good luck!

Coordinator
Jan 22, 2010 at 11:10 AM

hi again!

I used your nice praise in the project description. If you mind for any reason, just let me know!

- bryan

Jan 22, 2010 at 1:35 PM

Hi again, and thanks for helping me out :)

 

Hehe, yeah, i noticed the description update, I dont mind at all :)

 

1.
I got the culling to work by doing this;

int count = Component.Model.Meshes.Count;
  
  for (int i = 0; i < count; i++)
      {
         Component.GetSurface(i,Component.Model.Root.Index).FaceMode = Ox.Engine.GeometryNamespace.FaceMode.AllFaces;
      }

 

But I got the feeling that iam using Root.Index wrong, but atleast it works for now! :)

 

2.
However, i still cant figure out how to draw my submeshes correctly
Normally, in my own engine, i would do something similar to this in my draw function:


Matrix[] transforms = new Matrix[Model.Bones.Count]; Model.CopyAbsoluteBoneTransformsTo(transforms); foreach (ModelMesh mesh in Model.Meshes) { foreach (BasicEffect effect in mesh.Effects) { effect.Begin(); effect.EnableDefaultLighting(); effect.World = transforms[mesh.ParentBone.Index] * localMatrix; effect.View = mGame.GetGameManager.GetCamera.GetViewMatrix(); effect.Projection = mGame.GetGameManager.GetCamera.GetProjectionMatrix(); effect.End(); } }
So all the submeshes ends up where they are supposed to correctly.
But how would i go about to do this in OX?


Coordinator
Jan 22, 2010 at 1:38 PM

thx :)

2 - This type of drawing isn't currently enabled in Ox. Give me a day and I'll see if I can ratchet it in without disturbing anything else.

cheers!

- b

Coordinator
Jan 22, 2010 at 1:55 PM

still thinking about what I can do, but, just as information, Ox currently expects animation to be done either with the AnimatedModel or with a new user-defined component.

on the other hand, I'm going to see what I can do to enable Ox to use the existing XNA bone information in the way you are (reasonably) expecting.

cheers!

- b

 

Coordinator
Jan 22, 2010 at 3:06 PM

I *think* I fixed the issue so that if your script sets the bones in various transformations, both BasicModel and StandardModel will draw them in their transformed position.

Are you currently using Ox in source form? If so, you can just pull down the latest and try your scripted animations at run-time. Otherwise, I'll just put up a new release build today or tomorrow.

Let me know :)

 

Jan 22, 2010 at 4:28 PM
Edited Jan 22, 2010 at 7:27 PM

haha, okey, thats really cool!! :)

iam currently working with the dll files, but i should be able to build new ones from the source.

Jan 22, 2010 at 5:44 PM
Edited Jan 22, 2010 at 10:48 PM

Great jobb, and thanks alot! =))
it works like a charm now after updating the dll files!

The only problem i noticed was that "autobox" function does not work as intended anymore, I think it's still calculating on the old model logic.
Or maybe I just missed to update something :)

//Torshall

 

 

 

Coordinator
Jan 23, 2010 at 1:42 AM

ah, okay, I think I can fix that too :)

thanks for your collaboration on this torshall ;)

- b

Coordinator
Jan 23, 2010 at 2:12 AM

Okay, looks like I got that sorted too. Please test this out. Keep in mind, though, that AutoBox wraps as tightly around your model as possible during its current frame of animation. You will want to increase the size of the auto box by a reasonable amount to cover places where vertices may move for the other animations.

Cheers!

Jan 23, 2010 at 2:44 PM

Hi!
Iam just glad i can help you out some some how :)

Iv'e had the time to check it out now, and again, it works without any hassle. 
Worked directly after updating the dll's 

Nicely done :))

 

If i bump into and trouble / bugs i think is related to this, i'll let you know.

 

 

 

Jan 25, 2010 at 7:15 PM

Hi again!
I beleive i stumbled across a new bugg related to this.

When adding DirectionalLightWithShadows to the scene, when i also have models, i get the following error:
at Engine.Draw() in program.cs

System.IndexOutOfRangeException was unhandled
  Message="Indexet låg utanför gränserna för matrisen."
  Source="Ox.Scene"
  StackTrace:
       vid Ox.Scene.Component.StandardModel.GetBoneAbsolute(Int32 parentBoneIndex, Matrix& boneAbsolute)
       vid Ox.Scene.Component.LightReceiverSurface.PopulateEffectTransform(ICamera camera, LightReceiverEffect lrEffect)
       vid Ox.Scene.Component.LightReceiverSurface.PopulateEffectHook(GameTime gameTime, ICamera camera, DrawMode drawMode)
       vid Ox.Scene.Component.ShadowReceiverSurface.PopulateEffectHook(GameTime gameTime, ICamera camera, DrawMode drawMode)
       vid Ox.Scene.Component.StandardSurface.PopulateEffect(GameTime gameTime, ICamera camera, DrawMode drawMode)
       vid Ox.Scene.Component.StandardSurface.DrawHook(GameTime gameTime, ICamera camera, DrawMode drawMode)
       vid Ox.Scene.Surface.BaseSurface`1.Draw(GameTime gameTime, ICamera camera, DrawMode drawMode)
       vid Ox.Scene.Shadow.DirectionalShadow.DrawShadowMap(GameTime gameTime)
       vid Ox.Scene.Shadow.DirectionalShadow.Draw(GameTime gameTime)
       vid Ox.Scene.Light.DirectionalLight.DrawShadow(GameTime gameTime, ICamera camera)
       vid Ox.Scene.SceneSystem.DrawShadows(GameTime gameTime, ICamera camera)
       vid Ox.Scene.SceneSystem.PreDraw(GameTime gameTime, ICamera camera)
       vid Ox.DefaultEngineNamespace.DefaultEngine.DrawHook(GameTime gameTime)
       vid Ox.Engine.OxEngine.Draw(GameTime gameTime)
       vid OXGameTemplate.GameCore.Draw(GameTime gameTime) i F:\projekt\XNA\OXGE\OXGameTemplate\OXGameTemplate\GameCore.cs:rad 123
       vid Microsoft.Xna.Framework.Game.DrawFrame()
       vid Microsoft.Xna.Framework.Game.Tick()
       vid Microsoft.Xna.Framework.Game.HostIdle(Object sender, EventArgs e)
       vid Microsoft.Xna.Framework.GameHost.OnIdle()
       vid Microsoft.Xna.Framework.WindowsGameHost.ApplicationIdle(Object sender, EventArgs e)
       vid System.Windows.Forms.Application.ThreadContext.System.Windows.Forms.UnsafeNativeMethods.IMsoComponent.FDoIdle(Int32 grfidlef)
       vid System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
       vid System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       vid System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       vid System.Windows.Forms.Application.Run(Form mainForm)
       vid Microsoft.Xna.Framework.WindowsGameHost.Run()
       vid Microsoft.Xna.Framework.Game.Run()
       vid OXGameTemplate.GameCore.Main(String[] args) i F:\projekt\XNA\OXGE\OXGameTemplate\OXGameTemplate\GameCore.cs:rad 132
  InnerException:


All though, this problem seams to appear abit random, with some models it works, sometimes.

Any idea what might cause this?

 

//Torshall

Coordinator
Jan 25, 2010 at 7:43 PM

Ah, I think I spot the issue. Will reply when fixed!

 

Coordinator
Jan 25, 2010 at 7:50 PM

Okay, I think the issue is fixed. Let me know if otherwise!

cheers!

- b

 

Jan 25, 2010 at 8:42 PM
Edited Jan 25, 2010 at 11:03 PM

Ok, nice! will test it straight away.   :)

 


But i do have another question for you, if you don't mind.
I was searching for a way to controll my character in a "nice" (none sliding motion) way using jiglibx.

And i came across a post you made about creating a Character Physics Controller for Jiglibx a time ago.
Any chance that you had time to implente that to OX?   :)

This problem is killing me ;)

 

 

Coordinator
Jan 26, 2010 at 6:14 AM

Here's what someone came up with a while back -

using JigLibX.Collision;
using JigLibX.Geometry;
using JigLibX.Math;
using JigLibX.Physics;
using Microsoft.Xna.Framework;
using Ox.Engine;
using Ox.Engine.Component;
using Ox.Scene.Component;

namespace PsychoWard
{
    public class CharacterBody : Body
    {
        private Vector3 desiredVelocity;

        public Vector3 DesiredVelocity
        {
            get { return desiredVelocity; }
            set { desiredVelocity = value; }
        }

        public CharacterBody() : base() { }

        public override void AddExternalForces(float dt)
        {
            ClearForces();
            Vector3 deltaVel = desiredVelocity - Velocity;
            deltaVel.Y = 0.0f;
            float forceFactor = 1000.0f;
            AddBodyForce(deltaVel * Mass * dt * forceFactor);
            AddGravityToExternalForce();
        }
    }

    public class CharacterPhysics : UpdateableSubcomponent<ISceneComponent>
    {
        private readonly CollisionSkin skin;
        private readonly CharacterBody body;

        public Vector3 DesiredVelocity
        {
            get { return body.DesiredVelocity; }
            set { body.DesiredVelocity = value; }
        }

        public CharacterPhysics(IOxEngine engine, ISceneComponent parent)
            : base(engine, parent)
        {
            CreateBodyAndSkin(out body, out skin);
        }

        protected override void UpdateHook(GameTime gameTime)
        {
            base.UpdateHook(gameTime);
            Component.Position = body.Position;
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing) DestroyBody();
            base.Dispose(disposing);
        }

        private void CreateBodyAndSkin(out CharacterBody body, out CollisionSkin skin)
        {
            body = new CharacterBody();
            skin = new CollisionSkin(body);
            Capsule capsule = new Capsule(Vector3.Zero, Matrix.CreateRotationX(MathHelper.PiOver2), 1.0f, 1.0f);
            skin.AddPrimitive(capsule, (int)MaterialTable.MaterialID.NotBouncyNormal);
            body.CollisionSkin = skin;
            Vector3 com = SetMass(100.0f);
            body.MoveTo(Component.Position + com, Matrix.Identity);
            skin.ApplyLocalTransform(new Transform(-com, Matrix.Identity));
            body.SetBodyInvInertia(0.0f, 0.0f, 0.0f);
            body.EnableBody();
        }

        private void DestroyBody()
        {
            body.DisableBody();
        }

        private Vector3 SetMass(float mass)
        {
            PrimitiveProperties primitiveProperties = new PrimitiveProperties(
                PrimitiveProperties.MassDistributionEnum.Solid,
                PrimitiveProperties.MassTypeEnum.Density,
                mass);
            float junk;
            Vector3 com;
            Matrix it, itCoM;
            skin.GetMassProperties(primitiveProperties, out junk, out com, out it, out itCoM);
            body.BodyInertia = itCoM;
            body.Mass = junk;
            return com;
        }
    }
}

using JigLibX.Collision;
using JigLibX.Geometry;
using JigLibX.Math;
using JigLibX.Physics;
using Microsoft.Xna.Framework;
using Ox.Engine;
using Ox.Engine.Component;
using Ox.Scene.Component;

namespace PsychoWard
{
    public class CharacterBody : Body
    {
        private Vector3 desiredVelocity;

        public Vector3 DesiredVelocity
        {
            get { return desiredVelocity; }
            set { desiredVelocity = value; }
        }

        public CharacterBody() : base() { }

        public override void AddExternalForces(float dt)
        {
            ClearForces();
            Vector3 deltaVel = desiredVelocity - Velocity;
            deltaVel.Y = 0.0f;
            float forceFactor = 1000.0f;
            AddBodyForce(deltaVel * Mass * dt * forceFactor);
            AddGravityToExternalForce();
        }
    }

    public class CharacterPhysics : UpdateableSubcomponent<ISceneComponent>
    {
        private readonly CollisionSkin skin;
        private readonly CharacterBody body;

        public Vector3 DesiredVelocity
        {
            get { return body.DesiredVelocity; }
            set { body.DesiredVelocity = value; }
        }

        public CharacterPhysics(IOxEngine engine, ISceneComponent parent)
            : base(engine, parent)
        {
            CreateBodyAndSkin(out body, out skin);
        }

        protected override void UpdateHook(GameTime gameTime)
        {
            base.UpdateHook(gameTime);
            Component.Position = body.Position;
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing) DestroyBody();
            base.Dispose(disposing);
        }

        private void CreateBodyAndSkin(out CharacterBody body, out CollisionSkin skin)
        {
            body = new CharacterBody();
            skin = new CollisionSkin(body);
            Capsule capsule = new Capsule(Vector3.Zero, Matrix.CreateRotationX(MathHelper.PiOver2), 1.0f, 1.0f);
            skin.AddPrimitive(capsule, (int)MaterialTable.MaterialID.NotBouncyNormal);
            body.CollisionSkin = skin;
            Vector3 com = SetMass(100.0f);
            body.MoveTo(Component.Position + com, Matrix.Identity);
            skin.ApplyLocalTransform(new Transform(-com, Matrix.Identity));
            body.SetBodyInvInertia(0.0f, 0.0f, 0.0f);
            body.EnableBody();
        }

        private void DestroyBody()
        {
            body.DisableBody();
        }

        private Vector3 SetMass(float mass)
        {
            PrimitiveProperties primitiveProperties = new PrimitiveProperties(
                PrimitiveProperties.MassDistributionEnum.Solid,
                PrimitiveProperties.MassTypeEnum.Density,
                mass);
            float junk;
            Vector3 com;
            Matrix it, itCoM;
            skin.GetMassProperties(primitiveProperties, out junk, out com, out it, out itCoM);
            body.BodyInertia = itCoM;
            body.Mass = junk;
            return com;
        }
    }
}