From 27c1ba250a7db26cf24dd456d20af9ff1649e638 Mon Sep 17 00:00:00 2001 From: hwc487 Date: Mon, 23 Apr 2012 17:04:48 -0700 Subject: canvas interaction --- js/lib/drawing/world.js | 9 ++++++--- js/lib/geom/circle.js | 8 ++++++-- js/lib/geom/rectangle.js | 39 +++++++++++++++++++++++++++------------ 3 files changed, 39 insertions(+), 17 deletions(-) (limited to 'js/lib') diff --git a/js/lib/drawing/world.js b/js/lib/drawing/world.js index 945c9883..8ad4c6f5 100755 --- a/js/lib/drawing/world.js +++ b/js/lib/drawing/world.js @@ -362,9 +362,9 @@ var World = function GLWorld( canvas, use3D, preserveDrawingBuffer ) { // start RDGE passing your runtime object, and false to indicate we don't need a an initialization state // in the case of a procedurally built scene an init state is not needed for loading data + this._canvas.rdgeid = this._canvas.getAttribute( "data-RDGE-id" ); if (this._useWebGL) { rdgeStarted = true; - this._canvas.rdgeid = this._canvas.getAttribute( "data-RDGE-id" ); RDGE.globals.engine.unregisterCanvas( this._canvas ); RDGE.globals.engine.registerCanvas(this._canvas, this); RDGE.RDGEStart( this._canvas ); @@ -835,8 +835,11 @@ World.prototype.importJSON = function (jObj) { // import the objects // there should be exactly one child of the parent object - if (jObj.children && (jObj.children.length === 1)) - this.importObjectsJSON( jObj.children[0] ); + if (jObj.children) + { + for (var i=0; i 0) { - ctx.quadraticCurveTo( inset, height-inset, inset+rad, height-inset ); + ctx.quadraticCurveTo( inset+xOff, height-inset+yOff, inset+rad+xOff, height-inset+yOff ); } // do the bottom of the rectangle @@ -392,11 +407,11 @@ var Rectangle = function GLRectangle() { rad = brRad - inset; if (rad < 0) rad = 0; pt[0] -= rad; - ctx.lineTo( pt[0], pt[1] ); + ctx.lineTo( pt[0]+xOff, pt[1]+yOff ); // get the bottom right arc if (MathUtils.fpSign(rad) > 0) { - ctx.quadraticCurveTo( width-inset, height-inset, width-inset, height-inset-rad ); + ctx.quadraticCurveTo( width-inset+xOff, height-inset+yOff, width-inset+xOff, height-inset-rad+yOff ); } // get the right of the rectangle @@ -404,11 +419,11 @@ var Rectangle = function GLRectangle() { rad = trRad - inset; if (rad < 0) rad = 0; pt[1] += rad; - ctx.lineTo( pt[0], pt[1] ); + ctx.lineTo( pt[0]+xOff, pt[1]+yOff ); // do the top right corner if (MathUtils.fpSign(rad) > 0) { - ctx.quadraticCurveTo( width-inset, inset, width-inset-rad, inset ); + ctx.quadraticCurveTo( width-inset+xOff, inset+yOff, width-inset-rad+xOff, inset+yOff ); } // do the top of the rectangle @@ -416,13 +431,13 @@ var Rectangle = function GLRectangle() { rad = tlRad - inset; if (rad < 0) rad = 0; pt[0] += rad; - ctx.lineTo( pt[0], pt[1] ); + ctx.lineTo( pt[0]+xOff, pt[1]+yOff ); // do the top left corner if (MathUtils.fpSign(rad) > 0) { - ctx.quadraticCurveTo( inset, inset, inset, inset+rad ); + ctx.quadraticCurveTo( inset+xOff, inset+yOff, inset+xOff, inset+rad+yOff ); } else { - ctx.lineTo( inset, 2*inset ); + ctx.lineTo( inset+xOff, 2*inset+yOff ); } } }; @@ -430,7 +445,7 @@ var Rectangle = function GLRectangle() { this.render = function() { // get the world var world = this.getWorld(); - if (!world) throw( "null world in rectangle render" ); + if (!world) throw( "null world in rectangle render" ); // get the context var ctx = world.get2DContext(); -- cgit v1.2.3 From cec076988d3ff6547b7c9d74ebc80530ffcea67b Mon Sep 17 00:00:00 2001 From: hwc487 Date: Tue, 24 Apr 2012 17:16:29 -0700 Subject: Snapping tocontained objects --- js/lib/geom/circle.js | 53 ++++++++++++++++++++++++++++++++++++++++--- js/lib/geom/geom-obj.js | 59 ++++++++++++++++++++++++++++++++++++++++++++++++ js/lib/geom/rectangle.js | 1 - 3 files changed, 109 insertions(+), 4 deletions(-) (limited to 'js/lib') diff --git a/js/lib/geom/circle.js b/js/lib/geom/circle.js index 896803bf..b7027eec 100755 --- a/js/lib/geom/circle.js +++ b/js/lib/geom/circle.js @@ -4,9 +4,12 @@ No rights, expressed or implied, whatsoever to this software are provided by Mot (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. */ -var GeomObj = require("js/lib/geom/geom-obj").GeomObj; -var ShapePrimitive = require("js/lib/geom/shape-primitive").ShapePrimitive; -var MaterialsModel = require("js/models/materials-model").MaterialsModel; +var GeomObj = require("js/lib/geom/geom-obj").GeomObj; +var ShapePrimitive = require("js/lib/geom/shape-primitive").ShapePrimitive; +var MaterialsModel = require("js/models/materials-model").MaterialsModel; +var drawUtils = require("js/helper-classes/3D/draw-utils").DrawUtils; +var vecUtils = require("js/helper-classes/3D/vec-utils").VecUtils; + /////////////////////////////////////////////////////////////////////// // Class GLCircle // GL representation of a circle. @@ -710,6 +713,49 @@ var Circle = function GLCircle() { return (MathUtils.fpCmp(distToPt,distToBoundary) <= 0); }; + this.getNearPoint = function( pt, dir ) + { + var world = this.getWorld(); + if (!world) throw( "null world in getNearPoint" ); + + // the input point and direction are in GL space + // project to the z == 0 plane + var mat = this.getMatrix(); + var plane = [0,0,1,0]; + plane = MathUtils.transformPlane( plane, mat ); + var projPt = MathUtils.vecIntersectPlane ( pt, dir, plane ); + + // get the center of the circle in GL space + var ctr = this.getGLCenter(); + + // transform the projected point to the plane of the circle + var planePt = MathUtils.transformPoint( projPt, mat ); + + // get a matrix mapping the circle to a 2D coordinate system + var normal = [ mat[8], mat[9], mat[10] ]; + var planeMat = drawUtils.getPlaneToWorldMatrix(normal, ctr); + var planeMatInv = glmat4.inverse( planeMat, [] ); + var planePt2D = MathUtils.transformPoint( planePt, planeMatInv ); + + // get 2 points on the axes of the oval + var wPt = this.preViewToGL( [this._xOffset + 0.5*this.getWidth(), this._yOffset, 0] ), + hPt = this.preViewToGL( [this._xOffset, this._yOffset + 0.5*this.getHeight(), 0] ); + var w = vecUtils.vecDist( 2, wPt, ctr ), + h = vecUtils.vecDist( 2, hPt, ctr ); + var aspect = w/h; + + // get the angle of the projected point relative to the circle + var angle = Math.atan2( planePt2D[1], planePt2D[0]/aspect ); + var degrees = angle*180.0/Math.PI; + + // get the corresponding point on the object + var pt = [ Math.cos(angle)*w, Math.sin(angle)*h, 0 ]; + var glPt = MathUtils.transformPoint( pt, planeMat ); + + return glPt; + } + + /* this.getNearPoint = function( pt, dir ) { var world = this.getWorld(); if (!world) throw( "null world in getNearPoint" ); @@ -759,6 +805,7 @@ var Circle = function GLCircle() { return objPt; }; + */ this.recalcTexMapCoords = function( vrts, uvs ) { var n = vrts.length/3; diff --git a/js/lib/geom/geom-obj.js b/js/lib/geom/geom-obj.js index f2991bdb..7cb9b80f 100755 --- a/js/lib/geom/geom-obj.js +++ b/js/lib/geom/geom-obj.js @@ -375,6 +375,65 @@ var GeomObj = function GLGeomObj() { } }; + + this.getGLCenter = function() + { + // get the normalized device coordinates (NDC) for + // all position and dimensions. + var world = this.getWorld(); + var vpw = world.getViewportWidth(), vph = world.getViewportHeight(); + var xNDC = 2*this._xOffset/vpw, yNDC = -2*this._yOffset/vph; + + var aspect = world.getAspect(); + var zn = world.getZNear(), zf = world.getZFar(); + var t = zn * Math.tan(world.getFOV() * Math.PI / 360.0), + b = -t, + r = aspect*t, + l = -r; + + // calculate the object coordinates from their NDC coordinates + var z = -world.getViewDistance(); + + // unproject to get the position of the origin in GL + var x = -z*(r-l)/(2.0*zn)*xNDC, + y = -z*(t-b)/(2.0*zn)*yNDC; + z = 0.0; + + // transform by the object's transformation matrix + var ctr = MathUtils.transformPoint( [x, y, z], this.getMatrix() ); + + return ctr; + }; + + this.preViewToGL = function( preViewPt ) + { + // get the normalized device coordinates (NDC) for + // all position and dimensions. + var world = this.getWorld(); + var vpw = world.getViewportWidth(), vph = world.getViewportHeight(); + var xNDC = 2*preViewPt[0]/vpw, yNDC = -2*preViewPt[1]/vph; + + var aspect = world.getAspect(); + var zn = world.getZNear(), zf = world.getZFar(); + var t = zn * Math.tan(world.getFOV() * Math.PI / 360.0), + b = -t, + r = aspect*t, + l = -r; + + // calculate the object coordinates from their NDC coordinates + var z = -world.getViewDistance(); + + // unproject to get the position of the origin in GL + var x = -z*(r-l)/(2.0*zn)*xNDC, + y = -z*(t-b)/(2.0*zn)*yNDC; + z = 0.0; + + // transform by the object's transformation matrix + var glPt = MathUtils.transformPoint( [x, y, z], this.getMatrix() ); + + return glPt; + }; + this.buildBuffers = function () { // this function must be overridden by the base class alert("GLGeomObj.buildBuffers must be overridden by base class"); diff --git a/js/lib/geom/rectangle.js b/js/lib/geom/rectangle.js index d9f1f0b1..41c51e2f 100755 --- a/js/lib/geom/rectangle.js +++ b/js/lib/geom/rectangle.js @@ -693,7 +693,6 @@ var Rectangle = function GLRectangle() { var projPt = MathUtils.vecIntersectPlane ( pt, dir, plane ); // transform the projected point back to the XY plane - //var invMat = mat.inverse(); var invMat = glmat4.inverse(mat, []); var planePt = MathUtils.transformPoint( projPt, invMat ); -- cgit v1.2.3 From 4b83774cdbfbf30add9a8fa2f11b1c4ff35179fa Mon Sep 17 00:00:00 2001 From: hwc487 Date: Thu, 26 Apr 2012 12:50:57 -0700 Subject: canvas interaction --- js/lib/drawing/world.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/lib') diff --git a/js/lib/drawing/world.js b/js/lib/drawing/world.js index 7ee9ee00..7ce23921 100755 --- a/js/lib/drawing/world.js +++ b/js/lib/drawing/world.js @@ -758,7 +758,7 @@ World.prototype.exportJSON = function () { // would not be destructive of the data. You would be wrong... // We need to rebuild everything if (this._useWebGL) { - if (worldObj.children && (worldObj.children.length === 1)) { + if (worldObj.children && (worldObj.children.length >= 1)) { this.rebuildTree(this._geomRoot); this.restartRenderLoop(); } -- cgit v1.2.3 From d2a5fcbaed6b3c3377edecbc27e6a2818b79be40 Mon Sep 17 00:00:00 2001 From: Valerio Virgillito Date: Wed, 2 May 2012 15:34:49 -0700 Subject: Nesting absolute element in the Tag tool. Refactoring element creation and element models Signed-off-by: Valerio Virgillito --- js/lib/NJUtils.js | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) (limited to 'js/lib') diff --git a/js/lib/NJUtils.js b/js/lib/NJUtils.js index dae128e4..301af3f1 100755 --- a/js/lib/NJUtils.js +++ b/js/lib/NJUtils.js @@ -54,13 +54,25 @@ exports.NJUtils = Object.create(Object.prototype, { return document.createTextNode(text); } }, - + ///// Quick "createElement" function "attr" can be classname or object ///// with attribute key/values - ///// Suppor for data attributes - make : { - value: function(tag, attr) { - var el = document.createElement(tag); + ///// Support for data attributes + ///// Support user/ninja document + make: { + value: function(tag, attr, doc) { + var _doc, el; + + _doc = doc ? doc._document : document; + el = _doc.createElement(tag); + this.decor(el, attr); + + return el; + } + }, + + decor: { + value: function(el, attr) { if (typeof attr === 'object') { for (var a in attr) { if (attr.hasOwnProperty(a)) { @@ -74,8 +86,12 @@ exports.NJUtils = Object.create(Object.prototype, { } else if (typeof attr === 'string') { el.className = (el.className + ' ' + attr).trim(); } - - return el; + } + }, + + createModel: { + value: function(el) { + el.elementModel = Montage.create(ElementModel).initialize(el); } }, @@ -94,8 +110,6 @@ exports.NJUtils = Object.create(Object.prototype, { ///// TODO: find a different place for this function makeElementModel: { value: function(el, selection, controller, isShape) { - //el.elementModel = Montage.create(ElementModel).initialize(el.nodeName, selection, controller, isShape); - var p3d = Montage.create(Properties3D); var shapeProps = null; -- cgit v1.2.3 From 2078bfa96afaef40acb4edac99848ba55e808ef1 Mon Sep 17 00:00:00 2001 From: Valerio Virgillito Date: Thu, 3 May 2012 15:15:21 -0700 Subject: Refactor creating elements. Removed makeNJElement and separated the model creation Signed-off-by: Valerio Virgillito --- js/lib/NJUtils.js | 80 +++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 69 insertions(+), 11 deletions(-) (limited to 'js/lib') diff --git a/js/lib/NJUtils.js b/js/lib/NJUtils.js index 301af3f1..5aaeb5f2 100755 --- a/js/lib/NJUtils.js +++ b/js/lib/NJUtils.js @@ -5,16 +5,15 @@ No rights, expressed or implied, whatsoever to this software are provided by Mot */ var Montage = require("montage/core/core").Montage, + Component = require("montage/ui/component").Component, Uuid = require("montage/core/uuid").Uuid, ElementModel = require("js/models/element-model").ElementModel, Properties3D = require("js/models/properties-3d").Properties3D, ShapeModel = require("js/models/shape-model").ShapeModel, ControllerFactory = require("js/controllers/elements/controller-factory").ControllerFactory; -exports.NJUtils = Object.create(Object.prototype, { - - - +exports.NJUtils = Montage.create(Component, { + /* =============== DOM Access ================ */ ///// Quick "getElementById" @@ -95,14 +94,73 @@ exports.NJUtils = Object.create(Object.prototype, { } }, - ///// Element factory function for Ninja Elements - ///// selection is the string displayed in the PI - makeNJElement: { - value: function(tag, selection, controller, attr, isShape) { - var el = this.make(tag, attr); - this.makeElementModel(el, selection, controller, isShape); + createModelWithShape: { + value: function(el, selection) { + el.elementModel = Montage.create(ElementModel).initialize(el, true, selection); + } + }, - return el; + createModelWithSelection: { + value: function(el, selection) { + el.elementModel = Montage.create(ElementModel).initialize(el, false, selection); + } + }, + + createModelForComponent: { + value: function(el, selection) { + el.elementModel = Montage.create(ElementModel).initialize(el, false, selection, true); + } + }, + + // TODO: Find a better place for this method + stylesFromDraw: { + value: function(element, width, height, drawData, pos) { + var styles = {}; + + styles['position'] = pos ? pos: "absolute"; + styles['left'] = (Math.round(drawData.midPt[0] - 0.5 * width)) - this.application.ninja.currentSelectedContainer.offsetLeft + 'px'; + styles['top'] = (Math.round(drawData.midPt[1] - 0.5 * height)) - this.application.ninja.currentSelectedContainer.offsetTop + 'px'; + styles['width'] = width + 'px'; + styles['height'] = height + 'px'; + + // TODO: Check why Canvas has different tranform styles from default. + if(!MathUtils.isIdentityMatrix(drawData.planeMat)) { + styles['-webkit-transform-style'] = 'preserve-3d'; + styles['-webkit-transform'] = this.getElementMatrix(drawData.planeMat, drawData.midPt); + } + + if(element.nodeName === "CANVAS") { + element.width = width; + element.height = height; + delete styles['width']; + delete styles['height']; + + styles['-webkit-transform-style'] = 'preserve-3d'; + } + + return styles; + } + }, + + // Get the matrix for the actual element being added to the user document. + // TODO: Find a better place for this method + getElementMatrix: { + value: function(planeMat, midPt) { + var divMat, flatMat, flatMatSafe; + // we should not need to worry about divide by zero below since we snapped to the point + divMat = planeMat.slice(0); + divMat[12] = 0.0; + divMat[13] = 0.0; + //divMat[14] = 0.0; + divMat[14] = midPt[2]; + + // set the left and top of the element such that the center of the rectangle is at the mid point + this.application.ninja.stage.setStageAsViewport(); + + flatMat = divMat; + flatMatSafe = MathUtils.scientificToDecimal(flatMat, 10); + + return "matrix3d(" + flatMatSafe + ")"; } }, -- cgit v1.2.3