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