Advertisement
Guest User

Untitled

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