Outerra forum

Please login or register.

Login with username, password and session length
Advanced search  

News:

Download Outerra Tech Demo. Unofficial Outerra Discord server, MicroProse Discord server for OWS.

Pages: 1 2 3 [4] 5

Author Topic: Importer and vehicle physics video  (Read 64351 times)

giucam

  • Full Member
  • ***
  • Posts: 171
  • It's an ugly pile of bones... like me.
Re: Importer and vehicle physics video
« Reply #45 on: November 21, 2012, 04:42:57 pm »

New version 0.3 :). diff 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)
« Last Edit: November 21, 2012, 04:45:52 pm by giucam »
Logged
ResidualVM 0.1.1 is OUT! www.residualvm.org

murkz

  • Full Member
  • ***
  • Posts: 152
    • The Antisocial Gamer
Re: Importer and vehicle physics video
« Reply #46 on: November 21, 2012, 04:46:30 pm »

Thank you giucam  :)

angrypig

  • Sr. Member
  • ****
  • Posts: 454
Re: Importer and vehicle physics video
« Reply #47 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...
Logged

giucam

  • Full Member
  • ***
  • Posts: 171
  • It's an ugly pile of bones... like me.
Re: Importer and vehicle physics video
« Reply #48 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.
Logged
ResidualVM 0.1.1 is OUT! www.residualvm.org

giucam

  • Full Member
  • ***
  • Posts: 171
  • It's an ugly pile of bones... like me.
Re: Importer and vehicle physics video
« Reply #49 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?
Logged
ResidualVM 0.1.1 is OUT! www.residualvm.org

cameni

  • Brano Kemen
  • Outerra Administrator
  • Hero Member
  • *****
  • Posts: 6721
  • No sense of urgency.
    • outerra.com
Re: Importer and vehicle physics video
« Reply #50 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.
Logged

Midviki

  • Full Member
  • ***
  • Posts: 242
  • Nothing matters... but everything is important.
Re: Importer and vehicle physics video
« Reply #51 on: January 31, 2013, 05:42:45 pm »

I saw something from first posts, but I didn't understood exactly.



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?
Logged
ATI AMD RADEON HD 6670

hhrhhr

  • Member
  • **
  • Posts: 60
Re: Importer and vehicle physics video
« Reply #52 on: February 06, 2013, 05:06:55 pm »

a couple of questions on Vehicle interface
  • for wheels method geomob.get_joint_local_pos returns the coordinates of a static model without regard to their vertical movement. this is a bug or a feature? I wanted to get the vertical displacement of each wheel to animate the suspension, but in motion these coordinates are not changed.
  • according to wikivehicle_params structure contains properties steering_speed and centering_speed, but they do not work. I think that this is the correct names: steering and centering.
  • methods log_err, log_dbg, log_ing do not work.
  • what do these methods: get_obb_hvec and get_obb_offset?
  • which the order of elements in the structure quaternion, {x,y,z,w} or {w,x,y,z}?
« Last Edit: February 06, 2013, 05:10:30 pm by hhrhhr »
Logged

cameni

  • Brano Kemen
  • Outerra Administrator
  • Hero Member
  • *****
  • Posts: 6721
  • No sense of urgency.
    • outerra.com
Re: Importer and vehicle physics video
« Reply #53 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
Logged

hhrhhr

  • Member
  • **
  • Posts: 60
Re: Importer and vehicle physics video
« Reply #54 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.
« Last Edit: February 06, 2013, 09:42:37 pm by hhrhhr »
Logged

cameni

  • Brano Kemen
  • Outerra Administrator
  • Hero Member
  • *****
  • Posts: 6721
  • No sense of urgency.
    • outerra.com
Re: Importer and vehicle physics video
« Reply #55 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.
Logged

hhrhhr

  • Member
  • **
  • Posts: 60
Re: Importer and vehicle physics video
« Reply #56 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):
... ... ... ...

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 ;)


but if I could get the vertical displacement directly, it would be easier and would not have to do a nested group objects.
Logged

cameni

  • Brano Kemen
  • Outerra Administrator
  • Hero Member
  • *****
  • Posts: 6721
  • No sense of urgency.
    • outerra.com
Re: Importer and vehicle physics video
« Reply #57 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.
Logged

ZeosPantera

  • ||>>-Z-<<||
  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2520
  • #1 Outerra Fan Boy
    • My Youtube
Re: Importer and vehicle physics video
« Reply #58 on: February 07, 2013, 12:42:49 pm »

If I could model I would give a double wishbone a try..



And or a 4 link rear axle

Logged
"Fear accompanies the possibility of death, Calm shepherds its certainty" - General Ka Dargo

Midviki

  • Full Member
  • ***
  • Posts: 242
  • Nothing matters... but everything is important.
Re: Importer and vehicle physics video
« Reply #59 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.
Logged
ATI AMD RADEON HD 6670
Pages: 1 2 3 [4] 5