I got that to work... I created another long, thin cylinder to be the "hinge", positioned it along one edge of the half-cylinder that's the lid, and made the "hinge" the root prim so when it rotates, it swings the lid along with it. Fine and dandy.
Problem: if anyone moves the chest, the lid (and hinge) stay behind, because the main chest is one object (2 prims: hollow box main body and one that's a bottom) and the lid & hinge combo is a seperate object. And of course if I link them, then either the lid won't rotate, or the entire chest rotates (depending on which prim is the root prim).
I fooled around with all kinds of solutions... and none of them were satisfactory, mainly because they didn't work properly.
Finally I hit on the idea of having all four pieces linked into a single object... when someone opens or closes the chest (by clicking on the lid) a script in the main body of the chest breaks the links between the prims, the "hinge" script links the lid to the hinge, the hinge rotates, and then the script in the main body links the hinge & lid object back into the main body. This way, the hinge and lid are a seperate object only when opening or closing... at all other times the chest is a single linkset, so it can be grabbed and moved as a unit, with the lid open or closed.
Once again, I got this to work... but!
Before the lid starts moving (to open or close), and after it's done moving... it sort of does a little flip/twist motion. Every. Frickin'. Time. And I have NO idea why. It's driving me bonkers!
Initially I suspected that the process of breaking the links between the prims, and/or creating links, might be responsible, but I don't think so. The prim that forms the bottom (legs) of the chest also gets relinked to the main body of the chest after the links are broken, and IT doesn't do any funny flipping around.
I wish there were a way to capture this in a short animation so I could demonstrate it... it would only need to be roughly 3 seconds long... but at the moment I don't have a way to do that. So the above description will have to do.
I'll include the code of the scripts below, just in case I'm doing something wrong... but I've altered the way it does things six ways from Sunday, and STILL have the SAME [censored] flip/twist every time...!
Edit: Okay, I figured it out. Linking the hinge & lid COMBO back to the main body causes the twist/flip behavior for some reason; if I have the hinge script break the link to the lid when it's done moving, and have the main body relink to both the hinge and the lid SEPERATELY, there's no funny stuff. So now I just have to live with the built-in 1 second delay before the lid opens or closes after it's been clicked on.
So... does anyone have any idea why linking in a linkset, instead of individual prims, causes them to momentarily rotate wildly before settling down back into the position they had before being linked in?
The script in the main body of the chest:
CODE
key lidkey = "";
key hingekey = "";
key legkey = "";
integer channel = 23456;
store_keys()
{
integer i = 0;
integer num = llGetNumberOfPrims();
string name = "";
key id = "";
for(i=1; i< (num + 1); i++)
{
name = llGetLinkName(i);
id = llGetLinkKey(i);
if(name == "ChestHinge")
hingekey = id;
else if(name == "ChestLid")
lidkey = id;
else if(name == "ChestLegs")
legkey = id;
}
llMessageLinked(LINK_SET, 0, "LIDKEY", lidkey); // so the hinge can link to it
}
lid_touched()
{
if ((llGetPermissions() & PERMISSION_CHANGE_LINKS))
{
store_keys();
llBreakAllLinks(); // split it up
llCreateLink(legkey, TRUE); // put the legs back on
llSay(channel,"FLIP"); // tell the lid to open or close
}
}
get_perms()
{
if (!(llGetPermissions() & PERMISSION_CHANGE_LINKS))
{
llRequestPermissions(llGetOwner(), PERMISSION_CHANGE_LINKS);
llMessageLinked(LINK_SET, 0, "GETPERMS", ""); // tell the hinge to also get permissions
}
llListen(channel,"","","");
}
default
{
state_entry()
{
get_perms();
}
on_rez(integer num)
{
get_perms();
}
run_time_permissions(integer perm)
{
if (perm & PERMISSION_CHANGE_LINKS)
{
store_keys();
llListen(channel,"","","");
}
}
listen(integer channel, string name, key id, string message)
{
if((id == hingekey) && (message=="DONE"))
llCreateLink(hingekey, TRUE); // link hinge & lid combo back into main object
}
link_message(integer sender_num, integer num, string str, key id)
{
if(str == "START") // the lid's been touched, so start the process to open or close it
lid_touched();
}
}
The script in the hinge:
CODE
integer channel = 23456;
key lidkey = "";
integer Open = FALSE;
get_perms()
{
if (!(llGetPermissions() & PERMISSION_CHANGE_LINKS))
llRequestPermissions(llGetOwner(), PERMISSION_CHANGE_LINKS);
llListen(channel,"","","");
}
default
{
state_entry()
{
get_perms();
}
on_rez(integer num)
{
get_perms();
}
listen(integer channel, string name, key id, string message)
{
if(message == "FLIP")
{
llCreateLink(lidkey, TRUE); // link the lid to the hinge (this prim)
if(Open)
{
llSetRot((llEuler2Rot(<0,0,-PI/2>)* llGetRot() ));
Open = FALSE;
}
else
{
llSetRot((llEuler2Rot(<0,0,PI/2>)*llGetRot()));
Open = TRUE;
}
llSay(channel, "DONE");
}
if(message == "GETPERMS")
get_perms();
}
link_message(integer sender_num, integer num, string str, key id)
{
if(str == "LIDKEY") // get and store the UUID of the lid
lidkey = id;
}
}
And just for completeness' sake, the tiny little script from the lid:
CODE
integer channel = 23456;
default
{
state_entry()
{
}
touch_start(integer touched)
{
llMessageLinked(LINK_SET,0,"START","");
}
}
