Jump to content

Help with creating script for synchronized auto open/close double mesh doors?


siennasprout
 Share

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

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

Recommended Posts

I'm extremely new to LSL scripting, so apologies in advance!

I have some mesh doors I've been working on scripting and they've been giving me a lot of trouble. I really want to avoid using a touch to open script as a matter of personal preference, so my goal is finding a way to make it so these double doors open when an avatar walks within range. I successfully managed to get an auto open/close script working using an invisible hinge prim linked individually with each door, and that would be fine if it weren't for the fact the doors don't open at the same time. This is a problem because they're cafe doors, and the sound that I scripted it to play is a shop bell, so it plays twice as each door individually opens.

Unfortunately, as they're mesh doors I have no idea how to script them to move together and play a sound once since by nature of being mesh they seem to require their own individually linked hinge prims. Is there any way to fix this? Thanks in advance for any help!

Link to comment
Share on other sites

3 hours ago, siennasprout said:

I'm extremely new to LSL scripting, so apologies in advance!

I have some mesh doors I've been working on scripting and they've been giving me a lot of trouble

if the doors are going to be a for sale item then best to post in Inworld Employment. Scripters scripting for for-sale items tend to have for-sale scripting skills

if the doors are for your own personal use then post in Wanted for somebody who might help you on a personal basis to become a scripter

 

we can't really answer your question without seeing the doors themselves. Like are they linked as a pair, are they linked to the main build, etc. Will the doors open out or in, or will they swing both ways like batwings, etc

then the next questions for the scripting are like: When a person is near the door but walking past the door do you want the doors to open or not open ? Or only open when the person is moving toward the door. And so on

  • Like 1
Link to comment
Share on other sites

Molly's right. There's such a range of possible ways to build doors and then link them to each other and to a building (or not link them) that it's impossible to give a generic answer that is guaranteed to work for your doors. However, I have found that the best way to be sure that double doors will swing together is to (1) link the doors to each other and (2) write one single script that controls both doors.  One simple way is to rotate the doors with llSetLinkPrimitiveParams, putting the rotations for both doors in one statement and addressing them with PRIM_LINK_TARGET.  That still leaves the question of whether to link the doors to a building, whether they need to open and close slowly, whether they autoclose, and how they are triggered, but at least it's a start.

  • Like 3
Link to comment
Share on other sites

16 hours ago, Mollymews said:

if the doors are going to be a for sale item then best to post in Inworld Employment. Scripters scripting for for-sale items tend to have for-sale scripting skills

if the doors are for your own personal use then post in Wanted for somebody who might help you on a personal basis to become a scripter

 

we can't really answer your question without seeing the doors themselves. Like are they linked as a pair, are they linked to the main build, etc. Will the doors open out or in, or will they swing both ways like batwings, etc

then the next questions for the scripting are like: When a person is near the door but walking past the door do you want the doors to open or not open ? Or only open when the person is moving toward the door. And so on

These doors will be for personal use. They aren't linked to anything yet because I haven't placed them in my build, but ideally I'd want them to be linked as a pair and then linked to the rest of the building and only move outward. Also, I would like to make it so the doors will only open if a person is walking toward the door. I don't know if that's possible with this kind of scripting, but this is what I have so far. These are two separate mesh doors each linked with their own invisible cylindrical hinge prim.

GOxnONn.png

HGymGaW.png

1biNqbN.png

When I walk within a few meters of the door (doesn't matter which direction) they will open outward. Since the sensor is based on avatar proximity they don't open at the same time if you approach them perpendicularly. Also, as I said before, they are not linked together and have a scripted hinge prim each, so that means the door open movement and sound plays twice and out of sync.

Here is what the script looks like:

Quote

// :CATEGORY:Door
// :NAME:AutoDoor
// :AUTHOR:Encog Dod
// :CREATED:2010-01-10 05:20:56.000
// :EDITED:2013-09-18 15:38:48
// :ID:66
// :NUM:93
// :REV:1.0
// :WORLD:Second Life
// :DESCRIPTION:
// AutoDoor
// :CODE:
// From the book:
//
// Scripting Recipes for Second Life
// by Jeff Heaton (Encog Dod in SL)
// ISBN: 160439000X
// Copyright 2007 by Heaton Research, Inc.
//
// This script may be freely copied and modified so long as this header
// remains unmodified.
//
// For more information about this book visit the following web site:
//
// http://www.heatonresearch.com/articles/series/22/

float       TIMER_CLOSE = 5.0;      
integer     DIRECTION   = -1;       // direction door opens in. Either 1 (outwards) or -1 (inwards);

integer     DOOR_OPEN   = 1;
integer     DOOR_CLOSE  = 2;

vector      originalPos;      

door(integer what) 
{
    rotation    rot;
    rotation    delta;
    vector eul;
    
    llSetTimerEvent(0); 
    
    if ( what == DOOR_OPEN ) 
    {
        llTriggerSound("door open", 1);  
        eul = <0, 0, 90*DIRECTION>; //90 degrees around the z-axis, in Euler form 
           
    } else if ( what == DOOR_CLOSE) 
    {
        llTriggerSound("88d13f1f-85a8-49da-99f7-6fa2781b2229", 1);  
        eul = <0, 0, 90*-DIRECTION>; //90 degrees around the z-axis, in Euler form
    }
    
    eul *= DEG_TO_RAD; //convert to radians rotation
    rot = llGetRot();
    delta = llEuler2Rot(eul);
    rot = delta * rot;                  
    llSetRot(rot); 
}
        

default 
{   
    on_rez(integer start_param) 
    { 
        llResetScript();
    }
    
    state_entry() 
    {
        originalPos = llGetPos();  
        llSensorRepeat("", "",AGENT, 5, PI, 1);   
    }
    
    sensor(integer num_detected)
    {
        door(DOOR_OPEN);
        state open_state;
    }
    
    moving_end() 
    {  
        originalPos = llGetPos();
    }
}

state open_state
{
    state_entry() 
    {
        llSensorRepeat("", "",AGENT, 5, PI, 1); 
    }
    
    no_sensor()
    { 
        door(DOOR_CLOSE);
        llSetPos(originalPos);            
        state default;
    }
    
    sensor(integer num_detected)
    {
    }
    
    
    moving_start() 
    { 
        door(DOOR_CLOSE);
        state default;
    }
}

 

  • Like 1
Link to comment
Share on other sites

Those extra hinge prims are going to be a complication.  Let me show you another way.  First, arrange your doors like this:

30ad2b7e38b3d05ab73fb24f55c75c82.png

So, two identical doors made just like your two but without the prim hinges, plus a small flat  prim at ground level that will be the root prim when you link the three together.  This script goes in that new root prim:

integer intSwing =90;
rotation rotSwing;
vector vOffset;

default{    

    state_entry(){
        rotSwing = llEuler2Rot(<0.0,0.0,(float)intSwing>*DEG_TO_RAD);  //90 degrees on the z axis       
        vector size = (vector)llList2String(llGetLinkPrimitiveParams(2,[PRIM_SIZE]),0);       
        vOffset = <(size.x*-0.5),(size.y*-0.5),0.0>;    
    }    

        touch_start(integer total_number){
        list l2 = llGetLinkPrimitiveParams(2,[PRIM_POS_LOCAL,PRIM_ROT_LOCAL]);
        vector v2 = llList2Vector(l2,0);
        rotation r2 = llList2Rot(l2,1);
        list l3 = llGetLinkPrimitiveParams(3,[PRIM_POS_LOCAL,PRIM_ROT_LOCAL]);
        vector v3 = llList2Vector(l3,0);
        rotation r3 = llList2Rot(l3,1);
        rotation rotSwing3 = <rotSwing.x, rotSwing.y,rotSwing.z,-rotSwing.s>;
        llSetLinkPrimitiveParamsFast(LINK_SET,[34,2,PRIM_POS_LOCAL,v2+(vOffset-vOffset * rotSwing)*r2,PRIM_ROT_LOCAL,rotSwing*r2,34,3,PRIM_POS_LOCAL,v3+(vOffset-vOffset * rotSwing3)*r3,PRIM_ROT_LOCAL,rotSwing3*r3]);
        rotSwing.s*=-1;             
    }
}

This isn't a pretty script.  I slapped it together quickly without any thought about optimizing it.  Just creating an example.  It treats the two door prims (links 2 and 3 in the linkset) in exactly the same way except that the rotation of link 3 is the reverse of the rotation of link 2.   Updating the local positions and rotations of the two doors in the same llSetLinkPrimitiveParamsFast statement makes them simultaneous.  Take a look at Innula Zenovka's simple door script in this sticky thread at the top of the LSL Scripting forum:

All I have done is slam two copies of her script together, basically.  (EDIT:  The number 34, which appears in that llSetLinkPrimitiveParamsFast statement is shorthand for the parameter PRIM_LINK_TARGET, which allows you to address more than one link in a single statement.)  Study both her original and this one of mine carefully to understand how they work.  With a little imagination and some care in identifying the link numbers of the two doors, you should be able to figure out how to generalize this approach by linking both doors to your house and then putting the controlling script in the house's root prim.

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

The best way to keep linked double-doors opening in sync is to have them respond not to a touch or collision but to a linked message.    So when you detect the approaching avatar by whatever means, or even when she touches or collides with one of the doors, have that trigger a link message to the whole linkset, and have those two doors start to open and close when they receive it.

 

  • Like 3
Link to comment
Share on other sites

On 11/27/2020 at 6:14 AM, siennasprout said:

They aren't linked to anything yet because I haven't placed them in my build, but ideally I'd want them to be linked as a pair and then linked to the rest of the building

In Second Life, you can't exactly "link two things together, then link them to something else" in a meaningful way. The two linksets become one, and the doors can no longer tell which prim is the "hinge" that used to belong to it. For this reason, a rotating door that is part of the building itself needs to be handled differently from free-standing ones.

Rolig's example is great, but it won't work once the doors are linked to anything else because the link numbers will change.

Edited by Wulfie Reanimator
  • Like 1
Link to comment
Share on other sites

1 hour ago, Wulfie Reanimator said:

but it won't work once the doors are linked to anything else because the link numbers will change

I've had this issue and tried putting a changed_link section in the changed event in but it's tedious. The simplest solution is to name the doors such that they are unique but when double, paired, ie name a pair of doors "library door L" and "library door R". When touched, the door sends a message to the linkset of the form myName + " open" or " close" . Other doors listening to link messages are given names to action, so when "Library Door R" hears "Library door L" announce a position it goes to the same position. The door being told what to do must not in turn announce it's position but simply wait for a further message if there is to be an auto-close on a timer. The door which was touched and sent the message can set a timer if it was commanded to open and there is to be an auto-close, this timer event changes the door position and sends the message to the other listeners.

Two advantages to this system:

1) it survives changes to the link set, even the removal of one of the pair of doors won't harm it

2) you can do things like have all the doors on a long corridor open or close according to one door, useful in haunted hotels, for example.

Link to comment
Share on other sites

5 hours ago, Wulfie Reanimator said:

Rolig's example is great, but it won't work once the doors are linked to anything else because the link numbers will change.

Thank you. That's a very good point. I didn't take time to deal with it in this quick reply to the OP, but I did address it in a more complete version of the script, posted in the Door sticky thread at the top of this forum:

Even there, as Prof points out, information about link numbers will be lost unless you reset the script after adding or removing a link from the structure. One easy solution would be to reset the script in a changed event if CHANGED_LINK is detected.  I'm not sure why he considers that a tedious solution.  Another simple solution, though, is to ignore the problem. I'm not necessarily recommending that, but it's at least worth considering since most people rarely change links in a house.  I think the last time I changed links in my primary skybox was a few years ago.  I locked it to keep me from changing things absent-mindedly then, and haven't touched it since.

 

Link to comment
Share on other sites

I use 2 global variables:

integer     gnumber_of_prims;
integer     gDirty = TRUE;

at startup the linkset is scanned and I get link#s for the names and i set the number of prims

changed event: dirty flag is set if the linkset is changed AND NOT if an avatar sits/unsits

changed(integer change) {
     if (change & CHANGED_LINK) gDirty = gnumber_of_prims!=llGetObjectPrimCount(llGetKey());
}  

and b4 accessing the links:

if (gDirty) call_the_linkset_scanner - scans linkset, sets gnumber_of_prims and resets gDirty;

Some overhead involved but not too much by my taste, object can be changed and can be sat upon and script will still work. And: it will not scan the linkset permanently.

The linkset scanner for a door gets the distance to the "prims" and only takes them when they are under a certain distance! If too far away - keep looping.
That way I can link multiple doors to the same object and there is no need to use different names.
I am way too lazy to set up every single door, they have to work once linked.

  • Like 1
Link to comment
Share on other sites

2 hours ago, Rolig Loon said:

I'm not sure why he considers that a tedious solution

If it happens once in a while it's fine, but supposing you start adding an extension wing to house an ex-president who won't move out or digging a cellar to bury the bodies? You either have to go through the existing linkset to find and disable all door scripts, or put up with scripts thrashing away each time you add or remove a prim. If you disable them, which is the easiest, you then have to painstakingly go through all the child prims resetting them. With my approach, the worst that can happen is that you inadvertently name a new child door prim with an already existing name and end up with ghostly doors.

Edited by Profaitchikenz Haiku
  • Like 1
Link to comment
Share on other sites

2 hours ago, Rachel1206 said:

@Mollymews why is a simple recompile not enough on your existing own builds?

sometimes in complex builds we drag copy items with compiled scripts in. [ And drag copy compiled scripts from Inventory ]. When we do this then the copied scripts execute the one compiled code block by reference, which reduces memory consumption on the server

resetting drag copy scripts preserves the by reference method. When we recompile all scripts then each script is compiled into its own code block and the by reference method is no longer available to the once were copies.  The lsl compiler process is not smart enough at this time to know that a newly compiled code block is the same as another. At this time It only knows by inference thru drag copy

 

Edited by Mollymews
[ ]
  • Like 2
Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 1255 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...