This is also useful for starting with a cylinder and making a tube prim that's shaped exactly the same; just rotate 90 degrees about the Y axis. You can reorient the dimple or cut axes of a sphere, too.
CODE
// Rotate while maintaining scale
//
// This script, when dropped into a prim, will reorient its axes but try to keep its dimensions oriented the same.
// For example, this is useful if you just want to reorient the hollow on a box.
//
// To use, just drop the script into a prim, and choose which (local) axis to rotate about. When you're done,
// click "done", and the script will delete itself.
//
// Concept and implementation by Lex Neva. Free to distribute, modify, turn into a birthday cake, etc, if you
// retain this attribution.
sendDialog(key av) {
llDialog(av, "Rotate how much around which axis?",["90 about X","90 about Y","90 about Z","-90 about X","-90 about Y","-90 about Z","done"],1);
}
default
{
state_entry()
{
sendDialog(llGetOwner());
llListen(1,"","","");
}
touch_start(integer num) {
sendDialog(llDetectedKey(0));
}
listen(integer channel, string name, key id, string message) {
if (id == llGetOwner()
// uncomment the next line to allow group members to use the scripts in shared objects
// otherwise if they drop the script into a shared object they don't own, the script
// won't listen to them
|| llSameGroup(id)
) {
if (message == "done") {
llSay(0,"Rotate script deleting.");
llRemoveInventory(llGetScriptName());
} else {
list parts = llParseString2List(message, [" "],[]);
float degrees = llList2Float(parts,0);
string axisName = llList2String(parts, 2);
vector axis;
if (axisName == "X")
axis = <1,0,0>;
else if (axisName == "Y")
axis = <0,1,0>;
else if (axisName == "Z")
axis = <0,0,1>;
rotation rot = llAxisAngle2Rot(axis, degrees * DEG_TO_RAD);
llSetRot(rot * llGetRot());
// Theoretically I should rotate the scale vector by the inverse of the rotation
// I rotate the prim by... but in practice, it doesn't matter since I'm using 90
// degree rotations and turning negatives to positives.
vector newScale = llGetScale() * rot;
// Correct negative values.
newScale.x = llFabs(newScale.x);
newScale.y = llFabs(newScale.y);
newScale.z = llFabs(newScale.z);
llSetScale(newScale);
sendDialog(id);
}
}
}
}