Jump to content

button to rotating object


sayua
 Share

You are about to reply to a thread that has been inactive for 1215 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

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

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.  

  • Like 1
Link to comment
Share on other sites

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 by sayua
  • Like 1
Link to comment
Share on other sites

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

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 by Profaitchikenz Haiku
Link to comment
Share on other sites

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

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 by Rolig Loon
  • Haha 1
Link to comment
Share on other sites

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

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

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

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

@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 by Xiija
Link to comment
Share on other sites

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 by Profaitchikenz Haiku
  • Thanks 1
Link to comment
Share on other sites

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 by Quistessa
Link to comment
Share on other sites

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.

  • Thanks 1
Link to comment
Share on other sites

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

  • Like 1
Link to comment
Share on other sites

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

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

You are about to reply to a thread that has been inactive for 1215 days.

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
 Share

×
×
  • Create New...