Advertisement
Guest User

Untitled

a guest
Sep 8th, 2019
129
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. list agents = [];
  2.  
  3. float closingStartAngle;
  4. float currentAngle;
  5. vector hinge;
  6. vector ref_pos;
  7. rotation ref_rot;
  8.  
  9.  
  10. float distance_from_hinge(vector aPos)
  11. {
  12.     return llVecDist(<hinge.x, hinge.y, 0>, <aPos.x, aPos.y, 0>);
  13. }
  14.  
  15. track_agent(key agent)
  16. {
  17.     if (llListFindList(agents, [agent]) == -1)
  18.     {
  19.         agents += [agent];
  20.     }
  21. }
  22.  
  23. set_door_rotation()
  24. {
  25.     rotation r = llAxisAngle2Rot(<0,0,1>, currentAngle * DEG_TO_RAD);
  26.     vector   p = rotate_around_axis(hinge, ref_pos, r);
  27.     llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_ROTATION, r * ref_rot, PRIM_POSITION, p]);
  28. }
  29.  
  30. //https://stackoverflow.com/questions/1211212/how-to-calculate-an-angle-from-three-points
  31. float getAngle(float centreX, float centreY, float pointX, float pointY)
  32. {
  33.     float x = pointX - centreX;
  34.     float y = pointY - centreY;
  35.  
  36.     float magnitude = llSqrt(x * x + y * y);
  37.     float angle;
  38.     if (magnitude > 0)
  39.         angle = llAcos(x / magnitude);
  40.        
  41.     angle = angle * 180 / PI;
  42.     if (y < 0)
  43.         angle = 360 - angle;
  44.     return angle;
  45. }
  46.  
  47. vector get_hinge()
  48. {
  49.     vector pos = llGetPos();
  50.     rotation rot = llGetRot();
  51.     vector scale = llGetScale();
  52.     // Offset
  53.     vector offset = <scale.x/2, scale.y/2,0> * rot;
  54.  
  55.     vector hingePos = pos + offset;
  56.     llWhisper(-72, (string)hingePos);
  57.     return hingePos;
  58. }
  59.  
  60.  
  61. vector rotate_around_axis(vector axis, vector position, rotation r)
  62. {
  63.     // Calculate position's offset from axis.
  64.     vector offset = position - axis;
  65.     // Rotate the offset
  66.     vector rotOffset = offset * r;
  67.  
  68.     return axis + rotOffset;
  69. }
  70.  
  71. float sine_easeInOut2(float time, float begin, float cend, float duration)
  72. {
  73.     cend = cend - begin;
  74.     return -cend/2 * (llCos(PI * time / duration) - 1) + begin;
  75. }
  76.  
  77.  
  78. default
  79. {
  80.     state_entry()
  81.     {
  82.         ref_pos = llGetPos();
  83.         ref_rot = llGetRot();
  84.         hinge = get_hinge();
  85.         llSetStatus(STATUS_SANDBOX, TRUE);
  86.         state closed;
  87.        
  88.     }
  89. }
  90.  
  91. state closed
  92. {
  93.     state_entry()
  94.     {
  95.         agents = [];
  96.         llVolumeDetect(TRUE);
  97.         vector euler = llRot2Euler(ref_rot);
  98.         llSetText("Closed... ref angle="  + (string)(euler.z * RAD_TO_DEG), <1,1,1>, 0.5);
  99.         currentAngle = 0;
  100.     }
  101.  
  102.     collision_start(integer num_detected)
  103.     {
  104.         integer i;
  105.         for (i = 0; i < num_detected; i++)
  106.         {
  107.             if (llDetectedType(i) & AGENT)
  108.             {  
  109.                 track_agent(llDetectedKey(i));
  110.             }
  111.         }
  112.         if (llGetListLength(agents) > 0)
  113.         {
  114.             state open;
  115.         }
  116.     }
  117. }
  118.  
  119. state open
  120. {
  121.     state_entry()
  122.     {
  123.         llSetTimerEvent(1 / llGetRegionFPS());
  124.     }
  125.  
  126.     timer()
  127.     {
  128.         integer i;
  129.         integer numAgents = llGetListLength(agents);
  130.         integer agentsInRange = 0;
  131.         for (i = 0; i < numAgents; i++)
  132.         {
  133.             key agent = llList2Key(agents, i);
  134.             vector agentPos = llList2Vector(llGetObjectDetails(agent, [OBJECT_POS]), 0);
  135.             agentPos = rotate_around_axis(hinge, agentPos, ref_rot); // For the purpose of angle calculation, we're making this position rotated to the reference rotation.
  136.             if (distance_from_hinge(agentPos) < 1.25)
  137.             {
  138.  
  139.                 agentsInRange++;
  140.                 vector euler = llRot2Euler(ref_rot);
  141.                 // float startAngle = euler.z * RAD_TO_DEG;
  142.                 float thisAngle = getAngle(hinge.x, hinge.y, agentPos.x, agentPos.y) + 15 ;
  143.                 // while (thisAngle > 360)
  144.                 // {
  145.                 //     thisAngle -= 360;
  146.                 // }
  147.                 // while (thisAngle < 0)
  148.                 // {
  149.                 //     thisAngle += 360;
  150.                 // }
  151.                 llSetText("Tracking... " + (string)thisAngle, <1,1,1>, 0.5);
  152.                 if (thisAngle > 0 && thisAngle < 90)
  153.                 {
  154.  
  155.                     if(numAgents == 1 || thisAngle > currentAngle) currentAngle = thisAngle;
  156.                 }
  157.             }
  158.         }
  159.         if (agentsInRange > 0)
  160.         {
  161.             //llSetText("Open " + (string) currentAngle, <1,1,1>, 0.5);
  162.             set_door_rotation();
  163.         } else {
  164.             state closing;
  165.         }
  166.     }
  167. }
  168.  
  169. state closing
  170. {
  171.     state_entry()
  172.     {
  173.         agents = [];
  174.         closingStartAngle = currentAngle;
  175.         llSetTimerEvent(1 / llGetRegionFPS());
  176.         llResetTime();
  177.         llSetText("Closing", <1,1,1>, 0.5);
  178.     }
  179.  
  180.     collision_start(integer num_detected)
  181.     {
  182.         integer i;
  183.         for (i = 0; i < num_detected; i++)
  184.         {
  185.             if (llDetectedType(i) & AGENT)
  186.             {  
  187.                 track_agent(llDetectedKey(i));
  188.             }
  189.         }
  190.         if (llGetListLength(agents) > 0)
  191.         {
  192.             state open;
  193.         }
  194.     }
  195.  
  196.     timer()
  197.     {
  198.         float elapsed_time = llGetTime();
  199.  
  200. // float sine_easeInOut(float time, float begin, float cend, float duration)
  201. // {
  202. //     return -cend/2 * (llCos(PI * time / duration) - 1) + begin;
  203. // }
  204.  
  205.         if (elapsed_time > 3.0)
  206.         {
  207.             llSetTimerEvent(FALSE);
  208.             currentAngle = 0;
  209.             set_door_rotation();
  210.             state closed;
  211.  
  212.         }
  213.         if (elapsed_time < 3.0)
  214.         {
  215.             currentAngle = sine_easeInOut2(elapsed_time, closingStartAngle, 0, 3.0);
  216.             llSetText("Closing " + (string) currentAngle, <1,1,1>, 0.5);
  217.             set_door_rotation();
  218.         }
  219.     }
  220. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement