diff options
-rwxr-xr-x | js/helper-classes/3D/snap-manager.js | 139 | ||||
-rwxr-xr-x | js/helper-classes/3D/view-utils.js | 5 |
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 | } |
diff --git a/js/helper-classes/3D/view-utils.js b/js/helper-classes/3D/view-utils.js index 919f7c50..48d4cacf 100755 --- a/js/helper-classes/3D/view-utils.js +++ b/js/helper-classes/3D/view-utils.js | |||
@@ -288,6 +288,11 @@ exports.ViewUtils = Montage.create(Component, { | |||
288 | value: function( localPt, elt ) { | 288 | value: function( localPt, elt ) { |
289 | this.pushViewportObj( elt ); | 289 | this.pushViewportObj( elt ); |