Jump to content

A Really Great Smooth Door Script Except...


Prokofy Neva
 Share

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

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

Recommended Posts

OK, I totally get that I can hire scripters by posting in "Wanted" (and PS, I have two scripters I regularly hire and pay). But if this is a simple matter of just changing a number, there's no need to bother them.

Doors are hard, at least for me. I have studied them for 16 years. Yes, I'm a slow learner. Long ago it was shown to me how prims had to be cut in a certain way at a certain angle, and then certain scripts had to be put in with certain numbers.

I must have easily two dozen or more different door scripts, aside from "sliding door" which is what I resort to when all those others fail -- scripts with Z axis or Y axis, or any axis, or open inward or open outward. I have tried them all. And sometimes I'll try jamming in 10 of them to a door until it works.

Of course mesh, you can't cut them as you can a prim (inworld, anyway). So there, the numbers and angles matter more.

There's Osprey's Lid and Void Singer's script, it's great and grand. IM me if you need them.

But my ideal door script will be one I can put in a lid to a trunk or a door, and still link up all the things so that the user or buyer who gets the drunk or house doesn't have to have a coalesced soft-link he will struggle to deploy, losing parts, but just one think linked solidly that works.

I finally found one like that which I share here, and on the wiki, I believe it even tells you how on mesh, you may have to play with the numbers.

/*
 * 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            = <90.0, 0.0, 0.0>;
 
/*
 * Define the position of the virtual hinge; usually this is half the door
 * prim's width and thickness
 */
vector      HINGE_POSITION      = <-0.05, 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();
    }
}

Another thing I've learned (from Osprey, may her memory be a blessing!) and Void is that you have to make a hinge, like in real life. You attach the lid with the script in it to the hinge, and the hinge to the door jamb or trunk to make it work.

The beauty part with this script is that you can do that and link them all and it sort of works.

The problem is that you cannot get it to work ideally, i.e. with the lid set far back enough so that it both closes normally without gaps, but doesn't open leaving a gap.

Of course, this being Second Life, it doesn't matter. A trunk can be magic and have a floating lid. You could put straps in the gap I suppose, visible on a prim on one side, and not another (although that looks terrible).

I have tried all kinds of things. I try moving the trunk to fit the lid (easier than constantly moving a scripted lid that constantly re-sets or moves). I try changing numbers. I try shrinking or expanding the mesh lid. It just never gets right. And maybe it never will.

Another trick I learned is not to copy the item with the lid closed. Then both the original and the copy, or at least one of the two, will revert to closing in the wrong direction. Copy it with the lid open, and it's fine. But of course down the line, the next user or buyer is going to find this messes up. Maybe it's a pipe dream to have a lid to a trunk with a hinge all being linked. But why? I mean so many things are possible in SL.

Changing the angle from 90 degrees to some other number like 120 or 80 does not work, and of course on the other axes doesn't work either.

Changing the hinge number within the script doesn't seem to do anything.

Changing the size or position of the prim hinge doesn't matter.

Again, I'm not looking to make someone work for free. If this is not a question of changing a number or adding a line, and requires some extensive reworking, fine, I'll hire a scripter if it is possible. But first, the diagnosis.

 

Edited by Prokofy Neva
Link to comment
Share on other sites

Without getting too far into the code, it's maybe helpful to note that this script doesn't use an actual hinge, but rather specifies where such a hinge would be located in the HINGE_POSITION vector. It wouldn't matter if there were such a hinge item linked into the object, but the script wouldn't pay any attention to it; all it cares about is that position vector, and the ROTATION vector, to determine the motion of the door.

Perhaps obvious: to work at all, this particular script must be in the door part of the assembly, and only one part (prim, mesh, whatever) is rotated when the door opens and closes (so no separate "handle" link or anything moving with the door).

Just playing around with it, I found the advice in the comment is correct: the HINGE_POSITION will typically be half the door prim's width and thickness, assuming the origin of the door is at its center (which will not be the case if the old trick of slicing or cutting away half the door prim is used).

FWIW, using a quick and dirty .5 * .5m * .01m door prim, I had good luck with:

vector      ROTATION            = <0.0, -90.0, 0.0>;
vector      HINGE_POSITION      = <0.25, 0.0, 0.005>;

or 

vector      ROTATION            = <90.0, 0.0, 0.0>;
vector      HINGE_POSITION      = <0.0, 0.25, 0.005>;

depending which axis on which I wanted the door to rotate, but anyway those are really the values to adjust to get a different range and direction of motion.

Glancing at the code, I'd have expected it to be problematic to copy an open door, not a closed one, and that seems to be what I'm seeing, so I'm not sure what situation causes the opposite effect that you encountered.

Link to comment
Share on other sites

Thanks for answering!

Yes, I realize the script doesn't use an actual hinge, Qie, and I talked about the in-script hinge and the external hinge.

But I found that UNLESS I used an external inworld prim hinge, I couldn't get it to work linked.

Making half the MESH item's  dimension does not work.

I'm going to try your numbers anyway just in case I missed something.

Yes, I read the script pinned article.

No, this scripter isn't inworld any more.

I will be back with pictures.

Link to comment
Share on other sites

On 2/8/2021 at 12:38 AM, Prokofy Neva said:

Thanks for answering!

Yes, I realize the script doesn't use an actual hinge, Qie, and I talked about the in-script hinge and the external hinge.

But I found that UNLESS I used an external inworld prim hinge, I couldn't get it to work linked.

Making half the MESH item's  dimension does not work.

I'm going to try your numbers anyway just in case I missed something.

Yes, I read the script pinned article.

No, this scripter isn't inworld any more.

I will be back with pictures.

@Qie thanks so much for help again!

These numbers here didn't work, partly because I was making two things, one for biggies and one for tinies, and they obviously had to be different. But there was one clue I should have thought of -- the negative sign. That did the trick to solve the problem of direction.

I've seen that on the "rez object correctly" script but I hadn't realized that of course it's the same principle here.

I forget the name of that concept, there's a YouTube about it, about how things revolve.

So then it was a question of just shaving the numbers and also moving the inworld hinge (perhaps numbers alone could have done it but I found moving the hinge inworld was easier for me to see and adjust.

I realized it can't be absolutely perfect because a mesh item with fake hinge rings on it can't make that perfect revolution without then having the latch land in the wrong place, not over the keyhole. That is, maybe someone has the craftsmanship to make it do that, but I was mainly interested in it closing "normally," staying linked, and when opening, not taking up half the chest but going back far enough.

(And making it absolutely perfect probably lies in the direction of this set of tips, which are too hard for me, but someone else may find them useful.)

I also found that once you set the script up right in the closed state, you could copy in the closed state and keep it that way. So mission accomplished, and the forums worked right for once.

Edited by Prokofy Neva
  • Like 1
Link to comment
Share on other sites

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