Hello Mr Oud!
The script that I have is for a very simple demo. You have two prims. When you change the master prim the other prim automatically readjusts itself to keep the same orientation. It uses a timer to know when to update. It does not use a sensor to minimize lag.
It does not do anything fancy in the way it moves so it is jumpy. It is just the very basic set up, and I have not tried to figure out how to deal with lag or make it move smoothly. For those kind of issues you would have to look at how they deal with those big yachts.
Here is the master script. Note there is
no security built in yet. All it does is identify itself to the slave script.
Code: Select all
integer theChannel = -38881881;
integer theControl;
vector originalPos;
rotation originalRot;
default
{
state_entry()
{
theControl = llListen(theChannel,"",NULL_KEY,"");
llSetText("Master",<1.0,1.0,1.0>,1.0);
originalPos = llGetPos();
originalRot = llGetRot();
}
listen(integer channel,string name,key id,string message) {
if(llGetOwner() != llGetOwnerKey(id)) {
return;
}
if(message == "ping") {
llShout(channel,"home");
originalPos = llGetPos();
originalRot = llGetRot();
}
else if (message == "reset") {
llSetPrimitiveParams([PRIM_POSITION,originalPos,
PRIM_ROTATION,originalRot]);
}
}
}
Here is the slave script. Once it finds the master it sets a timer and continually updates itself. Again, no security no fancy movement. Just the basics.
Code: Select all
integer theChannel = -38881881;
integer theControl;
key home;
rotation originalRot;
vector originalPos;
rotation myOriginalRot;
vector myOriginalPos;
integer follow = FALSE;
default
{
state_entry()
{
theControl = llListen(theChannel,"",NULL_KEY,"");
llSetText("Slave\nTouch me to have me readjust myself",<1.0,1.0,1.0>,1.0);
}
touch_start(integer total_number)
{
if(llGetOwner()==llDetectedKey(0)) {
follow = !follow;
if(follow) {
llShout(theChannel,"ping");
} else {
llShout(theChannel,"reset");
llSetPrimitiveParams([PRIM_POSITION,myOriginalPos,
PRIM_ROTATION,myOriginalRot]);
llSetTimerEvent(0.0);
llSay(0,"Not following anymore");
llSetText("Slave\nTouch me to have me readjust myself",<1.0,1.0,1.0>,1.0);
}
}
}
listen(integer channel,string name,key id,string message) {
list info;
if(llGetOwner() != llGetOwnerKey(id)) {
return;
}
if(message == "home") {
home = id;
llSay(0,"My home: " + llKey2Name(home));
llSetTimerEvent(1.0);
llSetText("Slave\nChange the master and I will change",<1.0,1.0,1.0>,1.0);
info = llGetObjectDetails(home,[OBJECT_POS,OBJECT_ROT]);
originalRot = llList2Rot(info,1);
originalPos = llList2Vector(info,0);
myOriginalRot = llGetRot();
myOriginalPos = llGetPos();
}
}
// offSet*originalRot=myOriginalRot;
// originalRot*newDiff=newRot;
// => offSet*newRot = (myOriginalRot/originalRot)*newRot
// => newDiff = (ZERO_ROTATION/originalRot)*newRot
timer() {
list info = llGetObjectDetails(home,[OBJECT_POS,OBJECT_ROT]);
vector newPos = llList2Vector(info,0);
rotation newRot = llList2Rot(info,1);
rotation newDiff;
newDiff = (ZERO_ROTATION/originalRot)*newRot;
llSetPrimitiveParams([PRIM_POSITION,
newPos+(myOriginalPos-originalPos)*newDiff,
PRIM_ROTATION,
(myOriginalRot/originalRot)*newRot]);
}
}
[Edit: I did the code as a quick demo. Now that I look at it, I suspect that
(myOriginalRot/originalRot)*newRot can be changed to
originalRot*newRot which would be a little more streamlined. ]
[Edit II & III : This edit has been removed. I put something in here that was incorrect.... ]