Change font size
It is currently Sun May 19, 2013 1:03 am

Forum rules


Image



Post a new topicPost a reply Page 1 of 1   [ 4 posts ]
Author Message
 Post subject: Help needed with physical elevator script
PostPosted: Thu Feb 17, 2011 6:06 pm 

Joined: Thu Feb 17, 2011 4:40 pm
Posts: 2
I modified a physical elevator script for a client in Second Life, and am now exporting the build containing that elevator to an opensim grid for the client. My version of the script has working doors on the elevator shaft and the elevator car, and can be used to access multiple floors at random heights. It was modified pretty severely from a simple open-source script for a physical elevator, to add the messaging for the linked sliding doors in the elevator car, and the linked sliding doors in the shaft. The car and shaft communicate with each other, and with the call buttons, by means of a command string on a non-zero channel (17).

This script works flawlessly in the SL grid. There, the car moves straight up and down on the Z axis, and never tries to tilt or rotate the car's prims. But on opensim, the elevator car occasionally 'tumbles'. It goes physical, but instead of only changing the Z position of the car, the root prim gets all sorts of random rotation vectors thrown at it, the car pitches at a weird angle in the shaft, and the car apparently becomes phantom and the passengers get dumped off the car and into the bottom of the shaft. I also tested it without the shaft, and when it malfunctions, the car goes tumbling all over the place, and doesn't stay anywhere near it's assigned X and Y location.

Here's the code that moves the elevator car. There's a list of floor heights at the start, with 4 values for the possible Z-height of the root prim of the elevator car, which is the floor of the car. (Lists have a "zero" position value, so the ground floor is repeated in the first and second positions in the list, allowing the floor number to directly point to the value in the list for that floor's height.)
Code:
vector  alignment;
vector  targetVector;
integer travelDistance;
integer numListen;
integer targetFloor;
list    floorHeights = [28.726,28.726,34.17,37.995];
float   fixedFloorHeight = -1; //Set to floor heights, or set to -1 to use floorHeights list
float   speed = 0.25; //Valid values are 0.01 to 1.0, a Percentage of maxSpeed;
float   maxSpeed = 16;
float   precision = 0.25;
integer autoSpeed = TRUE;
integer initialDistance;
integer doorsopen = 1; // 1 = Car doors are open now, 2 = closed

elevate (vector end)
{
    vector current = llGetPos();
    travelDistance = llRound(current.z-end.z);
    travelDistance = llAbs(travelDistance);
   
    if (autoSpeed)
    {
        if (travelDistance < (initialDistance / 2))
        {
            speed -= (precision / 50);
            if (speed < 0.25)
              speed = 0.25;
        }
        else
        {
            speed += (precision / 25);
            if (speed > 1)
              speed = 1;
        }
    }
    if (travelDistance > 30)
    {
        travelDistance = 30;
        if (end.z > current.z)
        {
            end.z = current.z + 30;
        }
        else
        {
            end.z = current.z - 30;
        }
    }
    float i = travelDistance/(maxSpeed*speed);
    llMoveToTarget(end,i);
}

GotoFloor (integer floor, key id)
{   
    llWhisper(0, "Moving to floor #" + (string)floor);
    llSay(17, "Moving to floor #" + (string)floor);
    if (doorsopen == 1)
    {
        llMessageLinked(LINK_SET, 7, "", NULL_KEY); // send signal to close the doors
        doorsopen = 2;
    }
    llSetStatus(STATUS_PHYSICS, TRUE);
//    llLoopSound("ElevatorNoises", 1);
   
    targetFloor = floor;

    if (fixedFloorHeight > 0)
    {
        targetVector = alignment;
        targetVector.z = alignment.z + (fixedFloorHeight * floor);
    }
    else
    {
        targetVector = alignment;
        targetVector.z = llList2Float(floorHeights, floor);
    }
//    llWhisper(0, "At " + (string)targetVector.z + " meters...");
   
    vector current = llGetPos();
    initialDistance = llRound(current.z-targetVector.z);
    initialDistance = llAbs(initialDistance);
   
    if (autoSpeed)
    {
        speed = 0.01;
    }

    elevate(targetVector);
    llSetTimerEvent(precision);
}

reset()
{
    llSay(0, "Resetting Elevator...");
    llSetStatus(STATUS_ROTATE_X| STATUS_ROTATE_Y| STATUS_ROTATE_Z, FALSE);
   
    alignment = llGetPos();
    llSetStatus(STATUS_PHYSICS, FALSE);
//    llStopSound();
    llListenRemove(numListen);
    numListen = llListen( 17, "", "", "" );
}
default
{
    state_entry()
    {
        reset();
    }
    object_rez(key id)
    {
        llResetScript();
    }
    listen(integer a, string n, key id, string m)
    {
        vector pos;
        integer Floor;
        float tempFloat;
       
        if (llSubStringIndex(m, "goto floor") == 0)
        {
            Floor = (integer)llGetSubString(m, 10, llStringLength(m));
            GotoFloor(Floor, NULL_KEY);
        }
        if (llSubStringIndex(m, "speed") == 0)
        {
            tempFloat = (float)llGetSubString(m, 5, llStringLength(m));
            if ((tempFloat > 0.001) && (tempFloat <= 1.0))
            {
                speed = tempFloat;
            }
        }
        if ((m=="elevator reset") && (id==llGetOwner()))
        {
            reset();
        }       
    }
   
    timer()
    {
        vector CurrentPos;
        float tempfloat;
       
        CurrentPos = llGetPos();
        tempfloat = (CurrentPos.z - targetVector.z);
       
        if (llFabs(tempfloat) < 2)
        {
            if (llFabs(tempfloat) < 0.05)
            {
                //Arrived at Floor
                llWhisper(0, "Arrived at floor #" + (string)targetFloor);
                llSay(17, "Arrived at floor #" + (string)targetFloor);
                if (doorsopen == 2)
                {
                    llMessageLinked(LINK_SET, 8, "", NULL_KEY); // send signal to open the doors
                    doorsopen = 1;
                }
                llSetTimerEvent(0);
                llSetStatus(STATUS_PHYSICS, FALSE);
//                llStopSound();
            }
            else
            {
                llMoveToTarget(targetVector,1.0);
            }
        }
        else
        {
            if (fixedFloorHeight > 0)
            {
                targetVector = alignment;
                targetVector.z = alignment.z + (fixedFloorHeight * targetFloor);
            }
            else
            {
                targetVector = alignment;
                targetVector.z = llList2Float(floorHeights, targetFloor);
            }
            elevate(targetVector);
        }
    }
}


And here is an example of one of the call buttons that sends the elevator to a particular floor (1 in this case):
Code:
default
{
    state_entry()
    {
        //llSay(0, "Control ready");
    }

    touch_start(integer total_number)
    {
        llSay(17, "goto floor 1");
    }
}


The code in the shaft merely listens for the "arrived at" and 'moving to' messages from the car, and opens and closes the shaft doors via link messages.
Code:
door3(integer open3) {
    if (open3 == 1 && door3open == 2) { // closed now, signal sent to open them
        llMessageLinked(LINK_SET, 5, "", NULL_KEY); // send signal to open the doors
        door3open = 1;
    } else if (open3 == 2 && door3open == 1) { // open now, signal sent to close them
        llMessageLinked(LINK_SET, 6, "", NULL_KEY); // send signal to close the doors
        door3open = 2;
    }
}

default
{
    state_entry()
    {
        // Start listening.
        stoplisten();
        startlisten();
        state waiting;
    }
}

state waiting
{
    state_entry() {
        stoplisten();
        startlisten();
    }
   
    listen(integer number, string name, key id, string message)
    {
        if(message=="Arrived at floor #1")
        {
            door1(1); //action here to open, for floor 1;
        } else if (message=="Arrived at floor #2") {
            door2(1); //action here to open, for floor 2;
        } else if (message=="Arrived at floor #3") {
            door3(1); //action here to open, for floor 3;
        } else if (message=="Moving to floor #1" || message=="Moving to floor #2" || message=="Moving to floor #3") {
            door1(2); //action here to close, for floor 1;
            door2(2); //action here to close, for floor 2;
            door3(2); //action here to close, for floor 3;
        }
    }
   
//    timer() { // auto-close
//        door1(2);
//        door2(2);
//        door3(2);
//    }
//   
//    state_exit() {
//        llSetTimerEvent(0);
//    }
   
}


For the curious, here's one of the linkset move listeners for the east doors on floor 1 of the shaft. The West doors have the same script, but opposite sign for the move vectors.
Code:
// Sliding Door Script by Ceera Murakami
// Linkset Listener script. Works with Linkset Control Script in root prim.
// Place this in the prims that must move.

vector gPrimPos; //Recorded position of prim relative to the root prim
float gMoveX = 0.55;//Local offset in x-direction for this prim.
float gMoveY = 0.0; //Local offset in Y direction for this prim

default
{
    link_message(integer sender_number,integer number,string message,key id)
    {
        if(number == 1) {
            gPrimPos = llGetLocalPos();
            llSetPos(<gPrimPos.x+gMoveX,gPrimPos.y+gMoveY,gPrimPos.z>);
        }
        if(number == 2) {
            gPrimPos = llGetLocalPos();
            llSetPos(<gPrimPos.x-gMoveX,gPrimPos.y-gMoveY,gPrimPos.z>);
        }
    }
}


Top
 Profile  
 
 Post subject: Re: Help needed with physical elevator script
PostPosted: Thu Feb 17, 2011 6:26 pm 
OSG Elite
User avatar

Joined: Thu Dec 11, 2008 7:51 am
Posts: 391
Location: England UK
The issue is to do with opensim's physics engine. In SL they use Havok4 which is a like a Rolls Royce compared to opensim's ODE (Open Dynamics Engine) similar to a Ford Escort. Whilst the basic physics functions do work it is very rough around the edges. Whether it is the engine itself or the implementation of the engine I don't know, but physical scripts that do work properly in SL will most likely not work here.

The best solution I can offer (as I have been in the same boat as you a long time ago) is to modify your elevator to use llSetPos in a loop to move the elevator up and down. Add some linked pose balls for the avatars to either sit or stand in the elevator cart when it is moving. This will stop them falling through the floor and as the object won't be physical there is no chance of it 'falling off its rails'.

You will also find that vehicles don't work properly here and also physical prims/objects in general don't operate the same as in SL.

_________________
"...And then one day you'll find, ten years have got behind you, no one told you when to run, you missed the starting gun"
~Pink Floyd


Top
 Profile  
 
 Post subject: Re: Help needed with physical elevator script
PostPosted: Thu Feb 17, 2011 6:31 pm 

Joined: Thu Feb 17, 2011 4:40 pm
Posts: 2
Adelle Fitzgerald wrote:
The issue is to do with opensim's physics engine. In SL they use Havok4 which is a like a Rolls Royce compared to opensim's ODE (Open Dynamics Engine) similar to a Ford Escort. Whilst the basic physics functions do work it is very rough around the edges. Whether it is the engine itself or the implementation of the engine I don't know, but physical scripts that do work properly in SL will most likely not work here.

The best solution I can offer (as I have been in the same boat as you a long time ago) is to modify your elevator to use llSetPos in a loop to move the elevator up and down. Add some linked pose balls for the avatars to either sit or stand in the elevator cart when it is moving. This will stop them falling through the floor and as the object won't be physical there is no chance of it 'falling off its rails'.

You will also find that vehicles don't work properly here and also physical prims/objects in general don't operate the same as in SL.
*Sigh*

I was afraid it would be something like that. I really didn't want to switch this to being a 'sit elevator' with pose balls. It's a very realistic build that duplicates a building on the client's campus, and having to sit on pose balls to use the elevator will really blow that realism.

Oh well. Thanks for answering.


Top
 Profile  
 
 Post subject: Re: Help needed with physical elevator script
PostPosted: Thu May 31, 2012 1:30 pm 

Joined: Sat May 05, 2012 9:05 am
Posts: 10
dang :( , seems Ive run into the same thing. At least this thread saved me some brainache. Does anyone know if things have progressed in this area? I also would detest using poseballs.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post a new topicPost a reply Page 1 of 1   [ 4 posts ]


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
610nm Style by Daniel St. Jules of Gamexe.net