diff options
Diffstat (limited to 'js/helper-classes/3D')
-rwxr-xr-x | js/helper-classes/3D/StageLine.js | 309 |
1 files changed, 177 insertions, 132 deletions
diff --git a/js/helper-classes/3D/StageLine.js b/js/helper-classes/3D/StageLine.js index b86673d1..23e8cf5b 100755 --- a/js/helper-classes/3D/StageLine.js +++ b/js/helper-classes/3D/StageLine.js | |||
@@ -184,138 +184,183 @@ var StageLine = exports.StageLine = Object.create(Object.prototype, { | |||
184 | }, | 184 | }, |
185 | 185 | ||
186 | doCoplanarIntersection: { | 186 | doCoplanarIntersection: { |
187 | value: function( plane ) | 187 | value: function( plane ) |
188 | { | 188 | { |
189 | // get the boundary points for the plane | 189 | // get the boundary points for the plane |
190 | var boundaryPts = plane.getBoundaryPoints(); | 190 | var boundaryPts = plane.getBoundaryPoints(); |
191 | var planeEq = plane.getPlaneEq(); | 191 | var planeEq = plane.getPlaneEq(); |
192 | 192 | ||
193 | if (plane.isBackFacing()) | 193 | if (plane.isBackFacing()) |
194 | { | 194 | { |
195 | var tmp; | 195 | var tmp; |
196 | tmp = boundaryPts[0]; boundaryPts[0] = boundaryPts[3]; boundaryPts[3] = tmp; | 196 | tmp = boundaryPts[0]; boundaryPts[0] = boundaryPts[3]; boundaryPts[3] = tmp; |
197 | tmp = boundaryPts[1]; boundaryPts[1] = boundaryPts[2]; boundaryPts[2] = tmp; | 197 | tmp = boundaryPts[1]; boundaryPts[1] = boundaryPts[2]; boundaryPts[2] = tmp; |
198 | } | 198 | } |
199 | 199 | ||
200 | var pt0 = this.getPoint0(), | 200 | var pt0 = this.getPoint0(), |
201 | pt1 = this.getPoint1(); | 201 | pt1 = this.getPoint1(); |
202 | 202 | ||
203 | // keep a couple flags to prevent counting crossings twice in edge cases | 203 | // keep a couple flags to prevent counting crossings twice in edge cases |
204 | var gotEnter = false, | 204 | var gotEnter = false, |
205 | gotExit = false; | 205 | gotExit = false; |
206 | 206 | ||
207 | var bp1 = boundaryPts[3]; | 207 | var bp1 = boundaryPts[3]; |
208 | for (var i=0; i<4; i++) | 208 | for (var i=0; i<4; i++) |
209 | { | 209 | { |
210 | var bp0 = bp1; | 210 | var bp0 = bp1; |
211 | bp1 = boundaryPts[i]; | 211 | bp1 = boundaryPts[i]; |
212 | var vec = vecUtils.vecSubtract(3, bp1, bp0); | 212 | var vec = vecUtils.vecSubtract(3, bp1, bp0); |
213 | var nrm = vecUtils.vecCross(3, vec, planeEq); | 213 | var nrm = vecUtils.vecCross(3, vec, planeEq); |
214 | nrm[3] = -vecUtils.vecDot(3, bp0, nrm); | 214 | nrm[3] = -vecUtils.vecDot(3, bp0, nrm); |
215 | 215 | ||
216 | var d0 = vecUtils.vecDot(3, nrm, pt0) + nrm[3], | 216 | var d0 = vecUtils.vecDot(3, nrm, pt0) + nrm[3], |
217 | d1 = vecUtils.vecDot(3, nrm, pt1) + nrm[3]; | 217 | d1 = vecUtils.vecDot(3, nrm, pt1) + nrm[3]; |
218 | 218 | ||
219 | var s0 = MathUtils.fpSign(d0), | 219 | var s0 = MathUtils.fpSign(d0), |
220 | s1 = MathUtils.fpSign(d1); | 220 | s1 = MathUtils.fpSign(d1); |
221 | 221 | ||
222 | if (s0 != s1) | 222 | if (s0 != s1) |
223 | { | 223 | { |
224 | var t = Math.abs(d0)/( Math.abs(d0) + Math.abs(d1) ); | 224 | var t = Math.abs(d0)/( Math.abs(d0) + Math.abs(d1) ); |
225 | if ( (MathUtils.fpSign(t) >= 0) && (MathUtils.fpCmp(t,1.0) <= 0)) | 225 | if (t == 0) |
226 | { | 226 | { |
227 | // get the point where the line crosses the edge of the element plane | 227 | if (s1 > 0) // entering the material from the beginning of the line that is to be drawn |
228 | var pt = MathUtils.interpolateLine3D(pt0, pt1, t ); | 228 | { |
229 | 229 | // see if the start point of the line is at a corner of the bounded plane | |
230 | // we know that the line crosses the infinite extension of the edge. Determine | 230 | var lineDir = vecUtils.vecSubtract(3, pt1, pt0); |
231 | // if that crossing is within the bounds of the edge | 231 | vecUtils.vecNormalize(3, lineDir); |
232 | var dot0 = vecUtils.vecDot(3, vecUtils.vecSubtract(3,pt, bp0), vec), | 232 | var dist = vecUtils.vecDist( 3, pt0, bp1 ); |
233 | dot1 = vecUtils.vecDot(3, vecUtils.vecSubtract(3,pt, bp1), vec); | 233 | var bp2, bv0, bv1, cross1, cross2, cross3; |
234 | if ((MathUtils.fpSign(dot0) > 0) && (MathUtils.fpSign(dot1) < 0)) | 234 | if ( MathUtils.fpSign(dist) == 0) |
235 | { | 235 | { |
236 | // determine if the line is entering or exiting | 236 | bp2 = boundaryPts[(i+1) % 4]; |
237 | if (s0 <= 0) // entering | 237 | bv0 = vecUtils.vecSubtract(3, bp2, bp1); |
238 | { | 238 | bv1 = vecUtils.vecSubtract(3, bp0, bp1); |
239 | if (!gotEnter) | 239 | cross1 = vecUtils.vecCross(3, bv0, lineDir); |
240 | { | 240 | cross2 = vecUtils.vecCross(3, lineDir, bv1); |
241 | gotEnter = true; | 241 | cross3 = vecUtils.vecCross(3, bv0, bv1); |
242 | this.addIntersection( plane, t, 1 ); | 242 | if ( (MathUtils.fpSign(vecUtils.vecDot(3, cross1, cross3)) == 0) && (MathUtils.fpSign(vecUtils.vecDot(3, cross2, cross3)) == 0)) |
243 | } | 243 | { |
244 | } | 244 | gotEnter = true; |
245 | else if (s0 > 0) // exiting | 245 | this.addIntersection( plane, t, 1 ); |
246 | { | 246 | } |
247 | if (!gotExit) | 247 | } |
248 | { | 248 | else if (MathUtils.fpSign( vecUtils.vecDist(3, pt0, bp0)) === 0) |
249 | gotExit = true; | 249 | { |
250 | this.addIntersection( plane, t, -1 ); | 250 | bp2 = boundaryPts[(i+2) % 4]; |
251 | } | 251 | bv0 = vecUtils.vecSubtract(3, bp2, bp0); |
252 | } | 252 | bv1 = vecUtils.vecSubtract(3, bp1, bp0); |
253 | else // s0 == 0 | 253 | cross1 = vecUtils.vecCross(3, bv0, lineDir); |
254 | { | 254 | cross2 = vecUtils.vecCross(3, lineDir, bv1); |
255 | // TODO | 255 | cross3 = vecUtils.vecCross(3, bv0, bv1); |
256 | } | 256 | if ( (MathUtils.fpSign(vecUtils.vecDot(3, cross1, cross3)) == 0) && (MathUtils.fpSign(vecUtils.vecDot(3, cross2, cross3)) == 0)) |
257 | } | 257 | { |
258 | else if ((MathUtils.fpSign(dot0) == 0) && (MathUtils.fpSign(dot1) < 0)) | 258 | gotEnter = true; |
259 | { | 259 | this.addIntersection( plane, t, 1 ); |
260 | var j = i - 2; | 260 | } |
261 | if (j < 0) j += 4; | 261 | } |
262 | var bp = boundaryPts[j]; | 262 | else |
263 | 263 | { | |
264 | var v0 = vecUtils.vecSubtract( 3, bp, bp0 ), | 264 | // check if the line is on the edge of the boundary or goes to the interior |
265 | v1 = vec; | 265 | gotEnter = true; |
266 | 266 | this.addIntersection( plane, t, 1 ); | |
267 | if (s0 <= 0) | 267 | } |
268 | { | 268 | } |
269 | var v = vecUtils.vecSubtract(3, pt1, pt0); | 269 | } |
270 | if ((MathUtils.fpSign(vecUtils.vecCross(3, v0,v)) > 0) && (MathUtils.fpSign(vecUtils.vecCross(3, v,v1)) > 0)) | 270 | else if ( (MathUtils.fpSign(t) > 0) && (MathUtils.fpCmp(t,1.0) <= 0)) |
271 | { | 271 | { |
272 | gotEnter = true; | 272 | // get the point where the line crosses the edge of the element plane |
273 | this.addIntersection( plane, t, 1 ); | 273 | var pt = MathUtils.interpolateLine3D(pt0, pt1, t ); |
274 | } | 274 | |
275 | } | 275 | // we know that the line crosses the infinite extension of the edge. Determine |
276 | else if (s0 > 0) | 276 | // if that crossing is within the bounds of the edge |
277 | { | 277 | var dot0 = vecUtils.vecDot(3, vecUtils.vecSubtract(3,pt, bp0), vec), |
278 | var v = vecUtils.vecSubtract(3, pt0, pt1); // note the reversed order from the previous case | 278 | dot1 = vecUtils.vecDot(3, vecUtils.vecSubtract(3,pt, bp1), vec); |
279 | if ((MathUtils.fpSign(vecUtils.vecCross(3, v0,v)) > 0) && (MathUtils.fpSign(vecUtils.vecCross(3, v,v1)) > 0)) | 279 | if ((MathUtils.fpSign(dot0) > 0) && (MathUtils.fpSign(dot1) < 0)) |
280 | { | 280 | { |
281 | gotEnter = true; | 281 | // determine if the line is entering or exiting |
282 | this.addIntersection( plane, t, -1 ); | 282 | if (s0 <= 0) // entering |
283 | } | 283 | { |
284 | } | 284 | if (!gotEnter) |
285 | } | 285 | { |
286 | else if ((MathUtils.fpSign(dot0) > 0) && (MathUtils.fpSign(dot1) == 0)) | 286 | gotEnter = true; |
287 | { | 287 | this.addIntersection( plane, t, 1 ); |
288 | var j = (i + 1) % 4; | 288 | } |
289 | var bp = boundaryPts[j]; | 289 | } |
290 | 290 | else if (s0 > 0) // exiting | |
291 | var v1 = vec.slice(0), | 291 | { |
292 | v0 = vecUtils.vecSubtract( 3, bp, bp1 ), | 292 | if (!gotExit) |
293 | v1 = vecUtils.vecNegate(3, v1); | 293 | { |
294 | 294 | gotExit = true; | |
295 | if (s0 <= 0) | 295 | this.addIntersection( plane, t, -1 ); |
296 | { | 296 | } |
297 | var v = vecUtils.vecSubtract(3, pt1, pt0); | 297 | } |
298 | if ((MathUtils.fpSign(vecUtils.vecCross(3, v0,v)) < 0) && (MathUtils.fpSign(vecUtils.vecCross(3, v,v1)) < 0)) | 298 | else // s0 == 0 |
299 | { | 299 | { |
300 | gotEnter = true; | 300 | // TODO |
301 | this.addIntersection( plane, t, 1 ); | 301 | } |
302 | } | 302 | } |
303 | } | 303 | else if ((MathUtils.fpSign(dot0) == 0) && (MathUtils.fpSign(dot1) < 0)) |
304 | else if (s0 > 0) | 304 | { |
305 | { | 305 | var j = i - 2; |
306 | var v = vecUtils.vecSubtract(3, pt0, pt1); // note the reversed order from the previous case | 306 | if (j < 0) j += 4; |
307 | if ((MathUtils.fpSign(vecUtils.vecCross(3, v0,v)) > 0) && (MathUtils.fpSign(vecUtils.vecCross(3, v,v1)) > 0)) | 307 | var bp = boundaryPts[j]; |
308 | { | 308 | |
309 | gotEnter = true; | 309 | var v0 = vecUtils.vecSubtract( 3, bp, bp0 ), |
310 | this.addIntersection( plane, t, -1 ); | 310 | v1 = vec; |
311 | } | 311 | |
312 | } | 312 | if (s0 <= 0) |
313 | } | 313 | { |
314 | } | 314 | var v = vecUtils.vecSubtract(3, pt1, pt0); |
315 | } | 315 |