From 952e0b2c28af081041fa8987c3e865b931d052fa Mon Sep 17 00:00:00 2001 From: Nivesh Rajbhandari Date: Mon, 9 Apr 2012 16:04:24 -0700 Subject: Single perspective fix. Note that rotating multiple objects when the stage is rotated still doesn't work and flatten still doesn't work. Signed-off-by: Nivesh Rajbhandari --- js/controllers/elements/element-controller.js | 10 +- js/controllers/elements/stage-controller.js | 20 +++- js/controllers/styles-controller.js | 35 +++--- js/helper-classes/3D/hit-record.js | 10 +- js/helper-classes/3D/snap-manager.js | 12 +- js/helper-classes/3D/view-utils.js | 163 +++++++++++++++++++------- js/models/properties-3d.js | 6 +- js/tools/ShapeTool.js | 2 +- js/tools/TagTool.js | 2 +- js/tools/drawing-tool-base.js | 9 +- 10 files changed, 188 insertions(+), 81 deletions(-) diff --git a/js/controllers/elements/element-controller.js b/js/controllers/elements/element-controller.js index fda3a3c5..7ab6664f 100755 --- a/js/controllers/elements/element-controller.js +++ b/js/controllers/elements/element-controller.js @@ -249,10 +249,6 @@ exports.ElementController = Montage.create(Component, { else { var dist = this.application.ninja.stylesController.getPerspectiveDistFromElement(el, false); - if(dist == null) { - dist = 1400; - } - el.elementModel.props3D.perspectiveDist = dist; return dist; } @@ -266,9 +262,13 @@ exports.ElementController = Montage.create(Component, { mat = props[index]["mat"]; this.application.ninja.stylesController.setElementStyle(el, "-webkit-transform", - "perspective(" + dist + ") " + "matrix3d(" + MathUtils.scientificToDecimal(mat, 5) + ")"); + // TODO - We don't support perspective on individual elements yet +// this.application.ninja.stylesController.setElementStyle(el, +// "-webkit-perspective", +// dist); + el.elementModel.props3D.matrix3d = mat; el.elementModel.props3D.perspectiveDist = dist; diff --git a/js/controllers/elements/stage-controller.js b/js/controllers/elements/stage-controller.js index dc916b1a..f376e40f 100755 --- a/js/controllers/elements/stage-controller.js +++ b/js/controllers/elements/stage-controller.js @@ -90,7 +90,7 @@ exports.StageController = Montage.create(ElementController, { return el.elementModel.stageView.style.getProperty(p); } default: - return ElementController.getProperty(el, p, false, true); + return ElementController.getProperty(el, p, true, true); //console.log("Undefined Stage property ", p); } } @@ -119,6 +119,7 @@ exports.StageController = Montage.create(ElementController, { break; case "-webkit-transform-style": el.elementModel.stageView.style.setProperty(p, value); + this.application.ninja.stage.updatedStage = true; break; default: console.log("Undefined property ", p, "for the Stage Controller"); @@ -178,5 +179,20 @@ exports.StageController = Montage.create(ElementController, { return mat; } } - } + }, + + getPerspectiveDist: { + value: function(el) { + if(el.elementModel && el.elementModel.props3D && el.elementModel.props3D.perspectiveDist) + { + return el.elementModel.props3D.perspectiveDist; + } + else + { + var dist = this.application.ninja.stylesController.getPerspectiveDistFromElement(el, true); + el.elementModel.props3D.perspectiveDist = dist; + return dist; + } + } + }, }); diff --git a/js/controllers/styles-controller.js b/js/controllers/styles-controller.js index 5d5f27ba..ec4314f9 100755 --- a/js/controllers/styles-controller.js +++ b/js/controllers/styles-controller.js @@ -1130,7 +1130,7 @@ var stylesController = exports.StylesController = Montage.create(Component, { getMatrixFromElement : { value: function(element, isStage) { - var xformStr = this.getElementStyle(element, "-webkit-transform", false, isStage), + var xformStr = this.getElementStyle(element, "-webkit-transform", true, isStage), mat; if (xformStr) { @@ -1163,26 +1163,29 @@ var stylesController = exports.StylesController = Montage.create(Component, { getPerspectiveDistFromElement : { value: function(element, isStage) { - var xformStr = this.getElementStyle(element, "-webkit-transform", false, isStage), + var xformStr = this.getElementStyle(element, "-webkit-perspective", false, isStage), dist; - if (xformStr) { - var index1 = xformStr.indexOf( "perspective("); - if (index1 >= 0) { - index1 += 12; // do not include 'perspective(' - var index2 = xformStr.indexOf( ")", index1 ); - if (index2 >= 0) { - var substr = xformStr.substr( index1, (index2-index1)); - if (substr && (substr.length > 0)) { - dist = parseInt( substr ); + if(xformStr) { + dist = parseInt(xformStr); + } else { + xformStr = this.getElementStyle(element, "-webkit-transform", true, isStage); + if (xformStr) { + var index1 = xformStr.indexOf( "perspective("); + if (index1 >= 0) { + index1 += 12; // do not include 'perspective(' + var index2 = xformStr.indexOf( ")", index1 ); + if (index2 >= 0) { + var substr = xformStr.substr( index1, (index2-index1)); + if (substr && (substr.length > 0)) { + dist = parseInt( substr ); + } } } } - } else { - xformStr = this.getElementStyle(element, "-webkit-perspective", false, isStage); - if(xformStr) { - dist = parseInt(xformStr); - } + } + if(isNaN(dist)) { + dist = null; } return dist; } diff --git a/js/helper-classes/3D/hit-record.js b/js/helper-classes/3D/hit-record.js index 2c60adc6..265bf2a4 100755 --- a/js/helper-classes/3D/hit-record.js +++ b/js/helper-classes/3D/hit-record.js @@ -232,7 +232,15 @@ var HitRecord = exports.HitRecord = Object.create(Object.prototype, var elt = this.getElt(); viewUtils.pushViewportObj( elt ); var viewPt = viewUtils.screenToView( scrPt[0], scrPt[1], scrPt[2] ); - var eyePt = viewUtils.getEyePoint(); + var eyePt; + if(viewUtils.getPerspectiveDistFromElement(elt)) + { + eyePt = viewUtils.getEyePoint(); + } + else + { + eyePt = [viewPt[0], viewPt[1], 1400]; + } var projPt = MathUtils.vecIntersectPlane( eyePt, MathUtils.vecSubtract(viewPt,eyePt), plane ); return projPt; diff --git a/js/helper-classes/3D/snap-manager.js b/js/helper-classes/3D/snap-manager.js index a401c363..61f5bc97 100755 --- a/js/helper-classes/3D/snap-manager.js +++ b/js/helper-classes/3D/snap-manager.js @@ -229,7 +229,9 @@ var SnapManager = exports.SnapManager = Montage.create(Component, { parentPt = [quadPt[0], quadPt[1], 0.0]; else parentPt = [xScreen, yScreen, 0.0]; - var vec = viewUtils.parentToChildVec(parentPt, stage); + + var eyePt = []; + var vec = viewUtils.parentToChildVec(parentPt, stage, eyePt); if (vec) { // activate the drag working plane @@ -241,7 +243,6 @@ var SnapManager = exports.SnapManager = Montage.create(Component, { var wp = currentWorkingPlane.slice(0); var mat = viewUtils.getMatrixFromElement(stage); wp = MathUtils.transformPlane(wp, mat); - var eyePt = viewUtils.getEyePoint(); var projPt = MathUtils.vecIntersectPlane(eyePt, vec, wp); if (projPt) { @@ -709,8 +710,8 @@ var SnapManager = exports.SnapManager = Montage.create(Component, { var wp = currentWorkingPlane.slice(0); var mat = viewUtils.getMatrixFromElement(stage); wp = MathUtils.transformPlane(wp, mat); - var eyePt = viewUtils.getEyePoint(); - var vec = viewUtils.parentToChildVec(gPt, stage); + var eyePt = []; + var vec = viewUtils.parentToChildVec(gPt, stage, eyePt); var projPt = MathUtils.vecIntersectPlane(eyePt, vec, wp); var wpMat = drawUtils.getPlaneToWorldMatrix(currentWorkingPlane, MathUtils.getPointOnPlane(currentWorkingPlane)); projPt[3] = 1.0; @@ -1067,8 +1068,9 @@ var SnapManager = exports.SnapManager = Montage.create(Component, { // Snapping is done in screen space, so convert the bounds from // local element space to global screen space var bounds3D = new Array(); + var eltMat = viewUtils.getLocalToGlobalMatrix( elt ); for (var i=0; i<4; i++) - bounds3D[i] = viewUtils.localToGlobal( bounds[i], elt ); + bounds3D[i] = viewUtils.localToGlobal2(bounds[i], eltMat); var hitRec = this.snapToScreenBounds( elt, globalScrPt, bounds, bounds3D ); diff --git a/js/helper-classes/3D/view-utils.js b/js/helper-classes/3D/view-utils.js index 63c2cb52..55ecbc59 100755 --- a/js/helper-classes/3D/view-utils.js +++ b/js/helper-classes/3D/view-utils.js @@ -37,10 +37,8 @@ exports.ViewUtils = Montage.create(Component, { setViewportObj: { value: function( vp ) { this.m_viewportObj = vp; - this._perspectiveDist = 1400; - var dist = this.getPerspectiveDistFromElement( vp ); - var mode = this.getPerspectiveModeFromElement( vp ); + this._perspectiveDist = this.getPerspectiveDistFromElement( vp ); } }, getViewportObj: { value: function() { return this.m_viewportObj; } }, @@ -360,11 +358,21 @@ exports.ViewUtils = Montage.create(Component, { if (this.elementHas3D( child )) { + // TODO - Commenting out flatten support until new perspective workflow is fully working // if (flatten) pt[2] = 0; +// var flatten = (parent !== this._rootElement) && (ElementsMediator.getProperty(parent, "-webkit-transform-style") !== "preserve-3d"); +// if(flatten) +// { +// pt[2] = 0; +// } pt = this.screenToView( pt[0], pt[1], pt[2] ); pt[3] = 1; //var wPt = childMat.multiply( pt ); var wPt = glmat4.multiplyVec3( childMat, pt, [] ); +// if(flatten) +// { +// wPt[2] = 0; +// } var scrPt = this.viewToScreen( wPt ); pt = scrPt; } @@ -480,7 +488,15 @@ exports.ViewUtils = Montage.create(Component, { var plane = MathUtils.transformPlane( [0,0,1,0], mat ); // project the view point onto the plane - var eyePt = this.getEyePoint(); + var eyePt; + if(this.getPerspectiveDistFromElement(child)) + { + eyePt = this.getEyePoint(); + } + else + { + eyePt = [viewPt[0], viewPt[1], 1400]; + } var projPt = MathUtils.vecIntersectPlane( eyePt, MathUtils.vecSubtract(viewPt,eyePt), plane ); var childPt; @@ -522,7 +538,15 @@ exports.ViewUtils = Montage.create(Component, { var plane = MathUtils.transformPlane( [0,0,1,0], mat ); // project the view point onto the plane - var eyePt = this.getEyePoint(); + var eyePt; + if(this.getPerspectiveDistFromElement(child)) + { + eyePt = this.getEyePoint(); + } + else + { + eyePt = [viewPt[0], viewPt[1], 1400]; + } var projPt = MathUtils.vecIntersectPlane( eyePt, MathUtils.vecSubtract(viewPt,eyePt), plane ); this.popViewportObj(); @@ -533,7 +557,7 @@ exports.ViewUtils = Montage.create(Component, { parentToChildVec: { - value: function( parentPt, child ) { + value: function( parentPt, child, rtnEyePt ) { var pt = parentPt.slice(0); if (pt.length == 2) pt[2] = 0.0; @@ -546,12 +570,24 @@ exports.ViewUtils = Montage.create(Component, { this.setViewportObj( child ); pt = this.screenToView( pt[0], pt[1], pt[2] ); - var eyePt = this.getEyePoint(); - //var eyePt = [0, 0, 0]; - //var vec = [pt[0], pt[1], pt[2]].subtract( eyePt ); + var eyePt; + if(this.getPerspectiveDistFromElement(child)) + { + eyePt = this.getEyePoint(); + } + else + { + eyePt = [pt[0], pt[1], 1400]; + } var vec = vecUtils.vecSubtract(3, [pt[0], pt[1], pt[2]], eyePt); vec = vecUtils.vecNormalize( 3, vec ); + if(rtnEyePt) + { + rtnEyePt[0] = eyePt[0]; + rtnEyePt[1] = eyePt[1]; + rtnEyePt[2] = eyePt[2]; + } return vec; } }, @@ -707,6 +743,10 @@ exports.ViewUtils = Montage.create(Component, { projectToViewPlane: { value: function( viewPos ) { + if(!this._perspectiveDist) + { + return viewPos.slice(0); + } var viewPt; var viewport = this.m_viewportObj; if (viewport) @@ -734,6 +774,10 @@ exports.ViewUtils = Montage.create(Component, { unproject: { value: function( pt ) { + if(!this._perspectiveDist) + { + return pt.slice(0); + } var viewPt; var viewport = this.m_viewportObj; if (viewport) @@ -790,26 +834,33 @@ exports.ViewUtils = Montage.create(Component, { getStageWorldToGlobalMatrix: { value: function() { - var stage = this.application.ninja.currentDocument.documentRoot; + var stage = this.application.ninja.currentDocument.documentRoot, + projMat; this.pushViewportObj( stage ); - // get the matrix to the parent - var mat = Matrix.I(4); - //var projMat = Matrix.I(4).multiply( this.getPerspectiveDistFromElement(stage) ); - var p = this.getPerspectiveDistFromElement(stage); - var projMat = glmat4.scale( Matrix.I(4), [p,p,p], [] ); - projMat[11] = -1; - var cop = this.getCenterOfProjection(); - var v2s = Matrix.Translation([cop[0], cop[1], 0]); + // get the matrix to the parent + var mat = Matrix.I(4); + + var cop = this.getCenterOfProjection(); + var v2s = Matrix.Translation([cop[0], cop[1], 0]); - //mat = v2s.multiply( projMat ); + var p = this.getPerspectiveDistFromElement(stage); + if(p) + { + projMat = glmat4.scale( Matrix.I(4), [p,p,p], [] ); + projMat[11] = -1; mat = glmat4.multiply( v2s, projMat, [] ); + } + else + { + mat = v2s; + } - // offset to the parent - var offset = this.getElementOffset( stage ); - var offMat = Matrix.Translation([offset[0], offset[1], 0]); - //mat = offMat.multiply( mat ); - glmat4.multiply( offMat, mat, mat ); + // offset to the parent + var offset = this.getElementOffset( stage ); + var offMat = Matrix.Translation([offset[0], offset[1], 0]); + //mat = offMat.multiply( mat ); + glmat4.multiply( offMat, mat, mat ); this.popViewportObj(); @@ -837,7 +888,7 @@ exports.ViewUtils = Montage.create(Component, { globalScreenToLocalWorld: { value: function( globalPt, elt ) { var objPt = this.globalToLocal( globalPt, elt ); - var viewPt = this.localScreenToLocalWorld( objPt, elt ) + var viewPt = this.localScreenToLocalWorld( objPt, elt ); /* MathUtils.makeDimension3( objPt ); @@ -882,7 +933,15 @@ exports.ViewUtils = Montage.create(Component, { getLocalToGlobalMatrix: { value: function( elt ) { - var mat = Matrix.I(4); + var mat = Matrix.I(4), + projMat, + pDist; + // TODO - Commenting out flatten support until new perspective workflow is fully working + var zMat = Matrix.I(4); +// zMat[9] = 0; +// zMat[10] = 0; +// zMat[11] = 0; +// zMat[12] = 0; while (elt) { this.pushViewportObj( elt ); @@ -891,17 +950,33 @@ exports.ViewUtils = Montage.create(Component, { var objMat = this.getMatrixFromElement( elt ); //var projMat = Matrix.I(4).multiply( this.getPerspectiveDistFromElement(elt) ); - var pDist = this.getPerspectiveDistFromElement(elt); - var projMat = glmat4.scale(Matrix.I(4), [pDist,pDist,pDist], []); - projMat[11] = -1; - projMat[15] = 1400; + pDist = this.getPerspectiveDistFromElement(elt); + if(pDist) + { + projMat = glmat4.scale(Matrix.I(4), [pDist,pDist,pDist], []); + projMat[11] = -1; + projMat[15] = 1400; + } var v2s = Matrix.Translation([cop[0], cop[1], 0]); glmat4.multiply( s2v, mat, mat ); glmat4.multiply( objMat, mat, mat ); - glmat4.multiply( projMat, mat, mat ); +// glmat4.multiply( projMat, mat, mat ); + if(pDist) + { + //mat = projMat.multiply( mat ); + glmat4.multiply( projMat, mat, mat ); + pDist = null; + } glmat4.multiply( v2s, mat, mat ); + // TODO - Commenting out flatten support until new perspective workflow is fully working +// var flatten = (elt !== this._rootElement) && (elt.parentElement !== this._rootElement) && (ElementsMediator.getProperty(elt.parentElement, "-webkit-transform-style") !== "preserve-3d"); +// if(flatten) +// { +// glmat4.multiply( zMat, mat, mat ); +// } + // offset to the parent var offset = this.getElementOffset( elt ); var offMat = Matrix.Translation([offset[0], offset[1], 0]); @@ -922,21 +997,24 @@ exports.ViewUtils = Montage.create(Component, { getObjToStageWorldMatrix: { value: function( elt, shouldProject ) { - var mat = Matrix.I(4); + var mat = Matrix.I(4), + projMat, + pDist; while (elt) { this.pushViewportObj( elt ); var cop = this.getCenterOfProjection(); var s2v = Matrix.Translation([-cop[0], -cop[1], 0]); var objMat = this.getMatrixFromElement( elt ); - var projMat; if(shouldProject) { - //projMat = Matrix.I(4).multiply( this.getPerspectiveDistFromElement(elt) ); - var pDist = this.getPerspectiveDistFromElement(elt); - var projMat = glmat4.scale(Matrix.I(4), [pDist,pDist,pDist], []); - projMat[11] = -1; - projMat[15] = 1400; + pDist = this.getPerspectiveDistFromElement(elt); + if(pDist) + { + projMat = glmat4.scale(Matrix.I(4), [pDist,pDist,pDist], []); + projMat[11] = -1; + projMat[15] = 1400; + } } var v2s = Matrix.Translation([cop[0], cop[1], 0]); this.popViewportObj(); @@ -947,10 +1025,11 @@ exports.ViewUtils = Montage.create(Component, { if (elt === this._stageElement) break; //mat = objMat.multiply( mat ); glmat4.multiply( objMat, mat, mat ); - if(shouldProject) + if(shouldProject && pDist) { //mat = projMat.multiply( mat ); glmat4.multiply( projMat, mat, mat ); + pDist = null; } //mat = v2s.multiply( mat ); glmat4.multiply( v2s, mat, mat ); @@ -1101,8 +1180,8 @@ exports.ViewUtils = Montage.create(Component, { pushViewportObj: { value: function( obj ) { - this._viewportObjStack.push( this.m_viewportObj ); - this.m_viewportObj = obj; + this.setViewportObj(obj); + this._viewportObjStack.push( obj ); } }, @@ -1115,7 +1194,7 @@ exports.ViewUtils = Montage.create(Component, { } var rtn = this.m_viewportObj; - this.m_viewportObj = this._viewportObjStack.pop(); + this.setViewportObj(this._viewportObjStack.pop()); return rtn; } }, diff --git a/js/models/properties-3d.js b/js/models/properties-3d.js index 0a7cf8bb..c1270c3b 100755 --- a/js/models/properties-3d.js +++ b/js/models/properties-3d.js @@ -67,10 +67,6 @@ exports.Properties3D = Montage.create(Component, { this.matrix3d = Matrix.I(4); } - if(this.perspectiveDist == null) { - this.perspectiveDist = 1400; - } - return this; } }, @@ -94,7 +90,7 @@ exports.Properties3D = Montage.create(Component, { ResetTranslationValues : { value : function() { // this.m_objStartPos = [0,0,0]; - this.perspectiveDist = 1400; +// this.perspectiveDist = 1400; } } }); \ No newline at end of file diff --git a/js/tools/ShapeTool.js b/js/tools/ShapeTool.js index a8da7921..f3b5e92d 100755 --- a/js/tools/ShapeTool.js +++ b/js/tools/ShapeTool.js @@ -197,7 +197,7 @@ exports.ShapeTool = Montage.create(DrawingTool, { 'top' : top + 'px', 'left' : left + 'px', '-webkit-transform-style' : 'preserve-3d', - '-webkit-transform' : 'perspective(1400) matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)' + '-webkit-transform' : 'matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)' }; tmpDiv.width = w; diff --git a/js/tools/TagTool.js b/js/tools/TagTool.js index 752500e0..d946db72 100755 --- a/js/tools/TagTool.js +++ b/js/tools/TagTool.js @@ -256,7 +256,7 @@ exports.TagTool = Montage.create(DrawingTool, { value: function(tag) { var styles = { "-webkit-transform-style": "preserve-3d", - "-webkit-transform": "perspective(1400) matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)" + "-webkit-transform": "matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)" }; tag.innerHTML = "content"; diff --git a/js/tools/drawing-tool-base.js b/js/tools/drawing-tool-base.js index 84602186..476dca66 100755 --- a/js/tools/drawing-tool-base.js +++ b/js/tools/drawing-tool-base.js @@ -227,7 +227,7 @@ exports.DrawingToolBase = Montage.create(Montage, { //var planeMatInv = planeMat.inverse(); var planeMatInv = glmat4.inverse( planeMat, [] ); //var midPt = this.unprojectPoints( s0, s1, planeMat, planeMatInv, s1Proj ); - var midPt = this.unprojectPoints( s0, s1, planeMat, planeMatInv, true ); +// var midPt = this.unprojectPoints( s0, s1, planeMat, planeMatInv, true ); // get the 4 points of the bounding box in 2D space p0 = MathUtils.transformPoint( s0, planeMatInv ); @@ -237,7 +237,7 @@ exports.DrawingToolBase = Montage.create(Montage, { //midPt = s0.add(s1); //midPt = midPt.multiply(0.5); //midPt = MathUtils.makeDimension3(midPt); - midPt = vec3.add(s0, s1, []); + var midPt = vec3.add(s0, s1, []); midPt = vecUtils.vecScale( 3, midPt, 0.5 ); // the mid point is now relative to the center of the 3D space. To @@ -371,6 +371,9 @@ exports.DrawingToolBase = Montage.create(Montage, { // determine if the geometry is going to be projected. If so a second projected rectangle is drawn var isProjected = ((MathUtils.fpCmp(thePlane[2],1.0) !== 0) || (MathUtils.fpSign(thePlane[3]) !== 0)); + // TODO - We no longer need to project drawing after perspective fix. Need to clean up this code. + // For now, just setting isProjected to false so rest of the drawing still works. + isProjected = false; // get and draw the unprojected object points var projPtArr = []; if (isProjected) @@ -442,7 +445,7 @@ exports.DrawingToolBase = Montage.create(Montage, { flatMat = divMat; flatMatSafe = MathUtils.scientificToDecimal(flatMat, 10); - return "perspective(" + 1400 + ") matrix3d(" + flatMatSafe + ")"; + return "matrix3d(" + flatMatSafe + ")"; } }, -- cgit v1.2.3