Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Synchronizing movement of several large unlinkable objects

Rhombur Volos
King of Scripture & Kebab
Join date: 6 Oct 2004
Posts: 102
12-14-2004 13:57
I've recently finished the work of modelling a very large zeppelin (approximately 25x60m), and i need to find the very best method of making it move coherently.

I've familiarized myself with the usage of the llSetPos, llSetRot, and various other neccesary functions, and i already have a script that moves the thing, but it does not rotate the ship and is designed mainly to align the many pieces after rezzing or getting it from one set of coordinates to another.

My main problem is calculating the exact position of each piece relative to the center of the ship in variable states of rotation. I've recieved hints, but no matter how hard i look at the llGetLocalPos / Rot functions, i fail to see how i can use them to my advantage, since there seems to be no way of converting local coordinates to global ones..

Worst case scenario, i'll have to make a script that, based on the rotation of the commander object, calculates its own position by geometric approximation, but i fear this will be a bit inaccurate, and i was really hoping there would be an easier way.

Does anyone know how to solve this?
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
12-14-2004 15:50
The easiest way to do what you want is to align your objects to an unrotated root primitive. This way, when your script actually uses the coordinates you get from the initial alignment, it doesnt have to compensate for what the rotation of the root prim was at the time of alignment.

First, set the rotation of the primitive you will use as your "root" to <0, 0, 0> (ZERO_ROTATION). Then position the unlinked objects where you want them to be.

Record the quaternion rotation of each object in your set (from llGetRot), and the offset from the root to the object (objectPosition - rootPosition). Each object in your set is responsible for knowing its own rotation and offset, the way you do it is up to you; you can hardcode it in each object of the set or even have the root somehow distribute the info.

The set objects must know the position and rotation of the root at all times. The most reliable way of doing this, at least since last I experimented, is via listeners. When the root is moved or rotated, it should broadcast its position and rotation on a private chat channel that the set objects listen to. This method has several advantages over using a sensor: it wont drop out when the root goes over a sim border, and it will only broadcast a root update when the root moves. When you use the listener method, however, you need to compensate for simulator-relative coordinate's inconsistancies.

llGetPos returns the simulator-relative position of the root. If the root only broadcasts that information, when it passes into another simulator, objects in the set that are not in the same simulator may face an ambiguity.

For example, if the root object moves from Simulator A, <256, 256, 50> into Simulator B <0, 0, 50>, and broadcasts <0, 0, 50>, set objects that are not within Simulator B will move to Simulator A's <0, 0, 50>, nearly 362 meters away, outside of chat range. To solve this problem, it is necessesary to use global coordinates. The wiki has a nice page on them, but I think its still down. Basically, the root not only has to broadcast the position it gets from llGetPos(), but it also has to broadcast what it gets from llGetRegionCorner().

In each set object, the script must recieve the three pieces of information from the root, the root's region corner, the root's position, and the root's rotation, and calculate its orientation based on that.

I posted this neat little function that will do the positioning for you in the script library a while ago:
CODE
vector getLocalVec(vector localCoords, vector regionCorner)
{
vector simOffset = regionCorner - llGetRegionCorner();
return simOffset + localCoords;
}


This will convert the root's position and region corner into a position relative to the simulator the set object is in.

As for the actual math, here's some sample code:
CODE

// This code is in each set object.

// This variable contains the hardcoded offset of this object from the root.
vector MY_OFFSET;
// This variable contains the hardcoded rotation of the object.
rotation MY_ROT;

vector getLocalVec(vector localCoords, vector regionCorner)
{
vector simOffset = regionCorner - llGetRegionCorner();
return simOffset + localCoords;
}

listen(integer channel, string name, key id, string message) {
// Do stuff to fill these variables with their info:
vector rootRegion;
vector rootPosition;
rotation rootRotation;

// The root's position local to the simulator this object is in.
vector localRootPosition = getLocalVec(rootPosition, rootRegion);

// This rotates this object's position and rotation based on the root's rotation.
vector rootRotatedOffset = MY_OFFSET * rootRotation;
rotation rootRotatedRot = MY_ROT * rootRotation;

// Now pass the values to functions that orient this object:
llSetPos(rootRotatedOffset + localRotPosition);
llSetRot(rootRotatedRot);
}


Ive left some things up to you, namely the code required to parse the info passed from the root to the set object, and the set object's hardcoded positional data.

I hope this helps!
==Chris
Rhombur Volos
King of Scripture & Kebab
Join date: 6 Oct 2004
Posts: 102
12-14-2004 16:19
Actually, i've written that part already. If i manage to grasp that post, i'll be pretty near the finish line with this project :)

But i'm not sure i understand how i should convert the root rotation into a vector...
(found it.. llRot2Axis should do that :P )

My problem was that my current movement script doesn't include rotation, it only repositions and aligns the individual pieces in relation to each other, after recieving the new center coordinates from the commander object.
Rhombur Volos
King of Scripture & Kebab
Join date: 6 Oct 2004
Posts: 102
12-14-2004 16:28
Ah well. I'll start exploring that code as soon as they release a patch that stops my SL client from crashing every few minutes. Until then, i'm on SL hiatus.
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
12-14-2004 16:58
From: Rhombur Volos
But i'm not sure i understand how i should convert the root rotation into a vector...
(found it.. llRot2Axis should do that :P )


Yikes! Mistake on my part!
The rotation passed to the set object should still be a quaternion, I mislabeled all the rotation types as vector :eek: Ill correct that right now.