OpenSim: Kitto's Vehicle/ODE Fixes

Examples and Issues

OpenSim: Kitto's Vehicle/ODE Fixes

Postby Hiro Protagonist » Fri Oct 23, 2009 11:04 am

To make a long story short:

The code is now part of the master branch of the opensim project.

Q: What does this mean?

A: It means that all of Kitto's work to-date is now a part of 'trunk'

Q: Does this mean that my vehicle scripts from SL will work now?

A: Not exactly. Kitto still has a few things to do before that can happen. That being said, good vehicle scripts -can- be written with whats finished if one is creative, and most vehicle scripts could probably be tweaked to work.

Q: So where does this leave us?
A: See my next post concerning the sailboat scripts I have working on OSGrid


Oh hell, just go check this out for the detailz:
http://osgrid.org/forums/viewtopic.php?f=15&t=1861


Cheers!
James/Hiro
8-)
Hiro Protagonist
 
Posts: 5
Joined: Sat Jan 24, 2009 4:10 am

Re: OpenSim: Kitto's Vehicle/ODE Fixes

Postby admin » Fri Oct 23, 2009 2:03 pm

This is a fast and furious tut for making a scripted sailing vehicle for opensims. It works well on both single regions and megaregions, but excepting between subregions in a megaregion, it probably cannot cross from one sim to another at this time.

First, you will probably find that a prim larger than 10m in your vehicle build will prevent the script working. This is theoretically configurable per-region, but the safe bet is to use sub-10m prims in your vehicle build.

Additionally, while there is no fixed limit (that I'm aware of) to the number of prims you can use in a vehicle build, simpler is most likely better.

So for your boat you will need a hull with a mast. Our sail in this tut will consist of a single prim. First, make the boat hull. Remember that the boat portion of the script will go in the root prim, the boat will turn about the geometric center of this prim, and the captain's sit will be relative to it's position.

Having made such a hull (don't forget the mast!), you will now need to make the sail. The sail is a single prim, and is 'special' - it is special in that most of it is cut away to provide an edge (visible edge but geometric center) to pivot about. Following are the parameters for such a sail at it's maximum dimensions:

Code: Select all
Size:
X:  0.01
Y: 10.00
Z: 10.00

Cut:
B: 0.610
E: 0.630


It is important to have the sail oriented with positive 'z' pointing up (arrows pointing 'up' with local coordinates for the sail displayed).

Did I mention you should have your hull and mast in a linkset yet? you should. Leave the sail unlinked for now, though.

The boat script goes in the root prim of the hull, and is as follows:

Code: Select all
// Very simple vehicle script, mod for OpenSim & ODE & VEHICLE code
// By Kitto Flora  September 2009

// remodified by Hiro Protagonist for basic sailing aquatic motorcraft
// September 2009

// grafted in from Owen Oyen's work implementing sail force simulations
float gmass;

float gleft;
float gright;

vector heading;
float gincrement;
integer g_leftrightflag;
integer gstart;
integer gchannel_num;
integer gtouch_toggle;
integer gtouchoff;
integer gsailposn = 0;
integer gsailleftright;

key g_agent;

rotation grot;

float gheel;
float gWindMag;
float gWindDir;
float gBowDir;
vector bow;
vector gwind;
float grel_angle;
float gboatspeed;
float gsailangle;
float thrust;
//


integer Private = 1;    // Change to 1 to prevent others riding.

vector Sitpos = <-1.3,0.5,0.65>;
vector SitrotV = <0,-20,0>;
rotation Sitrot;
integer tt;
key oldagent;
key agent;

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

}

SetMaterial()
{
    llSetPrimitiveParams([PRIM_MATERIAL, PRIM_MATERIAL_WOOD]);
}

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);
                }
                else
                {
                    //llTriggerSound("car_start",1);
                    oldagent = agent;
                    setVehicle();
                    SetMaterial();
                    llSetStatus(STATUS_PHYSICS, TRUE);
                    //Sensor is to make a crude Timer as TimerEvent fails on vehicles
                    llSensorRepeat("Non-Entity",NULL_KEY,PASSIVE,1.0, PI_BY_TWO,2);

                    llRequestPermissions(agent, PERMISSION_TRIGGER_ANIMATION | PERMISSION_TAKE_CONTROLS);
//                    Sound(1);
                }
            }
            else
            {
                Init();
                llReleaseControls();
//                llStopSound();
            }
        }
    }
   
    touch_start(integer tn){
    }
   
    run_time_permissions(integer perm)
    {
        if (perm)
        {
            llStartAnimation("sit");
            llTakeControls(CONTROL_FWD | CONTROL_BACK | CONTROL_DOWN | CONTROL_UP | CONTROL_RIGHT |
                            CONTROL_LEFT | CONTROL_ROT_RIGHT | CONTROL_ROT_LEFT, TRUE, FALSE);
            llSetStatus(STATUS_PHYSICS, TRUE);
        }
    }
   
    control(key id, integer level, integer edge)
    {
        vector angular_motor;
       
        //get current speed
        vector vel = llGetVel();
        float speed = llVecMag(vel);

        //sheet controls
        if(level & CONTROL_FWD)
        {
// pasted from Owen's original work implementing sailing physics
            gsailposn = llAbs(gsailposn) + 1;
            gsailposn *= gsailleftright;
            gsailangle = gsailposn * DEG_TO_RAD;
//
        }
        if(level & CONTROL_BACK)
        {
// pasted from Owen's original work implementing sailing physics
            gsailposn = llAbs(gsailposn) - 1;
            gsailposn *= gsailleftright;
            gsailangle = gsailposn * DEG_TO_RAD;
//
        }
        // tiller controls
        if(level & (CONTROL_RIGHT|CONTROL_ROT_RIGHT))
        {
// pasted from Owen's original work implementing sailing physics
            if (gboatspeed > 1)
            {
//                llLoopSound("boatunderway_short", 1.0);               
                gright = -0.1;
            }
            grot = llGetRot();
            vector pres_heading = llRot2Euler(grot);
            heading = pres_heading;
            heading.x = 0;  // tumble stop
            heading.y = 0;  // tumble stop
            heading.z += (gright);
            grot = llEuler2Rot(heading);
            llSetRot(grot);
//
        }
       
        if(level & (CONTROL_LEFT|CONTROL_ROT_LEFT))
        {
// pasted from Owen's original work implementing sailing physics
            if (gboatspeed > 1)
            {
//                llLoopSound("boatunderway_short", 1.0);             
                gleft = 0.1;
            }

            grot = llGetRot();
            vector pres_heading = llRot2Euler(grot);
            heading = pres_heading;
            heading.x = 0;  // tumble stop
            heading.y = 0;  // tumble stop
            heading.z += (gleft);
            grot = llEuler2Rot(heading);

            llSetRot(grot);
//
        }
// pasted from Owen's original work implementing sailing physics
        if (gsailposn > 90) gsailposn = 90;  // set sail position
        if (gsailposn < -90) gsailposn = -90;  // set sail position
        llMessageLinked(LINK_SET,0,(string)gsailposn,llGetOwner());   // say it to the sail
//
        llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION, angular_motor);
    } //end control   
   
    //Sensor is to make a crude Timer as TimerEvent fails on vehicles
    no_sensor()
    {
        llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, <10.0, 2.0, 1000.0>);
        llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, <thrust,0,0>);
// pasted from Owen's original work implementing sailing physics
        gwind = < 3,3,0>;
        gWindMag = llVecMag(gwind);
        gboatspeed = llVecMag(llGetVel());
        bow = llRot2Euler(llGetRot()); // Euler angle description of boat's rotation
        bow.z -= 1.57;
        gBowDir = -bow.z;
           
        if (gBowDir < -PI) gBowDir += TWO_PI;                   
        //         Wind direction derived from its velocity vector
        //         Wind speed ditto

        gWindDir = llAtan2(gwind.y,gwind.x); // in Radians
        if (gWindDir < 0)
            gWindDir += TWO_PI;
        grel_angle= gWindDir - gBowDir;

        if (grel_angle > 0) // sail side flip
        {
            gsailleftright = -1;
        }
        else
        {
            gsailleftright = 1;
        }

        if (grel_angle > PI) grel_angle -= TWO_PI;      // This handles traverse of the zero point of circle
        if (grel_angle < -PI ) grel_angle += TWO_PI;  // This does same for the negative case
     
        float aaw = llSqrt( llPow((gWindMag * llCos (grel_angle) + gboatspeed),  2.) + llPow((gWindMag * llSin(grel_angle)),2.));
        if (aaw == 0) {
            aaw = .0001;
        }

        float awrel_angle  = llAtan2((llSin(grel_angle)*gWindMag ) , (gboatspeed + llCos(grel_angle) * gWindMag));

        if (awrel_angle > PI) awrel_angle -= TWO_PI;      // This handles traverse of the zero point of circle
        if (awrel_angle < -PI ) awrel_angle += TWO_PI;  // This does same for the negative case

        thrust = llFabs(llCos(awrel_angle + gsailangle) * aaw *0.85);  // Primary propulsion
        gheel += llSin(awrel_angle) * aaw * 3 * DEG_TO_RAD;
        if (gheel > 40)
            gheel = 40;
        heading.x = gheel;  // tumble stop
        heading.y = 0;  // tumble stop
        heading.z += (gleft);
        grot = llEuler2Rot(heading);

        llSetText(" Speed: "+(string)gboatspeed + " m/s heading: " + (string)gBowDir + " wind: " + (string)gWindDir + " sail trim: " + (string)gsailposn,<1,1,1>,1.0);
//               
    }
   
} //end default


You will likely need to tweak the vertical position of the root prim to get the boat to sit properly in the water.

The sail script goes in the sail. It is as shown:

Code: Select all
default
{
    link_message(integer sender, integer parameter, string message, key uuid)
    {
        if(uuid == llGetOwner())
        {
            float sheet=(float) message;
            llSetLocalRot(llEuler2Rot(DEG_TO_RAD*<0,10,((-1*sheet)+90)>));
        }                   
    }
}


ProTip: you can also slip the sail script into a similarly crafted boom

Having gotten the sail script into the sail, you should now position it relative to the mast and link it with the rest of the boat. Be sure to select the sail first in order to preserve the preexisting root prim.

Notes:

There is only a steady debug wind blowing out of the west. This could easily be changed to a variety of other methods.
The sail does not douse when the Captain stands. It would probably be good if it did.
The boat will sail right up onto and over land; this should probably be addressed.

All in all, this is a very simple working sailboat implementation for OpenSims - it is being offered to those who would form sailing and boating communities as some 'small stuff' in the tie that binds such, to do with as they will.

Have Fun!

Cheers
Hiro Protagonist/James Stallings II

ODE LSL Vehicle support for opensim by Kitto Flora
Boat Scripting by Hiro Protagonist aka James Stallings (derived from other work by Kitto Flora, Owen Oyen, and Hiro Protagonist)
Tutorial courtesy of James Stallings and SimHost.com

_________________
http://opensimulator.org http://osgrid.org http://simhost.com
---------------------------------------------------------------------------------------------------------------------------
The wind
scours the earth for prayers
The night obscures them
admin
Site Admin
 
Posts: 4
Joined: Sat Jan 24, 2009 12:10 am

Re: OpenSim: Kitto's Vehicle in Megasims

Postby ki xaris » Wed Aug 11, 2010 1:58 pm

Hope I'm posting this in the appropriate place but I'm experiencing strange behaviour with this script in a 2x2 megasim. It work fine in the SW quadrant but anywhere in the other three the boat jumps up along the z co-ordinate by about 9 metres when I stand after sailing. When I man it again it descends to sea level and works as it should, only to rise again when I stand. Can anyone please help, or point me to where I can get support with this?
I'm a noobie to scripting so please be gentle :?
ki xaris
 


Return to Scripting

Who is online

Users browsing this forum: No registered users and 1 guest

cron