Jump to content

Rotating all linked prims 90 degrees


Gakkor
 Share

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

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

Recommended Posts

Situation: I have a simple HUD design with 5 linked prims (more to come, this was just supposed to be a simple test) and need ALL the prims to rotate together when selected. This is to simulate a button press that expands the HUD to its full design.   {} to {+++++}. The reason for the prims is to be used as buttons for pressing, and one will hopefully be a headshot of the owner (If I can get that script finished also, XD).

 

Problem: When I set the button press to rotate the prims, it rotates the root prim,AND the child prims. That or it just rotates the child prim that is the "button" pressed. Rotated prims stay attached at their dead center and rotate on their axis. 

llSetRot, llSetLocalRot, llSetPrimitiveParamsFast, and all the such do not seem to want to work for me. Its late and I probably passed the answer several times in the last 2 hours of research, but for now I'm tired.

 

Simple answer. What script can I use, and expand upon later, to rotate the prim & its child "buttons" while keeping them aligned properly. Imagine rotating a box so you can see the next side and all its writing. Nothing else should move ON the prim, just the entire thing should rotate 90 degrees in whichever direction.

 

I want it to rotate (if looking at it from above) clockwise for the first press. 2nd button will rotate 90 degrees on a different axis.

 

Sorry for the possibly dumb and simple question, but as a new scripter to SL, I want to simplify a lot of the commands that are available, and put them as HUD components for personal use.

Link to comment
Share on other sites

Despite your careful description, I'm not sure that I understand exactly what you're after.  If you simply want to rotate the entire linkset 90 degrees around its Z axis each time you click, though, this will do it.

default{    touch_start(integer total_number)    {        llSetLinkPrimitiveParamsFast(LINK_THIS,[PRIM_ROTATION, llEuler2Rot(<0.0,0.0,PI/2>)*llGetRot()]);    }}

 

Link to comment
Share on other sites

That script sent the child prim into a tailspin. Went from    O    to   I   then to /   then \  then -  and repeated.   (That's if I was facing the prim.)

 

I managed to solve the problem by having the button prim send a message to a negative channel and having the root prim, after it was all linked, listen to that channel. Upon hearing the proper command it rotated to expand the HUD.   Now the odd problem I am having is that some of the HUDs I have seen out there, do this slow enough so that it looks like the HUD is expanding in the desired direction. As I have it, it just kind of appears/snaps to. 

 

HUD goes from:

side1.png

 

to:Side2.png

When the button on side 1 is pressed.

The button is the front, smaller half of a rectangle prism. When its pressed, the prism is rotated 90 degrees to show the right side of the prism which has the texture posted above. This side will then have other content on it using the Aplha settings.

 

The desired effect I want, is to have Side1 look like its slowly collapsing on itself Vertically and the new Side2 that's rotating around will look like its expanding from the right side of the screen.

Link to comment
Share on other sites

Like Rolig, I'm having a bit of difficulty following what's going on, despite your description.

First, though, please check your hud's construction and ensure that, by default, face 4 of the root prim is the one that faces the user when the hud is worn.   That's so that the hud starts off attached at ZERO_ROTATION, which is going to be crucial in what you're trying to do.    If it's not thus rotated, nothing that anyone suggests here is going to work properly.

Second, I think you're over-complicating stuff by sending messages on negative channels and so on.   I think you almost certainly need just the one script, in the root prim,  that looks, in part, like this:

 

integer button1;integer button2;integer button3;//and so onfind_buttons(){	integer max = llGetNumberOfPrims()+1;	integer i=1;	do {		string s = llToLower(llStringTrim(llList2String(llGetLinkPrimitiveParams(i,[PRIM_DESC]),0),STRING_TRIM));		if("button1"==s){			button1 = i;		}		else if ("button2"==s){			button2 = i;		}		else if ("button3"==s){			button3= i;		}		//and so on	}	while(++i<max);}default{	state_entry()	{		find_buttons();	}	changed(integer change)	{		if (change & CHANGED_LINK){			find_buttons();		}	}	attach(key attached)	{		if(attached){			find_buttons();		}	}	touch_start(integer total_number)	{		integer n = llDetectedLinkNumber(0);//which prim did I touch?		if (button1 == n){			//do something		}		else if (button2 == n){			//do something else		}		// and so on			}}

 As to the effects you describe, why do you think they're achieved by rotating prims rather than by sliding them in and out or by stretching and shrinking them?   I am not saying you're wrong, but I'm just wondering if there's not a better way to do it than rotating things.

Link to comment
Share on other sites

is this something like what you want?

changes the scale...then rotates the hud?

(from a curtain script- just for testing purposes)

(touch is on the main HUD prim-can be moded)



vector offset = <0,1,0>; //Prim moves/changes size along this local coordinatefloat hi_end_fixed = FALSE; //Which end of the prim should remain in place when size changes?                                      //The one with the higher (local) coordinate? float min = 0.2; //The minimum size of the prim relative to its maximum sizeinteger ns = 10; //Number of distinct steps for move/size changedefault {    state_entry()     {        offset *= ((1.0 - min) / ns) * (offset * llGetScale());        hi_end_fixed -= 0.5;    }    touch_start(integer detected)     {        integer i;        do         { llSetPrimitiveParams([PRIM_SIZE, llGetScale() - offset,            PRIM_POSITION, llGetLocalPos() + ((hi_end_fixed * offset) * llGetLocalRot())]);        }        while ((++i) < ns);                   offset = - offset;                 float move = 90/ns;         integer j;        do         {            llSetPrimitiveParams([PRIM_ROT_LOCAL,llGetLocalRot() * llEuler2Rot(<0,0,-move>*DEG_TO_RAD)]);         }        while ((++j) < ns);     }}

 

  • Like 1
Link to comment
Share on other sites

Sorry, but that makes no sense to me at all.  I can't imagine how simply rotating the entire linkset around the Z-axis can send anything into a tailspin, and your additional description simply confuses the picture further.  I agree with Innula that it sounds like you are making the whole project unnecessarily complicated.  Even from your initial description, it sounds to me as if you could do the entire thing with a single prim.

Link to comment
Share on other sites

http://youtu.be/qDS7Vgli37w

 

The hud I recorded in this is someone elses, but is an example of what I want done, because its simple. Its clean. It allows me to make multiple sides, with multiple backgrounds with multiple options. It makes the hud SMALL so that it doesn't fill the users screen. It gives the user the option to click on it, to have it expand.

 

To clarify: I was attaching the code you gave me to the front, BUTTON prim, not the root prim. The code acted funny at times. Sometimes only rotating the prim a little, other times sending it in different axis spins. If I attached it to the root prim, then everytime they clicked the "background" it would keep rotating. I just need it to rotate ONCE, thus the side button does the job just fine.

Link to comment
Share on other sites

I'm getting some problems with the script. The following errors occur:

The name 'llGetLinkPrimitiveParams' does not exist in the current context
The name 'PRIM_DESC' does not exist in the current context

I went ahead and saved the script anyways, and the "button" prims highlight with the "touch" hand, but when I have them set to llSay(o, "Button#");   nothing happens. I've copied and pasted a few times and no result.

Link to comment
Share on other sites

I have bypassed my problem with the following code in the root prim:

rotation rot_xyzq;rotation rot_pqrs;default{    state_entry()    {        vector xyz_angles = <0,0,-90.0>;        vector pqr_angles = <0, 0, 90.0>;        vector angles_in_radians = xyz_angles*DEG_TO_RAD;        vector angles_in_radians2 = pqr_angles*DEG_TO_RAD;        rot_xyzq = llEuler2Rot(angles_in_radians);        rot_pqrs = llEuler2Rot(angles_in_radians2);    }    link_message(integer sender_number, integer number, string message, key id)    {        if (message=="Button1")        {            llSetLocalRot(llGetLocalRot()*rot_xyzq);        }        if (message=="Minimize")        {            llSetLocalRot(llGetLocalRot()*rot_pqrs);        }    }}

 Then I have my Button1 and Minimize buttons in their appropriate positions. When pressed they rotate the entire prim with the child prims still properly attached. This prevents the use of Say channels and allows me to  have the prims communicate easily. I have also used the same link messaging to make the popup menus appear using a mixture of alpha and the code provided earlier in this thread to shrink the prim then rotate it. It looks wonderful.

 

If anyone has a different way of doing this, let me know as I am more than happy to expand the small amount of knowledge that I have. (please make sure that it works before posting, thanks.)

 

Edit: I messed around with an idea on the forums and made a simple flat plane with no textures and linked it in the corner of the once root prim. This plane is now the root prim and the rotation is smoother and when the expansion button is presses it expands to the left of the button. Video to be posted shortly.

Edit: With this script I can add several rotation points and use all sides of the Prim for whatever needs I may find. If I run out of room for menu options on one side, I can pop a NEXT button and have it rotate the prim to another side. This way no side is wasted and you can use as much space as you can fit on each side!

Link: http://youtu.be/FY9rXObG9Nc

 

Link to comment
Share on other sites

I don't understand why it's complaining about llGetLinkPrimitiveParams or PRIM_DESC, unless you're using a really old copy of LSLeditor or something.    If you are, please update it at Sourceforge.

The script is not going to do anything unless you label up the link numbers in the description fields, and have the script read them (it should do it automatically on attach, but reset it anyway to be sure).

The video you link to looks to me as it it's simply rotating the hud. Something like this (though I would probably make it with just one prim if I were doing it, but this is to demonstrate the concept.

Rez a box.   Make three copies by drag copying them along the positive x axis.  Colour each one a different colour.  

Now link them up, ensuring that the root prim  is the the one with the lowest x coordinate.   THIS IS IMPORTANT.   This is where that old "Side Numbering" script comes in handy (though it does mess up the texture resolution, so remember to reset the stuff on the texture tab later) -- side 4 of the root prim is the one you want as the visible side of the root prim when you attach this as a hud.

Then put this script in it:

integer button1;integer button2;integer button3;//and so onrotation z90;find_buttons(){	integer max = llGetNumberOfPrims()+1;	integer i=1;	do {		string s = llToLower(llStringTrim(llList2String(llGetLinkPrimitiveParams(i,[PRIM_DESC]),0),STRING_TRIM));		if("button1"==s){			button1 = i;		}		else if ("button2"==s){			button2 = i;		}		else if ("button3"==s){			button3= i;		}		//and so on	}	while(++i<max);}default{	state_entry()	{		find_buttons();		z90=llEuler2Rot(<0.0,0.0, -90.0>*DEG_TO_RAD);//turn right	}	changed(integer change)	{		if (change & CHANGED_LINK){			find_buttons();		}	}	attach(key attached)	{		if(attached){			find_buttons();		}	}	touch_start(integer total_number)	{		integer n = llDetectedLinkNumber(0);//which prim did I touch?		if(1==n){ // touched the root			llSetLocalRot(z90*llGetLocalRot());//turn 90 degrees to the right			z90=ZERO_ROTATION/z90; //invert the rotation		}		else{			string what;			if (button1 == n){				what = "button 1";			}			else if (button2 == n){				what = "button 2";			}			else if (button3== n){				what = "button 3";			}			llOwnerSay("You touched "+what);		}	}}

 

 

Link to comment
Share on other sites

Sorry for the late reply as I game on the side, and due to memorial day weekend, its been double exp weekend.

 

The version of LSL that I was using was indeed out of date, the new link your threw my way cleared up the error, thank you. As for your code, it works as intended. So my question goes down to: Several people have recommended only using 1 prim. How do I go about making different areas of the prim appear, and function, as "buttons" without overlapping a second, flat, smaller prim that uses the touch command that's set in the Root when they are linked?

 

Sorry for the annoying questions. I have to learn somewhere!

Link to comment
Share on other sites

Please don't apologise for asking questions -- this forum is all about helping each other learn scripting techniques.

I started to make a mock-up hud like yours, and ended up doing it with two prims.   This was simply so I don't need to worry about moving the hud as well as rotating it.  So I've got a cube as my root prim, and a child prim with the same y and z dimensions as my cube, but 4 times as long on the x axis.   The child is located forward of the root, assuming everything is set at ZERO_ROTATION.

Link it up and drop this script in.   If you've been able to follow my directions, you should see a red spot side 4 of the root prim (the side you will see by default when you attach the hud) and, on the right hand side of the hud, a red spot and 4 buttons.

When I made the texture for the buttons, I first laid out some guidelines in Gimp to ensure that each button occupies 25% of the image area.  I don't need to worry about the y coordinate of where I touch the texture on the child prim, since each button runs from the top to the bottom of the texture.

integer noOfButtons =4;integer divisor;rotation r90;default{	state_entry()	{		llSetLocalRot(ZERO_ROTATION);		r90=llEuler2Rot(<0.0,0.0,-90>*DEG_TO_RAD);		divisor = 100/noOfButtons;		llSetLinkPrimitiveParamsFast(LINK_SET,[			PRIM_LINK_TARGET,1,			PRIM_TEXTURE,4,"07e20e83-bc22-3281-f454-b34b25e0a83c",<1.0,1.0,0.0>,ZERO_VECTOR,0.0,			PRIM_TEXTURE,1,"07e20e83-bc22-3281-f454-b34b25e0a83c",<1.0,1.0,0.0>,ZERO_VECTOR,0.0,			PRIM_LINK_TARGET,2,			PRIM_TEXTURE,1,"dc67a1a3-fac1-7887-8dc0-fcaff123618b",<1.0,1.0,0.0>,ZERO_VECTOR,0.0]);	}	touch_start(integer total_number)	{		integer n = llDetectedLinkNumber(0);		if(1==n){			llSetLocalRot(r90*llGetLocalRot());			r90=ZERO_ROTATION/r90;		}		else if (2==n){			if (llDetectedTouchFace(0)==1){				vector v = llDetectedTouchUV(0);				integer n = (integer)(v.x*100);				llOwnerSay("You touched button "+(string)(1+(n/divisor)));			}		}	}}

 

Link to comment
Share on other sites

 

How many tiers of if-else statements can I throw together? I know there is a limit of 23 if statements per State, but not the tier amount. With your code I believe that I can add:

integer noOfButtons =4;integer divisor;rotation r90;default{    state_entry()    {        llSetLocalRot(ZERO_ROTATION);        r90=llEuler2Rot(<0.0,0.0,-90>*DEG_TO_RAD);        divisor = 100/noOfButtons;        llSetLinkPrimitiveParamsFast(LINK_SET,[            PRIM_LINK_TARGET,1,            PRIM_TEXTURE,4,"c856bd9b-c759-ffa6-a70f-6d65b8d9d38d",<1.0,1.0,0.0>,ZERO_VECTOR,0.0,            PRIM_TEXTURE,1,"c856bd9b-c759-ffa6-a70f-6d65b8d9d38d",<1.0,1.0,0.0>,ZERO_VECTOR,0.0,            PRIM_LINK_TARGET,2,            PRIM_TEXTURE,1,"dc67a1a3-fac1-7887-8dc0-fcaff123618b",<1.0,1.0,0.0>,ZERO_VECTOR,0.0]);    }    touch_start(integer total_number)    {        integer n = llDetectedLinkNumber(0);        integer BPress = (integer)(1+(n/divisor));            if(1==n)        {            llSetLocalRot(r90*llGetLocalRot());            r90=ZERO_ROTATION/r90;        }        else if (2==n)            {            if (llDetectedTouchFace(0)==1)                {                    vector v = llDetectedTouchUV(0);                    integer n = (integer)(v.x*100);                }                    if (1==BPress)                        {                        llSetScriptState("RadarHUD", TRUE);                        }                    if (2==BPress)                        {                        llSetScriptState("RadarHUD", FALSE);                        }                }            }}

 

Link to comment
Share on other sites

If there's a limit on the number of if statements per state, it's news to me.  There may have been one way back in the dark ages, but not in recent years.  There also seems to be no limit to nesting if conditions.  From a practical perspective, however, it's rarely necessary to nest more than three or four deep.

Link to comment
Share on other sites

I remember reading, back when I started, in the old, unmaintained LSL wiki, about there being a limit to the number of if statements you can use in a chain, rather than a state, but the official (and up-to-date) wiki says, "There seems to be no limit anymore (or very high > 120) for else-if chains."  

I've never tried writing a chain of 120-odd if-else if conditions (in fact, I would try my best to avoid it) but I don't think there's now a limit.

I don't understand your code, by the way.    In my example, 

divisor = 100/noOfButtons;vector v = llDetectedTouchUV(0);integer n = (integer)(v.x*100);integer whatButtonWasTouched = n/divisor;//starts at 0

 is supposed to calculate an integer from 0 to 3, to tell you which of the four "buttons" on the the texture "dc67a1a3-fac1-7887-8dc0-fcaff123618b" you've touched.    I would consider your script logic carefully (and also rename your local variables in the touch event, because I think there's confusion there about what is supposed to stand for what).

Link to comment
Share on other sites

The limits on if statements applied back when scripts were compiled on the viewer. The Windows version of the compiler, in particular, had some tight restraints on nested if statements.

At the time when Mono was introduced, all script compilation (both Mono and LSO) was moved to the server side, and this problem went away for practical purposes.

There are probably lots of old copies of lslint and similar tools around, that will still complain about this. If you see that, it's time for updated tools.

Link to comment
Share on other sites

Thanks for the replies on the if-else statements. I understood that "per state" there is a high limit on statements, I just didn't know how many I could stack ontop of each other with each one falling to a new tier.

Link to comment
Share on other sites

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