|
@@ -93,53 +93,70 @@ THREE.Ray.prototype = {
|
|
|
|
|
|
}(),
|
|
|
|
|
|
- distanceSqToSegment: function ( v0, v1, optionalPointOnRay, optionalPointOnSegment ) {
|
|
|
+ distanceSqToSegment: function () {
|
|
|
|
|
|
- // from http://www.geometrictools.com/LibMathematics/Distance/Wm5DistRay3Segment3.cpp
|
|
|
- // It returns the min distance between the ray and the segment
|
|
|
- // defined by v0 and v1
|
|
|
- // It can also set two optional targets :
|
|
|
- // - The closest point on the ray
|
|
|
- // - The closest point on the segment
|
|
|
+ var segCenter = new THREE.Vector3();
|
|
|
+ var segDir = new THREE.Vector3();
|
|
|
+ var diff = new THREE.Vector3();
|
|
|
+
|
|
|
+ return function ( v0, v1, optionalPointOnRay, optionalPointOnSegment ) {
|
|
|
+
|
|
|
+ // from http://www.geometrictools.com/LibMathematics/Distance/Wm5DistRay3Segment3.cpp
|
|
|
+ // It returns the min distance between the ray and the segment
|
|
|
+ // defined by v0 and v1
|
|
|
+ // It can also set two optional targets :
|
|
|
+ // - The closest point on the ray
|
|
|
+ // - The closest point on the segment
|
|
|
+
|
|
|
+ segCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 );
|
|
|
+ segDir.copy( v1 ).sub( v0 ).normalize();
|
|
|
+ diff.copy( this.origin ).sub( segCenter );
|
|
|
+
|
|
|
+ var segExtent = v0.distanceTo( v1 ) * 0.5;
|
|
|
+ var a01 = - this.direction.dot( segDir );
|
|
|
+ var b0 = diff.dot( this.direction );
|
|
|
+ var b1 = - diff.dot( segDir );
|
|
|
+ var c = diff.lengthSq();
|
|
|
+ var det = Math.abs( 1 - a01 * a01 );
|
|
|
+ var s0, s1, sqrDist, extDet;
|
|
|
+
|
|
|
+ if ( det > 0 ) {
|
|
|
+
|
|
|
+ // The ray and segment are not parallel.
|
|
|
+
|
|
|
+ s0 = a01 * b1 - b0;
|
|
|
+ s1 = a01 * b0 - b1;
|
|
|
+ extDet = segExtent * det;
|
|
|
|
|
|
- var segCenter = v0.clone().add( v1 ).multiplyScalar( 0.5 );
|
|
|
- var segDir = v1.clone().sub( v0 ).normalize();
|
|
|
- var segExtent = v0.distanceTo( v1 ) * 0.5;
|
|
|
- var diff = this.origin.clone().sub( segCenter );
|
|
|
- var a01 = - this.direction.dot( segDir );
|
|
|
- var b0 = diff.dot( this.direction );
|
|
|
- var b1 = - diff.dot( segDir );
|
|
|
- var c = diff.lengthSq();
|
|
|
- var det = Math.abs( 1 - a01 * a01 );
|
|
|
- var s0, s1, sqrDist, extDet;
|
|
|
+ if ( s0 >= 0 ) {
|
|
|
|
|
|
- if ( det >= 0 ) {
|
|
|
+ if ( s1 >= - extDet ) {
|
|
|
|
|
|
- // The ray and segment are not parallel.
|
|
|
+ if ( s1 <= extDet ) {
|
|
|
|
|
|
- s0 = a01 * b1 - b0;
|
|
|
- s1 = a01 * b0 - b1;
|
|
|
- extDet = segExtent * det;
|
|
|
+ // region 0
|
|
|
+ // Minimum at interior points of ray and segment.
|
|
|
|
|
|
- if ( s0 >= 0 ) {
|
|
|
+ var invDet = 1 / det;
|
|
|
+ s0 *= invDet;
|
|
|
+ s1 *= invDet;
|
|
|
+ sqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c;
|
|
|
|
|
|
- if ( s1 >= - extDet ) {
|
|
|
+ } else {
|
|
|
|
|
|
- if ( s1 <= extDet ) {
|
|
|
+ // region 1
|
|
|
|
|
|
- // region 0
|
|
|
- // Minimum at interior points of ray and segment.
|
|
|
+ s1 = segExtent;
|
|
|
+ s0 = Math.max( 0, - ( a01 * s1 + b0 ) );
|
|
|
+ sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
|
|
|
|
|
|
- var invDet = 1 / det;
|
|
|
- s0 *= invDet;
|
|
|
- s1 *= invDet;
|
|
|
- sqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c;
|
|
|
+ }
|
|
|
|
|
|
} else {
|
|
|
|
|
|
- // region 1
|
|
|
+ // region 5
|
|
|
|
|
|
- s1 = segExtent;
|
|
|
+ s1 = - segExtent;
|
|
|
s0 = Math.max( 0, - ( a01 * s1 + b0 ) );
|
|
|
sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
|
|
|
|
|
@@ -147,69 +164,62 @@ THREE.Ray.prototype = {
|
|
|
|
|
|
} else {
|
|
|
|
|
|
- // region 5
|
|
|
+ if ( s1 <= - extDet ) {
|
|
|
|
|
|
- s1 = - segExtent;
|
|
|
- s0 = Math.max( 0, - ( a01 * s1 + b0 ) );
|
|
|
- sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
|
|
|
+ // region 4
|
|
|
|
|
|
- }
|
|
|
+ s0 = Math.max( 0, - ( - a01 * segExtent + b0 ) );
|
|
|
+ s1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );
|
|
|
+ sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
|
|
|
|
|
|
- } else {
|
|
|
+ } else if ( s1 <= extDet ) {
|
|
|
|
|
|
- if ( s1 <= - extDet ) {
|
|
|
+ // region 3
|
|
|
|
|
|
- // region 4
|
|
|
+ s0 = 0;
|
|
|
+ s1 = Math.min( Math.max( - segExtent, - b1 ), segExtent );
|
|
|
+ sqrDist = s1 * ( s1 + 2 * b1 ) + c;
|
|
|
|
|
|
- s0 = Math.max( 0, - ( - a01 * segExtent + b0 ) );
|
|
|
- s1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );
|
|
|
- sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
|
|
|
+ } else {
|
|
|
|
|
|
- } else if ( s1 <= extDet ) {
|
|
|
+ // region 2
|
|
|
|
|
|
- // region 3
|
|
|
+ s0 = Math.max( 0, - ( a01 * segExtent + b0 ) );
|
|
|
+ s1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );
|
|
|
+ sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
|
|
|
|
|
|
- s0 = 0;
|
|
|
- s1 = Math.min( Math.max( - segExtent, - b1 ), segExtent );
|
|
|
- sqrDist = s1 * ( s1 + 2 * b1 ) + c;
|
|
|
+ }
|
|
|
|
|
|
- } else {
|
|
|
+ }
|
|
|
|
|
|
- // region 2
|
|
|
+ } else {
|
|
|
|
|
|
- s0 = Math.max( 0, - ( a01 * segExtent + b0 ) );
|
|
|
- s1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent );
|
|
|
- sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
|
|
|
+ // Ray and segment are parallel.
|
|
|
|
|
|
- }
|
|
|
+ s1 = ( a01 > 0 ) ? - segExtent : segExtent;
|
|
|
+ s0 = Math.max( 0, - ( a01 * s1 + b0 ) );
|
|
|
+ sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
|
|
|
|
|
|
}
|
|
|
|
|
|
- } else {
|
|
|
+ if ( optionalPointOnRay ) {
|
|
|
|
|
|
- // Ray and segment are parallel.
|
|
|
-
|
|
|
- s1 = ( a01 > 0 ) ? - segExtent : segExtent;
|
|
|
- s0 = Math.max( 0, - ( a01 * s1 + b0 ) );
|
|
|
- sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c;
|
|
|
-
|
|
|
- }
|
|
|
+ optionalPointOnRay.copy( this.direction ).multiplyScalar( s0 ).add( this.origin );
|
|
|
|
|
|
- if ( optionalPointOnRay ) {
|
|
|
+ }
|
|
|
|
|
|
- optionalPointOnRay.copy( this.direction.clone().multiplyScalar( s0 ).add( this.origin ) );
|
|
|
+ if ( optionalPointOnSegment ) {
|
|
|
|
|
|
- }
|
|
|
+ optionalPointOnSegment.copy( segDir ).multiplyScalar( s1 ).add( segCenter );
|
|
|
|
|
|
- if ( optionalPointOnSegment ) {
|
|
|
+ }
|
|
|
|
|
|
- optionalPointOnSegment.copy( segDir.clone().multiplyScalar( s1 ).add( segCenter ) );
|
|
|
+ return sqrDist;
|
|
|
|
|
|
- }
|
|
|
+ };
|
|
|
|
|
|
- return sqrDist;
|
|
|
+ }(),
|
|
|
|
|
|
- },
|
|
|
|
|
|
isIntersectionSphere: function ( sphere ) {
|
|
|
|