Difference between revisions of "Radar HUD Demo"
Kelly Linden (talk | contribs) |
Kelly Linden (talk | contribs) |
||
(2 intermediate revisions by the same user not shown) | |||
Line 17: | Line 17: | ||
* Rotate the map | * Rotate the map | ||
* Zoom the map | * Zoom the map | ||
* Options: scan different things, use different colors. | * Options: scan different things, use different colors. | ||
* Make the dots look better | |||
* Add direction indicator to 'me' dot. | |||
<lsl> | <lsl> | ||
// License: | // License: | ||
Line 24: | Line 25: | ||
// 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. | // 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. | // Created by Kelly Linden, 2011. | ||
integer display_face = 4; | integer display_face = 4; | ||
string index_html; | string index_html; | ||
build_index(string url) | build_index(string url) | ||
{ | { | ||
vector rc = llGetRegionCorner(); | vector rc = llGetRegionCorner(); | ||
string bg_url = "http://map.secondlife.com/map-1-" + (string)((integer)(rc.x / 256)) + "-" + (string)((integer)(rc.y / 256)) + "-objects.jpg"; | 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. | // Build the index page. | ||
index_html = | index_html = | ||
Line 43: | Line 42: | ||
var me;var req_me = false; | var me;var req_me = false; | ||
var people;var req_people = false; | var people;var req_people = false; | ||
function plot(ctx, points, color, border, size) { | function plot(ctx, points, color, border, size) { | ||
if (points != undefined) { | if (points != undefined) { | ||
Line 55: | Line 54: | ||
} | } | ||
} | } | ||
function updateMap() { | function updateMap() { | ||
canvas = document.getElementById( 'myCanvas' ); | canvas = document.getElementById( 'myCanvas' ); | ||
Line 61: | Line 60: | ||
img = new Image(); | img = new Image(); | ||
img.src = '" + bg_url + "'; | img.src = '" + bg_url + "'; | ||
if (!req_me) { | if (!req_me) { | ||
req_me = true; | req_me = true; | ||
$.getJSON('mypos',function(data){me = data;req_me=false;}); | $.getJSON('mypos',function(data){me = data;req_me=false;}); | ||
} | } | ||
if (!req_people) { | if (!req_people) { | ||
req_people = true; | req_people = true; | ||
$.getJSON('avatars',function(data){people = data;req_people=false;}); | $.getJSON('avatars',function(data){people = data;req_people=false;}); | ||
} | } | ||
ctx.save(); | ctx.save(); | ||
if (img.complete) { | if (img.complete) { | ||
ctx.drawImage( img, 0, 0, canvas.getAttribute('width'), canvas.getAttribute('height') ); | ctx.drawImage( img, 0, 0, canvas.getAttribute('width'), canvas.getAttribute('height') ); | ||
} | } | ||
plot(ctx,people,'#FF0000','#FFFFFF',5); | plot(ctx,people,'#FF0000','#FFFFFF',5); | ||
plot(ctx,me,'#FFFFFF','#000000',7); | plot(ctx,me,'#FFFFFF','#000000',7); | ||
Line 88: | Line 87: | ||
</canvas></body></html>"; | </canvas></body></html>"; | ||
} | } | ||
set_url(string url) | set_url(string url) | ||
{ | { | ||
build_index(url); | build_index(url); | ||
llSetLinkMedia(LINK_THIS, display_face, // Side to display the media on. | llSetLinkMedia(LINK_THIS, display_face, // Side to display the media on. | ||
[PRIM_MEDIA_AUTO_PLAY,TRUE, // Show this page immediately | [PRIM_MEDIA_AUTO_PLAY,TRUE, // Show this page immediately | ||
Line 100: | Line 99: | ||
PRIM_MEDIA_WIDTH_PIXELS,256, // rounded up to nearest power of 2. | PRIM_MEDIA_WIDTH_PIXELS,256, // rounded up to nearest power of 2. | ||
PRIM_MEDIA_PERMS_CONTROL, PRIM_MEDIA_PERM_NONE]); | PRIM_MEDIA_PERMS_CONTROL, PRIM_MEDIA_PERM_NONE]); | ||
llOwnerSay("Mem: " + (string)llGetUsedMemory()); | llOwnerSay("Mem: " + (string)llGetUsedMemory()); | ||
} | } | ||
default | default | ||
{ | { | ||
Line 113: | Line 112: | ||
{ llResetScript(); } | { llResetScript(); } | ||
} | } | ||
http_request(key id, string method, string body) | http_request(key id, string method, string body) | ||
{ | { | ||
Line 124: | Line 123: | ||
llOwnerSay("Failed to get url: " + body); | llOwnerSay("Failed to get url: " + body); | ||
} | } | ||
if (method == "GET") | if (method == "GET") | ||
{ | { | ||
list path = llParseString2List(llGetHTTPHeader(id,"x-path-info"),["/"],[]); | list path = llParseString2List(llGetHTTPHeader(id,"x-path-info"),["/"],[]); | ||
if (llGetListLength(path) == 0) | if (llGetListLength(path) == 0) | ||
{ | { | ||
llSetContentType(id,CONTENT_TYPE_HTML); | llSetContentType(id,CONTENT_TYPE_HTML); | ||
llHTTPResponse(id,200,index_html); | llHTTPResponse(id,200,index_html); | ||
} | } | ||
Line 142: | Line 141: | ||
else if (llList2String(path,0) == "avatars") | 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> | </lsl> |
Latest revision as of 09:21, 25 June 2012
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>