The code uses a timer to periodically get the rotation of the avatar while in mouselook. We then convert this to a Euler rotation and use the y and z components of this vector to determine where the user is looking. We then set the position of the cursor primitive using a scaling factor (which could be better chosen. I just chose some rough values which worked) to adjust the rate of cursor movement. The cursor prim is the secondary prim in my test rig, and the primary prim has the HUD texture and code to pass the touch via link messages.
I have attached a screenshot of the HUD setup and another figure showing how the coordinate system is setup. I hope this is clear enough to follow, and at least somewhat useful.
Primary prim:
CODE
default
{
touch_start(integer total_number)
{
llMessageLinked(LINK_SET, 1, "", NULL_KEY);
}
}
Secondary prim:
CODE
//This code moves a cursor prim in a linked HUD while in mouselook and recognizes when a click has activated a hotspot.
vector rot;
vector cursor_pos;
//This list defines the hotspots which will be active. Format is name of the hotspot, lower left extent, upper right extent.
//This code only accomodates rectangular hotspots. Implementation of other hotspot shapes would not be that difficult, I think.
list hotspots = ["button 1", 0.52, -0.4, 0.26, -0.2, "button 2", -0.26, 0.2, -0.52, 0.4];
list check_hotspot(vector pos)
{
integer i = 0;
list hits = [];
while (i <= llGetListLength(hotspots)/5)
{
if (pos.y < llList2Float(hotspots, i * 5 + 1) && pos.x > llList2Float(hotspots, i * 5 + 2))
{
if (pos.y > llList2Float(hotspots, i * 5 + 3) && pos.x < llList2Float(hotspots, i * 5 + 4))
{
hits = hits + [llList2String(hotspots, i * 5)];
}
}
i++;
}
return hits;
}
default
{
state_entry()
{
llSetTimerEvent(0.2);
}
timer()
{
if (llGetAgentInfo(llGetOwner()) & AGENT_MOUSELOOK)
{
rot = llRot2Euler(llGetRot()) * RAD_TO_DEG;
cursor_pos = <-0.5 * (rot.y/20), 0.65 * (rot.z/55), 0.002>;
llSetPos(cursor_pos);
}
}
link_message(integer sender_num, integer clicked, string msg, key id)
{
llOwnerSay(llList2CSV(check_hotspot(cursor_pos)));
}
}