aboutsummaryrefslogtreecommitdiff
path: root/js/helper-classes/3D/snap-manager.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/snap-manager.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/snap-manager.js')
-rw-r--r--js/helper-classes/3D/snap-manager.js2247
1 files changed, 2247 insertions, 0 deletions
diff --git a/js/helper-classes/3D/snap-manager.js b/js/helper-classes/3D/snap-manager.js
new file mode 100644
index 00000000..3ed96082
--- /dev/null
+++ b/js/helper-classes/3D/snap-manager.js
@@ -0,0 +1,2247 @@
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 SnapManager
9// Class to do hit testing of objects in the html page
10///////////////////////////////////////////////////////////////////////
11var Montage = require("montage/core/core").Montage,
12 Component = require("montage/ui/component").Component;
13
14var viewUtils = require("js/helper-classes/3D/view-utils").ViewUtils;
15var vecUtils = require("js/helper-classes/3D/vec-utils").VecUtils;
16var drawUtils = require("js/helper-classes/3D/draw-utils").DrawUtils;
17var HitRecord = require("js/helper-classes/3D/hit-record").HitRecord;
18var Snap2DRecord = require("js/helper-classes/3D/snap-2d-record").Snap2DRecord;
19var NJUtils = require("js/lib/NJUtils").NJUtils;
20
21var SnapManager = exports.SnapManager = Montage.create(Component, {
22 ///////////////////////////////////////////////////////////////////////
23 // Instance variables
24 ///////////////////////////////////////////////////////////////////////
25 currentStage: { value: null, writable: true },
26 drawingCanvas: { value: null, writable: true},
27
28 // we keep a stack of working planes to facilitate working on other planes temporarily
29 _workingPlaneStack : { value: [], writable: true },
30
31 // snapping radii relative to a 25 pixel grid
32 GRID_VERTEX_HIT_RAD : { value: 10, writable: true },
33 GRID_EDGE_HIT_RAD : { value: 6, writable: true},
34
35 // these are the grid snapping tolerances scaled to the current grid spacing
36 _gridVertexHitRad : { value: this.GRID_VERTEX_HIT_RAD, writable: true },
37 _gridEdgeHitRad : { value: this.GRID_EDGE_HIT_RAD, writable: true },
38
39 ELEMENT_VERTEX_HIT_RAD : { value: 18, writable: true },
40 ELEMENT_EDGE_HIT_RAD : { value: 14, writable: true },
41
42 // keep a reference to the most recent hitRecord. Used for drawing feedback on the stage
43 _lastHit : { value: null, writable: true },
44
45 // keep a list of objects to avoid snapping to
46 _avoidList : { value: [], writable: true },
47
48 // keep a cache of 2D elements to snap to
49 _elementCache : { value: null, writable: true },
50 _isCacheInvalid : { value: false, writable: true },
51
52 // the snap manager can handle a 2D plane for dragging.
53 // A call to initDragPlane sets these variables.
54 // a call to clearDragPlane MUST be called on the completion of a drag
55 _hasDragPlane : {value: false, writable: true },
56 _dragPlane : { value: null, writable: true },
57 _dragPlaneToWorld : { value: Matrix.I(4), writable: true },
58 _worldToDragPlane : { value: Matrix.I(4), writable: true },
59 _dragPlaneActive : {value: false, writable: true },
60
61 // cache the matrix linking stage world and global spaces
62 _stageWorldToGlobalMat : { value: Matrix.I(4), writable: true },
63 _globalToStageWorldMat : { value: Matrix.I(4), writable: true },
64
65 // various flags to enable snapping
66 _snapAlignEnabled : {value: true, writable: true },
67 _elementSnapEnabled : {value: true, writable: true },
68 _gridSnapEnabled : {value: true, writable: true },
69
70 // these represent the app level snap settings as set by the end user through
71 // the menus. These should be stored somewhere else and serialized. Putting them here for now...
72 _snapAlignEnabledAppLevel : {value: true, writable: true },
73 _elementSnapEnabledAppLevel : {value: true, writable: true },
74 _gridSnapEnabledAppLevel : {value: true, writable: true },
75
76 // App Model pointer
77 appModel: { value: null },
78
79
80 ///////////////////////////////////////////////////////////////////////
81 // Property accessors
82 ///////////////////////////////////////////////////////////////////////
83 pushWorkingPlane : { value: function (p) { this._workingPlaneStack.push(workingPlane.slice(0)); workingPlane = p.slice(0); }},
84 popWorkingPlane : { value: function () { workingPlane = this._workingPlaneStack.pop(); return workingPlane; }},
85
86 getStageWidth : { value: function () {
87 return parseInt(this.currentStage.offsetWidth);
88 }},
89
90 getStageHeight : { value: function () {
91 return parseInt(this.currentStage.offsetHeight);
92 }},
93
94 getStage : { value: function() { return this.currentStage; }},
95
96 getGridVertexHitRad : { value: function() { return this._gridVertexHitRad; }},
97 getGridEdgeHitRad : { value: function() { return this._gridEdgeHitRad; }},
98
99 getLastHit : { value: function() { return this._lastHit; }},
100 setLastHit : { value: function(h) { this._lastHit = h; }},
101
102 hasDragPlane : { value: function() { return this._hasDragPlane; }},
103 getDragPlane : { value: function() { return this._dragPlane.slice(0); }},
104
105 has2DCache : { value: function() { return (this._elementCache && !this._isCacheInvalid); }},
106
107 enableSnapAlign : { value: function(e) { this._snapAlignEnabled = e; }},
108 snapAlignEnabled : { value: function() { return this._snapAlignEnabled; }},
109 enableElementSnap : { value: function(e) { this._elementSnapEnabled = e; }},
110 elementSnapEnabled : { value: function() { return this._elementSnapEnabled; }},
111 enableGridSnap : { value: function(e) { this._gridSnapEnabled = e; }},
112 gridSnapEnabled : { value: function() { return this._gridSnapEnabled; }},
113
114 enableSnapAlignAppLevel : { value: function(e) { this._snapAlignEnabledAppLevel = e; }},
115 snapAlignEnabledAppLevel : { value: function() { return this._snapAlignEnabledAppLevel; }},
116 enableElementSnapAppLevel : { value: function(e) { this._elementSnapEnabledAppLevel = e; }},
117 elementSnapEnabledAppLevel : { value: function() { return this._elementSnapEnabledAppLevel; }},
118 enableGridSnapAppLevel : { value: function(e) { this._gridSnapEnabledAppLevel = e; }},
119 gridSnapEnabledAppLevel : { value: function() { return this._gridSnapEnabledAppLevel; }},
120
121 ///////////////////////////////////////////////////////////////////////
122 // Methods
123 ///////////////////////////////////////////////////////////////////////
124 initialize: {
125 value: function() {
126 this.eventManager.addEventListener("elementDeleted", this, false);
127 }
128 },
129
130 bindSnap: {
131 value: function() {
132 this.addEventListener("change@appModel.snap", this.toggleSnap, false);
133 this.addEventListener("change@appModel.snapGrid", this.toggleSnapGrid, false);
134 this.addEventListener("change@appModel.snapObjects", this.toggleSnapObjects, false);
135 this.addEventListener("change@appModel.snapAlign", this.toggleSnapAlign, false);
136 }
137 },
138
139 toggleSnap: {
140 value: function() {
141 this.enableSnapAlignAppLevel(this.appModel.snap);
142 this.enableElementSnapAppLevel(this.appModel.snap);
143 this.enableGridSnapAppLevel(this.appModel.snap);
144 }
145 },
146
147 toggleSnapGrid: {
148 value: function() {
149 this.enableGridSnapAppLevel(this.appModel.snapGrid);
150 }
151 },
152
153 toggleSnapObjects: {
154 value: function() {
155 this.enableElementSnapAppLevel(this.appModel.snapObjects);
156 }
157 },
158
159 toggleSnapAlign: {
160 value: function() {
161 this.enableSnapAlignAppLevel(this.appModel.snapAlign);
162 }
163 },
164
165
166 handleElementDeleted: {
167 value: function(event) {
168 this.removeElementFrom2DCache(event.detail);
169 }
170 },
171
172
173 setCurrentStage: {
174 value: function(stage) {
175 this.currentStage = stage;
176 }
177 },
178
179 snap : {
180 value: function (xScreen, yScreen, snap3D, quadPt)
181 {
182 // force a 3D snap if a 2D snap is requested but the 2D cache has not been initialized
183 if (!snap3D && !this._elementCache) snap3D = true;
184
185 // clear out the last hit record
186 this.setLastHit( null );
187
188 // snap to elements first, then the working plane
189 var screenPt = [xScreen, yScreen];
190 var hitRecArray = new Array();
191 if (this.elementSnapEnabled())
192 {
193 if (snap3D)
194 this.snapToElements( screenPt, hitRecArray );
195
196 // now always doing a 2D snap
197 this.snapToCached2DElements( screenPt, hitRecArray );
198 }
199
200 // if we did not hit anything, and we are in 2D mode, try a snap align
201 if (this.snapAlignEnabled())
202 {
203 //if (hitRecArray.length == 0)
204 this.snapAlign( screenPt, hitRecArray );
205 }
206
207
208 // if we did not find any objects to snap to, snap to the working plane and/or grid
209 //if (hitRecArray.length == 0)
210 {
211 var stage = this.getStage();
212 var parentPt;
213 if (quadPt)
214 parentPt = Vector.create([quadPt[0], quadPt[1], 0.0]);
215 else