Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Rotation Around an Arbitrary Point.

WarKirby Magojiro
Registered User
Join date: 24 Oct 2006
Posts: 49
02-09-2007 01:42
I'm trying to make a rather complex double door, but keep it all in one linkset.

I'm trying to make the doors rotate around an invisible point which is at a defined offset from the centred root prim. I found a little bit in the Wiki about this, but when I tried the suggested method, It didn't seem to work.

I will paste what I have so far in here.

The first script it the control script which goes in the root prim. It is a perfectly centred, invisible column. exactly the same height as the door.

Making the door as 2 seperate linksets, is NOT an option. I know it would make things much simpler but I am not willing to do it unless this is completely impossible, and i'm almost certain it CAN be done this way.

I will Pay 500l for some help in this matter.
--------------------------------------------------------------------------------------------------------
vector left_offset;
vector right_offset;
integer closed=TRUE;
integer locked=FALSE;
//The closed and locked variables are not used yet. Still trying to get the basic mechanics working before I bother with that.


default
{

touch_start(integer total_number)
{
left_offset= (llGetPos() + <4, 0, 0>;);
//Calculate the first rotation point. 4m offset from the centre
right_offset= (llGetPos() - <4, 0, 0>;);
//Calculate the first rotation point. 4m offset from the centre
llMessageLinked(LINK_SET, 1, "", NULL_KEY);
//This sends out a message to other moving parts in the door, and is irrelevant to this problem. Ignore this line
llSleep (2.0);
//A short break between the two stages of opening
llMessageLinked(LINK_SET, 2, (string)left_offset, (string)right_offset);
// Sends a triggering integer to the doors, as well as the rotation points as strings

}
}

--------------------------------------------------------------------------------------------------------
This second script, goes into the left hand door. It should be simple enough to adapt it for the right hand door. The problem, is that when executed, the door rotates on the spot, not around the point I set.
--------------------------------------------------------------------------------------------------------
string rota;

default
{
link_message(integer sender_num, integer num, string str, key id)
{
rotation x_45 = llEuler2Rot( -<0, 0, 8 * DEG_TO_RAD> );
//Calculates the amount that the door should rotate
if (num == 2) //Checks if it is the correct link message
{
rotation new_rot = x_45 * llGetLocalRot();
//Calculates the new rotation to set the door to
vector currentPos = llGetPos();
//Gets the current position of the door
rota = (string)id;//This line...
vector rotPoint = (vector)rota;
//And this one. Are just typecasting the rotation point back into a vector
vector newPos = rotPoint + ((currentPos - rotPoint) * x_45);
//Calculates the new position the door should be moved to. This line appears to be the source of the problem, bnut I'm not entirely sure.
llSetPos(newPos);
// Move the door to the appopriate position
llSetLocalRot(new_rot);
//Set the door to the appropriate rotation

}
}
}
--------------------------------------------------------------------------------------------------------
WarKirby
Scott Bristol
Registered User
Join date: 20 Jan 2007
Posts: 13
02-09-2007 05:33
I had a similar problem the other day (I am new at this too). Basically the easiest solution to this is if you can use cut and similar building settings to place the real center of the prim at your rotation point (or on the rotation axis). I am not at home right now so I can't find which setting it is but if your door isn't 10x10 you can basically just cut off the part thats on the wrong side of the center and use llSetLocalRot() to set the rotation without any position corrections at all.

edit: if you don't use that method you need to use llSetPrimitiveParams() to set the rotation and position or you will get a delay between those two which looks weird. I tried that first (in e.g. OpenGL a rotation about an arbitary point is basically a sequence: move arbitary point to (local) coordinate system center, rotate, move back; that doesn't work since you can't do that in one step without delays in SL).
WarKirby Magojiro
Registered User
Join date: 24 Oct 2006
Posts: 49
02-09-2007 22:09
Thanks for trying to help, Scott. I already knew of that method, and can't use it because of the unusual shape of my door.

I found this in the Wiki which seems to indicate it's possible.
--------------------------------------------------------------------------------------------------------
When rotating a vector, the rotation must appear to the right of the vector:



vector new_vec = old_vec * x_45; // compiles
vector new_v = x_45 * old_v; // doesn't compile

Note: An object can be rotated around an arbitrary point by multiplying a vector by a rotation in the manner described above. The vector should be the difference between the object's current position and the desired "center-point" of rotation. Take the result of the multiplication and add it to the point of rotation. This vector will be the "new location" the object should be moved to.




vector currentPos = llGetPos();
vector rotPoint = llGetPos() + <1, 1, 1>; // in global coordinates
vector newPos = rotPoint + ((currentPos - rotPoint) * x_45);
llSetPos(newPos);

Bear in mind that any translation (position) operation can result in a vector that would put the object outside of the world, or require a move further than 10 meters--so plan for these possibilities.

--------------------------------------------------------------------------------------------------------

However, when i try to use this method, my door simply rotates on the spot and moves nowhere..

Help will be greatly appreciated.

WarKirby
Soen Eber
Registered User
Join date: 3 Aug 2006
Posts: 428
02-09-2007 22:58
If you can't path cut the door so it swings about on its true center, then you have to link it to a hinge prim and move that instead.

Here's some relevant code from a door script I modified. However, it only works for a single door. In the code "pivot" takes a +1 or -1 value, depending on what direction you want the door to open.

For a double door within a single linkset ... that's going to be tough, and you'll need another method for that since you'd have to explicitly set the rotation and position for each door prim using trigonometric functions, instead of piggybacking on a hinge's rotation like below.

CODE

integer open()
{
rotation rot = llGetRot();
rotation delta = llEuler2Rot(<0,0,PI/4*pivot>);
rot = delta * rot;
llSetRot(rot);
llSleep(0.25);
return TRUE;
}
integer close()
{
rotation rot = llGetRot();
rotation delta = ZERO_ROTATION;
delta = llEuler2Rot(<0,0,PI/4*pivot*-1>);
rot = delta * rot;
llSetRot(rot);
llSleep(0.25);
return FALSE;
}
Jacques Groshomme
Registered User
Join date: 16 Mar 2005
Posts: 355
02-10-2007 06:34
WarKirby, you may benefit from taking a look at this thread as well. The situation isn't exactly the same as yours, but the concept of rotating around an arbitrary point is in there.

/54/ba/162994/1.html