Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Script for rotating around a fixed end

Paladin Pinion
The other one of 10
Join date: 3 Aug 2007
Posts: 191
02-08-2009 09:38
I'm not having any luck finding an example in the forums. I need to rotate a child prim around its local y-axis at one of it's ends. Using the examples I've found here and in the wiki, I have no problem rotating along its local y axis, and maintaining its distance from the root. But these all rotate the prim around its own center, and I can't figure out how to reposition it so that the end remains in a fixed position.

This would be very similar to rotating the hand of a clock around a fixed center point, but all the clock examples I've found cheat by using a half-transparent prim which rotates around its center.

Has anyone solved this? I'm sure it must have come up before, I just can't find it.
Nexii Malthus
[Cubitar]Mothership
Join date: 24 Apr 2006
Posts: 400
02-08-2009 10:00
llSetPos( GlobalPositionOfEdge + ( OffsetToCentre * Rotation ) );
_____________________

Geometric Library, for all your 3D maths needs.
https://wiki.secondlife.com/wiki/Geometric

Creator of the Vertical Life Client
Paladin Pinion
The other one of 10
Join date: 3 Aug 2007
Posts: 191
02-08-2009 14:44
Thanks. I'm probably doing something wrong, but it isn't working. I'm not clear whether the offset should be from the prim center or the root center, but I've tried both and neither work. Here's what I have so far. To prevent chasing wild prims across the sim, I've changed the script to just report the proposed position until I get something reasonable back.

CODE

vector gPosOffset = <0.0,-0.12,0.0>; //offset from child prim center
integer gDegrees = 20; // how many DEGREES to rotate each call
vector gRotPoint;


default
{
state_entry()
{
vector gRotPoint = llGetPos() + gPosOffset;
}

touch_start(integer num) // click to rotate once
{
rotation rotAngle = llEuler2Rot(<0,gDegrees,0> * DEG_TO_RAD);
// these 2 lines rotate the prim around its center correctly:
//rotation curRot = llGetLocalRot();
//llSetLocalRot(rotAngle*curRot); // rotates around center on y axis

vector newPos = gRotPoint + (gPosOffset * rotAngle);

llOwnerSay("NewPos: " + (string)newPos);

// for now, just reporting positions to prevent prim from going offworld
}


}


This reports: newPos: <-1.86584, 0.05425, -1.05081>, which isn't a reasonable position. The prim starts out at <232.62834, 10.32491, 22.42032>. What's the error of my ways?
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
02-08-2009 15:21
I haven't had time to look at the code but am very familiar with the "chasing prims around" part. Set your prims to "temp on" and they will die after about 50 seconds or so.
_____________________
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
Ollj Oh
Registered User
Join date: 28 Aug 2007
Posts: 522
02-09-2009 06:07
sls wiki calls it offset rotation and explains it in "rotation" article
Paladin Pinion
The other one of 10
Join date: 3 Aug 2007
Posts: 191
02-09-2009 08:24
From: Ollj Oh
sls wiki calls it offset rotation and explains it in "rotation" article


Thanks. I've read and experimented with the examples there for a couple of weeks now, but both examples rotate the prim around its own center. I need to rotate the prim around a point offset from its center. I also tried every example I could find in the forums too, but I'm not able to get even the first rotation to work correctly. All I can achieve is rotation around the prim center.

Here's what I want to do in a child prim:

______________
| |
| |
| * <----------------- rotate around this point
| |
______________

I found an example here that looks like what I need but it doesn't work, it also seems to rotate around the prim center:

CODE

offsetRot(vector rotPoint, rotation rotAngle)
{
rotation new_rot = llGetRot() * rotAngle;
llSetRot(new_rot);

vector currentPos = llGetPos();
vector newPos = rotPoint + ((currentPos - rotPoint) * rotAngle);
llSetPos(newPos);
}


Paladin Pinion
The other one of 10
Join date: 3 Aug 2007
Posts: 191
02-10-2009 16:05
Sorry to beat this dead horse to a bloody pulp, but... in this line:

llSetPos( GlobalPositionOfEdge + ( OffsetToCentre * Rotation ) );

The "offsetToCentre" is what? All the examples I've seen use either a hard-coded vector or a variable, so it isn't clear. Is it:

1. Distance from root center to child center?
2. Distance from root center to desired child rotation point?
3. Distance from child center to desired child rotation point?

Maybe this is where I'm going wrong.
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
02-10-2009 16:10
Offset is the offset from the center it normally rotates around and the one you want it to rotate around.
_____________________
Argent Stonecutter - http://globalcausalityviolation.blogspot.com/

"And now I'm going to show you something really cool."

Skyhook Station - http://xrl.us/skyhook23
Coonspiracy Store - http://xrl.us/coonstore
Paladin Pinion
The other one of 10
Join date: 3 Aug 2007
Posts: 191
02-10-2009 16:20
Thanks very much. Unfortunately that's what I've been using. I had such high hopes...
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
02-10-2009 16:46
currentPos + (offset2center - offset2center * arc2travel) * currentRot = newPos

then either change rot to match
arc2travel * currentRot = newRot

or change offset to match
offset2center * arc2travel = newOffset

http://wiki.secondlife.com/wiki/Rotation#Rotating_Vectors
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
Paladin Pinion
The other one of 10
Join date: 3 Aug 2007
Posts: 191
02-10-2009 17:33
Void, yes! It works, at least on a plain default cube. I'd tried your method before but without success, but I may have been using the wrong offset measurement (I've tried so many things, it's hard to remember.) I've poured over the wiki pages, the LSL rotation entry, the forum examples, the PDF windmill file...

I need to see if I can transfer this now to the actual object. Thank you.
Paladin Pinion
The other one of 10
Join date: 3 Aug 2007
Posts: 191
02-10-2009 21:22
Sigh. Doesn't work when put into a child prim. It's the same as all the other methods; it rotates around the center. The axis appear to be reversed as well. I've tried substituting llGetLocalPos and llGetLocalRot but that's even worse, the rotation goes off into an unrelated position.

Is this impossible? To rotate a linked child? I'd really like to know why this is failing.
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
02-11-2009 01:14
You're problem probably isn't with GETTING the position and rotation, but SETTING it. llSetRot() and 'llSetPrimitiveParams([ PRIM_ROTATION, ...])' are completely broken in child prims and have been for a very, very long time without any attention from Linden Lab. See http://jira.secondlife.com/browse/SVC-93

Your solution will be to either use the horrible workaround listed in the JIRA, or use llSetLocalRot() and live with a little more script delay.
Paladin Pinion
The other one of 10
Join date: 3 Aug 2007
Posts: 191
02-11-2009 09:21
Aha. So I'm not completely bonkers. I liked this part from the bug report, from Qarl Linden:

"our transformation API is a complete mess. position is treated differently than rotation. rotation is just plain broken. rotation of attachments is broken. scale is completely ignored. and most obviously, the transformation hierarchy can only be one layer deep....it's embarassing. and it'll be a nightmare to fix."

So they know about it, but there is too much legacy material in place to fix it. At any rate, I'll give it a go using the workaround. Thanks for the heads-up, which should be in big letters somewhere obvious, like in the tooltip. That alone would shave years off newcomers' total development time.
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
02-11-2009 19:58
sorry, should've mentioned the caveat on SVC-93...
though it can be done as unlinked (depending on your design use)

if the orbiting prim itself doesn't need to rotate using the updating offset method avoids the trouble there. however there might be a small chance of incremental error in the next calculated position over time. (distance and/or position may fall out of norms). you could check for this by running a complete cycle and seeing if the end position = the start position.
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
Paladin Pinion
The other one of 10
Join date: 3 Aug 2007
Posts: 191
02-12-2009 08:05
From: Void Singer
sorry, should've mentioned the caveat on SVC-93...
though it can be done as unlinked (depending on your design use)

if the orbiting prim itself doesn't need to rotate using the updating offset method avoids the trouble there. however there might be a small chance of incremental error in the next calculated position over time. (distance and/or position may fall out of norms). you could check for this by running a complete cycle and seeing if the end position = the start position.


It's funny, I'd done so much reading trying to solve this and I'd come across your solution several times way back at the beginning. But all my tests were originally done in the child object itself and nothing worked. It wasn't until I tried your method on a single test cube that it behaved. The reason I thought it should work was because I was using llSetRot() and the references I'd seen mostly said it only affected llSetPrimitiveParams. The light went on when Hewee mentioned it, and then I read the bug report and saw it affected llSetRot too. I wish I'd just read the JIRA first.

The prim itself does need to rotate. It's the handle of a well that has to rotate around an axle at an offset position so that the handle doesn't rotate away from the axle. Fortunately this is just a learning experiment for me and I have time to tinker. I sure appreciate your help, and others here.
Bloodsong Termagant
Manic Artist
Join date: 22 Jan 2007
Posts: 615
02-12-2009 08:31
heyas paladin;

did you find my forays into rotating from an edge?
/54/70/276049/1.html

or at least look up who that was who seems to understand the quaternion offset rotational hoopla, cuz i sure dont :X



you could also consider this.... if you cut a cube until you get a right angle, you could manage to get a well handle (it sounds like one you use to roll a bucket on a rope up and down) that you can rotate from its center and it will move exactly how you want it. and use one prim instead of two. it wont look as authentic as a cylinder handle on a box that connects it to the axle, though.


you could also build the handle, the whatever connects the handle to the axle part, and the axle as one piece, with the axle as the root prim, then rotate the axle, and the rest will follow precisely. of course, you cant link this part to the rest of the well.



if you meant some other mechanism, then never mind :)
_____________________
Why Johnny Can't Rotate:
http://forums.secondlife.com/showthread.php?t=94705
Paladin Pinion
The other one of 10
Join date: 3 Aug 2007
Posts: 191
02-13-2009 10:06
Hi Bloodsong. I so wish I could do all that, but I didn't make the object myself so I can't make those changes. I do have some other things I've created that use those techniques. The well handle in this case is a sculpted cube and can't be cut. The first thing I did was ask the creator if he could change it so that at least the place where the "handle" attaches to the axle would be centered, but he didn't make the sculpt map so we're stuck.

I've used the multi-object approach in some of my own things and that works very well. It's so much easier to just rotate the root and let SL figure out the rotations. I may have to do that eventually, but the challenge was to keep it all as a single linked set if possible. I've had a busy week and haven't had time to implement the work-around yet but I hope to try it over the weekend.

Thanks for the input though, all suggestions are welcome.
Troy McLuhan
Let's make it great
Join date: 17 Jul 2005
Posts: 73
The following code works for me
06-27-2009 09:02
This code works for me:

CODE


rot_child(vector rotaxis, float angle, vector offset)
{
// rotates a child prim by an angle "angle" (in radians)
// about the axis "rotaxis" (a unit vector with coordinates given in the frame of the root prim)
// about a point offset from the center of the child prim (by a vector "offset")

rotation rot = llEuler2Rot( angle * rotaxis );
vector dPos = (offset - (offset * rot)) * llGetLocalRot();
vector newPos = llGetLocalPos() + dPos;
rotation newRot = rot * llGetLocalRot();

// Method 1 (has a 0.2 second delay between the position change and the rotation change):
// llSetPos(newPos); // sleeps the script for 0.2 seconds
// llSetLocalRot(newRot); // sleeps the script for 0.2 seconds

// Method 2:
rotation rootRot = llGetRootRotation();
rotation fudgeRot = newRot/rootRot; // Fudge rotation to correct for incorrect implementation of llSetPrimitiveParams
llSetPrimitiveParams([PRIM_POSITION,newPos,PRIM_ROTATION,fudgeRot]); // sleeps the script for 0.2 seconds
}

Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
06-27-2009 09:15
From: Paladin Pinion
The first thing I did was ask the creator if he could change it so that at least the place where the "handle" attaches to the axle would be centered, but he didn't make the sculpt map so we're stuck.
If he has a full perm sculpt map it can be downloaded and touched up in photoshop. Applying a blue multiply filter, for example, will scale it in the Z axis.
_____________________
Argent Stonecutter - http://globalcausalityviolation.blogspot.com/

"And now I'm going to show you something really cool."

Skyhook Station - http://xrl.us/skyhook23
Coonspiracy Store - http://xrl.us/coonstore
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
06-27-2009 10:14
From: Argent Stonecutter
If he has a full perm sculpt map it can be downloaded and touched up in photoshop. Applying a blue multiply filter, for example, will scale it in the Z axis.

heh looks like you got bit by a necro post... but that is a useful tip that I will be using... know anyways to convert axes?

I already know both the inside out (mirror accross the horizontal) and rotation around z (copyleft to right, crop at new position)... I'll be adding the multiply/screen(?) to my repertoire now
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
06-27-2009 10:29
From: Void Singer
heh looks like you got bit by a necro post... but that is a useful tip that I will be using... know anyways to convert axes?
You'd have to swap channels, I don't know how to do that... my copy of photoshop is too old.
_____________________
Argent Stonecutter - http://globalcausalityviolation.blogspot.com/

"And now I'm going to show you something really cool."

Skyhook Station - http://xrl.us/skyhook23
Coonspiracy Store - http://xrl.us/coonstore
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
06-27-2009 12:33
From: Argent Stonecutter
You'd have to swap channels, I don't know how to do that... my copy of photoshop is too old.

but wouldn't that mess up the values of the non-swapped channel, or at least require some flipping or rotating of one of the channels?it's an easy enough thing in PSP... just seems off for some reason...
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
06-27-2009 12:48
From: Void Singer
but wouldn't that mess up the values of the non-swapped channel, or at least require some flipping or rotating of one of the channels?it's an easy enough thing in PSP... just seems off for some reason...
If you swap R and G channels completely, not left for right, just using the R channel for G and the G channel for R, you'll swap the X and Y axes for each other without changing Z.
_____________________
Argent Stonecutter - http://globalcausalityviolation.blogspot.com/

"And now I'm going to show you something really cool."

Skyhook Station - http://xrl.us/skyhook23
Coonspiracy Store - http://xrl.us/coonstore
Rygel Ryba
Registered User
Join date: 12 Feb 2008
Posts: 254
06-27-2009 13:15
Is this a box prim? Path cut it so it's half it's size - this puts the center on an edge and you can rotate on that with no math.
1 2