diff options
Diffstat (limited to 'js/helper-classes')
-rwxr-xr-x | js/helper-classes/3D/StageLine.js | 187 | ||||
-rwxr-xr-x | js/helper-classes/3D/math-utils.js | 9 |
2 files changed, 167 insertions, 29 deletions
diff --git a/js/helper-classes/3D/StageLine.js b/js/helper-classes/3D/StageLine.js index 5aaa325a..f9abc5ce 100755 --- a/js/helper-classes/3D/StageLine.js +++ b/js/helper-classes/3D/StageLine.js | |||
@@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE. | |||
34 | // The line class represents a line intersected with all planes on the scene | 34 | // The line class represents a line intersected with all planes on the scene |
35 | /////////////////////////////////////////////////////////////////////// | 35 | /////////////////////////////////////////////////////////////////////// |
36 | var vecUtils = require("js/helper-classes/3D/vec-utils").VecUtils; | 36 | var vecUtils = require("js/helper-classes/3D/vec-utils").VecUtils; |
37 | var viewUtils = require( "js/helper-classes/3D/view-utils").ViewUtils; | ||
37 | var LinePlaneIntersectRec = require("js/helper-classes/3D/LinePlaneIntersectRec").LinePlaneIntersectRec; | 38 | var LinePlaneIntersectRec = require("js/helper-classes/3D/LinePlaneIntersectRec").LinePlaneIntersectRec; |
38 | 39 | ||
39 | var StageLine = exports.StageLine = Object.create(Object.prototype, { | 40 | var StageLine = exports.StageLine = Object.create(Object.prototype, { |
@@ -96,7 +97,7 @@ var StageLine = exports.StageLine = Object.create(Object.prototype, { | |||
96 | if (minPt[2] > plane.getZMax()) return; | 97 | if (minPt[2] > plane.getZMax()) return; |
97 | 98 | ||
98 | // get the boundary points for the plane | 99 | // get the boundary points for the plane |
99 | var boundaryPts = plane.getBoundaryPoints(); | 100 | var boundaryPts = plane.getBoundaryPoints().slice(); |
100 | 101 | ||
101 | // get the points and direction vector for the current line | 102 | // get the points and direction vector for the current line |
102 | var pt0 = this.getPoint0(), pt1 = this.getPoint1(); | 103 | var pt0 = this.getPoint0(), pt1 = this.getPoint1(); |
@@ -115,7 +116,8 @@ var StageLine = exports.StageLine = Object.create(Object.prototype, { | |||
115 | 116 | ||
116 | // see if the intersection point is contained in the bounds | 117 | // see if the intersection point is contained in the bounds |
117 | //var contains = this.boundaryContainsPoint( boundaryPts, plane.isBackFacing(), pt ); | 118 | //var contains = this.boundaryContainsPoint( boundaryPts, plane.isBackFacing(), pt ); |
118 | var contains = MathUtils.boundaryContainsPoint( boundaryPts, pt, plane.isBackFacing() ); | 119 | var onEdge = []; |
120 | var contains = MathUtils.boundaryContainsPoint( boundaryPts, pt, plane.isBackFacing(), onEdge ); | ||
119 | if (contains == MathUtils.INSIDE) | 121 | if (contains == MathUtils.INSIDE) |
120 | { | 122 | { |
121 | // add the intersection | 123 | // add the intersection |
@@ -130,23 +132,40 @@ var StageLine = exports.StageLine = Object.create(Object.prototype, { | |||
130 | { | 132 | { |
131 | if (MathUtils.fpCmp(t,1.0) < 0) | 133 | if (MathUtils.fpCmp(t,1.0) < 0) |
132 | { | 134 | { |
133 | // take the dot product between the line and the normal to the plane | 135 | // determine if the intersection is on a front side (no intersection) of the polygons |
134 | // to determine the change in visibility | 136 | //var ctr = [ 0.5*(boundaryPts[0][0] + boundaryPts[2][0]), 0.5*(boundaryPts[0][1] + boundaryPts[2][1]), 0.5*(boundaryPts[0][2] + boundaryPts[2][2]) ]; |
135 | var vec = vecUtils.vecSubtract( 3, pt1, pt0 ); | 137 | //var vec = vecUtils.vecSubtract(3, pt, ctr ); |
136 | var dot = vecUtils.vecDot( 3, vec, plane.getPlaneEq() ); | 138 | if (this.edgeGoesBehindPlane( plane, boundaryPts, onEdge[0], onEdge[1], pt0, pt1 )) |
137 | var sign = MathUtils.fpSign( dot ); | ||
138 | if (sign == 0) | ||
139 | throw new Error( "coplanar intersection being treated as not coplanar" ); | ||
140 | if (!plane.isBackFacing()) | ||
141 | { | 139 | { |
142 | if (sign < 0) | 140 | this.addIntersection( plane, t, 1 ); |
143 | this.addIntersection( plane, t, 1 ); | ||
144 | } | 141 | } |
145 | else | 142 | else if (this.edgeGoesBehindPlane( plane, boundaryPts, onEdge[0], onEdge[1], pt1, pt0 )) |
146 | { | 143 | { |
147 | if (sign > 0) | 144 | this.addIntersection( plane, t, -1 ); |
148 | this.addIntersection( plane, t, -1 ); | 145 | } |
146 | |||
147 | /* | ||
148 | if ( !this.edgeIsFrontFacing(boundaryPts, planeEq, plane.isBackFacing(), onEdge[0], onEdge[1]) ) | ||
149 | { | ||
150 | // take the dot product between the line and the normal to the plane | ||
151 | // to determine the change in visibility | ||
152 | var vec = vecUtils.vecSubtract( 3, pt1, pt0 ); | ||
153 | var dot = vecUtils.vecDot( 3, vec, planeEq ); | ||
154 | var sign = MathUtils.fpSign( dot ); | ||
155 | if (sign == 0) | ||
156 | throw new Error( "coplanar intersection being treated as not coplanar" ); | ||
157 | if (!plane.isBackFacing()) | ||
158 | { | ||
159 | if (sign < 0) | ||
160 | this.addIntersection( plane, t, 1 ); | ||
161 | } | ||
162 | else | ||
163 | { | ||
164 | if (sign > 0) | ||
165 | this.addIntersection( plane, t, -1 ); | ||
166 | } | ||
149 | } | 167 | } |
168 | */ | ||
150 | } | 169 | } |
151 | } | 170 | } |
152 | } | 171 | } |
@@ -208,18 +227,122 @@ var StageLine = exports.StageLine = Object.create(Object.prototype, { | |||
208 | } | 227 | } |
209 | }, | 228 | }, |
210 | 229 | ||
230 | edgeGoesBehindPlane: | ||
231 | { | ||
232 | value: function( plane, boundaryPts, iEdge, t, lPt0, lPt1 ) | ||
233 | { | ||
234 | var rtnVal = false; | ||
235 | |||
236 | if ( MathUtils.fpCmp(t,1.0) == 0 ) | ||
237 | { | ||
238 | iEdge = (iEdge + 1) % 4; | ||
239 | t = 0.0; | ||
240 | } | ||
241 | |||
242 | // boundary points (line points: lPt0, lPt1) | ||
243 | var bPt0, bPt1, bPt2, bVec, bVec0, bVec1, lVec, d; | ||
244 | |||
245 | var planeEq = plane.getPlaneEq(); | ||
246 | if (MathUtils.fpSign(t) == 0) | ||
247 | { | ||
248 | // get the 3 relevant points. The line goes through pt1. | ||
249 | bPt0 = boundaryPts[(iEdge+3)%4].slice(); | ||
250 | bPt1 = boundaryPts[iEdge].slice(); | ||
251 | bPt2 = boundaryPts[(iEdge+1)%4].slice(); | ||
252 | bVec0 = vecUtils.vecSubtract(2, bPt0, bPt1); | ||
253 | bVec1 = vecUtils.vecSubtract(2, bPt2, bPt1); | ||
254 | lVec = vecUtils.vecSubtract(2, lPt1, bPt1); | ||
255 | |||
256 | var c0 = vecUtils.vecCross(2, bVec1, lVec), | ||
257 | c1 = vecUtils.vecCross(2, lVec, bVec0); | ||
258 | // if ((MathUtils.fpSign(c0) < 0) && (MathUtils.fpSign(c1) < 0)) | ||
259 | // rtnVal = true; | ||
260 | if (!plane.isBackFacing() && (MathUtils.fpSign(c0) < 0) && (MathUtils.fpSign(c1) < 0)) | ||
261 | rtnVal = true; | ||
262 | else if (plane.isBackFacing() && (MathUtils.fpSign(c0) > 0) && (MathUtils.fpSign(c1) > 0)) | ||
263 | rtnVal = true; | ||
264 | |||
265 | d = vecUtils.vecDot(3, lPt1, planeEq) + planeEq[3]; | ||
266 | if (rtnVal && (MathUtils.fpSign(d) > 0)) rtnVal = false; | ||
267 | } | ||
268 | else | ||
269 | { | ||
270 | bPt0 = boundaryPts[iEdge].slice(); | ||
271 | bPt1 = boundaryPts[(iEdge+1)%4].slice(); | ||
272 | bVec = vecUtils.vecSubtract(3, bPt1, bPt0); | ||
273 | lVec = vecUtils.vecSubtract(3, lPt1, lPt0); | ||
274 | |||
275 | var backFacing = plane.isBackFacing(); | ||
276 | var bNormal = vecUtils.vecCross(3, [0,0,1], bVec); | ||
277 | var dot = vecUtils.vecDot(3, bNormal, lVec); | ||
278 | if ((!backFacing && (MathUtils.fpSign(dot) < 0)) || (backFacing && (MathUtils.fpSign(dot) > 0))) | ||
279 | { | ||
280 | d = vecUtils.vecDot(3, lPt1, planeEq) + planeEq[3]; | ||
281 | if (MathUtils.fpSign(d) < 0) rtnVal = true; | ||
282 | } | ||
283 | } | ||
284 | |||
285 | return rtnVal; | ||
286 | } | ||
287 | }, | ||
288 | |||
289 | edgeIsFrontFacing: | ||
290 | { | ||
291 | value: function(boundaryPts, planeNormal, backfacing, iEdge, t) | ||
292 | { | ||
293 | var frontFacing = false; | ||
294 | if (MathUtils.fpCmp(t,1.0) == 0) | ||
295 | { | ||
296 | iEdge = (iEdge + 1) % 4; | ||
297 | t = 0.0; | ||
298 | } | ||
299 | |||
300 | var pt0 = boundaryPts[iEdge].slice(), | ||
301 | pt1 = boundaryPts[(iEdge+1)%4].slice(); | ||
302 | |||
303 | var ctr = [ 0.5*(boundaryPts[0][0] + boundaryPts[2][0]), 0.5*(boundaryPts[0][1] + boundaryPts[2][1]), 0.5*(boundaryPts[0][2] + boundaryPts[2][2]) ], | ||
304 | mid = MathUtils.interpolateLine3D( pt0, pt1, 0.5 ); | ||
305 | var vec = vecUtils.vecSubtract( 3, mid, ctr ); | ||
306 | |||
307 | if (MathUtils.fpSign(t) == 0) | ||
308 | { | ||
309 | // if the edge already calculated is back facing, check the preceeding edge | ||
310 | if (vec[2] > 0) | ||
311 | { | ||
312 | frontFacing = true; | ||
313 | } | ||
314 | else | ||
315 | { | ||
316 | var ptm1 = boundaryPts[(iEdge+3)%4].slice(); | ||
317 | mid = MathUtils.interpolateLine3D( ptm1, pt0, 0.5 ); | ||
318 | vec = vecUtils.vecSubtract( 3, mid, ctr ); | ||
319 | if (vec[2] > 0) frontFacing = true; | ||
320 | } | ||
321 | } | ||
322 | else | ||
323 | { | ||
324 | var cross = VecUtils.vecCross( 3, planeNormal, vecUtils.vecSubtract(3, pt1, pt0) ); | ||
325 | if ((!backfacing && (cross[2] > 0)) || (backfacing && (cross[2] < 0))) frontFacing = true; | ||
326 | } | ||
327 | |||
328 | return frontFacing; | ||
329 | } | ||
330 | }, | ||
331 | |||
211 | doCoplanarIntersection: { | 332 | doCoplanarIntersection: { |
212 | value: function( plane ) | 333 | value: function( plane ) |
213 | { | 334 | { |
214 | // get the boundary points for the plane | 335 | // get the boundary points for the plane |
215 | var boundaryPts = plane.getBoundaryPoints(); | 336 | var boundaryPts = plane.getBoundaryPoints().slice(); |
216 | var planeEq = plane.getPlaneEq(); | 337 | var planeEq = plane.getPlaneEq(); |
217 | 338 | ||
218 | if (plane.isBackFacing()) | 339 | var backFacing = plane.isBackFacing(); |
340 | if (backFacing) | ||
219 | { | 341 | { |
220 | var tmp; | 342 | var tmp; |
221 | tmp = boundaryPts[0]; boundaryPts[0] = boundaryPts[3]; boundaryPts[3] = tmp; | 343 | tmp = boundaryPts[0]; boundaryPts[0] = boundaryPts[3]; boundaryPts[3] = tmp; |
222 | tmp = boundaryPts[1]; boundaryPts[1] = boundaryPts[2]; boundaryPts[2] = tmp; | 344 | tmp = boundaryPts[1]; boundaryPts[1] = boundaryPts[2]; boundaryPts[2] = tmp; |
345 | vecUtils.vecNegate(4, planeEq); | ||
223 | } | 346 | } |
224 | 347 | ||