User:Hidenori Glushenko/SmoothOpeningDoor
Jump to navigation
Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
DoorInit
<lsl> /**
* door-init.lsl * Released into the public domain by Hidenori Glushenko */
default {
state_entry() { list params = llGetPrimitiveParams([PRIM_TYPE]); params = llListReplaceList(params,[<0.125,0.625,0.0>],2,2); llSetPrimitiveParams([PRIM_TYPE]+params+[PRIM_SIZE,<1.6,2.0,0.05>]); llRemoveInventory(llGetScriptName()); }
}</lsl>
SmoothOpeningDoor
<lsl> /*-------------------------------------------------------------------
* Smooth opening door script * This door opens toward the directrion opposit to the avatar's pos. * Released into the public domain by Hidenori Glushenko *------------------------------------------------------------------- * Please initialise your prim's share using door_init.lsl *------------------------------------------------------------------- */
rotation DOOR_ROT_ORG; // base rotation float DOOR_DIV_EULER = 150.0; // open angle float DOOR_OPEN_SEC = 10.0; // open time(seconds) float DOOR_MOVE_TARGET; integer TIMER_COUNT; integer TIMER_MAX = 40; // open speed
// larger is slower
/**
* @state default state : initialize prim's status */
default {
state_entry() { llSetBuoyancy(1.0); llMinEventDelay( 0.01 ); llSetStatus(STATUS_PHANTOM, FALSE); llSetStatus(STATUS_BLOCK_GRAB, TRUE); state DoorClose; }
}
/**
* @state closed state */
state DoorClose {
touch_start(integer total_number) { DOOR_ROT_ORG = llGetRot(); // check the touched avatar's position vector av_offset = (llDetectedPos(0)-llGetPos())/DOOR_ROT_ORG; float av_offset_z = av_offset.z; // calculate the angle depend on the avatar's pos DOOR_MOVE_TARGET = (av_offset_z/llFabs(av_offset_z)) *DOOR_DIV_EULER; state DoorOpen; }
}
/**
* @state opening-opened-closing state */
state DoorOpen {
state_entry() { TIMER_COUNT = 0; llSetTimerEvent(0.05); llSetStatus(STATUS_PHANTOM, TRUE); // set phantom } state_exit() { llSetStatus(STATUS_PHANTOM, FALSE); // set non-phantom when leaving this state llSetTimerEvent(0.0); } touch_start(integer total_number) { // restart timer llSetTimerEvent(0.05); } timer() { rotation rot; ++TIMER_COUNT; // count up // If counter indicates starting door-close if (TIMER_COUNT == TIMER_MAX + 1) { llSetStatus(STATUS_PHANTOM, TRUE); // set phantom llSetTimerEvent(0.05); } // calculate door-angle from counter float x = PI_BY_TWO*TIMER_COUNT/(float)TIMER_MAX; // calculate x(means the ratio) float new_rot_euler = DOOR_MOVE_TARGET * llPow(llSin(x), 2.0); // calculate angle llRotLookAt(rot = (llEuler2Rot(<0.0,new_rot_euler,0.0> *DEG_TO_RAD))*DOOR_ROT_ORG,1.0,1.0); // set door angle // stop when opened if (TIMER_COUNT == TIMER_MAX) { // switch timer to the 'open-time' llSetTimerEvent(DOOR_OPEN_SEC); llSleep(0.2); llSetStatus(STATUS_PHANTOM, FALSE); // set non-phantom when opened llSetStatus(STATUS_PHYSICS, TRUE); // force update rotation llSetStatus(STATUS_PHYSICS, FALSE); // force update rotation llSetRot(rot); // go to close state when closed } else if (TIMER_COUNT >= (TIMER_MAX*2)) { llSleep(0.2); llSetStatus(STATUS_PHYSICS, TRUE); // force update rotation llSetStatus(STATUS_PHYSICS, FALSE); // force update rotation llSetRot(DOOR_ROT_ORG); state DoorClose; } }
}</lsl>