Jump to content

Billboard


Tattooshop
 Share

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

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

Recommended Posts

Hello! 🖐️:)


I'm trying to make such a billboard, you've probably all seen one where several prismatic objects with parts of the texture rotate at an angle of 120 degrees (except the root) with a slight delay, one after the other at a certain interval. Wondering how this can be done?
(Creating the model itself everything is clear.)

Thank's for any help!

fdc99ae521adc6ea45bd0ca6dfa9582a.png

Link to comment
Share on other sites

just guessing, but mebbe something like...

one texture offset 7 different ways, or 7 textures.

a link message of fwd or back, and different delays for rotating each child depending on the direction.

hmmm...

Edited by Xiija
  • Like 1
Link to comment
Share on other sites

Since each element moves in sequence rather than simultaneously, I imagine you'll want a loop to iterate over each prism, setting the local rotation via llSetLinkPrimitiveParams. You could have a single global variable to keep track of what general orientation the parts should be at (120, 240, 360) and apply it to each element - then update it after finishing the loop. Place all that in a timer with an interval of however long you want the sign to display a single completed side.

If you want the elements to move more slowly, then you'll have to make multiple calls to llSetLinkPrimitiveParams to rotate each element in smaller steps one each loop iteration. Using the regular llSetLinkPrimitiveParams instead of the fast variant my be preferable due to the built in delay.

Lastly, if you carefully build the model such that each element is linked in ascending sequence, then it simplifies the loop logic, as you can use the same loop-control variable as the link number reference.

Edited by Fenix Eldritch
  • Thanks 1
Link to comment
Share on other sites

6 minutes ago, Xiija said:

just guessing, but mebbe something like...

one texture offset 7 different ways, or 7 textures.

a link message of fwd or back, and different delays for rotating each child depending on the direction.

hmmm...

Thank you! So I've started with single linked* prim to test... but it doesn't move :D

default
{

    touch_start(integer total_number)
    {
        llSetTimerEvent(1.0);
    }
    
    timer()
    {
        llSetLinkPrimitiveParamsFast(2, [PRIM_ROT_LOCAL, llEuler2Rot( <0.0, 0.0, 120.0> * DEG_TO_RAD ) * llGetLocalRot()]);
    }
}

 

Edited by Tattooshop
Link to comment
Share on other sites

11 minutes ago, Fenix Eldritch said:

Since each element moves in sequence rather than simultaneously, I imagine you'll want a loop to iterate over each prism, setting the local rotation via llSetLinkPrimitiveParams. You could have a single global variable to keep track of what general orientation the parts should be at (120, 240, 360) and update it after finishing the loop. Place all that in a timer with an interval of however long you want the sign to display a single side.

If you want the elements to move more slowly, then you'll have to make multiple calls to llSetLinkPrimitiveParams to rotate each element in smaller steps one each loop iteration. Using the regular llSetLinkPrimitiveParams instead of the fast variant my be preferable due to the built in delay.

Lastly, if you carefully build the model such that each element is linked in ascending sequence, then it simplifies the loop logic, as you can use the same loop-control variable as the link number reference.

Thank you! Here is what I have at the moment. Looks, of course, a little strange.

I have an idea, but I don't know how to do it - add a list of primitives to rotate here and apply parameters to each item of the list? If it makes sense :)

    touch_start(integer total_number)
    {
        llSetTimerEvent(15.0); // Full cycle
    }
    
    timer()
    {
        llSetLinkPrimitiveParams(2, [PRIM_ROT_LOCAL, llEuler2Rot( <0.0, 0.0, 120.0> * DEG_TO_RAD ) * llGetLocalRot()]);
        llSleep(5); // Per image
        llSetLinkPrimitiveParams(2, [PRIM_ROT_LOCAL, llEuler2Rot( <0.0, 0.0, 240.0> * DEG_TO_RAD ) * llGetLocalRot()]);
        llSleep(5);
        llSetLinkPrimitiveParams(2, [PRIM_ROT_LOCAL, llEuler2Rot( <0.0, 0.0, 360.0> * DEG_TO_RAD ) * llGetLocalRot()]);
        llSleep(5);
    }

 

Link to comment
Share on other sites

25 minutes ago, Tattooshop said:

I think the list needs to be squeezed in here   :D

llSetLinkPrimitiveParams(LIST?, [PRIM_ROT_LOCAL, llEuler2Rot( <0.0, 0.0, 120.0> * DEG_TO_RAD ) * llGetLocalRot()]);

and how to make a delay between the elements, because this way they will rotate at the same time ...

There will be about 20 such elements, so the list is really needed here (?) otherwise the script will be just gigantic!

Edited by Tattooshop
Link to comment
Share on other sites

3 hours ago, Tattooshop said:

I think the list needs to be squeezed in here   :D

llSetLinkPrimitiveParams(LIST?, [PRIM_ROT_LOCAL, llEuler2Rot( <0.0, 0.0, 120.0> * DEG_TO_RAD ) * llGetLocalRot()]);

That is not how the function works. Please see the wiki page on how to properly use the function. The first parameter is an integer and as such, can only target a single prim or specific sets as allowed by the special LINK_* constants. If you want to target a subset of prims within the linkset with the same function call, you wold use PRIM_LINK_TARGET within the parameters list.

But that's not what you appear to want to do. As said earlier, you indicated you want to move each element one at a time. Therefore it makes more sense to use a single call to llSetLinkPrimitiveParams, targeting just one prim. You would place the function call inside something like a for-loop and use the loop control variable as the input for which link number to target.

Also, you don't want to complete a full 360 in the same timer event. The way I understand it is that you begin with all elements at 0 rotation. This effectively makes the sign showing one complete image. You start the timer for however long you want that image to remain (15 seconds from you last example). Then when the timer event happens, you update the rotation variable to 120 and being your for-loop to apply that new rotation variable to all elements - again one at a time, via the loop. So the loop will start at 2 and go for 20 iterations (just as an example, assuming your sign consists of the root plus the 20 elements and nothing else). Each iteration will just target link number X. After the loop completes, the timer event is over and the script idles until 15 seconds elapses and the timer starts again. As before, it updates the global rotation variable to 360, and then performs that loop again, this time updating each element to the new rotation. And so on, and so on.

You should also check in the timer to see if the global rotation variable is greater than or equal to 360 and if so, set it back to 0.

Does this make sense?

Edited by Fenix Eldritch
minor clarification and typos
  • Like 1
Link to comment
Share on other sites

My 2 cents:

I'm a bit too disillusioned to help you with the loop logic, but to rotate a linked object 90 degrees about its local z-axis:

rotate_linked_object(integer link,vector axis,float angle)
{ // angle in specified in degrees for demonstration.
  // personally I always try to keep things in radians if I can help it though.
  rotation apply = llAxisAngle2Rot(axis,DEG_TO_RAD*angle);
  rotation local = llList2Rot(llGetLinkPrimitiveParams(link,[PRIM_ROT_LOCAL]),0);
  // note that PRIM_ROTATION is a bit broken for linked prims, so be sure to use PRIM_ROT_LOCAL.
  llSetLinkPrimitiveParamsFast(link,
  [  PRIM_ROT_LOCAL, apply*local // left multiply for a rotation in the local coordinate space of the prim,
   	// if you want to rotate about the root's coordinate system, use local*apply
  ]);
}

default
{
  touch_start(integer i)
  {
    // rotate link 2 90 degrees about z-axis:
    rotate_linked_object(2,<0,0,1>,90);
  }
}

(untested)

  • Thanks 1
Link to comment
Share on other sites

@Tattooshop

here is an example for the rotation bit,  changes all but the root...

. dbe5aae5542ccde25d0f1e750bce1fe4.gif

integer tog;
rotation rot_90;

update()
{  integer prims = llGetObjectPrimCount( llGetKey() );
   integer x = 2;
   for( ; x <= prims; ++x)
   {    vector ang = <0,0,90>; 
        vector rad = ang * DEG_TO_RAD;
        rot_90 = llEuler2Rot(rad); 
        
        list y =  llGetLinkPrimitiveParams( x, [PRIM_ROT_LOCAL]);
        rotation currRot = llList2Rot( y,0);
        
        llSetLinkPrimitiveParamsFast( x , [
          PRIM_ROT_LOCAL, currRot * rot_90  ]);
        llSleep(0.25);               
   }             
}
default
{
    state_entry()
    {  
    }
    touch_start( integer num)
    {
        if( tog = !tog)
        { llSetTimerEvent(0.1); llOwnerSay("ON");
        }
        else
        {  llSetTimerEvent(0.0);  llOwnerSay("OFF");
        }
    }
    timer()
    { llSetTimerEvent(10.0);  update();
    }
}

 

  • Like 2
  • Thanks 1
Link to comment
Share on other sites

13 hours ago, Xiija said:

@Tattooshop

here is an example for the rotation bit,  changes all but the root...

. dbe5aae5542ccde25d0f1e750bce1fe4.gif

integer tog;
rotation rot_90;

update()
{  integer prims = llGetObjectPrimCount( llGetKey() );
   integer x = 2;
   for( ; x <= prims; ++x)
   {    vector ang = <0,0,90>; 
        vector rad = ang * DEG_TO_RAD;
        rot_90 = llEuler2Rot(rad); 
        
        list y =  llGetLinkPrimitiveParams( x, [PRIM_ROT_LOCAL]);
        rotation currRot = llList2Rot( y,0);
        
        llSetLinkPrimitiveParamsFast( x , [
          PRIM_ROT_LOCAL, currRot * rot_90  ]);
        llSleep(0.25);               
   }             
}
default
{
    state_entry()
    {  
    }
    touch_start( integer num)
    {
        if( tog = !tog)
        { llSetTimerEvent(0.1); llOwnerSay("ON");
        }
        else
        {  llSetTimerEvent(0.0);  llOwnerSay("OFF");
        }
    }
    timer()
    { llSetTimerEvent(10.0);  update();
    }
}

 

Thank you so much!!! You are genius!

This is perhaps the most satisfying thing I've seen in SL! As for me, you did a real feat, the script is wonderful!

It is already a pleasure to just watch them turn over one by one. Thank you! :)👍

 

ezgif-4-592892abbeba.gif

  • Like 1
Link to comment
Share on other sites

A comment about the geometry:

In SL you can rotate squares put next to each other of course, but if it's supposed to work like a RL board you need triangles with 3x60°
The op's example shows triangles with 1x90° and 2x45° - that will not work.
It's necessary to mesh the triangle elements with the axis in the center. It's probably possible to bend a prim but the axis will not be in the center then and the rotations would be very painful. 🙃
 

  • Thanks 1
Link to comment
Share on other sites

3 minutes ago, Nova Convair said:

It's probably possible to bend a prim but the axis will not be in the center then and the rotations would be very painful. 🙃

Um, you do know that prisms are a basic prim type, no? A perfect equilateral triangle cross-section is the default with its axis in the center.

Edited by Quistess Alpha
  • Thanks 1
Link to comment
Share on other sites

1 minute ago, Quistess Alpha said:

Um, you do know that prisms are a basic prim type, no? A perfect equilateral triangle is the default with its axis in the center.

Show me one - 3x60° triangle - rotation axes in the center.
I will have a look when I get on later. Although I have never seen one I know there are shapes I've never tried.

  • Thanks 1
Link to comment
Share on other sites

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