Outerra forum

Outerra Engine => Development screen shots and videos => Topic started by: cameni on November 12, 2012, 09:29:15 am

Title: Importer and vehicle physics video
Post by: cameni on November 12, 2012, 09:29:15 am
A 15min video showing the importing process together with some basic vehicle physics editing.

Outerra Importer and Scripting (alpha) (http://www.youtube.com/watch?v=joY7G1iRUL4#ws)

I've added subtitles there in case someone has problems understanding my monotonous Englishshshsh ;)

Package with the imported BMW M3 model can be downloaded here (https://docs.google.com/open?id=0B2spgr2B2dvNRG1yd0ZwdEF3UnM) (unpack into your Outerra data folder). Original model by Amit Chippa (http://thefree3dmodels.com/stuff/vehicles/bmw_m3/13-1-0-223).
Title: Re: Importer and vehicle physics video
Post by: ZeosPantera on November 12, 2012, 10:22:24 am
Joygasm
Title: Re: Importer and vehicle physics video
Post by: murkz on November 12, 2012, 12:25:25 pm
Please may we have a download for the 1080p video, as going to youtube every time is a chore.

Also where did you get the script from @ 40seconds in the YT. Also what is the hierarchy for a vehicle (tank)
Title: Re: Importer and vehicle physics video
Post by: cameni on November 12, 2012, 12:43:42 pm
The original video I produced has 700MB, I would have to downsize it. But perhaps you could download it via a youtube downloader? I've previously used YTD downloader.

Script at 40s? Do you mean the hierarchy that shows up? That only reads the hierarchy that's in the model. The hierarchy is on you, OT doesn't enforce a particular one, but you need to mark the nodes that you want to be able to animate later from the script.
Title: Re: Importer and vehicle physics video
Post by: murkz on November 12, 2012, 12:51:51 pm
Thank you for the reply cameni:

I have this

(http://farm9.staticflickr.com/8070/8179427782_7a1939d670_b.jpg)

You can see the script box is empty, yours was not. Where did you get yours from?

Regards

Jeff
Title: Re: Importer and vehicle physics video
Post by: cameni on November 12, 2012, 12:59:43 pm
That is just the name of the script file, you can put anything in there. The video has been made with the latest (internal) version, and that one generates a script file name there (you can change it), and later when you insert the vehicle and the script file you provided here doesn't exist, it creates one (if you are the package owner). We will release this version soon, but you can still use the latest public version - just put a script name in the box here, and then create the file in the package directory, copying there the example script from T817, modifying appropriately.
Title: Re: Importer and vehicle physics video
Post by: murkz on November 12, 2012, 04:06:13 pm
Hi,

I think my issue is the rigging of the model. Is it possible to post a diagram or a model that is rigged with wheels and camera position.

At the moment I can not get into the my model or change view with C. My ALT E brings up a blank window that I can not close. I have to press ESC twice, where my model falls to the ground and sort of flips about.
Title: Re: Importer and vehicle physics video
Post by: giucam on November 12, 2012, 04:07:35 pm
Wonderful! Just wonderful!
I'm going to try the BMW as soon as I can. Now the only thing missing is OSM import ;)
And also other cars, since i can't model :P
Title: Re: Importer and vehicle physics video
Post by: cameni on November 12, 2012, 04:31:12 pm
At the moment I can not get into the my model or change view with C. My ALT E brings up a blank window that I can not close. I have to press ESC twice, where my model falls to the ground and sort of flips about.
I could spawn your model, esc twice to close menu then enter, then switch camera with C
But Alt+E produces an error when I do a clean install+patch, there seems to be something missing in the patch ...
Title: Re: Importer and vehicle physics video
Post by: cameni on November 12, 2012, 04:48:24 pm
Please update (3391), the editor code was missing in the installer.
Title: Re: Importer and vehicle physics video
Post by: angrypig on November 12, 2012, 05:31:39 pm
Hi,

I think my issue is the rigging of the model. Is it possible to post a diagram or a model that is rigged with wheels and camera position.

At the moment I can not get into the my model or change view with C. My ALT E brings up a blank window that I can not close. I have to press ESC twice, where my model falls to the ground and sort of flips about.

Currently we do not support standard rigged models with bones, you have to separate wheels and other moving parts into independent meshes and put them under group or parent dummy object.

car (dummy parent)
 |- chassis
 |- wheel0
 |- wheel1
 |- ...

OR

Chassis
 |- wheel0
 |- wheel1
 |- ...
Title: Re: Importer and vehicle physics video
Post by: jeffmorris on November 13, 2012, 08:53:49 pm
How should I create a vehicle in 3DS MAX for use in Outerra? Do I need dummy helpers?
Title: Re: Importer and vehicle physics video
Post by: giucam on November 14, 2012, 09:37:29 am
I have two questions:
Is it possible to make the suspensions less sensitive?
Is it possible to change the speed at which the steering wheels return back to the straight position?
Title: Re: Importer and vehicle physics video
Post by: cameni on November 14, 2012, 09:53:19 am
Steering/centering speed can be set in init_chassis when you return chassis parameters, see init_chassis (http://xtrac.outerra.com/index.fcgi/wiki/vehicle) and the return structure vehicle_params (http://xtrac.outerra.com/index.fcgi/wiki/vehicle_params). It's used in the code for BMW too.

Suspension sensitivity - when you add wheels, you pass in a structure with wheel parameters (http://xtrac.outerra.com/index.fcgi/wiki/wheel), you can modify suspension_stiffness and damping parameters there.
Title: Re: Importer and vehicle physics video
Post by: ZeosPantera on November 14, 2012, 11:38:08 am
The suspension stiffness is odd because the wheels currently have no "give" as a real wheel would deform and absorb a lot of the little bumps and here they are concrete. When a tire model is implemented the suspensions can do less work.
Title: Re: Importer and vehicle physics video
Post by: giucam on November 14, 2012, 12:14:35 pm
I modified the js a bit to have a more comfortable driving and so far it seems to work good.

this is the new init_chassis:
Code: [Select]
function init_chassis(){
  var wheelparam = {
    radius: 0.30,
    width: 0.20,
    suspension_max: 0.1,
    suspension_min: -0.05,
    suspension_stiffness: 50.0,
    damping_compression: 0.06,
    damping_relaxation: 0.05,
    slip: 2.2,
    roll_influence: 0.1,
    rotation: -1
  };
  this.add_wheel('wheel_FL', wheelparam);
  this.add_wheel('wheel_FR', wheelparam);
  this.add_wheel('wheel_RL', wheelparam);
  this.add_wheel('wheel_RR', wheelparam);
 
  return {mass:1500, steering:2.0, steering_ecf:60, centering: 2.6, centering_ecf:20};
}

I'm also experimenting a bit at adding the engine sound, but getting the pitch right is not so easy.
Also, i'm not aware of any free sound for that. I'm using some from rFactor but obviously those aren't redistributable.
Title: Re: Importer and vehicle physics video
Post by: Chaoz on November 14, 2012, 01:34:06 pm
I toyed around with the engine sound to but i couldn't find a sound that sounded good or real when pitched since expacially the sports version of BMW have a very distict sound when accelerating, which difers greatly from the idle sound.... the only thing i could do was a engine start sound...

EDIT: I took mine from BMW Performance Exhaust / Intake (http://www.youtube.com/watch?v=Q7hNZ5f1Se8#ws)
Title: Re: Importer and vehicle physics video
Post by: giucam on November 15, 2012, 04:49:12 pm
I implemented a still basic but a bit more realistic engine, with gears too (5 + 1).
The engine curve needs some adjustments though. Too little force when starting.
Code: [Select]
//vehicle script file
//see http://xtrac.outerra.com/index.fcgi/wiki/vehicle for example and documentation

var sound = -1;
var gear = 0;

//invoked only the first time the model is loaded, or upon reload
function init_chassis(){
  var wheelparam = {
    radius: 0.30,
    width: 0.20,
    suspension_max: 0.1,
    suspension_min: -0.05,
    suspension_stiffness: 50.0,
    damping_compression: 0.06,
    damping_relaxation: 0.05,
    slip: 2.2,
    roll_influence: 0.1,
    rotation: -1
  };
  this.add_wheel('wheel_FL', wheelparam);
  this.add_wheel('wheel_FR', wheelparam);
  this.add_wheel('wheel_RL', wheelparam);
  this.add_wheel('wheel_RR', wheelparam);
 
  this.load_sound("diesel-engine-start.ogg");
  this.load_sound("18L16V_onidle_ex.ogg");
  this.load_sound("18L16V_onverylow_in.ogg");
  this.add_sound_emitter("wheel_FL");

  return {mass:1500, steering:2.0, steering_ecf:60, centering: 2.6, centering_ecf:20};
}

//invoked for each new instance of the vehicle
function init_vehicle(){
  this.set_fps_camera_pos({x:-0.33,y:-0.25,z:1.15});
 
  this.snd = this.sound();
  this.snd.set_ref_distance(0, 9.0);

  this.started = 0;
}

//invoked when engine starts or stops
function engine(start){
  if(start) {
    this.started = 1;
        this.sound = 0;
    this.snd.play(0, 0, false, false);
  }
}

const BF = 4000.0;

function force(rpm) {
    var maxrpm = 7500;
    var mid = maxrpm / 2.0;

    var x = rpm - (mid - 200);
    return (-x * x + (mid + 200) * (mid + 200)) / 3000;
}

//invoked each frame to handle the inputs and animate the model
function update_frame(dt, engine, brake, steering) {
  if (this.started != 1)
    return;

  steering *= 0.6;
  this.steer(-2, steering);
 
  var radius = 0.24;
  var wheels = Math.abs(this.speed()) / (radius * (2 * 3.1415));

  var kmh = this.speed()*3.6;
 
  var gears = [ 1.0, 4.20, 2.49, 1.66, 1.24, 1.00 ]; //R, 1, 2, 3, 4, 5
 
  var speed = Math.abs(kmh);
  if (engine < 0)
    this.gear = 0;
  else if (speed < 40)
    this.gear = 1;
  else if (speed < 75)
        this.gear = 2;
  else if (speed < 115)
    this.gear = 3;
  else if (speed < 150)
        this.gear = 4;
  else
    this.gear = 5;

  var ratio = 3.0;
  var rpm = wheels * gears[this.gear] * ratio * 60;
  engine *= force(rpm);
 
  this.wheel_force(2, engine);
  this.wheel_force(3, engine);
 
  brake *= BF;
  this.wheel_brake(-1, brake);

  this.animate_wheels();
 
  if (engine == 0 && ((this.sound == 0 && !this.snd.is_playing(0)) || this.sound == 2)) {
        this.snd.stop(0);
    this.snd.play(0, 1, true, false);
        this.sound = 1;
  } else if (engine != 0 && ((this.sound == 0 && !this.snd.is_playing(0)) || this.sound == 1)) {
        this.snd.stop(0);
    this.snd.play(0, 2, true, false);
        this.sound = 2;
  }
 
  var basepitch = [ 0, 1, 0.7 ];
  if (this.sound > 0) {
    var pitch = rpm / 5000.0;
    this.snd.set_pitch(0, pitch + basepitch[this.sound]);
  }
}

That code also manages the sound. I still couldn't find any good free sample so if you want to try some sound you have you need to put them in the package folder, change the file names at lines 26,27, 28 and adjust the pitch at line 114 if needed. Otherwise comment out the sound parts.

With this driving the BMW starts to be enjoyable :)

EDIT: Silly me, i just realised i put a wrong ratio for the reverse gear. Should be something like 4. (If you have the real value that would be welcome. The other ones are real.)
Title: Re: Importer and vehicle physics video
Post by: murkz on November 15, 2012, 04:55:30 pm
WoW giucam, very nice indeed, is it possible to have multiple revers gears as well. Some tanks and vehicles have 4 or more revers gears.

Jeff
Title: Re: Importer and vehicle physics video
Post by: giucam on November 15, 2012, 05:03:19 pm
Yeah, it's sure possible. You just need to add the ratios in the gears array and add some ifs to choose the rigth gear.

btw, Cameni, can we have some speedometer in km/h? I'm using the airplane HUD right now, but i'm not even sure i know how much a knot is...  :P
Title: Re: Importer and vehicle physics video
Post by: ZeosPantera on November 15, 2012, 05:24:02 pm
can we have some speedometer in km/h? I'm using the airplane HUD right now, but i'm not even sure i know how much a knot is...  :P

Actually the HUD speedo is Meters per Second. It just says knots...
Title: Re: Importer and vehicle physics video
Post by: cameni on November 16, 2012, 10:16:23 am
btw, Cameni, can we have some speedometer in km/h? I'm using the airplane HUD right now, but i'm not even sure i know how much a knot is...  :P
Yea we need to make it configurable and switch to values used with different vehicles.

Nice work!
Title: Re: Importer and vehicle physics video
Post by: murkz on November 16, 2012, 10:40:44 am
Outerra SDKFZ 232 (PanzerTerra).avi (http://www.youtube.com/watch?v=9-wdyMCQc1k#ws)

A short WIP of the Schwerer Panzerspähwagen 232 used for testing the new Outerra importer and in understanding how the vehicle script works.
Title: Re: Importer and vehicle physics video
Post by: giucam on November 16, 2012, 11:38:02 am
Here's version 2.0. (or maybe 0.2) ;)

Code: [Select]
//vehicle script file
//see http://xtrac.outerra.com/index.fcgi/wiki/vehicle for example and documentation

var sound = -1;

//invoked only the first time the model is loaded, or upon reload
function init_chassis(){
    var wheelparam = {
        radius: 0.30,
        width: 0.20,
        suspension_max: 0.1,
        suspension_min: -0.05,
        suspension_stiffness: 50.0,
        damping_compression: 0.06,
        damping_relaxation: 0.05,
        slip: 2.2,
        roll_influence: 0.1,
        rotation: -1
    };
    this.add_wheel('wheel_FL', wheelparam);
    this.add_wheel('wheel_FR', wheelparam);
    this.add_wheel('wheel_RL', wheelparam);
    this.add_wheel('wheel_RR', wheelparam);

    this.load_sound("diesel-engine-start.ogg"); //start
    this.load_sound("18L16V_onidle_ex.ogg");    //idle
    this.load_sound("18L16V_onverylow_in.ogg"); //throttle
    this.basepitch = [ 0, 1, 0.7 ];             //base pitch for start, idle, throttle
    this.add_sound_emitter("wheel_FL");

    //engine properties -- modify these to change the engine behaviour
    this.wheelRadius = 0.24;

    this.torquePoints = [ { rpm: 0,    torque: 220},
                          { rpm: 1000, torque: 265},
                          { rpm: 2000, torque: 290},
                          { rpm: 3000, torque: 315},
                          { rpm: 4000, torque: 335},
                          { rpm: 4900, torque: 365},
                          { rpm: 6000, torque: 340},
                          { rpm: 7000, torque: 320},
                          { rpm: 8000, torque: 290},
                          { rpm: 8100, torque: 0  } ];

    this.forwardGears = [ { ratio: 4.20, shiftUp: 7000, shiftDown: -1   },
                          { ratio: 2.49, shiftUp: 7000, shiftDown: 4000 },
                          { ratio: 1.66, shiftUp: 7000, shiftDown: 4000 },
                          { ratio: 1.24, shiftUp: 7000, shiftDown: 4000 },
                          { ratio: 1.00, shiftUp: -1,   shiftDown: 4000 } ];
    this.reverseGears = [ { ratio: 4.20, shiftUp: -1, shiftDown: -1 } ];

    this.finalRatio = 3;
    this.torqueMultiplier = 10;
    //end of engine properties

    this.torque = engineTorque;

    return {mass:1500, steering:2.0, steering_ecf:60, centering: 2.6, centering_ecf:20};
}

//invoked for each new instance of the vehicle
function init_vehicle() {
    this.set_fps_camera_pos({x:-0.33,y:-0.25,z:1.15});

    this.snd = this.sound();
    this.snd.set_ref_distance(0, 9.0);

    this.started = 0;
    this.gear = 0;
}

//invoked when engine starts or stops
function engine(start) {
    if (start) {
        this.started = 1;
        this.sound = 0;
        this.snd.play(0, 0, false, false);
    }
}

const BF = 4000.0;

function engineTorque(rpm) {
    var min = 0;
    var max = this.torquePoints.length - 1;

    if (rpm > this.torquePoints[max].rpm || rpm < this.torquePoints[min].rpm)
        return 0;

    while (max - min > 1) {
        var mid = Math.floor(min + (max - min) / 2);
        var tp = this.torquePoints[mid];
        if (tp.rpm == rpm) {
            return tp.torque;
        } else if (tp.rpm > rpm) {
            max = mid;
        } else {
            min = mid;
        }
    }

    var minTp = this.torquePoints[min];
    var maxTp = this.torquePoints[max];
    var TM = maxTp.torque;
    var Tm = minTp.torque;
    var RM = maxTp.rpm;
    var Rm = minTp.rpm;

    var a = (TM - Tm) / (RM - Rm);

    return rpm * a + Tm - Rm * a;
}

//invoked each frame to handle the inputs and animate the model
function update_frame(dt, engine, brake, steering) {
    if (this.started != 1)
        return;

    steering *= 0.6;
    this.steer(-2, steering);


    var khm = Math.abs(this.speed()) * 3.6;
    var wheels = Math.abs(this.speed()) / (this.wheelRadius * (2 * Math.PI));

    var gears;
    if (this.speed() >= 0) {
        gears = this.forwardGears;
    } else {
        gears = this.reverseGears;
    }

    var rpm = wheels * gears[this.gear].ratio * this.finalRatio * 60;

    //automatic gear shifting
    var currentGear = gears[this.gear];
    if (rpm > currentGear.shiftUp && this.gear < gears.length - 1) {
        this.gear += 1;
    } else if (rpm < currentGear.shiftDown && this.gear > 0) {
        this.gear -= 1;
    }

    var force = engine * this.torque(rpm) * this.torqueMultiplier;
    this.wheel_force(2, force);
    this.wheel_force(3, force);


    brake *= BF;
    this.wheel_brake(-1, brake);

    this.animate_wheels();

    if (engine == 0 && ((this.sound == 0 && !this.snd.is_playing(0)) || this.sound == 2)) { //idle
        this.snd.stop(0);
        this.snd.play(0, 1, true, false);
        this.sound = 1;
    } else if (engine != 0 && ((this.sound == 0 && !this.snd.is_playing(0)) || this.sound == 1)) { //throttle
        this.snd.stop(0);
        this.snd.play(0, 2, true, false);
        this.sound = 2;
    }

    if (this.sound > 0) {
        var pitch = rpm / 5000.0;
        this.snd.set_pitch(0, pitch + this.basepitch[this.sound]);
    }
}

It doesn't use anymore a parabolic function for the engine torque but it interpolates from some given points in the torque by rpm graph. I took those from a graph of a M3 i found on internet but given there are many M3s i don't know if they are the true ones. It does 0-100 km/h in ~ 9 secs, maybe it's underpowered.
It also supports multiple reverse gears and a more flexible way for it to shift gear.

All the values it uses are defined in the init_chassis(), if you want to adapt it to another vehicle.
Title: Re: Importer and vehicle physics video
Post by: ZeosPantera on November 16, 2012, 09:54:07 pm
You are doing God's work my child.. But seriously. 9 Seconds to 60mph is an eternity. Is there a lot of wheel spin?
Title: Re: Importer and vehicle physics video
Post by: murkz on November 17, 2012, 04:50:40 am
Outerra - Kübelwagen in PanzerTerra with sounds.

Outerra - Kübelwagen in PanzerTerra with sounds. (http://www.youtube.com/watch?v=6cs9wiFyNUI#ws)

Here is another little update, this time with sounds and a new model. The modified script for the Kübelwagen needs some work, though as a start I am happy with it.

Kübelwagen is supplied by Foo'Bar
http://foorum.mexxoft.com/index.php?sid=4837f3d92f4fa277b8c6a22c9ef379a3 (http://foorum.mexxoft.com/index.php?sid=4837f3d92f4fa277b8c6a22c9ef379a3)

Kübelwagen sounds have been supplied by Olaf NSU Binder

The Kübelwagen is using a modified version of giucam's vehicle script.
http://www.outerra.com/forum/index.php?topic=1326.msg15518#msg15518 (http://www.outerra.com/forum/index.php?topic=1326.msg15518#msg15518)

Thank you to all.
Title: Re: Importer and vehicle physics video
Post by: giucam on November 17, 2012, 05:00:35 am
Quote
You are doing God's work my child.. But seriously. 9 Seconds to 60mph is an eternity. Is there a lot of wheel spin?

mmh... i didn't check that but anyway i get 9 secs with a little test app i made to develop the engine model and which has a dumb physics and no wheel spinning.
However, increasing the engine torque is just a matter of increasing the value of this.torqueMultiplier. With 15 it takes ~6 secs and with 20 ~4.50 secs.
Title: Re: Importer and vehicle physics video
Post by: murkz on November 17, 2012, 06:20:55 am
Hi Giucam,

Is there a way with the new settings to limit the top speed, I would like to limit the kubel's top speed.
Title: Re: Importer and vehicle physics video
Post by: giucam on November 17, 2012, 06:37:29 am
No, there's no way currently to force a maximum speed, even though adding support is easy.
Anyway you can change the torque curve so that at the rpm of the maximum speed the torque is 0.
Title: Re: Importer and vehicle physics video
Post by: ddenn on November 17, 2012, 02:40:48 pm
Nice work Giucam!

Cameni, does bullet physics have center of gravity point? BMW behaves now exactly like my mercedes on JSBSim and CG at zero height. If I move CG up, the car starts behave right, leaning forward when brake, and backwards with acceleration. Is there way to control CG on vehicles with Bullet physics?

Also can we have some custom commands to control animations, like door/hood/windows opening etc?
Title: Re: Importer and vehicle physics video
Post by: giucam on November 17, 2012, 03:41:35 pm
Nice work Giucam!
Thanks :)
I still can't get the sound right though. I found a sample which is quite good (i don't know if it's a BMW but i'm not so picky) but at high RPM it doesn't sound right. I'm starting to think we need a way to change the speed of the sound in addition of the pitch.
And then, I need another graphics card  >:(. With this 4850 it's a miracle if i can get to the end of the himalaya runway. Today i tried a Geforce  8400GS i have. No crashes, but slow like hell  :'(.

Anyway, version 0.2.1, with speed limiter: diff (http://pastebin.com/bfZy4Rcu) and full script (http://pastebin.com/KbwyN4W4).
I'm no car expert but i think anyway that normally this limiter shouldn't be needed, but it should emerge from the engine configuration. (At least for the BMW it does so).

Cameni, when can we have key bindings? I'd like to make manual shifting now ;)
Title: Re: Importer and vehicle physics video
Post by: cameni on November 17, 2012, 05:42:37 pm
CG will be customizable, there is some problem with it and right now it's supposed to sit at the center of the bounding box of the car. It's a bit awkward to move in Bullet (creating artificial shapes to offset it), and for some reason it doesn't work anyway. But I haven't given it too much thoughts yet, to be honest :)

Custom commands will be possible once we create some interface for input actions, that will work the same way for aircraft and vehicle both, allowing also to use any controls you may want to bind.
Title: Re: Importer and vehicle physics video
Post by: ddenn on November 18, 2012, 01:33:26 am
I still can't get the sound right though. I found a sample which is quite good (i don't know if it's a BMW but i'm not so picky) but at high RPM it doesn't sound right.

In FSX flightsim authors use a few sounds samples for the engine, one for idle RPM, one (or even two) for mid RPM and one for hight RPM, that way the engine sounds realistic.

Cameni, is there way to change tires friction, and make it dependable of the ground type? Now BMW behaves on the grass same as it does on tarmac.
Title: Re: Importer and vehicle physics video
Post by: ZeosPantera on November 18, 2012, 02:56:19 am
When surfaces get friction values they are going to require a base friction and then a range of randomization/error with either more or less friction so that grass and dirt can have big variations in grip across their surface but asphalt would be more constant.

Title: Re: Importer and vehicle physics video
Post by: cameni on November 18, 2012, 04:26:50 am
Cameni, is there way to change tires friction, and make it dependable of the ground type? Now BMW behaves on the grass same as it does on tarmac.
Not yet. The terrain type is being already read back together with the collision data, but it's not being used yet. The material system will change with the biomes so I wasn't hurrying to plug the existing one in. Though, it could be relatively simple ...
Title: Re: Importer and vehicle physics video
Post by: Racer on November 19, 2012, 12:28:48 am
Any chance I could get a collada file of a vehicle that is set up with multiple LODs and a Collision mesh? I am having a few problems, and would just like to have a model that I know works to compare to.
Title: Re: Importer and vehicle physics video
Post by: jeffmorris on November 19, 2012, 07:37:27 am
I would like a step-by-step tutorial on creating a vehicle in 3DS MAX and importing the vehicle into Outerra. I looked at the 3DS mesh of the 8X8 truck that came with Outerra but I don't know how the axles and wheels are set up in 3DS MAX.
Title: Re: Importer and vehicle physics video
Post by: jeffmorris on November 19, 2012, 09:08:53 pm
I created a box on wheels. When I try to import the vehicle into Outerra, Outerra quits to the desktop with "Error Report" dialog box open. Any suggestions?
Title: Re: Importer and vehicle physics video
Post by: giucam on November 20, 2012, 11:13:34 am
I found some good sound of a M3 but for some reason in Outerra it doesn't sound good. I added OpenAL to the test app i'm using to develop the engine model and, while it isn't perfect, it sounds quite good with that. But with Outerra the pitch seems to oscillate back and forth instead of changing in a monotonous way.
But logging out the pitch values I set shows they are indeed monotonous so the problem must be somewhere deeper.

Btw Cameni, what's the structure returned by vehicle.wheel()?
Title: Re: Importer and vehicle physics video
Post by: cameni on November 20, 2012, 12:05:36 pm
Is the sound mono?

I've added the structure to the wiki http://xtrac.outerra.com/index.fcgi/wiki/wheel_data (http://xtrac.outerra.com/index.fcgi/wiki/wheel_data)
Title: Re: Importer and vehicle physics video
Post by: adagio on November 20, 2012, 12:37:50 pm
Concerning vehicle physics, more specifically cars are there any plans to implement mouse steering? If done correctly it's so much more enjoyable and precise than using keyboard arrows.
Title: Re: Importer and vehicle physics video
Post by: cameni on November 20, 2012, 01:12:14 pm
Currently the inputs from keyboard or joysticks come normalized in -1..1 range. If the correct mouse steering can be somehow implemented as something that takes mouse events and produces steering - then it should be possible easily.
Title: Re: Importer and vehicle physics video
Post by: giucam on November 20, 2012, 01:20:06 pm
Is the sound mono?
Yes
Title: Re: Importer and vehicle physics video
Post by: giucam on November 21, 2012, 03:07:49 pm
I tried a stereo sound and that worked right indeed. Odd thing...

Anyway, i realized i made a stupid ugly error in the script which makes the engine behave unrealistically. A fix should be coming soon.
Title: Re: Importer and vehicle physics video
Post by: ZeosPantera on November 21, 2012, 03:20:57 pm
The vehicle sounds should be mono. I too played with stereo vs mono sound replacements for the 8x8.

Outerra - Sound Tests (http://www.youtube.com/watch?v=pjZb8_6oOOE#)
Title: Re: Importer and vehicle physics video
Post by: giucam on November 21, 2012, 04:42:57 pm
New version 0.3 :). diff (http://pastebin.com/B8Y3f0sM) and full:

Code: [Select]
//vehicle script file
//see http://xtrac.outerra.com/index.fcgi/wiki/vehicle for example and documentation

var sound = -1;

//invoked only the first time the model is loaded, or upon reload
function init_chassis(){
    var wheelparam = {
        radius: 0.30,
        width: 0.20,
        suspension_max: 0.1,
        suspension_min: -0.05,
        suspension_stiffness: 50.0,
        damping_compression: 0.06,
        damping_relaxation: 0.05,
        slip: 2.2,
        roll_influence: 0.1,
        rotation: -1
    };
    this.add_wheel('wheel_FL', wheelparam);
    this.add_wheel('wheel_FR', wheelparam);
    this.add_wheel('wheel_RL', wheelparam);
    this.add_wheel('wheel_RR', wheelparam);

    this.load_sound("diesel-engine-start.ogg"); //start
    this.load_sound("18L16V_onidle_ex.ogg");    //idle
    this.load_sound("18L16V_onverylow_in.ogg"); //throttle
    this.basepitch = [ 0, 1, 0.7 ];             //base pitch for start, idle, throttle
    this.add_sound_emitter("wheel_FL");

    //engine properties -- modify these to change the engine behaviour
    this.wheelRadius = 0.24;

    this.torquePoints = [ { rpm: 0,    torque: 180},
                          { rpm: 1000, torque: 250},
                          { rpm: 2000, torque: 335},
                          { rpm: 3000, torque: 380},
                          { rpm: 4000, torque: 400},
                          { rpm: 5000, torque: 395},
                          { rpm: 6000, torque: 400},
                          { rpm: 7000, torque: 390},
                          { rpm: 8000, torque: 365},
                          { rpm: 9000, torque: 0  } ];

    this.forwardGears = [ { ratio: 4.20, shiftUp: 8000, shiftDown: -1   },
                          { ratio: 2.49, shiftUp: 8000, shiftDown: 4500 },
                          { ratio: 1.66, shiftUp: 8000, shiftDown: 5000 },
                          { ratio: 1.24, shiftUp: 8000, shiftDown: 6000 },
                          { ratio: 1.00, shiftUp: -1,   shiftDown: 6000 } ];
    this.reverseGears = [ { ratio: 4.20, shiftUp: -1, shiftDown: -1 } ];

    this.finalRatio = 3;
    this.torqueMultiplier = 6;
    this.maximumSpeed = -1; // speed in m/s. a value < 0 means there's no maximum speed
    this.engineBrakeCoefficient = 0.2;
    this.pitchMultiplier = 1.8;
    //end of engine properties

    this.maxPowerTP = this.torquePoints[0];
    this.maxRPM = 0;
    var maxPw = 0;
    for (var i = 1; i < this.torquePoints.length; ++i) {
        var tp = this.torquePoints[i];
        if (tp.rpm * tp.torque > maxPw) {
            this.maxPowerTP = tp;
        }
        if (tp.rpm > this.maxRPM) {
            this.maxRPM = tp.rpm;
        }
    }

    this.neutroGear = { ratio: 0.0, shiftUp: -1, shiftDown: -1, index: 0 };
    var prev = null;
    for (var i = 0; i < this.forwardGears.length; ++i) {
        var gear = this.forwardGears[i];
        if (prev)
            prev.next = gear;
        gear.prev = prev;
        gear.index = i + 1;
        prev = gear;
    }

    prev = null;
    for (var i = 0; i < this.reverseGears.length; ++i) {
        var gear = this.reverseGears[i];
        if (prev)
            prev.next = gear;
        gear.prev = prev;
        gear.index = -i - 1;
        prev = gear;
    }


    this.torque = engineTorque;

    return {mass:1500, steering:2.0, steering_ecf:60, centering: 2.6, centering_ecf:20};
}

//invoked for each new instance of the vehicle
function init_vehicle() {
    this.set_fps_camera_pos({x:-0.33,y:-0.25,z:1.15});

    this.snd = this.sound();
    this.snd.set_ref_distance(0, 9.0);

    this.started = 0;
    this.gear = this.neutroGear;
    this.direction = 0;
}

//invoked when engine starts or stops
function engine(start) {
    if (start) {
        this.started = 1;
        this.sound = 0;
        this.snd.play(0, 0, false, false);
    }
}

const BF = 4000.0;

function engineTorque(rpm) {
    var min = 0;
    var max = this.torquePoints.length - 1;

    if (rpm > this.torquePoints[max].rpm || rpm < this.torquePoints[min].rpm)
        return 0;

    while (max - min > 1) {
        var mid = Math.floor(min + (max - min) / 2);
        var tp = this.torquePoints[mid];
        if (tp.rpm == rpm) {
            return tp.torque;
        } else if (tp.rpm > rpm) {
            max = mid;
        } else {
            min = mid;
        }
    }

    var minTp = this.torquePoints[min];
    var maxTp = this.torquePoints[max];
    var TM = maxTp.torque;
    var Tm = minTp.torque;
    var RM = maxTp.rpm;
    var Rm = minTp.rpm;

    var a = (TM - Tm) / (RM - Rm);

    return rpm * a + Tm - Rm * a;
}

function sign(x) {
    return (x > 0.0 ? 1 : (x < 0.0 ? -1 : 0));
}

//invoked each frame to handle the inputs and animate the model
function update_frame(dt, engine, brake, steering) {
    if (this.started != 1)
        return;

    steering *= 0.6;
    this.steer(-2, steering);

    var absSpeed = Math.abs(this.speed());
    var khm = absSpeed * 3.6;
    var wheels = absSpeed / (this.wheelRadius * (2 * Math.PI));

    //automatic gear shifting
    var rpm = wheels * this.gear.ratio * this.finalRatio * 60;
    if (rpm < 1 && this.gear.index != 0) {
        this.gear = this.neutroGear;
        this.direction = 0;
//         this.log_inf("neutro");
    }
    if (engine != 0.0 && sign(engine) != this.direction) {
        this.direction = sign(engine);
        if (this.direction == 1.0) {
            this.gear = this.forwardGears[0];
//             this.log_inf("forward, gear " + this.gear.index);
        } else if (this.direction == -1.0) {
            this.gear = this.reverseGears[0];
//             this.log_inf("reverse, gear " + this.gear.index);
        }
        rpm = wheels * this.gear.ratio * this.finalRatio * 60;
    }

    if (rpm > this.gear.shiftUp && this.gear.next) {
        this.gear = this.gear.next;
//         this.log_inf("gear up " + this.gear.index);
    } else if (rpm < this.gear.shiftDown && this.gear.prev) {
        this.gear = this.gear.prev;
//         this.log_inf("gear down " + this.gear.index);
    }

    rpm = wheels * this.gear.ratio * this.finalRatio * 60;

    if (this.maximumSpeed < 0 || this.speed < this.maximumSpeed) {
        var force = engine * this.torque(rpm) * this.torqueMultiplier * this.gear.ratio;
        this.wheel_force(2, force);
        this.wheel_force(3, force);
    }

    //From Torcs engine code
    var static_friction = 0.1;
    var engineBrake = this.maxPowerTP.torque * this.engineBrakeCoefficient * this.torqueMultiplier * this.gear.ratio *
                      (static_friction + (1.0 - static_friction) * rpm / this.maxRPM);

    brake *= BF;
    this.wheel_brake(-1, brake + engineBrake);

    this.animate_wheels();

    if (engine == 0 && ((this.sound == 0 && !this.snd.is_playing(0)) || this.sound == 2)) { //idle
        this.snd.stop(0);
        this.snd.play(0, 1, true, false);
        this.sound = 1;
    } else if (engine != 0 && ((this.sound == 0 && !this.snd.is_playing(0)) || this.sound == 1)) { //throttle
        this.snd.stop(0);
        this.snd.play(0, 2, true, false);
        this.sound = 2;
    }

    if (this.sound > 0) {
        var pitch = this.pitchMultiplier * rpm / this.maxRPM;
        this.snd.set_pitch(0, pitch + this.basepitch[this.sound]);
    }
}

This fixes the bug i mentioned above and another one that made the script hang sometimes when the car jumped.
Also, it adds engine brake. (to be tuned yet)
Title: Re: Importer and vehicle physics video
Post by: murkz on November 21, 2012, 04:46:30 pm
Thank you giucam  :)
Title: Re: Importer and vehicle physics video
Post by: angrypig on November 22, 2012, 04:10:37 am
I created a box on wheels. When I try to import the vehicle into Outerra, Outerra quits to the desktop with "Error Report" dialog box open. Any suggestions?

I finally test your model and it works, we probably fix the problem on the way to next milestone. The COLLADA file tells it has Y_UP we do not support this option yet, so you will have to rotate your model 90deg by X and 180 by Z, you have to add a root node or link wheels to the body.

Try to attach materials to meshes it should help to import it in your current version...
Title: Re: Importer and vehicle physics video
Post by: giucam on November 22, 2012, 11:19:54 am
I tried to get the actual rotations of the wheel but this.wheel(0).rotation returns undefined. this.wheel(0) returns an object so the problem is the rotation member.
Title: Re: Importer and vehicle physics video
Post by: giucam on November 27, 2012, 09:53:49 am
Cameni, does this.wheel_force account for the wheel radius? I mean, do i have to include the radius in the force i give it or not?
Title: Re: Importer and vehicle physics video
Post by: cameni on November 27, 2012, 10:20:12 am
Wheel force tells the force impulse acting on the wheel hub. Technically it should be the resulting forward force acting on the vehicle at the wheel attachment point, after the losses on the tire are accounted for.

As such it doesn't know anything about the tire radius. So if you have the torque as input, you can compute the force at the tire contact point, then after accounting for friction/skid/losses you can translate it to the hub point.
Title: Re: Importer and vehicle physics video
Post by: Midviki on January 31, 2013, 05:42:45 pm
I saw something from first posts, but I didn't understood exactly.

(http://i.minus.com/jqnCCOQiC9sWm.jpg) (http://minus.com/lqnCCOQiC9sWm)

Do I need to chain them from Max? Or how do I get the bones to appear?Yeah... and probably Alt+E issue of the window that doesn't appear is probably cause no bones?
Title: Re: Importer and vehicle physics video
Post by: hhrhhr on February 06, 2013, 05:06:55 pm
a couple of questions on Vehicle interface
Title: Re: Importer and vehicle physics video
Post by: cameni on February 06, 2013, 05:43:53 pm
1. geomob methods only return the static model positions. To get the dynamic wheel data, use the wheel() method and take the value of caxle - for vertical suspension it contains the displacement directly
2. you are right, I corrected the wiki
3. hmm, they should work, but only log_err should pop up the logger window automatically
4. information about the object's bounding box, half-vector from center to corner and offset from zero
5. elements in vectors and quaternions are also addressable by name (.x .y ...), default order is xyzw
Title: Re: Importer and vehicle physics video
Post by: hhrhhr on February 06, 2013, 09:14:14 pm
3) my mistake, sorry

1) in function update_frame(...) i do this:
Code: [Select]
var w = this.wheel(0);
this.log_inf(w);
this.log_inf(w.ssteer);
this.log_inf(w.csteer);
this.log_inf(w.saxle);
this.log_inf(w.caxle);
this.log_inf(w.rotation);

log:
Code: [Select]
INFO: 1:[object Object]
INFO: 2:undefined
INFO: 3:undefined
INFO: 4:undefined
INFO: 5:undefined
INFO: 6:undefined




updated:
 
Code: [Select]
var w = this.wheel(0); // <-- wrong
var w = this.wheel(0).wd; // <-- correct

but w.saxle or w.caxle work only with "tatra" wheels added by add_wheel_swing(), if I use add_wheel() (for z-moving) then these values is not changed.
Title: Re: Importer and vehicle physics video
Post by: cameni on February 07, 2013, 01:43:46 am
Code: [Select]
var w = this.wheel(0); // <-- wrong
var w = this.wheel(0).wd; // <-- correct

but w.saxle or w.caxle work only with "tatra" wheels added by add_wheel_swing(), if I use add_wheel() (for z-moving) then these values is not changed.
Hmm, that additional .wd required is a bug.
I'll look also why the data don't change for vertical suspension.
Title: Re: Importer and vehicle physics video
Post by: hhrhhr on February 07, 2013, 04:14:42 am
Quote
why the data don't change for vertical suspension
angles do not change with linear movement ;)

until I had to make three mesh and two nested groups, like this (all meshes and groups have pivot at the same point):
(http://s4.hostingkartinok.com/uploads/images/2013/02/5de6fcadf605b1219394e35ad0609096.jpg) ... (http://s4.hostingkartinok.com/uploads/images/2013/02/02af77b38efa059f3105fe45e7cc6706.jpg) ... (http://s2.hostingkartinok.com/uploads/images/2013/02/d2e664fb41b8eeebd47564de57bc2767.jpg) ... (http://s2.hostingkartinok.com/uploads/images/2013/02/bc9ab8afe5447330dd3d6e0c96291513.jpg) ... (http://s4.hostingkartinok.com/uploads/images/2013/02/79b43489c5b481459517dd355b6582ac.jpg)

code sample for one wheel:
Code: [Select]
var body, w_fl, s_fl, v_fl; // model, wheel group, suspension group, vertical bar

function init_chassis() {
...
    w_fl = this.add_wheel('group_wheel_fl', wheelparam);
...
}

function init_vehicle() {
...
    body = this.get_geomob(0);
    s_fl = body.get_joint('group_susp_fl');
    v_fl = body.get_joint('vert_fl');
...
}

function update_frame(dt, engine, brake, steering) {
...
    var rot = this.wheel(0).wd.rotation;
    body.rotate_joint_orig(s_fl, rot, {x: 1, y: 0, z: 0}); // counter-rotation for suspension
    var steer = steering * 0.5;
    body.rotate_joint_orig(v_fl, str, {x: 0, y: 0, z: -1}); // counter-rotation for vertical bar
...
}

result is not bad ;)
bandicam 2013 02 07 11 58 31 898 (http://www.youtube.com/watch?v=EdYTH1R3I1c#ws)

but if I could get the vertical displacement directly, it would be easier and would not have to do a nested group objects.
Title: Re: Importer and vehicle physics video
Post by: cameni on February 07, 2013, 05:53:30 am
Looks good ;)

Quote
why the data don't change for vertical suspension
angles do not change with linear movement ;)

Actually these were meant to be cosine and sine of the angle, and additionally multiplied by the half-axle length for swing axles. Thus the result for caxle would be the height of the wheel above or below the rest position. Similarly for linear suspension caxle should hold the same height, saxle should be 0.
Title: Re: Importer and vehicle physics video
Post by: ZeosPantera on February 07, 2013, 12:42:49 pm
If I could model I would give a double wishbone a try..

https://www.youtube.com/watch?v=nkLmZ39qgO0 (https://www.youtube.com/watch?v=nkLmZ39qgO0)

And or a 4 link rear axle

https://www.youtube.com/watch?v=eS5IPnadUG8 (https://www.youtube.com/watch?v=eS5IPnadUG8)
Title: Re: Importer and vehicle physics video
Post by: Midviki on February 07, 2013, 01:16:37 pm
If I could model I would give a double wishbone a try..

It is basically easy... go on ... (hmmm.. or not )

Hmmm.. actually I don't think I'm allowed to link illegal download links? But if you want to learn.. there are videos that you can fast learn. ;D

But anyway.. you should look for older version of Max tutorials.. max 06 or 2007.And there are different sources that you can learn from, I recommend those from Lynda.
Title: Re: Importer and vehicle physics video
Post by: Midviki on February 12, 2013, 04:21:51 pm
My wheels are spinning on the wrong direction.. I mean.. the animation.The physics works just fine... but the wheel animation seems to be working 90* degrees opposite of how it should work.

Its the same code as in the video for the BMW, and the wheels they don't roll, they flip like a coin.Any advice?
Title: Re: Importer and vehicle physics video
Post by: cameni on February 12, 2013, 04:36:34 pm
Likely the axes on the wheels (in the model) are not oriented correctly.
By default wheels roll around the x axis, and steer around the z axis.
Title: Re: Importer and vehicle physics video
Post by: hhrhhr on February 12, 2013, 04:55:41 pm
Outerra uses "a rarely used" a coordinate system where the "left" is equal to +X. Most 3D-editors think that the "left" means -X ;)

importing DAE obtained from SketchUp, for example, to properly display and animation has to conclude the whole model in a group and rotate it 180 degrees around a vertical axis.
Title: Re: Importer and vehicle physics video
Post by: Midviki on February 12, 2013, 05:03:53 pm
Likely the axes on the wheels (in the model) are not oriented correctly.
By default wheels roll around the x axis, and steer around the z axis.

So... any idea how would I observe if they are.... hmmm... I think I know...

So it is like this.. I have my object rotated from max cause it was facing wrong direction.. but now... the wheels face the wrong direction.Nice.. this will be a good tip for new comers. ;D

Thx again for the help.
Title: Re: Importer and vehicle physics video
Post by: ZeosPantera on February 14, 2013, 08:50:02 pm
Is there some way for people to add a friction to the body of vehicles? I rolled the 8x8 (thanks to the better CoG) and it went sliding away like a giant ice cube..
Title: Re: Importer and vehicle physics video
Post by: cameni on February 15, 2013, 01:04:49 am
That sliding is a bug, since I updated the Bullet lib it started sliding again, not being able to resolve friction constrains precisely, for some reason.
Title: Re: Importer and vehicle physics video
Post by: ddenn on February 15, 2013, 02:48:43 am
I notice that a few vehicles could collide with each other, I guess using their bounding boxes as collision meshes. Could it be possible to use that boxes for collisions with ground? Just reduce down part of the bounding box by wheel radius to allow wheel interaction with the ground.
Title: Re: Importer and vehicle physics video
Post by: cameni on February 15, 2013, 03:10:24 am
Yes that's the plan, once I get around it in Bullet vs our custom collider. Should be able to use convex meshes for collision then, and I'll make the collision box adjustable from the script as well.