Radar HUD Demo

What:
- Single prim, single script HUD that shows dots for nearby avatars on a map image.
- Less useful than the mini map.
- Uses LSL's HTTP-In, html 5 canvas and ajax.
- Currently under 16k memory as mono.
To use:
- Create a box, attach it to a HUD point, scale and position as you like.
- Drop this script in it.
- Requires media on a prim be enabled.
Bugs:
- Sometimes it just sits there blank. Not sure how/why. Requires a script restart usually to fix.
TODO:
- Add hover text for people (names)
- Add click action for people (profiles?)
- Rotate the map
- Zoom the map
- Options: scan different things, use different colors.
- Make the dots look better
- Add direction indicator to 'me' dot.
<lsl> // License: // This script itself is free to share, modify and use without restriction. // Any linked or referenced files are not included in this license and are licensed by their respective owners under their own respective copyright and other licenses. // Created by Kelly Linden, 2011.
integer display_face = 4;
string index_html;
build_index(string url) {
vector rc = llGetRegionCorner(); string bg_url = "http://map.secondlife.com/map-1-" + (string)((integer)(rc.x / 256)) + "-" + (string)((integer)(rc.y / 256)) + "-objects.jpg"; // Build the index page. index_html =
"<html><head> <script src='http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js' /> <script type='text/javascript' language='javascript'> var me;var req_me = false; var people;var req_people = false;
function plot(ctx, points, color, border, size) {
if (points != undefined) {
ctx.fillStyle=color;
for ( p in points ) {
ctx.fillStyle=border;
ctx.fillRect(points[p][0] - 2,points[p][1] - 2,size,size);
ctx.fillStyle=color;
ctx.fillRect(points[p][0] - 1,points[p][1] - 1,size - 2,size -2);
}
}
}
function updateMap() {
canvas = document.getElementById( 'myCanvas' );
ctx = canvas.getContext( '2d' );
img = new Image();
img.src = '" + bg_url + "';
if (!req_me) {
req_me = true;
$.getJSON('mypos',function(data){me = data;req_me=false;});
}
if (!req_people) {
req_people = true;
$.getJSON('avatars',function(data){people = data;req_people=false;});
}
ctx.save();
if (img.complete) {
ctx.drawImage( img, 0, 0, canvas.getAttribute('width'), canvas.getAttribute('height') );
}
plot(ctx,people,'#FF0000','#FFFFFF',5);
plot(ctx,me,'#FFFFFF','#000000',7);
ctx.restore();
setTimeout( updateMap, 500 );
} </script><base href='" + url + "/' /></head> <body style='background: #FFFFFF; width: 100%; height: 100%; margin: 0px;' onLoad='updateMap();'> <canvas id='myCanvas' width='256' height='256' style='position:fixed; top:0px; left:0px;'> Canvas unsupported. </canvas></body></html>"; }
set_url(string url) {
build_index(url);
llSetLinkMedia(LINK_THIS, display_face, // Side to display the media on.
[PRIM_MEDIA_AUTO_PLAY,TRUE, // Show this page immediately
PRIM_MEDIA_CURRENT_URL,url, // The url if they hit 'home'
PRIM_MEDIA_HOME_URL,url, // The url currently showing
PRIM_MEDIA_HEIGHT_PIXELS,256, // Height/width of media texture will be
PRIM_MEDIA_WIDTH_PIXELS,256, // rounded up to nearest power of 2.
PRIM_MEDIA_PERMS_CONTROL, PRIM_MEDIA_PERM_NONE]);
llOwnerSay("Mem: " + (string)llGetUsedMemory());
}
default {
state_entry() { llRequestURL(); }
on_rez(integer i) { llResetScript(); }
changed(integer c)
{
if (c & (CHANGED_REGION | CHANGED_TELEPORT | CHANGED_OWNER))
{ llResetScript(); }
}
http_request(key id, string method, string body)
{
if (method == URL_REQUEST_GRANTED)
{
set_url(body);
}
else if (method == URL_REQUEST_DENIED)
{
llOwnerSay("Failed to get url: " + body);
}
if (method == "GET")
{
list path = llParseString2List(llGetHTTPHeader(id,"x-path-info"),["/"],[]);
if (llGetListLength(path) == 0)
{
llSetContentType(id,CONTENT_TYPE_HTML);
llHTTPResponse(id,200,index_html);
}
else if (llList2String(path,0) == "mypos")
{
vector my_pos = llGetPos();
llHTTPResponse(id,200,"" + (string)((integer)my_pos.x) + "," + (string)(256 - (integer)my_pos.y) + "");
}
else if (llList2String(path,0) == "avatars")
{
list avatars = llGetAgentList(AGENT_LIST_REGION,[]);
string body = "[";
integer i;
integer n = llGetListLength(avatars);
for(i=0;i<n;++i)
{
if (i != 0) body += ",";
vector pos = llList2Vector(llGetObjectDetails(llList2Key(avatars,i),[OBJECT_POS]),0);
body += "[" + (string)((integer)pos.x) + "," + (string)(256 - (integer)pos.y) + "]";
}
body += " ]";
llHTTPResponse(id,200,body);
}
}
}
} </lsl>