Rolig Loon

Linkable Multiprim Sliding Door

Recommended Posts

This simple script will operate a multiprim sliding door that you have linked to a larger structure. Each prim in the door must be named "DOOR", and none of the door prims may be the root prim of the linkset. Also, all prims in the door must have the same orientation.  As written, the script assumes that door prims all have their local Z axes horizontal and that the door is supposed to slide on its Y axis.   You could easily change that orientation by changing the order of X,Y,Z parameters in the vector <0.0, gDistance*gON, 0.0>.

The door will only open if you click on one of the door prims.

 

//Linkable Multiprim Sliding Door -- Rolig Loon -- March 2011

// All prims in the door must be named "DOOR", and none can be the root prim of the linkset

integer gON = 1; // Change to -1 to reverse the direction of opening
float gDistance; // Adjust to set the distance the door should move long its local Y axis

default { touch_start(integer total_number) { if (llGetLinkName(llDetectedLinkNumber(0)) == "DOOR") { integer i; for (i=2;i<=llGetNumberOfPrims();++i) { if (llGetLinkName(i) == "DOOR") { list temp = llGetLinkPrimitiveParams(i,[PRIM_POSITION,PRIM_ROT_LOCAL]); rotation local_rot = (rotation)llList2String(temp,1); vector local_pos = ((vector)llList2String(temp,0)- llGetPos())/llGetRot(); llSetLinkPrimitiveParamsFast(i,[PRIM_POSITION,local_pos + (<0.0,gDistance *gON,0.0>*local_rot),PRIM_ROTATION,local_rot/llGetRot()]); } } gON = (-1)*gON; } } }

ETA:  BTW, this script should not be placed in the door itself, but in the frame (or whatever the door is linked to).

 

Share this post


Link to post
Share on other sites

Ohhh, that looks useful!

Of course, you could change "DOOR" in both the script and in the prim names to allow more than one of these in a linkset. As presented in your post, if I did a case-sensitive search and replace and changed "DOOR" with "Bedroom door" for one script, and with "Bathroom door" for another, the two doors should both work and co-exist happily in the same linkset. I have used that trick before with linkable doors using my own scripts.

As an added elegant touch, you might try using llSetObjectDesc( "open" ); to set the description of the door prim to open, or llSetObjectDesc( "closed" ); to set it to closed, and then use llGetObjectDesc(); to determine the current open or closed state of the door. That trick makes the state persist even if the scripts are reset or the linkset is picked up into inventory while the door happens to be open, and then rezzed back in-world. Without that trick, taking the item and re-rezzing it, or resetting the scripts, can make the script think it is starting with the door closed, when in fact it is open, and can make the door move the wrong way, going out of position and into the wall when you try to close it, instead of closing.

I'm popping in-world now to test a variation of your script that used that modification, and will post it here when I have one that works.

Share this post


Link to post
Share on other sites

I'm brand new at this, and don't know what I'm doing wrong. I recreated the door to my shed into 3-linked parts, then C&Ped this script from "default" to the bottom in it's entirety as a new script in the wall next to the "DOOR".

When I got to "Save" - I did that, and then linked the parts together starting with the roof, and ending with the floor, and the door was somewhere in between - so I'd remember not to do it last.

Then I tested the door by 'touching' the wall with the included script.... didn't work.

Where'd I mess up?

Share this post


Link to post
Share on other sites

For a start you'll have missed the global variables above 'default' - copy the whole script as Rolig has it.  Secondly you need to change gDistance to how far you want the prims to move.  ... There may be more, but that should get things moving

Share this post


Link to post
Share on other sites

somehow missed this before... but there is a way to remove the caveat about needing all the pieces to have the same orientation... simply calculate from an arbitrary center how far it has to move, rotate it to be correct for the frame, then add that offset to the pieces.... since it's just and offset, the rotation of the part is irrelevant.

Share this post


Link to post
Share on other sites

I've been trying to use this script to allow a single prim door, linked to a house, to slide along the Y axis and haven't succeeded.  As a test, I've linked the door to a single (root) prim and placed the script in that prim.  I've reset the script.  When I touch the door, nothing happens.  I've copied the entire script, including the variables.

... any ideas what I'm not doing correctly?

thanks, again, to Rolig for her reference.

Share this post


Link to post
Share on other sites


Pazzo Pestana wrote:

[ ...] As a test, I've linked the door to a single (root) prim and placed the script in that prim.  I've reset the script.  When I touch the door, nothing happens.  I've copied the entire script, including the variables.

... any ideas what I'm not doing correctly?

[ ... ]

See my note in the OP >>> "BTW, this script should not be placed in the door itself, but in the frame (or whatever the door is linked to)."  Also, be sure that the door is named "DOOR".

Share this post


Link to post
Share on other sites

Thanks for the script, it seems to do what I want it to do except that once the door slides open, or in this case after the window slides up, I can't get the window to slide down again.

Everytime I click it, it just repeats its 'go up' move.

Share this post


Link to post
Share on other sites

Here is the script I've used;

 

// All prims in the door must be named "Mesh sash window glass", and none can be the root prim of the linksetinteger gON = 1; // Change to -1 to reverse the direction of openingfloat gDistance; // Adjust to set the the door should move long its local Y axisdefault{touch_start(integer total_number){if (llGetLinkName(llDetectedLinkNumber(0)) == "Mesh sash window glass"){integer i;for (i=2;i<=llGetNumberOfPrims();++i){if (llGetLinkName(i) == "Mesh sash window glass"){list temp = llGetLinkPrimitiveParams(i,[PRIM_POSITION,PRIM_ROT_LOCAL]);rotation local_rot = (rotation)llList2String(temp,1);vector local_pos = ((vector)llList2String(temp,0)- llGetPos())/llGetRot();llSetLinkPrimitiveParamsFast(i,[PRIM_POSITION,local_pos + (<0.0,gDistance *gON,0.5>*local_rot),PRIM_ROTATION,local_rot/llGetRot()]);}}gON = (1)*gON;}}}

 

Share this post


Link to post
Share on other sites

That's because you're not reversing direction, Jo.   To go back down again, gON has to become -gON.  You omitted the minus sign, so nothing changes.

gON = (-1)*gON;

or, more simply

gON = -gON;

Share this post


Link to post
Share on other sites

I've added the minus sign to the last bit but now the window only goes up:)

This may be a good moment to confess I am an absolute noob when it comes to scripting ;)

 

// All prims in the door must be named "Mesh sash window glass", and none can be the root prim of the linksetinteger gON = 1; // Change to -1 to reverse the direction of openingfloat gDistance; // Adjust to set the the door should move long its local Y axisdefault{touch_start(integer total_number){if (llGetLinkName(llDetectedLinkNumber(0)) == "Mesh sash window glass"){integer i;for (i=2;i<=llGetNumberOfPrims();++i){if (llGetLinkName(i) == "Mesh sash window glass"){list temp = llGetLinkPrimitiveParams(i,[PRIM_POSITION,PRIM_ROT_LOCAL]);rotation local_rot = (rotation)llList2String(temp,1);vector local_pos = ((vector)llList2String(temp,0)- llGetPos())/llGetRot();llSetLinkPrimitiveParamsFast(i,[PRIM_POSITION,local_pos + (<0.0,gDistance *gON,0.5>*local_rot),PRIM_ROTATION,local_rot/llGetRot()]);}}gON = (-1)*gON;}}}

 

Share this post


Link to post
Share on other sites

Oh, I see what you did, Jo.  Two mistakes:

1. You didn't specify any distance for the window to move.  That's the variable named gDistance, defined at the top of the script, where the note says "Adjust to set the distance the door should move along its Y axis."  So, specify a distance.  Maybe 0.5?  Give it a try.

2. Notice that the note does say that the door (window) will move along its Y axis.  You have not only told it to ignore the Y axis by telling it that gDistance = 0, you have also told it that you want to move 0.5 m on the Z axis every time you click.  Since you do want to move on the Z axis, you need to change the code to tell it that's what your toggle switch should act on.  Your line should say

llSetLinkPrimitiveParamsFast(i,[PRIM_POSITION,local_pos + (<0.0,0.0,gDistance*gON>*local_rot),PRIM_ROTATION,local_rot/llGetRot()]);

 



Share this post


Link to post
Share on other sites

I see, well I did get it to move up a certain amount so I thought that was ok, I did it without having to rotate it.

So I did specify the distance, but probably in the wrong spot or something.

But it is all abracadabra to me :)

I'm such a noob!

I replaced that line with the one you gave but the window now only goes backwards or forwards but still does not return to its original position.

 

// All prims in the door must be named "Mesh sash window glass", and none can be the root prim of the linksetinteger gON = 1; // Change to -1 to reverse the direction of openingfloat gDistance; // Adjust to set the the door should move long its local Y axisdefault{touch_start(integer total_number){if (llGetLinkName(llDetectedLinkNumber(0)) == "Mesh sash window glass"){integer i;for (i=2;i<=llGetNumberOfPrims();++i){if (llGetLinkName(i) == "Mesh sash window glass"){list temp = llGetLinkPrimitiveParams(i,[PRIM_POSITION,PRIM_ROT_LOCAL]);rotation local_rot = (rotation)llList2String(temp,1);vector local_pos = ((vector)llList2String(temp,0)- llGetPos())/llGetRot();llSetLinkPrimitiveParamsFast(i,[PRIM_POSITION,local_pos + (<0.5,0.0,gDistance*gON>*local_rot),PRIM_ROTATION,local_rot/llGetRot()]);}}gON = (-1)*gON;}}}

 

Share this post


Link to post
Share on other sites

Jo, copy that line I just gave you exactly.  What you have done now is to tell it to move 0.5m on the X axis every time you click, and you still haven't specified any value for gDistance at the top of the script, so it's ignoring the gON toggle switch completely.  If you want it to move 0.5 m up and down on its Z axis, you have to tell it that .....

float gDistance = 0.5;

so that the script knows what value of gDistance to multiply gON by each time it gets to the line I just gave you.

  • Like 1

Share this post


Link to post
Share on other sites

Bingo!

I did try and set the distance at the top but it kept giving me an error so I assumed I had to put it somewhere else.

But now it works, thanks for the patience!

 

Share this post


Link to post
Share on other sites

I started working with this script today for a buld I am doing.  I have been playing with it for awhile with no luck, what I am trying to do is make the door automatically close on their own several second after they are first clicked.  I will admit I am absolutly terrible at scripting and normally just throw mulptiple scripts together to get what I need, unfortunatly it is not working this time..  Any help would be appreciated.

Share this post


Link to post
Share on other sites

To do that, you'll have to trigger the door to close in a timer event. You'll start the timer event when the door is opened, give it 5 seconds, and then close, using the same code that is now in the touch_start event for closing the door.  The only trick at all is that you'll have to keep track of what the current state of the gON toggle is, setting it deliberately to OFF as the timer event closes the door again.  Other than that, you just need to copy the existing code from one event into the other.

Oh, and you'll probably want to include a failsafe in the touch_start event to shut the timer event off if you decide to shut the door manually by clicking it before the timer triggers.

Share this post


Link to post
Share on other sites

Hello Rolig Loon, i was able to use this script on my door, thanks for the help, but one big question, is there a way to make the slide smoth? slower? is open too fast ...

Thank you for your help

Share this post


Link to post
Share on other sites
9 minutes ago, Lolita Erin said:

is there a way to make the slide smoth? slower? is open too fast ...

No, at least not easily.  The door is intended to open in a single movement, using llSetLinkPrimitiveParamsFast to move the door's prims together as a unit.  To slow down the movement, you would need to move the door in small steps, looping through the heart of the script each time.  The more steps, the smoother the movement.  If you are up to the challenge, you are welcome to try it.  Frankly, though, I would probably start with a very different basic approach if you want to make a smooth, slow door.  You might begin with SimonT Quinnell's Smooth Sliding Door in the wiki library or, better still, write a script that uses Keyframed Motion.  There are many ways to script doors for different purposes. The challenge is to choose an approach that fits your own situation best.

Share this post


Link to post
Share on other sites

Hello i try many ways and not able to make slower sliding i found this code and work great but is not for slide is for rotate, is anyone able to help me make a sliding link door and  like this code use the SECONDS_TO_ROTATE  variable and the use of while (llGetTime() < SECONDS_TO_ROTATE)  to make smoot slide i will pay lindens for any help i have spend 4 days and not able to make what i need, thank you

/*
 * Smooth Rotating Linked Door With Hinge
 *
 * By: Lyn Mimistrobell
 * Version: 1.1
 * License: Do whatever you like with it, just don't blame me if you break it :)
 */
 
/*
 * Define the rotation in degrees, using the door prim's local coordinate
 * system
 */
vector      ROTATION            = <0.0, 0.0, 80.0>;
 
/*
 * Define the position of the virtual hinge; usually this is half the door
 * prim's width and thickness
 */
vector      HINGE_POSITION      = <-0.8, 0.05, 0.0>;
 
/*
 * Define how fast the door opens, in seconds
 */
float       SECONDS_TO_ROTATE   = 1.0;
 
/*
 * Define after how much time the door should close automatically, in seconds;
 * set to 0.0 to disable autolmatic closing
 */
float       AUTO_CLOSE_TIME     = 10.0;
 
/*
 * Define a sound that plays when the door starts to open; set to NULL_KEY
 * for no sound.
 */
key         SOUND_ON_OPEN       = "e5e01091-9c1f-4f8c-8486-46d560ff664f";
 
/*
 * Define a sound that plays when the door has closed; set to NULL_KEY
 * for no sound.
 */
key         SOUND_ON_CLOSE      = "88d13f1f-85a8-49da-99f7-6fa2781b2229";
 
/*
 * Define the volume of the opening and closing sounds
 */
float       SOUND_VOLUME        = 1.0;
 
/*
 * NORMALLY, THERE IS NO NEED TO CHANGE ANYTHING BELOW THIS COMMENT. IF YOU DO
 * YOU RISK BREAKING IT.
 */
 
integer     gClosed;            // Door state: TRUE = closed, FALSE = opened
rotation    gRotationClosed;    // Initial rotation of the door (closed)
vector      gPositionClosed;    // Initial position of the door (closed)
vector      gRotationPerSecond; // The amount to rotate each second
 
doOpenOrClose() {
    /*
     * Only perform the rotation if the door isn't root or unlinked
     */
    integer linkNumber = llGetLinkNumber();
    if (linkNumber < 2)
        return;
 
    if (gClosed) {
        /*
         * Store the initial rotation and position so we can return to it.
         *
         * Rotating back purely by calculations can in the longer term cause the door
         * to be positioned incorrectly because of precision errors
         *
         * We determine this everytime before the door is being opened in case it was
         * moved, assuming the door was closed whilst being manipulated.
         */
        gPositionClosed = llGetLocalPos();
        gRotationClosed = llGetLocalRot();
 
        /*
         * Play the opening sound and preload the closing sound
         */
        if (SOUND_ON_OPEN)
            llPlaySound(SOUND_ON_OPEN, SOUND_VOLUME);
    }
 
    vector hingePosition = gPositionClosed + HINGE_POSITION * gRotationClosed;
 
    /*
     * Reset the timer and start moving
     */
    llResetTime();
    while (llGetTime() < SECONDS_TO_ROTATE) {
        float time = llGetTime();
        if (! gClosed)
            /*
             * Invert the timer for closing direction
             */
            time = SECONDS_TO_ROTATE - time;
 
        rotation rotationThisStep = llEuler2Rot(gRotationPerSecond * time) * gRotationClosed;
        vector positionThisStep = hingePosition - HINGE_POSITION * rotationThisStep;
        llSetLinkPrimitiveParamsFast(linkNumber, [PRIM_ROT_LOCAL, rotationThisStep, PRIM_POS_LOCAL, positionThisStep]);
    }
 
    /*
     * Set the new state
     */
    gClosed = !gClosed;
 
    if (gClosed) {
        /*
         * Finalize the closing movement
         */
        llSetLinkPrimitiveParamsFast(linkNumber, [PRIM_ROT_LOCAL, gRotationClosed, PRIM_POS_LOCAL, gPositionClosed]);
 
        /*
         * Play the closing sound and preload the opening sound
         */
        if (SOUND_ON_CLOSE)
            llPlaySound(SOUND_ON_CLOSE, SOUND_VOLUME);
        if (SOUND_ON_OPEN)
            llPreloadSound(SOUND_ON_OPEN);
    } else {
        /*
         * Finalize the opening movement
         */
        rotation rotationOpened = llEuler2Rot(ROTATION * DEG_TO_RAD) * gRotationClosed;
        vector positionOpened = hingePosition - HINGE_POSITION * rotationOpened;
        llSetLinkPrimitiveParamsFast(linkNumber, [PRIM_ROT_LOCAL, rotationOpened, PRIM_POS_LOCAL, positionOpened]);
 
        /*
         * Preload the closing sound
         */
        if (SOUND_ON_CLOSE)
            llPreloadSound(SOUND_ON_CLOSE);
 
        /*
         * Set a timer to automatically close
         */
        llSetTimerEvent(AUTO_CLOSE_TIME);
    }
}
 
default {
    state_entry() {
        /*
         * Assume the door is closed when the script is reset
         */
        gClosed = TRUE;
 
        /*
         * These doesn't change unless the script is changed, calculate them once
         */
        gRotationPerSecond = (ROTATION * DEG_TO_RAD / SECONDS_TO_ROTATE);
 
        /*
         * Preload the opening sound
         */
        if (SOUND_ON_OPEN)
            llPreloadSound(SOUND_ON_OPEN);
    }
    touch_start(integer agentCount) {
        doOpenOrClose();
    }
    timer() {
        llSetTimerEvent(0.0);
 
        /*
         * Close the door if it isn't already closed
         */
        if (! gClosed)
            doOpenOrClose();
    }
}

 

 

Share this post


Link to post
Share on other sites
Posted (edited)

I already gave you a link to

On 7/17/2017 at 4:23 PM, Rolig Loon said:

Why didn't you start with it instead?  Please do not advertise here if you want to hire a scripter.  Post in the InWorld Employment forum.

Edited by Rolig Loon

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now