aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xjs/helper-classes/3D/StageLine.js373
-rwxr-xr-xjs/helper-classes/3D/math-utils.js12
2 files changed, 231 insertions, 154 deletions
diff --git a/js/helper-classes/3D/StageLine.js b/js/helper-classes/3D/StageLine.js
index 23e8cf5b..12efb140 100755
--- a/js/helper-classes/3D/StageLine.js
+++ b/js/helper-classes/3D/StageLine.js
@@ -52,149 +52,201 @@ var StageLine = exports.StageLine = Object.create(Object.prototype, {
52 // Methods 52 // Methods
53 /////////////////////////////////////////////////////////////////////// 53 ///////////////////////////////////////////////////////////////////////
54 54
55 intersectWithPlane: { 55 intersectWithPlane: {
56 value: function( plane ) 56 value: function( plane )
57 { 57 {
58 // if the plane is edge-on, ignore it 58 // if the plane is edge-on, ignore it
59 if ( MathUtils.fpSign( plane.getPlaneEq()[2] ) == 0 ) return; 59 if ( MathUtils.fpSign( plane.getPlaneEq()[2] ) == 0 ) return;
60 60
61 // do some quick box tests. 61 // do some quick box tests.
62 var minPt = this.getMinPoint(), 62 var minPt = this.getMinPoint(),
63 maxPt = this.getMaxPoint(); 63 maxPt = this.getMaxPoint();
64 64
65 if (maxPt[0] < plane._rect.getLeft()) return; 65 if (maxPt[0] < plane._rect.getLeft()) return;
66 if (minPt[0] > plane._rect.getRight()) return; 66 if (minPt[0] > plane._rect.getRight()) return;
67 67
68 if (maxPt[1] < plane._rect.getTop()) return; 68 if (maxPt[1] < plane._rect.getTop()) return;
69 if (minPt[1] > plane._rect.getBottom()) return; 69 if (minPt[1] > plane._rect.getBottom()) return;
70 70
71 if (minPt[2] > plane.getZMax()) return; 71 if (minPt[2] > plane.getZMax()) return;
72 72
73 // get the boundary points for the plane 73 // get the boundary points for the plane
74 var boundaryPts = plane.getBoundaryPoints(); 74 var boundaryPts = plane.getBoundaryPoints().slice();
75 75
76 // get the points and direction vector for the current line 76 // get the points and direction vector for the current line
77 var pt0 = this.getPoint0(), pt1 = this.getPoint1(); 77 var pt0 = this.getPoint0(), pt1 = this.getPoint1();
78 //var lineDir = pt1.subtract( pt0 ); 78 //var lineDir = pt1.subtract( pt0 );
79 var lineDir = vecUtils.vecSubtract(3, pt1, pt0); 79 var lineDir = vecUtils.vecSubtract(3, pt1, pt0);
80 80
81 // intersect with the front plane 81 // intersect with the front plane
82 var planeEq = plane.getPlaneEq(); 82 var planeEq = plane.getPlaneEq();
83 var t = MathUtils.vecIntersectPlaneForParam( pt0, lineDir, planeEq ); 83 var t = MathUtils.vecIntersectPlaneForParam( pt0, lineDir, planeEq );
84 if (t != undefined) 84 if (t != undefined)
85 { 85 {
86 if ((MathUtils.fpSign(t) >= 0) && (MathUtils.fpCmp(t,1.0) <= 0)) 86 if ((MathUtils.fpSign(t) >= 0) && (MathUtils.fpCmp(t,1.0) <= 0))
87 { 87 {
88 // get the intersection point 88 // get the intersection point
89 var pt = MathUtils.interpolateLine3D( pt0, pt1, t ); 89 var pt = MathUtils.interpolateLine3D( pt0, pt1, t );
90 90
91 // see if the intersection point is contained in the bounds 91 // see if the intersection point is contained in the bounds
92 //var contains = this.boundaryContainsPoint( boundaryPts, plane.isBackFacing(), pt ); 92 //var contains = this.boundaryContainsPoint( boundaryPts, plane.isBackFacing(), pt );
93 var contains = MathUtils.boundaryContainsPoint( boundaryPts, pt, plane.isBackFacing() ); 93 var onEdge = [];
94 if (contains == MathUtils.INSIDE) 94 var contains = MathUtils.boundaryContainsPoint( boundaryPts, pt, plane.isBackFacing(), onEdge );
95 { 95 if (contains == MathUtils.INSIDE)
96 // add the intersection 96 {
97 var dot = MathUtils.dot3( pt0, planeEq ) + planeEq[3]; 97 // add the intersection
98 var deltaVis = (dot > 0) ? 1 : -1; 98 var dot = MathUtils.dot3( pt0, planeEq ) + planeEq[3];
99 var deltaVis = (dot > 0) ? 1 : -1;
99// if (plane.isBackFacing()) 100// if (plane.isBackFacing())
100// deltaVis = (dot < 0) ? 1 : -1; 101// deltaVis = (dot < 0) ? 1 : -1;
101 102
102 this.addIntersection( plane, t, deltaVis ); 103 this.addIntersection( plane, t, deltaVis );
103 } 104 }
104 else if (contains == MathUtils.ON) 105 else if (contains == MathUtils.ON)
105 { 106 {
106 if (MathUtils.fpCmp(t,1.0) < 0) 107 if (MathUtils.fpCmp(t,1.0) < 0)
107 { 108 {
108 // take the dot product between the line and the normal to the plane 109 // determine if the intersection is on a front side (no intersection) of the polygons
109 // to determine the change in visibility 110 //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]) ];
110 var vec = vecUtils.vecSubtract( 3, pt1, pt0 ); 111 //var vec = vecUtils.vecSubtract(3, pt, ctr );
111 var dot = vecUtils.vecDot( 3, vec, plane.getPlaneEq() ); 112 if ( !this.edgeIsFrontFacing(boundaryPts, planeEq, plane.isBackFacing(), onEdge[0], onEdge[1]) )
112 var sign = MathUtils.fpSign( dot ); 113 {
113 if (sign == 0) 114 // take the dot product between the line and the normal to the plane
114 throw new Error( "coplanar intersection being treated as not coplanar" ); 115 // to determine the change in visibility
115 if (!plane.isBackFacing()) 116 var vec = vecUtils.vecSubtract( 3, pt1, pt0 );
116 { 117 var dot = vecUtils.vecDot( 3, vec, planeEq );
117 if (sign < 0) 118 var sign = MathUtils.fpSign( dot );
118 this.addIntersection( plane, t, 1 ); 119 if (sign == 0)
119 } 120 throw new Error( "coplanar intersection being treated as not coplanar" );
120 else 121 if (!plane.isBackFacing())
121 { 122 {
122 if (sign > 0) 123 if (sign < 0)
123 this.addIntersection( plane, t, -1 ); 124 this.addIntersection( plane, t, 1 );
124 } 125 }
125 } 126 else
126 } 127 {
127 } 128 if (sign > 0)
128 } 129 this.addIntersection( plane, t, -1 );
129 else 130 }
130 { 131 }
131 // the line must be parallel to the plane. If the line is in the plane, 132 }
132 // we need to do some special processing 133 }
133 var d0 = vecUtils.vecDot(3, planeEq, pt0) + planeEq[3], 134 }
134 d1 = vecUtils.vecDot(3, planeEq, pt1) + planeEq[3]; 135 }
135 if ((MathUtils.fpSign(d0) == 0) && (MathUtils.fpSign(d1) == 0)) 136 else
136 this.doCoplanarIntersection( plane ); 137 {
137 } 138 // the line must be parallel to the plane. If the line is in the plane,
139 // we need to do some special processing
140 var d0 = vecUtils.vecDot(3, planeEq, pt0) + planeEq[3],
141 d1 = vecUtils.vecDot(3, planeEq, pt1) + planeEq[3];
142 if ((MathUtils.fpSign(d0) == 0) && (MathUtils.fpSign(d1) == 0))
143 this.doCoplanarIntersection( plane );
144 }
138 145
139 // intersect with the 4 planes formed by the edges of the plane, going back in Z 146 // intersect with the 4 planes formed by the edges of the plane, going back in Z
140 var bPt1 = boundaryPts[3]; 147 var bPt1 = boundaryPts[3];
141 for (var i=0; i<4; i++) 148 for (var i=0; i<4; i++)
142 { 149 {
143 // get the 2 points that define the front edge of the plane 150 // get the 2 points that define the front edge of the plane
144 var bPt0 = bPt1; 151 var bPt0 = bPt1;
145 var bPt1 = boundaryPts[i]; 152 var bPt1 = boundaryPts[i];
146 153
147 // calculate the plane equation. The normal should point towards the OUTSIDE of the boundary 154 // calculate the plane equation. The normal should point towards the OUTSIDE of the boundary
148 //var vec = bPt1.subtract( bPt0 ); 155 //var vec = bPt1.subtract( bPt0 );
149 var vec = vecUtils.vecSubtract(3, bPt1, bPt0); 156 var vec = vecUtils.vecSubtract(3, bPt1, bPt0);
150 if (plane.isBackFacing()) 157 if (plane.isBackFacing())
151 MathUtils.negate( vec ); 158 MathUtils.negate( vec );
152 planeEq = [-vec[1], vec[0], 0]; 159 planeEq = [-vec[1], vec[0], 0];
153 var normal = [planeEq[0], planeEq[1], planeEq[2]]; 160 var normal = [planeEq[0], planeEq[1], planeEq[2]];
154// var d = -planeEq.dot(bPt0); 161// var d = -planeEq.dot(bPt0);
155 var d = -vecUtils.vecDot(3, planeEq, bPt0); 162 var d = -vecUtils.vecDot(3, planeEq, bPt0);
156 planeEq[3] = d; 163 planeEq[3] = d;
157 164
158 t = MathUtils.vecIntersectPlaneForParam( pt0, lineDir, planeEq ); 165 t = MathUtils.vecIntersectPlaneForParam( pt0, lineDir, planeEq );
159 if (t) 166 if (t)
160 { 167 {
161 if ((MathUtils.fpSign(t) > 0) && (MathUtils.fpCmp(t,1.0) <= 0)) // the strict vs not-strict inequality comparisons are IMPORTANT! 168 if ((MathUtils.fpSign(t) > 0) && (MathUtils.fpCmp(t,1.0) <= 0)) // the strict vs not-strict inequality comparisons are IMPORTANT!
162 { 169 {
163 // get the intersection point 170 // get the intersection point
164 var pt = MathUtils.interpolateLine3D( pt0, pt1, t ); 171 var pt = MathUtils.interpolateLine3D( pt0, pt1, t );
165 172
166 // we need to get the parameter on the edge of the projection 173 // we need to get the parameter on the edge of the projection
167 // of the intersection point onto the line. 174 // of the intersection point onto the line.
168 var index = (Math.abs(vec[0]) > Math.abs(vec[1])) ? 0 : 1; 175 var index = (Math.abs(vec[0]) > Math.abs(vec[1])) ? 0 : 1;
169 var tEdge = (pt[index] - bPt0[index])/(bPt1[index] - bPt0[index]); 176 var tEdge = (pt[index] - bPt0[index])/(bPt1[index] - bPt0[index]);
170 if ((MathUtils.fpSign(tEdge) > 0) && (MathUtils.fpCmp(tEdge,1.0) <= 0)) 177 if ((MathUtils.fpSign(tEdge) > 0) && (MathUtils.fpCmp(tEdge,1.0) <= 0))
171 { 178 {
172 var edgePt = MathUtils.interpolateLine3D( bPt0, bPt1, tEdge ); 179 var edgePt = MathUtils.interpolateLine3D( bPt0, bPt1, tEdge );
173 if (MathUtils.fpCmp(pt[2],edgePt[2]) < 0) 180 if (MathUtils.fpCmp(pt[2],edgePt[2]) < 0)
174 { 181 {
175 // add the intersection 182 // add the intersection
176 var deltaVis = MathUtils.dot(lineDir,normal) > 0 ? -1 : 1; 183 var deltaVis = MathUtils.dot(lineDir,normal) > 0 ? -1 : 1;
177 this.addIntersection( plane, t, deltaVis );