Jump to content

Linkable Multiprim Sliding Door


Rolig Loon
 Share

You are about to reply to a thread that has been inactive for 1137 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

On 12/31/2018 at 1:57 AM, Rolig Loon said:

Ceera's note tells you the answers to those questions. Just try it.

does it mean several scripts for several doors? or i understand incorrect? but can it be done by one script if its not too difficult?

Link to comment
Share on other sites

  • 1 month later...

hi, I've read more times about sliding doors, but there are some things that are not clear to me.

When you say the door prims must be called DOOR must have the '' DOOR '' or without? DOOR? this must be written in the name tab of the object's tool, right?
I bought a script for sliding doors. I thought as for the light script, to put it in the contents of the door. Mine is a door to a sauna shower cabin. Everything has a base and walls. I first linked the walls, the floor, and then the door. Nothing is happening. I disconnected everything, linked everything without the door. The door runs but if I move the sauna cabin the door does not follow. Then I read the post, I disconnected everything, removed the scritp from the door and placed in the contents of the wall where it should flow. Linked everything, touch the door that CALLS DOOR but you move the whole cabin, in another attempt ... door and floor ... I'm going crazy.
With simple words, how do you link a door to a building?
and the script where should it go?
you first link the door as Father and then the shower cabin  (where I put the script) as a child or the other way around
simple words are enough

for ex: I already have the cabin built but not linked

1) rez a prim 
2) create the door
3) it is from here that I can not continue

I know they are elementary things but I am self-taught ...
thanks for help
Adriana (deplove resident)

Edited by deplove
Link to comment
Share on other sites

Sorry, I have only just now seen your note.  The answers to all of your questions are in the text right at the top of the script. Every door must be named "DOOR" because that's how the script finds them. Link the doors to the house and drop the script in the root of the linkset.  Just be sure, as the notes say, that you do not make any of the doors the root prim. If you are unsure about how to link objects, review the basic instructions in the Knowledge Base at 

 

Finally, pay attention to the orientation of your door, as also discussed in the notes.

Link to comment
Share on other sites

  • 4 weeks later...
On 3/6/2011 at 7:09 AM, Rolig Loon said:

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

 

Hello! How to make the door automatically open and close? I managed to add a collision event but I can't add a close timer.

Link to comment
Share on other sites

1 hour ago, ainst Composer said:

Hello! How to make the door automatically open and close? I managed to add a collision event but I can't add a close timer.

Scroll back and look at my response to Lea Vendetta's post in 2014.  She asked exactly the same thing. ;)

  • Thanks 1
Link to comment
Share on other sites

  • 1 month later...
//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;
        }
    }
}

 

This is really a bad script. The door has to be linked to the "root" prim. The movement and also position of the door, is related to the position of the root. So its almost impossible to find the right position of the door.

  • Haha 1
Link to comment
Share on other sites

2 hours ago, Bo Grafta said:

The door has to be linked to the "root" prim. The movement and also position of the door, is related to the position of the root. So its almost impossible to find the right position of the door. 

Of course it does.  That's why it's called a "Linkable Multi-Prim Sliding Door."  And you don't need to do anything at all to determine the position of the door. The position and rotation of the door are always relative to the root of the linkset, and are determined by

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

The script does the work of getting the local position and rotation.  The only adjustment that you might need to do, as noted in the instructions, is to reorder the elements in the vector

(<0.0,gDistance *gON,0.0>*local_rot)

if you want the door to slide along something other than its Y axis.  Otherwise, it's about as basic and straightforward a door design as you can get.

Link to comment
Share on other sites

Hi @Rolig Loon,

I am struggling to understand this, and hopefully you (or someone else ) can clarify for me. I'm trying to create an overall controller for my sliding doors .. which are a bit more complex as they have multiple panels, and thus I move them in stepped groups (i.e. first panel slides until it is even with panel two, then they both move 'together' .. etc). so my questions

1) Why:

vector local_pos = ((vector)llList2String(temp,0)- llGetPos())/llGetRot();

Instead of simply changing the initial PP call to:

list temp = llGetLinkPrimitiveParams(i,[PRIM_POS_LOCAL,PRIM_ROT_LOCAL]);
vector local_pos = (vector)llList2String(temp,0);

2) Actually not clear what all the rotation stuff is doing ... why do we reset the prim's rotation? Moving a linked prim along an axis, in-world, we can see that neither its world nor its local rotations every change .. so why are we doing that here?

3) Following onto 1) why are we not simply doing the following when setting the position:

llSetLinkPrimitiveParamsFast(i, [PRIM_POS_LOCAL, local_pos + (<0.0, gDistance * gON, 0.0>)]);

Is there something I am missing here?

Link to comment
Share on other sites

5 hours ago, Wandering Soulstar said:

Is there something I am missing here?

The easy answer is that you are missing the date when this script was posted, eight years ago. If I were writing the script today, I would be starting with eight years more experience than I had then. Also, PRIM_POS_LOCAL and PRIM_ROT_LOCAL were still very new parameter options in 2011, so the business with llGetPos())/llGetRot() was still part of our common toolkit.  Times change, LSL matures, and we all learn new tricks. 

This is why I often advise new scripters to look at scripts that they find in libraries with a critical eye.  There are many good examples out there to learn from, but you shouldn't use  a script without taking it apart to understand how it works.  And without asking whether there are better ways to do the same thing, especially if the script has been around for a while.

Thank you.

 

  • Like 1
Link to comment
Share on other sites

  • 1 month later...

Hello Rolig Loon,

I'm having an issue. I made a sliding glass door (mesh) with the sliding portion or the door named "DOOR" and the frame (non moving part) being named Frame set as the root prim on linking. However my issue is on first click of the door the door oriented itself to the frame part which isn't the position I wanted the door to start/finish if that makes sense. Would you know an easy fix or way to correct the issue? I've got the mesh sliding door uploaded to the beta server where I have been working. :) Thank you

Link to comment
Share on other sites

I think I've temporarily solved the issue, I added a third piece lined up where I needed it to be and made it invis. It works but maybe I'll figure something out later for a more long term fix. Also as someone had suggested using this script for windows would be a terrific idea but how would that work with multiple windows linked? 

Thank you for your reply and I'll look forward to talking with you on your return in July =)

Link to comment
Share on other sites

  • 2 months later...

@Rolig Loon, if I were to get this all setup and working with the doors linked to the root prim of the house, if I move the root prim will it mess up anything? 

Let me explain a bit further. I'm using mesh made by others so I have to add a prim to show me as creator. That is the root prim. Currently, while it is linked, it is not in the final position it will occupy so I will be moving it into it's final position once I have completed the build (my final step).

Will moving the root prim have any effect/affect on the script?

Link to comment
Share on other sites

3 minutes ago, Selene Gregoire said:

Will moving the root prim have any effect/affect on the script?

Nope.  Normally, when you use a script like this it's wise to reset the script when the root is in its new position.  All positions and rotations in the script are calculated relative to the root (that is, they are "local" positions and rotations), so if you move the root, the relative positions of all child prims will change.  Resetting the script will teach it where "ground zero" is again, though.  That's always wise advice and a good habit to be in, but in this particular case you don't actually have to do that.  I wrote the script so that it always checks the relative position and rotation of whatever door you touched before it does anything. To be sure that the script is sensitive to touches anywhere in the house, though, be sure that it's in the root prim.

  • Thanks 1
Link to comment
Share on other sites

18 minutes ago, Rolig Loon said:

Nope.  Normally, when you use a script like this it's wise to reset the script when the root is in its new position.  All positions and rotations in the script are calculated relative to the root (that is, they are "local" positions and rotations), so if you move the root, the relative positions of all child prims will change.  Resetting the script will teach it where "ground zero" is again, though.  That's always wise advice and a good habit to be in, but in this particular case you don't actually have to do that.  I wrote the script so that it always checks the relative position and rotation of whatever door you touched before it does anything. To be sure that the script is sensitive to touches anywhere in the house, though, be sure that it's in the root prim.

Thought so. Just wanted to be sure. Thanks! 

Link to comment
Share on other sites

  • 4 months later...
On 3/6/2011 at 7:09 AM, Rolig Loon said:

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

 

Hello there! Is this possible to add automatic door close timer to this script? :)

Link to comment
Share on other sites

2 minutes ago, Tattooshop said:

Hello there! Is this possible to add automatic door close timer to this script? :)

Certainly.  Just add a timer event that essentially duplicates what's in the scope of that if test in the touch_start event. Trigger it when you touch, and remember to turn it off when the timer fires.

  • Thanks 1
Link to comment
Share on other sites

1 hour ago, Rolig Loon said:

Certainly.  Just add a timer event that essentially duplicates what's in the scope of that if test in the touch_start event. Trigger it when you touch, and remember to turn it off when the timer fires.

Thank you so much! ❤️

//version with automatic closing

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

default
{
    touch_start(integer total_number)
    {
        llSetTimerEvent(Timer);
        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;
        }
    }

    timer()
    {
        llSetTimerEvent(0);
        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;
    }
}

 

  • Like 1
Link to comment
Share on other sites

Now, having done that, you can further simplify by taking the entire routine inside the 

if (llGetLinkName(llDetectedLinkNumber(0)) == "DOOR")

{

}

block and making it into a user-defined function, OpenShut(), that you can call from both the touch_start and the timer events.  😉

Edited by Rolig Loon
  • Thanks 1
Link to comment
Share on other sites

50 minutes ago, Rolig Loon said:

Now, having done that, you can further simplify by taking the entire routine inside the 

if (llGetLinkName(llDetectedLinkNumber(0)) == "DOOR")

{

}

block and making it into a user-defined function, OpenShut(), that you can call from both the touch_start and the timer events.  😉

integer gON = 1; // Change to -1 to reverse the direction of opening
float gDistance = 1; // Adjust to set the distance the door should move long its local Y axis
float TIMER = 5; // Timer (5 seconds by default)

OpenShut()
{
    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;
}

default
{
    touch_start(integer total_number)
    {
        llSetTimerEvent(TIMER);
        if (llGetLinkName(llDetectedLinkNumber(0)) == "DOOR")
        {
            OpenShut();
        }
    }

    timer()
    {
        llSetTimerEvent(0);
        OpenShut();
    }
}

So much better thanks! :D

Discovered unusual behavior. the door opens perfectly, but it’s better not to close it with a click but wait for the automatic closing. because if you open and close it with a click, then the orientation of the door changes and the timer slides it the other way... :(  If double click the door script thinks that open position is the initial one and works again. How to make it to do not react on the touch if the door is open already? Or do not trigger timer on period the door is open?

yes it’s probably better not to turn on the timer again until the door closes ...

Edited by Tattooshop
Link to comment
Share on other sites

Just disable touches as soon as you touch the door and then re-enable them when the timer triggers.  There are several ways to do that.  Perhaps simplest ...

touch_start(integer num)
{
     if (!iTouched)
     {
            iTouched = TRUE;	// This is a global integer variable
            // and then everything else
    }
}

timer()
{
    iTouched = FALSE;
    // And then everything else
}

Or you could take a completely different approach and disable the timer if someone clicks a second time (that is, while iTouched == TRUE). If you do that, a second click will close the door immediately.

touch_start(integer num)
{
    llSetTimerEvent(TIMER)
    {
    if (!iTouched)
    {
        iTouched = TRUE;
        OpenShut();
    }
    else
    {
        llSetTimerEvent(0.0);
        iTouched = FALSE;
        OpenShut();
    }
}

 

  • Thanks 2
Link to comment
Share on other sites

28 minutes ago, Rolig Loon said:

Just disable touches as soon as you touch the door and then re-enable them when the timer triggers.  There are several ways to do that.  Perhaps simplest ...


touch_start(integer num)
{
     if (!iTouched)
     {
            iTouched = TRUE;	// This is a global integer variable
            // and then everything else
    }
}

timer()
{
    iTouched = FALSE;
    // And then everything else
}

Or you could take a completely different approach and disable the timer if someone clicks a second time (that is, while iTouched == TRUE). If you do that, a second click will close the door immediately.


touch_start(integer num)
{
    llSetTimerEvent(TIMER)
    {
    if (!iTouched)
    {
        iTouched = TRUE;
        OpenShut();
    }
    else
    {
        llSetTimerEvent(0.0);
        iTouched = FALSE;
        OpenShut();
    }
}

 

Thank you so much! You are genious! :D

Link to comment
Share on other sites

  • 1 month later...
You are about to reply to a thread that has been inactive for 1137 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...