aboutsummaryrefslogtreecommitdiff
path: root/js/helper-classes/3D/snap-manager.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/helper-classes/3D/snap-manager.js')
-rwxr-xr-xjs/helper-classes/3D/snap-manager.js179
1 files changed, 90 insertions, 89 deletions
diff --git a/js/helper-classes/3D/snap-manager.js b/js/helper-classes/3D/snap-manager.js
index 6766ac7f..069c6022 100755
--- a/js/helper-classes/3D/snap-manager.js
+++ b/js/helper-classes/3D/snap-manager.js
@@ -21,7 +21,6 @@ var SnapManager = exports.SnapManager = Montage.create(Component, {
21 /////////////////////////////////////////////////////////////////////// 21 ///////////////////////////////////////////////////////////////////////
22 // Instance variables 22 // Instance variables
23 /////////////////////////////////////////////////////////////////////// 23 ///////////////////////////////////////////////////////////////////////
24 currentStage: { value: null, writable: true },
25 drawingCanvas: { value: null, writable: true}, 24 drawingCanvas: { value: null, writable: true},
26 25
27 // we keep a stack of working planes to facilitate working on other planes temporarily 26 // we keep a stack of working planes to facilitate working on other planes temporarily
@@ -84,14 +83,14 @@ var SnapManager = exports.SnapManager = Montage.create(Component, {
84 popWorkingPlane : { value: function () { workingPlane = this._workingPlaneStack.pop(); return workingPlane; }}, 83 popWorkingPlane : { value: function () { workingPlane = this._workingPlaneStack.pop(); return workingPlane; }},
85 84
86 getStageWidth : { value: function () { 85 getStageWidth : { value: function () {
87 return parseInt(this.currentStage.offsetWidth); 86 return parseInt(this.application.ninja.currentDocument.model.documentRoot.offsetWidth);
88 }}, 87 }},
89 88
90 getStageHeight : { value: function () { 89 getStageHeight : { value: function () {
91 return parseInt(this.currentStage.offsetHeight); 90 return parseInt(this.application.ninja.currentDocument.model.documentRoot.offsetHeight);
92 }}, 91 }},
93 92
94 getStage : { value: function() { return this.currentStage; }}, 93 getStage : { value: function() { return this.application.ninja.currentDocument.model.documentRoot; }},
95 94
96 getGridVertexHitRad : { value: function() { return this._gridVertexHitRad; }}, 95 getGridVertexHitRad : { value: function() { return this._gridVertexHitRad; }},
97 getGridEdgeHitRad : { value: function() { return this._gridEdgeHitRad; }}, 96 getGridEdgeHitRad : { value: function() { return this._gridEdgeHitRad; }},
@@ -130,10 +129,10 @@ var SnapManager = exports.SnapManager = Montage.create(Component, {
130 129
131 bindSnap: { 130 bindSnap: {
132 value: function() { 131 value: function() {
133 this.addEventListener("change@appModel.snap", this.toggleSnap, false); 132 this.addPropertyChangeListener("appModel.snap", this.toggleSnap, false);
134 this.addEventListener("change@appModel.snapGrid", this.toggleSnapGrid, false); 133 this.addPropertyChangeListener("appModel.snapGrid", this.toggleSnapGrid, false);
135 this.addEventListener("change@appModel.snapObjects", this.toggleSnapObjects, false); 134 this.addPropertyChangeListener("appModel.snapObjects", this.toggleSnapObjects, false);
136 this.addEventListener("change@appModel.snapAlign", this.toggleSnapAlign, false); 135 this.addPropertyChangeListener("appModel.snapAlign", this.toggleSnapAlign, false);
137 } 136 }
138 }, 137 },
139 138
@@ -185,12 +184,6 @@ var SnapManager = exports.SnapManager = Montage.create(Component, {
185 } 184 }
186 }, 185 },
187 186
188 setCurrentStage: {
189 value: function(stage) {
190 this.currentStage = stage;
191 }
192 },
193
194 snap : { 187 snap : {
195 value: function (xScreen, yScreen, snap3D, quadPt) 188 value: function (xScreen, yScreen, snap3D, quadPt)
196 { 189 {
@@ -230,64 +223,22 @@ var SnapManager = exports.SnapManager = Montage.create(Component, {
230 else 223 else
231 parentPt = [xScreen, yScreen, 0.0]; 224 parentPt = [xScreen, yScreen, 0.0];
232 225
233 var eyePt = []; 226 if (!snap3D && this._hasDragPlane)
234 var vec = viewUtils.parentToChildVec(parentPt, stage, eyePt); 227 this.activateDragPlane();
235 if (vec) 228
236 { 229 var hitRec = this.snapToStage( parentPt, quadPt );
237 // activate the drag working plane 230
238 if (!snap3D && this.hasDragPlane()) 231 // try snapping to the 3D grid, or to the stage boundaries if the grid is not displayed
239 this.activateDragPlane(); 232 if (this.gridSnapEnabled())
240 233 this.snapToGrid( hitRec );
241 // project to the working plane 234
242 var currentWorkingPlane = workingPlane.slice(0); 235 // save the hit record
243 var wp = currentWorkingPlane.slice(0); 236 hitRecArray.push( hitRec );
244 var mat = viewUtils.getMatrixFromElement(stage); 237
245 wp = MathUtils.transformPlane(wp, mat); 238 // restore the original working plane
246 var projPt = MathUtils.vecIntersectPlane(eyePt, vec, wp); 239 if (!snap3D && this.hasDragPlane())
247 if (projPt) 240 this.deactivateDragPlane();
248 { 241
249 // the local point gets stored in the coordinate space of the plane
250 var wpMat = drawUtils.getPlaneToWorldMatrix(currentWorkingPlane, MathUtils.getPointOnPlane(currentWorkingPlane));
251 projPt[3] = 1.0;
252 //var planeToViewMat = mat.multiply(wpMat);
253 var planeToViewMat = glmat4.multiply(mat, wpMat, []);
254 //var viewToPlaneMat = planeToViewMat.inverse();
255 var viewToPlaneMat = glmat4.inverse( planeToViewMat, [] );
256 var planePt = projPt.slice(0);
257 planePt[3] = 1.0;
258 //planePt = viewToPlaneMat.multiply(planePt);
259 planePt = glmat4.multiplyVec3( viewToPlaneMat, planePt );
260
261 // get the screen position of the projected point
262 viewUtils.setViewportObj(stage);
263 var offset = viewUtils.getElementOffset(stage);
264 offset[2] = 0;
265 var scrPt = viewUtils.viewToScreen(projPt);
266 //scrPt = scrPt.add(offset);
267 scrPt = vecUtils.vecAdd(3, scrPt, offset);
268
269 // create the hit record
270 var hitRec = Object.create(HitRecord);//new HitRecord();
271 hitRec.setLocalPoint(planePt);
272 hitRec.setPlaneMatrix( wpMat );
273 hitRec.setScreenPoint(scrPt);
274 hitRec.setPlane(currentWorkingPlane);
275 hitRec.setType( hitRec.SNAP_TYPE_STAGE );
276 hitRec.setElt( stage );
277 if (quadPt) hitRec.setUseQuadPoint( true );
278
279 // try snapping to the 3D grid, or to the stage boundaries if the grid is not displayed
280 if (this.gridSnapEnabled())
281 this.snapToGrid( hitRec );
282
283 // save the hit record
284 hitRecArray.push( hitRec );
285
286 // restore the original working plane
287 if (!snap3D && this.hasDragPlane())
288 this.deactivateDragPlane();
289 }
290 }
291 } //if (hitRecArray.length == 0) 242 } //if (hitRecArray.length == 0)
292 243
293 var rtnHit; 244 var rtnHit;
@@ -312,6 +263,62 @@ var SnapManager = exports.SnapManager = Montage.create(Component, {
312 } 263 }
313 }, 264 },
314 265
266 snapToStage:
267 {
268 value: function( scrPt, quadPt )
269 {
270 var stage = this.getStage();
271 var l2g = viewUtils.getLocalToGlobalMatrix( stage );
272 var g2l = glmat4.inverse( l2g, [] );
273
274 var pt0 = scrPt.slice(), pt1 = scrPt.slice();
275 pt0[2] = 0.0; pt1[2] = 10;
276
277 var localPt0 = MathUtils.transformAndDivideHomogeneousPoint( pt0, g2l ),
278 localPt1 = MathUtils.transformAndDivideHomogeneousPoint( pt1, g2l );
279
280 var stageWorldPt0 = viewUtils.localToStageWorld( localPt0, stage ),
281 stageWorldPt1 = viewUtils.localToStageWorld( localPt1, stage );
282 var vec = vecUtils.vecSubtract( 3, stageWorldPt1, stageWorldPt0 );
283
284 var ptOnWorkingPlane = MathUtils.vecIntersectPlane(stageWorldPt0, vec, workingPlane);
285
286 var wpMat = drawUtils.getPlaneToWorldMatrix(workingPlane, MathUtils.getPointOnPlane(workingPlane)),
287 wpMatInv = glmat4.inverse( wpMat, [] );
288 var localPt = MathUtils.transformPoint( ptOnWorkingPlane, wpMatInv );
289
290 // create the hit record
291 var hitRec = Object.create(HitRecord);
292 hitRec.setLocalPoint( localPt );
293 hitRec.setPlaneMatrix( wpMat );
294 hitRec.setScreenPoint(scrPt);
295 hitRec.setPlane(workingPlane);
296 hitRec.setType( hitRec.SNAP_TYPE_STAGE );
297 hitRec.setElt( stage );
298 if (quadPt) hitRec.setUseQuadPoint( true );
299
300 // DEBUG CODE
301 // check that the point is on the working plane
302 var tmpStageWorldPt = hitRec.calculateStageWorldPoint();
303 var err = vecUtils.vecDot(3, tmpStageWorldPt, workingPlane) + workingPlane[3];
304 if (MathUtils.fpSign(err) !== 0)
305 console.log( "snapToStage (function) not on working plane: " + err );
306 //////////////////////////////////////////////////////////////////////
307
308 var calculatedScreenPt = hitRec.calculateScreenPoint();
309 hitRec.setScreenPoint(calculatedScreenPt);
310
311 // DEBUG CODE
312 // check that the point is on the working plane
313 var err2 = vecUtils.vecDist(2, calculatedScreenPt, scrPt );
314 if (MathUtils.fpSign(err2) !== 0)
315 console.log( "snapToStage (function) error in screen point: " + err2 );
316 //////////////////////////////////////////////////////////////////////
317
318 return hitRec;
319 }
320 },
321
315 snapToGrid : { 322 snapToGrid : {
316 value: function( hitRec ) 323 value: function( hitRec )
317 { 324