Jump to content

change a door script into a cabinet script - rotation :D


Chic Aeon
 Share

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

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

Recommended Posts

So I am not the greatest scriptor. I "fiddle". I don't fiddle enough to know what to change in this script and have NO clue about target omega *wink*.

All I want to do is have the door swing OUT insteat of IN. I am assuming that is an easy thing to do if you are a sciptor - LOL. Not so much if you are not. Anyway help appreciated. Another cabinet door that works when linked would be fine, not picky. This is just the one I like for doors.

 

*******************************************

 

// Smooth Door Script - Version 1.2
// by Toy Wylie
// Distributed under the following licence:
// - You can use it in your own works
// - You can sell it with your work
// - This script must remain full permissions
// - This header notice must remain intact
// - You may modify this script as needed
 
float openingTime=3.0;      // in seconds
float openingAngle=90.0;    // in degrees
float autocloseTime=15.0;   // in seconds
integer steps=4;            // number of internal rotation steps
integer world=TRUE;         // align to world or root prim rotation
 
string soundOpen="door_open";
string soundClose="door_close";
 
float omega=0.0;
 
vector axis;
rotation closedRot;
rotation openRot;
 
integer swinging;
integer open;
 
sound(string name)
{
    if(llGetInventoryType(name)==INVENTORY_SOUND)
        llTriggerSound(name,1.0);
}
 
openDoor(integer yes)
{
    if(yes)
        sound(soundOpen);
 
    vector useAxis=axis;
    open=yes;
 
    if(!yes)
        useAxis=-axis;
 
    llSetTimerEvent(openingTime/(float) steps);
    llTargetOmega(useAxis,1.0,omega);
}
 
go()
{
    if(swinging==0)
    {
        if(!open)
        {
            axis=<0.0,0.0,1.0>/llGetRootRotation();
 
            closedRot=llGetLocalRot();
 
            if(world)
                openRot=llGetRot()*llEuler2Rot(<0.0,0.0,openingAngle>*DEG_TO_RAD)/llGetRootRotation();
            else
                openRot=closedRot*llEuler2Rot(<0.0,0.0,openingAngle>*DEG_TO_RAD);
        }
        swinging=steps;
        openDoor(!open);
    }
}
 
rotation slerp(rotation source,rotation target,float amount)
{
   return llAxisAngle2Rot(llRot2Axis(target/=source),amount*llRot2Angle(target))*source;
}
 
default
{
    state_entry()
    {
        swinging=0;
        open=FALSE;
        omega=TWO_PI/360*openingAngle/openingTime;
        llTargetOmega(ZERO_VECTOR,1.0,1.0);
    }
 
    touch_start(integer dummy)
    {
        go();
    }
 
    collision_start(integer dummy)
    {
        go();
    }
 
    timer()
    {
        if(swinging>0)
        {
            swinging--;
            if(swinging!=0)
            {
                float amount=(float) swinging/(float) steps;
                if(open)
                    amount=1.0-amount;
                llSetLinkPrimitiveParamsFast(LINK_THIS,[PRIM_ROT_LOCAL,slerp(closedRot,openRot,amount)]);
                return;
            }
 
            llTargetOmega(axis,0.0,0.0);
            if(open)
            {
                llSetLinkPrimitiveParamsFast(LINK_THIS,[PRIM_ROT_LOCAL,openRot]);
                llSetTimerEvent(autocloseTime);
            }
            else
            {
                llSetLinkPrimitiveParamsFast(LINK_THIS,[PRIM_ROT_LOCAL,closedRot]);
                sound(soundClose);
                llSetTimerEvent(0.0);
            }
        }
        else // autoclose time reached
        {
            llSetTimerEvent(0.0);
            openDoor(!open);
            swinging=steps;
        }
    }
}

 

 

Link to comment
Share on other sites

Well I think that is part of it and changing Omega to -1 is part too, but I spent a long time and never could get it to return to its starting point without going too far (to the point where it would have stopped it if were opening th original way.

 

SO -- going to leave it unlinked and folks can choose to have the door or an open case :D. And that may be just fine. For a hunt and I will most likely never need to know this again. Hence, enough time spent. Appreciate the thought.

Link to comment
Share on other sites

Yeah, I had a play with it and it's more than just changing the rotation.   Something strange happens when it finishes describing the arc and it seems to go all over the place for a moment.

Here's a very simplified version I made, which seems to work well if you just switch the swing angle from positive to negative, depending on which way you want it to open.

ETA: Tweaked version because Chic and I encountered llTargetOmega oddities with the previous one:

 

float swing = -90.0; //90 degreesinteger steps =5;rotation r;rotation tweak;//shouldn't be necessary but seems to befloat f;integer counter;integer initialised;debug( string bugger){//uncomment the next line for debug messages  //  llOwnerSay(bugger);}init(){    initialised = TRUE;    f =  (swing/(float)steps)*DEG_TO_RAD;    r = llEuler2Rot(<0.0,0.0,f>);    tweak = ZERO_ROTATION/r;}default{    state_entry()    {        llTargetOmega(<0.0,0.0,0.0>,0,0.0);        if(initialised==FALSE){            init();        }        }    touch_end(integer total_number)    {        state moving;    }}state moving{    state_entry(){        counter=0;        llTargetOmega(<0.0,0.0,1.0>*llGetLocalRot(),f,0.1);        llSetTimerEvent(1.0);    }    timer(){        ++counter;        llSetText((string)counter,<1.0,1.0,1.0>,0.0);// force viewer to redraw, in the hope of avoiding llTargetOmega oddities        debug((string)counter);        if(counter<steps){            llSetLocalRot(r*llGetLocalRot());        }        else{            llSetTimerEvent(0.0);            debug("turning target omega off");             llTargetOmega(<0.0,0.0,0.0>,0,0.0);            llSetLocalRot(r*llGetLocalRot());                       f*=-1.0;            r.s*=-1;                        counter = 0;                        state default;        }    }}

 

 

Link to comment
Share on other sites

hi :)

Like you I only ever mess with scripts when i have to so I can't explain why the changes I made work but maybe one of the scriptors who have already replied can .

I tried your "Smooth Door Script" in  the setup shown in the first picture , with a mesh door linked to a legacy cube as the root prim (script in door )   :

mesh door 1.PNG

(The yellow face is the extra geometry normally set to invisible to get the axis of the mesh door looking as if it is where it is suppose to be .)

The door opened away from the viwer but not at all smooth for me ,like in 4 distict steps. Setting a Z (?) value from 1.0 to 0.5 sorted the jerky opening . Image below :

opening away from veiwer.PNG

 

After some more fiddling I  found setting that same  Z value and the DEG_TO_RAD  to negative ( third image ) the door opened towards the veiwer.

opening towards veiwer.PNG

Link to comment
Share on other sites

here is a snippet of a door script...may help a bit? opens on left hinge-outward

no prim cutting needed...linked doors need llSetLinkPrimitiveParams..

 

http://forums-archive.secondlife.com/54/85/170765/1.html

 

//--ged larsson's edge rotation script, expanded to a function//--to rotate on any edge/axis combination//--fixed for child/attached prims with info from lex neva//--compiled by bloodsong termagantinteger  Y_POS = 3; //hinge on left ... 90 = open ininteger Z_AXIS = 3;RotFromEdge(float fAngle, integer iSide, integer iAxis){      vector size = llGetScale(); //--gets length of sides to find edges.      vector currentRot = <0.0,0.0,0.0>;         rotation desiredRot;  //--we will build this from our single angle    vector rotOriginBefore;  //--starting origin position rotation            currentRot.z = fAngle*DEG_TO_RAD;        desiredRot = llEuler2Rot(currentRot);              rotOriginBefore = (llRot2Left(llGetLocalRot()) * size.y / 2.0);   //hinge on left//  size.y /-2.0 for right       rotation newLocalRot =  desiredRot * llGetLocalRot();     vector rotOriginAfter;          //--same as before, but with our new rotation           rotOriginAfter = (llRot2Left(newLocalRot) * size.y / 2.0);     //hinge on left//  size.y /-2.0 for right      llSetPrimitiveParams([PRIM_POSITION, llGetLocalPos() + rotOriginBefore - rotOriginAfter,       PRIM_ROTATION, newLocalRot]);}integer k;integer open = -90; // 90 for open indefault{   touch_start(integer num)    {     k = !k;     if(k)     {        llOwnerSay("open");              RotFromEdge(open, Y_POS, Z_AXIS);            }    else     {       llOwnerSay("closed");       RotFromEdge(-open, Y_POS, Z_AXIS);     }                }}

 

 

Link to comment
Share on other sites

The issue wasn't so much opening and closing the door, I think, as combining it with llTargetOmega to give it a smooth and slow rotation, which is what the original script was about.

While I understand how to rotate things round an arbirary point with llSetRot, I am wondering -- I am not even sure it's possible -- how you would offset the axis of llTargetOmega in a child prim.    

Link to comment
Share on other sites

You don't have to.  This script goes into the child prim that is the door.  It's a standard cut-prim door -- cut so that the edge it uses as a rotation axis is actually the centerline (the Z axis) of the prim.  Nothing has to be offset.

The script is creating its smooth rotation by simultaneously rotating the door stepwise with llSetLocalRot (although you could do it better and without the 0.2 second delay by using SLPPF([PRIM_ROT_LOCAL]) ) and rotating it in the viewer with llTargetOmega.  The rotation axis of both functions is the same.  To reverse the opening direction of the door, you have to change the sign of the rotation angle in both functions, as Aquila noted.

Link to comment
Share on other sites

Yes, I realise that the script Chic posted goes in a path-cut prim (or a mesh with an offset centre of rotation).

Maybe I should have started a separate thread, to avoid confusion, but what I was wondering was -- in the event I wanted to use a script like the one Xiija posted (or like the one I posted the other day) to rotate an uncut prim, is there any way I can use an offset version of  llTargetOmega to control the apparent speed of rotation?   

If someone presents me with a mesh door that hasn't been made with a built-in offset, is there any way I can use llTargetOmega to make it rotate smoothly, in the way that the Smooth Door Script posted by Chic does?    I don't think there is, at least not if it's a child prim in the linkset.

 

Link to comment
Share on other sites

Gotcha.  The rotation axis of llTargetOmega has to run through the center of the prim.  Since we don't have heirarchical linking, there's no way to make the door a child prim of a hinge that is, itself, a child of the root. If there were, you could put this script into the hinge and set the hinge wherever you wanted it on the door.  Then the door would rotate around the hinge instead of its own centerline.  Maybe someday.

Link to comment
Share on other sites

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