Home Blog Virtual Worlds llDetectedTouchNormal

llDetectedTouchNormal

Written by Peter R. Bloomfield | Friday, 19 September 2008 10:28 | 0 comments

Today I've been trying out one of the new LSL functions in Second Life ®. The function is llDetectedTouchNormal, which returns a vector representing the normal of a surface at the point it was touched. (You need SLClient 1.21 to use these functions).

The aim of my endeavour was to make an object which detects where you touch it, and moves a stack of small spheres to point at that location. The reason the normal is useful here is because it will make this stack work on all sides of the object, even if it is a complex, deformed, rotated object.

Here is the script for the main object:

default
{
    touch_start(integer num)
    {
        // Ignore touches on anything but this prim
        if (llDetectedLinkNumber(0) != llGetLinkNumber()) return;
        
        // Determine the exact local position and normal of the touch
        rotation rootrot = llGetRootRotation();
        vector pos = (llDetectedTouchPos(0) - llGetPos()) / rootrot;
        vector nml = llDetectedTouchNormal(0) / rootrot;
        
        // Encode the information, and send it out to our pointer objects
        llMessageLinked(LINK_SET, 0, (string)pos + "|" + (string)nml, NULL_KEY);
    }
}

Notice that we have to correct for the main object's orientation? This is very important, in case it is rotated in any way. Here is the script to put inside each 'pointer' object:

default
{
    link_message(integer sender, integer num, string sval, key kval)
    {
        // Determine our position and normal vectors
        list parts = llParseString2List(sval, ["|"], []);
        if (llGetListLength(parts) < 2) return;
        vector pos = (vector)llList2String(parts, 0);
        vector nml = (vector)llList2String(parts, 1);
        
        // Determine the offset of this pointer
        float offset = (float)llGetObjectDesc();
        
        // Update the position of this pointer
        llSetPos(pos + (nml * offset));        
    }
}

You will perhaps notice that the pointer object uses its object description. When you create your pointer objects, enter a number into each one's description field. This number (or 'offset') indicates how far (in metres) you want that object to be from the surface of the main object. My original example had four pointer objects, stacked with offsets of 0, 0.25, 0.5, and 0.75 (the pointers themselves were spheres with diameter 0.2m).

You can adjust the offset values to whatever you prefer. A value of 0 will centre the pointer directly on wherever you touch the main object, while negative values will make the pointers go the opposite direction.

Here's a screenshot of my implementation:

[caption id="attachment_71" align="aligncenter" width="150" caption="Screenshot of my Touch Normals demo"]Screenshot of my Touch Normals demo[/caption]

This example is fairly simple, and could certainly be improved upon significantly. One particularly useful feature to add would be determine the rotation for an object to make it point along the normal (so you could e.g. use arrows instead of spheres). Feel free to IM me in-world if you'd like a copy of my demo (full perm, of course!). My avatar is Pedro McMillan.

Add new comment