Want to add a script or a project? Upload it and a half million people will see it and your name here this year.

Category: Contributor: Creator
Close_Approach_Calculator__Imaginar

# Close_Approach_Calculator__Imaginar

## This is something I've seen asked for a lot on various forums and in world. It could be useful for a few things I suppose, combat systems, path finding, what have you. The work here is done by a function that given the starting positions of two objects, and their velocities, it will tell you how close they'll get. In a combat system you might do something like assume all avatars have a radius of about one meter, and then use this to calculate how close an imaginary projectile could come to hitting someone. If it comes closer than one meter, it would be a hit. Here's the code in the form of an "Imaginary Gun".

Category:
By :
Created: 2010-11-16 Edited: 2010-11-16
Worlds: Second Life Download all files for Close_Approach_Calculator__Imaginar
Contents are in zip format, with .LSL (text) source code and (text + Solution) formats. Get file # 1. Close_Approach_Calculator__Imaginar_1.lsl
`  1 float target_radius = 1.0;  2 float bullet_speed = 50.0;  3   4 float ClosestApproachDistance(vector target, vector target_velocity, vector me, vector me_velocity)  5 {  6     // This makes the calculation much simpler by changing the frame of  7     // reference so that the target appears stationary in relation to me.  8     // Now it's a matter of calculating closest approach between a point and  9     // a ray, instead of two rays. 10     vector target_relative_velocity = me_velocity - target_velocity; 11  12     // Initial distance between you and the target. This becomes the hypotenuse 13     // of a right triangle. 14     float initial_distance = llVecDist(me, target); 15  16     // Use the dot product of the normalized vector to target and my normalized 17     // velocity to determine the angle of approach. 18     float angle_of_approach = llAcos(llVecNorm(target - me) * llVecNorm(target_relative_velocity)); 19  20     if(angle_of_approach < PI_BY_TWO) // Make sure the projectile is headed toward the target. 21     { 22         // We have the hypotenuse and theta, so now it's just trig to determine 23         // distance of closest approach. 24         return llSin(angle_of_approach) * initial_distance; 25     } 26     else 27     { 28         // I'm already moving tangent or headed away from the target. We're not 29         // getting any closer than we already are. 30         return initial_distance; 31     } 32 } 33  34 initialize() 35 { 36     llRequestPermissions(llGetOwner(), PERMISSION_TAKE_CONTROLS); 37 } 38  39 finalize() 40 { 41     llReleaseControls(); 42 } 43  44 default 45 { 46 // --> Basic Attachment Junk. 47     state_entry() 48     { 49         if(llGetAttached() != 0) 50         { 51             initialize(); 52         } 53     } 54      55     on_rez(integer sparam) 56     { 57         // If for some reason detach didn't call finalize, we call it again now. 58         if(llGetAttached() == 0) 59         { 60             finalize(); 61         } 62     } 63      64     attach(key id) 65     { 66         // Start when attached and stop when detached. 67         if(id != NULL_KEY) 68         { 69             initialize(); 70         } 71         else 72         { 73             finalize(); 74         } 75     } 76 // --> Basic Attachment Junk. 77      78     run_time_permissions(integer perms) 79     { 80         if((perms & PERMISSION_TAKE_CONTROLS) != 0) 81         { 82             llTakeControls(CONTROL_ML_LBUTTON, TRUE, FALSE); 83         } 84     } 85      86     control(key id, integer level, integer edge) 87     { 88         if((edge & level & CONTROL_ML_LBUTTON) != 0) 89         { 90             llSensor("", NULL_KEY, AGENT, 96.0, PI_BY_TWO); 91             llOwnerSay("BANG!"); 92         } 93     } 94      95     sensor(integer n) 96     { 97         vector agent_size = llGetAgentSize(llGetOwner()); 98         vector bullet_start_position = llGetPos() + <0.0, 0.0, agent_size.z * 0.45>; 99         vector bullet_velocity = llRot2Fwd(llGetRot()) * bullet_speed;100         integer i;101         102         for (i = 0; i < n; i += 1)103         {104             if(ClosestApproachDistance(llDetectedPos(i), llDetectedVel(i), bullet_start_position, bullet_velocity) < target_radius)105             {106                 llOwnerSay("You shot " + llDetectedName(0) + "!");107                 return;108             }109         }110     }111 }`

Back to the Best Free Tools in Second Life and OpenSim.