In Search of the Perfect SwingScript
|
|
Bloodsong Termagant
Manic Artist
Join date: 22 Jan 2007
Posts: 615
|
01-22-2008 17:57
heyas; okay, ALL i want to do (yeah, i never ask much, right?) is to tell a swing script how far, how fast, and on *what root prim axis* to turn on. AND, heh, for it to work after i turn the fool object. so i started with a script that works. for the root object's z axis.... and that uses target omega calls to smooth the rotation. well, i took out the target omega, and i put in a little axis selection routine. it doesnt work. i tried setting the backrot and forerot llSetRot to llSetLocalRot, and that was an utter disaster. one last ancillary question.... i THOUGHT that an object's local axis was the root prim's local axis. NOT the center, but the direction anyway. yet, when i add a prim to a linkset and flip from world to local axis, i get weird, different axis direction pointings. what's up with that?? has sl been changing these things, or have i been deluding myself all along? i KNOW that when you rotate the root prim on its local axis (uh, with the edit palette up and down arrows, anyhow), that the whole thing rotates on the root's local axis. should i be messing with the root local rotation? i hate rotations. (dont really know how to do the php trick.)
float distance = 1.3; float time = 2.4; string axis = "Y"; //--the blinkin local axis you want to swing ON
string swingtext = "Swing"; string stoptext = "Stop";
float speed; rotation backrot; rotation forerot; rotation stoprot;
integer swinging = FALSE;
startSwing() { speed = distance/time; llSetTimerEvent(time); llSetRot(stoprot); }
swingChange() { if(speed < 0) llSetRot(backrot); else llSetRot(forerot); speed = 0 - speed; }
default { on_rez(integer sp) { llResetScript(); } state_entry() { rotation rrot = llGetRot(); vector vrot = llRot2Euler(rrot); stoprot = rrot; if(axis == "X") vrot.x += distance/2; else if (axis == "Y") vrot.y += distance/2; else vrot.z += distance/2; backrot = llEuler2Rot( vrot );
if(axis == "X") vrot.x -= distance; else if (axis == "Y") vrot.y -= distance; else vrot.z -= distance; forerot = llEuler2Rot( vrot ); swinging = FALSE; llSetTouchText(swingtext); } timer() { swingChange(); }
touch_start(integer total_number) { if(swinging) { llSetTimerEvent(0.0); llSetRot(stoprot); llSetTouchText(swingtext); } else { llSetTouchText(stoptext); startSwing(); } swinging = !swinging; } moving_end() {//--the rotation isnt moving it, i hope llSleep(2.0); llOwnerSay("stopped moving, reset"); llResetScript(); } }
_____________________
Why Johnny Can't Rotate: http://forums.secondlife.com/showthread.php?t=94705
|
|
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
|
01-23-2008 04:53
when you say swing, you mean like a playground swing that you sit on? anyways llSetLocalRot() sets the rotation of the prim it's in (acts just like llSetRot when used in the root), and depending on the math used it can be a global axis rotation, or a local axis rotation. assuming a playground swing I use a root at the top point and something like this vector gVecAngle = <0.0, 10.0, 0.0>; //-- angle and axis from center to swing limit rotation gRotAngle;
default{ state_entry(){ gRotAngle = llEuler2Rot( gVecAngle * DEG_TO_RAD ); }
touch_start( integer vNull ){ state sMoving; } }
state sMoving{ state_entry(){ llSetTimerEvent( 0.1 ); llSetRot( gRotAngle * llGetRot() ); //-- swing out to edge gRotAngle.s *= -1; //-- reverse the rotation //-- alternate single step swing, replaces previous line // gRotAngle.s *= -0.5; //-- doubles the swing angle and reverses it }
timer(){ //-- remove first llSetRot statment for alternate single step swing llSetRot( gRotAngle * llGetRot() ); //-- swing in to center llSetRot( gRotAngle * llGetRot() ); //-- swing out to other edge gRotAngle.s *= -1; //-- reverse the rotation }
touch_start( integer vNull ){ llSetTimerEvent( 0.0 ); state default; }
state_exit(){ //-- alternate extra step for single step swing // gRotAngle.s *= 2; //-- halves the swing angle llSetRot( gRotAngle * llGetRot() ); //-- swing in to center } }
_____________________
| | . "Cat-Like Typing Detected" | . This post may contain errors in logic, spelling, and | . grammar known to the SL populace to cause confusion | | - Please Use PHP tags when posting scripts/code, Thanks. | - Can't See PHP or URL Tags Correctly? Check Out This Link... | - 
|
|
Bloodsong Termagant
Manic Artist
Join date: 22 Jan 2007
Posts: 615
|
01-25-2008 04:46
thats amazing!!!
uh... what the heck is it doing???
wow, it even keeps going the right way when i turn it WHILE its moving. dang.
vector gVecAngle = <0.0, 10.0, 0.0>;
okay, so this bit here, its like the targetomega axis info, right? and the 10 means... what? ten degrees? ten centimeters...? ten steps? it aint ten rads anyway.
and just mostly... why does yours work where mine doesnt?
thanks, void.
_____________________
Why Johnny Can't Rotate: http://forums.secondlife.com/showthread.php?t=94705
|
|
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
|
01-26-2008 10:27
10 degrees same as the edit window...
if you precalculate the result of llEuler2Rot you can remove both the global vectore and the default state entry, but I usually leave it alone so that it's easier to tweak.
that's the same trick I use for doors, especially linked ones, so they don't fall appart when rotated at odd angles, good to know that it works WHILE it's being turned, I wasn't sure if turning it would corrupt it, or just make it play catch up, and never really thought to try =)
for best results allthe deafult code except the state entry should be moved to another state, so it doesn't recalculate the conversion from vector degrees to rotation, then just bounce between the new state and state sMoving
_____________________
| | . "Cat-Like Typing Detected" | . This post may contain errors in logic, spelling, and | . grammar known to the SL populace to cause confusion | | - Please Use PHP tags when posting scripts/code, Thanks. | - Can't See PHP or URL Tags Correctly? Check Out This Link... | - 
|
|
Bloodsong Termagant
Manic Artist
Join date: 22 Jan 2007
Posts: 615
|
02-27-2008 13:47
hey void... (or anybody, really)...
im trying to make a tire swing, and i kinda want it to not go on just one axis, but to have it turn randomly (or maybe sequentially, im not sure).
i know how to change the x, y, or z parts of the vector angle, but i dont know how to do that AND preserve the s of the rotation, too. at least, i think that's what i need to do?
i put this in, but it keeps going in one direction.
state sMoving { state_entry() { llSetTouchText("Stop"); llSetRot( gRotAngle * llGetRot() ); //-- swing out to edge // gRotAngle.s *= -1; //-- reverse the rotation //-- alternate single step swing, replaces previous line gRotAngle.s *= -0.5; llSetTimerEvent(cycletime); }
timer() {
llSetRot( gRotAngle * llGetRot() ); //-- swing out to other edge vector vAngle = gVecAngle; vAngle.y = llFrand(16.0)-8.0; gRotAngle = llEuler2Rot( gVecAngle * DEG_TO_RAD ); gRotAngle.s *= -1.0;
}
but i reset s when i put vAngle = to gVecAngle. :/ meh, im all confused.
|
|
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
|
02-28-2008 01:12
the way I'd go about it personally, is handle it as 3 stored rotations....
your normal swing rotation (some degrees on the x or y axis) your 'random' rotation (some degrees change on the z axis) and at rest = llGetRot before moving the swing (so you can reset it after)
at rest isn't absolutely necessary unless you want to reset the facing...
halfway through your normal swing steps apply your random element, spinning the swing to face a new direction and continuing the swing steps.
another posibility would be to apply a small z rotation to the step rotation after the initial swing out rotation (so it's no longer aimed at going through the 'at rest' position) which should cause an arc similar to transcribing a star (bouncing off the insided of a sphere) or only apply it once at the begining or end of each swing (not saving) for a straight line version. these variations require the same z change for all uses.
another method would to be to spin the tire as it swings, but not change the tire swing, by applying the z rotation after saving the swing position. this could be applied by (zChange = zChange * zChange) * (current position = step * current postion) or something similar
you could also chose more complex methods, like randomly determining an edge point in the cone (centered on the at rest position) and calculate the steps inbetween, but there'd need to be a fair amount of code to make it pretty, and would be hard to squeeze into one active script and make it look nice. I'll leave some other math whiz to figure out how to apply that (including limits on how far off the central swing line it can go).
_____________________
| | . "Cat-Like Typing Detected" | . This post may contain errors in logic, spelling, and | . grammar known to the SL populace to cause confusion | | - Please Use PHP tags when posting scripts/code, Thanks. | - Can't See PHP or URL Tags Correctly? Check Out This Link... | - 
|
|
Lysila Denja
Registered User
Join date: 14 Nov 2007
Posts: 20
|
02-28-2008 15:44
Hi, I was looking for a swing script and stumbled onto this post. When I copied this into a new script, it gives me a syntax error on the first line. This is what I put in there (as per your post): vector gVecAngle = <0.0, 10.0, 0.0>; //-- angle and axis from center to swing limit rotation gRotAngle; default{ state_entry(){ gRotAngle = llEuler2Rot( gVecAngle * DEG_TO_RAD ); } touch_start( integer vNull ){ state sMoving; } } state sMoving{ state_entry(){ llSetTimerEvent( 0.1 ); llSetRot( gRotAngle * llGetRot() ); //-- swing out to edge gRotAngle.s *= -1; //-- reverse the rotation //-- alternate single step swing, replaces previous line // gRotAngle.s *= -0.5; //-- doubles the swing angle and reverses it } timer(){ //-- remove first llSetRot statment for alternate single //step swing llSetRot( gRotAngle * llGetRot() ); //-- swing in to center llSetRot( gRotAngle * llGetRot() ); //-- swing out to other edge gRotAngle.s *= -1; //-- reverse the rotation } touch_start( integer vNull ){ llSetTimerEvent( 0.0 ); state default; } state_exit(){ //-- alternate extra step for single step swing // gRotAngle.s *= 2; //-- halves the swing angle llSetRot( gRotAngle * llGetRot() ); //-- swing in to center } }
Am I doing something wrong? It says (1,0) Error: Syntax error.
|
|
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
|
02-28-2008 17:01
From: Lysila Denja Hi, I was looking for a swing script and stumbled onto this post. When I copied this into a new script, it gives me a syntax error on the first line. ........................... Am I doing something wrong? It says (1,0) Error: Syntax error. Try it again Lysila. What you posted works fine with no compile error.
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime. From: someone I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
|
|
Lysila Denja
Registered User
Join date: 14 Nov 2007
Posts: 20
|
02-28-2008 17:42
so the script should start with ?
I dont get it. It says (0, 0) ERROR: Syntax error. :-(
|
|
Lysila Denja
Registered User
Join date: 14 Nov 2007
Posts: 20
|
02-28-2008 17:46
ok I got it, and it works. Realized I had to take the out. Now I have it on a swing (love seat type swing), and working on getting the bench attached to the frame, but want the bench to swing on its own, attached to "rope" to the frame of the love seat bench prim. Any thoughts on how to accomplish this? Thanks!
|
|
Tobias Convair
Registered User
Join date: 17 Nov 2007
Posts: 30
|
02-28-2008 19:43
I used the posted script to create a pendulum for some clocks that I am creating. The way that I got it to work is to create a root prim, a sphere in my case, and insert the script in this root prim. The swing motion created by the script rotated the root prim about it's Y axis. All I did then was to link the pendulum to the root prim with the proper relationship to its Y axis and adjusted the angle of swing to what I liked.
I would guess for a swing you could use a cylinder or elongated box shape for the root prim and attach the two ropes to the root prim. The root prim could be made invisible if you wanted to attach the swing to another separate structure. The touch start trigger still works if you touch a linked object attached to the root prim.
I hope this answers your question...
And thanks Void for your usual excellent contribution.One thing I don't understand, Void, in your posting was your comment at the end of the script regarding the alternate extra step. Could you please elaborate?
Thanks so much everyone....
|
|
Lysila Denja
Registered User
Join date: 14 Nov 2007
Posts: 20
|
02-28-2008 20:07
Thank you so much to taking the time to explain all that. It does explain a lot. I will play around with it and post back to let you all know how it goes. If it all comes together, I will be teaching the class to make the love seat swing for two at TUi.
Thanks!
|
|
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
|
02-29-2008 01:03
you can eliminate the sphere root by cutting the root prim so that it's center is at thevisible edge, I usually start with a half dimpled sphere and conver to the type I need (box for example) but it can work similarly for any cot that takes away half of the root (like .125 & .625 pathcuts for doors)
_____________________
| | . "Cat-Like Typing Detected" | . This post may contain errors in logic, spelling, and | . grammar known to the SL populace to cause confusion | | - Please Use PHP tags when posting scripts/code, Thanks. | - Can't See PHP or URL Tags Correctly? Check Out This Link... | - 
|
|
Bloodsong Termagant
Manic Artist
Join date: 22 Jan 2007
Posts: 615
|
02-29-2008 05:37
heyas;
thanks void, i got it working by adding 3.3 on the z each swing, and memorizing the 'at rest' to reset it. (which i dont think is the optimal solution, since yours never needed that before.)
BUT....
the fact is, the target omega (gawd, THAT) style swinging is much nicer for swings, because they are smoother. yours works for doors and pendulums and rocking chairs.....
anyway, this is what i have as my usual swing script. is there a way to possibly add in the target omega bits to yours, void? for smoothing? (and who the dip made target omega only work on the world axes???) i wouldnt know how to calculate the omega vector from... well, anything, really.
float distance = 1.3; float timetotake = 2.4; float speed; rotation backrot; rotation forerot; rotation stoprot;
startSwing() { vector vDir; speed = distance / timetotake; // llOwnerSay("Speed = " + (string)speed + " at start"); llSetTimerEvent(timetotake); vDir = llRot2Up(llGetRot()); llSetRot(stoprot); llTargetOmega( vDir, -distance / ( 2 * timetotake ), 1.0 ); }
swingchange() { vector vDir = llRot2Up(llGetRot()); // llOwnerSay("timer(): gain=" + (string)gain); // llTargetOmega( <0,0,0>, speed, 1.0 ); if( speed < 0 ) { llSetRot(backrot); } else { llSetRot(forerot); } llTargetOmega( vDir, speed, 1.0 ); speed = 0 - speed; }
integer swinging = 0;
default { on_rez(integer sp) { llResetScript(); } state_entry() { rotation rrot = llGetRot(); vector vrot = llRot2Euler( rrot ); stoprot = rrot; vrot.z += distance/2; backrot = llEuler2Rot( vrot ); vrot.z -= distance; forerot = llEuler2Rot( vrot );
// vector vrot = llRot2Euler( llGetRot() ); // vrot.z = (distance/2);//2 * speed; // backrot = llEuler2Rot( vrot ); // vrot.z = -(distance/2);//-2 * speed; // forerot = llEuler2Rot( vrot ); llTargetOmega(<0,0,0>, 0, 0.0); swinging = 0; // vrot.z = 0; // stoprot = llEuler2Rot( vrot ); // llSetRot( stoprot ); // llOwnerSay("Backrot: " + (string)backrot + ", forerot: " + (string)forerot); } timer() { swingchange(); }
touch_start(integer total_number) { if( swinging > 0 ) { swinging = 0; llSetTimerEvent(0.0); llTargetOmega(<0,0,0>, 0, 0.0 ); llSetRot(stoprot); llTargetOmega(<0,0,0>, 0, 0.0 ); } else { swinging = 1; startSwing(); } } moving_end() { llSleep(2.0); llResetScript(); } }
|
|
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
|
02-29-2008 13:20
the problem with target omega is that it changes per viewer (nevermind it seems borked by something LL did more times than not) so I've avoided it like the plague (read: I've no clue how to do that) I've also noticed it doesn't handle time dilation very well.
another reason I prefer, the rot style swing is becasue I can actually reduce the amount of rot as I swing upwards, effectively slowing it at the top of the swing arcs, making it more realistic. it works using the same multiplation/division of the rot.s component, I'm too tired to code the example, but I'm hoping you get the idea.
_____________________
| | . "Cat-Like Typing Detected" | . This post may contain errors in logic, spelling, and | . grammar known to the SL populace to cause confusion | | - Please Use PHP tags when posting scripts/code, Thanks. | - Can't See PHP or URL Tags Correctly? Check Out This Link... | - 
|
|
Lysila Denja
Registered User
Join date: 14 Nov 2007
Posts: 20
|
02-29-2008 17:14
Well I made a sphere and put the script there, and then the bench linked to the sphere.
2 Things: 1 I dont know how to make the sphere invisible. 2 I can't seem to figure out how to link the frame to the bench without it swinging too. I posted to my teachers group and it seems this is not possible. Is this not possible to do? Thanks!
|
|
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
|
03-01-2008 08:40
1) to make a prim invisible, use llSetAlpha( 0.0 ); or the equivalent cother commands.
2) not possible, or at the very least not useful for us in this case.
there are 3 methods available here: A) the rotation of the root prim, which will rotate the whole object and seated av(s) also. this is easy, requires little math, and a single call to do the moving. it degrades gracefully under lag (worst thing to happen is a little hang between rotation steps)
B) link everything, but only change the position/rotation of the things you want to move, including the Av(s). this method requires more math and a seperate call for each prim being moved, detection of avatars, and individual movement of them as well, with total scripts being 1+1 per prim moving+1 per av seated, just to make it work half the time. the other half of the time things won't move all at once and the effect is ruined, and the constant calls and processing take more of a hit on the sim, and increase the chance for items moving out of sequence the longer it runs.
C) there is the TargetOmega approach, that is best applied like the A to a root prim, but could be applied like B to a linked structure (with a lot more effort in scripting) but the tiniest bit of difference in the call time fore each part would not only have the swing in multiple parts swinging seperately, but guarantee they stayed that way. with an unlinked approach it's safer, but degrade disasterously. for instance the swing angle can be off for new viewers just entering range of sight, lag can ultimately have you swinging back and forth upside down over the top of the swing, and not all viewers will see the same thing at the same time.
_____________________
| | . "Cat-Like Typing Detected" | . This post may contain errors in logic, spelling, and | . grammar known to the SL populace to cause confusion | | - Please Use PHP tags when posting scripts/code, Thanks. | - Can't See PHP or URL Tags Correctly? Check Out This Link... | - 
|
|
Bloodsong Termagant
Manic Artist
Join date: 22 Jan 2007
Posts: 615
|
03-11-2008 14:24
From: Void Singer the problem with target omega is that it changes per viewer (nevermind it seems borked by something LL did more times than not) so I've avoided it like the plague (read: I've no clue how to do that) I've also noticed it doesn't handle time dilation very well.
amen to that! From: someone another reason I prefer, the rot style swing is becasue I can actually reduce the amount of rot as I swing upwards, effectively slowing it at the top of the swing arcs, making it more realistic. it works using the same multiplation/division of the rot.s component, I'm too tired to code the example, but I'm hoping you get the idea.
you're... mocking me, aren't you? im gonna guess that you do each swing arc in steps to do this. um... so in the timer do a for loop of however many steps with an exponential decrese of the .s multiplier. sounds smart, huh? i have no idea how to do exponential progressions. :X uh, and its gonna be so all of them add up to the gVecAngle? im not actually a programmer, i just play one in rpg games :X and i REALLY dont do math! but does that really make it swing smoothly? i DID see you talking targetomega in that other thread! im gonna try putting that in.... its wonky, but it aint that important for a little swing. they're still fun to ride on.
|
|
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
|
03-11-2008 20:38
lol not mocking, and to be honest the multiplication/division of the .s component is only aproximate with increasing error as the rotation gets bigger (as I learned the hard way) so no good for more than say 7-10 degrees on the decreased angle side. for accurate rotation fractions you'd use the SLERP algorythm found on the lsl portal
in truth I used a rotation that I split each step upwards, and doubled each step down to mimic gravity, the .s hack I mentioned above provides a good FAST approximate, but isn't really useful for anything that requires accuracy or for larger rotations
_____________________
| | . "Cat-Like Typing Detected" | . This post may contain errors in logic, spelling, and | . grammar known to the SL populace to cause confusion | | - Please Use PHP tags when posting scripts/code, Thanks. | - Can't See PHP or URL Tags Correctly? Check Out This Link... | - 
|