sayua Posted June 7, 2021 Share Posted June 7, 2021 Hello, I found a script here, its rotating a object 90" when you touch the object here the script Quote integer intSwing =90; rotation rotSwing; vector vOffset; default{ state_entry(){ rotSwing = llEuler2Rot(<0.0,0.0,(float)intSwing>*DEG_TO_RAD); //90 degrees on the z axis vector size = llGetScale(); vOffset = <(size.x*-0.5),(size.y*-0.5),0.0>;//open away from someone standing in front of face 2 -- that is, in front of the prim -- hinged on the left. } touch_start(integer total_number){ list l = llGetPrimitiveParams([PRIM_POS_LOCAL,PRIM_ROT_LOCAL]); vector v = llList2Vector(l,0); rotation r = llList2Rot(l,1); llSetPrimitiveParams([PRIM_POS_LOCAL,v+(vOffset-vOffset * rotSwing)*r,PRIM_ROT_LOCAL,rotSwing*r]); rotSwing.s*=-1; } } and its work great, but I want create two object, one as button and other one the object that rotating. please help me thank you Link to comment Share on other sites More sharing options...
Rolig Loon Posted June 7, 2021 Share Posted June 7, 2021 I'm not sure that I understand what you are asking for, but it sounds like you just want to be able to rotate your object by clicking on a separate button. That's easy. All you need to do is take Void's initial script and turn the touch_start event into a listen event. Open a communication channel in the state_entry event so that the script has something to listen for: llListen(-3928573,"","TURN",""); Put the script into your rotating object. Then write a second simple switch and put it in your button object: default { touch_start(integer num) { llRegionSay(-3928573,"TURN"); } } All the fun stuff is still done in the rotating object. The button switch is just a dumb clicker. 1 Link to comment Share on other sites More sharing options...
sayua Posted June 8, 2021 Author Share Posted June 8, 2021 (edited) 16 hours ago, Rolig Loon said: I'm not sure that I understand what you are asking for, but it sounds like you just want to be able to rotate your object by clicking on a separate button. That's easy. All you need to do is take Void's initial script and turn the touch_start event into a listen event. Open a communication channel in the state_entry event so that the script has something to listen for: llListen(-3928573,"","TURN",""); Put the script into your rotating object. Then write a second simple switch and put it in your button object: default { touch_start(integer num) { llRegionSay(-3928573,"TURN"); } } All the fun stuff is still done in the rotating object. The button switch is just a dumb clicker. thank you for reply, yes I want to rotate other object with separate button. I try to follow your instruction, maybe I do something wrong, because its not working Quote integer intSwing =90; rotation rotSwing; vector vOffset; default { state_entry() { llListen(-3928573,"","TURN",""); } listen(integer channel, string name, key id, string message) { rotSwing = llEuler2Rot(<0.0,0.0,(float)intSwing>*DEG_TO_RAD); //90 degrees on the z axis vector size = llGetScale(); vOffset = <(size.x*-0.5),(size.y*-0.5),0.0>;//open away from someone standing in front of face 2 -- that is, in front of the prim -- hinged on the left. list l = llGetPrimitiveParams([PRIM_POS_LOCAL,PRIM_ROT_LOCAL]); vector v = llList2Vector(l,0); rotation r = llList2Rot(l,1); llSetPrimitiveParams([PRIM_POS_LOCAL,v+(vOffset-vOffset * rotSwing)*r,PRIM_ROT_LOCAL,rotSwing*r]); rotSwing.s*=-1; } } Is it correct script ? Please help, thank you. Edited June 8, 2021 by sayua 1 Link to comment Share on other sites More sharing options...
Xiija Posted June 8, 2021 Share Posted June 8, 2021 I put the regionsay in one prim and your script in the other, and it worked for me? Link to comment Share on other sites More sharing options...
sayua Posted June 8, 2021 Author Share Posted June 8, 2021 3 hours ago, Xiija said: I put the regionsay in one prim and your script in the other, and it worked for me? yes its work, but the movement bit different with originial script. with last script the object turn 360", but with original script the object only turn 90" and second touch the object back to original position. thank you Link to comment Share on other sites More sharing options...
Profaitchikenz Haiku Posted June 8, 2021 Share Posted June 8, 2021 (edited) 7 hours ago, sayua said: rotSwing*r]); This should be the other way round, r * rotSwing (r is the actual local rotation, rotSwing is the amount it is to be altered by) More interestingly though, I can't see how this bit is going to work state_entry() { llListen(-3928573,"","TURN",""); } listen(integer channel, string name, key id, string message) { You're listening on channel -3928573 for any name talking, with an id of "TURN" , for any message? If it works at all it's because whatever the key value of "TURN" equates to it just happens to be the key of your sender? Edited June 8, 2021 by Profaitchikenz Haiku Link to comment Share on other sites More sharing options...
sayua Posted June 8, 2021 Author Share Posted June 8, 2021 45 minutes ago, Profaitchikenz Haiku said: This should be the other way round, r * rotSwing (r is the actual local rotation, rotSwing is the amount it is to be altered by) More interestingly though, I can't see how this bit is going to work state_entry() { llListen(-3928573,"","TURN",""); } listen(integer channel, string name, key id, string message) { You're listening on channel -3928573 for any name talking, with an id of "TURN" , for any message? If it works at all it's because whatever the key value of "TURN" equates to it just happens to be the key of your sender? thank you for reply r * rotSwing or rotSwing*r both are work for me, my problem is the second touch (button) the object didn't come to original position (-90"), its keep moving 90" left Link to comment Share on other sites More sharing options...
Rolig Loon Posted June 8, 2021 Share Posted June 8, 2021 (edited) 1 hour ago, Profaitchikenz Haiku said: You're listening on channel -3928573 for any name talking, with an id of "TURN" , for any message? If it works at all it's because whatever the key value of "TURN" equates to it just happens to be the key of your sender? Ooops. That was my mistake in hasty typing. I should have said On 6/7/2021 at 11:28 AM, Rolig Loon said: llListen(-3928573,"","","TURN"); BTW, this is twice in one week that I have misattributed the originator of a useful and quotable creation (a personal record, for which I slink away in embarrassment). The script that the OP posted was originally written by @Innula Zenovka and then re-posted in the sticky at the top of this forum. The order of multiplication ( rotSwing*r ) works just fine. Edited June 8, 2021 by Rolig Loon 1 Link to comment Share on other sites More sharing options...
Profaitchikenz Haiku Posted June 8, 2021 Share Posted June 8, 2021 37 minutes ago, sayua said: my problem is the second touch (button) the object didn't come to original position (-90"), its keep moving 90" left That's because although you negate rotSwing immediately after using it, the next time into the listen it is re-initialised to 90 degrees and your previous negation is thus trashed. Move the initialisation of rotSwing into the state_entry and the altered value of rotSwing will be available next time in the listen. Link to comment Share on other sites More sharing options...
Profaitchikenz Haiku Posted June 8, 2021 Share Posted June 8, 2021 20 minutes ago, Rolig Loon said: The order of multiplication ( rotSwing*r ) works just fine. I agree, in this case with simple rotation to and fro around the z-axis it will, but The wiki is quite definite about the rotation multiplication and division being non-commutative. If rotation1 * rotation2 == rotation2 * rotation1 why state the operation order is important? I can see somebody adapting this script to make adjustments to a chiild prim in more than one axis at a time and coming unstuck. I could of course be wrong and I am confident that the usual subjects will be along shortly to put me in my place Link to comment Share on other sites More sharing options...
sayua Posted June 8, 2021 Author Share Posted June 8, 2021 2 minutes ago, Profaitchikenz Haiku said: I agree, in this case with simple rotation to and fro around the z-axis it will, but The wiki is quite definite about the rotation multiplication and division being non-commutative. If rotation1 * rotation2 == rotation2 * rotation1 why state the operation order is important? I can see somebody adapting this script to make adjustments to a chiild prim in more than one axis at a time and coming unstuck. I could of course be wrong and I am confident that the usual subjects will be along shortly to put me in my place I see thank you, can you help me with this script ? so the object (with 2nd button click) back to original position ? thank you so much Link to comment Share on other sites More sharing options...
Rolig Loon Posted June 8, 2021 Share Posted June 8, 2021 In fact, the OP has moved all three of these lines out of state_entry for some reason: rotSwing = llEuler2Rot(<0.0,0.0,(float)intSwing>*DEG_TO_RAD); //90 degrees on the z axis vector size = llGetScale(); vOffset = <(size.x*-0.5),(size.y*-0.5),0.0>;//open away from someone standing in front of face 2 -- that is, in front of the prim -- hinged on the left. They should not have been moved. Link to comment Share on other sites More sharing options...
Profaitchikenz Haiku Posted June 8, 2021 Share Posted June 8, 2021 9 minutes ago, sayua said: can you help me with this script ? so the object (with 2nd button click) back to original position ? What Rolig said will do it Link to comment Share on other sites More sharing options...
Xiija Posted June 8, 2021 Share Posted June 8, 2021 (edited) @sayua If you just want a simple rot in place 90 deg, mebbe kinda like ... Touch object: integer ownerChan; default { state_entry() { ownerChan = 0x80000000 | (integer)("0x"+(string)llGetOwner() ); } touch_start(integer num) { llRegionSay(ownerChan,"TURN"); } } Rotating object: integer ownerChan; integer Swing = 90; rotation Rot; default { state_entry() { Rot = llEuler2Rot( <0.0, 0.0, (float)Swing * DEG_TO_RAD> ); ownerChan = 0x80000000 | (integer)("0x"+(string)llGetOwner() ); llListen(ownerChan,"","TURN",""); } listen(integer channel, string name, key id, string message) { if( message == "TURN") { llSetLocalRot( Rot * llGetLocalRot() ); } } } if you want it to rotate 180 deg, and back to normal, change the 90 to 180 , and change the rotation line to: llSetLocalRot( ZERO_ROTATION / Rot * llGetLocalRot() ); Edited June 8, 2021 by Xiija Link to comment Share on other sites More sharing options...
Profaitchikenz Haiku Posted June 8, 2021 Share Posted June 8, 2021 (edited) I did a quick test inworld to see what the effect of changing the order in which you multiply rotations might do, and the results are very interesting. TL;DR If you're working on an object with zero rotation, then you'll get away with ignoring the order, but that's an IFF The Script, dropped in a simple cube with initially zero rotation // check the order of multiplying rotations key owner; rotation rot1; rotation rot2; rotation rot3; vector angle1 = <0.0, 0.0, 90.0>; vector angle2 = <45.0, 45.0, 0.0>; vector angle3 = <90.0, 0.0, 90.0>; rotation baseRot; rotation result; vector answer; default { state_entry() { owner = llGetOwner(); baseRot = llGetRot(); rot1 = llEuler2Rot(angle1*DEG_TO_RAD); rot2 = llEuler2Rot(angle2*DEG_TO_RAD); rot3 = llEuler2Rot(angle3*DEG_TO_RAD); } touch_start(integer touches) { result = baseRot * rot1; answer = llRot2Euler(result)*RAD_TO_DEG; llOwnerSay("BaseRot * rot1 = " + (string) answer); result = rot1 * baseRot; answer = llRot2Euler(result)*RAD_TO_DEG; llOwnerSay("rot1 * BaseRot = " + (string) answer); result = baseRot * rot2; answer = llRot2Euler(result)*RAD_TO_DEG; llOwnerSay("BaseRot * rot2 = " + (string) answer); result = rot2 * baseRot; answer = llRot2Euler(result)*RAD_TO_DEG; llOwnerSay("rot2 * BaseRot = " + (string) answer); result = baseRot * rot3; answer = llRot2Euler(result)*RAD_TO_DEG; llOwnerSay("BaseRot * rot4 = " + (string) answer); result = rot3 * baseRot; answer = llRot2Euler(result)*RAD_TO_DEG; llOwnerSay("rot3 * BaseRot = " + (string) answer); } } and the answers, first with the cube having zero rotation, then with the cube turned 45 degrees counterclockwise on the Z axis 13:42] checkRotOrder: BaseRot * rot1 = <0.00000, 0.00000, 90.00000> [13:42] checkRotOrder: rot1 * BaseRot = <0.00000, 0.00000, 90.00000> [13:42] checkRotOrder: BaseRot * rot2 = <45.00000, 45.00000, 0.00000> [13:42] checkRotOrder: rot2 * BaseRot = <45.00000, 45.00000, 0.00000> [13:42] checkRotOrder: BaseRot * rot4 = <90.00000, 0.00000, 90.00000> [13:42] checkRotOrder: rot3 * BaseRot = <90.00000, 0.00000, 90.00000> [13:43] Profaitchikenz Haiku: turned 45 degrees (and reset the script to get the new base rotation) [13:43] checkRotOrder: BaseRot * rot1 = <0.00000, 0.00000, 135.00000> [13:43] checkRotOrder: rot1 * BaseRot = <0.00000, 0.00000, 135.00000> [13:43] checkRotOrder: BaseRot * rot2 = <45.00000, 45.00002, 45.00001> [13:43] checkRotOrder: rot2 * BaseRot = <-16.32497, 58.60028, 73.67507> [13:43] checkRotOrder: BaseRot * rot4 = <90.00000, 0.00000, 135.00000> [13:43] checkRotOrder: rot3 * BaseRot = <90.00000, 45.00002, 90.00000> It makes a difference in anything but the simple case. If you want to rotate an object by an amount, the correct order is objectRot * amountRot; Looking at the above output, if your object has zero rotation, or if the amount you are rotating it by is only non-zero in one of the three axes, it seems to be commutative, but the moment you have non-zero values on more than one of the three axes it is non-commutative. One of these lovely gotchas Edited June 8, 2021 by Profaitchikenz Haiku 1 Link to comment Share on other sites More sharing options...
Quistess Alpha Posted June 9, 2021 Share Posted June 9, 2021 (edited) 6 hours ago, Profaitchikenz Haiku said: If you want to rotate an object by an amount, the correct order is objectRot * amountRot; Actually, it depends on how you think about the rotation. It's quite odd, but if you think about the rotation happening in the local reference frame of the object then the reverse order: amountRot * objectRot is correct. I didn't explain it at all, but the long examples I dropped in the script library demonstrate this quite nicely: Maybe I'll post a video of it working when I have a hot minute. Edit: video: The first one is rotation * base, the second is base * rotation. Edited June 9, 2021 by Quistessa Link to comment Share on other sites More sharing options...
Quistess Alpha Posted June 9, 2021 Share Posted June 9, 2021 5 hours ago, Profaitchikenz Haiku said: if the amount you are rotating it by is only non-zero in one of the three axes, it seems to be commutative, Not true, do more tests, or compare llAxisAngle2Rot(<1,0,0>,PI) * llAxisAngle2Rot(<0,1,0>,PI); and llAxisAngle2Rot(<0,1,0>,PI) * llAxisAngle2Rot(<1,0,0>,PI); Rotating an object towards yourself then to the left (if the object's forward axis is pointing at you that's 90y then 90z) is different than rotating an object to the left then towards yourself. in the first case its top is pointing left, in the second it's pointing at you. 1 Link to comment Share on other sites More sharing options...
sayua Posted June 9, 2021 Author Share Posted June 9, 2021 8 hours ago, Xiija said: @sayua If you just want a simple rot in place 90 deg, mebbe kinda like ... Touch object: integer ownerChan; default { state_entry() { ownerChan = 0x80000000 | (integer)("0x"+(string)llGetOwner() ); } touch_start(integer num) { llRegionSay(ownerChan,"TURN"); } } Rotating object: integer ownerChan; integer Swing = 90; rotation Rot; default { state_entry() { Rot = llEuler2Rot( <0.0, 0.0, (float)Swing * DEG_TO_RAD> ); ownerChan = 0x80000000 | (integer)("0x"+(string)llGetOwner() ); llListen(ownerChan,"","TURN",""); } listen(integer channel, string name, key id, string message) { if( message == "TURN") { llSetLocalRot( Rot * llGetLocalRot() ); } } } if you want it to rotate 180 deg, and back to normal, change the 90 to 180 , and change the rotation line to: llSetLocalRot( ZERO_ROTATION / Rot * llGetLocalRot() ); thank you @Xiija its working thank you @Rolig Loon thank you @Profaitchikenz Haiku 1 Link to comment Share on other sites More sharing options...
Profaitchikenz Haiku Posted June 9, 2021 Share Posted June 9, 2021 5 hours ago, Quistessa said: Actually, it depends on how you think about the rotation. You know, as I typed the post I just knew I was going to be wrong, but like Dougal in the cockpit with the big red button, I couldn't resist it. You raised a point I had forgotten about, the local orientation, I think I'd better look again at this using a child prim. In all of the scripts I've created using rotations of attachment, avatars on objects... I've always obtained the current local rotation and multiplied it by the desired adjustment then re-applied it, and now I'm wondering if I've just been luck all this time (although I always only apply rotation adjustments one axis at a time, and this was what I seemed to be seeing in my earlier post, single-axis changes seeem Ok). Link to comment Share on other sites More sharing options...
Quistess Alpha Posted June 9, 2021 Share Posted June 9, 2021 3 minutes ago, Profaitchikenz Haiku said: using a child prim. If you set the rotation of a child prim, remember to use PRIM_ROT_LOCAL and not PRIM_ROTATION. There are a couple reasonable things to set the rotation to that you could play with (assuming oldRot is the rotation you get from the prim, and deltaRot is a change to apply): oldRot * deltaRot; // rotate on axes defined by the root prim. deltaRot * oldRot; // rotate on axes defined by the child prim. newRot / llGetRootRotation(); // set the rotation to an absolute orientation. (ZERO_ROTATION/llGetRootRotation()) * newRot; // not sure, but worth a play. Link to comment Share on other sites More sharing options...
Recommended Posts
Please take a moment to consider if this thread is worth bumping.
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now