diff options
Diffstat (limited to 'js/helper-classes/3D/draw-utils.js')
-rw-r--r-- | js/helper-classes/3D/draw-utils.js | 1208 |
1 files changed, 1208 insertions, 0 deletions
diff --git a/js/helper-classes/3D/draw-utils.js b/js/helper-classes/3D/draw-utils.js new file mode 100644 index 00000000..3fd6e8fc --- /dev/null +++ b/js/helper-classes/3D/draw-utils.js | |||
@@ -0,0 +1,1208 @@ | |||
1 | /* <copyright> | ||
2 | This file contains proprietary software owned by Motorola Mobility, Inc.<br/> | ||
3 | No 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 DrawUtils | ||
9 | // Overlay drawing utility functions | ||
10 | /////////////////////////////////////////////////////////////////////// | ||
11 | var Montage = require("montage/core/core").Montage, | ||
12 | Component = require("montage/ui/component").Component; | ||
13 | |||
14 | var vecUtils = require("js/helper-classes/3D/vec-utils").VecUtils; | ||
15 | var Rectangle = require("js/helper-classes/3D/rectangle").Rectangle; | ||
16 | var StageLine = require("js/helper-classes/3D/StageLine").StageLine; | ||
17 | |||
18 | |||
19 | var DrawUtils = exports.DrawUtils = Montage.create(Component, { | ||
20 | |||
21 | /////////////////////////////////////////////////////////////////////// | ||
22 | // Instance variables | ||
23 | /////////////////////////////////////////////////////////////////////// | ||
24 | viewUtils: { value: null, writable: true }, | ||
25 | snapManager: { value: null }, | ||
26 | ElementPlanes : { value: null, writable: true }, | ||
27 | |||
28 | // the drawing surface (a canvas) | ||
29 | _drawingSurfaceElt : { value: null, writable: true }, | ||
30 | _drawingContext : { value: null, writable: true }, | ||
31 | |||
32 | // color to draw the lines | ||
33 | _lineColor : { value: "black", writable: true}, | ||
34 | |||
35 | // define a stack for quickly setting graphics states and restoring them | ||
36 | _stateArray : { value: [], writable: true }, | ||
37 | |||
38 | // save references to the grid lines for quick redraw | ||
39 | _gridLineArray : {value: [], writable: true }, | ||
40 | |||
41 | // state for moveTo, lineTo | ||
42 | _curPt : { value: null, writable: true }, | ||
43 | _curVis : { value: null, writable: true }, | ||
44 | |||
45 | // the element that defines the coordinate system for the displayed lines | ||
46 | _sourceSpaceElt : { value: null, writable: true }, | ||
47 | |||
48 | // maintain a list of objects to hide against | ||
49 | _eltArray : {value: [], writable: true }, | ||
50 | |||
51 | // maintain a list of the planes to test against | ||
52 | _planesArray : {value: [], writable: true }, | ||
53 | |||
54 | // the working plane. | ||
55 | // a grid may be drawn aligned with this working plane | ||
56 | _workingPlane : { value: null, writable: true }, | ||
57 | |||
58 | // save some parameters about the grid. | ||
59 | // these parameters are set when the grid is drawn | ||
60 | _gridHorizontalSpacing : {value: 50, writable: true }, | ||
61 | _gridVerticalSpacing : {value: 50, writable: true }, | ||
62 | _gridHorizontalLineCount : {value:10, writable: true }, | ||
63 | _gridVerticalLineCount : {value:0, writable: true }, | ||
64 | _gridOrigin : {value: null, writable: true }, | ||
65 | |||
66 | drawXY : {value: false, writable: true }, | ||
67 | drawXZ : {value: false, writable: true }, | ||
68 | drawYZ : {value: false, writable: true }, | ||
69 | |||
70 | drawElementN : {value: false, writable: true }, | ||
71 | |||
72 | _selectionCtr : {value: null, writable: true }, | ||
73 | |||
74 | /////////////////////////////////////////////////////////////////////// | ||
75 | // Property accessors | ||
76 | /////////////////////////////////////////////////////////////////////// | ||
77 | setDrawingSurfaceElement : { value: function( s ) { this._drawingSurfaceElt = s; if (s) this._drawingContext = s.getContext("2d"); }}, | ||
78 | getDrawingSurfaceElement : { value: function() { return this._drawingSurfaceElt; }}, | ||
79 | |||
80 | getDrawingContext : { value: function() { return this._drawingContext; }}, | ||
81 | |||
82 | setSourceSpaceElement : { value: function(ss) { this._sourceSpaceElt = ss; }}, | ||
83 | getSourceSpaceElement : { value: function() { return this._sourceSpaceElt; }}, | ||
84 | |||
85 | getWorkingPlane : { value: function() { return this._workingPlane; }}, | ||
86 | setWorkingPlane : { value: function (wp) { this._workingPlane = wp; }}, | ||
87 | |||
88 | getGridHorizontalSpacing : { value: function() { return this._gridHorizontalSpacing; }}, | ||
89 | getGridVerticalSpacing : { value: function() { return this._gridVerticalSpacing; }}, | ||
90 | getGridHorizontalLineCount : { value: function() { return this._gridHorizontalLineCount; }}, | ||
91 | getGridVerticalLineCount : { value: function() { return this._gridVerticalLineCount; }}, | ||
92 | getGridOrigin : { value: function() { return this._gridOrigin.slice(0); }}, | ||
93 | |||
94 | isDrawingGrid : { value: function() { return this.drawXY || this.drawYZ || this.drawXZ; }}, | ||
95 | isDrawingElementNormal : { value: function() { return this.drawElementN }}, | ||
96 | |||
97 | getLineColor : { value: function() { return this._lineColor; }}, | ||
98 | setLineColor : { value: function( color ) { this._lineColor = color; }}, | ||
99 | |||
100 | getLineWidth : { value: function() { return this._drawingContext.lineWidth; }}, | ||
101 | setLineWidth : { value: function( w ) { this._drawingContext.lineWidth = w; }}, | ||
102 | |||
103 | |||
104 | initialize: { | ||
105 | value: function() { | ||
106 | this._gridOrigin = [0,0]; // 2D plane space point | ||
107 | |||
108 | this.eventManager.addEventListener("elementAdded", this, false); | ||
109 | this.eventManager.addEventListener("elementDeleted", this, false); | ||
110 | } | ||
111 | }, | ||
112 | |||
113 | handleElementAdded: { | ||
114 | value: function(event) { | ||
115 | this.addElement(event.detail); | ||
116 | this.drawWorkingPlane(); | ||
117 | } | ||
118 | }, | ||
119 | |||
120 | handleElementDeleted: { | ||
121 | value: function(event) { | ||
122 | this.removeElement(event.detail); | ||
123 | } | ||
124 | }, | ||
125 | |||
126 | |||
127 | /////////////////////////////////////////////////////////////////////// | ||
128 | // Methods | ||
129 | /////////////////////////////////////////////////////////////////////// | ||
130 | |||
131 | addElement: | ||
132 | { | ||
133 | value: function( elt ) | ||
134 | { | ||
135 | // check if we already know about this object | ||
136 | var n = this._eltArray.length; | ||
137 | for (var i=0; i<n; i++) | ||
138 | { | ||
139 | if (elt == this._eltArray[i]) | ||
140 | { | ||
141 | // console.log( "element already added to stage display: " + elt.id ); | ||
142 | return; | ||
143 | } | ||
144 | } | ||
145 | |||
146 | this._eltArray.push( elt ); | ||
147 | |||
148 | // create the planes for this element | ||
149 | var plane = Object.create(this.ElementPlanes, {}); | ||
150 | plane.setElement( elt ); | ||
151 | plane.init(); | ||
152 | this._planesArray.push( plane ); | ||
153 | } | ||
154 | }, | ||
155 | |||
156 | removeElement : { | ||
157 | value: function( elt ) { | ||
158 | // check if object exists | ||
159 | var n = this._eltArray.length; | ||
160 | for (var i=0; i<n; i++) | ||
161 | { | ||
162 | if (elt == this._eltArray[i]) | ||
163 | { | ||
164 | // First remove the planes for this element | ||
165 | this._planesArray.splice(i, 1); | ||
166 | |||
167 | // Then remove the element | ||
168 | this._eltArray.splice(i, 1); | ||
169 | return; | ||
170 | } | ||
171 | } | ||
172 | } | ||
173 | }, | ||
174 | |||
175 | clear : { | ||
176 | value: function() { | ||
177 | if (this._drawingContext) | ||
178 | this._drawingContext.clearRect( 0, 0, this._drawingSurfaceElt.width, this._drawingSurfaceElt.height ); | ||
179 | } | ||
180 | }, | ||
181 | |||
182 | updatePlanes : { | ||
183 | value: function() { | ||
184 | var n = this._planesArray.length; | ||
185 | |||
186 | for (var i=0; i<n; i++) | ||
187 | { | ||
188 | var plane = this._planesArray[i]; | ||
189 | plane.init(); | ||
190 | } | ||
191 | } | ||
192 | }, | ||
193 | |||
194 | getVisibilityAtPoint: | ||
195 | { | ||
196 | value: function( targetPt ) | ||
197 | { | ||
198 | // duplicate the point and make sure it has the correct dimension (2) | ||
199 | var pt = targetPt.slice(0); | ||
200 | while (pt.length > 3) pt.pop(); | ||
201 | |||
202 | var z = pt[2]; | ||
203 | var n = this._planesArray.length; | ||
204 | var vis = 0; | ||
205 | for (var i=0; i<n; i++) | ||
206 | { | ||
207 | var plane = this._planesArray[i]; | ||
208 | |||
209 | // ignore if the point is in front of the polygon | ||
210 | if (z > plane.getZMax()) continue; | ||
211 | |||
212 | // test for containment in the polygon bounds | ||
213 | var contain = MathUtils.boundaryContainsPoint( plane.getBoundaryPoints(), pt, plane.isBackFacing() ); | ||
214 | if (contain == MathUtils.OUTSIDE) continue; | ||
215 | if (contain == MathUtils.ON) continue; | ||
216 | |||
217 | // shoot a ray from the point in the +Z direction to get the z value of the plane | ||
218 | var vec = [0,0,1]; | ||
219 | var planeEq = plane.getPlaneEq(); | ||
220 | var ptOnPlane = MathUtils.vecIntersectPlane( pt, vec, planeEq ); | ||
221 | if (ptOnPlane) | ||
222 | { | ||
223 | // in keeping with the convention that a point "on" a face is outside the element, | ||
224 | // check that case. | ||
225 | //if (MathUtils.fpCmp(pt[2], ptOnPlane[2]) == 0) continue; | ||
226 | |||
2 |