Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

End point rotation

Magellan Egoyan
Registered User
Join date: 27 Jan 2007
Posts: 16
03-20-2007 22:18
Hello,

I've been trying to figure out how to rotate an object (e.g. a rectangular beam) by its endpoint. I understand about rotation and quaternions (roughly), but I just can't seem to get the script working right. I've been testing with a beam placed vertically on the ground and getting it to move incrementally down through a 45 degree rotation, leaving its bottom end "fixed" and the rest to move. I cribbed code from a discussion about rotating points to get the new position of the beam centre after each rotation, but then I need to set the beam's orientation, for which I use llSetRot(). After each incremental turn, I recalculate the vector that takes me from the beam's centre to the endpoint. But my object descends into the ground. Something's not tweaked correctly.

I'm sure I'll work it out on my own eventually, but in the meantime, if someone could give me a little help, it will be less frustrating!

rotation r;
vector pivot;
integer ii;
vector currentPos;
vector rotPoint;
vector newPos;
float ang;
float length = 5.0; //double
rotation rinit;

default
{
state_entry()
{
}

touch_start(integer total_number)
{
ang = 4.5;
rinit = llEuler2Rot(<0,0,0>*DEG_TO_RAD);
pivot = <0.0,0.0,-2.5>;
rotPoint = llGetPos()+pivot;
for (ii=0; ii<10;ii++) {
r = llEuler2Rot( <ang,0,0> * DEG_TO_RAD );
pivot = <0.0,0.0,-2.5>*rinit;
currentPos = llGetPos();
rotPoint = currentPos + pivot;
newPos = rotPoint + ((currentPos - rotPoint) * r);
llSetPos(newPos);
llSetRot(r);
ang = ang + 4.5;
rinit = r;
}
}
}
Ed Gobo
ed44's alt
Join date: 20 Jun 2006
Posts: 220
03-20-2007 23:27
You basically need to find the beam's endpoint by adding half the beam's length, multiplied by your own rotation, to the current position.

That becomes a constant position from which you move the beam.

You reverse the half beam vector, multiply it by the rotation you want and that is added to your constant position to make the beam's new position.

Hope that makes sense. Put some llOwnerSay statements in there to tell you what the positions/rotations are are.

eg
CODE
llOwnerSay ("main pivot at " + (string) mainPivot);
Magellan Egoyan
Registered User
Join date: 27 Jan 2007
Posts: 16
Confirms my understanding
03-22-2007 17:59
Your statement of the problem is clearer than mine, Ed, but I had understood that was what was needed. I just haven't figured out what I've done wrong in the coding :) As for readout statements, I took them out before I posted the code, as I thought it made the code harder to read. I'll know next time to leave them in ;)
Bloodsong Termagant
Manic Artist
Join date: 22 Jan 2007
Posts: 615
03-23-2007 07:16
check this out:

/54/85/170765/1.html


it still needs a bit of work. as of now, it doesn't work if the prim is a child of something. but you can see the math that is used, basically.
DrFran Babcock
Registered User
Join date: 30 Apr 2006
Posts: 69
end point rotation
03-23-2007 10:44
This means you haven't solved the flapping butterfly wing problem yet, nor have I. :-(
BamBam Sachertorte
floral engineer
Join date: 12 Jul 2005
Posts: 228
03-23-2007 13:55
If the beam is 5m or shorter then you could path cut it so that the prim center is on the X or Y face of the box prim.
Ed Gobo
ed44's alt
Join date: 20 Jun 2006
Posts: 220
03-23-2007 14:21
CODE

vector gLever;
vector gRotPoint;
float gAng = 4.5;
float gLength = 5.0; //double
rotation gRinit;
integer gBentOver = FALSE;
integer gSteps = 10;



init () {
gRinit = llGetRot (); //llEuler2Rot(<0,0,0>*DEG_TO_RAD);
gLever = <0.0,0.0, gLength / 2>;// * rinit;
gRotPoint = llGetPos() - gLever / gRinit;
}

down () {
integer ii;
init ();
for (ii = 0; ii < gSteps; ++ii) {
rotation r = llEuler2Rot( <gAng,0,0> * DEG_TO_RAD * ii) * gRinit;
vector newPos = gRotPoint + (gLever * r);
//llSetPos(newPos);
//llSetRot(r);
llSetPrimitiveParams([ PRIM_POSITION , newPos,PRIM_ROTATION , r ]);
}
gBentOver = TRUE;
llOwnerSay ("gBentOver = TRUE");
}

up () {
integer ii;
for (ii = 9; ii >= 0; --ii) {
rotation r = llEuler2Rot( <gAng,0,0> * DEG_TO_RAD * ii) * gRinit;
vector newPos = gRotPoint + (gLever * r);
//llSetPos(newPos);
//llSetRot(r);
llSetPrimitiveParams([ PRIM_POSITION , newPos,PRIM_ROTATION , r ]);
}
gBentOver = FALSE;
llOwnerSay ("gBentOver = FALSE");

}

default
{
state_entry()
{
init ();
}

touch_start(integer total_number)
{
if (gBentOver)
up ();
else
down ();
llOwnerSay ("gBentOver = " + (string) gBentOver);
}
}
Lee Ponzu
What Would Steve Do?
Join date: 28 Jun 2006
Posts: 1,770
Lovely
03-24-2007 08:23
I take it this works? Congratualtions. One question..why do you call init() in down? It looks like after it is called the first time, the values it sets should not change.

lee
ed44 Gupte
Explorer (Retired)
Join date: 7 Oct 2005
Posts: 638
03-24-2007 16:27
I develop programs in a modular way. So I did init () first to give me the rotating point (should have called that the pivot). Given the pivot and lever, then developed the down () routine and reworked that to be the up () routine.

I also took into account the original rotation so if you turn this fence post, it will bend over in the direction you turn it to (but only if you call init () before going down).

I combined the setrot and setpos to make the action smoother. Each of the set's has a .2 sec delay so it becomes quite jerky without the setprimpars line.

I extracted the main presettable variables and made them global for easy adjustment.

The init () call in the down () function I put in because I was continually recompiling the script and resetting the position of the pole. Every time you move the pole, the script forgets its parameters and the movement starts where it started before, not from the new position. That idea might be helpful to the feather case. However, they would have to rework this for linked components wrt the parent prim; they might get some ideas from the timeless door script.

If you follow the steps, it is all really quite simple. Hope it helps.
Magellan Egoyan
Registered User
Join date: 27 Jan 2007
Posts: 16
Awesome!
04-02-2007 21:09
That is awesome, Ed. Works like a charm. I'm going to spend a little bit of time unpicking the code, but it does what it's supposed to. Thanks. Sorry I took so long getting back to this thread... I've been busy with other things.

I also liked BamBam's suggestion, might still use it in something else I'm working on.
Winter Ventura
Eclectic Randomness
Join date: 18 Jul 2006
Posts: 2,579
04-02-2007 22:46
As BamBam suggested, you can always dimple or cut the beam, so that the "object center" is at one end. This of course limits you to 5m long from the axis.. but it's how most single prim doors are done. That would allow "wings" to flap too.
_____________________

● Inworld Store: http://slurl.eclectic-randomness.com
● Website: http://www.eclectic-randomness.com
● Twitter: @WinterVentura