Advertisement
Dorex

Smooth rotating door with hinge

Feb 9th, 2016
257
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //
  2. // http://wiki.secondlife.com/wiki/Smooth_Rotating_Linked_Door_With_Hinge
  3. //
  4. /*
  5.  * Smooth Rotating Linked Door With Hinge
  6.  *
  7.  * By: Lyn Mimistrobell
  8.  * Version: 1.1
  9.  * License: Do whatever you like with it, just don't blame me if you break it :)
  10.  */
  11.  
  12. /*
  13.  * Define the rotation in degrees, using the door prim's local coordinate
  14.  * system
  15.  */
  16. vector      ROTATION            = <0.0, 0.0, 90.0>;
  17.  
  18. /*
  19.  * Define the position of the virtual hinge; usually this is half the door
  20.  * prim's width and thickness
  21.  */
  22. vector      HINGE_POSITION      = <-1.0, 0.005, 0.0>;
  23.  
  24. /*
  25.  * Define how fast the door opens, in seconds
  26.  */
  27. float       SECONDS_TO_ROTATE   = 1.0;
  28.  
  29. /*
  30.  * Define after how much time the door should close automatically, in seconds;
  31.  * set to 0.0 to disable autolmatic closing
  32.  */
  33. float       AUTO_CLOSE_TIME     = 10.0;
  34.  
  35. /*
  36.  * Define a sound that plays when the door starts to open; set to NULL_KEY
  37.  * for no sound.
  38.  */
  39. key         SOUND_ON_OPEN       = "e5e01091-9c1f-4f8c-8486-46d560ff664f";
  40.  
  41. /*
  42.  * Define a sound that plays when the door has closed; set to NULL_KEY
  43.  * for no sound.
  44.  */
  45. key         SOUND_ON_CLOSE      = "88d13f1f-85a8-49da-99f7-6fa2781b2229";
  46.  
  47. /*
  48.  * Define the volume of the opening and closing sounds
  49.  */
  50. float       SOUND_VOLUME        = 1.0;
  51.  
  52. /*
  53.  * NORMALLY, THERE IS NO NEED TO CHANGE ANYTHING BELOW THIS COMMENT. IF YOU DO
  54.  * YOU RISK BREAKING IT.
  55.  */
  56.  
  57. integer     gClosed;            // Door state: TRUE = closed, FALSE = opened
  58. rotation    gRotationClosed;    // Initial rotation of the door (closed)
  59. vector      gPositionClosed;    // Initial position of the door (closed)
  60. vector      gRotationPerSecond; // The amount to rotate each second
  61.  
  62. doOpenOrClose() {
  63.     /*
  64.      * Only perform the rotation if the door isn't root or unlinked
  65.      */
  66.     integer linkNumber = llGetLinkNumber();
  67.     if (linkNumber < 2)
  68.         return;
  69.  
  70.     if (gClosed) {
  71.         /*
  72.          * Store the initial rotation and position so we can return to it.
  73.          *
  74.          * Rotating back purely by calculations can in the longer term cause the door
  75.          * to be positioned incorrectly because of precision errors
  76.          *
  77.          * We determine this everytime before the door is being opened in case it was
  78.          * moved, assuming the door was closed whilst being manipulated.
  79.          */
  80.         gPositionClosed = llGetLocalPos();
  81.         gRotationClosed = llGetLocalRot();
  82.  
  83.         /*
  84.          * Play the opening sound and preload the closing sound
  85.          */
  86.         if (SOUND_ON_OPEN)
  87.             llPlaySound(SOUND_ON_OPEN, SOUND_VOLUME);
  88.     }
  89.  
  90.     vector hingePosition = gPositionClosed + HINGE_POSITION * gRotationClosed;
  91.  
  92.     /*
  93.      * Reset the timer and start moving
  94.      */
  95.     llResetTime();
  96.     while (llGetTime() < SECONDS_TO_ROTATE) {
  97.         float time = llGetTime();
  98.         if (! gClosed)
  99.             /*
  100.              * Invert the timer for closing direction
  101.              */
  102.             time = SECONDS_TO_ROTATE - time;
  103.  
  104.         rotation rotationThisStep = llEuler2Rot(gRotationPerSecond * time) * gRotationClosed;
  105.         vector positionThisStep = hingePosition - HINGE_POSITION * rotationThisStep;
  106.         llSetLinkPrimitiveParamsFast(linkNumber, [PRIM_ROT_LOCAL, rotationThisStep, PRIM_POS_LOCAL, positionThisStep]);
  107.     }
  108.  
  109.     /*
  110.      * Set the new state
  111.      */
  112.     gClosed = !gClosed;
  113.  
  114.     if (gClosed) {
  115.         /*
  116.          * Finalize the closing movement
  117.          */
  118.         llSetLinkPrimitiveParamsFast(linkNumber, [PRIM_ROT_LOCAL, gRotationClosed, PRIM_POS_LOCAL, gPositionClosed]);
  119.  
  120.         /*
  121.          * Play the closing sound and preload the opening sound
  122.          */
  123.         if (SOUND_ON_CLOSE)
  124.             llPlaySound(SOUND_ON_CLOSE, SOUND_VOLUME);
  125.         if (SOUND_ON_OPEN)
  126.             llPreloadSound(SOUND_ON_OPEN);
  127.     } else {
  128.         /*
  129.          * Finalize the opening movement
  130.          */
  131.         rotation rotationOpened = llEuler2Rot(ROTATION * DEG_TO_RAD) * gRotationClosed;
  132.         vector positionOpened = hingePosition - HINGE_POSITION * rotationOpened;
  133.         llSetLinkPrimitiveParamsFast(linkNumber, [PRIM_ROT_LOCAL, rotationOpened, PRIM_POS_LOCAL, positionOpened]);
  134.  
  135.         /*
  136.          * Preload the closing sound
  137.          */
  138.         if (SOUND_ON_CLOSE)
  139.             llPreloadSound(SOUND_ON_CLOSE);
  140.  
  141.         /*
  142.          * Set a timer to automatically close
  143.          */
  144.         llSetTimerEvent(AUTO_CLOSE_TIME);
  145.     }
  146. }
  147.  
  148. default {
  149.     state_entry() {
  150.         /*
  151.          * Assume the door is closed when the script is reset
  152.          */
  153.         gClosed = TRUE;
  154.  
  155.         /*
  156.          * These doesn't change unless the script is changed, calculate them once
  157.          */
  158.         gRotationPerSecond = (ROTATION * DEG_TO_RAD / SECONDS_TO_ROTATE);
  159.  
  160.         /*
  161.          * Preload the opening sound
  162.          */
  163.         if (SOUND_ON_OPEN)
  164.             llPreloadSound(SOUND_ON_OPEN);
  165.     }
  166.     touch_start(integer agentCount) {
  167.         doOpenOrClose();
  168.     }
  169.    
  170.     collision_start(integer num)
  171.     {
  172.        doOpenOrClose();
  173.     }
  174.    
  175.    
  176.     timer() {
  177.         llSetTimerEvent(0.0);
  178.  
  179.         /*
  180.          * Close the door if it isn't already closed
  181.          */
  182.         if (! gClosed)
  183.             doOpenOrClose();
  184.     }
  185. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement