Jump to content

is it possible to push an object in a circle


VirtualKitten
 Share

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

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

Recommended Posts

Hi scriptwriters and scribblers

I am back with another question . 

Can i push an object in a circle with an angular impulse if so how do i set diameter of this circumference  as an angular vector

I have 

          target_relative_direction = pos - llGetPos();
          vector target_normalised_vector = llVecNorm(target_relative_direction);
          float push = 1;
          llPushObject( intruder_key, ((push/100.0)*2147483647)*target_normalised_vector, ZERO_VECTOR, FALSE );
   

 

Which pushes in a straight line on global co-ordinates . If I want to get a circle can i change ZERO_VECTOR to an angular rotation and how and what  and will this be in relation to diameter of circle pushed around ?

 

Thank you for looking :)

Link to comment
Share on other sites

i understand Since the arclength around a circle is given by the radius*angle (l = r*theta), you can convert an angular velocity w into linear velocity v by multiplying it by the radius r, so v = rw.

but not sure how to apply this to angular vector

 

Edited by VirtualKitten
Link to comment
Share on other sites

look up example scripts of llKeyFramedMotion for methods to plot points on the circumference of a circle

then a way is use a timer event to push the agent toward the next point in the sequence

a thing is that we can't rotate an agent with a script (agent can only rotate itself using its own input device/keyboard/mouse/etc) so it can look a bit naff as without agent input the agent will always be facing the same direction as it travels the circle

being able to rotate a agent with a script has often been requested but Linden haven't give it to us. Maybe one day hopefully

when we go down the path of pushing agents then we are on a journey to writing a impulse engine.  Argent Stonecutter's Flight Feather is an implementation of an agent impulse engine and I think it can still be gotten full permissions inworld on his parcel for some small amount of L$. I don't have a parcel SLURL for it but am pretty sure it can be found in inworld search

 

edit add:

i crossed out the bit about rotating not able to be done.  Wulfie showed me how llPushObject actually works when we apply/simulate angular impulse in code. Which is a pretty good thing to know about.  I ask Wulfie to post what he told me as I think is a good thing when we all can know about these things

 

Edited by Mollymews
Link to comment
Share on other sites

8 minutes ago, Profaitchikenz Haiku said:

There's always opencollar, that manages it :)

yes is true about the RLV engine.  I often tend to overlook things that 3rd party viewers can do.  My thoughts are always pretty much along what we can/can't do out of the Linden box

this said it would be pretty interesting to see an avatar impulse engine that incorporates the Z-rotational capability of RLV

Link to comment
Share on other sites

i have a script that pushes for magic . This works in a straight line without open collar or llKeyFrame

 

 link_message(integer sender, integer num, string str, key _key) {
         if (llGetAgentSize(intruder_key) == <0.0,0.0,0.0>) return;
         
         
          list tmp = llParseString2List(str,["|"],[]);
          string _name = llList2String(tmp,0); //llGetSubString(str,  0, llSubStringIndex(str,"|") - 1);
          vector pos = (vector)llList2String(tmp,1); 
          vector target_relative_direction;
          float push = .010;
          target_relative_direction = pos - llGetPos();
          vector target_normalised_vector = llVecNorm(target_relative_direction);
          string action = "Push";

          if (llGetAgentSize(_key) == <0.0,0.0,0.0>) return;
          llPushObject( _key, ((push/100.0)*2147483647)*target_normalised_vector,  link_message(integer sender, integer num, string str, key intruder_key) {
       
         
        

 

i tried      llPushObject( intruder_key, ((push/100.0)*2147483647)*target_normalised_vector, <0.3,0.3,0.0>, FALSE ); using <0.3,0.3,0.3> as the angular vector but it still travels the avatar in a straight line . I don't understand these angular pushes  can anyone sagest how you get an angular vector that pushes in a circle 

Link to comment
Share on other sites

we have to plot points on the circumference of circle. Then at each plotted point we apply impulse toward the next point, either in a loop or using a timer

at the moment your script is only applying impulse one time, when it needs to be done more than once, if the avatar is to move in a circle

 

 

Link to comment
Share on other sites

  • 1 month later...

Well i had some help from my college and we think the calculations are correct but this still doesn't get you in a circle. The calculations are correct but it pushes in a straight line its not perfect as it has an infinite loop  for testing. I am sure someone cleaver out there can say why it doesn't and how to get it going ? Thanks Tenso for your help with this :)

rotation rot3ToQuat(vector deg) {
    return(llEuler2Rot(deg*DEG_TO_RAD));
}
default
{
    state_entry()
    {
        
    }

    touch_start(integer total_number)
    {
            
            llMessageLinked(LINK_THIS,0,(string)llGetDisplayName(llDetectedKey(0)),llDetectedKey(0));
    }
    link_message(integer sender, integer num, string str, key intruder_key) {
         if (llGetAgentSize(intruder_key) == <0.0,0.0,0.0>) return;
         
         
          list tmp = llParseString2List(str,["|"],[]);
          string intruder_name = llList2String(tmp,0); //llGetSubString(str,  0, llSubStringIndex(str,"|") - 1);
          vector pos = (vector)llList2String(tmp,1); 
          vector target_relative_direction;
          float push = .010;
          target_relative_direction = pos - llGetPos();
          vector target_normalised_vector = llVecNorm(target_relative_direction);
          string action = "Push";
          llOwnerSay((string)target_normalised_vector+", and llGetPos"+(string)target_relative_direction);
          llPushObject( intruder_key, ((push/100.0)*2147483647)*target_normalised_vector, <0.0,0.0,0.0>, FALSE );
          // push away from box .3 to make box a centre then we have a diameter of .3 
          // we know we want to move around the cirumferance so we need and angle of movement and
          // to get oposite sin (theta)  = opposite / hypotinuse or diameter.
          // new movement 
        float  iv     = 10.0;        // interval in degrees each cycle
        vector iRot3d = ZERO_VECTOR; // Starting rotation in degrees XYZ.
        vector origin = llGetPos();  // Take this to be the circle origin, for the sake of example.
        vector ipos;
        rotation irot;
        while(1) {
            iRot3d.z += iv;
            if(iRot3d.z >= 360.0) {iRot3d.z = 0.0; return;}
            
            // for demo purposes only.
            llSetText((string)iRot3d,<1.0,1.0,1.0>,1.0);
            float magnitude = .1;
            irot = llEuler2Rot(iRot3d*DEG_TO_RAD);
            ipos = llGetPos()+(<0.3,0.0,0.0>*irot);
            vector  iForceVec =  <magnitude,0.0,0.0>*rot3ToQuat(<0.0,0.0,iRot3d.z-90.0>);
            llPushObject( intruder_key,iForceVec,<0.0,0.0,0.0>, FALSE );
            //llSetLinkPrimitiveParamsFast(0,[PRIM_POSITION,ipos]);
        }
          
         
    }
}

 

Link to comment
Share on other sites

rotation rot3ToQuat(vector deg) {
    return(llEuler2Rot(deg*DEG_TO_RAD));
}

default
{
    state_entry()
    {
        float  iv     = 10.0;        // interval in degrees each cycle
        float  magnitude = 155.0;
        vector i3rot = ZERO_VECTOR;  // Starting rotation in degrees XYZ.
        vector origin = llGetPos();  // Take this to be the circle origin, for the sake of example.
        vector iForceVec;
        while(1) {
            i3rot.z += iv;
            if(i3rot.z >= 360.0) i3rot.z = 0.0;
                        
            iForceVec = <magnitude,0.0,0.0>*rot3ToQuat(i3rot-<0.0,0.0,90.0>);
            
            // for demo purposes only.
            llSetText((string)i3rot 
                + "\nForce: " + (string)iForceVec
                + "\nMag: " + (string)llVecMag(iForceVec),<1.0,1.0,1.0>,1.0);
           llPushObject((key)"my key",iForceVec,<0.0,0.0,0.0>,FALSE);
            llSleep(1.0);
        }
        
    }

 

And it shows magnitude fall

Edited by VirtualKitten
Link to comment
Share on other sites

@Andrew LindenThe PushObject api is very odd in its behavior I was told by my Collège that this system was good enough to push a person in LSL . It seems to manifest odd behavior . To Observe  this you must remove huds . Once removed the activation can be a touch or a collision I used the latter.   as below in code. The result was to use  alot of energy in one mass to move you away . I expected this but the continual call to PushObject did not use the same magnitude as the original even though it was still applied. It seems that the only force added to this component is a walking direction force . If this is added to the  push by way of moving the avatar it pushes with the correct energy to complete a circle . I hve only looked at push Object so far  and am aware other API. if I am distant from the collided object why does my walking affect this api and running code . If the same magnitude is being supplied surely this should be evident . The havoc code talkes about what force is available to the push surely this is a combination of the magnitude . I have not tried  llSetForce( or  llApplyImpulse( vector momentum, integer local ) and llSetForceAndTorque( vector force, vector torque, integer local ); which need llSetStatus(STATUS_PHYSICS, TRUE);  I can post a video of this if it helps however i am pretty sure with this snippet you can see this for yourself. I would be grateful of any help or clarity  you can give. Thank you D.

Code:

rotation rot3ToQuat(vector deg) {
    return(llEuler2Rot(deg*DEG_TO_RAD));
}

default
{
    collision_start(integer num_detected)
    {
        integer count= 360;
        float  iv     = 20.0;        // interval in degrees each cycle
        float  magnitude = 255.0;
        vector i3rot = ZERO_VECTOR;  // Starting rotation in degrees XYZ.
        vector origin = llGetPos();  // Take this to be the circle origin, for the sake of example.
        vector iForceVec;
        while(count--) {
            i3rot.z += iv;
            if(i3rot.z >= 360.0) i3rot.z = 0.0;
                        
            iForceVec = <magnitude,0.0,0.0>*rot3ToQuat(i3rot-<0.0,0.0,90.0>);
            
            // for demo purposes only.
            llSetText((string)i3rot 
                + "\nForce: " + (string)iForceVec
                + "\nMag: " + (string)llVecMag(iForceVec),<1.0,1.0,1.0>,1.0);
           llPushObject(llDetectedKey(0),iForceVec,<0.0,0.0,0.0>,TRUE);
            llSleep(.2);
        }
        
    }
}

Link to comment
Share on other sites

Thanks @Mollymewsthat's quite interesting however it talks about energy, the object loses energyenergy as the energy is reduced by llPushObject . This makes no sense as the magnitude of the force is applied into llPushObject,  as I said the the llSetForce( or  llApplyImpulse( and llSetForceAndTorque(  might be of use but why does walking  the avatar away from the object in the script in it magnify this energy into the system. I would expect repeated calls of llPushObject(llDetectedKey(0),iForceVec,<0.0,0.0,0.0>,TRUE); to force the energy onto the detected key . I understand this may loose energy  but why when an initial force unrealistically to the push detected key away then when  the detected key walk away  why does it apply this new  energy force in the circle, which  I was trying to exert force in the first place but some meters away  because my avatar introduced different energy of walking in an entirely separate area? Is this supposed to be intentionally as it looks like the force of energy drop of is to fast . Is there anything to control this energy drop of curve please?

Thanks Denise

Link to comment
Share on other sites

the idea behind LSL energy accords with the concept that a LSL physical object is not a perpetual motion engine

it consumes energy, which in the LSL case replenishes at a rate of  200 / mass units of energy per second. Where 1.0 is notionally 200 units and 0.0 is none. Basically the greater the mass the longer it takes to replenish to 1.0. An object that has more mass consumes more energy to travel the same distance as an object with less mass. As an object consumes energy then the slower it will travel. All the way down to energy = 0.0, at which point it will stop

mass being the result of llGetMass()

when we don't factor energy/mass into our calculations then we are assuming that physical objects are perpetual motion machines when they are not, and while we assume this then have difficulty reconciling what is observably happening on our screen

not that this assumption is bad per se. It is tho the assumption that most people have when first introduced to LSL physics. Which we typically learn to unassume as we get further into it

  • Like 1
Link to comment
Share on other sites

 

@MollymewsYou seem to refer to conservation of momentum not not a perpetual motion engine.

I understood you informed me llGetMass() the mass of the box is 1.25 and is a cube 0.5x0.5x05 in size  :) This is pretty normal for a test .

@Andrew Linden I hope you do not mind me saying  However my answer is not being answered . I wanted to know why the magnitude of force was being given straight in first push . Then every time it was applying the same force this force diminished unrealistically. You can see from the video that the forces are changing just as first push is used  with one big push then nothing that moves . If you begin to walk and stop this same force moves you in desired circle  which it did not do before pushing in one direction even though the push is rotational  . Is it because its not being given an impulse vector, is this required  or is there someway to upload more energy to the system?

I would expect the angular force to do what it should alone  I cant see what mass will do other than multiply the force . which is not being applied correctly . each cycle of the while loop changes the bearing why is this not happening with same force as first one .

Edited by VirtualKitten
to add name correction
Link to comment
Share on other sites

@Andrew Linden

Ok I have had another look at this and put llGetEnergy() into script to determine if the system has full energy which it does 1.0  at all times so I still do not understand what is happening. Some experimentation has determined that :

1) this first push is annoying it puts my avatar out of range and is unhelpful.
2)  My walking is not putting in more energy par ce! As I get close to the proximity to the box the forces start affecting my avatar to make it rotate in a circle.
3) As no force is being depleted here why is there this initial un realistic force  and why are my other pushes not doing same thing if the energy stays at 1.0?
4) There is no fall of of energy then so please can you explain this ?

Video 

showing initial un proportionate force  and the no effect on Energy continues at 1

https://youtu.be/AODz6eTSumU

 

Code:

rotation rot3ToQuat(vector deg) {
    return(llEuler2Rot(deg*DEG_TO_RAD));
}

default
{
    collision_start(integer num_detected)
    {
        integer count= 360;
        float  iv     = 20.0;        // interval in degrees each cycle
        float  magnitude = 255.0;
        vector i3rot = ZERO_VECTOR;  // Starting rotation in degrees XYZ.
        vector origin = llGetPos();  // Take this to be the circle origin, for the sake of example.
        vector iForceVec;
        float ObjMass = llGetObjectMass( llDetectedKey(0));
        float boxMass = llGetMass();
        while(count--) {
            i3rot.z += iv;
            if(i3rot.z >= 360.0) i3rot.z = 0.0;
                        
            iForceVec = <magnitude,0.0,0.0>*rot3ToQuat(i3rot-<0.0,0.0,90.0>);
             llSetForceAndTorque(iForceVec,<0.0,0.0,0.0>,TRUE);
            // for demo purposes only.
            llSetText((string)i3rot 
                + "\nForce: " + (string)iForceVec
                + "\n Energy: " + (string) llGetEnergy()
                +"\n Mass: "+(string)llGetMass()+  " lindogram = 100kg."
                + "\nMag: " + (string)llVecMag(iForceVec),<1.0,1.0,1.0>,1.0);
           llPushObject(llDetectedKey(0),iForceVec,<0.0,0.0,0.0>,TRUE);
            llSleep(.2);
        }
         llSetText("",<1.0,1.0,1.0>,1.0);
    }
}

Edited by VirtualKitten
Link to comment
Share on other sites

Ok I have had another look at this and I made a  bigger box made of plastic  1.77m3 this still gives a ridiculous first push as you can see from video its un realistic and even the script cannot compensate for it I am hoping for some help? s if I can loose the initial kick i can get what I am trying to do working . 

 

Video

https://youtu.be/LAJ6ZIaXHqE

 

Code :

rotation rot3ToQuat(vector deg) {
    return(llEuler2Rot(deg*DEG_TO_RAD));
}

default
{
    state_entry()
    {
        llSetText("",<1.0,1.0,1.0>,1.0);
    }
    collision_start(integer num_detected)
    {
         float  iv     = 20.0; 
         integer count= (360/(integer)iv)+(integer)iv;
              // interval in degrees each cycle
        float  magnitude = 5.0;
        vector i3rot = ZERO_VECTOR;  // Starting rotation in degrees XYZ.
        vector origin = llGetPos();  // Take this to be the circle origin, for the sake of example.
        vector iForceVec;
        float ObjMass = llGetObjectMass( llDetectedKey(0));
        float boxMass = llGetMass();
        while(count--) {
            i3rot.z += iv;
            if(i3rot.z >= 360.0) i3rot.z = 0.0;
                        
            iForceVec = <magnitude,0.0,0.0>*rot3ToQuat(i3rot-<0.0,0.0,90.0>);
            llSetForceAndTorque(<0.0,0.0,0.0>,<0.0,0.0,0.0>,TRUE);
            // for demo purposes only.
            llSetText((string)i3rot 
                + "\nForce: " + (string)iForceVec
                + "\n Energy: " + (string) llGetEnergy()
                +"\n Mass: "+(string)llGetMass()+  " lindogram = 100kg."
                + "\nMag: " + (string)llVecMag(iForceVec),<1.0,1.0,1.0>,1.0);
           llPushObject(llDetectedKey(0),iForceVec,<0.0,0.0,0.0>,TRUE);
            llSleep(.2);
            if(count <365) magnitude = 255.0;
        }
         llSetText("",<1.0,1.0,1.0>,1.0);
    }
}

Link to comment
Share on other sites

10 minutes ago, VirtualKitten said:

Wolfie what am i doing wrong then can i have your size of your item please you are walking around and the items mass and substance feature settings please?

I'm not sure what you're doing wrong, since I haven't read your script. Here's the object though, it's a default prim with changed size:
c982d6dcfa.png69c598acd9.png

10 minutes ago, VirtualKitten said:

And your code please?

Not to you, not from me. I've wasted too much time trying to help you. I'm only here to confirm that it can be done, since this thread is active again since August.

Edited by Wulfie Reanimator
Link to comment
Share on other sites

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