Jump to content

llMoveToTarget limited to Region - not really


Susie Chaffe
 Share

You are about to reply to a thread that has been inactive for 254 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

This has not shown up in the forums for a while so I thought it maybe time for a reminder for anyone brave enough to put up with the current state of region crossings.

Because llMoveToTarget only accepts region coordinates, it is frequently assumed that it can only be used within a single region. Not true.
Given a target outside of it's current region an object will travel far enough into an adjacent region to trigger a CHANGED_REGION event.
At this point a new target can be calculated and the object can proceed on its merry way.

Any distance can be covered as long as it is broken down into steps .The maximum distance that can be moved in one hop is 64 metres - but based on experience I would recommend a slightly lower value.

Below is a sample tour script that demonstrates one method of inter sim travel.
The script also attempts to maintain an almost constant velocity throughout each move.

I have included a short sample tour from Blake Sea Spyglass to Barbarossa infohub.
There is rez zone at the end of the pier in Spyglass where you can create or rez a tour disc.

slurl:  http://maps.secondlife.com/secondlife/Blake%20Sea%20-%20Spyglass/145/213/22

Note. This is a rework of a script that appeared in the legacy scripting archives somewhere around 2005 - thanks to the original creator whoever you are.

//Tour Gadget using llMoveToTarget - Susie Chaffe 2008-2013
 
integer DEBUG = FALSE;
//--------------------- Target Variables ----------------------
vector gTargetLocal;  // Target in Region coordinates
vector gTargetRC;     // Target Region Corner
vector gCurrentPos;   // Current position in Region coordinates
vector gCurrentRC;    // Current Region Corner
 
//--------------------- llMoveTo Control Variables -------------
integer targetID;
vector  gMoveTo;             // Next target vector
float   maxStepSize = 60.0;  // Avoid using the 64metre limit of llMoveToTarget
float   range = 0.5;         // at_target condition
float   speed = 5.0;         //
 
// -------------------- Notecard Reader Variables --------
string   gNotecard;    // name of route notecard in the object's inventory
integer  gLine = 0;    // current line number
key      gQueryID;     // id used to identify dataserver queries
list     gLstData;     // List to hold notecard line for parsing to commands
string   gCommand;
 
//--------------------- User Functions ---------------------------
gNextLine()
{
    ++gLine;
    gQueryID = llGetNotecardLine(gNotecard, gLine);
}
 
waypoint()
{
    llSetStatus(STATUS_PHYSICS | STATUS_PHANTOM, TRUE);
    gTargetLocal = (vector)llList2String(gLstData, 2);  //Local xyz
    gTargetRC =    (vector)llList2String(gLstData, 3);  //Region Corner
    gCurrentPos = llGetPos();
    gCurrentRC  = llGetRegionCorner();
 
    if (gTargetRC == gCurrentRC)  gMoveTo = gTargetLocal;
    else gMoveTo = gTargetLocal + (gTargetRC - gCurrentRC);
 
    vector vectorAngle = gMoveTo - gCurrentPos;
    float distance = llVecMag(vectorAngle);    //Calculate Distance
 
    if(distance <= range)
    {
        llTargetRemove(targetID);
        llStopMoveToTarget();
        gNextLine();
        return;
    }
    else
    {
        if (distance > maxStepSize) distance = maxStepSize;
        gMoveTo = gCurrentPos + llVecNorm(vectorAngle)*distance;
        targetID = llTarget(gMoveTo, range);
        llLookAt(gMoveTo,1,1);
        llMoveToTarget(gMoveTo,distance/speed);
    }
}
//----------------------Create Personal Transport Device-------------------------
makePTD()
{
    llSetLinkPrimitiveParamsFast(LINK_THIS,[
        PRIM_TYPE, PRIM_TYPE_SPHERE, 0, <0.0, 1.0, 0.0>, 0.0, ZERO_VECTOR, <0.0, 1.0, 0.0>
        ,   PRIM_SIZE, <0.1, 0.5, 0.5>
        ,   PRIM_ROTATION, <0.0, 0.70711, 0.0, 0.70711>
        ,   PRIM_TEXTURE, 0, "5748decc-f629-461c-9a36-a35a221fe21f", <1.0, 1.0, 0.0>,ZERO_VECTOR, 0.0
        ,   PRIM_COLOR, 0, <0.5, 0.0, 0.0>, 1.0
        ,   PRIM_BUMP_SHINY, 0, PRIM_SHINY_MEDIUM, PRIM_BUMP_NONE]);
    llSetClickAction(CLICK_ACTION_SIT);
    llSitTarget(<-0.76916, 0.004, -0.09061>, <0.0, -0.70711, 0.0, 0.70711>);
    llSetPos(llGetPos() + <0.0,0.0,0.75>);
    llSetText("Sit to Start \n Tour \n  \n ", <1.0, 1.0, 1.0>, 1.0);
}
//-------------------------------------------------------------------------------
default
{
    on_rez(integer start_param)
    {
        llResetScript();
    }
 
    state_entry()
    {
        makePTD();
    }
 
    changed(integer change)
    {
        if (change & CHANGED_LINK)
        {
            llSleep(0.5);
            if (llAvatarOnSitTarget() != NULL_KEY)
            {
                llSetText("", ZERO_VECTOR, 0.0);
                state Tour;
            }
        }
    }
}
 
state Tour
{
    on_rez(integer start_param)
    {
        llResetScript();
    }
 
    state_entry()
    {
        llSetStatus(STATUS_PHYSICS | STATUS_ROTATE_Y | STATUS_ROTATE_Z, FALSE);
        llSetStatus(STATUS_ROTATE_X, TRUE);
        gNotecard = llGetInventoryName(INVENTORY_NOTECARD, 0);
        gQueryID = llGetNotecardLine(gNotecard, gLine);
    }
 
    dataserver(key query_id, string data)
    {
        if (query_id == gQueryID)
        {
            if(data != EOF)
            {
                // Delete Comments Routine by Void Singer
                integer comment = llSubStringIndex (data, "//");
                if (~(comment = llSubStringIndex( data, "//" ))) data = llDeleteSubString( data, comment, -1);
                data = llStringTrim( data, STRING_TRIM );
                if (data)
                {
                    if(DEBUG) llOwnerSay((string) gLine + " : " + data);
                    llToUpper(data);
                    gLstData = llParseString2List(data, ["|"], []);
                    gCommand = llList2String(gLstData, 0);
                    if("W" == gCommand) waypoint();
                    else gNextLine();
                }
                else gNextLine();
            }
            else
            {
                llSetStatus(STATUS_PHYSICS | STATUS_PHANTOM, FALSE);
                llUnSit(llAvatarOnSitTarget());
                llSleep(1.0);
                llDie();
            }
        }
    }
 
    not_at_target()
    {
        float thisStep = llVecDist(llGetPos(),gMoveTo);
        llMoveToTarget(gMoveTo,thisStep/speed);
    }
    at_target( integer number, vector targetpos, vector ourpos )
    {
        llTargetRemove(targetID);
        waypoint();
    }
 
    changed(integer change)
    {
        if (change & CHANGED_REGION)
        {
            gCurrentRC  = llGetRegionCorner();
            waypoint();
        }
        else if (change & CHANGED_LINK)
        {
            if (llAvatarOnSitTarget() == NULL_KEY)
            {
                llSleep(0.5);
                llDie();
            }
        }
    }
}
//============================================================================

Sample Tour - copy and paste into a new notecard:

W|Blake Sea - Spyglass|<145,212,40.0>|<290048,269568,0>
W|Blake Sea - Spyglass|<152,110,40.0>|<290048,269568,0>
W|Blake Sea - Half Hitch|<116,152,35.0>|<290048,268800,0>
W|Blake Sea - Half Hitch|<72,122,35.0>|<290048,268800,0>
W|Barbarossa|<175,19,24.0>|<289792,268800,0>
W|Barbarossa|<175,19,21.0>|<289792,268800,0>

  • Like 1
Link to comment
Share on other sites

A quick side note along the lines of this subject.

 

I have an elevator script-set that I developed from 2008 to 2012. At one point a customer asked me to bypass the 64m limit, which I did. When dealing with horizontal movement, the method works fine (I did the same as you). When dealing with vertical movement, up works fine as well, but down does not. What I found was that when a physical object is moving down from a given height, gravity and acceleration combine to cause the physical object to free-fall, not move in a controllable manner. My customer made a space needle elevator. The way up worked fine, but the way down was a ride of death. LOL Anyone attempting to bypass the 64m limit should keep in mind, the greater the distance between current position and destination position, the faster the object moves to get there. This can be mitigated somewhat with the tau setting but not completely. Free-fall occurs when distance is so great that the object breaks free from control and just falls like a rock.

 

One other tidbit... if you are particular about the object jittering when sitting at its destination, just toggle physical off. I also like to use a jump-to range of a fraction of a meter; if the object gets within that range of the destination, it goes non-physical and llSetPos, this making for a smooth stop and eliminating jitter at the end.

Link to comment
Share on other sites

  • 7 years later...
You are about to reply to a thread that has been inactive for 254 days.

Please take a moment to consider if this thread is worth bumping.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...