Simulating llSensor() in Blue Mars

While I’m quite sure that there are probably more efficient ways to get the same kind of information, I decided to spend an hour seeing what it would take to simulate the familiar LSL function llSensor() in Blue Mars. Below is a lua function that detects all avatars within a given radius, and narrows down the list by an angle (given here in degrees).

You can see a video of the function being tested below.  In that video, I have set the range to 5 meters, and the angle to 180 degrees. When the function detects any avatar, it updates a simple Flash HUD to show a notification that an avatar was detected. Very simplistic, but it should be enough to show that it works.

Obviously this function does not support the full range of functionality that llSensor() has, but it should be enough to extrapolate from if such a thing were desired.

Returns a Table with a .count property indicating the number of avatars detected, which can then be retrieved using table[index] notation:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
function ARSensor( range, angle )
 
	-- For ease of testing, angle is passed as degrees
	local halfAngle = (angle * g_Deg2Rad) / 4;
 
	local player = g_localActor;
	local playerPos = player:GetWorldPos();
	local playerDirection = player:GetDirectionVector();
 
	local detected = {};
	local detectCount = 0;
 
	local avatarFound = false;
	local nearby = System.GetEntitiesInSphereByClass( playerPos, range, "Avatar" );
	for i,v in pairs( nearby ) do
 
		local detectedPos = v:GetWorldPos();
		local relative = vecNormalize( vecSub( detectedPos, playerPos ) );
		local dot = vecDot( relative, playerDirection );
		local angle = math.acos( dot );
 
		if angle <= halfAngle then
 
			local entityName = v:GetName();
			local entityPos = v:GetWorldPos();
			local entityDir = v:GetDirectionVector();
			local entityDist = DistanceVectors( playerPos, entityPos );
 
			detectCount = detectCount + 1;
 
			detected[ detectCount] = { 
				name = entityName, 
				pos = entityPos, 
				dir = entityDir, 
				dist = entityDist 
				};
 
		end
 
	end
 
	detected.count = detectCount;
 
	return detected;
 
end

3 Comments

  1. Colin
    Posted 2009/10/27 at 4:23 pm | Permalink

    This is the first time I’ve seen Lua code. I can’t imagine how the creators didn’t see code like this and think “Hey, how about we make local the default scope for a variable?”

  2. Posted 2009/10/27 at 4:52 pm | Permalink

    That makes two of us, quite frankly. I’ve always hated when language designers make global scope default, and then compound that monumental error with implicit variable declaration.

    I guess it makes a good third-party market for IDE providers, but you really shouldn’t even need lint to check for accidental global variable declaration.

  3. Shindo
    Posted 2009/11/06 at 12:41 pm | Permalink

    Yeah… Boooooooo! C:SI! C:SI! C:SI!