|
|
Line 2: |
Line 2: |
| {{RightToc|clear:right;}} | | {{RightToc|clear:right;}} |
|
| |
|
| == Documentation == | | == Geometric Library == |
| === Line Functions === | | === Line Functions === |
| {|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%" | | {|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%" |
Line 996: |
Line 996: |
| |} | | |} |
|
| |
|
| == Geometric Library Code ==
| |
| === Legend === | | === Legend === |
| | For anyone curious to the shorthand used and who wish to use a lookup table can use this as a reference. Or anyone who wishes to add a new function to the library is welcome to but it would be recommended to keep consistency. |
| I tried to minimize the script function names to be easily readable. All the geometric function names start with a g. | | I tried to minimize the script function names to be easily readable. All the geometric function names start with a g. |
| Please note, Nexii Malthus is no maths professor and so one or two functions might not work as expected.
| |
|
| |
| Here is the legend: | | Here is the legend: |
|
| |
|
Line 1,008: |
Line 1,006: |
| ! '''Name''' | | ! '''Name''' |
| ! class="unsortable" | '''Description''' | | ! class="unsortable" | '''Description''' |
| | |- |
| | ! colspan="3" height="50%" | Geometric Types |
| |- | | |- |
| ||X | | ||X |
Line 1,019: |
Line 1,019: |
| ||R | | ||R |
| ||Ray | | ||Ray |
| ||A ray is like a line, except it is more distinct as it can define weather it points forward or back | | ||A ray is like a line, except it is more distinct as it defines wether it points forward or back |
| |- | | |- |
| ||P | | ||P |
| ||Plane | | ||Plane |
| ||A two dimensional doubly ruled surface of infinite size | | ||A 2D doubly ruled surface of infinite size |
| |- | | |- |
| ||S | | ||S |
| ||Sphere | | ||Sphere |
| ||A sphere is defined by origin and radius | | ||A sphere is defined by origin and radius |
| | |- |
| | ! colspan="3" height="50%" | What does it do? |
| |- | | |- |
| ||d | | ||d |
Line 1,044: |
Line 1,046: |
| ||Intersection | | ||Intersection |
| ||Calculates intersection | | ||Calculates intersection |
| | |- |
| | ! colspan="3" height="50%" | What kind of data do I get out of it? |
| |- | | |- |
| ||Z | | ||Z |
Line 1,061: |
Line 1,065: |
| ||Direction from the Origin | | ||Direction from the Origin |
| |} | | |} |
|
| |
| === LSL Script ===
| |
| This is the script in its entirety.
| |
| <lsl>//===================================================//
| |
| // Geometric Library 1.0 //
| |
| // "May 4 2008", "2:24:30" //
| |
| // Copyright (C) 2008, Nexii Malthus (cc-by) //
| |
| // http://creativecommons.org/licenses/by/3.0/ //
| |
| //===================================================//
| |
|
| |
| vector CP(vector A,vector B){
| |
| return A % B;}
| |
|
| |
| vector Project3D(vector A,vector B){
| |
| vector proj;
| |
| proj.x = ( (A*B) / (B.x*B.x + B.y*B.y + B.z*B.z) ) * B.x;
| |
| proj.y = ( (A*B) / (B.x*B.x + B.y*B.y + B.z*B.z) ) * B.y;
| |
| proj.z = ( (A*B) / (B.x*B.x + B.y*B.y + B.z*B.z) ) * B.z;
| |
| return proj;}
| |
|
| |
| // POINT //
| |
| float gXXdZ(vector A,vector B){
| |
| // Distance P2P.
| |
| return llVecDist(A,B);}
| |
|
| |
| vector gXXdV(vector A,vector B){
| |
| // Vector to move from P2P.
| |
| return A-B;}
| |
|
| |
| // LINE //
| |
| vector gLXdV(vector O,vector D,vector A){
| |
| // Calculates the vector from a point to the closest point on a line
| |
| return (O-A)-((O-A)*D)*D;}
| |
|
| |
| float gLXdZ(vector O,vector D,vector A){
| |
| // Calculates distance of this vector, but faster on it's own
| |
| return llSqrt(CP((A-O),D)*CP((A-O),D));}
| |
|
| |
| vector gLLdV(vector O1,vector D1,vector O2,vector D2){
| |
| // Shortest vector of two lines
| |
| return Project3D( (O2-O1), CP(D1,D2) );}
| |
|
| |
| float gLLdZ(vector O1,vector D1,vector O2,vector D2){
| |
| // Returns the distance between two lines
| |
| vector A = CP(D1,D2);float B = llVecMag(A);A = <A.x/B,A.y/B,A.z/B>;
| |
| return (O2-O1) * A;}
| |
|
| |
| vector gLLnX(vector O1,vector D1,vector O2,vector D2){
| |
| // Closest point of two lines
| |
| vector nO1 = < O1*D1, O1*D2, 0>;
| |
| vector nO2 = < O2*D1, O2*D2, 0>;
| |
| vector nD1 = < D1*D1, O1*D2, 0>;
| |
| vector nD2 = < O2*D1, O2*D2, 0>;
| |
|
| |
| float t = ( nD2.x*nD1.y - nD1.x*nD2.y );
| |
|
| |
| t = ( nD2.y*(nO1.x-nO2.x) - nD2.x*(nO1.y-nO2.y) ) / t;
| |
|
| |
| return O1 + D1*t;}
| |
|
| |
| vector X1;vector X2;vector V1;float Z1;
| |
|
| |
| gLLnnXX(vector O1,vector D1,vector O2,vector D2){
| |
| // Two closest points of two lines
| |
| vector nO1 = < O1*D1, O1*D2, 0>;
| |
| vector nO2 = < O2*D1, O2*D2, 0>;
| |
| vector nD1 = < D1*D1, O1*D2, 0>;
| |
| vector nD2 = < O2*D1, O2*D2, 0>;
| |
|
| |
| float t = ( nD2.x*nD1.y - nD1.x*nD2.y );
| |
|
| |
| t = ( nD2.y*(nO1.x-nO2.x) - nD2.x*(nO1.y-nO2.y) ) / t;
| |
|
| |
| X1 = O1 + D1*t;
| |
| X2 = X1 + CP(nD1,nD2);}
| |
|
| |
| gLLnnXXVZ(vector O1,vector D1,vector O2,vector D2){
| |
| // Computes two closest points of two lines, vector and distance
| |
| vector nO1 = < O1*D1, O1*D2, 0>;
| |
| vector nO2 = < O2*D1, O2*D2, 0>;
| |
| vector nD1 = < D1*D1, O1*D2, 0>;
| |
| vector nD2 = < O2*D1, O2*D2, 0>;
| |
|
| |
| float t = ( nD2.x*nD1.y - nD1.x*nD2.y );
| |
|
| |
| t = ( nD2.y*(nO1.x-nO2.x) - nD2.x*(nO1.y-nO2.y) ) / t;
| |
|
| |
| X1 = O1 + D1*t;
| |
| X2 = X1 + CP(nD1,nD2);
| |
| V1 = CP(nD1,nD2);
| |
| Z1 = llVecMag(V1);}
| |
|
| |
| // PLANE //
| |
| float gPXdZ(vector Pn,float Pd,vector A){
| |
| // Finds distance of a point from a plane
| |
| return A * Pn + Pd;}
| |
|
| |
| vector gPXdV(vector Pn,float Pd,vector A){
| |
| // Finds vector that points from point to nearest on plane
| |
| return -(Pn * A + Pd)*Pn;}
| |
|
| |
| vector gPXnX(vector Pn,float Pd,vector A){
| |
| // Finds closest point on plane given point
| |
| return A - (Pn * A + Pd) * Pn;}
| |
|
| |
| float gPRxZ(vector Pn,float Pd,vector O,vector D){
| |
| // Finds distance to intersection of plane along ray
| |
| return -( ( (Pn*D)+(Pn*O) ) / (Pn*D) );}
| |
| //return -( (Pn*D)/(Pn*O+Pd) );}
| |
|
| |
| vector gPRdV(vector Pn,float Pd,vector O,vector D){
| |
| // Finds distance vector along a ray to a plane
| |
| return D * gPRxZ(Pn,Pd,O,D);}
| |
| //return -( (Pn*D)/(Pn*O+Pd) )*D;}
| |
|
| |
| vector gPRxX(vector Pn,float Pd,vector O,vector D){
| |
| // Finds intersection point along a ray to a plane
| |
| return O + gPRdV(Pn,Pd,O,D);}
| |
|
| |
| vector gPLxX(vector Pn,float Pd,vector O,vector D){
| |
| // Finds interesection point of a line and a plane
| |
| return O -( (Pn*D)/(Pn*O+Pd) )*D;}
| |
|
| |
| vector oO;vector oD;
| |
|
| |
| gPPxL(vector Pn,float Pd,vector Qn,float Qd){
| |
| // Finds line of intersection of two planes
| |
| oD = CP(Pn,Qn)/llVecMag(CP(Pn,Qn));
| |
| vector Cross = CP(CP(Pn,Qn),Pn);
| |
| vector Bleh = (-Pd*Pn);
| |
| oO = Bleh - (Qn*Cross)/(Qn*Bleh+Qd)*Cross/llVecMag(Cross);}
| |
|
| |
| gPRpR(vector Pn,float Pd,vector O,vector D){
| |
| // Projects a ray onto a plane
| |
| oO = O - (Pn * O + Pd) * Pn;
| |
| vector t = llVecNorm( D - Project3D(D,Pn) );t = <1.0/t.x,1.0/t.y,1.0/t.z>;
| |
| oD = CP(Pn,t);}
| |
|
| |
| // SPHERE //
| |
| vector gSRxX(vector Sp, float Sr, vector Ro, vector Rd){
| |
| float t;Ro = Ro - Sp;
| |
| //vector RayOrg = llDetectedPos(x) - llGetPos();
| |
| if(Rd == ZERO_VECTOR) return ZERO_VECTOR;
| |
|
| |
| float a = Rd * Rd;
| |
| float b = 2 * Rd * Ro;
| |
| float c = (Ro * Ro) - (Sr * Sr);
| |
|
| |
| float disc = b * b - 4 * a * c;
| |
|
| |
| if(disc < 0) return ZERO_VECTOR;
| |
|
| |
| float distSqrt = llSqrt(disc);
| |
| float q;
| |
|
| |
| if(b < 0)
| |
| q = (-b - distSqrt)/2.0;
| |
| else
| |
| q = (-b + distSqrt)/2.0;
| |
|
| |
| float t0 = q / a;
| |
| float t1 = c / q;
| |
|
| |
| if(t0 > t1){
| |
| float temp = t0;
| |
| t0 = t1;
| |
| t1 = temp;
| |
| }
| |
|
| |
| if(t1 < 0) return ZERO_VECTOR;
| |
|
| |
| if(t0 < 0)
| |
| t = t1;
| |
| else
| |
| t = t0;
| |
|
| |
| return Ro + (t * Rd);
| |
| }
| |
|
| |
| integer gSRx(vector Sp, float Sr, vector Ro, vector Rd){
| |
| float t;Ro = Ro - Sp;
| |
| //vector RayOrg = llDetectedPos(x) - llGetPos();
| |
| if(Rd == ZERO_VECTOR) return FALSE;
| |
|
| |
| float a = Rd * Rd;
| |
| float b = 2 * Rd * Ro;
| |
| float c = (Ro * Ro) - (Sr * Sr);
| |
|
| |
| float disc = b * b - 4 * a * c;
| |
|
| |
| if(disc < 0) return FALSE;
| |
| return TRUE;
| |
| }
| |
|
| |
| // RAY //
| |
| float gRXpZ(vector O,vector D,vector A){
| |
| // Finds projected distance of a point along a ray
| |
| return (A-O)*D;}
| |
|
| |
| vector gRZiX(vector O,vector D,float z){
| |
| return O+z*D;}
| |
|
| |
| // OTHER //
| |
| vector pN;float pD;
| |
| gTiP(vector p1,vector p2,vector p3){
| |
| // Turns three vector points in space into a plane
| |
| pN = llVecNorm( CP((p2-p1),(p3-p1)) );
| |
| pD = -p1*pN;}
| |
|
| |
| integer gTXcC(vector p1,vector p2,vector p3,vector x){
| |
| // Can be used to check weather a point is inside a triangle
| |
| gTiP(p1,p2,p3);
| |
| vector Vn;vector En;
| |
| Vn = p1 - x;
| |
| En = CP((p2-p1),pN);
| |
| if( ((p1-x)*CP(p2-p1,pN) >= 0)&&((p2-x)*CP(p3-p2,pN) >= 0)&&((p3-x)*CP(p1-p3,pN) >= 0) ) return TRUE;
| |
| return FALSE;}
| |
|
| |
| integer gTVXcC(vector p1,vector p2,vector p3,vector v,vector x){
| |
| if( ((p1-x)*CP(p2-p1,v) >= 0)&&((p2-x)*CP(p3-p2,v) >= 0)&&((p3-x)*CP(p1-p3,v) >= 0) ) return TRUE;
| |
| return FALSE;}
| |
|
| |
| integer gTRcC(vector p1,vector p2,vector p3,vector O,vector D){
| |
| return gTVXcC(p1,p2,p3,O,D);}
| |
|
| |
| default{state_entry(){}}
| |
|
| |
| </lsl>
| |
|
| |
| == Expanded Library ==
| |
| I was informed by Strife that shorthand one/two letter variable names is out of fashion these days, so it's up to the opinion of the reader if they really think this is cleaner and can now choose from two versions.
| |
|
| |
| <lsl>
| |
| //===================================================//
| |
| // Geometric Library 1.0 //
| |
| // "May 4 2008", "2:24:30" //
| |
| // Copyright (C) 2008, Nexii Malthus (cc-by) //
| |
| // http://creativecommons.org/licenses/by/3.0/ //
| |
| //===================================================//
| |
|
| |
| vector CrossProduct(vector Point1,vector Point2){
| |
| return Point1 % Point2;}
| |
|
| |
| vector Project3D(vector A,vector B){
| |
| vector proj;
| |
| proj.x = ( (A*B) / (B.x*B.x + B.y*B.y + B.z*B.z) ) * B.x;
| |
| proj.y = ( (A*B) / (B.x*B.x + B.y*B.y + B.z*B.z) ) * B.y;
| |
| proj.z = ( (A*B) / (B.x*B.x + B.y*B.y + B.z*B.z) ) * B.z;
| |
| return proj;}
| |
|
| |
| // POINT
| |
| float gPoint2Point_Distance_Float(vector Point1,vector Point2){
| |
| // Distance P2P.
| |
| return llVecDist(Point1,Point2);}
| |
|
| |
| vector gPoint2Point_Distance_Vector(vector Point1,vector Point2){
| |
| // Vector to move from P2P.
| |
| return Point1-Point2;}
| |
|
| |
| // LINE
| |
| vector gLine2Point_Distance_Vector(vector LineOrigin,vector LineDirection,vector Point){
| |
| // Calculates the vector from a point to the closest point on a line
| |
| return (LineOrigin-Point)-((LineOrigin-Point)*LineDirection)*LineDirection;}
| |
|
| |
| float gLine2Point_Distance_Float(vector LineOrigin,vector LineDirection,vector Point){
| |
| // Calculates distance of this vector, but faster on it's own
| |
| return llSqrt(CrossProduct((Point-LineOrigin),LineDirection)*CrossProduct((Point-LineOrigin),LineDirection));}
| |
|
| |
| vector gLine2Line_Distance_Vector(vector LineOrigin1,vector LineDirection1,vector LineOrigin2,vector LineDirection2){
| |
| // Shortest vector of two lines
| |
| return Project3D( (LineOrigin2-LineOrigin1), CrossProduct(LineDirection1,LineDirection2) );}
| |
|
| |
| float gLine2Line_Distance_Float(vector LineOrigin1,vector LineDirection1,vector LineOrigin2,vector LineDirection2){
| |
| // Returns the distance between two lines
| |
| vector A = CrossProduct(LineDirection1,LineDirection2);float B = llVecMag(A);A = <A.x/B,A.y/B,A.z/B>;
| |
| return (LineOrigin2-LineOrigin1) * A;}
| |
|
| |
| vector gLine2Line_Nearest_Point(vector LineOrigin1,vector LineDirection1,vector LineOrigin2,vector LineDirection2){
| |
| // Closest point of two lines
| |
| vector nearestOrigin1 = < LineOrigin1*LineDirection1, LineOrigin1*LineDirection2, 0>;
| |
| vector nearestOrigin2 = < LineOrigin2*LineDirection1, LineOrigin2*LineDirection2, 0>;
| |
| vector nearestDirection1 = < LineDirection1*LineDirection1, LineOrigin1*LineDirection2, 0>;
| |
| vector nearestDirection2 = < LineOrigin2*LineDirection1, LineOrigin2*LineDirection2, 0>;
| |
|
| |
| float t = ( nearestDirection2.x*nearestDirection1.y - nearestDirection1.x*nearestDirection2.y );
| |
|
| |
| t = ( nearestDirection2.y*(nearestOrigin1.x-nearestOrigin2.x) - nearestDirection2.x*(nearestOrigin1.y-nearestOrigin2.y) ) / t;
| |
|
| |
| return LineOrigin1 + LineDirection1*t;}
| |
|
| |
| vector outPoint1;vector outPoint2;vector outVector1;float outFloat1;
| |
|
| |
| gLine2Line_Nearest_Two_Points(vector LineOrigin1,vector LineDirection1,vector LineOrigin2,vector LineDirection2){
| |
| // Two closest points of two lines
| |
| vector nearestOrigin1 = < LineOrigin1*LineDirection1, LineOrigin1*LineDirection2, 0>;
| |
| vector nearestOrigin2 = < LineOrigin2*LineDirection1, LineOrigin2*LineDirection2, 0>;
| |
| vector nearestDirection1 = < LineDirection1*LineDirection1, LineOrigin1*LineDirection2, 0>;
| |
| vector nearestDirection2 = < LineOrigin2*LineDirection1, LineOrigin2*LineDirection2, 0>;
| |
|
| |
| float t = ( nearestDirection2.x*nearestDirection1.y - nearestDirection1.x*nearestDirection2.y );
| |
|
| |
| t = ( nearestDirection2.y*(nearestOrigin1.x-nearestOrigin2.x) - nearestDirection2.x*(nearestOrigin1.y-nearestOrigin2.y) ) / t;
| |
|
| |
| outPoint1 = LineOrigin1 + LineDirection1*t;
| |
| outPoint2 = outPoint1 + CrossProduct(nearestDirection1,nearestDirection2);}
| |
|
| |
| gLine2Line_Nearest_Two_Points_Vector_Distance(vector LineOrigin1,vector LineDirection1,vector LineOrigin2,vector LineDirection2){
| |
| // Computes two closest points of two lines, vector and distance
| |
| vector nearestOrigin1 = < LineOrigin1*LineDirection1, LineOrigin1*LineDirection2, 0>;
| |
| vector nearestOrigin2 = < LineOrigin2*LineDirection1, LineOrigin2*LineDirection2, 0>;
| |
| vector nearestDirection1 = < LineDirection1*LineDirection1, LineOrigin1*LineDirection2, 0>;
| |
| vector nearestDirection2 = < LineOrigin2*LineDirection1, LineOrigin2*LineDirection2, 0>;
| |
|
| |
| float t = ( nearestDirection2.x*nearestDirection1.y - nearestDirection1.x*nearestDirection2.y );
| |
|
| |
| t = ( nearestDirection2.y*(nearestOrigin1.x-nearestOrigin2.x) - nearestDirection2.x*(nearestOrigin1.y-nearestOrigin2.y) ) / t;
| |
|
| |
| outPoint1 = LineOrigin1 + LineDirection1*t;
| |
| outPoint2 = outPoint1 + CrossProduct(nearestDirection1,nearestDirection2);
| |
| outVector1 = CrossProduct(nearestDirection1,nearestDirection2);
| |
| outFloat1 = llVecMag(outVector1);}
| |
|
| |
| // PLANE
| |
| float gPlane2Point_Distance_Float(vector PlaneNormal,float PlaneDistance,vector A){
| |
| // Finds distance of a point from a plane
| |
| return A * PlaneNormal + PlaneDistance;}
| |
|
| |
| vector gPlane2Point_Distance_Vector(vector PlaneNormal,float PlaneDistance,vector A){
| |
| // Finds vector that points from point to nearest on plane
| |
| return -(PlaneNormal * A + PlaneDistance)*PlaneNormal;}
| |
|
| |
| vector gPlane2Point_Nearest_Point(vector PlaneNormal,float PlaneDistance,vector A){
| |
| // Finds closest point on plane given point
| |
| return A - (PlaneNormal * A + PlaneDistance) * PlaneNormal;}
| |
|
| |
| float gPlane2Ray_Nearest_Float(vector PlaneNormal,float PlaneDistance,vector RayOrigin,vector RayDirection){
| |
| // Finds distance to intersection of plane along ray
| |
| return -( ( (PlaneNormal*RayDirection)+(PlaneNormal*RayOrigin) ) / (PlaneNormal*RayDirection) );}
| |
|
| |
| vector gPlane2Ray_Distance_Vector(vector PlaneNormal,float PlaneDistance,vector RayOrigin,vector RayDirection){
| |
| // Finds distance vector along a ray to a plane
| |
| return RayDirection * gPlane2Ray_Nearest_Float(PlaneNormal,PlaneDistance,RayOrigin,RayDirection);}
| |
|
| |
| vector gPlane2Ray_Intersection_Point(vector PlaneNormal,float PlaneDistance,vector RayOrigin,vector RayDirection){
| |
| // Finds intersection point along a ray to a plane
| |
| return RayOrigin + gPlane2Ray_Distance_Vector(PlaneNormal,PlaneDistance,RayOrigin,RayDirection);}
| |
|
| |
| vector gPlane2Line_Intersection_Point(vector PlaneNormal,float PlaneDistance,vector LineOrigin,vector LineDirection){
| |
| // Finds interesection point of a line and a plane
| |
| return LineOrigin -( (PlaneNormal*LineDirection)/(PlaneNormal*LineOrigin+PlaneDistance) )*LineDirection;}
| |
|
| |
| vector outLineOrigin;vector outLineDirection;
| |
|
| |
| gPlane2Plane_Intersection_Line(vector PlaneA_Normal,float PlaneA_Distance,vector PlaneB_Normal,float PlaneB_Distance){
| |
| // Finds line of intersection of two planes
| |
| outLineDirection = CrossProduct(PlaneA_Normal,PlaneB_Normal)/llVecMag(CrossProduct(PlaneA_Normal,PlaneB_Normal));
| |
| vector Cross = CrossProduct(CrossProduct(PlaneA_Normal,PlaneB_Normal),PlaneA_Normal);
| |
| vector Bleh = (-PlaneA_Distance*PlaneA_Normal);
| |
| outLineOrigin = Bleh - (PlaneB_Normal*Cross)/(PlaneB_Normal*Bleh+PlaneB_Distance)*Cross/llVecMag(Cross);}
| |
|
| |
| float gRay2Point_Project_Float(vector RayOrigin,vector RayDirection,vector Projection){
| |
| // Finds projected distance of a point along a ray
| |
| return (Projection-RayOrigin)*RayDirection;}
| |
|
| |
| gPlane2Ray_Project_Ray(vector PlaneNormal,float PlaneDistance,vector RayOrigin,vector RayDirection){
| |
| // Projects a ray onto a plane
| |
| outLineOrigin = RayOrigin - (PlaneNormal * RayOrigin + PlaneDistance) * PlaneNormal;
| |
| vector t = llVecNorm( RayDirection - Project3D(RayDirection,PlaneNormal) );t = <1.0/t.x,1.0/t.y,1.0/t.z>;
| |
| outLineDirection = CrossProduct(PlaneNormal,t);}
| |
|
| |
| // SPHERE
| |
| vector gSphere2Ray_Intersection_Point(vector SphereOrigin, float SphereRadius, vector RayOrigin, vector RayDirection){
| |
| float t;RayOrigin = RayOrigin - SphereOrigin;
| |
| if(RayDirection == ZERO_VECTOR) return ZERO_VECTOR;
| |
|
| |
| float a = RayDirection * RayDirection;
| |
| float b = 2 * RayDirection * RayOrigin;
| |
| float c = (RayOrigin * RayOrigin) - (SphereRadius * SphereRadius);
| |
|
| |
| float disc = b * b - 4 * a * c;
| |
|
| |
| if(disc < 0) return ZERO_VECTOR;
| |
|
| |
| float distSqrt = llSqrt(disc);
| |
| float q;
| |
|
| |
| if(b < 0)
| |
| q = (-b - distSqrt)/2.0;
| |
| else
| |
| q = (-b + distSqrt)/2.0;
| |
|
| |
| float t0 = q / a;
| |
| float t1 = c / q;
| |
|
| |
| if(t0 > t1){
| |
| float temp = t0;
| |
| t0 = t1;
| |
| t1 = temp;
| |
| }
| |
|
| |
| if(t1 < 0) return ZERO_VECTOR;
| |
|
| |
| if(t0 < 0)
| |
| t = t1;
| |
| else
| |
| t = t0;
| |
|
| |
| return RayOrigin + (t * RayDirection);
| |
| }
| |
|
| |
| integer gSphere2Ray_Intersection(vector SphereOrigin, float SphereRadius, vector RayOrigin, vector RayDirection){
| |
| // IS there a intersection?
| |
|
| |
| float t;RayOrigin = RayOrigin - SphereOrigin;
| |
| if(RayDirection == ZERO_VECTOR) return FALSE;
| |
|
| |
| float a = RayDirection * RayDirection;
| |
| float b = 2 * RayDirection * RayOrigin;
| |
| float c = (RayOrigin * RayOrigin) - (SphereRadius * SphereRadius);
| |
|
| |
| float disc = b * b - 4 * a * c;
| |
|
| |
| if(disc < 0) return FALSE;
| |
| return TRUE;
| |
| }
| |
|
| |
| // Other
| |
| vector planeNormal;float planeDistance;
| |
| gTriangle_into_Plane(vector p1,vector p2,vector p3){
| |
| planeNormal = llVecNorm( CrossProduct((p2-p1),(p3-p1)) );
| |
| planeDistance = -p1*planeNormal;}
| |
|
| |
| integer gTriangle2Point_CheckCollision(vector p1,vector p2,vector p3,vector x){
| |
| gTriangle_into_Plane(p1,p2,p3);
| |
| vector Vn;vector En;
| |
| Vn = p1 - x;
| |
| En = CrossProduct((p2-p1),planeNormal);
| |
| if( ((p1-x)*CrossProduct(p2-p1,planeNormal) >= 0)&&((p2-x)*CrossProduct(p3-p2,planeNormal) >= 0)&&((p3-x)*CrossProduct(p1-p3,planeNormal) >= 0) ) return TRUE;
| |
| return FALSE;}
| |
|
| |
| integer gTVXcC(vector p1,vector p2,vector p3,vector v,vector x){
| |
| if( ((p1-x)*CrossProduct(p2-p1,v) >= 0)&&((p2-x)*CrossProduct(p3-p2,v) >= 0)&&((p3-x)*CrossProduct(p1-p3,v) >= 0) ) return TRUE;
| |
| return FALSE;}
| |
|
| |
| integer gTriangel2Ray_CheckCollision(vector p1,vector p2,vector p3,vector Origin,vector Direction){
| |
| return gTVXcC(p1,p2,p3,Origin,Direction);}
| |
|
| |
| vector gRay2Float_into_Point(vector Origin,vector Direction,float Float){
| |
| return Origin+Float*Direction;}
| |
|
| |
| default{state_entry(){}}
| |
|
| |
| </lsl>
| |
|
| |
| ==Optimized ESL==
| |
| <lsl>//===================================================//
| |
| // Geometric Library 1.0 Optimized ESL Build 1 //
| |
| // "May 4 2008", "14:19:37" //
| |
| // Copyright (C) 2008, Nexii Malthus (cc-by) //
| |
| // Copyright (C) 2008, Strife Onizuka (cc-by) //
| |
| // http://creativecommons.org/licenses/by/3.0/ //
| |
| //===================================================//
| |
|
| |
| #define CP(A, B) ((A) % (B))
| |
| #ifndef CP
| |
| vector CP(vector A,vector B){
| |
| return A % B;}
| |
| #endif
| |
|
| |
| #if 0
| |
| vector Project3D(vector A,vector B){
| |
| vector proj;
| |
| proj.x = ( (A*B) / (B.x*B.x + B.y*B.y + B.z*B.z) ) * B.x;
| |
| proj.y = ( (A*B) / (B.x*B.x + B.y*B.y + B.z*B.z) ) * B.y;
| |
| proj.z = ( (A*B) / (B.x*B.x + B.y*B.y + B.z*B.z) ) * B.z;
| |
| return proj;}
| |
| #else
| |
| vector Project3D(vector A,vector B){
| |
| return B * ((A*B) / (B*B));}
| |
| #endif
| |
|
| |
| // POINT
| |
| #define gXXdZ llVecDist
| |
| #ifndef gXXdZ
| |
| float gXXdZ(vector A,vector B){
| |
| // Distance P2P.
| |
| return llVecDist(A,B);}
| |
| #endif
| |
|
| |
| #define gXXdV(A,B) ((A) - (B))
| |
| #ifndef gXXdV
| |
| vector gXXdV(vector A,vector B){
| |
| // Vector to move from P2P.
| |
| return A-B;}
| |
| #endif
| |
|
| |
| // LINE
| |
| #if 0
| |
| vector gLXdV(vector O,vector D,vector A){
| |
| // Calculates the vector from a point to the closest point on a line
| |
| return (O-A)-((O-A)*D)*D;}
| |
| #else
| |
| vector gLXdV(vector O,vector D,vector A){
| |
| // Calculates the vector from a point to the closest point on a line
| |
| vector t = (O-A);
| |
| return t - (t*D)*D;}
| |
| #endif
| |
|
| |
| #define gLXdZ(O, D, A) llVecMag(CP((A-O),D))
| |
| #ifndef gLXdZ
| |
| float gLXdZ(vector O,vector D,vector A){
| |
| // Calculates distance of this vector, but faster on it's own
| |
| return llVecMag(CP((A-O),D));}
| |
| #endif
| |
|
| |
| #define gLLdV(O, D, A) Project3D( (O2-O1), CP(D1,D2) )
| |
| #ifndef gLLdV
| |
| vector gLLdV(vector O1,vector D1,vector O2,vector D2){
| |
| // Shortest vector of two lines
| |
| return Project3D( (O2-O1), CP(D1,D2) );}
| |
| #endif
| |
|
| |
| #define gLLdZ(O1, D1, O2, D2) ((O2-O1) * llVecNorm(CP(D1,D2)))
| |
| #ifndef gLLdZ
| |
| float gLLdZ(vector O1,vector D1,vector O2,vector D2){
| |
| // Returns the distance between two lines
| |
| vector A = CP(D1,D2);float B = llVecMag(A);A = <A.x/B,A.y/B,A.z/B>;
| |
| return (O2-O1) * A;}
| |
| #endif
| |
|
| |
| #if 0
| |
| vector gLLnX(vector O1,vector D1,vector O2,vector D2){
| |
| // Closest point of two lines
| |
| vector nO1 = < O1*D1, O1*D2, 0>;
| |
| vector nO2 = < O2*D1, O2*D2, 0>;
| |
| vector nD1 = < D1*D1, O1*D2, 0>;
| |
| vector nD2 = < O2*D1, O2*D2, 0>;
| |
|
| |
| float t = ( nD2.x*nD1.y - nD1.x*nD2.y );
| |
|
| |
| t = ( nD2.y*(nO1.x-nO2.x) - nD2.x*(nO1.y-nO2.y) ) / t;
| |
|
| |
| return O1 + D1*t;}
| |
| #else
| |
| vector gLLnX(vector O1,vector D1,vector O2,vector D2){
| |
| // Closest point of two lines
| |
| vector t = <O2*D1, O1*D2, O2*D2>;
| |
|
| |
| return O1 + D1 * (( t.z * ((O1*D1)-t.x) - t.x * (t.y-t.z) ) / ( t.x*t.y - (D1*D1)*t.z ));}
| |
| #endif
| |
|
| |
| vector X1;vector X2;vector V1;float Z1;
| |
|
| |
| #if 0
| |
| gLLnnXX(vector O1,vector D1,vector O2,vector D2){
| |
| // Two closest points of two lines
| |
| vector nO1 = < O1*D1, O1*D2, 0>;
| |
| vector nO2 = < O2*D1, O2*D2, 0>;
| |
| vector nD1 = < D1*D1, O1*D2, 0>;
| |
| vector nD2 = < O2*D1, O2*D2, 0>;
| |
|
| |
| float t = ( nD2.x*nD1.y - nD1.x*nD2.y );
| |
|
| |
| t = ( nD2.y*(nO1.x-nO2.x) - nD2.x*(nO1.y-nO2.y) ) / t;
| |
|
| |
| X1 = O1 + D1*t;
| |
| X2 = X1 + CP(nD1,nD2);}
| |
| #else
| |
| gLLnnXX(vector O1,vector D1,vector O2,vector D2){
| |
| // Two closest points of two lines
| |
| #define a (O1*D1)
| |
| #define c (D1*D1)
| |
| #define d (O2*D1)
| |
| #define e (O1*D2)
| |
| #define f (O2*D2)
| |
| vector nD1 = < c, e, 0.0>;
| |
| vector nD2 = < d, f, 0.0>;
| |
| #undef c
| |
| #undef d
| |
| #undef e
| |
| #undef f
| |
| #define c nD1.x
| |
| #define d nD2.x
| |
| #define e nD1.y
| |
| #define f nD2.y
| |
| X2 = (X1 = (O1 + D1 * (( d*(a-d) - d*(e-f) ) / ( d*e - c*f )))) + CP(nD1,nD2);}
| |
| #undef a
| |
| #undef c
| |
| #undef d
| |
| #undef e
| |
| #undef f
| |
| #endif
| |
|
| |
| #if 0
| |
| gLLnnXXVZ(vector O1,vector D1,vector O2,vector D2){
| |
| // Computes two closest points of two lines, vector and distance
| |
| vector nO1 = < O1*D1, O1*D2, 0>;
| |
| vector nO2 = < O2*D1, O2*D2, 0>;
| |
| vector nD1 = < D1*D1, O1*D2, 0>;
| |
| vector nD2 = < O2*D1, O2*D2, 0>;
| |
|
| |
| float t = ( nD2.x*nD1.y - nD1.x*nD2.y );
| |
|
| |
| t = ( nD2.y*(nO1.x-nO2.x) - nD2.x*(nO1.y-nO2.y) ) / t;
| |
|
| |
| X1 = O1 + D1*t;
| |
| X2 = X1 + CP(nD1,nD2);
| |
| V1 = CP(nD1,nD2);
| |
| Z1 = llVecMag(V1);}
| |
| #else
| |
| gLLnnXXVZ(vector O1,vector D1,vector O2,vector D2){
| |
| // Computes two closest points of two lines, vector and distance
| |
| #define a (O1*D1)
| |
| #define c (D1*D1)
| |
| #define d (O2*D1)
| |
| #define e (O1*D2)
| |
| #define f (O2*D2)
| |
| vector nD1 = < c, e, 0.0>;
| |
| vector nD2 = < d, f, 0.0>;
| |
| #undef c
| |
| #undef d
| |
| #undef e
| |
| #undef f
| |
| #define c nD1.x
| |
| #define d nD2.x
| |
| #define e nD1.y
| |
| #define f nD2.y
| |
| X2 = (X1 = (O1 + D1 * (( f * (a-d) - d * (e-f) ) / ( d*e - c*f )))) + (V1 = (CP(nD1,nD2)));
| |
| Z1 = llVecMag(V1);}
| |
| #undef a
| |
| #undef c
| |
| #undef d
| |
| #undef e
| |
| #undef f
| |
| #endif
| |
|
| |
| // PLANE
| |
| #define gPXdZ(Pn, Pd, A) ((A) * (Pn) + (Pd))
| |
| #ifndef gPXdZ
| |
| float gPXdZ(vector Pn,float Pd,vector A){
| |
| // Finds distance of a point from a plane
| |
| return A * Pn + Pd;}
| |
| #endif
| |
|
| |
| vector gPXdV(vector Pn,float Pd,vector A){
| |
| // Finds vector that points from point to nearest on plane
| |
| return -(Pn * A + Pd)*Pn;}
| |
|
| |
| vector gPXnX(vector Pn,float Pd,vector A){
| |
| // Finds closest point on plane given point
| |
| return A - (Pn * A + Pd) * Pn;}
| |
|
| |
| #if 0
| |
| float gPRxZ(vector Pn,float Pd,vector O,vector D){
| |
| // Finds distance to intersection of plane along ray
| |
| return -( ( (Pn*D)+(Pn*O) ) / (Pn*D) );}
| |
| //return -( (Pn*D)/(Pn*O+Pd) );}
| |
| #else
| |
| float gPRxZ(vector Pn,float Pd,vector O,vector D){
| |
| // Finds distance to intersection of plane along ray
| |
| float a = (Pn*D);
| |
| return -( ( a+(Pn*O) ) / a );}
| |
| //return -( (Pn*D)/(Pn*O+Pd) );}
| |
| #endif
| |
|
| |
| vector gPRdV(vector Pn,float Pd,vector O,vector D){
| |
| // Finds distance vector along a ray to a plane
| |
| return D * gPRxZ(Pn,Pd,O,D);}
| |
| //return -( (Pn*D)/(Pn*O+Pd) )*D;}
| |
|
| |
| vector gPRxX(vector Pn,float Pd,vector O,vector D){
| |
| // Finds intersection point along a ray to a plane
| |
| return O + gPRdV(Pn,Pd,O,D);}
| |
|
| |
| vector gPLxX(vector Pn,float Pd,vector O,vector D){
| |
| // Finds interesection point of a line and a plane
| |
| return O -( (Pn*D)/(Pn*O+Pd) )*D;}
| |
|
| |
| vector oO;vector oD;
| |
|
| |
| #if 0
| |
| gPPxL(vector Pn,float Pd,vector Qn,float Qd){
| |
| // Finds line of intersection of two planes
| |
| oD = CP(Pn,Qn)/llVecMag(CP(Pn,Qn));
| |
| vector Cross = CP(CP(Pn,Qn),Pn);
| |
| vector Bleh = (-Pd*Pn);
| |
| oO = Bleh - (Qn*Cross)/(Qn*Bleh+Qd)*Cross/llVecMag(Cross);}
| |
| #else
| |
| gPPxL(vector Pn,float Pd,vector Qn,float Qd){
| |
| // Finds line of intersection of two planes
| |
| vector a = CP(Pn,Qn);
| |
| oD = llVecNorm(a);
| |
| vector Cross = CP(a,Pn);
| |
| vector Bleh = (-Pd*Pn);
| |
| oO = Bleh - (Qn*Cross)/(Qn*Bleh+Qd)*llVecNorm(Cross);}
| |
| #endif
| |
|
| |
| #define gRXpZ(O, D, A) (A-O)*D
| |
| #ifndef gRXpZ
| |
| float gRXpZ(vector O,vector D,vector A){
| |
| // Finds projected distance of a point along a ray
| |
| return (A-O)*D;}
| |
| #endif
| |
|
| |
| #if 0
| |
| gPRpR(vector Pn,float Pd,vector O,vector D){
| |
| // Projects a ray onto a plane
| |
| oO = O - (Pn * O + Pd) * Pn;
| |
| vector t = llVecNorm( D - Project3D(D,Pn) );t = <1.0/t.x,1.0/t.y,1.0/t.z>;
| |
| oD = CP(Pn,t);}
| |
| #else
| |
| gPRpR(vector Pn,float Pd,vector O,vector D){
| |
| // Projects a ray onto a plane
| |
| oO = O - (Pn * O + Pd) * Pn;
| |
| O = llVecNorm( D - Project3D(D,Pn) );
| |
| oD = CP(Pn, (<1.0/O.x,1.0/O.y,1.0/O.z>));}
| |
| #endif
| |
|
| |
| // SPHERE
| |
| #if 0
| |
| vector gSRxX(vector Sp, float Sr, vector Ro, vector Rd){
| |
| float t;Ro = Ro - Sp;
| |
| //vector RayOrg = llDetectedPos(x) - llGetPos();
| |
| if(Rd == ZERO_VECTOR) return ZERO_VECTOR;
| |
|
| |
| float a = Rd * Rd;
| |
| float b = 2 * Rd * Ro;
| |
| float c = (Ro * Ro) - (Sr * Sr);
| |
|
| |
| float disc = b * b - 4 * a * c;
| |
|
| |
| if(disc < 0) return ZERO_VECTOR;
| |
|
| |
| float distSqrt = llSqrt(disc);
| |
| float q;
| |
|
| |
| if(b < 0)
| |
| q = (-b - distSqrt)/2.0;
| |
| else
| |
| q = (-b + distSqrt)/2.0;
| |
|
| |
| float t0 = q / a;
| |
| float t1 = c / q;
| |
|
| |
| if(t0 > t1){
| |
| float temp = t0;
| |
| t0 = t1;
| |
| t1 = temp;
| |
| }
| |
|
| |
| if(t1 < 0) return ZERO_VECTOR;
| |
|
| |
| if(t0 < 0)
| |
| t = t1;
| |
| else
| |
| t = t0;
| |
|
| |
| return Ro + (t * Rd);
| |
| }
| |
| #else
| |
| vector gSRxX(vector Sp, float Sr, vector Ro, vector Rd){
| |
| if(Rd)
| |
| {
| |
| Ro -= Sp;
| |
| //vector RayOrg = llDetectedPos(x) - llGetPos();
| |
| float a = Rd * Rd;
| |
| float b = 2 * Rd * Ro;
| |
| float c = (Ro * Ro) - (Sr * Sr);
| |
|
| |
| float disc = b * b - 4 * a * c;
| |
|
| |
| if(disc >= 0)
| |
| {
| |
| float q = ((llSqrt(disc) * ~((b > 0) * -2)) - b) / 2.0;
| |
| if(q)//avoid a divide by zero!
| |
| {
| |
| float t0 = q / a;
| |
| float t1 = c / q;
| |
|
| |
| if(((t0 < t1) || (t1 < 0)) && (t0 >= 0))
| |
| return Ro + (t0 * Rd);
| |
| if(t1 >= 0)
| |
| return Ro + (t1 * Rd);
| |
| }
| |
| }
| |
| }
| |
| return ZERO_VECTOR;
| |
| }
| |
| #endif
| |
|
| |
| #if 0
| |
| integer gSRx(vector Sp, float Sr, vector Ro, vector Rd){
| |
| float t;Ro = Ro - Sp;
| |
| //vector RayOrg = llDetectedPos(x) - llGetPos();
| |
| if(Rd == ZERO_VECTOR) return FALSE;
| |
|
| |
| float a = Rd * Rd;
| |
| float b = 2 * Rd * Ro;
| |
| float c = (Ro * Ro) - (Sr * Sr);
| |
|
| |
| float disc = b * b - 4 * a * c;
| |
|
| |
| if(disc < 0) return FALSE;
| |
| return TRUE;
| |
| }
| |
| #else
| |
| integer gSRx(vector Sp, float Sr, vector Ro, vector Rd){
| |
| if(Rd)
| |
| {
| |
| Ro -= Sp;
| |
| //vector RayOrg = llDetectedPos(x) - llGetPos();
| |
| float a = Rd * Rd;
| |
| float b = 2 * Rd * Ro;
| |
| float c = (Ro * Ro) - (Sr * Sr);
| |
| return (b * b - 4 * a * c) >= 0;
| |
| }
| |
| return FALSE;
| |
| }
| |
| #endif
| |
|
| |
| // Other
| |
| vector pN;float pD;
| |
| #if 0
| |
| gTiP(vector p1,vector p2,vector p3){
| |
| // Turns three vector points in space into a plane
| |
| pN = llVecNorm( CP((p2-p1),(p3-p1)) );
| |
| pD = -p1*pN;}
| |
| #else
| |
| gTiP(vector p1,vector p2,vector p3){
| |
| // Turns three vector points in space into a plane
| |
| pD = -p1*(pN = llVecNorm( CP((p2-p1),(p3-p1)) ));}
| |
| #endif
| |
|
| |
| #if 0
| |
| integer gTXcC(vector p1,vector p2,vector p3,vector x){
| |
| gTiP(p1,p2,p3);
| |
| vector Vn;vector En;
| |
| Vn = p1 - x;
| |
| En = CP((p2-p1),pN);
| |
| if( ((p1-x)*CP(p2-p1,pN) >= 0)&&((p2-x)*CP(p3-p2,pN) >= 0)&&((p3-x)*CP(p1-p3,pN) >= 0) ) return TRUE;
| |
| return FALSE;}
| |
| #else
| |
| integer gTXcC(vector p1,vector p2,vector p3,vector x){
| |
| gTiP(p1,p2,p3);
| |
| vector Vn = p1 - x;
| |
| vector En = CP((p2-p1),pN);
| |
| return( ((p1-x)*CP(p2-p1,pN) >= 0) && ((p2-x)*CP(p3-p2,pN) >= 0) && ((p3-x)*CP(p1-p3,pN) >= 0) );}
| |
| #endif
| |
|
| |
| #if 0
| |
| integer gTVXcC(vector p1,vector p2,vector p3,vector v,vector x){
| |
| if( ((p1-x)*CP(p2-p1,v) >= 0)&&((p2-x)*CP(p3-p2,v) >= 0)&&((p3-x)*CP(p1-p3,v) >= 0) ) return TRUE;
| |
| return FALSE;}
| |
| #else
| |
| integer gTVXcC(vector p1,vector p2,vector p3,vector v,vector x){
| |
| // Can be used to check weather a point is inside a triangle
| |
| return ( ((p1-x)*CP(p2-p1,v) >= 0)&&((p2-x)*CP(p3-p2,v) >= 0)&&((p3-x)*CP(p1-p3,v) >= 0) );}
| |
| #endif
| |
|
| |
| #define gTRcC gTVXcC
| |
| #ifndef gTRcC
| |
| integer gTRcC(vector p1,vector p2,vector p3,vector O,vector D){
| |
| return gTVXcC(p1,p2,p3,O,D);}
| |
| #endif
| |
|
| |
| #define gRZiX(O, D, z) ((O)+(D)*(z))
| |
| #ifndef gRZiX
| |
| vector gRZiX(vector O,vector D,float z){
| |
| return O+z*D;}
| |
| #endif</lsl>
| |