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