Difference between revisions of "PhysicsLib"

From Second Life Wiki
Jump to navigation Jump to search
m (<lsl> tag to <source>)
 
(2 intermediate revisions by one other user not shown)
Line 1: Line 1:
{{LSL Header}}
{{LSL Header}}
== License ==
== Non-License ==
<lsl>
<source lang="lsl2">
//===================================================//
//===================================================//
//                Physics Library 0.2                //
//                Physics Library 0.2                //
//          "May 6 2009", "11:00:00 GMT-0"          //
//          "May 6 2009", "11:00:00 GMT-0"          //
//     Copyright (C) 2009, Nexii Malthus (cc-by)    //
//                 By Nexii Malthus                 //
//   http://creativecommons.org/licenses/by/3.0/    //
//                   Public Domain                  //
//===================================================//
//===================================================//
</lsl>
</source>


== Trajectory Functions ==
== Trajectory Functions ==


=== Time Of Flight ===
=== Time Of Flight ===
<lsl>
<source lang="lsl2">
float pTimeOfFlight(float Dist, float Angle, float Height, float Vel, float Gravity ){// UNTESTED!
float pTimeOfFlight(float Dist, float Angle, float Height, float Vel, float Gravity ){// UNTESTED!
     float cos = llCos(Angle); float sin = llSin(Angle);
     float cos = llCos(Angle); float sin = llSin(Angle);
     return ( Dist / Vel*cos ) * ( ( llPow(Vel*sin,2) + 2 * Gravity * Height ) / Gravity);}
     return ( Dist / Vel*cos ) * ( ( llPow(Vel*sin,2) + 2 * Gravity * Height ) / Gravity);}
</lsl>
</source>
Experimental untested function, supposed to be used together with a device to prevent the familiar avatar 'splat', to calculate when a falling object hits Z=0, based on the (relative) float Height.
Experimental untested function, supposed to be used together with a device to prevent the familiar avatar 'splat', to calculate when a falling object hits Z=0, based on the (relative) float Height.


=== Angle of Reach ===
=== Angle of Reach ===
<lsl>
<source lang="lsl2">
rotation pAngleOfReach(vector cPos,vector tPos,float V,float G,integer cAng){
rotation pAngleOfReach(vector cPos,vector tPos,float V,float G,integer cAng){
     float Theta;float D = llVecDist(cPos,tPos);float D2 = D*D;
     float Theta;
     float V2 = V*V;float V4 = V*V*V*V;
     float V2 = V*V;float V4 = V*V*V*V;
     float X = llVecDist(<cPos.x,cPos.y,0>,<tPos.x,tPos.y,0>);float X2 = X*X;
     float X = llVecDist(<cPos.x,cPos.y,0>,<tPos.x,tPos.y,0>);float X2 = X*X;
Line 34: Line 34:
      
      
     float Sqrt = llSqrt(Thingy);
     float Sqrt = llSqrt(Thingy);
     float x;// = V2 - Sqrt;//llSqrt(V4 - G * (G*X2 + 2*Y*V2 ) );
     float x;
     if( cAng ) x = V2 + Sqrt;
     if( cAng ) x = V2 + Sqrt;
     else x = V2 - Sqrt;
     else x = V2 - Sqrt;
     float y = G*X;
     float y = G*X;
    Theta = llAtan2(x,y);
    Theta = llAtan2(x,y);
     return <0, llSin( Theta/2 ), 0, -llCos( Theta/2 )>;
     return <0, llSin( Theta/2 ), 0, -llCos( Theta/2 )>;
}
}
</lsl>
</source>
Returns quaternion rotation equivilant to the Y-Axis Rotation that is required to fullfill the conditions. Returns ZERO_ROTATION if there is an error though.
Returns quaternion rotation equivilant to the Y-Axis Rotation that is required to fullfill the conditions. Returns ZERO_ROTATION if there is an error though.


=== Angle of Reach, Height ===
=== Angle of Reach, Height ===
<lsl>
<source lang="lsl2">
rotation pAngleOfReachHeight(vector cPos,vector tPos,float V,float G,integer cAng){
rotation pAngleOfReachHeight(vector cPos,vector tPos,float V,float G,integer cAng){
     float Theta;
     float Theta;
    float D = llVecDist(cPos,tPos);float D2 = D*D;
     float V2 = V*V;float V4 = V*V*V*V;
     float V2 = V*V;float V4 = V*V*V*V;
     float X = llVecDist(<cPos.x,cPos.y,0>,<tPos.x,tPos.y,0>);float X2 = X*X;
     float X = llVecDist(<cPos.x,cPos.y,0>,<tPos.x,tPos.y,0>);float X2 = X*X;
     float Y = tPos.z - cPos.z;
     float Y = tPos.z - cPos.z;
      
      
     float MaxD =  (V * llCos(PI/4) / G) + (V * llSin(PI/4) + llSqrt( llPow( (V*llSin(PI/4)) + (2*G*Y),2) ) );
     //float MaxD =  (V * llCos(PI/4) / G) + (V * llSin(PI/4) + llSqrt( llPow( (V*llSin(PI/4)) + (2*G*Y),2) ) );
    // MaxD is the Maximum Distance. Can be useful if you need to know how far you can shoot with certain velocities!
      
      
     float Thingy = V4 - ( G * (G*X2 + 2*Y*V2 ));
     float Thingy = V4 - ( G * (G*X2 + 2*Y*V2 ));
Line 68: Line 68:
     return <0, llSin( Theta/2 ), 0, -llCos( Theta/2 )>;
     return <0, llSin( Theta/2 ), 0, -llCos( Theta/2 )>;
}
}
</lsl>
</source>
Same as the other one, but this time can cope when the target may be at a different height than the source.
Same as the other one, but this time can cope when the target may be at a different height than the source.


== Target Interception ==
== Target Interception ==
<lsl>
<source lang="lsl2">
vector Interception( vector cPos, vector tPos, vector cVel, vector tVel ){
vector Interception( vector cPos, vector tPos, vector cVel, vector tVel ){
     vector rPos = tPos - cPos;
     vector rPos = tPos - cPos;
Line 79: Line 79:
     float a = cVel * cVel - tVxtV;
     float a = cVel * cVel - tVxtV;
     return tPos + ( b + llSqrt( b*b + a * (rPos*rPos) ) ) / a * tVel;}
     return tPos + ( b + llSqrt( b*b + a * (rPos*rPos) ) ) / a * tVel;}
</lsl>
</source>
Returns vector of position to aim at so that an accurate hit is made. This is assuming both objects travel in a linear fashion in a constant speed. Still pretty damn good and close enough. Doesn't account for gravity though, so cannot be used with Angle of Reach unless you work out the average XY velocity for a preliminary trajectory I suppose.
Returns vector of position to aim at so that an accurate hit is made. This is assuming both objects travel in a linear fashion in a constant speed. Still pretty damn good and close enough. Doesn't account for gravity though, so cannot be used with Angle of Reach unless you work out the average XY velocity for a preliminary trajectory I suppose.


== Usage Example ==
== Usage Example ==
<lsl>
<source lang="lsl2">
     rotation PointRot = llRotBetween(<1,0,0>,llVecNorm(<tPos.x,tPos.y,cPos.z> - cPos));
     rotation PointRot = llRotBetween(<1,0,0>,llVecNorm(<tPos.x,tPos.y,cPos.z> - cPos));
     rotation TrajRot = pAngleOfReachHeight(cPos, tPos, 10.0, 9.8, FALSE );
     rotation TrajRot = pAngleOfReachHeight(cPos, tPos, 10.0, 9.8, FALSE );
Line 93: Line 93:
     RezRot = PointRot;
     RezRot = PointRot;
     RezObj = llGetInventoryName(INVENTORY_OBJECT,0);
     RezObj = llGetInventoryName(INVENTORY_OBJECT,0);
</lsl>
</source>
A simple example.
A simple example.

Latest revision as of 08:31, 25 January 2015

Non-License

//===================================================//
//                Physics Library 0.2                //
//          "May 6 2009", "11:00:00 GMT-0"           //
//                  By Nexii Malthus                 //
//                   Public Domain                   //
//===================================================//

Trajectory Functions

Time Of Flight

float pTimeOfFlight(float Dist, float Angle, float Height, float Vel, float Gravity ){// UNTESTED!
    float cos = llCos(Angle); float sin = llSin(Angle);
    return ( Dist / Vel*cos ) * ( ( llPow(Vel*sin,2) + 2 * Gravity * Height ) / Gravity);}

Experimental untested function, supposed to be used together with a device to prevent the familiar avatar 'splat', to calculate when a falling object hits Z=0, based on the (relative) float Height.

Angle of Reach

rotation pAngleOfReach(vector cPos,vector tPos,float V,float G,integer cAng){
    float Theta;
    float V2 = V*V;float V4 = V*V*V*V;
    float X = llVecDist(<cPos.x,cPos.y,0>,<tPos.x,tPos.y,0>);float X2 = X*X;
    float Y = 0.0;
    
    float Thingy = V4 - ( G * (G*X2 + 2*Y*V2 ));
    if(Thingy <= 0){
        //llSetText("Over max distance!",<1,1,1>,1.0);
        return ZERO_ROTATION;}
    
    float Sqrt = llSqrt(Thingy);
    float x;
    if( cAng ) x = V2 + Sqrt;
    else x = V2 - Sqrt;
    float y = G*X;
    Theta = llAtan2(x,y);
    return <0, llSin( Theta/2 ), 0, -llCos( Theta/2 )>;
}

Returns quaternion rotation equivilant to the Y-Axis Rotation that is required to fullfill the conditions. Returns ZERO_ROTATION if there is an error though.

Angle of Reach, Height

rotation pAngleOfReachHeight(vector cPos,vector tPos,float V,float G,integer cAng){
    float Theta;
    float V2 = V*V;float V4 = V*V*V*V;
    float X = llVecDist(<cPos.x,cPos.y,0>,<tPos.x,tPos.y,0>);float X2 = X*X;
    float Y = tPos.z - cPos.z;
    
    //float MaxD =  (V * llCos(PI/4) / G) + (V * llSin(PI/4) + llSqrt( llPow( (V*llSin(PI/4)) + (2*G*Y),2) ) );
    // MaxD is the Maximum Distance. Can be useful if you need to know how far you can shoot with certain velocities!
    
    float Thingy = V4 - ( G * (G*X2 + 2*Y*V2 ));
    if(Thingy <= 0){
        //llSetText("Over max distance!",<1,1,1>,1.0);
        return ZERO_ROTATION;}
    
    float Sqrt = llSqrt(Thingy);
    float x;
    if( cAng ) x = V2 + Sqrt;
    else x = V2 - Sqrt;
    float y = G*X;
    Theta = llAtan2(x,y);
    return <0, llSin( Theta/2 ), 0, -llCos( Theta/2 )>;
}

Same as the other one, but this time can cope when the target may be at a different height than the source.

Target Interception

vector Interception( vector cPos, vector tPos, vector cVel, vector tVel ){
    vector rPos = tPos - cPos;
    float tVxtV = tVel * tVel; 
    float b = rPos * tVel; 
    float a = cVel * cVel - tVxtV;
    return tPos + ( b + llSqrt( b*b + a * (rPos*rPos) ) ) / a * tVel;}

Returns vector of position to aim at so that an accurate hit is made. This is assuming both objects travel in a linear fashion in a constant speed. Still pretty damn good and close enough. Doesn't account for gravity though, so cannot be used with Angle of Reach unless you work out the average XY velocity for a preliminary trajectory I suppose.

Usage Example

    rotation PointRot = llRotBetween(<1,0,0>,llVecNorm(<tPos.x,tPos.y,cPos.z> - cPos));
    rotation TrajRot = pAngleOfReachHeight(cPos, tPos, 10.0, 9.8, FALSE );

    if(TrajRot == ZERO_ROTATION) return;

    RezPos = cPos;
    RezVel = < 10.0, 0.0, 0.0 > * (TrajRot * PointRot);
    RezRot = PointRot;
    RezObj = llGetInventoryName(INVENTORY_OBJECT,0);

A simple example.