WarpPos -- llSetPos without the limits
|
Skalligrim Tripp
Registered User
Join date: 4 May 2006
Posts: 15
|
05-31-2006 11:17
Maybe one reason I think this is so brilliant is because its so similar to something I was about to begin experimentation with after the update ;^P Since you were so cool as to share all this, and are clearly someone with deep insights into how this works, I figure I should throw this out for some feedback  Basically my idea was to perform a more conventional sort of prim torture, and move one of the size parameters of a prim (the root in a linkset, say) along a given axis of motion in the desired direction (up to 10m) shortly followed by a similar process at the opposite end of the prim; the idea to make a sort of 'linear kinetic drive'. I've got good reasons to think that this will work and equally good reasons to think it wont; the thing I was chasing was to try to ease the intersim transit crash risk. Like several others, I've also got a looped llSetPos() drive in use atm that slows to a crawl (.7m/sec is pretty reliably most of the time for my comp/network combo) at the region boundaries, and can haull it through the balance of the sim, making for some pretty comfortable long distance travel speeds. I've come to believe from what I've read in this thread however, that the problem is not with the vehicle so much as it is with the av. Probably what would have happened is I would have followed in your footsteps when I discovered my idea wasnt functional or practical =) In any case, I'll say it again: Awesome Work  Cheers!
|
Keknehv Psaltery
Hacker
Join date: 11 Apr 2005
Posts: 1,185
|
05-31-2006 11:27
From: 2fast4u Nabob This is fantastic, Keknehv! I was using a long range teleporter for my condos in the sky - it was using llSetPos. I added your function and what a huge difference! The teleporter now works like a Sit style teleporter - very fast! It takes longer of my teleporter to start its funky glowing lights than it does to actually teleport someone!
I could not get the optimized function working - my av was always dropped about half-way to the the destination. Your original function works perfectly!
Thank you for sharing this! You may find the teleporter code that I wrote interesting. Set the object's description to the coordinates of the destination, and drop this script in. list rules; vector dest; vector home;
calcWarpPos( vector d ) //R&D by Keknehv Psaltery, ~05/25/2006 { if ( d.z > 768 ) //Otherwise we'll get stuck hitting the ceiling d.z = 768; //The number of jumps necessary integer s = (integer)(llVecMag(d-llGetPos())/10)+1; //Try and avoid stack/heap collisions if ( s > 100 ) s = 100; // 1km should be plenty //Solve '2^n=s' integer e = (integer)( llLog( s ) / llLog( 2 ) ); rules = [ PRIM_POSITION, d ]; //The start for the rules list integer i; for ( i = 0 ; i < e ; ++i ) //Start expanding the list rules += rules; integer r = s - (integer)llPow( 2, e ); if ( r > 0 ) //Finish it up rules += llList2List( rules, 0, r * 2 + 1 ); } doWarpPos() { llSetPrimitiveParams( rules ); }
default { state_entry() { llSitTarget(<0,0,0.01>,llGetRot()); home = llGetPos(); dest = (vector)llGetObjectDesc(); calcWarpPos( dest ); } changed( integer change ) { if ( change & CHANGED_LINK ) { if ( llAvatarOnSitTarget() != NULL_KEY ) { llSetLinkAlpha(LINK_SET,0,ALL_SIDES); doWarpPos(); llUnSit( llAvatarOnSitTarget() ); calcWarpPos(home); doWarpPos(); llSetLinkAlpha(LINK_SET,1,ALL_SIDES); calcWarpPos(dest); } } } } I'll have a look at the optimized code to try and find that bug. I didn't bother testing it 
|
Travis Lambert
White dog, red collar
Join date: 3 Jun 2004
Posts: 2,819
|
05-31-2006 13:21
From: Foolish Frost I have news for you: Crossing sim borders at ANY high rate of speed it like asking for your avi to get vaporized.
Even normal setpos movement can wreak unholy avatar damage at sim borders, or that's been my experience. This thing? It's almost a certanty. Still works wonders inside a sim though... Hehe no doubt, and "unholy avatar damage" is a good charachterization  . I've been fooling with this thing for the last couple days, trying to come up with some method of safely crossing sims. I was so fired up about making this work, I stayed up till 2am last night experimenting with a friend  You're absolutely right - because of the way this works, you *just can't* use warpPos to move an avatar across a sim boundary without some sort of risk. Multiple sim boundaries using this function alone are completely outside the realm of posibility. Here's what I've learned in my testing so far: After performing a 'jump' with warpPos, you need at least a 7-second recovery time before attempting to cross another simulator boundary with an avatar attached. Unfortunately (If I'm doing my math right) - this 7-second recovery time completely nullifies any performance gain with warpPos over the standard llSetPos() call, assuming you're using it to transport avatars across sim boundaries. Not to say warpPos isn't most awesome in its own right  Here's the code I've been testing with, with my journey starting in Isabel, and ending in Osterhout - over 2000m away: integer handle; integer sleep = 7; //Seconds to wait in between jumps. Less than 7 seconds is dangerous.
vector wingocorner = <260608.00000, 254208.00000, 300.00000>; //adding 300m to each Z so I don't end up in the ground vector isabelcorner = <260608.00000, 253952.00000, 300.00000>; vector galinascorner = <260352.00000, 254208.00000, 300.00000>; vector orientcorner = <260352.00000, 253952.00000, 300.00000>; vector Ligurian = <260864.00000, 254208.00000, 300.00000>; vector Mirtoon = <261120.00000, 254208.00000, 300.00000>; vector Tyrrhenian = <261376.00000, 254208.00000, 300.00000>; vector Lily = <261632.00000, 254208.00000, 300.00000>; vector Sutherland = <261888.00000, 254208.00000, 300.00000>; vector Osterhout = <262144.00000, 254208.00000, 0.00000>; //Final destination - no need to add to Z vector destination = <234,8,107>;
//R&D by Keknehv Psaltery, ~05/25/2006 //Optimized by Strife Onizuka & Gaius Goodlife glSetPos(vector dest) // dest must be in global coordinates { vector prev = dest; vector pos = llGetRegionCorner() + llGetPos(); // glGetPos() inlined while ( llVecDist(pos, dest) >= 0.01 && llVecDist(pos, prev) >= 0.01 ) { integer steps = (integer)llCeil(llVecDist(pos, dest) / 10.0); if ( steps > 128 ) steps = 128; list rules = [PRIM_POSITION, dest - llGetRegionCorner()]; integer len = 2; while ( len < steps ) { rules += rules; len += len; } rules += llList2List(rules, 0, steps * 2 - len - 1); llSetPrimitiveParams(rules); prev = pos; pos = llGetRegionCorner() + llGetPos(); // glGetPos() inlined } }
default { state_entry() { llSay(0, "Hello, Avatar!"); }
touch_start(integer total_number) { handle = llListen(-606,"","",""); llDialog(llDetectedKey(0),"You are about to attempt an 8-sim crossing at your own peril. Do you wish to try the journey?", ["Yes","No"],-606); } listen(integer channel, string name, key id, string message) { if (message == "Yes") { llListenRemove(handle); glSetPos(isabelcorner + <0,255,0>); llSleep(sleep); llSetPos(<0,265,300>); glSetPos(wingocorner+ <255,0,0>); llSleep(sleep); llSetPos(<265,0,300>); glSetPos(Ligurian + <255,0,0>); llSleep(sleep); llSetPos(<265,0,300>); glSetPos(Mirtoon + <255,0,0>); llSleep(sleep); llSetPos(<265,0,300>); glSetPos(Tyrrhenian + <255,0,0>); llSleep(sleep); llSetPos(<265,0,300>); glSetPos(Lily + <255,0,0>); llSleep(sleep); llSetPos(<265,0,300>); glSetPos(Sutherland + <255,0,0>); llSleep(sleep); llSetPos(<265,0,300>); glSetPos(Osterhout + destination); llOwnerSay("I think I'm in " + llGetRegionName()); } llListenRemove(handle); } }
_____________________
------------------ The ShelterThe Shelter is a non-profit recreation center for new residents, and supporters of new residents. Our goal is to provide a positive & supportive social environment for those looking for one in our overwhelming world.
|
Keknehv Psaltery
Hacker
Join date: 11 Apr 2005
Posts: 1,185
|
05-31-2006 13:45
Very interesting. It looks like we don't quite have llTeleportAgent yet.
|
Geuis Dassin
Filming Path creator
Join date: 3 May 2006
Posts: 565
|
05-31-2006 13:52
I think the root problem with teleporting agents versus prims has to do with the difference between them.
When you fly/walk from one sim to another, like on the mainland, then the client is able to make new connections and download the content of the new sim relatively easily and you don't notice any kind of "teleport". Unless I'm wrong about this, it seems that moving from one sim to another must use alot of the basic "teleport" technology that the client uses to get position and other inworld info.
When doing what we would qualify as a full teleport, meaning you click teleport on the map to go somewhere, then you are noticing a lag time while a complete set of positional information is being downloaded for the new region/sim. Unlike walking from one sim to another, there is no way to gradually update your client-state when doing a full teleport.
When a prim moves from one sim to another, its mainly server-side and any client-side information is extremely small in comparison to a full AV teleport.
It seems that using llSitPos, or WarpPos, to move an AV is causing problems because its breaking the client-server code that normally transfers the position of an AV into a new region, whether it be walking or full teleport.
It might be possible to get around this limitation if a method could be found that would force the client to update its position information between the client and server during a WarpPos.
If it was possible to get the current Home coordinates and to change them via script, a teleport system would be easy using llTeleportAgentHome.
Earlier I was using llTeleportAgentHome on a prim, using llGetKey. It only seemed to operate when I was close to 100 meters away, and then the prim disappears for a few seconds before reappearing. So far I can't really determine where its going.
|
2fast4u Nabob
SL-ice.net
Join date: 28 Dec 2005
Posts: 542
|
05-31-2006 13:56
From: Keknehv Psaltery You may find the teleporter code that I wrote interesting. Looks very cool indeed! I cannot get into SL from where I am now - I'll give this a try as soon as I can. Seems perfect for quick, one-way teleports. By the way, I modified Cubey Terra's teleporters to use warpPos...works very well. I'll try making an attachment that uses warpPos to quickly teleport within my sim...will let you know how that works out.
|
Keknehv Psaltery
Hacker
Join date: 11 Apr 2005
Posts: 1,185
|
05-31-2006 17:33
Attachments can't use llSetPos to move an avatar-- llSetPos on an attachment will just move its position relative to the av. However, it is possible to rez a teleporter and tell it the location to go.
|
2fast4u Nabob
SL-ice.net
Join date: 28 Dec 2005
Posts: 542
|
05-31-2006 21:50
From: Keknehv Psaltery Attachments can't use llSetPos to move an avatar-- Thanks....still learning..the hard way sometimes  Well my teleporters are fantastic now and this is a huge improvement over moving 10m at a time.
|
Luc Aubret
Oreo-eater
Join date: 14 Sep 2005
Posts: 86
|
06-01-2006 14:33
Bloody brill, man. Much better than the threaded setpos crap I was using (5 bloody scripts, link messages abound, i blush just thinking about how messy it was comparatively).
Strife, for some reason, I can't get your ver. to move more than 40m. No idea why; everything seems in order, but that's all it'll go.
|
Keknehv Psaltery
Hacker
Join date: 11 Apr 2005
Posts: 1,185
|
06-01-2006 16:32
Many people have observed the same thing-- I recently informed him of the problems, and he said he'd look into it.
Anyways, I'm glad it's helpful. Threaded setpos loops...?
|
Rickard Roentgen
Renaissance Punk
Join date: 4 Apr 2004
Posts: 1,869
|
06-01-2006 16:44
From: Keknehv Psaltery Many people have observed the same thing-- I recently informed him of the problems, and he said he'd look into it.
Anyways, I'm glad it's helpful. Threaded setpos loops...? ya multiple scripts using llSetPos to get around the small delay llSetPos imposes  . In my experience 4 wasn't really an improvement over 3.
|
Talarus Luan
Ancient Archaean Dragon
Join date: 18 Mar 2006
Posts: 4,831
|
06-02-2006 21:04
I couldn't get Strife's version to work, so I "fixed" it. I can't claim it is anywhere near as optimized as what he intended, but it works. warpPos( vector d ) //R&D by Keknehv Psaltery, ~05/25/2006 { //with a little pokeing by Strife, and a bit more if ( d.z > 768 ) //Otherwise we'll get stuck hitting the ceiling d.z = 768; //The number of jumps necessary integer s = ((integer)(llVecDist(d, llGetPos())/10)+1) << 1; //Try and avoid stack/heap collisions if ( s > 200 ) s = 200; // 1km should be plenty //Solve '2^n=s' integer e = (integer)( llLog( s ) / 0.69314718055994530941723212145818 ); integer i = 2; list rules = [ PRIM_POSITION, d ]; //The start for the rules list if (i <= e) do rules = (rules=[]) + rules + rules;//should tighten memory use. while (++i <= e); //Start expanding the list llSetPrimitiveParams(rules + llDeleteSubList( rules, s - (1 << e), (1 << e) - 1)); }
|
Talarus Luan
Ancient Archaean Dragon
Join date: 18 Mar 2006
Posts: 4,831
|
06-03-2006 14:37
Even better, no log functions: warpPos( vector destpos) { //R&D by Keknehv Psaltery, ~05/25/2006 //with a little pokeing by Strife, and a bit more //some tinkering by Talarus Luan as well // Keep us at ground level at the destination; assumes it is the same sim vector startpos = llGetPos(); float groundheight = llGround(destpos - startpos); if (destpos.z < groundheight) destpos.z = groundheight; // Limit to max setpos height if (destpos.z > 768) destpos.z = 768; // Compute the number of jumps necessary integer jumps = (integer)(llVecDist(destpos, startpos) / 10.0) + 1; // Try and avoid stack/heap collisions if (jumps > 100 ) jumps = 100; // 1km should be plenty integer count = 2; list rules = [ PRIM_POSITION, destpos ]; //The start for the rules list while (count < jumps) { rules = (rules=[]) + rules + rules; // Should tighten memory use. count = count << 1; } llSetPrimitiveParams(rules + llDeleteSubList( rules, 0, ((count - jumps) << 1) - 1)); }
|
Keknehv Psaltery
Hacker
Join date: 11 Apr 2005
Posts: 1,185
|
06-03-2006 19:14
Nice, although I don't think the error checking to prevent it from going into the ground is very useful. It can still run into ground during the journey and be stuck.
|
Talarus Luan
Ancient Archaean Dragon
Join date: 18 Mar 2006
Posts: 4,831
|
06-03-2006 22:20
Aye, this version was primarily used for intrasim tping. The ground check was implemented by a friend. It made more sense to be teleported the the correct X/Y location than cut short because of ground interference for that application.
It still does not address the issue of intervening terrain stopping the TP, but the best way to handle it is a 3-phase move; a vertical move at current (X,Y) coords to some arbitrary Z height (well above the tallest possible terrain), a horizontal move to the destination (X,Y) location, then a vertical move to the destination Z. Such a routine would completely eliminate the possibility of problems with intervening terrain, since terrain is nothing more than a simple heightmap, and thus cannot overlap with multiple Z crossings at the same (X,Y) coordinate.
|
Angela Salome
Registered User
Join date: 6 Oct 2005
Posts: 224
|
06-04-2006 00:05
From: Talarus Luan It still does not address the issue of intervening terrain stopping the TP, That doesn't matter. llSetPos will slither up and down over terrain and won't jam up in a hollow.
|
Angela Salome
Registered User
Join date: 6 Oct 2005
Posts: 224
|
06-04-2006 00:10
From: Rickard Roentgen ya multiple scripts using llSetPos to get around the small delay llSetPos imposes  . In my experience 4 wasn't really an improvement over 3. I found that 20 llSetPos threads approach the quickness of WarpPos. It's what I used before WarpPos for high speed movement/teleporting. I used a lower number of threads to get smooth follower motion from my sit target teleport follower.
|
Foolish Frost
Grand Technomancer
Join date: 7 Mar 2005
Posts: 1,433
|
06-04-2006 06:35
From: Travis Lambert Hehe no doubt, and "unholy avatar damage" is a good charachterization  . I've been fooling with this thing for the last couple days, trying to come up with some method of safely crossing sims. I was so fired up about making this work, I stayed up till 2am last night experimenting with a friend  You're absolutely right - because of the way this works, you *just can't* use warpPos to move an avatar across a sim boundary without some sort of risk. Multiple sim boundaries using this function alone are completely outside the realm of posibility. Here's what I've learned in my testing so far: After performing a 'jump' with warpPos, you need at least a 7-second recovery time before attempting to cross another simulator boundary with an avatar attached. Unfortunately (If I'm doing my math right) - this 7-second recovery time completely nullifies any performance gain with warpPos over the standard llSetPos() call, assuming you're using it to transport avatars across sim boundaries. Not to say warpPos isn't most awesome in its own right  Ahyup. And even then, I've watched it send me spinning off into the Void with no hope of recovery except a relog. Again, makes a wonderful intra-sim TP.
|
Aodhan McDunnough
Gearhead
Join date: 29 Mar 2006
Posts: 1,518
|
06-04-2006 07:42
Haven't tested it but it looks like good stuff. I strongly believe however that someone must have figured it out long ago but just kept quiet about it.
I routinely "teleport" stuff (with myself) hundreds of meters vertically with a single edit interface action, from that it's not a far stretch to assume someone has been doing the warppos thing for a long time now.
I'm doing mostly physics motion so don't really twiddle with setpos and setpos via setprimparameters much except for the aforementioned teleports.
When I get around to it will see if there's something that can be done about sim crossings.
|
Khalek Trescothick
Registered Idiot
Join date: 28 Dec 2005
Posts: 10
|
Excellent
06-04-2006 07:57
I have for a long time tried to find a viable transport script for my Transport Rings. Cross sims is HELL for avatars, so a decent workaround is needed. I modified mine, and was able to get cross-sim working well again. I will release the script here. Saying /92805 x,y,z*Simname will get you there. //Warp Cross-Sim Teleportation //Warp from warpPos script by Keknehv Psaltery //Full Script by Khalek Trescothick //This Script is classified as open-source //Do not remove this header vector pos; vector my_pos; vector g_target; vector save; string sim; string dest_sim; integer c = 92805; integer NeedToCrossSim = FALSE; integer near_check = FALSE; integer target = FALSE; llWarp2Pos( vector d ) { if ( d.z > 768 ) d.z = 768; integer s = (integer)(llVecMag(d-llGetPos())/10)+1; if ( s > 100 ) s = 100; integer e = (integer)( llLog( s ) / llLog( 2 ) ); list rules = [ PRIM_POSITION, d ]; integer i; for ( i = 0 ; i < e ; ++i ) rules += rules; integer r = s - (integer)llPow( 2, e ); if ( r > 0 ) rules += llList2List( rules, 0, r * 2 + 1 ); llSetPrimitiveParams( rules ); } default { on_rez(integer rez) { llResetScript(); } state_entry() { llListen(92805, "", "", ""); llSitTarget(<0,0,0>,ZERO_ROTATION); } dataserver(key TID, string data) { g_target += (vector)data; vector G2 = g_target; G2.z = 200; save = llVecNorm(G2 - llGetRegionCorner()); if(llRound(save.y*2)>0) save = <127,255,200>; else if(llRound(save.y*2)<0) save = <128,0,200>; else if(llRound(save.x*2)>0) save = <255,128,200>; else if(llRound(save.x*2)<0) save = <0,128,200>; if(llEdgeOfWorld(llGetPos(), llVecNorm(save - llGetPos()))) { save = llVecNorm(g_target - llGetRegionCorner()); if(llRound(save.x*2)>0) save = <255,128,200>; else if(llRound(save.x*2)<0) save = <0,128,200>; else if(llRound(save.y*2)>0) save = <128,255,200>; else if(llRound(save.y*2)<0) save = <128,1,200>; if(llEdgeOfWorld(llGetPos(), llVecNorm(save - llGetPos()))) { llWhisper(0,"Pinpoint Error"); llUnSit(llAvatarOnSitTarget()); llSleep(1.0); llDie(); } } NeedToCrossSim=TRUE; llWarp2Pos(save); llMessageLinked(-1,0,"done",""); } link_message(integer prim,integer chan,string m, key id) { if(m == "done") { if(NeedToCrossSim) { vector P = llGetPos(); if(P.x==0) P.x = -3; else if(P.x==255) P.x = 258; if(P.y==0) P.y = -3; else if(P.y==255) P.y = 258; llSleep(3.5);//Needed delay so you do not crash over sim borders! llSetPos(P); NeedToCrossSim = FALSE; llSleep(4); } sim = llGetRegionName(); if(sim != dest_sim) { g_target.z = 200; save = llVecNorm(g_target - llGetRegionCorner()); if(llRound(save.y*2)>0) save = <128,255,200>; else if(llRound(save.y*2)<0) save = <128,0,200>; else if(llRound(save.x*2)>0) save = <255,128,200>; else if(llRound(save.x*2)<0) save = <0,128,200>; if(llEdgeOfWorld(llGetPos(), llVecNorm(save - llGetPos()))) { save = llVecNorm(g_target - llGetRegionCorner()); if(llRound(save.x*2)>0) save = <255,128,200>; else if(llRound(save.x*2)<0) save = <0,128,200>; else if(llRound(save.y*2)>0) save = <128,255,200>; else if(llRound(save.y*2)<0) save = <128,0,200>; } NeedToCrossSim = TRUE; llWarp2Pos(save); llMessageLinked(-1,0,"done",""); } else if(sim == dest_sim) { NeedToCrossSim = FALSE; llWarp2Pos(my_pos); llSay(0,"Luccyy im hoomee"); llUnSit(llAvatarOnSitTarget()); llDie(); } } else { pos = g_target - llGetRegionCorner(); } } changed(integer change) { if(change & CHANGED_REGION) { llMessageLinked(LINK_SET, 0, "done", ""); } } listen(integer channel,string name,key id,string message) { if(message == message) { list d = llParseString2List(message,["*"],[]); list p = llCSV2List(llList2String(d,0)); float x = llList2Float(p,0); float y = llList2Float(p,1); float z = llList2Float(p,2); pos = <x,y,z>; my_pos = <x,y,z>; llMessageLinked(LINK_SET, 0, "bu", NULL_KEY); dest_sim = llList2String(d,1); if(llGetSubString(dest_sim,0,0) == " ") { dest_sim = llGetSubString(dest_sim,1,-1); } if(llGetRegionName() == dest_sim) { llWarp2Pos(my_pos); } else { llRequestSimulatorData(dest_sim, DATA_SIM_POS); } } } }
Have Fun!
|
Talarus Luan
Ancient Archaean Dragon
Join date: 18 Mar 2006
Posts: 4,831
|
06-04-2006 09:48
From: Angela Salome That doesn't matter. llSetPos will slither up and down over terrain and won't jam up in a hollow. Not according to my tests. I was attempting to go up a low grade to a plateau, and it stopped me every time, only doing one setpos no matter how many were in the array. It's like as soon as it hits terrain, it cancels the entire call. So, yes, with multiple calls, it will do one setpos at a time until you get clear of the terrain, but with nearly vertical terrain, it likely would take a LOT of calls to get over it. Thus, the safest and most guaranteed way to do ptp tps is the 3-phase way.
|
Ron Overdrive
Registered User
Join date: 10 Jul 2005
Posts: 1,002
|
06-04-2006 18:46
From: Khalek Trescothick I have for a long time tried to find a viable transport script for my Transport Rings. Cross sims is HELL for avatars, so a decent workaround is needed. I modified mine, and was able to get cross-sim working well again. I will release the script here. Saying /92805 x,y,z*Simname will get you there. //Warp Cross-Sim Teleportation //Warp from warpPos script by Keknehv Psaltery //Full Script by Khalek Trescothick //This Script is classified as open-source //Do not remove this header vector pos; vector my_pos; vector g_target; vector save; string sim; string dest_sim; integer c = 92805; integer NeedToCrossSim = FALSE; integer near_check = FALSE; integer target = FALSE; llWarp2Pos( vector d ) { if ( d.z > 768 ) d.z = 768; integer s = (integer)(llVecMag(d-llGetPos())/10)+1; if ( s > 100 ) s = 100; integer e = (integer)( llLog( s ) / llLog( 2 ) ); list rules = [ PRIM_POSITION, d ]; integer i; for ( i = 0 ; i < e ; ++i ) rules += rules; integer r = s - (integer)llPow( 2, e ); if ( r > 0 ) rules += llList2List( rules, 0, r * 2 + 1 ); llSetPrimitiveParams( rules ); } default { on_rez(integer rez) { llResetScript(); } state_entry() { llListen(92805, "", "", ""); llSitTarget(<0,0,0>,ZERO_ROTATION); } dataserver(key TID, string data) { g_target += (vector)data; vector G2 = g_target; G2.z = 200; save = llVecNorm(G2 - llGetRegionCorner()); if(llRound(save.y*2)>0) save = <127,255,200>; else if(llRound(save.y*2)<0) save = <128,0,200>; else if(llRound(save.x*2)>0) save = <255,128,200>; else if(llRound(save.x*2)<0) save = <0,128,200>; if(llEdgeOfWorld(llGetPos(), llVecNorm(save - llGetPos()))) { save = llVecNorm(g_target - llGetRegionCorner()); if(llRound(save.x*2)>0) save = <255,128,200>; else if(llRound(save.x*2)<0) save = <0,128,200>; else if(llRound(save.y*2)>0) save = <128,255,200>; else if(llRound(save.y*2)<0) save = <128,1,200>; if(llEdgeOfWorld(llGetPos(), llVecNorm(save - llGetPos()))) { llWhisper(0,"Pinpoint Error"); llUnSit(llAvatarOnSitTarget()); llSleep(1.0); llDie(); } } NeedToCrossSim=TRUE; llWarp2Pos(save); llMessageLinked(-1,0,"done",""); } link_message(integer prim,integer chan,string m, key id) { if(m == "done") { if(NeedToCrossSim) { vector P = llGetPos(); if(P.x==0) P.x = -3; else if(P.x==255) P.x = 258; if(P.y==0) P.y = -3; else if(P.y==255) P.y = 258; llSleep(3.5);//Needed delay so you do not crash over sim borders! llSetPos(P); NeedToCrossSim = FALSE; llSleep(4); } sim = llGetRegionName(); if(sim != dest_sim) { g_target.z = 200; save = llVecNorm(g_target - llGetRegionCorner()); if(llRound(save.y*2)>0) save = <128,255,200>; else if(llRound(save.y*2)<0) save = <128,0,200>; else if(llRound(save.x*2)>0) save = <255,128,200>; else if(llRound(save.x*2)<0) save = <0,128,200>; if(llEdgeOfWorld(llGetPos(), llVecNorm(save - llGetPos()))) { save = llVecNorm(g_target - llGetRegionCorner()); if(llRound(save.x*2)>0) save = <255,128,200>; else if(llRound(save.x*2)<0) save = <0,128,200>; else if(llRound(save.y*2)>0) save = <128,255,200>; else if(llRound(save.y*2)<0) save = <128,0,200>; } NeedToCrossSim = TRUE; llWarp2Pos(save); llMessageLinked(-1,0,"done",""); } else if(sim == dest_sim) { NeedToCrossSim = FALSE; llWarp2Pos(my_pos); llSay(0,"Luccyy im hoomee"); llUnSit(llAvatarOnSitTarget()); llDie(); } } else { pos = g_target - llGetRegionCorner(); } } changed(integer change) { if(change & CHANGED_REGION) { llMessageLinked(LINK_SET, 0, "done", ""); } } listen(integer channel,string name,key id,string message) { if(message == message) { list d = llParseString2List(message,["*"],[]); list p = llCSV2List(llList2String(d,0)); float x = llList2Float(p,0); float y = llList2Float(p,1); float z = llList2Float(p,2); pos = <x,y,z>; my_pos = <x,y,z>; llMessageLinked(LINK_SET, 0, "bu", NULL_KEY); dest_sim = llList2String(d,1); if(llGetSubString(dest_sim,0,0) == " ") { dest_sim = llGetSubString(dest_sim,1,-1); } if(llGetRegionName() == dest_sim) { llWarp2Pos(my_pos); } else { llRequestSimulatorData(dest_sim, DATA_SIM_POS); } } } }
Have Fun! Doesn't seem to like sims with two words in its name, then again maybe I'm doing something wrong
|
Angela Salome
Registered User
Join date: 6 Oct 2005
Posts: 224
|
06-04-2006 23:15
From: Talarus Luan So, yes, with multiple calls, it will do one setpos at a time until you get clear of the terrain, but with nearly vertical terrain, it likely would take a LOT of calls to get over it. Yes, I was using lots of calls to llSetPos, 20 or so threads all running at once.
|
Talarus Luan
Ancient Archaean Dragon
Join date: 18 Mar 2006
Posts: 4,831
|
06-05-2006 13:54
From: Angela Salome Yes, I was using lots of calls to llSetPos, 20 or so threads all running at once. I would think that fits the textbook definition of "brute force".  Wouldn't it be better to make just 3 (minimum) calls instead (up, over*, down) ? IE, fast, more efficient, less sim resources, etc?
|
Haravikk Mistral
Registered User
Join date: 8 Oct 2005
Posts: 2,482
|
06-06-2006 01:23
I'm now using this on doors to "teleport" to a skybox (so when you 'open' the door with right-click you end up in a skybox but don't really know unless you're paying close attention). Really handy, also gets around the problem of sit-target teleports being insecure (you can't leave a person where they are if they don't have permission), that and my skybox is actually 50m too high up for sit-target TP and I don't want to move it  Really awesome find! I have however found that sometimes warpPos isn't always completing, it seems that regardless of whether it is still being calculated the delay from calling it is constant, ie: warpPos(target); llDie(); Can die early if target is quite far away (in my case 300m or so), presumably the delay must be 0.2, but it may take longer to execute all the moves? It might be good to tweak the function to include an appropriate delay before returning after the llSetPrimitiveParams call, not sure what though. I also found it getting stuck sometimes, so my solution was to do: warpPos(target); integer counter = 1; while (llVecDist(llGetPos(), target) < 0.1) { // See if it's been a full second, since we aren't there yet, we may be stuck if (!((++counter) % 5)) warpPos(target); else llSleep(0.2); // Otherwise just wait a bit and check again } llUnSit(id); // Kick avatar off llDie(); // We're done Also, I couldn't get the optimised version of the warpPos function to work beyond 30m, I wasn't really in the mood to debug and didn't notice if a fix was posted? The original worked just fine though. This system works by rezzing an object with this script in it (plus some permission check using llSameGroup(id)), when the object is sat on, if the avatar has permission to move it informs the controller which rezzes a new door, and then goes invisible and moves. Quite neatly moving to the corresponding door in the skybox and flipping around before forcing the avatar off. A really nice door teleport system 
_____________________
Computer (Mac Pro): 2 x Quad Core 3.2ghz Xeon 10gb DDR2 800mhz FB-DIMMS 4 x 750gb, 32mb cache hard-drives (RAID-0/striped) NVidia GeForce 8800GT (512mb)
|