A Touching Event

My friend bucky Barkley just told me yesterday about an incredibly cool feature, that the ever-amazing Qarl Linden has been silently developing: getting the coordinates of the exact spot where you touch on a prim.

Why is this so cool? Well, it allows you to do very complex interfaces with just a handful of prims (or one single prim), and naturally enough, you can imagine how important this is to be able to do browsable HTML-on-a-prim.

In the mean time, I’ll leave you with one simple application as a demonstration: changing the colour of a prim by simply dragging with the mouse over a prim’s surface:


People like Timeless Prototype and Strife Onizuka have been all enthusiastic about this, since Qarl announced in March that he would be implementing this. Shortly thereafter, a Wiki page for comments has been set up by Qarl. The discussion there seemed not to gather much attention, so Qarl turned to the Public JIRA instead.

So, silently but inexorably, this project advanced without many announcements — until, at last, a few days ago, it was launched on the Preview Grid for anyone to explore. It’s rock-solid and works incredibly well — the kind of thing we actually have been expecting from “Magic Qarl”, Wizard of SL Features!

To do a simple test I had to figure out something within my reach to demonstrate how it works, and that is also visually appealing. My first thought was to get back to my old LSL-based web browser and add proper support for clicking on hyperlinks and moving the scrollbars, but that is not the work of a couple of hours. The second idea was to create a whiteboard, that dynamically updates a texture (streamed via HTML-on-a-prim) with dots as you move the cursor over a prim. This would be quite useful, and it’s not too hard to do. Alas, I would need a parcel on the Preview Grid to be able to set the Media URL to allow HTML-on-a-prim, and I can’t do that on the public sandbox, so I have to wait until this feature is rolled out on the Agni (main) Grid — very likely, it’ll be there once Mono is rolled out, which is scheduled for “any time real soon now” (watch the Linden Lab Official Blog for announcements in the next few days!).

So I thought about my old scripting classes, where I usually give the students learning LSL something to do that is visually appealing to encourage them. One of the items that they almost always start to do is a colour changing script (usually tied in to clicking on buttons to change another prim’s colour). This is a variant of the same old story — since you have three parameters for a colour (red, green, blue), showing all possible colours is best done by using a cube — an interface issue on all “colour picker” widgets on the 2D world of our desktops, since invariably you have to map a 3D vector space onto a 2D interface. Not so in SL! A colour cube for picking all possible colours is a natural interface inside a 3D virtual world, of course, and thanks to Qarl’s magic LSL functions, which retrieve things like the face you’ve touched, the coordinates on top of the face, and even the normal and binormal vectors of the avatar-prim interaction (think what people will now be able to do with particles and the physics engine!), this becomes immensely easy to do in plain old LSL.

Here goes the scripts I’ve used. You should read something about how to map colours on top of a cube to understand how those textures were generated. I recommend the introduction to colours by Dan Short; from his site (looking at the HTML source 🙂 ) you can also easily retrieve the textures used in the video above and upload them to Second Life®.

So, log in to the Preview Grid, and create a simple cube, and link it to another object. The cube will be the root prim and will detect touch events, sending the appropriate colour to the second object, which will just set it to the colour selected. Thanks to the touch event, you can repeatedly send these messages, and thus smoothly change the other prim’s colour, resulting in a nice effect as it gradually changes to the colour you’ve chosen.

Smoothly? Oh yes! 🙂 Remember, this is all being compiled to Mono on the Preview Grid — so you get blindingly fast responsiveness 🙂

Anyway, on the Colour Cube (the prim that will serve as a 3D colour changing button), place the script below. Notice that you might have to tweak the ranges depending on the textures you’ve placed and the way they’re rotated (this was actually what took me the most time!). As said, I’ve used Dan Short’s textures, and they’re clearly labeled as “top”, “bottom”, “left”, “right”, “front”, and “back”, so it’s easy to apply them on a cube just rezzed in front of you (assuming you didn’t rotate it!). If you design your own textures for the Colour Cube, you’ll very likely need to adjust the ranges for each face (I used paper and a pencil to finally figure out half of the faces, since the trial-and-error method was taking too long for my taste!)

// Gwyn's Color Cube
// See http://www.danshort.com/colorcube/
vector range;  // these are globals to save some precious CPU cycles
vector colour;
integer face;
colour = <1.0, 1.0, 1.0>;
llSetText((string)colour, colour, 1.0);
llMessageLinked(LINK_ALL_CHILDREN, 0, (string)colour, NULL_KEY);
touch(integer total_number)
// Face will say which pairs of colour to change
face = llDetectedTouchFace(0);
// this is the X, Y position on the face just touched
range = llDetectedTouchST(0);
if (face == 0) // red (primary) is fixed
colour = <1.0, 1.0-range.y, 1.0-range.x>;
else if (face == 1) // green (primary) is fixed
colour = <range.y, 1.0, 1.0-range.x>;
else if (face == 2) // blue is always absent
colour = <range.y, 1.0-range.x, 0.0>;
else if (face == 3) // green is always absent
colour = <range.y, 0.0, range.x>;
else if (face == 4) // blue (primary) is fixed
colour = <range.y, range.x, 1.0>;
else if (face == 5) // red is always absent
colour = <0.0, range.y, 1.0-range.x>;
llSetText((string)colour, colour, 1.0);
llMessageLinked(LINK_ALL_CHILDREN, 0, (string)colour, NULL_KEY);

The prim that changes colour (in my case, a sphere) just replies to linked messages and changes the colour of all faces:

integer r;
integer g;
integer b;
vector colour;
link_message(integer sender_num, integer num, string str, key id)
colour = (vector) str;
llSetColor(colour, ALL_SIDES);
r = (integer)(colour.x * 255);
g = (integer)(colour.y * 255);
b = (integer)(colour.z * 255);
llSetText((string) r + "," + (string) g + "," + (string) b, colour, 1.0);

If you’re concerned about performance, you could do it the other way round: leave the main prim just to send the range coordinates, and do the math on the sphere’s script. I’ve added some hovertext to display the colours in float (on the Colour Cube) and in decimal (on the sphere), just as a visual feedback to be sure I was doing this correctly. You can obviously remove them, as well as the float-to-decimal conversion — hovertext is laggy, although, again, compiling it on Mono you won’t see any issues.

Many, many thanks to Qarl Linden and his amazing talent to develop the kind of features that will have huge impact on how future Second Life devices will work! Now you can have a one-prim-HUD and simplify dramatically your interface with just a single click 🙂 I’m eager to try this out on the main grid… very, very soon!

Print Friendly, PDF & Email

About Gwyneth Llewelyn

I’m just a virtual girl in a virtual world…

  • Oh, I had no idea! I’m such a JIRA nOOb, but this is superb news. Thanks for bringing this to the fore.

  • Oh my, this is insanely wonderful.

  • BTW, good news. At the latest Volunteer Meeting, Periapse Linden has announced that Mono and llDetectedTouch() would be rolled out this Monday as SL server 1.24 is going to be deployed on the grid!

  • yer so nice Gwyneth. let me know where to send the check. 🙂

  • Aww you deserve way more praise than I can possibly write, Qarl — and my “payment” is that we all get a wonderful, totally unexpected fantastic feature in SL thanks to you!

  • Great video G!

    Since then, I did an implementation of image maps (one list defines the regions for every face on a prim – easy to bind rectangles to actions)

    For now on the beta grid:

    Cant wait till this goes live!

  • Nice catch, this is huge. We scripters have been asking for this for years 🙂

  • Surprised you weren’t aware, but glad to see an update. Thank you.

  • Now that’s useful.
    Here come HUDs with sliders at last.

  • I’ve heard something about it but never saw working, for sure it’s totally great 🙂 tyvm for sharing.

  • Gwyn(gwyngwyn) 🙂 Glad to see you did a video too! This is one of those features which is best seen as-is, in-action!

    I look forward to some hella awesome gadgets made with this new feature. It will be touching indeed.

  • Treminari

    I wonder if theres anyone willing to mod VNC to stream in a quicktime compatible format and script VNC client into SL 😮 this feature is amazing!

    If this comes out and someone releases such a version of VNC I could give linux Demo’s on SL and share this great operating system with those unaware.

    Im going to have to revize all the HUD’s i started working on to use this feature!