Was going nuts trying to figure out the best way to code rotation independent doors in Second Life. Then I discovered the Lindens helpfully created a function that takes the rotation and calculated vectors for you, so that no matter which way the door is facing you can move it, for instance, one meter to the left.
Anyway, here is my solution if anyone needs a robust door script. It assumes that the initial position for the door is along the Y-axis, set to slide north.
The script will either just slide the door or slide the door halfway and then do a little flip to fold the door against the wall. The second one makes for an elegant little effect.
// Creative Commons Attribute Share-Alike License // Mootly Obviate 2008 // ========== // This script controls doors that slide or slide or slide // and rotate. It is rotation independent and can be used // when linked in single prim doors. Remember that prims // pivot on their center. // The point of this script is to make doors that slide // partly out of the way and then rotate to fold away. // defaults - no reason to touch integer on = 1; // set on flag to 1 (on) integer ont = 0; // set timer flag to 0 (off) rotation delta = <0,0,0,0>; rotation rot = <0,0,0,0>; integer thisstep = 0; // Set this to determine delay before door autocloses. float time = 30; // close after x seconds // Not really position, so much as length of movement. // These should be set to how many meters you want the // doors to move. Normally they should have the same value. float posi = 1; // position float dpos = 1; // default position // Set whether the rotation and movement (x-axis) is // positive or negative integer rotdir = 1; // set positive/negative rotation integer movdir = 1; // set positive/negative movement // Set rotation action: number of steps and degrees per // step. Remember a quarter turn is 90 degrees. integer steps = 2; // set steps in rotation float degper = 45; // set degrees per step // Set flag (0/1) on whether to rotate after sliding. integer rot_tf = 1; // set true false on rotation default { // state entry stuff state_entry() { llOwnerSay("Door Ready"); } // auto close timer timer() { if (ont == 1) { if (rot_tf == 1) { rot = llGetLocalRot(); delta = llEuler2Rot(<0,0,-(rotdir*degper*DEG_TO_RAD)>); thisstep = 0; for (; thisstep < steps; thisstep++) { rot = rot * delta; llSetLocalRot(rot); } } rot = llGetLocalRot(); llSetPos(llGetLocalPos() - dpos*movdir*llRot2Left(rot)); ont = 0; posi = dpos; } } // touch scripts: open, then close touch(integer touches) { if (on == 1) { if (posi == dpos) { rot = llGetLocalRot(); llSetPos(llGetLocalPos() + dpos*movdir*llRot2Left(rot)); posi = 0-dpos; ont = 1; if (rot_tf == 1) { delta = llEuler2Rot(<0,0,(rotdir*degper*DEG_TO_RAD)>); thisstep = 0; for (; thisstep < steps; thisstep++) { rot = rot * delta; llSetLocalRot(rot); } } llSetTimerEvent(time); } else { if (rot_tf == 1) { rot = llGetLocalRot(); delta = llEuler2Rot(<0,0,-(rotdir*degper*DEG_TO_RAD)>); thisstep = 0; for (; thisstep < steps; thisstep++) { rot = rot * delta; llSetLocalRot(rot); } } rot = llGetLocalRot(); llSetPos(llGetLocalPos() - dpos*movdir*llRot2Left(rot)); posi = dpos; ont = 0; } } if (on == 0) { on = 1; } } } // fin
No comments:
Post a Comment