Page 1 of 2

Custom car fbx model

Posted: Thu Aug 12, 2010 6:12 am
by slickyrich*
how can I use the vehicle demo with a custom car model (just like in jiglibx) instead of primitives. I also noticed that the fbx wheels used in the demos are symmetrical: how can I implement asymmetrical wheel models and orient them properly?

Re: Custom car fbx model

Posted: Thu Aug 12, 2010 7:15 am
by Norbo
The vehicle's body entity has a position/orientation, which together form its world transform (entity.worldTransform property). You can use this transform to make any model follow an entity.

You will probably notice that your model is offset to begin with if your model isn't centered in the same way as the geometric body of the entity. You can apply a local transformation to the graphics to center it properly before applying the entity's world transform to fix this. For example, if your model appears to be 2 units higher than the entity, apply a transform of Matrix.CreateTranslation(new Vector3(0, -2, 0)) first.

Every wheel has its own local graphics transform. In the default VehicleInput you can see that one transform is re-used since they are symmetrical, but you can easily specify a transform unique to each wheel.

Re: Custom car fbx model

Posted: Thu Aug 12, 2010 2:28 pm
by slickyrich*
i'm totally new to xna coding but where do I put that information(for the main car body) and how do I load it? Is it in the VehicleDemo.cs, PhoneGame.cs or VehicleInput.cs? can you give me an example?

Re: Custom car fbx model

Posted: Thu Aug 12, 2010 2:38 pm
by Norbo
Usually, when drawing 3d models, you specify a world matrix. The world matrix transforms the vertices in the shader that's drawing the model. That is where you'd use the entity's worldTransform. For an example, you could check out the BasicSetupDemo on the documentation part of the website. However, for general xna development/graphics stuff, I'd highly recommend the main XNA site and forums. There are a lot of good learning resources there that cover a lot of information, and the community can help with non-physics engine related questions.

If you get confused looking at the BEPUphysicsDrawer, don't worry too much- it's made for drawing entities and not much else. I don't recommend using it as a basis for a game's renderer; creating something simpler that is tailored for the game's needs works much better.

Re: Custom car fbx model

Posted: Thu Aug 12, 2010 2:55 pm
by slickyrich*
I figured that part out thank you but now i need to figure out how to assign unique matrices to each asymmetrical wheel to orient it properly...please sow me an example

Re: Custom car fbx model

Posted: Thu Aug 12, 2010 3:00 pm
by Norbo
In the VehicleInput.cs:

Code: Select all

       #region RaycastWheelShapes
            //The wheel model used is not aligned initially with how a wheel would normally look, so rotate them.
            Matrix wheelGraphicRotation = Matrix.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2);
            vehicle.addWheel(new Wheel(
                new RaycastWheelShape(.375f, wheelGraphicRotation),
                new WheelSuspension(2000, 100f, Vector3.Down, .8f, new Vector3(-1.1f, 0, 1.8f)),
                new WheelDrivingMotor(2.5f, 30000, 10000),
                new WheelBrake(1.5f, 2, .02f),
                new WheelSlidingFriction(4, 5)));
            vehicle.addWheel(new Wheel(
                new RaycastWheelShape(.375f, wheelGraphicRotation),
                new WheelSuspension(2000, 100f, Vector3.Down, .8f, new Vector3(-1.1f, 0, -1.8f)),
                new WheelDrivingMotor(2.5f, 30000, 10000),
                new WheelBrake(1.5f, 2, .02f),
                new WheelSlidingFriction(4, 5)));
            vehicle.addWheel(new Wheel(
                new RaycastWheelShape(.375f, wheelGraphicRotation),
                new WheelSuspension(2000, 100f, Vector3.Down, .8f, new Vector3(1.1f, 0, 1.8f)),
                new WheelDrivingMotor(2.5f, 30000, 10000),
                new WheelBrake(1.5f, 2, .02f),
                new WheelSlidingFriction(4, 5)));
            vehicle.addWheel(new Wheel(
                new RaycastWheelShape(.375f, wheelGraphicRotation),
                new WheelSuspension(2000, 100f, Vector3.Down, .8f, new Vector3(1.1f, 0, -1.8f)),
                new WheelDrivingMotor(2.5f, 30000, 10000),
                new WheelBrake(1.5f, 2, .02f),
                new WheelSlidingFriction(4, 5)));

            #endregion
Notice that wheelGraphicRotation is used in every wheel. It doesn't have to be re-used; you can change it to whatever you want. In your example, you may need to rotate the wheels of one side around the Y axis 180 degrees (Pi radians).

Re: Custom car fbx model

Posted: Wed Sep 29, 2010 3:52 am
by slickyrich*
HI I am still trying to learn this wonderful physics engine but i'm a total newbie. I figured how to render the wheels with different orientations(up and down)<thanks to you>. But this time around I designed a car model in max and i want to use it in the engine. I wanted to achieve something like this(http://www.youtube.com/watch?v=jTDBeGP12_Y) <which i did using bone animation of the wheels>. Can you please use an example to illustrate how i can use a custom fbx model with the raycast wheels. thank you very much.

Re: Custom car fbx model

Posted: Wed Sep 29, 2010 3:25 pm
by Norbo
If you already have a model moving around, you're halfway there. It just needs to take its transformation information from the physics system now. The vehicle's body entity has a WorldTransform, and each wheel has a WorldTransform. Use those transforms to position the appropriate meshes.

For learning different ways of handling rendering and other aspects of general game development, the creator's club website really is the best place to start.

Re: Custom car fbx model

Posted: Wed Sep 29, 2010 3:43 pm
by slickyrich*
Thanks for the swift reply. The demo link i sent you was done with the individual bone animation of each wheel (the four of them) with quaternion rotation of the whole model when steering. My question was how I can achieve the same demo using the bepuphysics engine. Thank you very much.

Re: Custom car fbx model

Posted: Wed Sep 29, 2010 4:04 pm
by Norbo
It isn't really a matter of knowing how to use the physics engine. The world transforms that the vehicle and wheels provide are about as far as the engine goes. The rest is on the rendering side of things.

The individual bones can be transformed according to the wheels' WorldTransforms, and the car body can be transformed using the Vehicle body entity's WorldTransform. This replaces however the model was being transformed before.

Re: Custom car fbx model

Posted: Thu Sep 30, 2010 4:34 am
by slickyrich*
do I need to use the bepuPhysics drawer or was that specifically used for the phone demo?

Re: Custom car fbx model

Posted: Thu Sep 30, 2010 2:59 pm
by Norbo
The BEPUphysicsDrawer is just a simple rendering system to easily debug/prototype physical simulations. There are different versions of it for all platforms, but I'd only recommend using it for what it's made for- debugging and prototyping physics.

The physics engine doesn't know or care how things are drawn. It just provides the physical information to whatever is responsible for rendering.

Re: Custom car fbx model

Posted: Thu Sep 30, 2010 6:58 pm
by slickyrich*

Code: Select all

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Xna.Framework.Media;
using BEPUphysics;
using BEPUphysics.Vehicle;
using BEPUphysics.Entities;

namespace BEPU
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class BEPUgame : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        Model wheelModel;
        Vehicle vehicle;
        Space space;
        Vector3 position = Vector3.Zero;
        Entity entity;
        List<Model> wheelModels;
        Matrix offsetTransform;
        Matrix worldTransform;

        public BEPUgame()
        {
            space = new Space();
            this.entity = entity;
            graphics = new GraphicsDeviceManager(this);
            graphics.IsFullScreen = true;
            Content.RootDirectory = "Content";
            offsetTransform = Matrix.Identity;
            worldTransform = offsetTransform;
            CompoundBody body = new CompoundBody();
            body.addBody(new Box(new Vector3(0, 0, 0), 2.5f, .75f, 4.5f, 60));
            body.centerOfMassOffset = new Vector3(0, -.5f, 0);
            body.teleportTo(position);
            vehicle = new Vehicle(body);

            #region RaycastWheelShapes
            //The wheel model used is not aligned initially with how a wheel would normally look, so rotate them.
            Matrix wheelGraphicRotation = Matrix.CreateFromAxisAngle(Vector3.Forward, MathHelper.PiOver2);
            vehicle.addWheel(new Wheel(
                new RaycastWheelShape(.375f, wheelGraphicRotation),
                new WheelSuspension(2000, 100f, Vector3.Down, .5f, new Vector3(-1.1f, -.3f, 1.8f)),
                new WheelDrivingMotor(2.5f, 30000, 10000),
                new WheelBrake(1.5f, 2, .02f),
                new WheelSlidingFriction(4, 5)));
            vehicle.addWheel(new Wheel(
                new RaycastWheelShape(.375f, wheelGraphicRotation),
                new WheelSuspension(2000, 100f, Vector3.Down, .5f, new Vector3(-1.1f, -.3f, -1.8f)),
                new WheelDrivingMotor(2.5f, 30000, 10000),
                new WheelBrake(1.5f, 2, .02f),
                new WheelSlidingFriction(4, 5)));
            vehicle.addWheel(new Wheel(
                new RaycastWheelShape(.375f, wheelGraphicRotation),
                new WheelSuspension(2000, 100f, Vector3.Down, .5f, new Vector3(1.1f, -.3f, 1.8f)),
                new WheelDrivingMotor(2.5f, 30000, 10000),
                new WheelBrake(1.5f, 2, .02f),
                new WheelSlidingFriction(4, 5)));
            vehicle.addWheel(new Wheel(
                new RaycastWheelShape(.375f, wheelGraphicRotation),
                new WheelSuspension(2000, 100f, Vector3.Down, .5f, new Vector3(1.1f, -.3f, -1.8f)),
                new WheelDrivingMotor(2.5f, 30000, 10000),
                new WheelBrake(1.5f, 2, .02f),
                new WheelSlidingFriction(4, 5)));

            #endregion

            foreach (Wheel wheel in vehicle.wheels)
            {
                //This is a cosmetic setting that makes it looks like the car doesn't have antilock brakes.
                wheel.shape.freezeWheelsWhileBraking = true;

                //By default, wheels use as many iterations as the space.  By lowering it,
                //performance can be improved at the cost of a little accuracy.
                wheel.suspension.solverSettings.maximumIterations = 1;
                wheel.brake.solverSettings.maximumIterations = 1;
                wheel.slidingFriction.solverSettings.maximumIterations = 1;
                wheel.drivingMotor.solverSettings.maximumIterations = 1;
            }

            space.add(vehicle);
            Model model;
            wheelModels = new List<Model>();
            for (int k = 0; k < 4; k++)
            {
                vehicle.wheels[k].shape.detector.tag = "noDisplayObject";
                model = wheelModel;
                wheelModels.Add(model);
            }
            // Frame rate is 30 fps by default for Windows Phone.
            TargetElapsedTime = TimeSpan.FromTicks(333333);
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            wheelModel = Content.Load<Model>("carWheel");
            // TODO: use this.Content to load your game content here
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
            
            // TODO: Add your update logic here
            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

            // Copy any parent transforms.
            Matrix[] transforms = new Matrix[wheelModel.Bones.Count];
            wheelModel.CopyAbsoluteBoneTransformsTo(transforms);

            // Draw the model. A model can have multiple meshes, so loop.
            foreach (ModelMesh mesh in wheelModel.Meshes)
            {
                // This is where the mesh orientation is set, as well 
                // as our camera and projection.
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.EnableDefaultLighting();
                    effect.World = transforms[mesh.ParentBone.Index] *
                        worldTransform;
                    effect.View = Matrix.CreateLookAt(new Vector3(0, 5, 0),
                        Vector3.Zero, Vector3.Up);
                    effect.Projection = Matrix.CreatePerspectiveFieldOfView(
                        MathHelper.ToRadians(45.0f), graphics.GraphicsDevice.Viewport.AspectRatio,
                        1.0f, 10000.0f);
                }
                // Draw the mesh, using the effects set above.
                mesh.Draw();
            }
            base.Draw(gameTime);
        }
    }
}

Hi Norbo thanks for your reply and assistance. I used to above code to draw the wheels but nothing was rendered. lol I KNOW I'M A NOOB but a code snippet would help me learn faster. I attached the youtube demo so you can check it out/Thanks very very very much

Re: Custom car fbx model

Posted: Thu Sep 30, 2010 7:13 pm
by Norbo
I strongly recommend going to the creator's club website. There are a huge number of educational resources on there, in addition to the forums. There's also other places like sgtconker.com which have a variety of other resources. All of that combined can help you a lot more with non-physics engine stuff than I can.

That said, at a glance, it does look like the view matrix in that example would cause a problem. It's looking straight down, while its Up vector is straight up.

Re: Custom car fbx model

Posted: Fri Oct 01, 2010 12:38 am
by slickyrich*
So i got the Matrix part now but when I run the process I get the following message System.NullReferenceException was unhandled
Message=NullReferenceException here

Code: Select all

 public Car(Game game, Vector3 position)
        {
            worldMatrix = entity.WorldTransform;
            Space = new Space();
I tried the creators website but i was always referred back here that this was the best place i could get help.