Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Can WarpPos jump to 4096m?

Partington Gould
Registered User
Join date: 15 Sep 2005
Posts: 94
06-02-2008 20:49
Hi, I'm using a version of the 1000m Menu-driven Intra-Sim Teleporter using WarpPos.

I found and removed the 1km limit, but get stack heap collisions at heights above 2500m.

first I removed the limits at:
// Try and avoid stack/heap collisions
if (jumps > 250 )
jumps = 250; //

Then later just used 50m increments, it seems to fail at 250 (2500m).



Is there a solution for fast TP with the new build limits?

I guess sit on a prim still works :)


Thanks



Before anyone asks to post the script:

CODE

// Long distance teleport version 1.1
// ----------------------------------
// This script is based on other public domain free scripts, so I don't
// take credit for any of the work here.
// Bits and pieces combined by Lisbeth Cohen - plus added show/hide.
//
// The basics of the script is based on Till Sterling's simple teleport
// script, with cross sim transportation routine developed by
// Keknehv Psaltery, modified by Strife Onizuka, Talarus Luan and
// Keknehv Psaltery.
// The transportation functionality is based upon Nepenthes Ixchel's
// 1000m Menu-driven Intra-Sim Teleporter
//
// Thank you to authors who have given me permission to publish this script.
// A special thank you to Keknehv Psaltery for suggesting small improvements!
//
// Realeased as public domain - you are NOT allowed to sell it without the
// permissions of all the authors I've credited above (except those who
// may have left sl at the time)!
// Feel free to use it in freebies and to give it to your friends :-)
//
// Please do not take credit for the work of all those great authors
// mentioned above!
// If you edit the script, please do not change the lines above - thanks!
// ------------------------------------------------------------------------


//The target location .. change this to where you want to end up (x, y, z)
vector gTargetPos = <175, 112, 4000>;
// Text for the "pie menu"
string gSitText="Teleport";
// Define channel number to listen to user commands from
integer myChannel = 123;


// No need to edit the global variables below

// Return position for tp object - no need to edit
vector gStartPos=<0,0,0>;
// Key for avatar sitting on object, if any
key gAvatarID=NULL_KEY;
// If you don't enable this the teleport object will be left at the destination.
integer gReturnToStartPos=TRUE;


// This routine do the actual transport
warpPos( vector destpos)
{ //R&D by Keknehv Psaltery, 05/25/2006
//with a little pokeing by Strife, and a bit more
//some more munging by Talarus Luan
//Final cleanup by Keknehv Psaltery
// Compute the number of jumps necessary
integer jumps = (integer)(llVecDist(destpos, llGetPos()) / 10.0) + 1;
// Try and avoid stack/heap collisions
if (jumps > 250 )
jumps = 250; // *****These are the parameters I changed***
list rules = [ PRIM_POSITION, destpos ]; //The start for the rules list
integer count = 1;
while ( ( count = count << 1 ) < jumps)
rules = (rules=[]) + rules + rules; //should tighten memory use.
llSetPrimitiveParams( rules + llList2List( rules, (count - jumps) << 1, count) );
}

default
{
state_entry()
{
// Put the teleport text in place of the Sit in the pie menu
llSetSitText(gSitText);
// Read the objects position so it can return to it after teleporting
gStartPos = llGetPos();
// Sit the avatar on the object
llSitTarget(<0,0,1>,ZERO_ROTATION);
// Define commands to listen for
llListen(myChannel,"","","");
}

on_rez(integer startup_param)
{
llResetScript();
}

listen(integer chan, string name, key id, string cmd)
{
if (cmd == "show")
{
llSetAlpha( 1, ALL_SIDES );
}
else if (cmd == "hide")
{
llSetAlpha( 0, ALL_SIDES );
}
else if (cmd == "reset")
{
llResetScript();
}
else if (cmd == "help")
{
llSay(0, "Usage:");
llSay(0, "");
llSay(0, "show Make teleporter visible");
llSay(0, "hide Make teleporter invisible");
llSay(0, "reset Resets teleporter script");
llSay(0, "help This text");
}
}

changed(integer change){
if(change & CHANGED_LINK)
{
// Find id for avatar sitting on the object
gAvatarID = llAvatarOnSitTarget();
// If someone sits on it...
if(gAvatarID != NULL_KEY)
{
// Move avatar to destination
warpPos(gTargetPos);
// Pause for 1 second
llSleep(1);
// Unsit avatar
llUnSit(gAvatarID);
// Wait 1 second more
llSleep(1);
// If teleporter should return to original position....
if (gReturnToStartPos)
{
// ... send object to its start position
warpPos(gStartPos);
}
}
}
}

}
_____________________
PG - Permanently Confused and prone to Wandering
Viktoria Dovgal
Join date: 29 Jul 2007
Posts: 3,593
06-02-2008 21:29
One way is to wrap the whole thing into a bigger loop so you don't crash.

CODE

bigwarp(vector destpos) {
vector tempPos = llGetPos();

while (llVecDist(tempPos, destpos) > .001 ) {
//R&D by Keknehv Psaltery, 05/25/2006
//with a little pokeing by Strife, and a bit more
//some more munging by Talarus Luan
//Final cleanup by Keknehv Psaltery
//and then defaced by tori
// Compute the number of jumps necessary
integer jumps = (integer)(llVecDist(destpos, llGetPos()) / 10.0) + 1;
// Try and avoid stack/heap collisions
if (jumps > 100 )
jumps = 100; // 1km should be plenty
list rules = [ PRIM_POSITION, destpos ]; //The start for the rules list
integer count = 1;
while ( ( count = count << 1 ) < jumps)
rules = (rules=[]) + rules + rules; //should tighten memory use.
llSetPrimitiveParams( rules + llList2List( rules, (count - jumps) << 1, count) );
// just in case warpPos gets broken again
vector myPos = llGetPos();
if ((llVecDist(myPos, destpos) > .001) && (llVecDist(myPos, tempPos ) < 10.001)) {
llWhisper(0,"oops fallback at " + (string)myPos );
while ( llVecDist( llGetPos(), destpos ) > .001 )
llSetPos( destpos );
}
tempPos = llGetPos();
}
}
_____________________
Nika Talaj
now you see her ...
Join date: 2 Jan 2007
Posts: 5,449
06-02-2008 22:51
Here's Jesse's 4096 teleport script:

/54/a1/258022/1.html#post1982901
.
Partington Gould
Registered User
Join date: 15 Sep 2005
Posts: 94
06-03-2008 07:37
Thanks,

I'd looked at Jesse's on her Wiki page, but only saw:
integer jumps = (integer) (llVecDist(target, llGetPos()) / 10.0) + 1;
if (jumps > 206)
jumps = 206;

Which got me to about 2500.

I see this seems to be 2 loops as Viktoria mentioned as well.

I'll give it a shot tonight using 2-loops.

Thanks Again :)
_____________________
PG - Permanently Confused and prone to Wandering
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
06-03-2008 09:04
From: Partington Gould
Thanks,

I'd looked at Jesse's on her Wiki page, but only saw:
integer jumps = (integer) (llVecDist(target, llGetPos()) / 10.0) + 1;
if (jumps > 206)
jumps = 206;

Which got me to about 2500.

I see this seems to be 2 loops as Viktoria mentioned as well.

I'll give it a shot tonight using 2-loops.

Thanks Again :)

Look down in the changed event. The loop is called twice.
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime.
From: someone
I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
Dnali Anabuki
Still Crazy
Join date: 17 Oct 2006
Posts: 1,633
06-03-2008 13:36
Jesse, I love your 4096 script with HUD and have long appreciated your generosity on these forums.

I have a general question I would like to ask you.

I noticed with both your script and one I Frankensteined together that during a lateral TP, I occasionally stop briefly at sim coords 0,0,0 before completing my TP. Is this due to the jumps? I'm going from one side of my sim to the other.

Thanks again for your great TP script..just love it.
Boreal Latte
Registered User
Join date: 15 Nov 2007
Posts: 104
A minimal WarpPos that go as far as you want
06-03-2008 16:12
I recently had a need to get a warppos that would take me to my platform at 3000 meters, so I cleaned up (or so I think) the usual warppos function. Here we go:
CODE

warpPos( vector destpos )
{
while(llVecDist(destpos, llGetPos()) > 0.1) {
integer jumps = (integer)(llVecDist(destpos, llGetPos()) / 10.0) + 1;
if (jumps > 255 ) // use 63, 127, 255
{
jumps = 255;
}
list rules = [ PRIM_POSITION, destpos ];
while (jumps > 0)
{
rules += rules; // double the list
jumps = jumps >> 1; // An other way of "jumps = jumps / 2"
}
llSetPrimitiveParams( rules );
}
}

For those not into WarpPos it a based on a funny thing in the llSetPrimitiveParams function. Normally one cannot move an object more than 10 meters at a time. However, llSetPrimitiveParams take a list of commands so that you can move and rotate the primitive in one call. Someone found out that one could also move an object more than one time. So, if you make a list of 5 position change commands, you can move the object 50 meters.

Just how far you can move the object depends on the length of the list. And how long you can make the list depends on the amount of memory you can use, which again depends on how much other stuff your script does.
The clue of the WarpPos is an old programming trick, namely to make a really long list, you do not add elements to the list one at the time, but make the list twice as long each time around.

In the inner loop, it says "rules += rules" - this mean that the rules list is the old list + the old list. So first time we get a list of two moves, then 4 moves, 8, 16, 32,64,....
To stop we count down. Every time we double the length of the list, we half the jump counter. Then when the jump counter hits 0, the list has reached max length.
Programmers do not like to divide by 2 to half. Instead the "shift the integer right", which is a programmers guild trick to keep the uninitiated in the woods. It is slightly faster.

The outer loop just check if we are there yet, and if not, we take an other round. To get to 4000 meters should be possible in two rounds. But really, this should take you any distance - obstacles and permissions to stop underway not accounted for.

The above script is just the movement of an object. It need to be combined with some sit-here scripting as well.

The above script is a bit strange to my eyes (even thought I rewrote it). If you need to make 45 jumps, it will make a list of 64 jumps as that is the least number obtained by doubling the list, which is larger than 45. But it seems from the documentation that the llSetPrimitiveParams function always take 0.2 sec, so it really does not matter that we are doing 19 extra moves. Making the program do the exactly right number of moves takes up more memory and thus you need more rounds in the outer loop.

Sorry for rambling, but the thing that got me going was that the scripts posted above used tests for jumps > 207 or so. That makes no sense from a programming perspective as we double the length in the inner loop, and will never hit 207, but 256.

And if I have misunderstood - please correct me - I too am just learning, and there might be some peculiarity I did not get.
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
06-03-2008 17:32
From: Boreal Latte

The above script is just the movement of an object. It need to be combined with some sit-here scripting as well.

The above script is a bit strange to my eyes (even thought I rewrote it). If you need to make 45 jumps, it will make a list of 64 jumps as that is the least number obtained by doubling the list, which is larger than 45. But it seems from the documentation that the llSetPrimitiveParams function always take 0.2 sec, so it really does not matter that we are doing 19 extra moves. Making the program do the exactly right number of moves takes up more memory and thus you need more rounds in the outer loop.

Sorry for rambling, but the thing that got me going was that the scripts posted above used tests for jumps > 207 or so. That makes no sense from a programming perspective as we double the length in the inner loop, and will never hit 207, but 256.

And if I have misunderstood - please correct me - I too am just learning, and there might be some peculiarity I did not get.

Don't know about from a programming perpective, except that it works. It was based on math, the length of a line/10 from 0,0,0 to 256,256,4096 in a cube. 412 jumps in one call caused a stack-heap collision. Dividing the number by two and calling it twice worked.

Haven't noticed it being any slower then the unmodified warpPos except for a very slight hiccup during the change between calls.

You can expirement but I think you will run into the heap if you change it to 256 as Partington noted. And finally, at first I called warpPos with sets of 100 jumps but found the extra loops unnecessary. Since 256 doesn't work then you would have to go with 128 per your analysis, but then that would end up being 4 loops.

So what I posted works but I also would welcome more feedback if there is a better way. And I'll pop over to Aditi and give yours a try from 0,0,0 > 256,256,4096. Hope it works, it's a nice, neat little script snippet!
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime.
From: someone
I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
06-03-2008 17:39
From: Dnali Anabuki
Jesse, I love your 4096 script with HUD and have long appreciated your generosity on these forums.

I have a general question I would like to ask you.

I noticed with both your script and one I Frankensteined together that during a lateral TP, I occasionally stop briefly at sim coords 0,0,0 before completing my TP. Is this due to the jumps? I'm going from one side of my sim to the other.

Thanks again for your great TP script..just love it.

I've had that happen to me on more then a few occasions. and have seen it mentioned before here in the forum. I don't recall seeing an "official" explanation. My "theory" has always been that you are moving non-stop to your destination but the sim can't keep up with position updates from the client and defaults to 0,0,0 until the two are synced again. Something along the lines of when you first TP to a new region, you take off flying and then find walls and a roof rezzing around you.

Oh and HEY! TY!
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime.
From: someone
I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
Partington Gould
Registered User
Join date: 15 Sep 2005
Posts: 94
06-03-2008 20:09
still playing with this, but just an aside...

I tried the regular warpos I posted above in Mono and it seemed to jump as far as I wanted it to, it just removed the 'limit' lines.

No collisions in MONO.

I'm no scripter, but wanted to share that tidbit :)
_____________________
PG - Permanently Confused and prone to Wandering
Tyken Hightower
Automagical
Join date: 15 Feb 2006
Posts: 472
06-03-2008 20:19
There's still a limit, it's just way above 4096m when using Mono. Hooray for more memory!
_____________________
Partington Gould
Registered User
Join date: 15 Sep 2005
Posts: 94
06-03-2008 20:22
Last post from me :)

I inserted Boreal snippet into the 1000m script I posted originally and went from as near to 0,0,0 (I think it was 1,1,10) to 256,256,4096.

Mt teleport was blown offworld, but it got me there. just need to figure out the brakes now.. :rolleyes:
_____________________
PG - Permanently Confused and prone to Wandering
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
06-03-2008 20:24
From: Partington Gould
Last post from me :)

I inserted Boreal snippet into the 1000m script I posted originally and went from as near to 0,0,0 (I think it was 1,1,10) to 256,256,4096.

Mt teleport was blown offworld, but it got me there. just need to figure out the brakes now.. :rolleyes:

COOL! and the brakes are 255,255,4095
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime.
From: someone
I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
grumble Loudon
A Little bit a lion
Join date: 30 Nov 2005
Posts: 612
06-04-2008 05:29
From: Partington Gould
Last post from me :)

I inserted Boreal snippet into the 1000m script I posted originally and went from as near to 0,0,0 (I think it was 1,1,10) to 256,256,4096.

Mt teleport was blown offworld, but it got me there. just need to figure out the brakes now.. :rolleyes:


I found adding a sleep (1 sec) before unsit helps a lot.
Dnali Anabuki
Still Crazy
Join date: 17 Oct 2006
Posts: 1,633
06-04-2008 06:52
From: Jesse Barnett
I've had that happen to me on more then a few occasions. and have seen it mentioned before here in the forum. I don't recall seeing an "official" explanation. My "theory" has always been that you are moving non-stop to your destination but the sim can't keep up with position updates from the client and defaults to 0,0,0 until the two are synced again. Something along the lines of when you first TP to a new region, you take off flying and then find walls and a roof rezzing around you.

Oh and HEY! TY!



That fits perfectly. I am really enjoying learning this stuff though I never in a million years thought I would. Yay, SL...full of surprises.

Thanks again Jesse for all your great posts and also to all the other generous script forum folks...
Ollj Oh
Registered User
Join date: 28 Aug 2007
Posts: 522
06-04-2008 13:39
the warppos procedure is one pathetic piece of crap that has no excuse for existance, it is slow, inaccurate, wasting memory, and crashes due to stack heap.

It actually tries to create a list of vectors in a very slow, inefficient and inaccurate manner, and up to 100 of them, to be moved to one after another (even without checking IF it can get there), and in the end it may not even be NEAR the target even under easy conditions and it has no failsave systems for tricky conditions.

Instead of it just use a simple do(move to position and decrease counter) while(not at position &&counter>0) loop
Viktoria Dovgal
Join date: 29 Jul 2007
Posts: 3,593
06-04-2008 14:26
From: Ollj Oh
Instead of it just use a simple do(move to position and decrease counter) while(not at position &&counter>0) loop

LOL! You know that it takes a minute and a half to travel 4000m that way? :rolleyes:
_____________________
Boreal Latte
Registered User
Join date: 15 Nov 2007
Posts: 104
Pulling out the eyesore ;)
06-04-2008 14:41
I updated the warpPos I posted yesterday so it will produce the exact length list efficiently.
CODE

warpPos( vector destpos )
{
while(llVecDist(destpos, llGetPos()) > 0.1) {
integer jumps = (integer)(llVecDist(destpos, llGetPos()) / 10.0) + 1;
integer mask = 128;
if (jumps > 177 ) // This number depends on available heap
{
jumps = 177;
}
list oneMove = [ PRIM_POSITION, destpos ];
list rules = [];
while (mask > 0)
{
rules += rules; // double the list
if (jumps & mask) rules += oneMove;
mask = mask >> 1; // An other way of "mask = mask / 2"
}
llSetPrimitiveParams( rules );
}
}

Jesse is right, the available heap space is not one of the 2,4,8,16,32,.... series. Above I set the max length to 177 - it is a try and do not care value. The new thing is that it produces a list of the right length very fast. And if the distance it too long it split the distance into as few jumps as necessary.

Below I have included a full script ready to be inserted into an object. It reads the target from the description line of the object, so you need to change the script to use it. The target must be indicated in normal vector format, eg. <23,110,2598>. Enjoy or complain :D.
CODE

vector target;
vector home;

warpPos( vector destpos )
{
while(llVecDist(destpos, llGetPos()) > 0.1) {
integer jumps = (integer)(llVecDist(destpos, llGetPos()) / 10.0) + 1;
integer mask = 128;
if (jumps > 177 ) // This number depends on available heap
{
jumps = 177;
}
list oneMove = [ PRIM_POSITION, destpos ];
list rules = [];
while (mask > 0)
{
rules += rules; // double the list
if (jumps & mask) rules += oneMove;
mask = mask >> 1; // An other way of "mask = mask / 2"
}
llSetPrimitiveParams( rules );
}
}

vector getTarget()
{
vector t = (vector)llGetObjectDesc();
if (t == ZERO_VECTOR)
{
llWhisper(0,"Could not read target");
t = llGetPos();
}
return t;
}

default
{
state_entry()
{
llSitTarget(<0.0, 0.0, 0.4>, ZERO_ROTATION);
llSetSitText("Teleport");
}

changed(integer change)
{
key id = llAvatarOnSitTarget();
if( (change & CHANGED_LINK) && (id != NULL_KEY) )
{
target = getTarget();
home = llGetPos();
warpPos(target);
llUnSit(id);
llSleep(0.5);
warpPos(home);
}
}
}
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
06-04-2008 15:48
From: Ollj Oh
the warppos procedure is one pathetic piece of crap that has no excuse for existance, it is slow, inaccurate, wasting memory, and crashes due to stack heap.

It actually tries to create a list of vectors in a very slow, inefficient and inaccurate manner, and up to 100 of them, to be moved to one after another (even without checking IF it can get there), and in the end it may not even be NEAR the target even under easy conditions and it has no failsave systems for tricky conditions.

Instead of it just use a simple do(move to position and decrease counter) while(not at position &&counter>0) loop

OK I'll call this one like I see it:

BS

and this comes from a person that uses 3 different TP types in her hud; warpPos, a physics movement and movement like you described.
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime.
From: someone
I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
Viktoria Dovgal
Join date: 29 Jul 2007
Posts: 3,593
06-04-2008 16:02
The only thing that comes to mind with the "inaccurate" part is the occasional ban line splat, but that would affect plain old llSetPos too. But that one has an easy workaround, go straight up if needed, then across, then back to the z you really wanted.
_____________________
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
06-04-2008 16:28
I agree that "WarpPos" is a dirty hack. Unfortunately it is a NECESSARY dirty hack at the moment. It serves as a good indication that LL should revamp their movement/script delay system. Another good indicator is all the complex systems we implement that use multiple scripts to get around the script delay for smooth non-physical movement or instant messges, e-mail, etc. Such hacks almost certainly are more costly to the system than a less restrictive set of library functions would be.