diff options
-rwxr-xr-x | js/helper-classes/3D/StageLine.js | 184 | ||||
-rwxr-xr-x | js/helper-classes/3D/math-utils.js | 9 |
2 files changed, 164 insertions, 29 deletions
diff --git a/js/helper-classes/3D/StageLine.js b/js/helper-classes/3D/StageLine.js index 5aaa325a..17021e91 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,119 @@ 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; | ||
244 | |||
245 | if (MathUtils.fpSign(t) == 0) | ||
246 | { | ||
247 | // get the 3 relevant points. The line goes through pt1. | ||
248 | bPt0 = boundaryPts[(iEdge+3)%4].slice(); | ||
249 | bPt1 = boundaryPts[iEdge].slice(); | ||
250 | bPt2 = boundaryPts[(iEdge+1)%4].slice(); | ||
251 | bVec0 = vecUtils.vecSubtract(2, bPt0, bPt1); | ||
252 | bVec1 = vecUtils.vecSubtract(2, bPt2, bPt1); | ||
253 | lVec = vecUtils.vecSubtract(2, lPt1, bPt1); | ||
254 | |||
255 | var c0 = vecUtils.vecCross(2, bVec1, lVec), | ||
256 | c1 = vecUtils.vecCross(2, lVec, bVec0); | ||
257 | // if ((MathUtils.fpSign(c0) < 0) && (MathUtils.fpSign(c1) < 0)) | ||
258 | // rtnVal = true; | ||
259 | if (!plane.isBackFacing() && (MathUtils.fpSign(c0) < 0) && (MathUtils.fpSign(c1) < 0)) | ||
260 | rtnVal = true; | ||
261 | else if (plane.isBackFacing() && (MathUtils.fpSign(c0) > 0) && (MathUtils.fpSign(c1) > 0)) | ||
262 | rtnVal = true; | ||
263 | } | ||
264 | else | ||
265 | { | ||
266 | bPt0 = boundaryPts[iEdge].slice(); | ||
267 | bPt1 = boundaryPts[(iEdge+1)%4].slice(); | ||
268 | bVec = vecUtils.vecSubtract(3, bPt1, bPt0); | ||
269 | lVec = vecUtils.vecSubtract(3, lPt1, lPt0); | ||
270 | |||
271 | var planeEq = plane.getPlaneEq(); | ||
272 | var bNormal = vecUtils.vecCross(3, planeEq, bVec); | ||
273 | var dot = vecUtils.vecDot(3, bNormal, lVec); | ||
274 | if (MathUtils.fpSign(dot) < 0) | ||
275 | { | ||
276 | var d = vecUtils.vecDot(3, lPt1, planeEq) + planeEq[3]; | ||
277 | if (plane.isBackFacing()) d = -d; | ||
278 | if (MathUtils.fpSign(d) < 0) rtnVal = true; | ||
279 | } | ||
280 | } | ||
281 | |||
282 | return rtnVal; | ||
283 | } | ||
284 | }, | ||
285 | |||
286 | edgeIsFrontFacing: | ||
287 | { | ||
288 | value: function(boundaryPts, planeNormal, backfacing, iEdge, t) | ||
289 | { | ||
290 | var frontFacing = false; | ||
291 | if (MathUtils.fpCmp(t,1.0) == 0) | ||
292 | { | ||
293 | iEdge = (iEdge + 1) % 4; | ||
294 | t = 0.0; | ||
295 | } | ||
296 | |||
297 | var pt0 = boundaryPts[iEdge].slice(), | ||
298 | pt1 = boundaryPts[(iEdge+1)%4].slice(); | ||
299 | |||
300 | 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]) ], | ||
301 | mid = MathUtils.interpolateLine3D( pt0, pt1, 0.5 ); | ||
302 | var vec = vecUtils.vecSubtract( 3, mid, ctr ); | ||
303 | |||
304 | if (MathUtils.fpSign(t) == 0) | ||
305 | { | ||
306 | // if the edge already calculated is back facing, check the preceeding edge | ||
307 | if (vec[2] > 0) | ||
308 | { | ||
309 | frontFacing = true; | ||
310 | } | ||
311 | else | ||
312 | { | ||
313 | var ptm1 = boundaryPts[(iEdge+3)%4].slice(); | ||
314 | mid = MathUtils.interpolateLine3D( ptm1, pt0, 0.5 ); | ||
315 | vec = vecUtils.vecSubtract( 3, mid, ctr ); | ||
316 | if (vec[2] > 0) frontFacing = true; | ||
317 | } | ||
318 | } | ||
319 | else | ||
320 | { | ||
321 | var cross = VecUtils.vecCross( 3, planeNormal, vecUtils.vecSubtract(3, pt1, pt0) ); | ||
322 | if ((!backfacing && (cross[2] > 0)) || (backfacing && (cross[2] < 0))) frontFacing = true; | ||
323 | } | ||
324 | |||
325 | return frontFacing; | ||
326 | } | ||
327 | }, | ||
328 | |||
211 | doCoplanarIntersection: { | 329 | doCoplanarIntersection: { |
212 | value: function( plane ) | 330 | value: function( plane ) |
213 | { | 331 | { |
214 | // get the boundary points for the plane | 332 | // get the boundary points for the plane |
215 | var boundaryPts = plane.getBoundaryPoints(); | 333 | var boundaryPts = plane.getBoundaryPoints().slice(); |
216 | var planeEq = plane.getPlaneEq(); | 334 | var planeEq = plane.getPlaneEq(); |
217 | 335 | ||
218 | if (plane.isBackFacing()) | 336 | var backFacing = plane.isBackFacing(); |
337 | if (backFacing) | ||
219 | { | 338 | { |
220 | var tmp; | 339 | var tmp; |
221 | tmp = boundaryPts[0]; boundaryPts[0] = boundaryPts[3]; boundaryPts[3] = tmp; | 340 | tmp = boundaryPts[0]; boundaryPts[0] = boundaryPts[3]; boundaryPts[3] = tmp; |
222 | tmp = boundaryPts[1]; boundaryPts[1] = boundaryPts[2]; boundaryPts[2] = tmp; | 341 | tmp = boundaryPts[1]; boundaryPts[1] = boundaryPts[2]; boundaryPts[2] = tmp; |
342 | vecUtils.vecNegate(4, planeEq); | ||
223 | } | 343 | } |
224 | 344 | ||
225 | var pt0 = this.getPoint0(), | 345 | var pt0 = this.getPoint0(), |
@@ -246,19 +366,27 @@ var StageLine = exports.StageLine = Object.create(Object.prototype, { | |||
246 | 366 | ||
247 | if (s0 != s1) | 367 | if (s0 != s1) |
248 | { |