Vehicles
From OpenSimulator
(→DYNAMIC) |
(→Historic Only) |
||
(40 intermediate revisions by 5 users not shown) | |||
Line 1: | Line 1: | ||
+ | {{obsolete}} | ||
+ | == Historic Only == | ||
+ | THis article is kept only for historic reasons. This information is no longer valid | ||
+ | |||
== Summary == | == Summary == | ||
− | August 2009: Kitto Flora is revising the OdePlugin files in an attempt to provide SL-compatible VEHICLE functionality to OpenSimulator. A couple of test regions have been provided by Bri Hasp, these are Sea-3 and Sea-4 in OSgrid. You may visit there and test vehicles but please clean up after. The revised | + | August 2009: Kitto Flora is revising the OdePlugin files in an attempt to provide SL-compatible VEHICLE functionality to OpenSimulator. A couple of test regions have been provided by Bri Hasp, these are Sea-3 and Sea-4 in OSgrid. You may visit there and test vehicles but please clean up after. The regions will frequently be restarted to test revisions. The revised Open Simulator files are being made available as a git branch, check here to see what may or may not work. |
+ | |||
+ | == News == | ||
+ | ==== Oct 24 2009 (apx) PROJECT HALTED. ==== | ||
+ | At about this date opensim trunk was merged into the vehicles branch bringing in the packet prioritization modifications. It had already been pointed out that those modifications caused problems with the display of motion of physical objects. The result of this merge is that a physical object that is simply rotating is no longer updated on the viewer screen. Debug messages show that ODE is indeed rotating the object, and sending update requests but it appears that the packet system is not transmitting updates to the viewer. This makes it impossible to see the results of the work in progress - adding functions such as llRotLookAt(). Work is therefore suspended until this packet problem is fixed. See http://opensimulator.org/mantis/view.php?id=4336 | ||
+ | ==== Oct 22 2009 ==== | ||
+ | * Vehicle branch is merged into opensim. Any version r11303 or later will have the VEHICLE capabilities (and problems) listed below available. | ||
+ | ==== Oct 6 2009 ==== | ||
+ | * Sea-3/Sea4 are down because osgrid is being upgraded/fixed to deal with other ongoing problems, and the vehicle branch is no longer compatible. I am waiting for trunk to stabilize before proceeding. | ||
+ | Meanwhile I am investigating the details of SL physics parameters. | ||
+ | ==== Sept 28 2009 ==== | ||
+ | * Cause of poor update rate of rotating physical prims found and fixed. | ||
+ | ==== Sept 24 2009 ==== | ||
+ | * OpenSimulator Vehicle version running at Sea-3 and Sea-4 in OSgrid have been adjusted to improve the Vertical Attractor. | ||
+ | * The Tako sailboat works somewhat, but the listen() event on channel 0 fails after 30 seconds or so, resulting in some loss of control. | ||
+ | * Camera controls are still a problem, it appears that camera position depends on which prim is clicked to 'sit'. (Camera fails to reference to root prim of a link-set???). | ||
+ | * timer() event will keep working if llSetTimer(float) is called at every timer() event. | ||
+ | * Racecar updated to 'ODB VEH racecar10', deals with changed Vertical Attractor; timer() used in place of llSensor(), resulting in much lower simulator CPU load. Available in sea-3. | ||
== Terminology == | == Terminology == | ||
Here some terms are defined so that when we communicate we are talking about the same things. | Here some terms are defined so that when we communicate we are talking about the same things. | ||
− | === Vehicle === | + | ==== Vehicle ==== |
Any object or link-set that moves. It is usually rideable. It may be Physical or not. | Any object or link-set that moves. It is usually rideable. It may be Physical or not. | ||
Line 25: | Line 46: | ||
==== Dynamic ==== | ==== Dynamic ==== | ||
− | Motion system used by Physical objects, applied by such functions as llSetForce() and llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <...>). | + | Motion system used by Physical objects, applied by such functions as llSetForce() and llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <...>). |
− | + | ||
== About This Project == | == About This Project == | ||
The objectives of this project are: | The objectives of this project are: | ||
# To provide VEHICLE associated LSL functions within OpenSimulator that are compatible with Second Life functionality. This means trying to get them really close, but as we are trying to emulate complex HAVOK functions using what is available in ODE they may be only close to the SL functions. | # To provide VEHICLE associated LSL functions within OpenSimulator that are compatible with Second Life functionality. This means trying to get them really close, but as we are trying to emulate complex HAVOK functions using what is available in ODE they may be only close to the SL functions. | ||
− | # To clean up the OdePlugin files. Over many revisions and add-ons they | + | # To clean up the OdePlugin files. Over many revisions and add-ons they have become somewhat non-optimal. In particular the 'Move' operation that makes objects move around needs to be very clean and smooth so that the update rate remains high. |
# Maintain the existing non-VEHICLE dynamic functions and fix errors where found. | # Maintain the existing non-VEHICLE dynamic functions and fix errors where found. | ||
− | |||
== Vehicle LSL Functions in revised OpenSimulator == | == Vehicle LSL Functions in revised OpenSimulator == | ||
There are three categories of LSL functions that are used by Vehicles: Kinematic, Dynamic and VEHICLE. These are listed below with information on their current status within the revised OpenSimulator. (Not the general release at this time.) | There are three categories of LSL functions that are used by Vehicles: Kinematic, Dynamic and VEHICLE. These are listed below with information on their current status within the revised OpenSimulator. (Not the general release at this time.) | ||
− | Kinematic vehicle motion can be used by non-physical objects. VEHICLE motion and the associated functions '''ONLY''' apply to objects that are set to a VEHICLE_TYPE of AIRPLANE, BALLOON, BOAT, CAR or SLED. Dynamic functions '''ONLY''' apply (at this time) to VEHICLE_TYPE_NONE, which is the default condition of an object. (In SL it appears that one can use Dynamic functions on a VEHICLE, but to keep things simple at the start of this project such a combination is not | + | Kinematic vehicle motion can be used by non-physical objects. VEHICLE motion and the associated functions '''ONLY''' apply to objects that are set to a VEHICLE_TYPE of AIRPLANE, BALLOON, BOAT, CAR or SLED. Dynamic functions '''ONLY''' apply (at this time) to VEHICLE_TYPE_NONE, which is the default condition of an object. (In SL it appears that one can use Dynamic functions on a VEHICLE, but to keep things simple at the start of this project such a combination is ignored.) |
+ | |||
+ | == Known Problems == | ||
+ | # timer() event ceases about 10 seconds after Vehicle moves. Does not restart until many seconds after Vehicle stops. '''Work-around:''' Use llSensor() for a non-existent object at short range and no_sensor() event to re-trigger it. This produces about 1000 events per second. Divide down to produce more reasonable rates. | ||
+ | # llSetBuoyancy() is not hooked to physics methods. LSL engine problem. '''Work-around:''' None. Big problem for non-VEHICLE vehicles. | ||
+ | # llSetHoverHeight() is not hooked to physics methods. LSL engine problem. '''Work-around:''' None. Big problem for non VEHICLE vehicles. | ||
+ | # llSetVehicleFlags() and llRemoveVehicleFlags() are not hooked to physics methods, and may cause simulator crash. LSL engine problem. '''Work-around:''' None, but the VEHICLE_TYPE presets are setting necessary flags. | ||
+ | # Prim parameters like Material are not being saved. '''Work-around:''' Set by script on rez or whenever used. | ||
+ | # Script state is not maintained between Take and Rez. '''Work-around:''' on_rez() Reset script and set *everything* again. | ||
+ | # Border Crossing is bad. Vehicle will be killed and Av unseated and left drifting through target region. '''Work-around:''' Quickly double-click on Map to tele-port to old region. Drag vehicle back and reset it. | ||
== VEHICLE Scripting Notes == | == VEHICLE Scripting Notes == | ||
− | #(Not really scripting , but very important) DO NOT attempt to drive a VEHICLE across the Region boundary. If you do your Av will be orbited. You may be able to recover by Map double-click TP to a nearby Region. The VEHICLE object is usually killed, and sitting at edge of the destination region. | + | # (Not really scripting , but very important) DO NOT attempt to drive a VEHICLE across the Region boundary. If you do your Av will be orbited. You may be able to recover by Map double-click TP to a nearby Region. The VEHICLE object is usually killed, and sitting at edge of the destination region. |
− | #In revised OpenSimulator the function llSetVehicleType(VEHICLE_TYPE_xxx), where xxx is AIRPLANE, BALLOON, BOAT, CAR or SLED, pre-sets all the applicable VEHICLE parameters to reasonable numbers. If you wish to change any of these pre-set parameters do so after asserting llSetVehicleType(VEHICLE_TYPE_xxx). | + | # In revised OpenSimulator the function llSetVehicleType(VEHICLE_TYPE_xxx), where xxx is AIRPLANE, BALLOON, BOAT, CAR or SLED, pre-sets all the applicable VEHICLE parameters to reasonable numbers. If you wish to change any of these pre-set parameters do so after asserting llSetVehicleType(VEHICLE_TYPE_xxx). |
− | #At present it appears that some conditions | + | # At present it appears that some conditions within an instantiated scripted object are not maintained after a Region restart, and possibly between take and rez. Therefore you should assert llSetVehicleType(VEHICLE_TYPE_xxx) when the driver sits and llSetVehicleType(VEHICLE_TYPE_NONE)when the driver stands, and probably on_rez. |
− | #The advice above also applies to camera controls. Assert llSetCameraxxx() on sit and llClearCameraParams() on stand. | + | # The advice above also applies to camera controls. Assert llSetCameraxxx() on sit and llClearCameraParams() on stand. (At present there seems to be bugs in the Camera Control system, the camera will go underground!) |
− | #The advice above is also true of Material Type. Land vehicles need the 'wheels' to be PRIM_MATERIAL_GLASS. The script(s) must llSetPrimitiveParams([PRIM_MATERIAL, PRIM_MATERIAL_GLASS]) in every prim that touches the ground, when the rider sits, for reliable operation. Use a link mesage from the root to daughter prim scripts. | + | # The advice above is also true of Material Type. Land vehicles need the 'wheels' to be PRIM_MATERIAL_GLASS. The script(s) must llSetPrimitiveParams([PRIM_MATERIAL, PRIM_MATERIAL_GLASS]) in every prim that touches the ground, when the rider sits, for reliable operation. Use a link mesage from the root to daughter prim scripts. |
− | #Use llSetStatus(STATUS_PHYSICS, TRUE) to enable the VEHICLE, usually when the driver sits. Use llSetStatus(STATUS_PHYSICS, FALSE) to disable the VEHICLE, usually when the driver stands. | + | # Use llSetStatus(STATUS_PHYSICS, TRUE) to enable the VEHICLE, usually when the driver sits. Use llSetStatus(STATUS_PHYSICS, FALSE) to disable the VEHICLE, usually when the driver stands. |
− | #It appears that the timer() event freezes while a Vehicle is in motion, so do not rely | + | # It appears that the timer() event freezes while a Vehicle is in motion, so do not rely in Timer() to update things like steering or velocity. See Known Problems for a work-around. |
+ | |||
+ | == VEHICLE Scripting Examples == | ||
+ | Below are some initial (and very similar) Vehicle scripting examples, implementing a sort of go kart, and the second a motorboat. The motorboat script is a derivative work based on the go kart script. | ||
+ | |||
+ | |||
+ | *** Note that these scripts are works in progress and may or may not impact the performance of your region negatively. | ||
+ | |||
+ | |||
+ | Car or Go kart script: | ||
+ | |||
+ | <source lang=LSL> | ||
+ | // Very simple vehicle script, mod for OpenSimulator & ODE & VEHICLE code | ||
+ | // By Kitto Flora September 2009 | ||
+ | |||
+ | integer Private = 1; // Change to 1 to prevent others riding. | ||
+ | |||
+ | vector Sitpos = <0.35,0,0.35>; | ||
+ | vector SitrotV = <0,-20,0>; | ||
+ | rotation Sitrot; | ||
+ | integer tt; | ||
+ | key oldagent; | ||
+ | key agent; | ||
+ | float forward_power = 12; //Power used to go forward (1 to 30) | ||
+ | float reverse_power = -6; //Power ued to go reverse (-1 to -30) | ||
+ | float turning_ratio = 2.0; //How sharply the vehicle turns. Less is more sharply. (.1 to 10) | ||
+ | integer turncount; | ||
+ | string Wheeldir = "WC"; | ||
+ | string NewWheeldir = "WC"; | ||
+ | string Wheelrot = "S"; | ||
+ | string NewWheelrot = "S"; | ||
+ | integer scount; | ||
+ | integer Speed; | ||
+ | integer Run; | ||
+ | |||
+ | string sit_message = "Ride"; //Sit message | ||
+ | string not_owner_message = "You are not the owner of this vehicle, buy a copy for 0$ and have your own to test in this sim. It will not work in other Open Sim Regions."; //Not owner message | ||
+ | |||
+ | setVehicle() | ||
+ | { | ||
+ | //car | ||
+ | llSetVehicleType(VEHICLE_TYPE_CAR); | ||
+ | llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY, 0.2); | ||
+ | llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_EFFICIENCY, 0.80); | ||
+ | llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_TIMESCALE, 0.10); | ||
+ | llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_TIMESCALE, 0.10); | ||
+ | llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_TIMESCALE, 1.0); | ||
+ | llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE, 0.1); | ||
+ | llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_TIMESCALE, 0.1); | ||
+ | llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE, 0.1); | ||
+ | llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, <10.0, 2.0, 1000.0>); | ||
+ | llSetVehicleVectorParam(VEHICLE_ANGULAR_FRICTION_TIMESCALE, <0.1, 0.1, 0.1>); | ||
+ | llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY, 0.50); | ||
+ | llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_TIMESCALE, 0.50); | ||
+ | |||
+ | } | ||
+ | Init() | ||
+ | { | ||
+ | Sound(0); | ||
+ | llSetStatus(STATUS_PHYSICS, FALSE); | ||
+ | vector here = llGetPos(); | ||
+ | float h = llGround(<0,0,0>) + 0.52; | ||
+ | vector rotv = llRot2Euler(llGetRot()); | ||
+ | rotation rot = llEuler2Rot(<0,0,rotv.z>); | ||
+ | llSetPos(<here.x, here.y,h>); | ||
+ | llSetRot(rot); | ||
+ | Sitrot = llEuler2Rot(DEG_TO_RAD * SitrotV); | ||
+ | llSetVehicleType(VEHICLE_TYPE_NONE); | ||
+ | llMessageLinked(LINK_ALL_OTHERS, 0, "S", NULL_KEY); // wheels stop | ||
+ | llMessageLinked(LINK_ALL_OTHERS, 0, "WC", NULL_KEY); // wheels straight | ||
+ | Run = 0; | ||
+ | } | ||
+ | |||
+ | SetMaterial() | ||
+ | { | ||
+ | llSetPrimitiveParams([PRIM_MATERIAL, PRIM_MATERIAL_GLASS]); | ||
+ | llMessageLinked(LINK_ALL_OTHERS, 0, "SetMat", NULL_KEY); // Tell daughter pims on ground to be glass | ||
+ | } | ||
+ | |||
+ | Sound(integer n) | ||
+ | { | ||
+ | integer oldn; | ||
+ | if(n != oldn) | ||
+ | { | ||
+ | oldn = n; | ||
+ | if(n == 2) | ||
+ | { | ||
+ | llLoopSound("RUNNING",1); | ||
+ | } | ||
+ | else if(n == 1) | ||
+ | { | ||
+ | llLoopSound("IDLE",1); | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | llStopSound(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | default | ||
+ | { | ||
+ | state_entry() | ||
+ | { | ||
+ | Init(); | ||
+ | llSetSitText(sit_message); | ||
+ | // forward-back,left-right,updown | ||
+ | llSitTarget(Sitpos, Sitrot); | ||
+ | llStopSound(); | ||
+ | } | ||
+ | |||
+ | on_rez(integer rn){ | ||
+ | llResetScript(); | ||
+ | } | ||
+ | |||
+ | changed(integer change) | ||
+ | { | ||
+ | if ((change & CHANGED_LINK) == CHANGED_LINK) | ||
+ | { | ||
+ | agent = llAvatarOnSitTarget(); | ||
+ | if (agent != NULL_KEY) | ||
+ | { | ||
+ | if( (agent != llGetOwner()) && (Private == 1) ) | ||
+ | { | ||
+ | llSay(0, not_owner_message); | ||
+ | llUnSit(agent); | ||
+ | // not functional llPushObject(agent, <0,0,50>, ZERO_VECTOR, FALSE); | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | //llTriggerSound("car_start",1); | ||
+ | // llMessageLinked(LINK_ALL_CHILDREN , 0, "WHEEL_DRIVING", NULL_KEY); | ||
+ | oldagent = agent; | ||
+ | setVehicle(); | ||
+ | SetMaterial(); | ||
+ | llSleep(.4); | ||
+ | llSetStatus(STATUS_PHYSICS, TRUE); | ||
+ | llSleep(.1); | ||
+ | Run = 1; | ||
+ | //Sensor is to make a crude Timer as TimerEvent fails on vehicles | ||
+ | llSensor("Non-Entity",NULL_KEY,PASSIVE,1.0, PI_BY_TWO); | ||
+ | |||
+ | llRequestPermissions(agent, PERMISSION_TRIGGER_ANIMATION | PERMISSION_TAKE_CONTROLS); | ||
+ | Sound(1); | ||
+ | } | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | Init(); | ||
+ | llSleep(.4); | ||
+ | llReleaseControls(); | ||
+ | llMessageLinked(LINK_ALL_OTHERS, 0, "S", NULL_KEY); | ||
+ | Run = 0; | ||
+ | llStopSound(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | touch_start(integer tn){ | ||
+ | } | ||
+ | |||
+ | run_time_permissions(integer perm) | ||
+ | { | ||
+ | if (perm) | ||
+ | { | ||
+ | llTakeControls(CONTROL_FWD | CONTROL_BACK | CONTROL_DOWN | CONTROL_UP | CONTROL_RIGHT | | ||
+ | CONTROL_LEFT | CONTROL_ROT_RIGHT | CONTROL_ROT_LEFT, TRUE, FALSE); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | control(key id, integer level, integer edge) | ||
+ | { | ||
+ | integer reverse=1; | ||
+ | vector angular_motor; | ||
+ | |||
+ | //get current speed | ||
+ | vector vel = llGetVel(); | ||
+ | float speed = llVecMag(vel); | ||
+ | |||
+ | //car controls | ||
+ | if(level & CONTROL_FWD) | ||
+ | { | ||
+ | llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, <10.0, 2.0, 1000.0>); | ||
+ | llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <forward_power,0,0>); | ||
+ | reverse=1; | ||
+ | NewWheelrot = "F"; | ||
+ | Speed = 20; | ||
+ | } | ||
+ | if(level & CONTROL_BACK) | ||
+ | { | ||
+ | llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, <10.0, 2.0, 1000.0>); | ||
+ | llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <reverse_power,0,0>); | ||
+ | reverse = -1; | ||
+ | NewWheelrot = "R"; | ||
+ | Speed = 10; | ||
+ | } | ||
+ | |||
+ | if(level & (CONTROL_RIGHT|CONTROL_ROT_RIGHT)) | ||
+ | { | ||
+ | angular_motor.z -= speed / turning_ratio * reverse; | ||
+ | NewWheeldir = "WR"; | ||
+ | turncount = 10; | ||
+ | } | ||
+ | |||
+ | if(level & (CONTROL_LEFT|CONTROL_ROT_LEFT)) | ||
+ | { | ||
+ | angular_motor.z += speed / turning_ratio * reverse; | ||
+ | NewWheeldir = "WL"; | ||
+ | turncount = 10; | ||
+ | } | ||
+ | |||
+ | llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION, angular_motor); | ||
+ | if(turncount > 0) | ||
+ | { | ||
+ | turncount--; | ||
+ | } | ||
+ | if(turncount == 1) | ||
+ | { | ||
+ | NewWheeldir = "WC"; | ||
+ | } | ||
+ | if(Wheeldir != NewWheeldir){ | ||
+ | Wheeldir = NewWheeldir; | ||
+ | llMessageLinked(LINK_ALL_OTHERS, 0, Wheeldir, NULL_KEY); | ||
+ | } | ||
+ | if(Wheelrot != NewWheelrot){ | ||
+ | Wheelrot = NewWheelrot; | ||
+ | llMessageLinked(LINK_ALL_OTHERS, 0, Wheelrot, NULL_KEY); | ||
+ | } | ||
+ | } //end control | ||
+ | |||
+ | //Sensor is to make a crude Timer as TimerEvent fails on vehicles | ||
+ | no_sensor() | ||
+ | { | ||
+ | if(scount < 1000) | ||
+ | { | ||
+ | scount++; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | scount = 0; | ||
+ | // This happens about once per second | ||
+ | if(Speed > 0) Speed--; | ||
+ | |||
+ | if(Speed > 2) Sound(2); | ||
+ | |||
+ | if(Speed == 1) { | ||
+ | llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, <1.0, 2.0, 1000.0>); | ||
+ | llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <0,0,0>); | ||
+ | llMessageLinked(LINK_ALL_OTHERS, 0, "S", NULL_KEY); | ||
+ | Sound(1); | ||
+ | Wheelrot = "S"; | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | if(Run == 1) | ||
+ | llSensor("Non-Entity",NULL_KEY,PASSIVE,1.0, PI_BY_TWO); | ||
+ | } | ||
+ | |||
+ | } //end default | ||
+ | |||
+ | |||
+ | |||
+ | </source> | ||
+ | |||
+ | Motorboat script: | ||
+ | |||
+ | <source lang=LSL> | ||
+ | |||
+ | // Very simple vehicle script, mod for OpenSimulator & ODE & VEHICLE code | ||
+ | // By Kitto Flora September 2009 | ||
+ | |||
+ | // modified by Hiro Protagonist for basic aquatic motorcraft | ||
+ | // September 2009 | ||
+ | |||
+ | integer Private = 1; // Change to 1 to prevent others riding. | ||
+ | |||
+ | vector Sitpos = <0.35,0,0.35>; | ||
+ | vector SitrotV = <0,-20,0>; | ||
+ | rotation Sitrot; | ||
+ | integer tt; | ||
+ | key oldagent; | ||
+ | key agent; | ||
+ | float forward_power = 8; //Power used to go forward (1 to 30) | ||
+ | float reverse_power = -3; //Power ued to go reverse (-1 to -30) | ||
+ | float turning_ratio = 1.0; //How sharply the vehicle turns. Less is more sharply. (.1 to 10) | ||
+ | integer scount; | ||
+ | integer Speed; | ||
+ | integer Run; | ||
+ | |||
+ | string sit_message = "Man the Helm"; //Sit message | ||
+ | string not_owner_message = "You are not the owner of this vehicle, buy a copy for 0$ and have your own to test in this sim. It will not work in other Open Sim Regions."; //Not owner message | ||
+ | |||
+ | setVehicle() | ||
+ | { | ||
+ | //boat | ||
+ | llSetVehicleType(VEHICLE_TYPE_BOAT); | ||
+ | llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY, 0.2); | ||
+ | llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_EFFICIENCY, 0.80); | ||
+ | llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_TIMESCALE, 0.10); | ||
+ | llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_TIMESCALE, 0.10); | ||
+ | llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_TIMESCALE, 1.0); | ||
+ | llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE, 0.1); | ||
+ | llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_TIMESCALE, 0.1); | ||
+ | llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE, 0.1); | ||
+ | llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, <10.0, 2.0, 1000.0>); | ||
+ | llSetVehicleVectorParam(VEHICLE_ANGULAR_FRICTION_TIMESCALE, <0.1, 0.1, 0.1>); | ||
+ | llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY, 0.250); | ||
+ | llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_TIMESCALE, 0.250); | ||
+ | |||
+ | } | ||
+ | Init() | ||
+ | { | ||
+ | Sound(0); | ||
+ | llSetBuoyancy(1); | ||
+ | llSetStatus(STATUS_PHYSICS, FALSE); | ||
+ | vector here = llGetPos(); | ||
+ | float h = llWater(<0,0,0>) + 0.22; | ||
+ | vector rotv = llRot2Euler(llGetRot()); | ||
+ | rotation rot = llEuler2Rot(<0,0,rotv.z>); | ||
+ | llSetPos(<here.x, here.y,h>); | ||
+ | llSetRot(rot); | ||
+ | Sitrot = llEuler2Rot(DEG_TO_RAD * SitrotV); | ||
+ | llSetVehicleType(VEHICLE_TYPE_NONE); | ||
+ | llMessageLinked(LINK_ALL_OTHERS, 0, "S", NULL_KEY); // wheels stop | ||
+ | llMessageLinked(LINK_ALL_OTHERS, 0, "WC", NULL_KEY); // wheels straight | ||
+ | Run = 0; | ||
+ | } | ||
+ | |||
+ | SetMaterial() | ||
+ | { | ||
+ | llSetPrimitiveParams([PRIM_MATERIAL, PRIM_MATERIAL_WOOD]); | ||
+ | // llMessageLinked(LINK_ALL_OTHERS, 0, "SetMat", NULL_KEY); // Tell daughter pims on ground to be glass | ||
+ | } | ||
+ | |||
+ | Sound(integer n) | ||
+ | { | ||
+ | integer oldn; | ||
+ | if(n != oldn) | ||
+ | { | ||
+ | oldn = n; | ||
+ | if(n == 2) | ||
+ | { | ||
+ | // llLoopSound("RUNNING",1); | ||
+ | } | ||
+ | else if(n == 1) | ||
+ | { | ||
+ | // llLoopSound("IDLE",1); | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | // llStopSound(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | default | ||
+ | { | ||
+ | state_entry() | ||
+ | { | ||
+ | Init(); | ||
+ | llSetSitText(sit_message); | ||
+ | // forward-back,left-right,updown | ||
+ | llSitTarget(Sitpos, Sitrot); | ||
+ | // llStopSound(); | ||
+ | } | ||
+ | |||
+ | on_rez(integer rn){ | ||
+ | llResetScript(); | ||
+ | } | ||
+ | |||
+ | changed(integer change) | ||
+ | { | ||
+ | if ((change & CHANGED_LINK) == CHANGED_LINK) | ||
+ | { | ||
+ | agent = llAvatarOnSitTarget(); | ||
+ | if (agent != NULL_KEY) | ||
+ | { | ||
+ | if( (agent != llGetOwner()) && (Private == 1) ) | ||
+ | { | ||
+ | llSay(0, not_owner_message); | ||
+ | llUnSit(agent); | ||
+ | // not functional llPushObject(agent, <0,0,50>, ZERO_VECTOR, FALSE); | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | //llTriggerSound("car_start",1); | ||
+ | // llMessageLinked(LINK_ALL_CHILDREN , 0, "WHEEL_DRIVING", NULL_KEY); | ||
+ | oldagent = agent; | ||
+ | setVehicle(); | ||
+ | SetMaterial(); | ||
+ | llSleep(.4); | ||
+ | llSetStatus(STATUS_PHYSICS, TRUE); | ||
+ | llSleep(.1); | ||
+ | Run = 1; | ||
+ | //Sensor is to make a crude Timer as TimerEvent fails on vehicles | ||
+ | llSensor("Non-Entity",NULL_KEY,PASSIVE,1.0, PI_BY_TWO); | ||
+ | |||
+ | llRequestPermissions(agent, PERMISSION_TRIGGER_ANIMATION | PERMISSION_TAKE_CONTROLS); | ||
+ | Sound(1); | ||
+ | } | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | Init(); | ||
+ | llSleep(.4); | ||
+ | llReleaseControls(); | ||
+ | llMessageLinked(LINK_ALL_OTHERS, 0, "S", NULL_KEY); | ||
+ | Run = 0; | ||
+ | llStopSound(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | touch_start(integer tn){ | ||
+ | } | ||
+ | |||
+ | run_time_permissions(integer perm) | ||
+ | { | ||
+ | if (perm) | ||
+ | { | ||
+ | llTakeControls(CONTROL_FWD | CONTROL_BACK | CONTROL_DOWN | CONTROL_UP | CONTROL_RIGHT | | ||
+ | CONTROL_LEFT | CONTROL_ROT_RIGHT | CONTROL_ROT_LEFT, TRUE, FALSE); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | control(key id, integer level, integer edge) | ||
+ | { | ||
+ | integer reverse=1; | ||
+ | vector angular_motor; | ||
+ | |||
+ | //get current speed | ||
+ | vector vel = llGetVel(); | ||
+ | float speed = llVecMag(vel); | ||
+ | |||
+ | //car controls | ||
+ | if(level & CONTROL_FWD) | ||
+ | { | ||
+ | llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, <10.0, 2.0, 1000.0>); | ||
+ | llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <forward_power,0,0>); | ||
+ | reverse=1; | ||
+ | // NewWheelrot = "F"; | ||
+ | Speed = 20; | ||
+ | } | ||
+ | if(level & CONTROL_BACK) | ||
+ | { | ||
+ | llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, <10.0, 2.0, 1000.0>); | ||
+ | llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <reverse_power,0,0>); | ||
+ | reverse = -1; | ||
+ | // NewWheelrot = "R"; | ||
+ | Speed = 10; | ||
+ | } | ||
+ | |||
+ | if(level & (CONTROL_RIGHT|CONTROL_ROT_RIGHT)) | ||
+ | { | ||
+ | angular_motor.z -= speed / turning_ratio * reverse; | ||
+ | // NewWheeldir = "WR"; | ||
+ | // turncount = 10; | ||
+ | } | ||
+ | |||
+ | if(level & (CONTROL_LEFT|CONTROL_ROT_LEFT)) | ||
+ | { | ||
+ | angular_motor.z += speed / turning_ratio * reverse; | ||
+ | // NewWheeldir = "WL"; | ||
+ | // turncount = 10; | ||
+ | } | ||
+ | |||
+ | llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION, angular_motor); | ||
+ | // if(turncount > 0) | ||
+ | // { | ||
+ | // turncount--; | ||
+ | // } | ||
+ | // if(turncount == 1) | ||
+ | // { | ||
+ | // NewWheeldir = "WC"; | ||
+ | // } | ||
+ | // if(Wheeldir != NewWheeldir){ | ||
+ | // Wheeldir = NewWheeldir; | ||
+ | // llMessageLinked(LINK_ALL_OTHERS, 0, Wheeldir, NULL_KEY); | ||
+ | // } | ||
+ | // if(Wheelrot != NewWheelrot){ | ||
+ | // Wheelrot = NewWheelrot; | ||
+ | // llMessageLinked(LINK_ALL_OTHERS, 0, Wheelrot, NULL_KEY); | ||
+ | // } | ||
+ | } //end control | ||
+ | |||
+ | //Sensor is to make a crude Timer as TimerEvent fails on vehicles | ||
+ | no_sensor() | ||
+ | { | ||
+ | if(scount < 1000) | ||
+ | { | ||
+ | scount++; | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | scount = 0; | ||
+ | // This happens about once per second | ||
+ | if(Speed > 0) Speed--; | ||
+ | |||
+ | if(Speed > 2) Sound(2); | ||
+ | |||
+ | if(Speed == 1) { | ||
+ | llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, <1.0, 2.0, 1000.0>); | ||
+ | llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <0,0,0>); | ||
+ | // llMessageLinked(LINK_ALL_OTHERS, 0, "S", NULL_KEY); | ||
+ | // Sound(1); | ||
+ | // Wheelrot = "S"; | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | if(Run == 1) | ||
+ | llSensor("Non-Entity",NULL_KEY,PASSIVE,1.0, PI_BY_TWO); | ||
+ | } | ||
+ | |||
+ | } //end default | ||
+ | |||
+ | </source> | ||
== Vehicle LSL Functions and Status == | == Vehicle LSL Functions and Status == | ||
Line 52: | Line 597: | ||
OpenSimulator. | OpenSimulator. | ||
− | Key: Y = Yes; N = No; F = Framework present but commented out | + | Key: Y = Yes; N = No; F = Framework present but commented out; N/A = Has not been checked (much) yet |
− | + | ||
− | + | ||
=== KINEMATIC === | === KINEMATIC === | ||
− | + | Object must not be PHYSICAL | |
(Some work, some do not.) | (Some work, some do not.) | ||
{|class="wikitable sortable" | {|class="wikitable sortable" | ||
− | !Function | + | !Function!!Set by LSL?!!Used by OpenSimulator C#!!Works?!!Comments |
|- | |- | ||
− | |llSetPos()|| | + | |llSetPos()||Y||Y||Y||Also works on physical objects! |
|- | |- | ||
− | |llSetRot()|| | + | |llSetRot()||Y||Y||Y||Y |
|- | |- | ||
− | |llSetLocalRot()|| | + | |llSetLocalRot()||Y||Y||Y |
|- | |- | ||
|llSetScale()||N/A||N/A||N/A||N/A | |llSetScale()||N/A||N/A||N/A||N/A | ||
Line 84: | Line 627: | ||
=== DYNAMIC === | === DYNAMIC === | ||
− | + | Object must be PHYSICAL and VEHICLE_TYPE_NONE(default) at present, but this must probably change. | |
(Some work, some do not.) | (Some work, some do not.) | ||
{|class="wikitable sortable" | {|class="wikitable sortable" | ||
− | !Function!!Parameter!!Set by LSL?!!Used by | + | !Function!!Parameter!!Set by LSL?!!Used by OpenSimulator C#!!Comments |
|- | |- | ||
|llApplyImpulse()||N/A||N/A||N/A||N/A | |llApplyImpulse()||N/A||N/A||N/A||N/A | ||
Line 114: | Line 657: | ||
|llLookAt()||N/A||N/A||N/A||N/A | |llLookAt()||N/A||N/A||N/A||N/A | ||
|- | |- | ||
− | |llRotLookAt()|| | + | |llRotLookAt()||Use of this crashes script||N/A||N/A||N/A |
|- | |- | ||
|llSetPrimitiveParams()||N/A||N/A||N/A||N/A | |llSetPrimitiveParams()||N/A||N/A||N/A||N/A | ||
Line 121: | Line 664: | ||
|- | |- | ||
|llTargetOmega()||N/A||N/A||N/A||N/A | |llTargetOmega()||N/A||N/A||N/A||N/A | ||
− | | | + | |} |
− | } | + | |
=== VEHICLE === | === VEHICLE === | ||
− | + | Object must be PHYSICAL and VEHICLE_TYPE_<other than NONE> | |
+ | {|class="wikitable sortable" | ||
+ | !Functions!!Set by LSL?!!Used!!Works!!Exceptions | ||
+ | |- | ||
+ | |llSetVehicleType()||Y||Y||Y | ||
+ | |- | ||
+ | |llSetVehicleFlags()||N||N||N||Some flags are set by llSetVehicleType() | ||
+ | |- | ||
+ | |llRemoveVehicleFlags()||N||N||N|| | ||
+ | |- | ||
+ | |llSetVehicleFloatParam()||Y||Y||Y|| | ||
+ | |- | ||
+ | |llSetVehicleVectorParam()||Y||Y||Y|| | ||
+ | |- | ||
+ | |llSetVehicleRotationParam()||Y||Y||Y|| | ||
+ | |} | ||
− | + | {|class="wikitable sortable" | |
− | + | !Parameters!!Set by LSL?!!Used!!Works!!Exceptions | |
− | + | |- | |
− | + | |VEHICLE_LINEAR_MOTOR_DIRECTION||Y||Y||Y|| | |
− | + | |- | |
− | + | |VEHICLE_LINEAR_MOTOR_TIMESCALE||Y||Y||Y|| | |
− | + | |- | |
− | + | |VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE||Y||Y||Y|| | |
− | + | |- | |
− | + | |VEHICLE_LINEAR_FRICTION_TIMESCALE||Y||Y||Y|| | |
− | + | |- | |
− | + | |VEHICLE_LINEAR_MOTOR_OFFSET||F||N|| || | |
− | + | |- | |
− | + | |VEHICLE_ANGULAR_MOTOR_DIRECTION||Y||Y||Y|| | |
− | + | |- | |
− | + | |VEHICLE_ANGULAR_MOTOR_TIMESCALE||Y||Y||Y|| | |
− | + | |- | |
− | + | |VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE||Y||Y||Y|| | |
− | + | |- | |
− | + | |VEHICLE_ANGULAR_FRICTION_TIMESCALE||Y||Y||Y|| | |
− | + | |- | |
− | + | ||VEHICLE_BANKING_EFFICIENCY||F||N|| || | |
− | + | |- | |
− | + | |VEHICLE_BANKING_MIX||F||N|| || | |
+ | |- | ||
+ | |VEHICLE_BANKING_TIMESCALE||F||N|| || | ||
+ | |- | ||
+ | |VEHICLE_BUOYANCY||Y||Y||Y||(do not confuse with llSetBuoyancy()) | ||
+ | |- | ||
+ | |VEHICLE_HOVER_HEIGHT||Y||Y||Y||(do not confuse with llSetHoverHeight()) | ||
+ | |- | ||
+ | |VEHICLE_HOVER_EFFICIENCY||Y||N|| || | ||
+ | |- | ||
+ | |VEHICLE_HOVER_TIMESCALE||Y||N|| || | ||
+ | |- | ||
+ | |VEHICLE_LINEAR_DEFLECTION_EFFICIENCY||F||N|| || | ||
+ | |- | ||
+ | |VEHICLE_LINEAR_DEFLECTION_TIMESCALE||F||N|| || | ||
+ | |- | ||
+ | |VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY||F||N|| || | ||
+ | |- | ||
+ | |VEHICLE_ANGULAR_DEFLECTION_TIMESCALE||F||N|| || | ||
+ | |- | ||
+ | |VEHICLE_REFERENCE_FRAME||F||N|| || | ||
+ | |- | ||
+ | |VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY||Y||Y||Y|| | ||
+ | |- | ||
+ | |VEHICLE_VERTICAL_ATTRACTION_TIMESCALE||Y||Y||Y|| | ||
+ | |- | ||
+ | |VEHICLE_TYPE_NONE||Y||Y||Y|| | ||
+ | |- | ||
+ | |VEHICLE_TYPE_BALLOON||Y||Y||Y|| | ||
+ | |- | ||
+ | |VEHICLE_TYPE_BOAT||Y||Y||Y|| | ||
+ | |- | ||
+ | |VEHICLE_TYPE_CAR||Y||Y||Y|| | ||
+ | |- | ||
+ | |VEHICLE_TYPE_SLED||Y||Y||Y|| | ||
+ | |- | ||
+ | |VEHICLE_FLAG_NO_DEFLECTION_UP||Y||N|| || | ||
+ | |- | ||
+ | |VEHICLE_FLAG_LIMIT_ROLL_ONLY||Y||N|| || | ||
+ | |- | ||
+ | |VEHICLE_FLAG_HOVER_WATER_ONLY||Y||Y|| || | ||
+ | |- | ||
+ | |VEHICLE_FLAG_HOVER_TERRAIN_ONLY||Y||Y|| || | ||
+ | |- | ||
+ | |VEHICLE_FLAG_HOVER_GLOBAL_HEIGHT||Y||Y|| || | ||
+ | |- | ||
+ | |VEHICLE_FLAG_HOVER_UP_ONLY||Y||Y|| || | ||
+ | |- | ||
+ | |VEHICLE_FLAG_LIMIT_MOTOR_UP||Y||N|| || | ||
+ | |- | ||
+ | |VEHICLE_FLAG_MOUSELOOK_STEER||Y||N|| || | ||
+ | |- | ||
+ | |VEHICLE_FLAG_MOUSELOOK_BANK||Y||N|| || | ||
+ | |- | ||
+ | |VEHICLE_FLAG_CAMERA_DECOUPLED||Y||N|| || | ||
+ | |} | ||
+ | == VEHICLE TYPE Presets == | ||
+ | VEHICLE_TYPE_SLED: | ||
+ | linearFrictionTimescale <30, 1, 1000> | ||
+ | angularFrictionTimescale <1000, 1000, 1000> | ||
+ | linearMotorDirection <0, 0, 0> | ||
+ | linearMotorTimescale 1000 | ||
+ | linearMotorDecayTimescale 120 | ||
+ | angularMotorDirection <0, 0, 0> | ||
+ | angularMotorTimescale 1000 | ||
+ | angularMotorDecayTimescale 120 | ||
+ | VhoverHeight 0 | ||
+ | VhoverEfficiency 1 | ||
+ | VhoverTimescale 10 | ||
+ | VehicleBuoyancy 0 | ||
+ | linearDeflectionEfficiency 1 | ||
+ | linearDeflectionTimescale 1 | ||
+ | angularDeflectionEfficiency 1 | ||
+ | angularDeflectionTimescale 1000 | ||
+ | bankingEfficiency 0 | ||
+ | bankingMix 1 | ||
+ | bankingTimescale 10 | ||
+ | referenceFrame ZERO_ROTATION | ||
+ | flags FALSE: | ||
+ | HOVER_WATER_ONLY | ||
+ | HOVER_TERRAIN_ONLY | ||
+ | HOVER_GLOBAL_HEIGHT | ||
+ | HOVER_UP_ONLY | ||
+ | flags TRUE: | ||
+ | NO_DEFLECTION_UP | ||
+ | LIMIT_ROLL_ONLY | ||
+ | LIMIT_MOTOR_UP | ||
+ | |||
− | + | VEHICLE_TYPE_CAR: | |
− | + | linearFrictionTimescale <100, 2, 1000> | |
− | + | angularFrictionTimescale <1000, 1000, 1000> | |
− | + | linearMotorDirection <0, 0, 0> | |
+ | linearMotorTimescale 1 | ||
+ | linearMotorDecayTimescale 60 | ||
+ | angularMotorDirection <0, 0, 0> | ||
+ | angularMotorTimescale 1 | ||
+ | angularMotorDecayTimescale 0.8 | ||
+ | VhoverHeight 0 | ||
+ | VhoverEfficiency 0 | ||
+ | VhoverTimescale 1000 | ||
+ | VehicleBuoyancy 0 | ||
+ | // m_linearDeflectionEfficiency 1 | ||
+ | // m_linearDeflectionTimescale 2 | ||
+ | // m_angularDeflectionEfficiency 0 | ||
+ | angularDeflectionTimescale 10 | ||
+ | verticalAttractionEfficiency 1 | ||
+ | verticalAttractionTimescale 10 | ||
+ | bankingEfficiency -0.2 | ||
+ | bankingMix 1 | ||
+ | bankingTimescale 1 | ||
+ | referenceFrame ZERO_ROTATION | ||
+ | flags FALSE: | ||
+ | HOVER_WATER_ONLY | ||
+ | HOVER_TERRAIN_ONLY | ||
+ | HOVER_GLOBAL_HEIGHT | ||
+ | flags TRUE: | ||
+ | NO_DEFLECTION_UP | ||
+ | LIMIT_ROLL_ONLY | ||
+ | HOVER_UP_ONLY | ||
+ | LIMIT_MOTOR_UP | ||
+ | |||
+ | VEHICLE_TYPE_BOAT: | ||
+ | linearFrictionTimescale <10, 3, 2> | ||
+ | angularFrictionTimescale <10,10,10> | ||
+ | linearMotorDirection <0, 0, 0> | ||
+ | linearMotorTimescale 5 | ||
+ | linearMotorDecayTimescale 60 | ||
+ | angularMotorDirection <0, 0, 0> | ||
+ | angularMotorTimescale 4 | ||
+ | angularMotorDecayTimescale 4 | ||
+ | VhoverHeight 0 | ||
+ | VhoverEfficiency 0.5 | ||
+ | VhoverTimescale 2 | ||
+ | VehicleBuoyancy 1 | ||
+ | linearDeflectionEfficiency 0.5 | ||
+ | linearDeflectionTimescale 3 | ||
+ | angularDeflectionEfficiency 0.5 | ||
+ | angularDeflectionTimescale 5 | ||
+ | verticalAttractionEfficiency 0.5 | ||
+ | verticalAttractionTimescale 5 | ||
+ | bankingEfficiency -0.3 | ||
+ | bankingMix 0.8 | ||
+ | bankingTimescale 1 | ||
+ | referenceFrame ZERO_ROTATION | ||
+ | flags FALSE: | ||
+ | HOVER_TERRAIN_ONLY | ||
+ | LIMIT_ROLL_ONLY | ||
+ | HOVER_GLOBAL_HEIGHT | ||
+ | HOVER_UP_ONLY | ||
+ | flags TRUE: | ||
+ | NO_DEFLECTION_UP | ||
+ | HOVER_WATER_ONLY | ||
+ | LIMIT_MOTOR_UP | ||
− | |||
− | |||
− | |||
− | |||
+ | VEHICLE_TYPE_AIRPLANE: | ||
+ | linearFrictionTimescale <200, 10, 5> | ||
+ | angularFrictionTimescale <20, 20, 20> | ||
+ | linearMotorDirection <0, 0, 0> | ||
+ | linearMotorTimescale 2 | ||
+ | linearMotorDecayTimescale 60 | ||
+ | angularMotorDirection <0, 0, 0> | ||
+ | angularMotorTimescale 4 | ||
+ | angularMotorDecayTimescale 4 | ||
+ | VhoverHeight 0 | ||
+ | VhoverEfficiency 0.5 | ||
+ | VhoverTimescale 1000 | ||
+ | VehicleBuoyancy 0 | ||
+ | linearDeflectionEfficiency 0.5 | ||
+ | linearDeflectionTimescale 3 | ||
+ | angularDeflectionEfficiency 1 | ||
+ | angularDeflectionTimescale 2 | ||
+ | verticalAttractionEfficiency 0.9 | ||
+ | verticalAttractionTimescale 2 | ||
+ | bankingEfficiency 1 | ||
+ | bankingMix 0.7f | ||
+ | bankingTimescale 2 | ||
+ | referenceFrame ZERO_ROTATION | ||
+ | flags FALSE: | ||
+ | NO_DEFLECTION_UP | ||
+ | HOVER_WATER_ONLY | ||
+ | HOVER_TERRAIN_ONLY | ||
+ | HOVER_GLOBAL_HEIGHT | ||
+ | HOVER_UP_ONLY | ||
+ | LIMIT_MOTOR_UP | ||
+ | flags TRUE: | ||
+ | LIMIT_ROLL_ONLY | ||
− | |||
− | |||
− | |||
− | + | VEHICLE_TYPE_BALLOON: | |
− | VEHICLE_TYPE_BALLOON | + | linearFrictionTimescale <5, 5, 5> |
− | + | angularFrictionTimescale <10, 10, 10> | |
− | + | linearMotorDirection <0, 0, 0> | |
− | + | linearMotorTimescale 5 | |
− | + | linearMotorDecayTimescale 60 | |
− | + | angularMotorDirection <0, 0, 0> | |
− | + | angularMotorTimescale 6 | |
− | + | angularMotorDecayTimescale 10 | |
− | + | VhoverHeight 5 | |
− | + | VhoverEfficiency 0.8 | |
− | + | VhoverTimescale 10 | |
− | + | VehicleBuoyancy 1 | |
− | + | linearDeflectionEfficiency 0 | |
− | + | linearDeflectionTimescale 5 | |
+ | angularDeflectionEfficiency 0 | ||
+ | angularDeflectionTimescale 5 | ||
+ | verticalAttractionEfficiency 1 | ||
+ | verticalAttractionTimescale 1000 | ||
+ | bankingEfficiency 0 | ||
+ | bankingMix 0.7 | ||
+ | bankingTimescale 5 | ||
+ | referenceFrame ZERO_ROTATION | ||
+ | flags FALSE: | ||
+ | NO_DEFLECTION_UP | ||
+ | HOVER_WATER_ONLY | ||
+ | HOVER_TERRAIN_ONLY | ||
+ | HOVER_UP_ONLY | ||
+ | LIMIT_MOTOR_UP | ||
+ | flags TRUE: | ||
+ | LIMIT_ROLL_ONLY | ||
+ | HOVER_GLOBAL_HEIGHT |
Latest revision as of 15:48, 20 January 2020
This article or section contains obsolete and possibly misleading information. Please integrate this information into existing pages, update it to something more recent, or remove it. |
Contents |
[edit] Historic Only
THis article is kept only for historic reasons. This information is no longer valid
[edit] Summary
August 2009: Kitto Flora is revising the OdePlugin files in an attempt to provide SL-compatible VEHICLE functionality to OpenSimulator. A couple of test regions have been provided by Bri Hasp, these are Sea-3 and Sea-4 in OSgrid. You may visit there and test vehicles but please clean up after. The regions will frequently be restarted to test revisions. The revised Open Simulator files are being made available as a git branch, check here to see what may or may not work.
[edit] News
[edit] Oct 24 2009 (apx) PROJECT HALTED.
At about this date opensim trunk was merged into the vehicles branch bringing in the packet prioritization modifications. It had already been pointed out that those modifications caused problems with the display of motion of physical objects. The result of this merge is that a physical object that is simply rotating is no longer updated on the viewer screen. Debug messages show that ODE is indeed rotating the object, and sending update requests but it appears that the packet system is not transmitting updates to the viewer. This makes it impossible to see the results of the work in progress - adding functions such as llRotLookAt(). Work is therefore suspended until this packet problem is fixed. See http://opensimulator.org/mantis/view.php?id=4336
[edit] Oct 22 2009
- Vehicle branch is merged into opensim. Any version r11303 or later will have the VEHICLE capabilities (and problems) listed below available.
[edit] Oct 6 2009
- Sea-3/Sea4 are down because osgrid is being upgraded/fixed to deal with other ongoing problems, and the vehicle branch is no longer compatible. I am waiting for trunk to stabilize before proceeding.
Meanwhile I am investigating the details of SL physics parameters.
[edit] Sept 28 2009
- Cause of poor update rate of rotating physical prims found and fixed.
[edit] Sept 24 2009
- OpenSimulator Vehicle version running at Sea-3 and Sea-4 in OSgrid have been adjusted to improve the Vertical Attractor.
- The Tako sailboat works somewhat, but the listen() event on channel 0 fails after 30 seconds or so, resulting in some loss of control.
- Camera controls are still a problem, it appears that camera position depends on which prim is clicked to 'sit'. (Camera fails to reference to root prim of a link-set???).
- timer() event will keep working if llSetTimer(float) is called at every timer() event.
- Racecar updated to 'ODB VEH racecar10', deals with changed Vertical Attractor; timer() used in place of llSensor(), resulting in much lower simulator CPU load. Available in sea-3.
[edit] Terminology
Here some terms are defined so that when we communicate we are talking about the same things.
[edit] Vehicle
Any object or link-set that moves. It is usually rideable. It may be Physical or not.
[edit] VEHICLE
Any object or link-set that uses LSL VEHICLE functions to achieve mobility. It is set to other than 'VEHICLE_TYPE_NONE'.
[edit] Physical
Any object or link-set that is llSetStatus(STATUS_PHYSICS, TRUE). It will fall due to gravity (unless buoyancy is changed) and collide with other prims, avatars and the ground (unless set phantom).
[edit] Non-Physical
Any object or link-set that is llSetStatus(STATUS_PHYSICS, FALSE), or has never has llSetStatus(STATUS_PHYSICS,...) applied. Such objects 'stick in midair' and can interpenetrate other objects.
[edit] Kinematic
Motion system used by Non-Physical objects, applied by such functions as llSetPos() and llSetRot().
[edit] Dynamic
Motion system used by Physical objects, applied by such functions as llSetForce() and llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <...>).
[edit] About This Project
The objectives of this project are:
- To provide VEHICLE associated LSL functions within OpenSimulator that are compatible with Second Life functionality. This means trying to get them really close, but as we are trying to emulate complex HAVOK functions using what is available in ODE they may be only close to the SL functions.
- To clean up the OdePlugin files. Over many revisions and add-ons they have become somewhat non-optimal. In particular the 'Move' operation that makes objects move around needs to be very clean and smooth so that the update rate remains high.
- Maintain the existing non-VEHICLE dynamic functions and fix errors where found.
[edit] Vehicle LSL Functions in revised OpenSimulator
There are three categories of LSL functions that are used by Vehicles: Kinematic, Dynamic and VEHICLE. These are listed below with information on their current status within the revised OpenSimulator. (Not the general release at this time.) Kinematic vehicle motion can be used by non-physical objects. VEHICLE motion and the associated functions ONLY apply to objects that are set to a VEHICLE_TYPE of AIRPLANE, BALLOON, BOAT, CAR or SLED. Dynamic functions ONLY apply (at this time) to VEHICLE_TYPE_NONE, which is the default condition of an object. (In SL it appears that one can use Dynamic functions on a VEHICLE, but to keep things simple at the start of this project such a combination is ignored.)
[edit] Known Problems
- timer() event ceases about 10 seconds after Vehicle moves. Does not restart until many seconds after Vehicle stops. Work-around: Use llSensor() for a non-existent object at short range and no_sensor() event to re-trigger it. This produces about 1000 events per second. Divide down to produce more reasonable rates.
- llSetBuoyancy() is not hooked to physics methods. LSL engine problem. Work-around: None. Big problem for non-VEHICLE vehicles.
- llSetHoverHeight() is not hooked to physics methods. LSL engine problem. Work-around: None. Big problem for non VEHICLE vehicles.
- llSetVehicleFlags() and llRemoveVehicleFlags() are not hooked to physics methods, and may cause simulator crash. LSL engine problem. Work-around: None, but the VEHICLE_TYPE presets are setting necessary flags.
- Prim parameters like Material are not being saved. Work-around: Set by script on rez or whenever used.
- Script state is not maintained between Take and Rez. Work-around: on_rez() Reset script and set *everything* again.
- Border Crossing is bad. Vehicle will be killed and Av unseated and left drifting through target region. Work-around: Quickly double-click on Map to tele-port to old region. Drag vehicle back and reset it.
[edit] VEHICLE Scripting Notes
- (Not really scripting , but very important) DO NOT attempt to drive a VEHICLE across the Region boundary. If you do your Av will be orbited. You may be able to recover by Map double-click TP to a nearby Region. The VEHICLE object is usually killed, and sitting at edge of the destination region.
- In revised OpenSimulator the function llSetVehicleType(VEHICLE_TYPE_xxx), where xxx is AIRPLANE, BALLOON, BOAT, CAR or SLED, pre-sets all the applicable VEHICLE parameters to reasonable numbers. If you wish to change any of these pre-set parameters do so after asserting llSetVehicleType(VEHICLE_TYPE_xxx).
- At present it appears that some conditions within an instantiated scripted object are not maintained after a Region restart, and possibly between take and rez. Therefore you should assert llSetVehicleType(VEHICLE_TYPE_xxx) when the driver sits and llSetVehicleType(VEHICLE_TYPE_NONE)when the driver stands, and probably on_rez.
- The advice above also applies to camera controls. Assert llSetCameraxxx() on sit and llClearCameraParams() on stand. (At present there seems to be bugs in the Camera Control system, the camera will go underground!)
- The advice above is also true of Material Type. Land vehicles need the 'wheels' to be PRIM_MATERIAL_GLASS. The script(s) must llSetPrimitiveParams([PRIM_MATERIAL, PRIM_MATERIAL_GLASS]) in every prim that touches the ground, when the rider sits, for reliable operation. Use a link mesage from the root to daughter prim scripts.
- Use llSetStatus(STATUS_PHYSICS, TRUE) to enable the VEHICLE, usually when the driver sits. Use llSetStatus(STATUS_PHYSICS, FALSE) to disable the VEHICLE, usually when the driver stands.
- It appears that the timer() event freezes while a Vehicle is in motion, so do not rely in Timer() to update things like steering or velocity. See Known Problems for a work-around.
[edit] VEHICLE Scripting Examples
Below are some initial (and very similar) Vehicle scripting examples, implementing a sort of go kart, and the second a motorboat. The motorboat script is a derivative work based on the go kart script.
- Note that these scripts are works in progress and may or may not impact the performance of your region negatively.
Car or Go kart script:
// Very simple vehicle script, mod for OpenSimulator & ODE & VEHICLE code // By Kitto Flora September 2009 integer Private = 1; // Change to 1 to prevent others riding. vector Sitpos = <0.35,0,0.35>; vector SitrotV = <0,-20,0>; rotation Sitrot; integer tt; key oldagent; key agent; float forward_power = 12; //Power used to go forward (1 to 30) float reverse_power = -6; //Power ued to go reverse (-1 to -30) float turning_ratio = 2.0; //How sharply the vehicle turns. Less is more sharply. (.1 to 10) integer turncount; string Wheeldir = "WC"; string NewWheeldir = "WC"; string Wheelrot = "S"; string NewWheelrot = "S"; integer scount; integer Speed; integer Run; string sit_message = "Ride"; //Sit message string not_owner_message = "You are not the owner of this vehicle, buy a copy for 0$ and have your own to test in this sim. It will not work in other Open Sim Regions."; //Not owner message setVehicle() { //car llSetVehicleType(VEHICLE_TYPE_CAR); llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY, 0.2); llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_EFFICIENCY, 0.80); llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_TIMESCALE, 0.10); llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_TIMESCALE, 0.10); llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_TIMESCALE, 1.0); llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE, 0.1); llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_TIMESCALE, 0.1); llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE, 0.1); llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, <10.0, 2.0, 1000.0>); llSetVehicleVectorParam(VEHICLE_ANGULAR_FRICTION_TIMESCALE, <0.1, 0.1, 0.1>); llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY, 0.50); llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_TIMESCALE, 0.50); } Init() { Sound(0); llSetStatus(STATUS_PHYSICS, FALSE); vector here = llGetPos(); float h = llGround(<0,0,0>) + 0.52; vector rotv = llRot2Euler(llGetRot()); rotation rot = llEuler2Rot(<0,0,rotv.z>); llSetPos(<here.x, here.y,h>); llSetRot(rot); Sitrot = llEuler2Rot(DEG_TO_RAD * SitrotV); llSetVehicleType(VEHICLE_TYPE_NONE); llMessageLinked(LINK_ALL_OTHERS, 0, "S", NULL_KEY); // wheels stop llMessageLinked(LINK_ALL_OTHERS, 0, "WC", NULL_KEY); // wheels straight Run = 0; } SetMaterial() { llSetPrimitiveParams([PRIM_MATERIAL, PRIM_MATERIAL_GLASS]); llMessageLinked(LINK_ALL_OTHERS, 0, "SetMat", NULL_KEY); // Tell daughter pims on ground to be glass } Sound(integer n) { integer oldn; if(n != oldn) { oldn = n; if(n == 2) { llLoopSound("RUNNING",1); } else if(n == 1) { llLoopSound("IDLE",1); } else { llStopSound(); } } } default { state_entry() { Init(); llSetSitText(sit_message); // forward-back,left-right,updown llSitTarget(Sitpos, Sitrot); llStopSound(); } on_rez(integer rn){ llResetScript(); } changed(integer change) { if ((change & CHANGED_LINK) == CHANGED_LINK) { agent = llAvatarOnSitTarget(); if (agent != NULL_KEY) { if( (agent != llGetOwner()) && (Private == 1) ) { llSay(0, not_owner_message); llUnSit(agent); // not functional llPushObject(agent, <0,0,50>, ZERO_VECTOR, FALSE); } else { //llTriggerSound("car_start",1); // llMessageLinked(LINK_ALL_CHILDREN , 0, "WHEEL_DRIVING", NULL_KEY); oldagent = agent; setVehicle(); SetMaterial(); llSleep(.4); llSetStatus(STATUS_PHYSICS, TRUE); llSleep(.1); Run = 1; //Sensor is to make a crude Timer as TimerEvent fails on vehicles llSensor("Non-Entity",NULL_KEY,PASSIVE,1.0, PI_BY_TWO); llRequestPermissions(agent, PERMISSION_TRIGGER_ANIMATION | PERMISSION_TAKE_CONTROLS); Sound(1); } } else { Init(); llSleep(.4); llReleaseControls(); llMessageLinked(LINK_ALL_OTHERS, 0, "S", NULL_KEY); Run = 0; llStopSound(); } } } touch_start(integer tn){ } run_time_permissions(integer perm) { if (perm) { llTakeControls(CONTROL_FWD | CONTROL_BACK | CONTROL_DOWN | CONTROL_UP | CONTROL_RIGHT | CONTROL_LEFT | CONTROL_ROT_RIGHT | CONTROL_ROT_LEFT, TRUE, FALSE); } } control(key id, integer level, integer edge) { integer reverse=1; vector angular_motor; //get current speed vector vel = llGetVel(); float speed = llVecMag(vel); //car controls if(level & CONTROL_FWD) { llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, <10.0, 2.0, 1000.0>); llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <forward_power,0,0>); reverse=1; NewWheelrot = "F"; Speed = 20; } if(level & CONTROL_BACK) { llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, <10.0, 2.0, 1000.0>); llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <reverse_power,0,0>); reverse = -1; NewWheelrot = "R"; Speed = 10; } if(level & (CONTROL_RIGHT|CONTROL_ROT_RIGHT)) { angular_motor.z -= speed / turning_ratio * reverse; NewWheeldir = "WR"; turncount = 10; } if(level & (CONTROL_LEFT|CONTROL_ROT_LEFT)) { angular_motor.z += speed / turning_ratio * reverse; NewWheeldir = "WL"; turncount = 10; } llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION, angular_motor); if(turncount > 0) { turncount--; } if(turncount == 1) { NewWheeldir = "WC"; } if(Wheeldir != NewWheeldir){ Wheeldir = NewWheeldir; llMessageLinked(LINK_ALL_OTHERS, 0, Wheeldir, NULL_KEY); } if(Wheelrot != NewWheelrot){ Wheelrot = NewWheelrot; llMessageLinked(LINK_ALL_OTHERS, 0, Wheelrot, NULL_KEY); } } //end control //Sensor is to make a crude Timer as TimerEvent fails on vehicles no_sensor() { if(scount < 1000) { scount++; } else { scount = 0; // This happens about once per second if(Speed > 0) Speed--; if(Speed > 2) Sound(2); if(Speed == 1) { llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, <1.0, 2.0, 1000.0>); llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <0,0,0>); llMessageLinked(LINK_ALL_OTHERS, 0, "S", NULL_KEY); Sound(1); Wheelrot = "S"; } } if(Run == 1) llSensor("Non-Entity",NULL_KEY,PASSIVE,1.0, PI_BY_TWO); } } //end default
Motorboat script:
// Very simple vehicle script, mod for OpenSimulator & ODE & VEHICLE code // By Kitto Flora September 2009 // modified by Hiro Protagonist for basic aquatic motorcraft // September 2009 integer Private = 1; // Change to 1 to prevent others riding. vector Sitpos = <0.35,0,0.35>; vector SitrotV = <0,-20,0>; rotation Sitrot; integer tt; key oldagent; key agent; float forward_power = 8; //Power used to go forward (1 to 30) float reverse_power = -3; //Power ued to go reverse (-1 to -30) float turning_ratio = 1.0; //How sharply the vehicle turns. Less is more sharply. (.1 to 10) integer scount; integer Speed; integer Run; string sit_message = "Man the Helm"; //Sit message string not_owner_message = "You are not the owner of this vehicle, buy a copy for 0$ and have your own to test in this sim. It will not work in other Open Sim Regions."; //Not owner message setVehicle() { //boat llSetVehicleType(VEHICLE_TYPE_BOAT); llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY, 0.2); llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_EFFICIENCY, 0.80); llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_TIMESCALE, 0.10); llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_TIMESCALE, 0.10); llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_TIMESCALE, 1.0); llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE, 0.1); llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_TIMESCALE, 0.1); llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE, 0.1); llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, <10.0, 2.0, 1000.0>); llSetVehicleVectorParam(VEHICLE_ANGULAR_FRICTION_TIMESCALE, <0.1, 0.1, 0.1>); llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY, 0.250); llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_TIMESCALE, 0.250); } Init() { Sound(0); llSetBuoyancy(1); llSetStatus(STATUS_PHYSICS, FALSE); vector here = llGetPos(); float h = llWater(<0,0,0>) + 0.22; vector rotv = llRot2Euler(llGetRot()); rotation rot = llEuler2Rot(<0,0,rotv.z>); llSetPos(<here.x, here.y,h>); llSetRot(rot); Sitrot = llEuler2Rot(DEG_TO_RAD * SitrotV); llSetVehicleType(VEHICLE_TYPE_NONE); llMessageLinked(LINK_ALL_OTHERS, 0, "S", NULL_KEY); // wheels stop llMessageLinked(LINK_ALL_OTHERS, 0, "WC", NULL_KEY); // wheels straight Run = 0; } SetMaterial() { llSetPrimitiveParams([PRIM_MATERIAL, PRIM_MATERIAL_WOOD]); // llMessageLinked(LINK_ALL_OTHERS, 0, "SetMat", NULL_KEY); // Tell daughter pims on ground to be glass } Sound(integer n) { integer oldn; if(n != oldn) { oldn = n; if(n == 2) { // llLoopSound("RUNNING",1); } else if(n == 1) { // llLoopSound("IDLE",1); } else { // llStopSound(); } } } default { state_entry() { Init(); llSetSitText(sit_message); // forward-back,left-right,updown llSitTarget(Sitpos, Sitrot); // llStopSound(); } on_rez(integer rn){ llResetScript(); } changed(integer change) { if ((change & CHANGED_LINK) == CHANGED_LINK) { agent = llAvatarOnSitTarget(); if (agent != NULL_KEY) { if( (agent != llGetOwner()) && (Private == 1) ) { llSay(0, not_owner_message); llUnSit(agent); // not functional llPushObject(agent, <0,0,50>, ZERO_VECTOR, FALSE); } else { //llTriggerSound("car_start",1); // llMessageLinked(LINK_ALL_CHILDREN , 0, "WHEEL_DRIVING", NULL_KEY); oldagent = agent; setVehicle(); SetMaterial(); llSleep(.4); llSetStatus(STATUS_PHYSICS, TRUE); llSleep(.1); Run = 1; //Sensor is to make a crude Timer as TimerEvent fails on vehicles llSensor("Non-Entity",NULL_KEY,PASSIVE,1.0, PI_BY_TWO); llRequestPermissions(agent, PERMISSION_TRIGGER_ANIMATION | PERMISSION_TAKE_CONTROLS); Sound(1); } } else { Init(); llSleep(.4); llReleaseControls(); llMessageLinked(LINK_ALL_OTHERS, 0, "S", NULL_KEY); Run = 0; llStopSound(); } } } touch_start(integer tn){ } run_time_permissions(integer perm) { if (perm) { llTakeControls(CONTROL_FWD | CONTROL_BACK | CONTROL_DOWN | CONTROL_UP | CONTROL_RIGHT | CONTROL_LEFT | CONTROL_ROT_RIGHT | CONTROL_ROT_LEFT, TRUE, FALSE); } } control(key id, integer level, integer edge) { integer reverse=1; vector angular_motor; //get current speed vector vel = llGetVel(); float speed = llVecMag(vel); //car controls if(level & CONTROL_FWD) { llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, <10.0, 2.0, 1000.0>); llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <forward_power,0,0>); reverse=1; // NewWheelrot = "F"; Speed = 20; } if(level & CONTROL_BACK) { llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, <10.0, 2.0, 1000.0>); llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <reverse_power,0,0>); reverse = -1; // NewWheelrot = "R"; Speed = 10; } if(level & (CONTROL_RIGHT|CONTROL_ROT_RIGHT)) { angular_motor.z -= speed / turning_ratio * reverse; // NewWheeldir = "WR"; // turncount = 10; } if(level & (CONTROL_LEFT|CONTROL_ROT_LEFT)) { angular_motor.z += speed / turning_ratio * reverse; // NewWheeldir = "WL"; // turncount = 10; } llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION, angular_motor); // if(turncount > 0) // { // turncount--; // } // if(turncount == 1) // { // NewWheeldir = "WC"; // } // if(Wheeldir != NewWheeldir){ // Wheeldir = NewWheeldir; // llMessageLinked(LINK_ALL_OTHERS, 0, Wheeldir, NULL_KEY); // } // if(Wheelrot != NewWheelrot){ // Wheelrot = NewWheelrot; // llMessageLinked(LINK_ALL_OTHERS, 0, Wheelrot, NULL_KEY); // } } //end control //Sensor is to make a crude Timer as TimerEvent fails on vehicles no_sensor() { if(scount < 1000) { scount++; } else { scount = 0; // This happens about once per second if(Speed > 0) Speed--; if(Speed > 2) Sound(2); if(Speed == 1) { llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, <1.0, 2.0, 1000.0>); llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <0,0,0>); // llMessageLinked(LINK_ALL_OTHERS, 0, "S", NULL_KEY); // Sound(1); // Wheelrot = "S"; } } if(Run == 1) llSensor("Non-Entity",NULL_KEY,PASSIVE,1.0, PI_BY_TWO); } } //end default
[edit] Vehicle LSL Functions and Status
NOTE! This list applies to the revised OpenSimulator, not the released OpenSimulator.
Key: Y = Yes; N = No; F = Framework present but commented out; N/A = Has not been checked (much) yet
[edit] KINEMATIC
Object must not be PHYSICAL
(Some work, some do not.)
Function | Set by LSL? | Used by OpenSimulator C# | Works? | Comments |
---|---|---|---|---|
llSetPos() | Y | Y | Y | Also works on physical objects! |
llSetRot() | Y | Y | Y | Y |
llSetLocalRot() | Y | Y | Y | |
llSetScale() | N/A | N/A | N/A | N/A |
llLookAt() | N/A | N/A | N/A | N/A |
llRotLookAt() | N/A | N/A | N/A | N/A |
llSetPrimitiveParams() | N/A | N/A | N/A | N/A |
llSetLinkPrimitiveParams() | N/A | N/A | N/A | N/A |
llTargetOmega() | N/A | N/A | N/A | N/A |
[edit] DYNAMIC
Object must be PHYSICAL and VEHICLE_TYPE_NONE(default) at present, but this must probably change.
(Some work, some do not.)
Function | Parameter | Set by LSL? | Used by OpenSimulator C# | Comments |
---|---|---|---|---|
llApplyImpulse() | N/A | N/A | N/A | N/A |
llApplyRotationalImpulse() | N/A | N/A | N/A | N/A |
llGroundRepel() | N/A | N/A | N/A | N/A |
llMoveToTarget() | N/A | N/A | N/A | N/A |
llPushObject() | N/A | N/A | N/A | N/A |
llSetBuoyancy() | N/A | N/A | N/A | (do not confuse with VEHICLE_BUOYANCY) |
llSetForce() | N/A | N/A | N/A | N/A |
llSetForceAndTorque() | N/A | N/A | N/A | N/A |
llSetHoverHeight() | N/A | N/A | N/A | (do not confuse with VEHICLE_HOVER_HEIGHT) |
llSetTorque() | N/A | N/A | N/A | N/A |
llTargetOmega() | N/A | N/A | N/A | N/A |
llLookAt() | N/A | N/A | N/A | N/A |
llRotLookAt() | Use of this crashes script | N/A | N/A | N/A |
llSetPrimitiveParams() | N/A | N/A | N/A | N/A |
llSetLinkPrimitiveParams() | N/A | N/A | N/A | N/A |
llTargetOmega() | N/A | N/A | N/A | N/A |
[edit] VEHICLE
Object must be PHYSICAL and VEHICLE_TYPE_<other than NONE>
Functions | Set by LSL? | Used | Works | Exceptions |
---|---|---|---|---|
llSetVehicleType() | Y | Y | Y | |
llSetVehicleFlags() | N | N | N | Some flags are set by llSetVehicleType() |
llRemoveVehicleFlags() | N | N | N | |
llSetVehicleFloatParam() | Y | Y | Y | |
llSetVehicleVectorParam() | Y | Y | Y | |
llSetVehicleRotationParam() | Y | Y | Y |
Parameters | Set by LSL? | Used | Works | Exceptions |
---|---|---|---|---|
VEHICLE_LINEAR_MOTOR_DIRECTION | Y | Y | Y | |
VEHICLE_LINEAR_MOTOR_TIMESCALE | Y | Y | Y | |
VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE | Y | Y | Y | |
VEHICLE_LINEAR_FRICTION_TIMESCALE | Y | Y | Y | |
VEHICLE_LINEAR_MOTOR_OFFSET | F | N | ||
VEHICLE_ANGULAR_MOTOR_DIRECTION | Y | Y | Y | |
VEHICLE_ANGULAR_MOTOR_TIMESCALE | Y | Y | Y | |
VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE | Y | Y | Y | |
VEHICLE_ANGULAR_FRICTION_TIMESCALE | Y | Y | Y | |
VEHICLE_BANKING_EFFICIENCY | F | N | ||
VEHICLE_BANKING_MIX | F | N | ||
VEHICLE_BANKING_TIMESCALE | F | N | ||
VEHICLE_BUOYANCY | Y | Y | Y | (do not confuse with llSetBuoyancy()) |
VEHICLE_HOVER_HEIGHT | Y | Y | Y | (do not confuse with llSetHoverHeight()) |
VEHICLE_HOVER_EFFICIENCY | Y | N | ||
VEHICLE_HOVER_TIMESCALE | Y | N | ||
VEHICLE_LINEAR_DEFLECTION_EFFICIENCY | F | N | ||
VEHICLE_LINEAR_DEFLECTION_TIMESCALE | F | N | ||
VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY | F | N | ||
VEHICLE_ANGULAR_DEFLECTION_TIMESCALE | F | N | ||
VEHICLE_REFERENCE_FRAME | F | N | ||
VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY | Y | Y | Y | |
VEHICLE_VERTICAL_ATTRACTION_TIMESCALE | Y | Y | Y | |
VEHICLE_TYPE_NONE | Y | Y | Y | |
VEHICLE_TYPE_BALLOON | Y | Y | Y | |
VEHICLE_TYPE_BOAT | Y | Y | Y | |
VEHICLE_TYPE_CAR | Y | Y | Y | |
VEHICLE_TYPE_SLED | Y | Y | Y | |
VEHICLE_FLAG_NO_DEFLECTION_UP | Y | N | ||
VEHICLE_FLAG_LIMIT_ROLL_ONLY | Y | N | ||
VEHICLE_FLAG_HOVER_WATER_ONLY | Y | Y | ||
VEHICLE_FLAG_HOVER_TERRAIN_ONLY | Y | Y | ||
VEHICLE_FLAG_HOVER_GLOBAL_HEIGHT | Y | Y | ||
VEHICLE_FLAG_HOVER_UP_ONLY | Y | Y | ||
VEHICLE_FLAG_LIMIT_MOTOR_UP | Y | N | ||
VEHICLE_FLAG_MOUSELOOK_STEER | Y | N | ||
VEHICLE_FLAG_MOUSELOOK_BANK | Y | N | ||
VEHICLE_FLAG_CAMERA_DECOUPLED | Y | N |
[edit] VEHICLE TYPE Presets
VEHICLE_TYPE_SLED:
linearFrictionTimescale <30, 1, 1000> angularFrictionTimescale <1000, 1000, 1000> linearMotorDirection <0, 0, 0> linearMotorTimescale 1000 linearMotorDecayTimescale 120 angularMotorDirection <0, 0, 0> angularMotorTimescale 1000 angularMotorDecayTimescale 120 VhoverHeight 0 VhoverEfficiency 1 VhoverTimescale 10 VehicleBuoyancy 0 linearDeflectionEfficiency 1 linearDeflectionTimescale 1 angularDeflectionEfficiency 1 angularDeflectionTimescale 1000 bankingEfficiency 0 bankingMix 1 bankingTimescale 10 referenceFrame ZERO_ROTATION flags FALSE: HOVER_WATER_ONLY HOVER_TERRAIN_ONLY HOVER_GLOBAL_HEIGHT HOVER_UP_ONLY flags TRUE: NO_DEFLECTION_UP LIMIT_ROLL_ONLY LIMIT_MOTOR_UP
VEHICLE_TYPE_CAR:
linearFrictionTimescale <100, 2, 1000> angularFrictionTimescale <1000, 1000, 1000> linearMotorDirection <0, 0, 0> linearMotorTimescale 1 linearMotorDecayTimescale 60 angularMotorDirection <0, 0, 0> angularMotorTimescale 1 angularMotorDecayTimescale 0.8 VhoverHeight 0 VhoverEfficiency 0 VhoverTimescale 1000 VehicleBuoyancy 0 // m_linearDeflectionEfficiency 1 // m_linearDeflectionTimescale 2 // m_angularDeflectionEfficiency 0 angularDeflectionTimescale 10 verticalAttractionEfficiency 1 verticalAttractionTimescale 10 bankingEfficiency -0.2 bankingMix 1 bankingTimescale 1 referenceFrame ZERO_ROTATION flags FALSE: HOVER_WATER_ONLY HOVER_TERRAIN_ONLY HOVER_GLOBAL_HEIGHT flags TRUE: NO_DEFLECTION_UP LIMIT_ROLL_ONLY
HOVER_UP_ONLY LIMIT_MOTOR_UP
VEHICLE_TYPE_BOAT:
linearFrictionTimescale <10, 3, 2> angularFrictionTimescale <10,10,10> linearMotorDirection <0, 0, 0> linearMotorTimescale 5 linearMotorDecayTimescale 60 angularMotorDirection <0, 0, 0> angularMotorTimescale 4 angularMotorDecayTimescale 4 VhoverHeight 0 VhoverEfficiency 0.5 VhoverTimescale 2 VehicleBuoyancy 1 linearDeflectionEfficiency 0.5 linearDeflectionTimescale 3 angularDeflectionEfficiency 0.5 angularDeflectionTimescale 5 verticalAttractionEfficiency 0.5 verticalAttractionTimescale 5 bankingEfficiency -0.3 bankingMix 0.8 bankingTimescale 1 referenceFrame ZERO_ROTATION flags FALSE: HOVER_TERRAIN_ONLY LIMIT_ROLL_ONLY HOVER_GLOBAL_HEIGHT HOVER_UP_ONLY flags TRUE: NO_DEFLECTION_UP HOVER_WATER_ONLY LIMIT_MOTOR_UP
VEHICLE_TYPE_AIRPLANE:
linearFrictionTimescale <200, 10, 5> angularFrictionTimescale <20, 20, 20> linearMotorDirection <0, 0, 0> linearMotorTimescale 2 linearMotorDecayTimescale 60 angularMotorDirection <0, 0, 0> angularMotorTimescale 4 angularMotorDecayTimescale 4 VhoverHeight 0 VhoverEfficiency 0.5 VhoverTimescale 1000 VehicleBuoyancy 0 linearDeflectionEfficiency 0.5 linearDeflectionTimescale 3 angularDeflectionEfficiency 1 angularDeflectionTimescale 2 verticalAttractionEfficiency 0.9 verticalAttractionTimescale 2 bankingEfficiency 1 bankingMix 0.7f bankingTimescale 2 referenceFrame ZERO_ROTATION flags FALSE: NO_DEFLECTION_UP HOVER_WATER_ONLY HOVER_TERRAIN_ONLY HOVER_GLOBAL_HEIGHT HOVER_UP_ONLY LIMIT_MOTOR_UP flags TRUE: LIMIT_ROLL_ONLY
VEHICLE_TYPE_BALLOON:
linearFrictionTimescale <5, 5, 5> angularFrictionTimescale <10, 10, 10> linearMotorDirection <0, 0, 0> linearMotorTimescale 5 linearMotorDecayTimescale 60 angularMotorDirection <0, 0, 0> angularMotorTimescale 6 angularMotorDecayTimescale 10 VhoverHeight 5 VhoverEfficiency 0.8 VhoverTimescale 10 VehicleBuoyancy 1 linearDeflectionEfficiency 0 linearDeflectionTimescale 5 angularDeflectionEfficiency 0 angularDeflectionTimescale 5 verticalAttractionEfficiency 1 verticalAttractionTimescale 1000 bankingEfficiency 0 bankingMix 0.7 bankingTimescale 5 referenceFrame ZERO_ROTATION flags FALSE: NO_DEFLECTION_UP HOVER_WATER_ONLY HOVER_TERRAIN_ONLY HOVER_UP_ONLY LIMIT_MOTOR_UP flags TRUE: LIMIT_ROLL_ONLY HOVER_GLOBAL_HEIGHT