Vehicle - Ogre model created in Blender

I’ve got a problem with creating vehicle physics. I want to load ogre model (converted to j3o). The problem is that the vehicle checks collision correctly but wheels and a car body move completely wrong. I’ve been trying to do something similar to a sample code from tutorial. However blender doesn’t name Geometry object (TestFancyCar.java). I found geometry object by checking the children’s nodes but it didn’t solve the problem (parent node scales model). I also tried to load a model with the same parameters like in TestPhysicsCar.java but the position of wheels was still wrong.

The vehicle model is just made of 1 cube and 4 cylinders.
Blender 2.65

Make sure the vehicle is z-forward.

This makes nervous. I spent 2 days trying to solve it and… :frowning:
This film presents the “effect”
[video]http://www.youtube.com/watch?v=Jqj-HkxVZ7A&feature=youtu.be[/video]
This is a link to the model:
Model

It’s probably a simple mistake…

Your wheels are rotated 90 degrees over the Y-axis. Just select a wheel in Blender (in object mode) and apply rotation (CTRL+A, then Rotation). Do this for all the wheels.

It didn’t solve the problem. Moreover it makes wheels rotated in View model in jMonkeyEngine SDK :confused: Before this change wheels look like in a car.

I think the mistake is connected with transformations of nodes.

btw… jMonkeyEngine SDK has a bug. I’m using 2 monitors (notebook + additional monitor; extend mode). When I disconnect the monitor, jMonkeyEngine SDK crashs. It shows Notebook: Samsung R580.

@iblis said: It didn't solve the problem. Moreover it makes wheels rotated in View model in jMonkeyEngine SDK :/ Before this change wheels look like in a car.

I think the mistake is connected with transformations of nodes.

btw… jMonkeyEngine SDK has a bug. I’m using 2 monitors (notebook + additional monitor; extend mode). When I disconnect the monitor, jMonkeyEngine SDK crashs. It shows Notebook: Samsung R580.


Sorry to hear that, the lwjgl/swing integration is wonky, hopefully that will be better with jogl. Does this always happen or only when the OpenGL window is open?

Always… Moreover closing the OpenGL window doesn’t help. If you don’t use this window, it works correctly.

err, what :? that sounded like it would contradict itself. Anyway I guess it did not help :frowning:

I wanted to say… If you don’t open the OpenGL Window (View model, Edit vehicle), the jMonkeyEngine SDK won’t crash.

Sorry. English is not my native language.

1 Like

Oh alright, thanks, thats relatively good news :wink:

@iblis said: It didn't solve the problem. Moreover it makes wheels rotated in View model in jMonkeyEngine SDK :/ Before this change wheels look like in a car.

I think the mistake is connected with transformations of nodes.

Are you, by any chance, using a setLocalRotation on the wheels somewhere?

Nowhere…
[java]package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.bounding.BoundingBox;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.collision.shapes.BoxCollisionShape;
import com.jme3.bullet.collision.shapes.CompoundCollisionShape;
import com.jme3.bullet.control.VehicleControl;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Matrix3f;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;

/**

  • test

  • @author normenhansen
    */
    public class Main extends SimpleApplication
    implements ActionListener {

    private BulletAppState bulletAppState;
    private VehicleControl vehicle;
    private final float accelerationForce = 1000.0f;
    private final float brakeForce = 100.0f;
    private float steeringValue = 0;
    private float accelerationValue = 0;
    private Vector3f jumpForce = new Vector3f(0, 3000, 0);

    public static void main(String[] args) {
    Main app = new Main();
    app.start();
    }
    Material mat4;

    @Override
    public void simpleInitApp() {
    bulletAppState = new BulletAppState();
    stateManager.attach(bulletAppState);
    bulletAppState.getPhysicsSpace().enableDebug(assetManager);
    PhysicsTestHelper.createPhysicsTestWorld(rootNode, assetManager, bulletAppState.getPhysicsSpace());
    setupKeys();
    init();

    }

    private void setupKeys() {
    inputManager.addMapping(“Lefts”, new KeyTrigger(KeyInput.KEY_H));
    inputManager.addMapping(“Rights”, new KeyTrigger(KeyInput.KEY_K));
    inputManager.addMapping(“Ups”, new KeyTrigger(KeyInput.KEY_U));
    inputManager.addMapping(“Downs”, new KeyTrigger(KeyInput.KEY_J));
    inputManager.addMapping(“Space”, new KeyTrigger(KeyInput.KEY_SPACE));
    inputManager.addMapping(“Reset”, new KeyTrigger(KeyInput.KEY_RETURN));
    inputManager.addListener(this, “Lefts”);
    inputManager.addListener(this, “Rights”);
    inputManager.addListener(this, “Ups”);
    inputManager.addListener(this, “Downs”);
    inputManager.addListener(this, “Space”);
    inputManager.addListener(this, “Reset”);
    }

    private void init() {
    Material mat3 = new Material(getAssetManager(), “Common/MatDefs/Misc/Unshaded.j3md”);
    mat3.getAdditionalRenderState().setWireframe(true);
    mat3.setColor(“Color”, ColorRGBA.Red);
    Spatial loadModel = assetManager.loadModel(“Models/3.scene”);
    Node mainNode = (Node) loadModel;

     Node carBody = (Node) mainNode.getChild("Cube");
    
     Node carNode = initCarBody(carBody);
     Node wheelFL = (Node) mainNode.getChild("Cylinder");
     initWheel(wheelFL, true, carNode);
    
     Node wheelFP = (Node) mainNode.getChild("Cylinder.001");
     initWheel(wheelFP, true, carNode);
     Node wheelBP = (Node) mainNode.getChild("Cylinder.002");
     initWheel(wheelBP, false, carNode);
    
     Node wheelBL = (Node) mainNode.getChild("Cylinder.003");
     initWheel(wheelBL, false, carNode);
    
     rootNode.attachChild(carNode);
     carNode.setMaterial(mat3);
     bulletAppState.getPhysicsSpace().add(vehicle);
    

    }
    private Node initCarBody(Node carBody) {
    BoundingBox b = (BoundingBox) carBody.getWorldBound();

     Vector3f size = new Vector3f();
     b.getExtent(size);
     CompoundCollisionShape comp = new CompoundCollisionShape();
     BoxCollisionShape box = new BoxCollisionShape(size);
    
     comp.addChildShape(box, new Vector3f(0, 1, 0));
     vehicle = new VehicleControl(box, 400);
     Node carNode = new Node();
     carNode.attachChild(carBody);
     carNode.addControl(vehicle);
    
     float stiffness = 200.0f;
     float compValue = 0.3f;
     float dampValue = 0.4f;
    
     vehicle.setSuspensionCompression(compValue * 2.0f * FastMath.sqrt(stiffness));
     vehicle.setSuspensionDamping(dampValue * 2.0f * FastMath.sqrt(stiffness));
     vehicle.setSuspensionStiffness(stiffness);
     vehicle.setMaxSuspensionForce(10000.0f);
    
     return carNode;
    

    }

    private void initWheel(Node wheel, boolean front, Node carNode) {

     Vector3f wheelDirection = new Vector3f(0, -1, 0);
     Vector3f wheelAxle = new Vector3f(-1, 0, 0);
    
     BoundingBox box2 = (BoundingBox) wheel.getWorldBound();
     Vector3f center = box2.getCenter();
     Vector3f size = new Vector3f();
     box2.getExtent(size);
    
     float restLength = 0.3f;
     float wheelRadius = box2.getYExtent();
    
     Node buf = new Node();
     buf.attachChild(wheel);
     vehicle.addWheel(wheel, center,
             wheelDirection, wheelAxle, restLength, wheelRadius, front);
    
     carNode.attachChild(wheel);
    

    }

    @Override
    public void simpleUpdate(float tpf) {
    }

    @Override
    public void simpleRender(RenderManager rm) {
    }
    public static float change = 0.3f;

    public void onAction(String binding, boolean value, float tpf) {

     if (binding.equals("Lefts")) {
         if (value) {
             steeringValue += change;
         } else {
             steeringValue += -change;
         }
    
         vehicle.steer(steeringValue);
     } else if (binding.equals("Rights")) {
         if (value) {
             steeringValue += -change;
         } else {
             steeringValue += change;
         }
    
         vehicle.steer(steeringValue);
     } else if (binding.equals("Ups")) {
         System.err.println(binding + " - " + value);
         if (value) {
    
             accelerationValue += accelerationForce;
    
    
         } else {
             accelerationValue -= accelerationForce;
    
         }
         vehicle.accelerate(accelerationValue);
     } else if (binding.equals("Downs")) {
         if (value) {
             vehicle.brake(brakeForce);
         } else {
             vehicle.brake(0f);
         }
     } else if (binding.equals("Space")) {
         if (value) {
             vehicle.applyImpulse(jumpForce, Vector3f.ZERO);
         }
     } else if (binding.equals("Reset")) {
         if (value) {
             System.out.println("Reset");
             vehicle.setPhysicsLocation(Vector3f.ZERO);
             vehicle.setPhysicsRotation(new Matrix3f());
             vehicle.setLinearVelocity(Vector3f.ZERO);
             vehicle.setAngularVelocity(Vector3f.ZERO);
             vehicle.resetSuspension();
         } else {
         }
     }
    

    }
    }
    [/java]

And what about line 123 & 124:
Vector3f wheelDirection = new Vector3f(0, -1, 0);
Vector3f wheelAxle = new Vector3f(-1, 0, 0);

Shouldn’t wheelDirection be (0, 0, 1)? Y-axis is up in JME, so this would make the wheel pointing up, right? I am not sure, but could be interesting to check these two vectors.