Jump to content

Sabrina Tamerlane

Resident
  • Posts

    130
  • Joined

  • Last visited

Posts posted by Sabrina Tamerlane

  1.  

    9 hours ago, kali Wylder said:

    . I am not into BDSM, so I don't have much use for RLV anymore.

    Sometimes when you take a pose your feet don't touch the ground. With RLV you can adjust your height. I am using it in my AO, it only takes a few lines of code, and yes I have found this idea in Open Collar.

  2. There was another typo in the script! Here is the fixed version:

     

    integer link_axis; 
    integer link_box1; 
    integer link_box2;
    float rotClickAngle = 15;
    
    rotation rotRoot2Axis;
    vector posRoot2Axis;
    vector axisAxis;
    vector offsetBody_inRootFrame;
    vector offsetBeam_inRootFrame;
    
    rotation rotRoot2Body;
    vector posRoot2Body;
        
    rotation rotRoot2Beam;
    vector posRoot2Beam;
    
    integer listener;
    integer chan = -55555;
    
    do_rotate(float angle){
        rotation rotClick_inRootFrame = llAxisAngle2Rot(axisAxis, angle *DEG_TO_RAD);
        
        // for body.
        rotation newrotRoot2Body = rotRoot2Body * rotClick_inRootFrame;
        vector newoffsetBody_inRootFrame = offsetBody_inRootFrame* rotClick_inRootFrame;
           //Beam.
        rotation newrotRoot2Beam = rotRoot2Beam * rotClick_inRootFrame;
        vector newoffsetBeam_inRootFrame = offsetBeam_inRootFrame * rotClick_inRootFrame;
        
        llSetLinkPrimitiveParamsFast(1,[
             PRIM_LINK_TARGET,link_box1,PRIM_ROT_LOCAL,newrotRoot2Body,
             PRIM_LINK_TARGET, link_box2,PRIM_ROT_LOCAL, newrotRoot2Beam,PRIM_POS_LOCAL, posRoot2Axis + newoffsetBeam_inRootFrame]);
    } 
    
    integer rotating = FALSE;
    
    integer link_by_name(string linkName) {
        integer N=llGetNumberOfPrims();
        integer i;
        for(i=1;i<=N;i++) {
            if (llGetLinkName(i)==linkName) {
                llOwnerSay(linkName + " : " + (string)i);
                return i;
            }
        }
        llOwnerSay(linkName + " not found");
        return -99;
    }
    
    
    reset()
    {
        llSetLinkPrimitiveParamsFast(1,[
         PRIM_LINK_TARGET,link_box1,PRIM_ROT_LOCAL,rotRoot2Body,PRIM_POS_LOCAL, posRoot2Body,
         PRIM_LINK_TARGET, link_box2,PRIM_ROT_LOCAL, rotRoot2Beam,PRIM_POS_LOCAL, posRoot2Beam]);
    
    }
    
    default
    {
        state_entry()
        {
            
            link_axis = link_by_name("axis");
            link_box1 = link_by_name("box1");
            link_box2 = link_by_name("box2");      
            
            list L = llGetLinkPrimitiveParams(link_axis,[PRIM_ROT_LOCAL, PRIM_POS_LOCAL]);
            rotRoot2Axis = llList2Rot(L,0);
            posRoot2Axis = llList2Vector(L,1);
            axisAxis=<0,0,1>*rotRoot2Axis;
    
            L = llGetLinkPrimitiveParams(link_box1,[PRIM_ROT_LOCAL, PRIM_POS_LOCAL]);
            rotRoot2Body = llList2Rot(L,0);
            posRoot2Body = llList2Vector(L,1);
        
            L = llGetLinkPrimitiveParams(link_box2,[PRIM_ROT_LOCAL, PRIM_POS_LOCAL]);
            rotRoot2Beam = llList2Rot(L,0);
            posRoot2Beam = llList2Vector(L,1);
            offsetBody_inRootFrame = posRoot2Body - posRoot2Axis;
            offsetBeam_inRootFrame = posRoot2Beam - posRoot2Axis;
            
            listener = llListen(chan, "", NULL_KEY, "") ;
            llTextBox(llGetOwner(), "What angle would you like?", chan) ;
            
        
    
        }
    
        listen(integer chan, string name, key id, string text)
        {
            llListenRemove(listener) ;
            float angle = (float)text ;
            llOwnerSay("angle = " + (string)angle) ;
            do_rotate(angle) ;
            llOwnerSay("Done. Touch me for movement.");
        }
    
        touch_start(integer total_number)
        {
            llOwnerSay("this is link "+ (string)llDetectedLinkNumber(total_number)) ;
            if (!rotating) {
                rotating = TRUE ;     
                reset() ;   
                llSetTimerEvent(1.0) ;
            }
            else {
                rotating = FALSE ;        
                llSetTimerEvent(0.0) ;
                
                reset() ;
            }            
        }
        
        timer() 
        {
            rotClickAngle += 5 ;
            if (rotClickAngle > 359.0) {
                rotClickAngle = 0;
            }
            
            do_rotate(rotClickAngle) ;
        }    
    }

     

  3. 22 minutes ago, VirtualKitten said:

    Please NOTE!  It didn't work your version Sabrina  as I stated earlier!  It rotated the box one up on its center and the second box  about its center too. This is not  the same my script does  (see https://gyazo.com/055061a745dd16534dad968c9a6943f9) is what mine does Your

     

     

    https://gyazo.com/aedaf265a113c9bdc61b79e1ab9c7f83

    As I said earlier, if it does not work for you, double check the prim numbers at the start of the script :)

  4. 1 hour ago, VirtualKitten said:

      This version also increments and does not set an absolute angle and is incremental like mine :(

     

     

    The increment is in the timer, you can set any angle that you wish. If it does not work with your prims, make sure to set the right numbers.

     

    For example, if you would like to rotate 45° then you would call:

    do_rotate(45.0);
  5. integer link_axis = 3; // set this to real prim number
    integer link_box1 = 2; // set this to real prim number
    integer link_box2 = 4; // set this to real prim number
    float rotClickAngle = 5;
    
    rotation rotRoot2Axis;
    vector posRoot2Axis;
    vector axisAxis;
    
    rotation rotRoot2Body;
    vector posRoot2Body;
        
    rotation rotRoot2Beam;
    vector posRoot2Beam;
    
    
    do_rotate(float angle){
        rotation rotClick_inRootFrame = llAxisAngle2Rot(axisAxis, rotClickAngle *DEG_TO_RAD);
        // rotation rotClick_inRootFrame = llEuler2Rot(<0, 0, angle> *DEG_TO_RAD);
        
        // for body.
        rotation newrotRoot2Body = rotRoot2Body * rotClick_inRootFrame;
        vector offsetBody_inRootFrame = posRoot2Body - posRoot2Axis;
        vector newoffsetBody_inRootFrame = offsetBody_inRootFrame* rotClick_inRootFrame;
           //Beam.
        rotation newrotRoot2Beam = rotRoot2Body * rotClick_inRootFrame;
        vector offsetBeam_inRootFrame = posRoot2Beam - posRoot2Axis;
        vector newoffsetBeam_inRootFrame = offsetBeam_inRootFrame * rotClick_inRootFrame;
        
        llSetLinkPrimitiveParamsFast(1,[
             PRIM_LINK_TARGET,link_box1,PRIM_ROT_LOCAL,newrotRoot2Body,PRIM_POS_LOCAL, posRoot2Axis + newoffsetBody_inRootFrame,
             PRIM_LINK_TARGET, link_box2,PRIM_ROT_LOCAL,llEuler2Rot(<-90,0,0>*DEG_TO_RAD)*newrotRoot2Beam,PRIM_POS_LOCAL, posRoot2Axis + newoffsetBeam_inRootFrame]);
    } 
    
    integer rotating = FALSE;
    
    default
    {
        state_entry()
        {
        list L = llGetLinkPrimitiveParams(link_axis,[PRIM_ROT_LOCAL, PRIM_POS_LOCAL]);
        rotRoot2Axis = llList2Rot(L,0);
        posRoot2Axis = llList2Vector(L,1);
        axisAxis=<0,0,1>*rotRoot2Axis;
    
        L = llGetLinkPrimitiveParams(link_box1,[PRIM_ROT_LOCAL, PRIM_POS_LOCAL]);
        rotRoot2Body = llList2Rot(L,0);
        posRoot2Body = llList2Vector(L,1);
        
        L = llGetLinkPrimitiveParams(link_box2,[PRIM_ROT_LOCAL, PRIM_POS_LOCAL]);
        rotRoot2Beam = llList2Rot(L,0);
        posRoot2Beam = llList2Vector(L,1);
    
        }
    
        touch_start(integer total_number)
        {
            if (!rotating) {
                rotating = TRUE ;        
                llSetTimerEvent(1.0) ;
            }
            else {
                rotating = FALSE ;        
                llSetTimerEvent(0.0) ;
            }
        }
        
        timer() 
        {
            rotClickAngle += 5 ;
            if (rotClickAngle > 359.0) {
                rotClickAngle = 0;
            }
            
            do_rotate(rotClickAngle) ;
        }    
    }

    They need to be in state_entry so that you would rotate from the original position, and not increment it.

  6. Lines like these need to go away from the function and put in state_entry for example, and you need to make the rotation and vector globals as I explained before.

      list L = llGetLinkPrimitiveParams(link_axis,[PRIM_ROT_LOCAL, PRIM_POS_LOCAL]);
        rotation rotRoot2Axis = llList2Rot(L,0);
        vector posRoot2Axis = llList2Vector(L,1);

     

     

  7. I have made a mistake with llAxisAnglle2Rot and edited my answer... Yes, you can subtract a rotation with divide just like you add with multiply.

    You need to change your function do_rotate like this:

     

    do_rotate(float angle){
        rotation rotClick_inRootFrame = llAxisAngle2Rot(axisAxis, angle *DEG_TO_RAD);
        // for body.
        vector offsetBody_inRootFrame = posRoot2Body - posRoot2Axis;
        vector newoffsetBody_inRootFrame = offsetBody_inRootFrame* rotClick_inRootFrame;
           //Beam.
        vector offsetBeam_inRootFrame = posRoot2Beam - posRoot2Axis;
        vector newoffsetBeam_inRootFrame = offsetBeam_inRootFrame * rotClick_inRootFrame;
        
        llSetLinkPrimitiveParamsFast(1,[
             PRIM_LINK_TARGET,link_box1,PRIM_ROT_LOCAL,newrotRoot2Body,PRIM_POS_LOCAL, posRoot2Axis + newoffsetBody_inRootFrame,
             PRIM_LINK_TARGET, link_box2,PRIM_ROT_LOCAL,llEuler2Rot(<-90,0,0>*DEG_TO_RAD)*newrotRoot2Beam,PRIM_POS_LOCAL, posRoot2Axis + newoffsetBeam_inRootFrame]);
    }

    The missing variables should be made global as I explained before.

    I didn't test it so there may be errors, however this is the idea :)

  8. I was wrong about llAxisAngle2Rot, you need that one to get the correct rotation.

    Okay, rotations are very easy to understand when they are expressed in Euler angles (X, Y, Z) but they are very hard to compute that way. So we use quaternions instead that are very hard to understand but very easy to compute because you simply need to multiply quaternions to add rotations.

    So, for example, if you want to rotate 30° along z axis, you will first calculate the vector, so it is <0, 0, 1> * 30.0 * DEG_TO_RAD, because the angles are expressed in radians. And then you use llAxisAngle2Rot to convert this vector into a quaternion. You can also write <0, 0, 30.0> * DEG_TO_RAD.

    Now that you have this, lets call this q30z = llAxisAngle2Rot(<0, 0, 30> * DEG_TO_RAD), any rotation that you have you can make it rotate 30° along Z axis by multiplying it with q30z.

    You see that in your code you have:

      vector newoffsetBody_inRootFrame = offsetBody_inRootFrame* rotClick_inRootFrame;

    so if you want to rotate it 30° along z axis, you will use offsetBody_inRootFrame* q30t

    If you don't want to add a rotation, but instead rotate by a given amount, you will need to save the rotations at the start of the program then apply the rotations from that point:

      list L = llGetLinkPrimitiveParams(link_axis,[PRIM_ROT_LOCAL, PRIM_POS_LOCAL]);
        rotation rotRoot2Axis = llList2Rot(L,0);
        vector posRoot2Axis = llList2Vector(L,1);

    This has to be removed and put in state_entry. Make rotRoot2Axis and posRoot2Axis global.

     

      L = llGetLinkPrimitiveParams(link_box1,[PRIM_ROT_LOCAL, PRIM_POS_LOCAL]);
        rotation rotRoot2Body = llList2Rot(L,0);
        vector posRoot2Body = llList2Vector(L,1);

      L = llGetLinkPrimitiveParams(link_box2,[PRIM_ROT_LOCAL, PRIM_POS_LOCAL]);
        rotation rotRoot2Beam = llList2Rot(L,0);
        vector posRoot2Beam = llList2Vector(L,1);

    This too has to be made global.

     

     

  9. 3 hours ago, Profaitchikenz Haiku said:

    Interestingly, when I put a moving end event in Que's original script it was never triggered, you're getting it triggered by making discrete steps between his start and end position, and he's also saying a sleep is helping, it suggests that there needs to be enough time pause to actually detect the end of movement?

    I have noticed that if you pass KFM_CMD_STOP without a KFM_CMD_LOOP before then the moving end event will not be triggered.
     

  10. Does this fix your problem?

     

    float PERIOD = 4.0;
    float AMP = 0.1; 
    integer KFM_STEPS = 25;
    list kfmCommands;
    vector savePos;
    
    default
    {
        state_entry()
        {
            // set up KFM command list to bounce up and back
            float interval = (integer)((PERIOD / KFM_STEPS) * 45.0) / 45.0;
            float lastZ = llSin(0.0);
            integer step = 1;
            for (step = 1; step < KFM_STEPS; ++step)
            {
                float x = (TWO_PI * step) / KFM_STEPS;
                float newZ = AMP * llSin(x);
                kfmCommands += [ <0, 0, newZ - lastZ>, interval];
                lastZ = newZ;
            }
            savePos = llGetPos();
            llSetKeyframedMotion(kfmCommands, [KFM_DATA, KFM_TRANSLATION, KFM_MODE, KFM_LOOP]);
        }
        touch_start(integer num_detected)
        {
             llSetKeyframedMotion([], [KFM_COMMAND, KFM_CMD_STOP]);   // Doesn't help
        }
        moving_end()
        {
            vector atPos = llGetPos();
            llSetLinkPrimitiveParams(LINK_THIS, [PRIM_POSITION, savePos]);  // Restore position
            vector setPos = llGetPos();
            llOwnerSay((string)atPos.z+" --> "+(string)setPos.z);
            llSetKeyframedMotion(kfmCommands, [KFM_DATA, KFM_TRANSLATION, KFM_MODE, KFM_LOOP]);
        }
    }

     

    • Thanks 1
  11. On the wiki they say this:

     

    Quote

    for best results use moving_end to determine when the animation has ended and confirm the target position with llSetPos

    So, I think that if you reach moving_end you are at a known position. Alternatively, you can do llGetPos() to figure out what is the frame number and then make a new motion starting from that frame.

  12. If the names are stored in the script it is a memory hog. So, it can be very easy to do, but it can crash also very easily.

    Now if you are looking for a specific person like a dancer or host then it's different.

  13. 12 hours ago, meady212 said:

    I really wish that there was a scripting class in second life

     

    There are scripting classes in second life. I know for sure that you can join the HAPPY HIPPSTERS group and get lessons, but there is surely more than that.

    • Like 1
  14. You don't need to do that it is much simpler. First you need to create that function displayBoard and use the code provided by Xiija.

     

    displayBoard(list l)
    {
      integer x = 0;
        do
        { llMessageLinked(-1,DISPLAY_STRING, llList2String( l ,x),(string)x );
            x = x + 1;
        } while (x < 10); 
    }

    However that will cause 3 problems. The first is that you don't have 10 lines in that list. The second is that it won't be centered. And the third is that your title is missing.

    So, you need to modify the function to solve the 3 problems. To add your header you will use llListInsertList() and to center your text you will use Xiija's pad function.

    To solve the last issue you will need to find the size of the list with llGetListLength().

    So, to add the title you need to do this:

    displayBoard(list l)
    {
      integer x = 0;
      l = llListInsertList(l, pad("Second Life Status"), 0); 
      integer listSize = llGetListLength(l) ;
    
        do
        { 
           if (x<listSize)
           {                
                llMessageLinked(-1,DISPLAY_STRING, pad(llList2String( l ,x)),(string)x );
           }
           else {
                llMessageLinked(-1,DISPLAY_STRING, "",(string)x );
           }
            x = x + 1;
        } while (x < 10); 
    }

     

     

  15. Okay, have you figured out how long is a line on the board? And how many lines do you have? You will need to know this if you want to center that text.

    For the rest you can decide what is going on each line with a simple function. Since you already have a list you can choose to either modify it or you can just use it when you need it.

    The first step is to create a function displayBoard() at the top of your file, before the default state.

    So you will have to change your code like that:

                list lines = llParseString2List(gBuildText, ["\n"], []) ;
                displayBoard(lines) ;

    You can use this function as a starter:

    displayBoard(list l)
    {
        llMessageLinked(LINK_THIS,DISPLAY_STRING, "Let's display that board", "0");
    }

    You can also move the code you had to display the lines in the displayBoard function or start from scratch, it does not matter.

×
×
  • Create New...