Rotation Recipe: Continuously rotate a prim to face a moving target

Soen Eber

Vatican mole
VVO Supporter 🍦🎈👾❤
Joined
Sep 20, 2018
Messages
4,049
// continuous rotate to face a moving target
// avatar must touch to have it rotate to face them (positive X face)

Code:
key id_lookat = NULL_KEY;
integer bLookAt;

lookat()
{
    // Avatar can move over time, so poll their pos & rot every half second ...
    llSetTimerEvent(0.5);
}
pause()
{
    // ... since all the work happens in the timer event. No timer, no results
    llSetTimerEvent(0.0);
}
// clamp rotation to Z axis only
rotation clamp_to_Z(rotation r)
{
    vector v = llRot2Euler(r)*RAD_TO_DEG;
    v.x = 0;
    v.y = 0;        
    return(llEuler2Rot(v*DEG_TO_RAD));
}
default
{
    timer()
    {
        list l;
        vector pos_lookat;
        rotation rot_lookat;
        vector dir;
        rotation rot_work;

        // if someone has touched, get their UUID and look at them ..."
        if (id_lookat) {
            // ... get the avatar's pos & rot ...
            l = llGetObjectDetails(id_lookat, ([OBJECT_POS, OBJECT_ROT]));
            pos_lookat = llList2Vector(l,0);
            rot_lookat = llList2Rot(l,1);

            // ... and calculate rotation for prim/object                 
            dir = llVecNorm(pos_lookat - llGetPos());
            rot_work = clamp_to_Z(llRotBetween(<1.0, 0.0, 0.0>, dir));
            llSetRot(rot_work);
        }
    }
    on_rez(integer param)
    {
        // force a reset on rez so the script can work
        llResetScript();
    }
    touch_end(integer num_detected)
    {
        // flip bLookAt between on & off
        bLookAt = !bLookAt;
        if (bLookAt) {
            id_lookat = llDetectedKey(0);
            llWhisper(0, "Looking at "+llKey2Name(id_lookat));
            lookat();
        }
        else {
            llOwnerSay("stopped looking");
            pause();
        }
    }
}
 
Last edited:

Argent Stonecutter

Emergency Mustelid Hologram
Joined
Sep 20, 2018
Messages
7,872
Location
Coonspiracy Central, Noonkkot
SL Rez
2005
Joined SLU
Sep 2009
SLU Posts
20780
Nice.

The last call to `llSetTimerEvent(0);` should probably be changed to `pause();` since otherwise there's no reason for `pause() {...}` to exist. :)

Looks like that's what was intended, anyway.
 
  • 1Thanks
Reactions: Soen Eber

Argent Stonecutter

Emergency Mustelid Hologram
Joined
Sep 20, 2018
Messages
7,872
Location
Coonspiracy Central, Noonkkot
SL Rez
2005
Joined SLU
Sep 2009
SLU Posts
20780
I also don't think you're using this: `rot_lookat = llList2Rot(l,1);`

Were you going to have it look where the avatar was looking or something, and then removed or blew off that code?
 

Soen Eber

Vatican mole
VVO Supporter 🍦🎈👾❤
Joined
Sep 20, 2018
Messages
4,049
I also don't think you're using this: `rot_lookat = llList2Rot(l,1);`

Were you going to have it look where the avatar was looking or something, and then removed or blew off that code?
That was copy/paste from something I found that worked and then refactored. I missed that one ... I'll change the code in-world and retest, and then copy over what's here. Thanks for catching it!
 

Argent Stonecutter

Emergency Mustelid Hologram
Joined
Sep 20, 2018
Messages
7,872
Location
Coonspiracy Central, Noonkkot
SL Rez
2005
Joined SLU
Sep 2009
SLU Posts
20780
I've written this code a bunch of times, because I don't keep a library like this. I think I used llSensor() and llDetectedPos() to find the avatar though.