aboutsummaryrefslogtreecommitdiff
path: root/js/helper-classes/3D/StageLine.js
diff options
context:
space:
mode:
authorPierre Frisch2011-12-22 07:25:50 -0800
committerValerio Virgillito2012-01-27 11:18:17 -0800
commitb89a7ee8b956c96a1dcee995ea840feddc5d4b27 (patch)
tree0f3136ab0ecdbbbed6a83576581af0a53124d6f1 /js/helper-classes/3D/StageLine.js
parent2401f05d1f4b94d45e4568b81fc73e67b969d980 (diff)
downloadninja-b89a7ee8b956c96a1dcee995ea840feddc5d4b27.tar.gz
First commit of Ninja to ninja-internal
Signed-off-by: Valerio Virgillito <rmwh84@motorola.com>
Diffstat (limited to 'js/helper-classes/3D/StageLine.js')
-rw-r--r--js/helper-classes/3D/StageLine.js461
1 files changed, 461 insertions, 0 deletions
diff --git a/js/helper-classes/3D/StageLine.js b/js/helper-classes/3D/StageLine.js
new file mode 100644
index 00000000..e0e7a8e3
--- /dev/null
+++ b/js/helper-classes/3D/StageLine.js
@@ -0,0 +1,461 @@
1/* <copyright>
2This file contains proprietary software owned by Motorola Mobility, Inc.<br/>
3No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.<br/>
4(c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved.
5</copyright> */
6
7///////////////////////////////////////////////////////////////////////
8// Class StageLine
9// The line class represents a line intersected with all planes on the scene
10///////////////////////////////////////////////////////////////////////
11var vecUtils = require("js/helper-classes/3D/vec-utils").VecUtils;
12var LinePlaneIntersectRec = require("js/helper-classes/3D/LinePlaneIntersectRec").LinePlaneIntersectRec;
13
14var StageLine = exports.StageLine = Object.create(Object.prototype, {
15 ///////////////////////////////////////////////////////////////////////
16 // Instance variables
17 ///////////////////////////////////////////////////////////////////////
18
19 // the 2 points of the line
20 _pt0: { value: null, writable: true },
21 _pt1: { value: null, writable: true },
22
23 // cache the 3D min and max points for the line
24 _minPt: { value: null, writable: true },
25 _maxPt: { value: null, writable: true },
26
27 // the visibility at the start point (this._pt0).
28 _vis: { value: null, writable: true },
29
30 // each line/plane intersection records 2 values: the parameter along
31 // the line from pt0 to pt1, and the change in visibility (+1 or -1). we
32 // keep a doubly-linked list of intersection records
33 _intersectionList: { value: null, writable: true },
34 _intersectionCount: { value: 0, writable: true },
35
36 ///////////////////////////////////////////////////////////////////////
37 // Property accessors
38 ///////////////////////////////////////////////////////////////////////
39 getMinPoint: { value: function() { return this._minPt.slice(0); } },
40 getMaxPoint: { value: function() { return this._maxPt.slice(0); } },
41
42 getPoint0: { value: function() { return this._pt0.slice(0); } },
43 getPoint1: { value: function() { return this._pt1.slice(0); } },
44
45 getIntersectionCount: { value: function() { return this._intersectionCount; } },
46 getIntersectionList: { value: function() { return this._intersectionList; } },
47
48 getVisibility: { value: function() { return this._vis; } },
49 setVisibility: { value: function(v) { this._vis = v; } },
50
51 ///////////////////////////////////////////////////////////////////////
52 // Methods
53 ///////////////////////////////////////////////////////////////////////
54
55 intersectWithPlane: {
56 value: function( plane )
57 {
58 // if the plane is edge-on, ignore it
59 if ( MathUtils.fpSign( plane.getPlaneEq()[2] ) == 0 ) return;
60
61 // do some quick box tests.
62 var minPt = this.getMinPoint(),
63 maxPt = this.getMaxPoint();
64
65 if (maxPt[0] < plane._rect.getLeft()) return;
66 if (minPt[0] > plane._rect.getRight()) return;
67
68 if (maxPt[1] < plane._rect.getTop()) return;
69 if (minPt[1] > plane._rect.getBottom()) return;
70
71 if (minPt[2] > plane.getZMax()) return;
72
73 // get the boundary points for the plane
74 var boundaryPts = plane.getBoundaryPoints();
75
76 // get the points and direction vector for the current line
77 var pt0 = this.getPoint0(), pt1 = this.getPoint1();
78 //var lineDir = pt1.subtract( pt0 );
79 var lineDir = vecUtils.vecSubtract(3, pt1, pt0);
80
81 // intersect with the front plane
82 var planeEq = plane.getPlaneEq();
83 var t = MathUtils.vecIntersectPlaneForParam( pt0, lineDir, planeEq );
84 if (t != undefined)
85 {
86 if ((MathUtils.fpSign(t) >= 0) && (MathUtils.fpCmp(t,1.0) <= 0))
87 {
88 // get the intersection point
89 var pt = MathUtils.interpolateLine3D( pt0, pt1, t );
90
91 // see if the intersection point is contained in the bounds
92 //var contains = this.boundaryContainsPoint( boundaryPts, plane.isBackFacing(), pt );
93 var contains = MathUtils.boundaryContainsPoint( boundaryPts, pt, plane.isBackFacing() );
94 if (contains == MathUtils.INSIDE)
95 {
96 // add the intersection
97 var dot = MathUtils.dot3( pt0, planeEq ) + planeEq[3];
98 var deltaVis = (dot > 0) ? 1 : -1;
99// if (plane.isBackFacing())
100// deltaVis = (dot < 0) ? 1 : -1;
101
102 this.addIntersection( plane, t, deltaVis );
103 }
104 else if (contains == MathUtils.ON)
105 {
106 if (MathUtils.fpCmp(t,1.0) < 0)
107 {
108 // take the dot product between the line and the normal to the plane
109 // to determine the change in visibility
110 var vec = vecUtils.vecSubtract( 3, pt1, pt0 );
111 var dot = vecUtils.vecDot( 3, vec, plane.getPlaneEq() );
112 var sign = MathUtils.fpSign( dot );
113 if (sign == 0)
114 throw new Error( "coplanar intersection being treated as not coplanar" );
115 if (!plane.isBackFacing())
116 {
117 if (sign < 0)
118 this.addIntersection( plane, t, 1 );
119 }
120 else
121 {
122 if (sign > 0)
123 this.addIntersection( plane, t, -1 );
124 }
125 }
126 }
127 }
128 }
129 else
130 {
131 // the line must be parallel to the plane. If the line is in the plane,
132 // we need to do some special processing
133 var d0 = vecUtils.vecDot(3, planeEq, pt0) + planeEq[3],
134 d1 = vecUtils.vecDot(3, planeEq, pt1) + planeEq[3];
135 if ((MathUtils.fpSign(d0) == 0) && (MathUtils.fpSign(d1) == 0))
136 this.doCoplanarIntersection( plane );
137 }
138
139 // intersect with the 4 planes formed by the edges of the plane, going back in Z
140 var bPt1 = boundaryPts[3];
141 for (var i=0; i<4; i++)
142 {
143 // get the 2 points that define the front edge of the plane
144 var bPt0 = bPt1;
145 var bPt1 = boundaryPts[i];
146
147 // calculate the plane equation. The normal should point towards the OUTSIDE of the boundary
148 //var vec = bPt1.subtract( bPt0 );
149 var vec = vecUtils.vecSubtract(3, bPt1, bPt0);
150 if (plane.isBackFacing())
151 MathUtils.negate( vec );
152 planeEq = Vector.create( [-vec[1], vec[0], 0] );
153 var normal = Vector.create( [planeEq[0], planeEq[1], planeEq[2]] );
154// var d = -planeEq.dot(bPt0);
155 var d = -vecUtils.vecDot(3, planeEq, bPt0);
156 planeEq[3] = d;
157
158 t = MathUtils.vecIntersectPlaneForParam( pt0, lineDir, planeEq );
159 if (t)
160 {
161 if ((MathUtils.fpSign(t) > 0) && (MathUtils.fpCmp(t,1.0) <= 0)) // the strict vs not-strict inequality comparisons are IMPORTANT!
162 {
163 // get the intersection point
164 var pt = MathUtils.interpolateLine3D( pt0, pt1, t );
165
166 // we need to get the parameter on the edge of the projection
167 // of the intersection point onto the line.
168 var index = (Math.abs(vec[0]) > Math.abs(vec[1])) ? 0 : 1;
169 var tEdge = (pt[index] - bPt0[index])/(bPt1[index] - bPt0[index]);
170 if ((MathUtils.fpSign(tEdge) > 0) && (MathUtils.fpCmp(tEdge,1.0) <= 0))
171 {
172 var edgePt = MathUtils.interpolateLine3D( bPt0, bPt1, tEdge );
173 if (MathUtils.fpCmp(pt[2],edgePt[2]) < 0)
174 {
175 // add the intersection
176 var deltaVis = MathUtils.dot(lineDir,normal) > 0 ? -1 : 1;
177 this.addIntersection( plane, t, deltaVis );
178 }
179 }
180 }
181 }
182 }
183 }
184 },
185
186 doCoplanarIntersection: {
187 value: function( plane )
188 {
189 // get the boundary points for the plane
190 var boundaryPts = plane.getBoundaryPoints();
191 var planeEq = plane.getPlaneEq();
192
193 if (plane.isBackFacing())
194 {
195 var tmp;
196 tmp = boundaryPts[0]; boundaryPts[0] = boundaryPts[3]; boundaryPts[3] = tmp;
197 tmp = boundaryPts[1]; boundaryPts[1] = boundaryPts[2]; boundaryPts[2] = tmp;
198 }
199
200 var pt0 = this.getPoint0(),
201 pt1 = this.getPoint1();
202
203 // keep a couple flags to prevent counting crossings twice in edge cases
204 var gotEnter = false,
205 gotExit = false;
206
207 var bp1 = boundaryPts[3];
208 for (var i=0; i<4; i++)
209 {
210 var bp0 = bp1;
211 bp1 = boundaryPts[i];
212 var vec = vecUtils.vecSubtract(3, bp1, bp0);
213 var nrm = vecUtils.vecCross(3, vec, planeEq);
214 nrm[3] = -vecUtils.vecDot(3, bp0, nrm);
215
216 var d0 = vecUtils.vecDot(3, nrm, pt0) + nrm[3],
217 d1 = vecUtils.vecDot(3, nrm, pt1) + nrm[3];
218
219 var s0 = MathUtils.fpSign(d0),
220 s1 = MathUtils.fpSign(d1);
221