|
Ryken Redgrave
Registered User
Join date: 26 Dec 2006
Posts: 13
|
01-02-2007 02:16
I'm not real strong with math, and am still working to grasp the difference between the different ruler modes... and therein lies my issue.
I have a cylinder, that's been rotated 90 degrees (I usually rotate it around the y-axis) so that it looks like a wheel.
I want to be able to rotate that cylinder, as a wheel, to to specific points. For example, I may want to rotate it 90 degrees, so that if I put a dot on the top of the wheel, when I rotated it 90 degrees, the dot would be facing me. If I rotated it to the 180 degree mark, it would be facing the ground. 270 degrees, away from me. You get the idea.
I cannot get this to work. No matter what I do, it flips at weird angles, and I just can't seem to get this cylinder to rotate where I want it to.
I'm sure this is in an FAQ somewhere, but I can't seem to find it.
Please help this ruler mode/angle-math newb!
|
|
Peekay Semyorka
Registered User
Join date: 18 Nov 2006
Posts: 337
|
01-02-2007 02:41
You've discovered the difference between global and local axes. You can use the llRot2Up, llRot2Left and llRot2Fwd functions for this. E.g. the code below will turn your "wheel" correctly no matter how it is rotated: vector axis = llRot2Up(llGetRot()); llTargetOmega(axis, 1.0, 1.0);
-peekay
|
|
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
|
01-02-2007 02:43
Did you remember to use radians rather than degrees? Check the Rotation Wikki page
|
|
Ryken Redgrave
Registered User
Join date: 26 Dec 2006
Posts: 13
|
01-03-2007 02:24
Ah.. the llGetRot() and llRot2Up() functions looked like what I needed... but this thing is still behaving awkwardly. Here's the script (it's just test code right now). Remember, the prim has a 90 degree rotation on its y-axis: spinIt() { vector axis = llRot2Up(llGetRot()); float angle = -45 * llFloor(llFrand(8)); // llRotateTexture(angle * DEG_TO_RAD, ALL_SIDES); // llTargetOmega(<1,0,0>, -4, 4); llTargetOmega(axis, -4, 4); llSetTimerEvent( 3 ); }
stopIt() { vector axis = llRot2Up(llGetRot()); float angle = -45 * llFloor(llFrand(8)); llSetTimerEvent ( 0 ); llOwnerSay("Setting angle to " + (string)angle); llSetPrimitiveParams( [PRIM_ROTATION, llAxisAngle2Rot(axis, angle)] ); // llRotLookAt(llAxisAngle2Rot(axis, angle), 2, .2); }
default { state_entry() { // llSay(0, "Hello, Avatar!"); }
touch_start(integer total_number) { // llSay(0, "Touched."); } touch(integer num_detected) { spinIt(); } timer() { stopIt(); } }
The spinIt() routine works as expected. I touch the object, it spins for 3 seconds like I would expect (like a wheel on a car). As soon as the 3 seconds are up, and stopIt() is called, the wheel flips to the side (so now instead of the 'edge' facing me, the round disc-face is facing me) and starts rotating towards me like a fan.
|
|
Lee Ponzu
What Would Steve Do?
Join date: 28 Jun 2006
Posts: 1,770
|
Just guessing
01-03-2007 10:50
this rotation stuff still gives me the heebie-jeebies.
In stopIt(), I think you need to convert degrees to radians.
Also, in
touch() {}
you will repeatedly call spinIt() so long as you are touching. Seems to me that you acutally want to use
touch_start() {}
|
|
Ryken Redgrave
Registered User
Join date: 26 Dec 2006
Posts: 13
|
01-03-2007 13:18
Thanks, Lee, for pointing that out. I wasn't aware touch() would continually be triggered while the mouse was held down. That one bit of insight suddenly clarifies a lot.  That being said, Mat Warf was kind enough to deliver a working test script to my inventory while I wasn't logged in. For sake of completeness, I'm posting it here with Mat's permission (I took the liberty of moving stopIt() to touch_start()): // NOTE // Due to slight innacuricies in quaternion math, it might be best to reset the rotation now and again to an initial value. If you don't, the rotation axis can drift over many uses.
// local axis we want to rotate around vector axis = <0.0,0.0,1.0>; spinIt() { // spin needs to be around global axis vector omega_axis = axis * llGetRot(); llTargetOmega(omega_axis, -4.0, 4.0); // set timer value for length of spin llSetTimerEvent( 3.0 ); }
stopIt() { llSetTimerEvent ( 0.0 ); // spinning done, timer off llTargetOmega(ZERO_VECTOR, 0.0, 0.0); // stop the spin float angle = -45.0 * llFloor(llFrand(8)); // pick a random angle rotation start = llGetRot(); // find the current rotation // create a rotation, note: convert to radians rotation modify = llAxisAngle2Rot(axis, DEG_TO_RAD * angle); // add new rotation to our current rotation, note, new rotation goes on LEFT rotation new = modify * start; llOwnerSay("Setting angle to " + (string)angle); // etc... llSetPrimitiveParams([PRIM_ROTATION, new]); // set prim params }
default { state_entry() { }
touch_start(integer total_number) { spinIt(); } timer() { stopIt(); } }
Thanks everyone, for your comments. 
|