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 ... 8

Author Topic: Vehicle script [version 1.4.0]  (Read 81861 times)

giucam

  • Full Member
  • ***
  • Posts: 171
  • It's an ugly pile of bones... like me.
Vehicle script [version 1.4.0]
« on: May 03, 2013, 10:19:43 am »

Lately many vehicles have been imported in Outerra, but, while many use the same script as a base, there is not a shared effort toward a good vehicle script, and improvements can get lost in some vehicle's thread without them being applied to other vehicles.

I cannot model nor i understand how to import a model in OT, but i can develop, so i though it was time to start the ball running.
I took my script from my BMW thread and i updated it to support and use the new keys:

See here for the latest version!
You can freely use, modify and redistribute it for your project, the only requirement is to keep the license header, with the copyright assignment.


Code: [Select]
/*
    Vehicle script file
    Copyright (C) 2012 - 2013  Giulio Camuffo <giuliocamuffo@gmail.com>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public
    License as published by the Free Software Foundation; either
    version 3.0 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

//see [url]http://xtrac.outerra.com/index.fcgi/wiki/vehicle[/url] for example and documentation

// VERSION 1.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: 5.0,
        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("e90_startup.ogg"); //startup
    this.load_sound("e90_onidle.ogg"); //idle
    this.load_sound("e90_offlow.ogg");    //off
    this.load_sound("e90_onlow.ogg"); //on
    this.basepitch = [ 1, 1, 0.4, 0.4 ];             //base pitch for start, idle, off, on
    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.06, shiftUp: 8000, shiftDown: -1   },
                          { ratio: 2.40, shiftUp: 8000, shiftDown: 4500 },
                          { ratio: 1.58, shiftUp: 8000, shiftDown: 5000 },
                          { ratio: 1.19, shiftUp: 8000, shiftDown: 5500 },
                          { ratio: 1.00, shiftUp: 8000, shiftDown: 6000 },
                          { ratio: 0.87, shiftUp: -1,   shiftDown: 6000 } ];
    this.reverseGears = [ { ratio: 4.68, shiftUp: -1, shiftDown: -1 } ];

    this.differentialRatio = 3.85;
    this.efficiency = 0.7;
    this.speedLimiter = -1; // speed in m/s. a value < 0 means there's no limiter
    this.engineBrakeCoefficient = 0.1;
    this.breakingForce = 5000.0;
    this.pitchMultiplier = 1.0;
    this.automaticTransmission = false;
    //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.prev = gear;
        gear.next = prev;
        gear.index = -i - 1;
        prev = gear;
    }

    this.torque = engineTorque;
    this.shiftUp = shift_up;
    this.shiftDown = shift_down;

    return {mass:1570, steering:1.0, steering_ecf:10000, centering: 2.0, centering_ecf: 10};
}

//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 = false;
    this.gear = this.neutroGear;
    this.direction = 0;
}

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

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

function action(key, value, dt)
{
    if (key == AAuxb1 && value == 0) {
        this.automaticTransmission = !this.automaticTransmission;
        this.log_inf("Automatic transmission " + (this.automaticTransmission ? "enabled" : "disabled"));
    }

    if (value == 1 && !this.automaticTransmission) {
        switch(key) {
            case AShiftUp:
                this.shiftUp();
                break;
            case AShiftDown:
                this.shiftDown();
                break;
            default:
                break;
        }
    }
}

function shift_up()
{
    var i = this.gear.index;
    if (this.gear.next) {
        this.gear = this.gear.next;
    } else if (i == 0) {
        this.gear = this.forwardGears[0];
    } else if (i == -1) {
        this.gear = this.neutroGear;
    } else {
        return;
    }

    this.log_inf("gear " + i + " => " + this.gear.index);
}

function shift_down()
{
    var i = this.gear.index;
    if (this.gear.prev) {
        this.gear = this.gear.prev;
    } else if (i == 0) {
        this.gear = this.reverseGears[0];
    } else if (i == 1) {
        this.gear = this.neutroGear;
    } else {
        return;
    }

    this.log_inf("gear " + i + " => " + this.gear.index);
}

//invoked each frame to handle the inputs and animate the model
function update_frame(dt, engine, brake, steering) {
    steering *= 0.6;
    this.steer(-2, steering);

    var wheelsRpm = this.max_rpm();

    var rpm = wheelsRpm * this.gear.ratio * this.differentialRatio;
    if (this.automaticTransmission) {
        if (rpm < 10 && this.gear.index != 0) {
            this.gear = this.neutroGear;
            this.direction = 0;
            this.log_inf("neutro");
        }
        if (engine != 0.0) {
            if (sign(engine) != this.direction) {
                this.direction = sign(engine);
                if (this.direction == 1.0) {
                    this.shiftUp();
                } else if (this.direction == -1.0) {
                    this.shiftDown();
                }
                rpm = wheelsRpm * this.gear.ratio * this.differentialRatio;
            }

            if (rpm > this.gear.shiftUp && this.gear.next) {
                this.shiftUp();
            } else if (rpm < this.gear.shiftDown && this.gear.prev) {
                this.shiftDown();
            }
        }
    } else if (engine < 0) {
        engine = -engine;
    }

    rpm = wheelsRpm * this.gear.ratio * this.differentialRatio;

    var engineStarted = this.started && (this.sound > 0 || (this.sound == 0 && !this.snd.is_playing(0)));

    if (engineStarted && (this.speedLimiter < 0 || this.speed < this.speedLimiter)) {
        var force = engine * this.torque(rpm) * this.gear.ratio * this.differentialRatio * this.efficiency / this.wheelRadius;
        if (!this.automaticTransmission && this.gear.index < 0)
            force = -force;
        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.differentialRatio * this.gear.ratio *
                      (static_friction + (1.0 - static_friction) * rpm / this.maxRPM) / this.wheelRadius;

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

    this.animate_wheels();

    if (engineStarted) {
        if (this.gear.index == 0 && (!this.snd.is_playing(0) || this.sound != 1)) {
            this.snd.stop(0);
            this.
« Last Edit: July 05, 2013, 12:40:40 pm by giucam »
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: Vehicle script [version 1.1]
« Reply #1 on: May 03, 2013, 10:27:29 am »

P.S. cameni, can we have some way to write on screen? I'd like to write the current gear.
That fading log? .. yep, will add it.
Logged

giucam

  • Full Member
  • ***
  • Posts: 171
  • It's an ugly pile of bones... like me.
Re: Vehicle script [version 1.1]
« Reply #2 on: May 03, 2013, 10:34:35 am »

Yeah, but also a thing like that but not fading.
Logged
ResidualVM 0.1.1 is OUT! www.residualvm.org

ZeosPantera

  • ||>>-Z-<<||
  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2520
  • #1 Outerra Fan Boy
    • My Youtube
Re: Vehicle script [version 1.1]
« Reply #3 on: May 03, 2013, 11:50:17 am »

I think me means more like at the very bottom center a permanent

P  R  N  D  3  2  1

And I always envisioned a highlight box around whatever gear you are in.. So "[P] R N D 3 2 1" The contents would be variable per car also.. Some cars only have 3 gears.. some have 12.
Logged
"Fear accompanies the possibility of death, Calm shepherds its certainty" - General Ka Dargo

Chaoz

  • Full Member
  • ***
  • Posts: 156
  • newbie
Re: Vehicle script [version 1.1]
« Reply #4 on: May 03, 2013, 01:44:37 pm »

a way to change the ui on script basis should be possible
Logged

ZeosPantera

  • ||>>-Z-<<||
  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2520
  • #1 Outerra Fan Boy
    • My Youtube
Re: Vehicle script [version 1.1]
« Reply #5 on: May 03, 2013, 02:10:37 pm »

A few comment on your script. Why does everyone put the slip values so high? Only on the Tiger2 Tank have I gone to 1.1 for the forward slip because.. its a tank. Between 0.6 and 0.8 is a pretty normal value in my testing for realism on the road and on the grass. The BMW getting a bit of tire spin off the line, etc. Obviously when the ground helps determine grip there will need to be a few tweaks to all scripts.

You also didn't add the lateral slip value. "slip_lateral_coef: 1.0" which is important for making cars turn more realistically while keeping the normal slip value down.
Logged
"Fear accompanies the possibility of death, Calm shepherds its certainty" - General Ka Dargo

cameni

  • Brano Kemen
  • Outerra Administrator
  • Hero Member
  • *****
  • Posts: 6721
  • No sense of urgency.
    • outerra.com
Re: Vehicle script [version 1.1]
« Reply #6 on: May 03, 2013, 02:39:28 pm »

Do you know that slip_lateral_coef: 1.0 actually gets you back to the time when there was no distinction between the lateral and longitudinal slip, since this coef is a multiplier of the normal (longitudinal) slip value?
Logged

ZeosPantera

  • ||>>-Z-<<||
  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2520
  • #1 Outerra Fan Boy
    • My Youtube
Re: Vehicle script [version 1.1]
« Reply #7 on: May 03, 2013, 02:53:36 pm »

The hell you say.. Well on some vehicles it works. Usually the lateral grip needs to be higher than forward due to the bending of the tire's edge, digging in to the road surface as the weight shifts and she rolls.
Logged
"Fear accompanies the possibility of death, Calm shepherds its certainty" - General Ka Dargo

mLichy

  • Full Member
  • ***
  • Posts: 104
  • newbie
Re: Vehicle script [version 1.1]
« Reply #8 on: May 03, 2013, 04:00:56 pm »

A few comment on your script. Why does everyone put the slip values so high? Only on the Tiger2 Tank have I gone to 1.1 for the forward slip because.. its a tank. Between 0.6 and 0.8 is a pretty normal value in my testing for realism on the road and on the grass. The BMW getting a bit of tire spin off the line, etc. Obviously when the ground helps determine grip there will need to be a few tweaks to all scripts.

You also didn't add the lateral slip value. "slip_lateral_coef: 1.0" which is important for making cars turn more realistically while keeping the normal slip value down.


Well, I might have to turn mine down more personally, but I want the car to slip/start to slide a little, going 45MPH or so around a corner.  I feel that is pretty realistic, or even too fast for some cars to maintain grip.  Maybe for a lower riding car with thin walled street tires and hard suspension, it could still grip well at 45+MPH.   

But, I don't think it's as fun to have a car that always grips super well.  Becomes more boring to drive, since it's pretty predictable.  Also, it's fun to drift around corners.  But actually drift, and not slide the entire car like you're on ice. 

Anyways, great Idea giucam, thanks for posting this. 
Logged

Sunnyyello

  • Jr. Member
  • *
  • Posts: 30
  • Nothing to see here, move along...
Re: Vehicle script [version 1.1]
« Reply #9 on: May 03, 2013, 04:38:23 pm »

A few comment on your script. Why does everyone put the slip values so high? Only on the Tiger2 Tank have I gone to 1.1 for the forward slip because.. its a tank. Between 0.6 and 0.8 is a pretty normal value in my testing for realism on the road and on the grass. The BMW getting a bit of tire spin off the line, etc. Obviously when the ground helps determine grip there will need to be a few tweaks to all scripts.

You also didn't add the lateral slip value. "slip_lateral_coef: 1.0" which is important for making cars turn more realistically while keeping the normal slip value down.


Well, I might have to turn mine down more personally, but I want the car to slip/start to slide a little, going 45MPH or so around a corner.  I feel that is pretty realistic, or even too fast for some cars to maintain grip.  Maybe for a lower riding car with thin walled street tires and hard suspension, it could still grip well at 45 MPH.   

But, I don't think it's as fun to have a car that always grips super well.  Becomes more boring to drive, since it's pretty predictable.  Also, it's fun to drift around corners.  But actually drift, and not slide the entire car like you're on ice. 

Anyways, great Idea giucam, thanks for posting this. 


[youtube]HQ7R_buZPSo[/youtube]

I think Mr. Ken Block would agree. I know it's old but any excuse to post it is a good one!  8)

« Last Edit: May 03, 2013, 04:58:52 pm by Sunnyyello »
Logged
I could waste my time training a noob but the end result would just be a really well trained noob...

giucam

  • Full Member
  • ***
  • Posts: 171
  • It's an ugly pile of bones... like me.
Re: Vehicle script [version 1.1]
« Reply #10 on: May 03, 2013, 06:45:17 pm »

A few comment on your script. Why does everyone put the slip values so high? Only on the Tiger2 Tank have I gone to 1.1 for the forward slip because.. its a tank. Between 0.6 and 0.8 is a pretty normal value in my testing for realism on the road and on the grass. The BMW getting a bit of tire spin off the line, etc. Obviously when the ground helps determine grip there will need to be a few tweaks to all scripts.

You also didn't add the lateral slip value. "slip_lateral_coef: 1.0" which is important for making cars turn more realistically while keeping the normal slip value down.

I cannot test the car behaviour at all, so that is just a dummy value at the moment.
Logged
ResidualVM 0.1.1 is OUT! www.residualvm.org

mLichy

  • Full Member
  • ***
  • Posts: 104
  • newbie
Re: Vehicle script [version 1.1]
« Reply #11 on: May 04, 2013, 10:20:19 am »


Edit:  Forget this post.
« Last Edit: May 04, 2013, 10:40:13 am by mLichy »
Logged

giucam

  • Full Member
  • ***
  • Posts: 171
  • It's an ugly pile of bones... like me.
Re: Vehicle script [version 1.2]
« Reply #12 on: May 08, 2013, 04:36:16 pm »

Version 1.2.

The main change is the addition of the clutch. You can now rev up the engine in neutral, and releasing the clutch when still would stall the engine (the code makes sure that doesn't happen though. still, you can disable the automatic clutch by setting this.automaticClutch to false).
The automatic clutch may still feel a little slow though, it's not trivial to do an efficient algorithm.

The engine provides now 0 torque at 0 RPM, so there is a minimum RPM and a minimum quantity of "fuel" the engine takes to make sure it doesn't go below that limit.

I'd like to implement manual clutch, but unfortunately i don't have a wheel with one, and using a key is just wrong. :/

Code: [Select]
/*
    Vehicle script file
    Copyright (C) 2012 - 2013  Giulio Camuffo <giuliocamuffo@gmail.com>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public
    License as published by the Free Software Foundation; either
    version 3.0 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

//see http://xtrac.outerra.com/index.fcgi/wiki/vehicle for example and documentation

// VERSION 1.2

//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: 5.0,
        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("e90_startup.ogg"); //startup
    this.load_sound("e90_onidle.ogg"); //idle
    this.load_sound("e90_offlow.ogg"); //off
    this.load_sound("e90_onlow.ogg"); //on
    this.basepitch = [ 1, 1, 0.4, 0.4 ];             //base pitch for start, idle, off, on
    this.add_sound_emitter("wheel_FL");

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

    this.torquePoints = [ { rpm: 200,    torque: 0},
                          { 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.06, shiftUp: 8000, shiftDown: -1   },
                          { ratio: 2.40, shiftUp: 8000, shiftDown: 4500 },
                          { ratio: 1.58, shiftUp: 8000, shiftDown: 5000 },
                          { ratio: 1.19, shiftUp: 8000, shiftDown: 5500 },
                          { ratio: 1.00, shiftUp: 8000, shiftDown: 6000 },
                          { ratio: 0.87, shiftUp: -1,   shiftDown: 6000 } ];
    this.reverseGears = [ { ratio: 4.68, shiftUp: -1, shiftDown: -1 } ];

    this.differentialRatio = 3.85;
    this.efficiency = 0.9;
    this.speedLimiter = 5; // maximum speed in m/s. a value < 0 means there's no limiter
    this.engineBrakeCoefficient = 0.4;
    this.breakingForce = 5000.0;
    this.pitchMultiplier = 1.5;
    this.automaticTransmission = false;
    this.automaticClutch = true;
    this.engineInertia = 0.05;
    this.minimumRPM = 1000;
    this.minimum = 0.2;
    //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.prev = gear;
        gear.next = prev;
        gear.index = -i - 1;
        prev = gear;
    }

    this.torque = engineTorque;
    this.shiftUp = shift_up;
    this.shiftDown = shift_down;
    this.selectGear = select_gear;
    this.die = die;
    this.updateAutomaticTransmission = automatic_transmission;
    this.animate = animate;

    return {mass:1570, steering:1.0, steering_ecf:10000, centering: 2.0, centering_ecf: 10};
}

//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 = false;
    this.gear = this.neutroGear;
    this.direction = 0;
    this.engineRPM = 0;
    this.appliedTorque = 0;
    this.starting = false;
    this.clutch = 0.0;
    this.clutchState = 1;
}

//invoked when engine starts or stops
function engine(start) {
    if (start) {
        this.started = false;
        this.soundId = 0;
        this.starting = true;
    } else {
        this.started = false;
    }
}

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

function action(key, value, dt)
{
    if (key == AAuxb1 && value == 0) {
        this.automaticTransmission = !this.automaticTransmission;
        this.log_inf("Automatic transmission " + (this.automaticTransmission ? "enabled" : "disabled"));
    }

    if (value == 1 && !this.automaticTransmission) {
        switch(key) {
            case AShiftUp:
                this.shiftUp();
                break;
            case AShiftDown:
                this.shiftDown();
                break;
            default:
                break;
        }
    }
}

function select_gear(gear)
{
    var i = this.gear.index;
    this.gear = gear;
    this.log_inf("gear " + i + " => " + this.gear.index);
}

function shift_up()
{
    var i = this.gear.index;
    if (this.gear.next) {
        this.selectGear(this.gear.next);
    } else if (i == 0) {
        this.selectGear(this.forwardGears[0]);
    } else if (i == -1) {
        this.selectGear(this.neutroGear);
    }
}

function shift_down()
{
    var i = this.gear.index;
    if (this.gear.prev) {
        this.selectGear(this.gear.prev);
    } else if (i == 0) {
        this.selectGear(this.reverseGears[0]);
    } else if (i == 1) {
        this.selectGear(this.neutroGear);
    }
}

function die()
{
    this.started = false;
}

function automatic_transmission(engine)
{
    if (this.engineRPM < 10 && this.gear.index != 0) {
        this.gear = this.neutroGear;
        this.direction = 0;
        this.selectGear(this.neutroGear);
    }
    if (engine != 0.0) {
        if (sign(engine) != this.direction) {
            this.direction = sign(engine);
            if (this.direction == 1.0) {
                this.selectGear(this.forwardGears[0]);
            } else if (this.direction == -1.0) {
                this.selectGear(this.reverseGears[0]);
            }
        }

        if (this.engineRPM > this.gear.shiftUp && this.gear.next) {
            this.shiftUp();
        } else if (this.engineRPM < this.gear.shiftDown && this.gear.prev) {
            this.shiftDown();
        }
    }
}

function animate()
{
    this.animate_wheels();
}

//invoked each frame to handle the inputs and animate the model
function update_frame(dt, engine, brake, steering) {
    steering *= 0.6;
    this.steer(-2, steering);

    var wheelsRpm = this.max_rpm();
    if (sign(this.speed()) != sign(this.gear.index) && this.gear.index != 0) {
        wheelsRpm = 0;
    }

    if (this.automaticTransmission) {
        this.updateAutomaticTransmission(engine);
    }
    if (engine < 0) {
        engine = -engine;
    }

    var clutched = this.clutchState == 1 && this.gear.index != 0;

    var clutchRPM = this.minimumRPM + 2000;
    if (this.automaticClutch) {
        if (clutched && this.engineRPM < this.minimumRPM) {
            this.clutchState = 0;
        } else if (!clutched && this.engineRPM > clutchRPM) {
            this.clutchState = 1;
        }
        clutched = this.clutchState == 1 && this.gear.index != 0;
    }

    var w = wheelsRpm * this.gear.ratio * this.differentialRatio;
    if (clutched) {
        this.clutch = (w > this.minimumRPM ? this.minimumRPM : w) / this.minimumRPM;

        // This makes an horizontal S-like shape. (mirrored, like Z)
        var f = this.clutch;
        if (f < 0.5) {
            f = f * 2 - 1;
            this.clutch = -(f * f * f * f - 1) / 5;
        } else {
            f = 2 * f - 1;
            this.clutch = f * f * f * f + 0.2;
        }
        this.clutch += 0.2;

        var r = this.engineRPM / clutchRPM;
        this.clutch *= (r > 1 ? 1 : (r < 0 ? 0 : r));

        if (this.clutch > 1) {
            this.clutch = 1;
        }
    } else if (!clutched) {
        this.clutch = 0;
    }

    this.appliedTorque = 0;
    if (this.starting) {
        if (this.engineRPM > this.minimumRPM) {
            this.starting = false;
            this.started = true;
        } else {
            this.appliedTorque = 100 * (1 - this.engineRPM / this.minimumRPM);
        }
    }

    var oldRPM = this.engineRPM;

    if (this.gear.index != 0) {
        this.engineRPM = this.engineRPM * (1 - this.clutch) + wheelsRpm * this.clutch * this.gear.ratio * this.differentialRatio;
    }

    var engineStarted = this.started;
    if (engineStarted || this.starting) {
        if (this.engineRPM < this.minimumRPM && engine < this.minimum) {
            engine = this.minimum;
        }
        if (Math.abs(this.speed()) < this.speedLimiter) {
            this.appliedTorque += engine * this.torque(this.engineRPM);
        }
    }

    var friction = 0.1;
    this.appliedTorque -= sign(this.engineRPM) * this.maxPowerTP.torque * this.engineBrakeCoefficient *
                          (friction + (1.0 - friction) * this.engineRPM / this.maxRPM);

    this.engineRPM = this.engineRPM + this.appliedTorque * dt / this.engineInertia;
    if (oldRPM < 300) {
        this.die();
    }

    var tq = this.appliedTorque + this.engineInertia * (oldRPM - this.engineRPM) / dt;
    var force = tq * this.clutch * this.gear.ratio * this.differentialRatio * this.efficiency / this.wheelRadius;
    if (this.gear.index < 0)
        force = -force;

    this.wheel_force(2, force / 2);
    this.wheel_force(3, force / 2);

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

    this.animate();

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

    var pitch = this.pitchMultiplier * (this.engineRPM - this.minimumRPM) / this.maxRPM;
    this.snd.set_pitch(0, pitch + this.basepitch[this.soundId]);
    var g = this.engineRPM / this.minimumRPM;
    this.snd.set_gain(0, Math.min(g * g * g, 1.0));
}
Logged
ResidualVM 0.1.1 is OUT! www.residualvm.org

M7

  • Hero Member
  • *****
  • Posts: 736
  • newbie
Re: Vehicle script [version 1.2]
« Reply #13 on: May 08, 2013, 10:43:10 pm »

Just tried it, didn't figured the clutch yet so i just put it to automatic clutch to quickly testdrive,  but in either mode, the car moves like  molass  ???   

Also i'm wondering if you could reimport the BMW and include another bone other than the wheels. I'd like to test other sounds using a manual transmission and the BMW being the only vehicle with  manual transmission. The problem is that you set the sound emiter to one of the wheel . Doesn't seems to be problematic with the default sound but when  replace it , it sound really weird  because when the wheel turn, the sound kind of woble.
Logged

mLichy

  • Full Member
  • ***
  • Posts: 104
  • newbie
Re: Vehicle script [version 1.2]
« Reply #14 on: May 08, 2013, 11:06:32 pm »

Yeah. I don't think we want to attach the engine audio to the wheel?
I'd had the same issue. Mines attached to the cars hood for now.

Even for tire slip audio, we might want to attach to the suspension or chassis maybe. Rotating audio like that sounds wrong.
Logged
Pages: [1] 2 3 ... 8