diff options
Diffstat (limited to 'js/helper-classes/3D')
-rwxr-xr-x | js/helper-classes/3D/StageLine.js | 829 |
1 files changed, 443 insertions, 386 deletions
diff --git a/js/helper-classes/3D/StageLine.js b/js/helper-classes/3D/StageLine.js index 069729d0..8292c469 100755 --- a/js/helper-classes/3D/StageLine.js +++ b/js/helper-classes/3D/StageLine.js | |||
@@ -77,394 +77,451 @@ var StageLine = exports.StageLine = Object.create(Object.prototype, { | |||
77 | // Methods | 77 | // Methods |
78 | /////////////////////////////////////////////////////////////////////// | 78 | /////////////////////////////////////////////////////////////////////// |
79 | 79 | ||
80 | intersectWithPlane: { | 80 | intersectWithPlane: { |
81 | value: function( plane ) | 81 | value: function( plane ) |
82 | { | 82 | { |
83 | // if the plane is edge-on, ignore it | 83 | // if the plane is edge-on, ignore it |
84 | if ( MathUtils.fpSign( plane.getPlaneEq()[2] ) == 0 ) return; | 84 | if ( MathUtils.fpSign( plane.getPlaneEq()[2] ) == 0 ) return; |
85 | 85 | ||
86 | // do some quick box tests. | 86 | // do some quick box tests. |
87 | var minPt = this.getMinPoint(), | 87 | var minPt = this.getMinPoint(), |
88 | maxPt = this.getMaxPoint(); | 88 | maxPt = this.getMaxPoint(); |
89 | 89 | ||
90 | if (maxPt[0] < plane._rect.getLeft()) return; | 90 | if (maxPt[0] < plane._rect.getLeft()) return; |
91 | if (minPt[0] > plane._rect.getRight()) return; | 91 | if (minPt[0] > plane._rect.getRight()) return; |
92 | 92 | ||
93 | if (maxPt[1] < plane._rect.getTop()) return; | 93 | if (maxPt[1] < plane._rect.getTop()) return; |
94 | if (minPt[1] > plane._rect.getBottom()) return; | 94 | if (minPt[1] > plane._rect.getBottom()) return; |
95 | 95 | ||
96 | if (minPt[2] > plane.getZMax()) return; | 96 | if (minPt[2] > plane.getZMax()) return; |
97 | 97 | ||
98 | // get the boundary points for the plane | 98 | // get the boundary points for the plane |
99 | var boundaryPts = plane.getBoundaryPoints().slice(); | 99 | var boundaryPts = plane.getBoundaryPoints().slice(); |
100 | 100 | ||
101 | // get the points and direction vector for the current line | 101 | // get the points and direction vector for the current line |
102 | var pt0 = this.getPoint0(), pt1 = this.getPoint1(); | 102 | var pt0 = this.getPoint0(), pt1 = this.getPoint1(); |
103 | //var lineDir = pt1.subtract( pt0 ); | 103 | //var lineDir = pt1.subtract( pt0 ); |
104 | var lineDir = vecUtils.vecSubtract(3, pt1, pt0); | 104 | var lineDir = vecUtils.vecSubtract(3, pt1, pt0); |
105 | 105 | ||
106 | // intersect with the front plane | 106 | // intersect with the front plane |
107 | var planeEq = plane.getPlaneEq(); | 107 | var planeEq = plane.getPlaneEq(); |
108 | var t = MathUtils.vecIntersectPlaneForParam( pt0, lineDir, planeEq ); | 108 | var t = MathUtils.vecIntersectPlaneForParam( pt0, lineDir, planeEq ); |
109 | if (t != undefined) | 109 | if (t != undefined) |
110 | { | 110 | { |
111 | if ((MathUtils.fpSign(t) >= 0) && (MathUtils.fpCmp(t,1.0) <= 0)) | 111 | if ((MathUtils.fpSign(t) >= 0) && (MathUtils.fpCmp(t,1.0) <= 0)) |
112 | { | 112 | { |
113 | // get the intersection point | 113 | // get the intersection point |
114 | var pt = MathUtils.interpolateLine3D( pt0, pt1, t ); | 114 | var pt = MathUtils.interpolateLine3D( pt0, pt1, t ); |
115 | 115 | ||
116 | // see if the intersection point is contained in the bounds | 116 | // see if the intersection point is contained in the bounds |
117 | //var contains = this.boundaryContainsPoint( boundaryPts, plane.isBackFacing(), pt ); | 117 | //var contains = this.boundaryContainsPoint( boundaryPts, plane.isBackFacing(), pt ); |
118 | var onEdge = []; | 118 | var onEdge = []; |
119 | var contains = MathUtils.boundaryContainsPoint( boundaryPts, pt, plane.isBackFacing(), onEdge ); | 119 | var contains = MathUtils.boundaryContainsPoint( boundaryPts, pt, plane.isBackFacing(), onEdge ); |
120 | if (contains == MathUtils.INSIDE) | 120 | if (contains == MathUtils.INSIDE) |
121 | { | 121 | { |
122 | // add the intersection | 122 | // add the intersection |
123 | var dot = MathUtils.dot3( pt0, planeEq ) + planeEq[3]; | 123 | var dot = MathUtils.dot3( pt0, planeEq ) + planeEq[3]; |
124 | var deltaVis = (dot > 0) ? 1 : -1; | 124 | var deltaVis = (dot > 0) ? 1 : -1; |
125 | // if (plane.isBackFacing()) | 125 | // if (plane.isBackFacing()) |
126 | // deltaVis = (dot < 0) ? 1 : -1; | 126 | // deltaVis = (dot < 0) ? 1 : -1; |
127 | 127 | ||
128 | this.addIntersection( plane, t, deltaVis ); | 128 | this.addIntersection( plane, t, deltaVis ); |
129 | } | 129 | } |
130 | else if (contains == MathUtils.ON) | 130 | else if (contains == MathUtils.ON) |
131 | { | 131 | { |
132 | if (MathUtils.fpCmp(t,1.0) < 0) | 132 | if (MathUtils.fpCmp(t,1.0) < 0) |
133 | { | 133 | { |
134 | // determine if the intersection is on a front side (no intersection) of the polygons | 134 | // determine if the intersection is on a front side (no intersection) of the polygons |
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]) ]; | 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]) ]; |
136 | //var vec = vecUtils.vecSubtract(3, pt, ctr ); | 136 | //var vec = vecUtils.vecSubtract(3, pt, ctr ); |
137 | this.edgeIsFrontFacing2( plane ); | 137 | if (this.edgeGoesBehindPlane( plane, boundaryPts, onEdge[0], onEdge[1], pt0, pt1 )) |
138 | if ( !this.edgeIsFrontFacing(boundaryPts, planeEq, plane.isBackFacing(), onEdge[0], onEdge[1]) ) | 138 | { |
139 | { | 139 | this.addIntersection( plane, t, 1 ); |
140 | // take the dot product between the line and the normal to the plane | 140 | } |
141 | // to determine the change in visibility | 141 | else if (this.edgeGoesBehindPlane( plane, boundaryPts, onEdge[0], onEdge[1], pt1, pt0 )) |
142 | var vec = vecUtils.vecSubtract( 3, pt1, pt0 ); | 142 | { |
143 | var dot = vecUtils.vecDot( 3, vec, planeEq ); | 143 | this.addIntersection( plane, t, -1 ); |
144 | var sign = MathUtils.fpSign( dot ); | 144 | } |
145 | if (sign == 0) | 145 | |
146 | throw new Error( "coplanar intersection being treated as not coplanar" ); | 146 | /* |
147 | if (!plane.isBackFacing()) | 147 | if ( !this.edgeIsFrontFacing(boundaryPts, planeEq, plane.isBackFacing(), onEdge[0], onEdge[1]) ) |
148 | { | 148 | { |
149 | if (sign < 0) | 149 | // take the dot product between the line and the normal to the plane |
150 | this.addIntersection( plane, t, 1 ); | 150 | // to determine the change in visibility |
151 | } | 151 | var vec = vecUtils.vecSubtract( 3, pt1, pt0 ); |
152 | else | 152 | var dot = vecUtils.vecDot( 3, vec, planeEq ); |
153 | { | 153 | var sign = MathUtils.fpSign( dot ); |
154 | if (sign > 0) | 154 | if (sign == 0) |
155 | this.addIntersection( plane, t, -1 ); | 155 | throw new Error( "coplanar intersection being treated as not coplanar" ); |
156 | } | 156 | if (!plane.isBackFacing()) |
157 | } | 157 | { |
158 | } | 158 | if (sign < 0) |
159 | } | 159 | this.addIntersection( plane, t, 1 ); |
160 | } | 160 | } |
161 | } | 161 | else |
162 | else | 162 | { |
163 | { | 163 | if (sign > 0) |
164 | // the line must be parallel to the plane. If the line is in the plane, | 164 | this.addIntersection( plane, t, -1 ); |
165 | // we need to do some special processing | 165 | } |
166 | var d0 = vecUtils.vecDot(3, planeEq, pt0) + planeEq[3], | 166 | } |
167 | d1 = vecUtils.vecDot(3, planeEq, pt1) + planeEq[3]; | 167 | */ |
168 | if ((MathUtils.fpSign(d0) == 0) && (MathUtils.fpSign(d1) == 0)) | 168 | } |
169 | this.doCoplanarIntersection( plane ); | 169 | } |
170 | } | 170 | } |
171 | 171 | } | |
172 | // intersect with the 4 planes formed by the edges of the plane, going back in Z | 172 | else |
173 | var bPt1 = boundaryPts[3]; | 173 | { |
174 | for (var i=0; i<4; i++) | 174 | // the line must be parallel to the plane. If the line is in the plane, |
175 | { | 175 | // we need to do some special processing |
176 | // get the 2 points that define the front edge of the plane | 176 | var d0 = vecUtils.vecDot(3, planeEq, pt0) + planeEq[3], |
177 | var bPt0 = bPt1; | 177 | d1 = vecUtils.vecDot(3, planeEq, pt1) + planeEq[3]; |
178 | var bPt1 = boundaryPts[i]; | 178 | if ((MathUtils.fpSign(d0) == 0) && (MathUtils.fpSign(d1) == 0)) |
179 | 179 | this.doCoplanarIntersection( plane ); | |
180 | // calculate the plane equation. The normal should point towards the OUTSIDE of the boundary | 180 | } |
181 | //var vec = bPt1.subtract( bPt0 ); | 181 | |
182 | var vec = vecUtils.vecSubtract(3, bPt1, bPt0); | 182 | // intersect with the 4 planes formed by the edges of the plane, going back in Z |
183 | if (plane.isBackFacing()) | 183 | var bPt1 = boundaryPts[3]; |
184 | MathUtils.negate( vec ); | 184 | for (var i=0; i<4; i++) |
185 | planeEq = [-vec[1], vec[0], 0]; | 185 | { |
186 | var normal = [planeEq[0], planeEq[1], planeEq[2]]; | 186 | // get the 2 points that define the front edge of the plane |
187 | var bPt0 = bPt1; | ||
188 | var bPt1 = boundaryPts[i]; | ||
189 | |||
190 | // calculate the plane equation. The normal should point towards the OUTSIDE of the boundary | ||
191 | //var vec = bPt1.subtract( bPt0 ); | ||
192 | var vec = vecUtils.vecSubtract(3, bPt1, bPt0); | ||
193 | if (plane.isBackFacing()) | ||
194 | MathUtils.negate( vec ); | ||
195 | planeEq = [-vec[1], vec[0], 0]; | ||
196 | var normal = [planeEq[0], planeEq[1], planeEq[2]]; | ||
187 | // var d = -planeEq.dot(bPt0); | 197 | // var d = -planeEq.dot(bPt0); |
188 | var d = -vecUtils.vecDot(3, planeEq, bPt0); | 198 | var d = -vecUtils.vecDot(3, planeEq, bPt0); |
189 | planeEq[3] = d; | 199 | planeEq[3] = d; |
190 | 200 | ||
191 | t = MathUtils.vecIntersectPlaneForParam( pt0, lineDir, planeEq ); | 201 | t = MathUtils.vecIntersectPlaneForParam( pt0, lineDir, planeEq ); |
192 | if (t) | 202 | if (t) |
193 | { | 203 | { |
194 | if ((MathUtils.fpSign(t) > 0) && (MathUtils.fpCmp(t,1.0) <= 0)) // the strict vs not-strict inequality comparisons are IMPORTANT! | 204 | if ((MathUtils.fpSign(t) > 0) && (MathUtils.fpCmp(t,1.0) <= 0)) // the strict vs not-strict inequality comparisons are IMPORTANT! |
195 | { | 205 | { |
196 | // get the intersection point | 206 | // get the intersection point |
197 | var pt = MathUtils.interpolateLine3D( pt0, pt1, t ); | 207 | var pt = MathUtils.interpolateLine3D( pt0, pt1, t ); |
198 | 208 | ||
199 | // we need to get the parameter on the edge of the projection | 209 | // we need to get the parameter on the edge of the projection |
200 | // of the intersection point onto the line. | 210 | // of the intersection point onto the line. |
201 | var index = (Math.abs(vec[0]) > Math.abs(vec[1])) ? 0 : 1; | 211 |