Jump to content

Problems returning rotating prims to center


Miguelito Shilova
 Share

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

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

Recommended Posts

I'm adapting a boat script to handle a pair of rotating engines (2 prims each), that rotate 45 degrees to the left and right whenever the boat turns in the accompanying direction.

I can get the prims to turn left and right, but when I release the direction key, the prims do not return to center. Additionally when the script stops (e.g., pilot stands), the engine prims do not return to center either.

I declare the engine prim linkset numbers at the top of the script, and this obviously works fine ...

integer RDPHousingSB = 12;
integer RDPHousingPT = 21;
integer RDPPropSB = 17;
integer RDPPropPT = 23;

The script also declares these values that relate to the turning of the boat ...

vector angMotor;
float Z_ANG_MAX = 0.5;
float Z_ANG_INCR = 0.05;

Here is what is in the boat controls section ...

 

    control(key id, integer held, integer change) 
    {

        
        float water_height = llWater(ZERO_VECTOR);
        vector pos = llGetPos();
        float float_diff = pos.z - water_height;


            
        if ((change & CONTROL_FWD) || (change & CONTROL_BACK))
        {
            if (held & CONTROL_FWD) 
            {
                if (throttle < THROTTLE_MAX)
                {
                    throttle++;
                }
            }
                                
            else if (held & CONTROL_BACK) 
            {
                if (throttle > THROTTLE_MIN)
                {                
                    throttle--;                     
                }
            }
            llMessageLinked(LINK_SET,throttle,"throttle",""); // pass throttle setting to child prims
        }
                
        if ((held & CONTROL_RIGHT) || (held & CONTROL_ROT_RIGHT)) 
        {
            if (angMotor.z > 0)
            {
                angMotor.z = 0;
            }
            else if (angMotor.z > -Z_ANG_MAX)
            {
                angMotor.z -= Z_ANG_INCR;
                llSetLinkPrimitiveParamsFast(RDPHousingSB, [PRIM_ROT_LOCAL,  llEuler2Rot(<0.0,0.0,135.0>*DEG_TO_RAD)]);
                llSetLinkPrimitiveParamsFast(RDPHousingPT, [PRIM_ROT_LOCAL,  llEuler2Rot(<0.0,0.0,135.0>*DEG_TO_RAD)]);
                llSetLinkPrimitiveParamsFast(RDPPropSB, [PRIM_ROT_LOCAL,  llEuler2Rot(<0.0,0.0,135.0>*DEG_TO_RAD)]);
                llSetLinkPrimitiveParamsFast(RDPPropPT, [PRIM_ROT_LOCAL,  llEuler2Rot(<0.0,0.0,135.0>*DEG_TO_RAD)]);
            }
        }   
        else if ((held & CONTROL_LEFT) || (held & CONTROL_ROT_LEFT)) 
        {
            if (angMotor.z < 0)
            {
                angMotor.z = 0;
            }
            else if (angMotor.z < Z_ANG_MAX)
            {
                angMotor.z += Z_ANG_INCR;
                llSetLinkPrimitiveParamsFast(RDPHousingSB, [PRIM_ROT_LOCAL,  llEuler2Rot(<0.0,0.0,-135.0>*DEG_TO_RAD)]);
                llSetLinkPrimitiveParamsFast(RDPHousingPT, [PRIM_ROT_LOCAL,  llEuler2Rot(<0.0,0.0,-135.0>*DEG_TO_RAD)]);
                llSetLinkPrimitiveParamsFast(RDPPropSB, [PRIM_ROT_LOCAL,  llEuler2Rot(<0.0,0.0,-135.0>*DEG_TO_RAD)]);
                llSetLinkPrimitiveParamsFast(RDPPropPT, [PRIM_ROT_LOCAL,  llEuler2Rot(<0.0,0.0,-135.0>*DEG_TO_RAD)]);
            }
        
        }
        else
        {
            angMotor = ZERO_VECTOR;
        }

 I thought if I put in another set of  llSetLinkPrimitiveParamsFast calls for each prim in the script with the Z rotation value set to 180, then I could get them to return to center. It seemed the best place would be after the 'else'. This does cause the engine prims to return to center, but then I lose the abiltiy to turn the boat left and right.

I suspect I need something else under 'else' to keep the boat rotation from being blocked, but I'm out of ideas.

As always, the community's help is greatly appreciated.

Mig

Link to comment
Share on other sites

Unless I'm missing something, there's nothing in the code about what to do when you release one of the controls.   Try something like to detect when you've taken your finger off the button.

integer release = ~level & edge;if (release & CONTROL_WHATEVER)

 Also, while this is nothing to do with the problem, you will probably get a better visual effect if you use PRIM_LINK_TARGET in llSetLinkPrimiveParamsFast and thus force all the prims to move in the same frame.

Link to comment
Share on other sites

I don't have a good way to test this, but can't you just write your last test as

if (~( held | change) ){    angMotor = ZERO_VECTOR;    llSetLinkPrimitiveParamsFast(RDPHousingSB, [PRIM_ROT_LOCAL,llEuler2Rot(<0.0,0.0,PI>)]);    llSetLinkPrimitiveParamsFast(RDPHousingPT, [PRIM_ROT_LOCAL,llEuler2Rot(<0.0,0.0,PI>)]);    llSetLinkPrimitiveParamsFast(RDPPropSB, [PRIM_ROT_LOCAL,llEuler2Rot(<0.0,0.0,PI>)]);    llSetLinkPrimitiveParamsFast(RDPPropSB, [PRIM_ROT_LOCAL,llEuler2Rot(<0.0,0.0,PI>)]);}

 ?  I'm not sure that I understand why you would expect to be able to turn the boat if the engines are centered and turned off, though.  Maybe I'm missing something. 

 

Link to comment
Share on other sites

Hi there, and thanks for your response ...

You are correct - as per the code above, there isn't anything in the code above that centers the engines. I presume by your example below that I would include the "integer release = ~level & edge;" with the other declarations at the top of the script, but I'm not sure I follow what you mean with the IF statement. Can you elaborate on how that would look, given my code example above?

Thanks,

Mig

Link to comment
Share on other sites

Sorry about the confusion - my mind goes in so many directions at once sometimes I confuse myself :matte-motes-confused:

Right now I can get the engine prims to rotate CCW 45 degrees when CONTROL_LEFT is pressed, and can get them to rotate CW 45 degrees when CONTROL_RIGHT is pressed, but I cant get the prims to return to center when either commands are released.

Mig

Link to comment
Share on other sites

I tried using the suggested code from Rolig, but I must not have it in the right spot ...

I turned off all scripts in the boat, and deleted the old engine script after turning it off as well.

I then unlinked all prims, ran a linknumber script in all four engine prims (both housings, and both impellers), relinked the boat, and captured fresh linknumbers, then turned off and deleted the linknumber scripts.

I updated the linknumber declarations as such ...

integer PT_RDT = 3;integer PT_Impeller = 5;integer SB_RDT = 2;integer SB_Impeller = 4;

The other declarations I left the same as before.

Now for the control portion, I updated the declaration labels and added Rolig's code where I thought it was intended ...

  control(key id, integer held, integer change)     {                float water_height = llWater(ZERO_VECTOR);        vector pos = llGetPos();        float float_diff = pos.z - water_height;                    if ((change & CONTROL_FWD) || (change & CONTROL_BACK))        {            if (held & CONTROL_FWD)             {                if (throttle < THROTTLE_MAX)                {                    throttle++;                }            }                                            else if (held & CONTROL_BACK)             {                if (throttle > THROTTLE_MIN)                {                                    throttle--;                                     }            }            llMessageLinked(LINK_SET,throttle,"throttle",""); // pass throttle setting to child prims        }                        // if (held & CONTROL_UP && float_diff < Z_FLOAT_HEIGHT)        {           // if (zLinearMotor < Z_MOTOR_MAX)            {             //   zLinearMotor += Z_MOTOR_INCR;            }        }       // else if (held & CONTROL_DOWN)        {         //   if (zLinearMotor > -Z_MOTOR_MAX)            {           //     zLinearMotor -= Z_MOTOR_INCR;            }        }       // else        {         //   zLinearMotor = 0;        }                        if ((held & CONTROL_RIGHT) || (held & CONTROL_ROT_RIGHT))         {            if (angMotor.z > 0)            {                angMotor.z = 0;            }            else if (angMotor.z > -Z_ANG_MAX)            {                angMotor.z -= Z_ANG_INCR;                llSetLinkPrimitiveParamsFast(SB_RDT, [PRIM_ROT_LOCAL,  llEuler2Rot(<0.0,0.0,135.0>*DEG_TO_RAD)]);                llSetLinkPrimitiveParamsFast(PT_RDT, [PRIM_ROT_LOCAL,  llEuler2Rot(<0.0,0.0,135.0>*DEG_TO_RAD)]);                llSetLinkPrimitiveParamsFast(SB_Impeller, [PRIM_ROT_LOCAL,  llEuler2Rot(<0.0,0.0,135.0>*DEG_TO_RAD)]);                llSetLinkPrimitiveParamsFast(PT_Impeller, [PRIM_ROT_LOCAL,  llEuler2Rot(<0.0,0.0,135.0>*DEG_TO_RAD)]);            }        }           else if ((held & CONTROL_LEFT) || (held & CONTROL_ROT_LEFT))         {            if (angMotor.z < 0)            {                angMotor.z = 0;            }            else if (angMotor.z < Z_ANG_MAX)            {                angMotor.z += Z_ANG_INCR;                llSetLinkPrimitiveParamsFast(SB_RDT, [PRIM_ROT_LOCAL,  llEuler2Rot(<0.0,0.0,-135.0>*DEG_TO_RAD)]);                llSetLinkPrimitiveParamsFast(PT_RDT, [PRIM_ROT_LOCAL,  llEuler2Rot(<0.0,0.0,-135.0>*DEG_TO_RAD)]);                llSetLinkPrimitiveParamsFast(SB_Impeller, [PRIM_ROT_LOCAL,  llEuler2Rot(<0.0,0.0,-135.0>*DEG_TO_RAD)]);                llSetLinkPrimitiveParamsFast(PT_Impeller, [PRIM_ROT_LOCAL,  llEuler2Rot(<0.0,0.0,-135.0>*DEG_TO_RAD)]);            }                }                if (~( held | change) ){    angMotor = ZERO_VECTOR;    llSetLinkPrimitiveParamsFast(SB_RDT, [PRIM_ROT_LOCAL, llEuler2Rot(<0.0,0.0,PI>)]);    llSetLinkPrimitiveParamsFast(PT_RDT, [PRIM_ROT_LOCAL, llEuler2Rot(<0.0,0.0,PI>)]);    llSetLinkPrimitiveParamsFast(SB_Impeller, [PRIM_ROT_LOCAL, llEuler2Rot(<0.0,0.0,PI>)]);    llSetLinkPrimitiveParamsFast(PT_Impeller, [PRIM_ROT_LOCAL, llEuler2Rot(<0.0,0.0,PI>)]);}                            else        {            angMotor = ZERO_VECTOR;        }        set_motor();    }       

 The net result was only the two impellers moved when I first pressed a control key. They rotated on the X and Z axes and then locked. The engine housings did not move, and the boat would only move forward and backward.

I'm hoping the problem is just where I put Rolig's suggested code. Thoughts?

Link to comment
Share on other sites

It ought to look like what I wrote, unless I've missed something.  As I said, I don't have an easy way to test it in world, but it feels right.  if (~(held | change)) should text to see whether you've let up on the controls.

ETA:  Replacing your final else.

Link to comment
Share on other sites

Rolig's code works for me.

I've just made up a very crude model of what I think you're describing, and this does the trick:

rotation r45Left;rotation r45Right;rotation r180;default{    state_entry()    {       llSitTarget(<0.0,0.0,0.5>,ZERO_ROTATION);       r45Left =  llEuler2Rot(<0.0,0.0,135.0>*DEG_TO_RAD);       r45Right = llEuler2Rot(<0.0,0.0,-135.0>*DEG_TO_RAD);       r180 = llEuler2Rot(<0.0,0.0,PI>);             llSetLinkPrimitiveParamsFast(LINK_SET,[            PRIM_LINK_TARGET,2,PRIM_ROT_LOCAL,r180 ,            PRIM_LINK_TARGET,3,PRIM_ROT_LOCAL,r180 ,            PRIM_LINK_TARGET,4,PRIM_ROT_LOCAL,r180 ,            PRIM_LINK_TARGET,5,PRIM_ROT_LOCAL,r180]);    }        changed(integer change){        if (change & CHANGED_LINK){            key k = llAvatarOnSitTarget();            if (k){                llRequestPermissions(k,PERMISSION_TAKE_CONTROLS);            }            else{                 llSetLinkPrimitiveParamsFast(LINK_SET,[            PRIM_LINK_TARGET,2,PRIM_ROT_LOCAL,r180 ,            PRIM_LINK_TARGET,3,PRIM_ROT_LOCAL,r180 ,            PRIM_LINK_TARGET,4,PRIM_ROT_LOCAL,r180 ,            PRIM_LINK_TARGET,5,PRIM_ROT_LOCAL,r180]);             }                    }    }          run_time_permissions(integer perm)    {        if(PERMISSION_TAKE_CONTROLS & perm)        {            llTakeControls(                            CONTROL_FWD |                            CONTROL_BACK |                            CONTROL_LEFT |                            CONTROL_RIGHT |                            CONTROL_ROT_LEFT |                            CONTROL_ROT_RIGHT |                            CONTROL_UP |                            CONTROL_DOWN |                            CONTROL_LBUTTON |                            CONTROL_ML_LBUTTON ,                            TRUE, FALSE);         }    }    control(key id, integer level, integer edge)    {        integer start = level & edge;        integer released = ~level & edge;        integer held = level & ~edge;        integer untouched = ~(level | edge);                       if((start & CONTROL_LEFT)||(start & CONTROL_ROT_LEFT)){            llSetLinkPrimitiveParamsFast(LINK_SET,[            PRIM_LINK_TARGET,2,PRIM_ROT_LOCAL,r45Left,            PRIM_LINK_TARGET,3,PRIM_ROT_LOCAL,r45Left,            PRIM_LINK_TARGET,4,PRIM_ROT_LOCAL,r45Left,            PRIM_LINK_TARGET,5,PRIM_ROT_LOCAL,r45Left]);        }                else if((start & CONTROL_RIGHT)||(start & CONTROL_ROT_RIGHT)){            llSetLinkPrimitiveParamsFast(LINK_SET,[            PRIM_LINK_TARGET,2,PRIM_ROT_LOCAL,r45Right,            PRIM_LINK_TARGET,3,PRIM_ROT_LOCAL,r45Right,            PRIM_LINK_TARGET,4,PRIM_ROT_LOCAL,r45Right,            PRIM_LINK_TARGET,5,PRIM_ROT_LOCAL,r45Right]);        }        else if ((released & CONTROL_LEFT)||(released & CONTROL_ROT_LEFT)||(released & CONTROL_RIGHT) || (released & CONTROL_ROT_RIGHT)){              llSetLinkPrimitiveParamsFast(LINK_SET,[            PRIM_LINK_TARGET,2,PRIM_ROT_LOCAL,r180 ,            PRIM_LINK_TARGET,3,PRIM_ROT_LOCAL,r180 ,            PRIM_LINK_TARGET,4,PRIM_ROT_LOCAL,r180 ,            PRIM_LINK_TARGET,5,PRIM_ROT_LOCAL,r180]);                        }     }}                        

 

 

Link to comment
Share on other sites

OK - I'm seeing some progress. I was able to make a linkset of 5 prims - one base, two rings (torus) and two cylinders, putting the cylinders in the rings to represent the props in the housings.

As soon as I started the script and pressed a directional key, the cylinders rotated on the Y axis (round faces up and down), but they and the rings still moved left and right on the Z axis 45 degrees according to the directional input.

Is there something that would keep the cylinders from realigining like that? If so, then I might be able to integrate this into the boat script.

Link to comment
Share on other sites

PRIM_ROTATION_LOCAL uses the relevant prim's own local rotation.   So you need to check, using edit linked parts and the local ruler mode, to see how you're actually rotating them.

I think you might find it simplest to put together a script that uses llGetLinkPrimitiveParams to chat out the link number, PRIM_ROT_LOCAL and (just in case) PRIM_POS_LOCAL for each prim in each of the three required positions.   Make a note of the results,  and hard code them.

Link to comment
Share on other sites

I agree.  Since you will be using those three particular rotations over and over again, you shouldn't have to calculate them each time anyway.   Grab them once, store them, and then use

[PRIM_ROT_LOCAL, gGoLeft]

[PRIM_ROT_LOCAL,GoRight]

or [PRIM_ROT_LOCAL, GoCenter]

as appropriate.

Link to comment
Share on other sites

It's refreshing to see a 10 year old script by Cubey Terra is still getting modded.

 

However, this seems to be pretty much the same question you were asking before in http://community.secondlife.com/t5/LSL-Scripting/Rudder-script-for-BWWind-sailing-engine/m-p/1526333 . Perhaps if you studied http://lslwiki.net/lslwiki/wakka.php?wakka=control it may help you get a handle on all this.

Link to comment
Share on other sites

Thanks for the feedback ...

Yes, it's true I've looked at prim rotation before. I was able to get the results I wanted, but I was also using a different script, and I simply don't know enough about scripting to fully understand what was different between the two boat scripts. 

But I do appreciate the Wiki link - I will be diving into that, as it will hopefully help me uncover how the two scripts handled control events to achieve the same result.

Mig

Link to comment
Share on other sites

Control events can be tricky to understand.   In addition to the wiki, I found the articles in the old LSL wiki on the control event and llTakeControls very helpful when I started to learn about controls.   

However, in this instance, it seems as you're having problems with the prims' local rotations.   When you're rotating child prims, I would suggest you concentrate on learning how to use PRIM_ROT_LOCAL,   This is because PRIM_ROTATION is rather badly bugged in child prims, and always has been. There's a simple enough work-round to correct for the bug, but if someone is trying to learn rotations, looking at examples that contain the work-round will probably confuse matters since, quite simply, the code doesn't do what it looks as if it should do.

PRIM_ROT_LOCAL isn't bugged, and behaves in the way it's supposed to.

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 3712 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...