1 | /**
|
---|
2 | * @author bhouston / http://exocortex.com
|
---|
3 | */
|
---|
4 |
|
---|
5 | THREE.Plane = function ( normal, constant ) {
|
---|
6 |
|
---|
7 | this.normal = ( normal !== undefined ) ? normal : new THREE.Vector3( 1, 0, 0 );
|
---|
8 | this.constant = ( constant !== undefined ) ? constant : 0;
|
---|
9 |
|
---|
10 | };
|
---|
11 |
|
---|
12 | THREE.Plane.prototype = {
|
---|
13 |
|
---|
14 | constructor: THREE.Plane,
|
---|
15 |
|
---|
16 | set: function ( normal, constant ) {
|
---|
17 |
|
---|
18 | this.normal.copy( normal );
|
---|
19 | this.constant = constant;
|
---|
20 |
|
---|
21 | return this;
|
---|
22 |
|
---|
23 | },
|
---|
24 |
|
---|
25 | setComponents: function ( x, y, z, w ) {
|
---|
26 |
|
---|
27 | this.normal.set( x, y, z );
|
---|
28 | this.constant = w;
|
---|
29 |
|
---|
30 | return this;
|
---|
31 |
|
---|
32 | },
|
---|
33 |
|
---|
34 | setFromNormalAndCoplanarPoint: function ( normal, point ) {
|
---|
35 |
|
---|
36 | this.normal.copy( normal );
|
---|
37 | this.constant = - point.dot( this.normal ); // must be this.normal, not normal, as this.normal is normalized
|
---|
38 |
|
---|
39 | return this;
|
---|
40 |
|
---|
41 | },
|
---|
42 |
|
---|
43 | setFromCoplanarPoints: function() {
|
---|
44 |
|
---|
45 | var v1 = new THREE.Vector3();
|
---|
46 | var v2 = new THREE.Vector3();
|
---|
47 |
|
---|
48 | return function ( a, b, c ) {
|
---|
49 |
|
---|
50 | var normal = v1.subVectors( c, b ).cross( v2.subVectors( a, b ) ).normalize();
|
---|
51 |
|
---|
52 | // Q: should an error be thrown if normal is zero (e.g. degenerate plane)?
|
---|
53 |
|
---|
54 | this.setFromNormalAndCoplanarPoint( normal, a );
|
---|
55 |
|
---|
56 | return this;
|
---|
57 |
|
---|
58 | };
|
---|
59 |
|
---|
60 | }(),
|
---|
61 |
|
---|
62 |
|
---|
63 | copy: function ( plane ) {
|
---|
64 |
|
---|
65 | this.normal.copy( plane.normal );
|
---|
66 | this.constant = plane.constant;
|
---|
67 |
|
---|
68 | return this;
|
---|
69 |
|
---|
70 | },
|
---|
71 |
|
---|
72 | normalize: function () {
|
---|
73 |
|
---|
74 | // Note: will lead to a divide by zero if the plane is invalid.
|
---|
75 |
|
---|
76 | var inverseNormalLength = 1.0 / this.normal.length();
|
---|
77 | this.normal.multiplyScalar( inverseNormalLength );
|
---|
78 | this.constant *= inverseNormalLength;
|
---|
79 |
|
---|
80 | return this;
|
---|
81 |
|
---|
82 | },
|
---|
83 |
|
---|
84 | negate: function () {
|
---|
85 |
|
---|
86 | this.constant *= -1;
|
---|
87 | this.normal.negate();
|
---|
88 |
|
---|
89 | return this;
|
---|
90 |
|
---|
91 | },
|
---|
92 |
|
---|
93 | distanceToPoint: function ( point ) {
|
---|
94 |
|
---|
95 | return this.normal.dot( point ) + this.constant;
|
---|
96 |
|
---|
97 | },
|
---|
98 |
|
---|
99 | distanceToSphere: function ( sphere ) {
|
---|
100 |
|
---|
101 | return this.distanceToPoint( sphere.center ) - sphere.radius;
|
---|
102 |
|
---|
103 | },
|
---|
104 |
|
---|
105 | projectPoint: function ( point, optionalTarget ) {
|
---|
106 |
|
---|
107 | return this.orthoPoint( point, optionalTarget ).sub( point ).negate();
|
---|
108 |
|
---|
109 | },
|
---|
110 |
|
---|
111 | orthoPoint: function ( point, optionalTarget ) {
|
---|
112 |
|
---|
113 | var perpendicularMagnitude = this.distanceToPoint( point );
|
---|
114 |
|
---|
115 | var result = optionalTarget || new THREE.Vector3();
|
---|
116 | return result.copy( this.normal ).multiplyScalar( perpendicularMagnitude );
|
---|
117 |
|
---|
118 | },
|
---|
119 |
|
---|
120 | isIntersectionLine: function ( line ) {
|
---|
121 |
|
---|
122 | // Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.
|
---|
123 |
|
---|
124 | var startSign = this.distanceToPoint( line.start );
|
---|
125 | var endSign = this.distanceToPoint( line.end );
|
---|
126 |
|
---|
127 | return ( startSign < 0 && endSign > 0 ) || ( endSign < 0 && startSign > 0 );
|
---|
128 |
|
---|
129 | },
|
---|
130 |
|
---|
131 | intersectLine: function() {
|
---|
132 |
|
---|
133 | var v1 = new THREE.Vector3();
|
---|
134 |
|
---|
135 | return function ( line, optionalTarget ) {
|
---|
136 |
|
---|
137 | var result = optionalTarget || new THREE.Vector3();
|
---|
138 |
|
---|
139 | var direction = line.delta( v1 );
|
---|
140 |
|
---|
141 | var denominator = this.normal.dot( direction );
|
---|
142 |
|
---|
143 | if ( denominator == 0 ) {
|
---|
144 |
|
---|
145 | // line is coplanar, return origin
|
---|
146 | if( this.distanceToPoint( line.start ) == 0 ) {
|
---|
147 |
|
---|
148 | return result.copy( line.start );
|
---|
149 |
|
---|
150 | }
|
---|
151 |
|
---|
152 | // Unsure if this is the correct method to handle this case.
|
---|
153 | return undefined;
|
---|
154 |
|
---|
155 | }
|
---|
156 |
|
---|
157 | var t = - ( line.start.dot( this.normal ) + this.constant ) / denominator;
|
---|
158 |
|
---|
159 | if( t < 0 || t > 1 ) {
|
---|
160 |
|
---|
161 | return undefined;
|
---|
162 |
|
---|
163 | }
|
---|
164 |
|
---|
165 | return result.copy( direction ).multiplyScalar( t ).add( line.start );
|
---|
166 |
|
---|
167 | };
|
---|
168 |
|
---|
169 | }(),
|
---|
170 |
|
---|
171 |
|
---|
172 | coplanarPoint: function ( optionalTarget ) {
|
---|
173 |
|
---|
174 | var result = optionalTarget || new THREE.Vector3();
|
---|
175 | return result.copy( this.normal ).multiplyScalar( - this.constant );
|
---|
176 |
|
---|
177 | },
|
---|
178 |
|
---|
179 | applyMatrix4: function() {
|
---|
180 |
|
---|
181 | var v1 = new THREE.Vector3();
|
---|
182 | var v2 = new THREE.Vector3();
|
---|
183 | var m1 = new THREE.Matrix3();
|
---|
184 |
|
---|
185 | return function ( matrix, optionalNormalMatrix ) {
|
---|
186 |
|
---|
187 | // compute new normal based on theory here:
|
---|
188 | // http://www.songho.ca/opengl/gl_normaltransform.html
|
---|
189 | var normalMatrix = optionalNormalMatrix || m1.getNormalMatrix( matrix );
|
---|
190 | var newNormal = v1.copy( this.normal ).applyMatrix3( normalMatrix );
|
---|
191 |
|
---|
192 | var newCoplanarPoint = this.coplanarPoint( v2 );
|
---|
193 | newCoplanarPoint.applyMatrix4( matrix );
|
---|
194 |
|
---|
195 | this.setFromNormalAndCoplanarPoint( newNormal, newCoplanarPoint );
|
---|
196 |
|
---|
197 | return this;
|
---|
198 |
|
---|
199 | };
|
---|
200 |
|
---|
201 | }(),
|
---|
202 |
|
---|
203 | translate: function ( offset ) {
|
---|
204 |
|
---|
205 | this.constant = this.constant - offset.dot( this.normal );
|
---|
206 |
|
---|
207 | return this;
|
---|
208 |
|
---|
209 | },
|
---|
210 |
|
---|
211 | equals: function ( plane ) {
|
---|
212 |
|
---|
213 | return plane.normal.equals( this.normal ) && ( plane.constant == this.constant );
|
---|
214 |
|
---|
215 | },
|
---|
216 |
|
---|
217 | clone: function () {
|
---|
218 |
|
---|
219 | return new THREE.Plane().copy( this );
|
---|
220 |
|
---|
221 | }
|
---|
222 |
|
---|
223 | };
|
---|