aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhwc4872012-05-10 16:53:18 -0700
committerhwc4872012-05-10 16:53:18 -0700
commitbabfa5f1ca4f702920d81d7e12a90b12ffbf42d8 (patch)
tree1f7cc59301d97db5875e1b515760edaa50b6a9a1
parent3e82beb51fe3f596147e9d7f1c405d9a8c4df63b (diff)
downloadninja-babfa5f1ca4f702920d81d7e12a90b12ffbf42d8.tar.gz
Fixed an inaccuracy snapping to the stage.
-rwxr-xr-xjs/helper-classes/3D/snap-manager.js139
-rwxr-xr-xjs/helper-classes/3D/view-utils.js5
2 files changed, 81 insertions, 63 deletions
diff --git a/js/helper-classes/3D/snap-manager.js b/js/helper-classes/3D/snap-manager.js
index 6766ac7f..27a95941 100755
--- a/js/helper-classes/3D/snap-manager.js
+++ b/js/helper-classes/3D/snap-manager.js
@@ -230,64 +230,19 @@ var SnapManager = exports.SnapManager = Montage.create(Component, {
230 else 230 else
231 parentPt = [xScreen, yScreen, 0.0]; 231 parentPt = [xScreen, yScreen, 0.0];
232 232
233 var eyePt = []; 233 var hitRec = this.snapToStage( parentPt, quadPt );
234 var vec = viewUtils.parentToChildVec(parentPt, stage, eyePt); 234
235 if (vec) 235 // try snapping to the 3D grid, or to the stage boundaries if the grid is not displayed
236 { 236 if (this.gridSnapEnabled())
237 // activate the drag working plane 237 this.snapToGrid( hitRec );
238 if (!snap3D && this.hasDragPlane()) 238
239 this.activateDragPlane(); 239 // save the hit record
240 240 hitRecArray.push( hitRec );
241 // project to the working plane 241
242 var currentWorkingPlane = workingPlane.slice(0); 242 // restore the original working plane
243 var wp = currentWorkingPlane.slice(0); 243 if (!snap3D && this.hasDragPlane())
244 var mat = viewUtils.getMatrixFromElement(stage); 244 this.deactivateDragPlane();
245 wp = MathUtils.transformPlane(wp, mat); 245
246 var projPt = MathUtils.vecIntersectPlane(eyePt, vec, wp);
247 if (projPt)
248 {
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) 246 } //if (hitRecArray.length == 0)
292 247
293 var rtnHit; 248 var rtnHit;
@@ -312,6 +267,62 @@ var SnapManager = exports.SnapManager = Montage.create(Component, {
312 } 267 }
313 }, 268 },
314 269
270 snapToStage:
271 {
272 value: function( scrPt, quadPt )
273 {
274 var stage = this.getStage();
275 var l2g = viewUtils.getLocalToGlobalMatrix( stage );
276 var g2l = glmat4.inverse( l2g, [] );
277
278 var pt0 = scrPt.slice(), pt1 = scrPt.slice();
279 pt0[2] = 0.0; pt1[2] = 10;
280
281 var localPt0 = MathUtils.transformAndDivideHomogeneousPoint( pt0, g2l ),
282 localPt1 = MathUtils.transformAndDivideHomogeneousPoint( pt1, g2l );
283
284 var stageWorldPt0 = viewUtils.localToStageWorld( localPt0, stage ),
285 stageWorldPt1 = viewUtils.localToStageWorld( localPt1, stage );
286 var vec = vecUtils.vecSubtract( 3, stageWorldPt1, stageWorldPt0 );
287
288 var ptOnWorkingPlane = MathUtils.vecIntersectPlane(stageWorldPt0, vec, workingPlane);
289
290 var wpMat = drawUtils.getPlaneToWorldMatrix(workingPlane, MathUtils.getPointOnPlane(workingPlane)),
291 wpMatInv = glmat4.inverse( wpMat, [] );
292 var localPt = MathUtils.transformPoint( ptOnWorkingPlane, wpMatInv );
293
294 // create the hit record
295 var hitRec = Object.create(HitRecord);
296 hitRec.setLocalPoint( localPt );
297 hitRec.setPlaneMatrix( wpMat );
298 hitRec.setScreenPoint(scrPt);
299 hitRec.setPlane(workingPlane);
300 hitRec.setType( hitRec.SNAP_TYPE_STAGE );
301 hitRec.setElt( stage );
302 if (quadPt) hitRec.setUseQuadPoint( true );
303
304 // DEBUG CODE
305 // check that the point is on the working plane
306 var tmpStageWorldPt = hitRec.calculateStageWorldPoint();
307 var err = vecUtils.vecDot(3, tmpStageWorldPt, workingPlane) + workingPlane[3];
308 if (MathUtils.fpSign(err) !== 0)
309 console.log( "snapToStage (function) not on working plane: " + err );
310 //////////////////////////////////////////////////////////////////////
311
312 var calculatedScreenPt = hitRec.calculateScreenPoint();
313 hitRec.setScreenPoint(calculatedScreenPt);
314
315 // DEBUG CODE
316 // check that the point is on the working plane
317 var err2 = vecUtils.vecDist(2, calculatedScreenPt, scrPt );
318 if (MathUtils.fpSign(err2) !== 0)
319 console.log( "snapToStage (function) error in screen point: " + err2 );
320 //////////////////////////////////////////////////////////////////////
321
322 return hitRec;
323 }
324 },
325
315 snapToGrid : { 326 snapToGrid : {
316 value: function( hitRec ) 327 value: function( hitRec )
317 { 328 {
@@ -481,7 +492,7 @@ var SnapManager = exports.SnapManager = Montage.create(Component, {
481 492
482 this._elementCache = null; 493 this._elementCache = null;
483 } 494 }
484 //console.log( "clear 2D cache" ); 495 console.log( "clear 2D cache" );
485 } 496 }
486 }, 497 },
487 498
@@ -494,7 +505,7 @@ var SnapManager = exports.SnapManager = Montage.create(Component, {
494 this.hLoadElementCache( stage, plane, 0 ); 505 this.hLoadElementCache( stage, plane, 0 );
495 this._isCacheInvalid = false; 506 this._isCacheInvalid = false;
496 507
497 //console.log( "2D cache loaded with " + this._elementCache.length + " elements" ); 508 console.log( "2D cache loaded with " + this._elementCache.length + " elements" );
498 } 509 }
499 }, 510 },
500 511
@@ -1779,7 +1790,7 @@ var SnapManager = exports.SnapManager = Montage.create(Component, {
1779 1790
1780 if (hSnap && vSnap) 1791 if (hSnap && vSnap)
1781 { 1792 {
1782 //console.log( "\tmerge 1" ); 1793 console.log( "\tmerge 1" );
1783 1794
1784 // intersect the 2 lines on the plane 1795 // intersect the 2 lines on the plane
1785 var hPt = hSnap.getLocalPoint(), 1796 var hPt = hSnap.getLocalPoint(),
@@ -1828,7 +1839,7 @@ var SnapManager = exports.SnapManager = Montage.create(Component, {
1828 1839
1829 if (hSnap && vSnap) 1840 if (hSnap && vSnap)
1830 { 1841 {
1831 //console.log( "\tmerge 2" ); 1842 console.log( "\tmerge 2" );
1832 1843
1833 // intersect the 2 lines on the plane 1844 // intersect the 2 lines on the plane
1834 var hPt = hSnap.getLocalPoint(), 1845 var hPt = hSnap.getLocalPoint(),
@@ -1881,7 +1892,7 @@ var SnapManager = exports.SnapManager = Montage.create(Component, {
1881 1892
1882 if (hSnap && vSnap) 1893 if (hSnap && vSnap)
1883 { 1894 {
1884 //console.log( "merge edge" ); 1895 console.log( "merge edge" );
1885 1896
1886 var hPt = hSnap.getLocalPoint(), 1897 var hPt = hSnap.getLocalPoint(),
1887 vPt = vSnap.getLocalPoint(); 1898 vPt = vSnap.getLocalPoint();
@@ -1945,6 +1956,8 @@ var SnapManager = exports.SnapManager = Montage.create(Component, {
1945 //this._globalToStageWorldMat = this._stageWorldToGlobalMat.inverse(); 1956 //this._globalToStageWorldMat = this._stageWorldToGlobalMat.inverse();
1946 this._globalToStageWorldMat = glmat4.inverse( this._stageWorldToGlobalMat, [] ); 1957 this._globalToStageWorldMat = glmat4.inverse( this._stageWorldToGlobalMat, [] );
1947 1958
1959 console.log( "setupDragPlane: " + this._dragPlane );
1960
1948 // load the 2D elements 1961 // load the 2D elements
1949 this.load2DCache( this._dragPlane ); 1962 this.load2DCache( this._dragPlane );
1950 } 1963