/* This file contains proprietary software owned by Motorola Mobility, Inc.
No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.
(c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved.
*/ /////////////////////////////////////////////////////////////////////// // Class GLPath // GL representation of a path. // Derived from class GLGeomObj // The position and dimensions of the stroke, fill, and inner Radius should be in pixels /////////////////////////////////////////////////////////////////////// function GLPath() { // initialize the inherited members this.inheritedFrom = GLGeomObj; this.inheritedFrom(); this.init = function( world, dataArray, typeArray, strokeWidth, strokeColor, strokeMaterial ) { /////////////////////////////////////////////////////////////////////// // Instance variables /////////////////////////////////////////////////////////////////////// // stroke this._strokeWidth = 0.25; this._strokeColor = strokeColor; this._strokeMaterial = strokeMaterial; // data this._dataArray = dataArray.slice(0); this._typeArray = typeArray.slice(0); this._world = world; } /////////////////////////////////////////////////////////////////////// // Property Accessors /////////////////////////////////////////////////////////////////////// this.getStrokeWidth = function() { return this._strokeWidth; } this.setStrokeWidth = function(w) { this._strokeWidth = w; } this.getStrokeMaterial = function() { return this._strokeMaterial; } this.setStrokeMaterial = function(m) { this._strokeMaterial = m; } this.getWorld = function() { return this._world; } this.setWorld = function(w) { this._world = w; } this.geomType = function() { return this.GEOM_TYPE_PATH; } /////////////////////////////////////////////////////////////////////// // Methods /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // update the "color of the material this.getStrokeColor = function() { return this._strokeColor; } // this.setStrokeColor = function(c) // { // this._strokeColor = c; // } /////////////////////////////////////////////////////////////////////// this.buildBuffers = function() { // currently no GL representation } this.render = function() { // get the world var world = this.getWorld(); if (!world) throw( "null world in buildBuffers" ); // get the context var ctx = world.get2DContext(); if (!ctx) return; // create the matrix var lineWidth = this._strokeWidth; // set up the stroke style ctx.beginPath(); ctx.lineWidth = lineWidth; ctx.strokeStyle = "#0000ff"; if (this._strokeColor) ctx.strokeStyle = MathUtils.colorToHex( this._strokeColor ); // declarations var pt, p0, p1, p2; // draw the stroke var index = 0; var dataIndex = 0; var n = this._typeArray.length; while (index < n) { var type = this._typeArray[index]; index++; switch (type) { case 0: // moveTo pt = this._dataArray[dataIndex]; dataIndex++; ctx.moveTo( pt[0], pt[1] ); break; case 1: // line pt = this._dataArray[dataIndex]; dataIndex++; ctx.lineTo( pt[0], pt[1] ); break; case 2: // quadratic Bezier p0 = this._dataArray[dataIndex]; dataIndex++; p1 = this._dataArray[dataIndex]; dataIndex++; ctx.quadraticCurveTo( p0[0], p0[1], p1[0], p1[1] ); break; case 3: // cubic Bezier p0 = this._dataArray[dataIndex]; dataIndex++; p1 = this._dataArray[dataIndex]; dataIndex++; p2 = this._dataArray[dataIndex]; dataIndex++; ctx.bezierCurveTo( p0[0], p0[1], p1[0], p1[1], p2[0], p2[1] ); break; default: console.log( "unsupported path type: " + type ); break; } } // render the stroke ctx.stroke(); } this.export = function() { var rtnStr = "type: " + this.geomType() + "\n"; rtnStr += "strokeWidth: " + this._strokeWidth + "\n"; rtnStr += "strokeMat: "; if (this._strokeMaterial) rtnStr += this._strokeMaterial.getName(); else rtnStr += "flatMaterial"; rtnStr += "\n"; return rtnStr; } this.import = function( importStr ) { this._strokeWidth = this.getPropertyFromString( "strokeWidth: ", importStr ); var strokeMaterialName = this.getPropertyFromString( "strokeMat: ", importStr ); var strokeMat = MaterialsLibrary.getMaterial( strokeMaterialName ); if (!strokeMat) { console.log( "object material not found in library: " + strokeMaterialName ); strokeMat = new FlatMaterial(); } this._strokeMaterial = strokeMat; } this.collidesWithPoint = function( x, y ) { return false; } this.containsPoint = function( pt, dir ) { return false; } this.getNearPoint = function( pt, dir ) { var world = this.getWorld(); if (!world) throw( "null world in getNearPoint" ); // get a point on the plane of the circle // the point is in NDC, as is the input parameters var mat = this.getMatrix(); var plane = [0,0,1,0]; plane = MathUtils.transformPlane( plane, mat ); 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 ); // get the normalized device coordinates (NDC) for // the position and radii. var vpw = world.getViewportWidth(), vph = world.getViewportHeight(); var xNDC = 2*this._xOffset/vpw, yNDC = 2*this._yOffset/vph; var projMat = world.makePerspectiveMatrix(); var z = -world.getViewDistance(); var planePtNDC = planePt.slice(0); planePtNDC[2] = z; planePtNDC = MathUtils.transformHomogeneousPoint( planePtNDC, projMat ); planePtNDC = MathUtils.applyHomogeneousCoordinate( planePtNDC ); // get the gl coordinates 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; // convert to GL coordinates var objPt = [0, 0, 0]; objPt[0] = -z*(r-l)/(2.0*zn)*objPt[0]; objPt[1] = -z*(t-b)/(2.0*zn)*objPt[1]; // re-apply the transform objPt = MathUtils.transformPoint( objPt, mat ); return objPt; } }