Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Discusison: Smooth Rotation

Gearsawe Stonecutter
Over there
Join date: 14 Sep 2005
Posts: 614
03-15-2007 18:10
USE AT YOUR OWN DISCRETION

Multi Purpose rotation script.
With this you can have objects control objects. Works with touch, link message, or chat.
It controls the rate at which an object rotates given the time to open, close or stay open or close. Also has the ability to use sounds at startup, stopping and looping while moving. The open angle is in Degress. not limited to 180 or 360. Rotation direction is set buy a positive angle or negative angle. Can be set to Owner only, Group or anyone for the Touch and Listen. All setting are set via a note card. so no need to edit the the script itself.

It loads the setting by looking for the name of the notecard in the the objects description field. Every time you make a change to the notecard it will update its settings.

there is one little bug if you multiple doors controlling each other. Ever once and a while one will slam shut. I think it has to do with a listen and timer being triggered at the same time. It is rare but it does happen.

If you have used something like Unreal Editor you might like this script.

CODE

// Coder: Gearsawe Stonecutter
// Date: 01/13/2006
// Smooth rotation version 0.5
// This code was designed to open a door slowly and smoothly without
// a multitude of rotation updates. Most of the animation is
// client side which reduces the server updates and server lag.
// Also note it can be controlled by saying open or close on the

integer inventory_note_num;
string inventory_note_name;
integer notecard_line;
key global_id;

string rotation_axis;
integer touch_enable;
integer collide_enable;
integer listen_enable;
integer say_enable;
string say_closing_command;
string say_opening_command;
string say_closed_command;
string say_opened_command;
integer link_enable;
integer owner_touch;
integer group_touch;
integer owner_listen;
integer group_listen;
string open_command;
string close_command;
integer listen_channel;
integer say_channel;
float time_to_open;
float time_to_stay_open;
float time_to_close;
float time_to_stay_close;
float open_angle;
float volume;
string open_start_sound;
string open_loop_sound;
string open_end_sound;
string close_start_sound;
string close_loop_sound;
string close_end_sound;
integer phantom_mode;
string oscillate_start;
string oscillate_stop;
integer oscillate;
string event_command;

key detect_key;
integer handle;
rotation closed_rot;
rotation opened_rot;
float rate;
vector omega;
integer door;
float lag = 0.3;
key owner_key;
integer listen_only;
integer link_test;
integer event_test;
integer OPEN = 1;
integer CLOSE = 2;
integer OPENED = 4;
integer CLOSED = 8;
integer OPENING = 16;
integer CLOSING = 32;

OpenDoorStop()
{
llSetTimerEvent(0.0);
llStopSound();
if (open_end_sound!= "") llTriggerSound (open_end_sound, volume);
llSetLocalRot(opened_rot);
llTargetOmega(omega, 0 , 1);
if (link_test <= 1 && phantom_mode) llSetStatus (STATUS_PHANTOM, FALSE);
door = OPENED;
llSetTimerEvent(time_to_stay_open);
if ((!listen_only && say_enable) || (say_enable && listen_channel != say_channel)) llShout(say_channel, say_opened_command);
if (event_test == CLOSE)
{
CloseDoorStart();
}
if (oscillate && time_to_stay_open == 0.0)
{
CloseDoorStart();
}
}

OpenDoorStart()
{
llSetTimerEvent(0.0);
door = OPENING;
event_test = 0;
link_test = llGetLinkNumber();
closed_rot = llGetLocalRot();
if (rotation_axis == "X")
{
omega = llRot2Fwd (closed_rot);
opened_rot = llEuler2Rot(<open_angle, 0, 0> * DEG_TO_RAD) * closed_rot;
}
if (rotation_axis == "Y")
{
omega = llRot2Left (closed_rot);
opened_rot = llEuler2Rot(<0, open_angle, 0> * DEG_TO_RAD) * closed_rot;
}
if (rotation_axis == "Z")
{
omega = llRot2Up (closed_rot);
opened_rot = llEuler2Rot(<0, 0, open_angle> * DEG_TO_RAD) * closed_rot;
}
rate = ((open_angle / 180.0) * PI / (time_to_open));
if (link_test <= 1 && phantom_mode) llSetStatus (STATUS_PHANTOM, TRUE);
if ((!listen_only && say_enable) || (say_enable && listen_channel != say_channel)) llShout(say_channel, say_opening_command);
if (open_start_sound != "") llTriggerSound (open_start_sound, volume);
if (open_loop_sound != "") llLoopSound (open_loop_sound, volume);
llTargetOmega(omega, rate , 1.0);
llSetText("1",<0,0,0>,0.0);
llSetTimerEvent(time_to_open - lag);
}

CloseDoorStop()
{
llSetTimerEvent(0.0);
llStopSound();
if (close_end_sound != "") llTriggerSound (close_end_sound, volume);
llSetLocalRot(closed_rot);
llTargetOmega(omega, 0, 1);
if (link_test <= 1 && phantom_mode) llSetStatus (STATUS_PHANTOM, FALSE);
if ((!listen_only && say_enable) || (say_enable && listen_channel != say_channel)) llShout(say_channel, say_closed_command);
door = CLOSED;
if (event_test == OPEN)
{
OpenDoorStart();
}
if (event_command == open_command && oscillate)
{
llSetTimerEvent(time_to_stay_close);
if (time_to_stay_close == 0.0) OpenDoorStart();
}
}

CloseDoorStart()
{
llSetTimerEvent(0.0);
door = CLOSING;
event_test = 0;
rate = ((open_angle / 180.0) * PI / (time_to_close));
if (link_test <= 1 && phantom_mode) llSetStatus (STATUS_PHANTOM, TRUE);
if ((!listen_only && say_enable) || (say_enable && listen_channel != say_channel)) llShout(say_channel, say_closing_command);
if (close_start_sound != "") llTriggerSound (close_start_sound, volume);
if (close_loop_sound != "") llLoopSound (close_loop_sound, volume);
llTargetOmega(omega, -rate , 1.0);
llSetText("0",<0,0,0>,0.0);
llSetTimerEvent(time_to_close - lag);
}

CheckEvent()
{
if (event_command == open_command && door == CLOSED) OpenDoorStart();
else if (event_command == close_command && door == OPENED) CloseDoorStart();
else if (event_command == open_command && door == CLOSING) event_test = OPEN;
else if (event_command == close_command && door == OPENING) event_test = CLOSE;
}

CheckTouchEvent()
{
listen_only = FALSE;
if (oscillate == FALSE)
{
if (door == CLOSING) event_test = OPEN;
if (door == OPENING) event_test = CLOSE;
if (door == OPENED) CloseDoorStart();
if (door == CLOSED) OpenDoorStart();
}
if (oscillate == TRUE)
{
if (event_command == close_command && door == CLOSED) {event_command = open_command; OpenDoorStart();}
else event_command = close_command;
}
}
default
{
state_entry()
{
state SetVars;
}
}

state Running
{
state_entry()
{
door = CLOSED;
llSetTimerEvent(0.0);
if (listen_enable) llListen(listen_channel, "", NULL_KEY, "");
owner_key = llGetOwner();
event_command = close_command;
llTargetOmega(omega, 0.0 , 1.0);
}
on_rez(integer param)
{
owner_key = llGetOwner();
}
changed(integer change)
{
if (change & CHANGED_INVENTORY)
{
state SetVars;
}
}
listen(integer ch, string name, key id, string listen_command)
{
if (listen_enable)
{
detect_key = id;
event_command = listen_command;
//listen_only = FALSE;
if (!owner_listen && !group_listen) listen_only = TRUE;
else if (owner_listen && detect_key == owner_key && !group_listen) listen_only = TRUE;
else if (group_listen && llSameGroup(detect_key) && !owner_listen) listen_only = TRUE;
else if (group_listen && owner_listen && (llSameGroup(detect_key) || detect_key == owner_key)) listen_only = TRUE;
if (listen_only) CheckEvent();
}
}
touch_start(integer touch_num)
{
if (touch_enable)
{
detect_key = llDetectedKey(0);
if (owner_touch && detect_key == owner_key && !group_touch) CheckTouchEvent();
else if (group_touch && llSameGroup(detect_key) && !owner_touch) CheckTouchEvent();
else if (group_touch && owner_touch && (llSameGroup(detect_key) || detect_key == owner_key)) CheckTouchEvent();
else if (!owner_touch && !group_touch) CheckTouchEvent();
}
}
link_message(integer sneder, integer num, string link_command, key id)
{
if (link_enable)
{
listen_only = FALSE;
event_command = link_command;
CheckEvent();
}
}
collision_start(integer collision_num)
{
if (collide_enable)
{
listen_only = FALSE;
if (door == CLOSED) OpenDoorStart();
}
}
timer()
{
llSetTimerEvent(0.0);
if (door == OPENED || (door == OPENED && oscillate)) CloseDoorStart();
else if (door == CLOSED && oscillate) OpenDoorStart();
else if (door == CLOSING) CloseDoorStop();
else if (door == OPENING) OpenDoorStop();
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
state SetVarsAgain
{
state_entry()
{
if (1) state SetVars;
}
}

state SetVars
{
state_entry()
{
touch_enable = collide_enable = listen_enable = link_enable = listen_channel = phantom_mode = oscillate = group_touch = group_listen = 0;
open_command = "open";
close_command = "close";
time_to_open = time_to_close = time_to_stay_open = 3.0;
open_angle = 90.0;
volume = 0.5;
open_start_sound = open_loop_sound = open_end_sound = close_start_sound = close_loop_sound = close_end_sound = "";
inventory_note_num = llGetInventoryNumber (INVENTORY_NOTECARD);
list desc_list = llCSV2List(llGetObjectDesc());
if (inventory_note_num == 0)
{
llOwnerSay("Setup notecard not found.");
inventory_note_name = "";
}
if (inventory_note_num >= 1)
{
integer found = FALSE;
integer i;
string inventory_note_name_test;
for (i = 0; i < inventory_note_num; i++)
{
inventory_note_name_test = llGetInventoryName (INVENTORY_NOTECARD, i);
if (llListFindList(desc_list,[inventory_note_name_test]) != -1)
{
found = TRUE;
inventory_note_name = llGetInventoryName (INVENTORY_NOTECARD, i);
}
}
if (found == TRUE)
{
llOwnerSay("Setup notecard found.");
llOwnerSay("Using '" + inventory_note_name + "' to setup. Please wait...");
notecard_line = 0;
global_id = llGetNotecardLine (inventory_note_name, notecard_line);
}
else
{
llOwnerSay("no setup card found by the name(s), " + llGetObjectDesc());
}
}
}
changed(integer change)
{
if (change & CHANGED_INVENTORY)
{
state SetVarsAgain;
}
}
dataserver(key id, string data)
{
if (global_id == id)
{
notecard_line++;
list data_list = llCSV2List (data);
string varible = llList2String (data_list, 0);
varible = llToUpper(varible);
if (data != EOF)
{
integer check = FALSE;
if (varible == "//") {check = TRUE;}
if (varible == "TOUCHENABLE") {touch_enable = llList2Integer(data_list, 1); check = TRUE;}
if (varible == "COLLIDEENABLE") {collide_enable = llList2Integer(data_list, 1); check = TRUE;}
if (varible == "LISTENENABLE") {listen_enable = llList2Integer(data_list, 1); check = TRUE;}
if (varible == "SAYENABLE") {say_enable = llList2Integer(data_list, 1); check = TRUE;}
if (varible == "LINKMESSAGEENABLE") {link_enable = llList2Integer(data_list, 1); check = TRUE;}
if (varible == "OPENCOMMAND") {open_command = llList2String(data_list, 1); check = TRUE;}
if (varible == "CLOSECOMMAND") {close_command = llList2String(data_list, 1); check = TRUE;}
if (varible == "TOUCHOWNERONLY") {owner_touch = llList2Integer(data_list, 1); check = TRUE;}
if (varible == "TOUCHGROUPONLY") {group_touch = llList2Integer(data_list, 1); check = TRUE;}
if (varible == "LISTENOWNERONLY") {owner_listen = llList2Integer(data_list, 1); check = TRUE;}
if (varible == "LISTENGROUPONLY") {group_listen = llList2Integer(data_list, 1); check = TRUE;}
if (varible == "LISTENCHANNEL") {listen_channel = llList2Integer(data_list, 1); check = TRUE;}
if (varible == "SAYCHANNEL") {say_channel = llList2Integer(data_list, 1); check = TRUE;}
if (varible == "SAYCLOSINGCOMMAND") {say_closing_command = llList2String(data_list, 1); check = TRUE;}
if (varible == "SAYOPENINGCOMMAND") {say_opening_command = llList2String(data_list, 1); check = TRUE;}
if (varible == "SAYCLOSEDCOMMAND") {say_closed_command = llList2String(data_list, 1); check = TRUE;}
if (varible == "SAYOPENEDCOMMAND") {say_opened_command = llList2String(data_list, 1); check = TRUE;}
if (varible == "TIMETOOPEN") {time_to_open = llList2Float(data_list, 1); check = TRUE;}
if (varible == "TIMETOCLOSE") {time_to_close = llList2Float(data_list, 1); check = TRUE;}
if (varible == "TIMETOSTAYOPEN") {time_to_stay_open = llList2Float(data_list, 1); check = TRUE;}
if (varible == "TIMETOSTAYCLOSE") {time_to_stay_close = llList2Float(data_list, 1); check = TRUE;}
if (varible == "OPENANGLE") {open_angle = llList2Float(data_list, 1); check = TRUE;}
if (varible == "SOUNDVOLUME") {volume = llList2Float(data_list, 1); check = TRUE;}
if (varible == "OPENSTARTSOUND") {open_start_sound = llList2String(data_list, 1); check = TRUE;}
if (varible == "OPENLOOPSOUND") {open_loop_sound = llList2String(data_list, 1); check = TRUE;}
if (varible == "OPENENDSOUND") {open_end_sound = llList2String(data_list, 1); check = TRUE;}
if (varible == "CLOSESTARTSOUND") {close_start_sound = llList2String(data_list, 1); check = TRUE;}
if (varible == "CLOSELOOPSOUND") {close_loop_sound = llList2String(data_list, 1); check = TRUE;}
if (varible == "CLOSEENDSOUND") {close_end_sound = llList2String(data_list, 1); check = TRUE;}
if (varible == "ROTATIONAXIS") {rotation_axis = llToUpper(llList2String(data_list, 1)); check = TRUE;}
if (varible == "PHANTOMMODE") {phantom_mode = llList2Integer(data_list, 1); check = TRUE;}
if (varible == "OSCILLATE") {oscillate = llList2Integer(data_list, 1); check = TRUE;}
if (check == FALSE)
{
llOwnerSay("Unkownen varilbe name.(" + varible + ")");
}
global_id = llGetNotecardLine (inventory_note_name, notecard_line);
}
if (data == EOF)
{
if (say_enable != 0 && say_enable != 1)
{
llSay(DEBUG_CHANNEL, "'SayEnable' does not have a valid setting of 0 or 1. Defaulting to 0");
say_enable = 0;
}
if (oscillate != 0 && oscillate != 1)
{
llSay(DEBUG_CHANNEL, "'Oscillate' does not have a valid setting of 0 or 1. Defaulting to 0");
oscillate = 0;
}
if (touch_enable != 0 && touch_enable != 1)
{
llSay(DEBUG_CHANNEL, "'TouchEnable' does not have a valid setting of 0 or 1. Defaulting to 0");
touch_enable = 0;
}
if (collide_enable != 0 && collide_enable != 1)
{
llSay(DEBUG_CHANNEL, "'CollideEnable' does not have a valid setting of 0 or 1. Defaulting to 0");
collide_enable = 0;
}
if (listen_enable != 0 && listen_enable != 1)
{
llSay(DEBUG_CHANNEL, "'ListenEnable' does not have a valid setting of 0 or 1. Defaulting to 0");
listen_enable = 0;
}
if (link_enable != 0 && link_enable != 1)
{
llSay(DEBUG_CHANNEL, "'LinkMessageEnable' does not have a valid setting of 0 or 1. Defaulting to 0");
link_enable = 0;
}
if (time_to_open < 0.5 || time_to_open > 3600.0)
{
llSay(DEBUG_CHANNEL, "'TimeToOpen' must be between of 0.5 and 3600.0. Defaulting of 3.0.");
time_to_open = 3.0;
}
if (time_to_close < 0.5 || time_to_close > 3600.0)
{
llSay(DEBUG_CHANNEL, "'TimeToClose' must be between of 0.5 and 3600.0. Defaulting of 3.0.");
time_to_close = 3.0;
}
if (time_to_stay_open < 0.0 || time_to_stay_open > 86400.0)
{
llSay(DEBUG_CHANNEL, "'TimeToStayOpen' must be in the range of 0.0 - 86400.0 . Defaulting to 3.0");
time_to_stay_open = 3.0;
}
if (listen_channel < 0 || listen_channel > 2147483647)
{
llSay(DEBUG_CHANNEL, "'ListenChannel' must be in the range of 1 - 2147483647. Default to 1");
listen_channel = 1;
}
if (volume < 0.0 || volume > 1.0)
{
llSay(DEBUG_CHANNEL, "'SoundVolume' must be in the range of 0.0 - 1.0 . Defaulting to 0.0");
volume = 0.0;
}
if (phantom_mode != 0 && phantom_mode != 1)
{
llSay(DEBUG_CHANNEL, "'PhantomMode' does not have a valid setting of 0 or 1. Defaulting to 0");
phantom_mode = 0;
}
llOwnerSay("complete");
state Running;
}
}
}
}


Example Setup NoteCard
CODE

OpenCommand, open
CloseCommand, close
TouchEnable, 0
TouchOwnerOnly, 0
TouchGroupOnly, 0
ListenEnable, 1
ListenChannel, 1234567
ListenOwnerOnly, 0
ListenGroupOnly, 0
SayEnable, 0
SayChannel, 123456
SayOpenedCommand,
SayOpeningCommand,
SayClosedCommand,
SayClosingCommand,
CollideEnable, 0
LinkMessageEnable, 0
TimeToOpen, 1.5
TimeToStayOpen, 0
TimeToClose, 2.0
TimeToStayClose, 0
OpenAngle, -90
SoundVolume, 0.5
OpenStartSound,b7b13576-3e0b-dcff-b05b-d0f0d83e2e1c
OpenLoopSound,54bcf155-5e80-2700-2fde-117cc96fff23
OpenEndSound,b7b13576-3e0b-dcff-b05b-d0f0d83e2e1c
CloseStartSound,b7b13576-3e0b-dcff-b05b-d0f0d83e2e1c
CloseLoopSound,54bcf155-5e80-2700-2fde-117cc96fff23
CloseEndSound,b7b13576-3e0b-dcff-b05b-d0f0d83e2e1c
RotationAxis, Z
PhantomMode, 0
Oscillate, 0
Nada Epoch
The Librarian
Join date: 4 Nov 2002
Posts: 1,423
Original Thread
03-16-2007 04:52
/15/ac/171669/1.html
_____________________
i've got nothing. ;)
Rocky Rutabaga
isn't wearing underwearâ„¢
Join date: 14 Apr 2006
Posts: 291
03-16-2007 06:27
I build, and have been developing a number of rotating amusement park rides. However, I am not a scripter nor pretend to understand half of what you savvy folk say.

Could you give some examples of how these key features would be used in a project? For instance: "This means one can create a turntable going clockwise on its axis and then link a smaller turntable at its outer edge which will turn counter clockwise on its axis." Don't want to waste your time with elaborate examples, but if you could offer a quick take on some practical uses for these, I and other builders might get some ideas on new items to create.

Then I could build the next slwidget, sell it and make a zillion Lindens (and give you a tidy percentage of the profits)!

From: Gearsawe Stonecutter

With this you can have objects control objects.


From: Gearsawe Stonecutter

The open angle is in Degress. not limited to 180 or 360. Rotation direction is set buy a positive angle or negative angle.


Thanks for your time!
AllieKat Stovall
Registered User
Join date: 7 Jun 2006
Posts: 1
Script sounds good....
03-16-2007 11:31
But... i cant seem to get it to find the notecard. is there a specific title to give the card?

like the one above i build things, and i am not a scripter. LOL that is actually a funky idea that i have even ventured into this place. but i did at a friends mentioning it. i have collected several scripts from here adn this partculat one, aong with some sit target finder thingy.... are the only 2 i cant seem to get working....

otherwise it looks like it will be good once i get it figured out =)

AllieKat Stovall
Gearsawe Stonecutter
Over there
Join date: 14 Sep 2005
Posts: 614
03-17-2007 17:18
From: AllieKat Stovall
But... i cant seem to get it to find the notecard. is there a specific title to give the card?...

AllieKat Stovall

put the name of the Notecard in the prims description field in which you put the script. you may have to do change to the notecard data then save to make a changed event happen
Gearsawe Stonecutter
Over there
Join date: 14 Sep 2005
Posts: 614
03-17-2007 17:28
From: Rocky Rutabaga
I build, and have been developing a number of rotating amusement park rides. However, I am not a scripter nor pretend to understand half of what you savvy folk say.

Could you give some examples of how these key features would be used in a project? For instance: "This means one can create a turntable going clockwise on its axis and then link a smaller turntable at its outer edge which will turn counter clockwise on its axis." Don't want to waste your time with elaborate examples, but if you could offer a quick take on some practical uses for these, I and other builders might get some ideas on new items to create.

Then I could build the next slwidget, sell it and make a zillion Lindens (and give you a tidy percentage of the profits)!
Thanks for your time!


Example: Lever activate a door to open. Have a lever with touch activated and listen disabled. Have the door with listen enabled and touch disabled. have the lever talk on a change and the door listen on the same channel. Have the lever SayOpenedCommand to "open" and the door OpenCommand to "open". when the lever reaches the end of its movement it should then start the door to open.

For fun put gears on the sides of the door and have it look like the gears are opening the door.
Rocky Rutabaga
isn't wearing underwearâ„¢
Join date: 14 Apr 2006
Posts: 291
cool beans
03-18-2007 06:28
Does this mean one could create a string of consecutive movements/events that are triggered from one touch/start command? Could I build a Rube Goldberg contraption or a giant recreation of the Mousetrap game?
Sterling Whitcroft
Registered User
Join date: 2 Jul 2006
Posts: 678
03-18-2007 07:43
OMG! You've created a Rocky-monster!

/me looks around for a candle burning a rope, releasing a bowling ball, rolling down a ramp, hits the mousetrap, whose bail snaps around, pulling a string which swings open a cage door, which releases yet another furrie into the SL world! :D

Rocky, you build an SL mousetrap game, and I'll play! Sounds like Loads of fun! When the trap comes down on the loser, he gets caged and shot off to location <0,0,1000> right? :D :D
Gearsawe Stonecutter
Over there
Join date: 14 Sep 2005
Posts: 614
03-18-2007 09:30
From: Rocky Rutabaga
Does this mean one could create a string of consecutive movements/events that are triggered from one touch/start command? Could I build a Rube Goldberg contraption or a giant recreation of the Mousetrap game?


why yes you could. I have set up a drawbridge defore. Boats would hit a sensor. which triggers gates to go down. Once they are down they trigger a draw bridge to go up. When the boats leave the sensing area it trigger the bridge to go down then the bridge trigger the gates to up.

It is also possible to make two prim bi-folding doors with this as well.
Gearsawe Stonecutter
Over there
Join date: 14 Sep 2005
Posts: 614
SL broke it.
03-18-2007 20:46
This script use to work great many months ago. but after all the changes done to TargetOmega it jsut does not work like it use to. So I am looking trying to fix it.
Tre Giles
Registered User
Join date: 16 Dec 2005
Posts: 294
04-09-2007 18:35
OMG! You've created a Rocky-master!

/me looks around for a candle burning a rope, releasing a bowling ball, rolling down a ramp, hits the mousetrap, whose bail snaps around, pulling a string which swings open a cage door, which releases yet another human into the SL world! :D

Rocky, you build an SL retardtrap game, and I'm sure he'll play! Sounds like Loads of fun for him! When the trap comes down on the losers, they get caged and shot off the side of the simulator? :D :D
Gearsawe Stonecutter
Over there
Join date: 14 Sep 2005
Posts: 614
04-09-2007 19:49
unfortunately like particles these days llTargetOmega from what I have seen is starting to suffer some of the same problems. Not start at all on child prims and sometimes not stop. The not working on child prims, stops working after a sever reset or have no clue. If I remember right recompiling the script seems to fix it. I have grown tied trying to keep this script working after every major update.