Rez To Target
|
|
Tiger Crossing
The Prim Maker
Join date: 18 Aug 2003
Posts: 1,560
|
12-11-2005 20:13
Ever use llRezObject or llRezAtRoot and need the object to end up farther from the script object than those functions can handle? The usual method is to have the target object listen for a position to be shouted from the script. But I have a trick that I wanted to share (since I was asked by someone about it) that avoids the need for such chatter. You have the scripted object which will be doing the rezing and which contains the object to be rezed. * round the script object's position off to the nearest integer values (<10,10,10>  * isolate the fractional portion of the destination (<0.123, 0.456, 0.789>  * add the two together - this is the position to pass into the Rez function (<10.123...) * isolate the integer portion of the destination position (<80,72,25>  * combine the integer x, y, and z positions into a single integer (x*1000000+y*1000+z) * pass that as the parameter of the rez function (80072025) *edit* Or, as Argent mentions below, we can replace the base 10 offsets I use above (next to last step) since the integer portion of the destination can't be over 256 - the size of a sim - if you want to pass additional information for simple rotations or whatnot. I went with base 10 so the values were human-readable since I didn't need rotation. */edit* The process can be reversed to build a perfectly accurate position, sim-wide, for the rezzed object to move to in a "while ( llVecDist( llGetPos(), dest ) > 0.01 )" loop. In my case, I knew my destination was in the SW corner, so I only needed two digits per X, Y, and Z of the parameter integer. I could then put in a rotation (6 positions at 60 deg increments) and a two-digit id number. But in the general case, using the rez position's fractional components lets you pass much more info to the rezed object without resorting to chat data.
_____________________
~ Tiger Crossing ~ (Nonsanity)
|
|
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
|
12-12-2005 05:33
Cute, but you're using too many bits: if you make it x*65536 + y*256 + z you'll have room for another 8 bits of data. That gives you room for 3 bits of rotation (0-7 * 45 degrees) and 5 bits of id (0-31).
|
|
Django Yifu
Beat Island Gaffer
Join date: 7 May 2007
Posts: 189
|
10-24-2007 10:14
This a very old post but would come in handy for something I am building. Problem is I'm a bit confused as to how to return the components of the position vectors.
If you know the vectors your working with it could be worked out manually but how could you get a script to work this out for you using the scripted objects position and another arbitrary position passed to that script when it tries to rez the objects?
_____________________
Tread softly upon the Earth for you walk on my face.
|
|
Tiger Crossing
The Prim Maker
Join date: 18 Aug 2003
Posts: 1,560
|
10-24-2007 11:33
(I'm going to include code here, but I haven't scripted in SL for months so I'll probably make some stupid function name and syntax errors. I usually only keep the 3 most recently used programming languages in active memory. The rest are in archived storage somewhere. My memory leaks...)
The base scripted object (that does the rezing) knows it's own position, and presumably you know the position you want to rez an object somewhere in the same sim. So the first step is to round off the base object's position.
vector basePos = llGetPos(); basePos = < llFloor(basePos.x), llFloor(basePos.y), llFloor(basePos.z) >;
the reason for this is that we really don't care where the base object is, except that it can only rez the new object within a 20 meter radius. The target destination could be anywhere in the sim, however. So we're going to build a temporary location that's close to the base to rez to. So next, in a similar fashion, you would split the destination's position into integer and fractional parts:
vector destInt = < llFloor(targetPos.x), llFloor(targetPos.y), llFloor(targetPos.z) >; vector destFrac = targetPos - destInt;
Then you can build the actual temporary rez location vector from those:
vector rezAt = basePos + destFrac;
So you should be able to see here how we are getting the fractional portion of the final destination vector to the rezed object. It will ignore the integer portion of it's own temporary position, but keep the fractional part (which came from the target vector to begin with). The last step is to pack the integer portions of the target destination into the one integer parameter you can pass to the rezed object:
integer rezParam = (destInt.x * 65536) + (destInt.y * 256) + destInt.z;
And if you want to also pass a simple z rotation constrained to 45 degree intervals (0 to 7 range, 4 being a 128 degree rotation), as Argent suggests above, you can add that in like so:
rezParam += rot45 * 16777216;
Then you call the llRezAtRoot function giving it the rezAt vector for a position and the rezParam for the param value.
The object that rezes then needs a script that takes the onRez param and parses that back into the destination vector's integer components (and the rotation if you used that).
vector rezedPos= llGetPos(); vector rezedInt= < llFloor(rezedPos.x), llFloor(rezedPos.y), llFloor(rezedPos.z) >; vector rezedFrac = rezedPos - rezedInt;
integer targetRot = llFloor( param / 16777216 ); integer targetX = llFloor( param / 65536 ) - (targetRot * 16777216); integer targetY = llFloor( param / 256) - (targetRot * 16777216) - ( targetX * 65536); integer targetZ = param - (targetRot * 16777216) - ( targetX * 65536) - (targetY * 256);
vector finalPos = rezedFrac + < targetX, targetY, targetZ >;
float finalRot = targetRot * 45 * DEG_TO_RAD;
Then you just need to move the object to this finalPos vector location, either with a looped llSetPos until the distance between finalPos and llGetPos is less than some small limit... Or you can build a list of enough llSetPrimitiveParams position commands to get it there in one shot. And llSetRot( finalRot ) if you used that part of the code.
The movement script in the rezed object can delete itself if you know it won't be needed again.
(Again, I'm sure I made some stupid mistakes in the above code snippets due to LSL memory leakage... Mine, not SL's. I'll fix them if they are pointed out.)
Hope that helps.
_____________________
~ Tiger Crossing ~ (Nonsanity)
|
|
Tyken Hightower
Automagical
Join date: 15 Feb 2006
Posts: 472
|
10-24-2007 15:01
These will work as expected, and bits are used such that it'll be able to rez up to 1024 (and higher) meters in height for when our Havok 4 comes. Mmm. However, don't try rezzing an object outside the normal sim x / y boundaries or bad stuff will happen, unless it's changed to limit the bits during packing. The first one does the rezzing, the second goes into the rezzed object and needs the start parameter passed into it. Or you can chop them up and do whatever you want. sim_rez(string object, vector target, rotation rot) { integer packed_target = ((integer)target.x << 22) | ((integer)target.y << 13) | ((integer)target.z & 8191); vector offset = target - <  integer)target.x, (integer)target.y, (integer)target.z>; target = llGetPos(); target = <  integer)target.x + offset.x, (integer)target.y + offset.y, (integer)target.z + offset.z>; llRezAtRoot(object, target, <0.0, 0.0, 0.0>, rot, packed_target); } rez_warp(integer data) { vector target = <  data >> 22), ((data >> 13) & 511), (data & 8191)>; vector offset = llGetPos(); target = target + offset - <  integer)offset.x, (integer)offset.y, (integer)offset.z>; integer jumps = (integer)(llVecDist(llGetPos(), target) / 10.0) + 1; if (jumps > 100) jumps = 100; integer i = 1; list rules = [PRIM_POSITION, target]; while ((i = i << 1) < jumps) rules = (rules = []) + rules + rules; llSetPrimitiveParams(rules + llList2List(rules, (i - jumps) << 1, i)); }
|
|
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
|
10-24-2007 15:08
From: Tyken Hightower if (jumps > 100) jumps = 100;
Been too long since I had to do trig and I am lazy right now  but we will need to raise the max = 100 jump limit to account for a 1,024 meter ceiling.
_____________________
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
|
|
Tiger Crossing
The Prim Maker
Join date: 18 Aug 2003
Posts: 1,560
|
10-24-2007 16:07
I'm tired, but...
sqrt( 256^2 + 256^2 + 1024^2 ) = 1086.116 1086.116 / 20 = 54.306
So 55 steps should get you from anywhere to anywhere in a sim it will be possible to go via setpos.
_____________________
~ Tiger Crossing ~ (Nonsanity)
|
|
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
|
10-24-2007 16:54
heehee Well I'm lazy and your tired Just fired up acad and did it the easy way. A box 255 x 255 x 1024 gives a point to point distance of 1085.6454, so we are both in the same neighborhood BUT........ You divided by 20 instead of 10. So to get anywhere in a sim with a ceiling of 1024 would require 109 jumps.
_____________________
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
|
|
Tyken Hightower
Automagical
Join date: 15 Feb 2006
Posts: 472
|
10-24-2007 18:22
From: Jesse Barnett heehee Well I'm lazy and your tired Just fired up acad and did it the easy way. A box 255 x 255 x 1024 gives a point to point distance of 1085.6454, so we are both in the same neighborhood BUT........ You divided by 20 instead of 10. So to get anywhere in a sim with a ceiling of 1024 would require 109 jumps. This is true, but I am lazy and merely pasted the warp snippet into this without thinking about how best to use it.  It's fairly likely that you can ask it to do 109 jumps without the script exploding; all you need to do is change the limiter.
|