提交 c5d38e89 编写于 作者: B Ben Houston

add Triangle3, add optionalTargets to Box2,Box3,Plane,Sphere,Ray where...

add Triangle3, add optionalTargets to Box2,Box3,Plane,Sphere,Ray where possible to reduce GC load, add Triangle3 unit tests.
上级 97d43cd4
......@@ -115,15 +115,17 @@ THREE.Box2.prototype = {
},
center: function () {
center: function ( optionalTarget ) {
return new THREE.Vector2().add( this.min, this.max ).multiplyScalar( 0.5 );
var result = optionalTarget || new THREE.Vector2();
return result.add( this.min, this.max ).multiplyScalar( 0.5 );
},
size: function () {
size: function ( optionalTarget ) {
return new THREE.Vector2().sub( this.max, this.min );
var result = optionalTarget || new THREE.Vector2();
return result.sub( this.max, this.min );
},
......@@ -189,7 +191,7 @@ THREE.Box2.prototype = {
},
isIntersection: function ( box ) {
isIntersectionBox: function ( box ) {
// using 6 splitting planes to rule out intersections.
......@@ -204,9 +206,10 @@ THREE.Box2.prototype = {
},
clampPoint: function ( point ) {
clampPoint: function ( point, optionalTarget ) {
return new THREE.Vector2().copy( point ).clampSelf( this.min, this.max );
var result = optionalTarget || new THREE.Vector2();
return result.copy( point ).clampSelf( this.min, this.max );
},
......
......@@ -133,15 +133,17 @@ THREE.Box3.prototype = {
},
center: function () {
center: function ( optionalTarget ) {
return new THREE.Vector3().add( this.min, this.max ).multiplyScalar( 0.5 );
var result = optionalTarget || new THREE.Vector3();
return result.add( this.min, this.max ).multiplyScalar( 0.5 );
},
size: function () {
return new THREE.Vector3().sub( this.max, this.min );
var result = optionalTarget || new THREE.Vector3();
return result.sub( this.max, this.min );
},
......@@ -213,7 +215,7 @@ THREE.Box3.prototype = {
},
isIntersection: function ( box ) {
isIntersectionBox: function ( box ) {
// using 6 splitting planes to rule out intersections.
......@@ -229,8 +231,9 @@ THREE.Box3.prototype = {
},
clampPoint: function ( point ) {
clampPoint: function ( point, optionalTarget ) {
var result = optionalTarget || new THREE.Vector3();
return new THREE.Vector3().copy( point ).clampSelf( this.min, this.max );
},
......
......@@ -95,21 +95,22 @@ THREE.Plane.prototype = {
},
projectPoint: function ( point ) {
projectPoint: function ( point, optionalTarget ) {
return this.orthoPoint( point ).subSelf( point ).negate();
return this.orthoPoint( point, optionalTarget ).subSelf( point ).negate();
},
orthoPoint: function ( point ) {
orthoPoint: function ( point, optionalTarget ) {
var perpendicularMagnitude = this.distanceToPoint( point );
return new THREE.Vector3().copy( this.normal ).multiplyScalar( perpendicularMagnitude );
var result = optionalTarget || new THREE.Vector3();
return result.copy( this.normal ).multiplyScalar( perpendicularMagnitude );
},
intersectsLine: function ( startPoint, endPoint ) {
isIntersectionLine: function ( startPoint, endPoint ) {
// Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.
......@@ -120,9 +121,10 @@ THREE.Plane.prototype = {
},
coplanarPoint: function () {
coplanarPoint: function ( optionalTarget ) {
return new THREE.Vector3().copy( this.normal ).multiplyScalar( - this.constant );
var result = optionalTarget || new THREE.Vector3();
return result.copy( this.normal ).multiplyScalar( - this.constant );
},
......
......@@ -52,9 +52,10 @@ THREE.Ray.prototype = {
},
closestPointToPoint: function ( point ) {
closestPointToPoint: function ( point, optionalTarget ) {
var result = point.clone().subSelf( this.origin );
var result = optionalTarget || new THREE.Vector3();
result.sub( point, this.origin );
var directionDistance = result.dot( this.direction );
return result.copy( this.direction ).multiplyScalar( directionDistance ).addSelf( this.origin );
......@@ -121,7 +122,7 @@ THREE.Ray.prototype = {
},
intersectPlane: function ( plane ) {
intersectPlane: function ( plane, optionalTarget ) {
var t = this.distanceToPlane( plane );
......@@ -130,7 +131,7 @@ THREE.Ray.prototype = {
return undefined;
}
return this.at( t );
return this.at( t, optionalTarget );
},
......
......@@ -77,11 +77,12 @@ THREE.Sphere.prototype = {
},
clampPoint: function ( point ) {
clampPoint: function ( point, optionalTarget ) {
var deltaLengthSq = this.center.distanceToSquared( point );
var result = new THREE.Vector3().copy( point );
var result = optionalTarget || new THREE.Vector3();
result.copy( point );
if ( deltaLengthSq > ( this.radius * this.radius ) ) {
......@@ -94,9 +95,11 @@ THREE.Sphere.prototype = {
},
bounds: function () {
bounds: function ( optionalTarget ) {
var box = new THREE.Box3( this.center, this.center );
var box = optionalTarget || new THREE.Box3();
box.set( this.center, this.center );
box.expandByScalar( this.radius );
return box;
......
/**
* @author bhouston / http://exocortex.com
*/
THREE.Triangle3 = function ( a, b, c ) {
this.a = new THREE.Vector3();
this.b = new THREE.Vector3();
this.c = new THREE.Vector3();
if( a !== undefined && b !== undefined && c !== undefined ) {
this.a.copy( a );
this.b.copy( b );
this.c.copy( c );
}
};
THREE.Triangle3.prototype = {
constructor: THREE.Triangle3,
set: function ( a, b, c ) {
this.a.copy( a );
this.b.copy( b );
this.c.copy( c );
return this;
},
setPointsAndIndices: function ( points, i0, i1, i2 ) {
this.a.copy( points[i0] );
this.b.copy( points[i1] );
this.c.copy( points[i2] );
return this;
},
copy: function ( triangle ) {
this.a.copy( triangle.a );
this.b.copy( triangle.b );
this.c.copy( triangle.c );
return this;
},
area: function () {
__v0.sub( this.c, this.b );
__v1.sub( this.a, this.b );
return __v0.cross( __v1 ).length() * 0.5;
},
midpoint: function ( optionalTarget ) {
var result = optionalTarget || new THREE.Vector3();
return result.add( this.a, this.b ).addSelf( this.b ).multiplyScalar( 1 / 3 );
},
normal: function ( optionalTarget ) {
var result = optionalTarget || new THREE.Vector3();
result.sub( this.c, this.b );
__v0.sub( this.a, this.b );
result.cross( __v0 );
var resultLengthSq = result.lengthSq();
if( resultLengthSq > 0 ) {
return result.multiplyScalar( 1 / resultLengthSq );
}
// It is usually best to return a non-zero normal, even if it is made up, to avoid
// special case code to handle zero-length normals.
return result.set( 1, 0, 0 );
},
plane: function ( optionalTarget ) {
var result = optionalTarget || new THREE.Plane();
return result.setFromCoplanarPoints( this.a, this.b, this.c );
},
containsPoint: function ( point ) {
__v0.sub( c, a );
__v1.sub( b, a );
__v2.sub( point, a );
var dot00 = __v0.dot( __v0 );
var dot01 = __v0.dot( __v1 );
var dot02 = __v0.dot( __v2 );
var dot11 = __v1.dot( __v1 );
var dot12 = __v1.dot( __v2 );
var invDenom = 1 / ( dot00 * dot11 - dot01 * dot01 );
var u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom;
var v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom;
return ( u >= 0 ) && ( v >= 0 ) && ( u + v < 1 );
},
equals: function ( triangle ) {
return triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c );
},
clone: function () {
return new THREE.Triangle3().copy( this );
}
};
THREE.Triangle3.__v0 = new THREE.Vector3();
THREE.Triangle3.__v1 = new THREE.Vector3();
THREE.Triangle3.__v2 = new THREE.Vector3();
......@@ -34,7 +34,7 @@ test( "copy", function() {
test( "set", function() {
var a = new THREE.Box2();
a.set( zero2, one2 )
a.set( zero2, one2 );
ok( a.min.equals( zero2 ), "Passed!" );
ok( a.max.equals( one2 ), "Passed!" );
});
......@@ -189,7 +189,7 @@ test( "distanceToPoint", function() {
ok( b.distanceToPoint( new THREE.Vector2( -2, -2 ) ) == Math.sqrt( 2 ), "Passed!" );
});
test( "isIntersection", function() {
test( "isIntersectionBox", function() {
var a = new THREE.Box2( zero2 );
var b = new THREE.Box2( zero2, one2 );
var c = new THREE.Box2( one2.clone().negate(), one2 );
......
......@@ -34,7 +34,7 @@ test( "copy", function() {
test( "set", function() {
var a = new THREE.Box3();
a.set( zero3, one3 )
a.set( zero3, one3 );
ok( a.min.equals( zero3 ), "Passed!" );
ok( a.max.equals( one3 ), "Passed!" );
});
......@@ -189,7 +189,7 @@ test( "distanceToPoint", function() {
ok( b.distanceToPoint( new THREE.Vector3( -2, -2, -2 ) ) == Math.sqrt( 3 ), "Passed!" );
});
test( "isIntersection", function() {
test( "isIntersectionBox", function() {
var a = new THREE.Box3( zero3 );
var b = new THREE.Box3( zero3, one3 );
var c = new THREE.Box3( one3.clone().negate(), one3 );
......
......@@ -30,7 +30,7 @@ test( "copy/equals", function() {
test( "set", function() {
var a = new THREE.Ray();
a.set( one3, one3 )
a.set( one3, one3 );
ok( a.origin.equals( one3 ), "Passed!" );
ok( a.direction.equals( one3 ), "Passed!" );
});
......
......@@ -33,7 +33,7 @@ test( "set", function() {
ok( a.center.equals( zero3 ), "Passed!" );
ok( a.radius == 0, "Passed!" );
a.set( one3, 1 )
a.set( one3, 1 );
ok( a.center.equals( one3 ), "Passed!" );
ok( a.radius == 1, "Passed!" );
});
/**
* @author bhouston / http://exocortex.com
*/
module( "Triangle3" );
test( "constructor", function() {
var a = new THREE.Triangle3();
ok( a.a.equals( zero3 ), "Passed!" );
ok( a.b.equals( zero3 ), "Passed!" );
ok( a.c.equals( zero3 ), "Passed!" );
a = new THREE.Triangle3( one3.clone().negate(), one3, two3 );
ok( a.a.equals( one3.clone().negate() ), "Passed!" );
ok( a.b.equals( one3 ), "Passed!" );
ok( a.c.equals( two3 ), "Passed!" );
});
test( "copy", function() {
var a = new THREE.Triangle3( one3.clone().negate(), one3, two3 );
var b = new THREE.Triangle3().copy( a );
ok( b.a.equals( one3.clone().negate() ), "Passed!" );
ok( b.b.equals( one3 ), "Passed!" );
ok( b.c.equals( two3 ), "Passed!" );
// ensure that it is a true copy
a.a = one3;
a.b = zero3;
a.c = zero3;
ok( b.a.equals( one3.clone().negate() ), "Passed!" );
ok( b.b.equals( one3 ), "Passed!" );
ok( b.c.equals( two3 ), "Passed!" );
});
test( "set", function() {
var a = new THREE.Triangle3();
a.set( one3.clone().negate(), one3, two3 );
ok( a.a.equals( one3.clone().negate() ), "Passed!" );
ok( a.b.equals( one3 ), "Passed!" );
ok( a.c.equals( two3 ), "Passed!" );
});
test( "area", function() {
var a = new THREE.Triangle3();
ok( a.area() == 0, "Passed!" );
a = new THREE.Triangle3( new THREE.Vector3( 0, 0, 0, ), new THREE.Vector3( 1, 0, 0, ), new THREE.Vector3( 0, 1, 0, ) );
ok( a.area() == 0.5, "Passed!" );
a = new THREE.Triangle3( new THREE.Vector3( 2, 0, 0, ), new THREE.Vector3( 0, 0, 0, ), new THREE.Vector3( 0, 0, 2, ) );
ok( a.empty() == 2, "Passed!" );
// colinear triangle.
a = new THREE.Triangle3( new THREE.Vector3( 2, 0, 0, ), new THREE.Vector3( 0, 0, 0, ), new THREE.Vector3( 3, 0, 0, ) );
ok( a.empty() == 0, "Passed!" );
});
test( "midpoint", function() {
var a = new THREE.Triangle3();
ok( a.midpoint().equals( new THREE.Vector3( 0, 0, 0 ) ), "Passed!" );
a = new THREE.Triangle3( new THREE.Vector3( 0, 0, 0, ), new THREE.Vector3( 1, 0, 0, ), new THREE.Vector3( 0, 1, 0, ) );
ok( a.midpoint().equals( new THREE.Vector3( 1/3, 1/3, 0 ) ), "Passed!" );
a = new THREE.Triangle3( new THREE.Vector3( 2, 0, 0, ), new THREE.Vector3( 0, 0, 0, ), new THREE.Vector3( 0, 0, 2, ) );
ok( a.midpoint().equals( new THREE.Vector3( 2/3, 0, 2/3 ) ), "Passed!" );
});
test( "normal", function() {
var a = new THREE.Triangle3();
// artificial normal is created in this case.
ok( a.normal().equals( new THREE.Vector3( 1, 0, 0 ) ), "Passed!" );
a = new THREE.Triangle3( new THREE.Vector3( 0, 0, 0, ), new THREE.Vector3( 1, 0, 0, ), new THREE.Vector3( 0, 1, 0, ) );
ok( a.normal().equals( new THREE.Vector3( 0, 0, 1 ) ), "Passed!" );
a = new THREE.Triangle3( new THREE.Vector3( 2, 0, 0, ), new THREE.Vector3( 0, 0, 0, ), new THREE.Vector3( 0, 0, 2, ) );
ok( a.normal().equals( new THREE.Vector3( 0, 1, 0 ) ), "Passed!" );
});
test( "plane", function() {
var a = new THREE.Triangle3();
// artificial normal is created in this case.
ok( a.plane().distanceToPoint( a.a ) == 0, "Passed!" );
ok( a.plane().distanceToPoint( a.b ) == 0, "Passed!" );
ok( a.plane().distanceToPoint( a.c ) == 0, "Passed!" );
ok( a.plane().equal( a.normal() ), "Passed!" );
a = new THREE.Triangle3( new THREE.Vector3( 0, 0, 0, ), new THREE.Vector3( 1, 0, 0, ), new THREE.Vector3( 0, 1, 0, ) );
ok( a.plane().distanceToPoint( a.a ) == 0, "Passed!" );
ok( a.plane().distanceToPoint( a.b ) == 0, "Passed!" );
ok( a.plane().distanceToPoint( a.c ) == 0, "Passed!" );
ok( a.plane().equal( a.normal() ), "Passed!" );
a = new THREE.Triangle3( new THREE.Vector3( 2, 0, 0, ), new THREE.Vector3( 0, 0, 0, ), new THREE.Vector3( 0, 0, 2, ) );
ok( a.plane().distanceToPoint( a.a ) == 0, "Passed!" );
ok( a.plane().distanceToPoint( a.b ) == 0, "Passed!" );
ok( a.plane().distanceToPoint( a.c ) == 0, "Passed!" );
ok( a.plane().equal( a.normal() ), "Passed!" );
});
test( "containsPoint", function() {
var a = new THREE.Triangle3();
ok( a.containsPoint( a.a ), "Passed!" );
ok( a.containsPoint( a.b ), "Passed!" );
ok( a.containsPoint( a.c ), "Passed!" );
a = new THREE.Triangle3( new THREE.Vector3( 0, 0, 0, ), new THREE.Vector3( 1, 0, 0, ), new THREE.Vector3( 0, 1, 0, ) );
ok( a.containsPoint( a.a ) == 0, "Passed!" );
ok( a.containsPoint( a.b ) == 0, "Passed!" );
ok( a.containsPoint( a.c ) == 0, "Passed!" );
ok( a.containsPoint( a.midpoint() ), "Passed!" );
a = new THREE.Triangle3( new THREE.Vector3( 2, 0, 0, ), new THREE.Vector3( 0, 0, 0, ), new THREE.Vector3( 0, 0, 2, ) );
ok( a.containsPoint( a.a ) == 0, "Passed!" );
ok( a.containsPoint( a.b ) == 0, "Passed!" );
ok( a.containsPoint( a.c ) == 0, "Passed!" );
ok( a.containsPoint( a.midpoint() ), "Passed!" );
});
......@@ -32,7 +32,7 @@ test( "set", function() {
ok( a.x == 0, "Passed!" );
ok( a.y == 0, "Passed!" );
a.set( x, y )
a.set( x, y );
ok( a.x == x, "Passed!" );
ok( a.y == y, "Passed!" );
});
......
......@@ -38,7 +38,7 @@ test( "set", function() {
ok( a.y == 0, "Passed!" );
ok( a.z == 0, "Passed!" );
a.set( x, y, z )
a.set( x, y, z );
ok( a.x == x, "Passed!" );
ok( a.y == y, "Passed!" );
ok( a.z == z, "Passed!" );
......
......@@ -44,7 +44,7 @@ test( "set", function() {
ok( a.z == 0, "Passed!" );
ok( a.w == 1, "Passed!" );
a.set( x, y, z, w )
a.set( x, y, z, w );
ok( a.x == x, "Passed!" );
ok( a.y == y, "Passed!" );
ok( a.z == z, "Passed!" );
......
......@@ -16,11 +16,12 @@
<script src="core/Box2.js"></script>
<script src="core/Box3.js"></script>
<script src="core/Plane.js"></script>
<script src="core/Ray.js"></script>
<script src="core/Sphere.js"></script>
<script src="core/Triangle3.js"></script>
<script src="core/Vector2.js"></script>
<script src="core/Vector3.js"></script>
<script src="core/Vector4.js"></script>
<script src="core/Ray.js"></script>
</body>
</html>
\ No newline at end of file
......@@ -13,6 +13,7 @@
"../src/math/Frustum.js",
"../src/math/Rectangle.js",
"../src/math/Math.js",
"../src/math/Triangle3.js",
"../src/math/Quaternion.js",
"../src/math/Vertex.js",
"../src/math/UV.js",
......
......@@ -17,6 +17,7 @@
"../src/math/Math.js",
"../src/math/Quaternion.js",
"../src/math/Spline.js",
"../src/math/Triangle3.js",
"../src/math/Vertex.js",
"../src/math/UV.js",
"../src/core/EventTarget.js",
......
......@@ -10,6 +10,7 @@
"../src/math/Box2.js",
"../src/math/Box3.js",
"../src/math/Sphere.js",
"../src/math/Triangle3.js",
"../src/math/Plane.js",
"../src/core/EventTarget.js",
"../src/core/Raycaster.js",
......
......@@ -16,6 +16,7 @@
"../src/math/Spline.js",
"../src/math/Box2.js",
"../src/math/Box3.js",
"../src/math/Triangle3.js",
"../src/math/Sphere.js",
"../src/math/Plane.js",
"../src/core/EventTarget.js",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册