diff options
-rwxr-xr-x | js/helper-classes/3D/StageLine.js | 373 | ||||
-rwxr-xr-x | js/helper-classes/3D/math-utils.js | 12 |
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 ); |