/* <copyright> This file contains proprietary software owned by Motorola Mobility, Inc.<br/> No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.<br/> (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. </copyright> */ /////////////////////////////////////////////////////////////////////// // Class GLLine // GL representation of a line. // Derived from class GLGeomObj /////////////////////////////////////////////////////////////////////// function GLLine( world, xOffset, yOffset, width, height, slope, strokeSize, strokeColor, strokeMaterial, strokeStyle, xAdj, yAdj) { /////////////////////////////////////////////////////////////////////// // Instance variables /////////////////////////////////////////////////////////////////////// this._width = 2.0; this._height = 2.0; this._xOffset = 0; this._yOffset = 0; // If line doesn't fit in canvas world, we had to grow the canvas by this much on either side this._xAdj = 0; this._yAdj = 0; this._slope = 0; this._strokeWidth = 0.25; this._strokeStyle = "Solid"; this._scaleX = 1.0; this._scaleY = 1.0; if (arguments.length > 0) { this._width = width; this._height = height; this._xOffset = xOffset; this._yOffset = yOffset; this._xAdj = xAdj; this._yAdj = yAdj; this._slope = slope; this._strokeWidth = strokeSize; this._strokeColor = strokeColor; this._strokeStyle = strokeStyle; this._scaleX = (world.getViewportWidth())/(world.getViewportHeight()); } this._strokeVerticesLen = 0; this.m_world = world; this._materialAmbient = [0.2, 0.2, 0.2, 1.0]; this._materialDiffuse = [0.4, 0.4, 0.4, 1.0]; this._materialSpecular = [0.4, 0.4, 0.4, 1.0]; // initialize the inherited members this.inheritedFrom = GLGeomObj; this.inheritedFrom(); if(strokeMaterial) { this._strokeMaterial = strokeMaterial; } /////////////////////////////////////////////////////////////////////// // 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.getStrokeColor = function() { return this._strokeColor; } //this.setStrokeColor = function(c) { this._strokeColor = c; } this.getStrokeStyle = function() { return this._strokeStyle; } this.setStrokeStyle = function(s) { this._strokeStyle = s; } this.getFillMaterial = function() { return null; } this.setStrokeMaterial = function(m) { this._strokeMaterial = m; } this.getStrokeMaterial = function() { return this._strokeMaterial; } this.getWidth = function() { return this._width; } this.setWidth = function(w) { this._width = w; } this.getHeight = function() { return this._height; } this.setHeight = function(h) { this._height = h; } this.getXAdj = function() { return this._xAdj; } this.setXAdj = function(x) { this._xAdj = x; } this.getYAdj = function() { return this._yAdj; } this.setYAdj = function(y) { this._yAdj = y; } this.getSlope = function() { return this._slope; } this.setSlope = function(m) { this._slope = m; } this.geomType = function() { return this.GEOM_TYPE_LINE; } /////////////////////////////////////////////////////////////////////// // Methods /////////////////////////////////////////////////////////////////////// this.export = function() { var rtnStr = "type: " + this.geomType() + "\n"; rtnStr += "xoff: " + this._xOffset + "\n"; rtnStr += "yoff: " + this._yOffset + "\n"; rtnStr += "width: " + this._width + "\n"; rtnStr += "height: " + this._height + "\n"; rtnStr += "xAdj: " + this._xAdj + "\n"; rtnStr += "yAdj: " + this._yAdj + "\n"; rtnStr += "strokeWidth: " + this._strokeWidth + "\n"; rtnStr += "strokeColor: " + String(this._strokeColor) + "\n"; rtnStr += "strokeStyle: " + this._strokeStyle + "\n"; rtnStr += "slope: " + String(this._slope) + "\n"; rtnStr += "strokeMat: "; if (this._strokeMaterial) rtnStr += this._strokeMaterial.getName(); else rtnStr += "flatMaterial"; rtnStr += "\n"; return rtnStr; } this.import = function( importStr ) { this._xOffset = Number( this.getPropertyFromString( "xoff: ", importStr ) ); this._yOffset = Number( this.getPropertyFromString( "yoff: ", importStr ) ); this._width = Number( this.getPropertyFromString( "width: ", importStr ) ); this._height = Number( this.getPropertyFromString( "height: ", importStr ) ); this._xAdj = Number( this.getPropertyFromString( "xAdj: ", importStr ) ); this._yAdj = Number( this.getPropertyFromString( "yAdj: ", importStr ) ); this._strokeWidth = Number( this.getPropertyFromString( "strokeWidth: ", importStr ) ); var slope = this.getPropertyFromString( "slope: ", importStr ); if(isNaN(Number(slope))) this._slope = slope; else this._slope = Number(slope); var strokeMaterialName = this.getPropertyFromString( "strokeMat: ", importStr ); this._strokeStyle = this.getPropertyFromString( "strokeStyle: ", importStr ); this._strokeColor = eval( "[" + this.getPropertyFromString( "strokeColor: ", importStr ) + "]" ); var strokeMat = MaterialsLibrary.getMaterial( strokeMaterialName ); if (!strokeMat) { console.log( "object material not found in library: " + strokeMaterialName ); strokeMat = new FlatMaterial(); } this._strokeMaterial = strokeMat; } /////////////////////////////////////////////////////////////////////// // Methods /////////////////////////////////////////////////////////////////////// this.buildBuffers = function() { // get the world var world = this.getWorld(); if (!world) throw( "null world in buildBuffers" ); if (!world._useWebGL) return; // make sure RDGE has the correct context g_Engine.setContext( world.getCanvas().uuid ); // create the gl buffer var gl = world.getGLContext(); this._strokeVerticesLen = 0; var strokeVertices = []; var strokeTextures = []; var strokeNormals = []; var strokeColors = []; // var scaleMat = Matrix.I(3); // scaleMat.elements[0][0] = this._scaleX; // scaleMat.elements[1][1] = this._scaleY; // get the normalized device coordinates (NDC) for // all position and dimensions. var vpw = world.getViewportWidth(), vph = world.getViewportHeight(); var xNDC = 2*this._xOffset/vpw, yNDC = 2*this._yOffset/vph, xFillNDC = this._width/vpw, yFillNDC = this._height/vph, xAdjNDC = this._xAdj/vpw, yAdjNDC = this._yAdj/vph, xStrokeNDC = this._strokeWidth/vpw, yStrokeNDC = this._strokeWidth/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(); // get the position of the origin var x = -z*(r-l)/(2.0*zn)*xNDC, y = -z*(t-b)/(2.0*zn)*yNDC; // get the x and y fill var xFill = -z*(r-l)/(2.0*zn)*xFillNDC, yFill = -z*(t-b)/(2.0*zn)*yFillNDC; // get the x & y stroke size var xStroke = -z*(r-l)/(2.0*zn)*xStrokeNDC, yStroke = -z*(t-b)/(2.0*zn)*yStrokeNDC; // get the x & y adjustments size var xAdj = -z*(r-l)/(2.0*zn)*xAdjNDC*2, yAdj = -z*(t-b)/(2.0*zn)*yAdjNDC*2; this._primArray = []; this._materialArray = []; this._materialTypeArray = []; this._materialNodeArray = []; this._scaleX = (world._viewportWidth)/(world._viewportHeight); var innerX = xFill-xStroke; var innerY = yFill-yStroke; // if( (this._strokeStyle === "Dashed") || (this._strokeStyle === "Dotted") ) // { // var sLen = this.createStippledStrokes(strokeVertices, this._strokeWidth, this._slope, this._strokeStyle, innerX, innerY); // this._strokeVerticesLen += sLen; // } // else { if(this._slope === "vertical") { strokeVertices = [ -xFill+x, yFill+y, 0.0, xFill+x, yFill+y, 0.0, -xFill+x, -yFill+y, 0.0, xFill+x, -yFill+y, 0.0, -xFill+x, -yFill+y, 0.0, xFill+x, yFill+y, 0.0 ]; } else if(this._slope === "horizontal") { // right now, this is the same as vertical line because, // our canvas is the same size as us. // But, we will need to use this when drawing in an existing GLWorld with other shapes strokeVertices = [ -xFill+x, yFill+y, 0.0, xFill+x, yFill+y, 0.0, -xFill+x, -yFill+y, 0.0, xFill+x, -yFill+y, 0.0, -xFill+x, -yFill+y, 0.0, xFill+x, yFill+y, 0.0 ]; } else if(this._slope > 0) { // if slope is positive, draw a line from top-left to bottom-right strokeVertices = [ -xFill+x, yFill-2*yAdj+y, 0.0, -xFill+2*xAdj+x, yFill+y, 0.0, xFill-2*xAdj+x, -yFill+y, 0.0, xFill+x, -yFill+2*yAdj+y, 0.0, xFill-2*xAdj+x, -yFill+y, 0.0, -xFill+2*xAdj+x, yFill+y, 0.0 ]; } else { // else slope is negative, draw a line from bottom-left to top-right strokeVertices = [ -xFill+x, -yFill+2*yAdj+y, 0.0, -xFill+2*xAdj+x, -yFill+y, 0.0, xFill-2*xAdj+x, yFill+y, 0.0, xFill+x, yFill-2*yAdj+y, 0.0, xFill-2*xAdj+x, yFill+y, 0.0, -xFill+2*xAdj+x, -yFill+y, 0.0 ]; } } var z = 0; var indices = []; var nVerts = strokeVertices.length/3; // for(var i=0; i<nVerts; i++) // { // var vertex = Vector.create([strokeVertices[i], strokeVertices[i+1], strokeVertices[i+2]]); // strokeTextures.push(vertex.e(1)*0.5 + 0.5); strokeTextures.push(vertex.e(2)*0.5 + 0.5); // } strokeTextures = [ 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0 ]; // stroke normals var index = 0; for (var i=0; i<nVerts; i++) { // push a normal for each vertex in the stroke strokeNormals.push(0.0); strokeNormals.push(0.0); strokeNormals.push(1); indices.push( index ); index++; } var prim = ShapePrimitive.create(strokeVertices, strokeNormals, strokeTextures, indices, g_Engine.getContext().renderer.TRIANGLES, indices.length); var strokeMaterial = this.makeStrokeMaterial(); this._primArray.push( prim ); this._materialNodeArray.push( strokeMaterial.getMaterialNode() ); world.updateObject(this); } this.render = function() { // get the world var world = this.getWorld(); if (!world) throw( "null world in rectangle render" ); // get the context var ctx = world.get2DContext(); if (!ctx) return; // set up the stroke style var lineWidth = this._strokeWidth; ctx.beginPath(); ctx.lineWidth = lineWidth; ctx.strokeStyle = "#0000ff"; if (this._strokeColor) ctx.strokeStyle = MathUtils.colorToHex( this._strokeColor ); // get the points var p0, p1; var w = this._width, h = this._height; if(this._slope === "vertical") { p0 = [0.5*w, 0]; p1 = [0.5*w, h]; } else if(this._slope === "horizontal") { p0 = [0, 0.5*h]; p1 = [w, 0.5*h]; } else if(this._slope > 0) { p0 = [this._xAdj, this._yAdj]; p1 = [w - this._xAdj, h - this._yAdj]; } else { p0 = [this._xAdj, h - this._yAdj]; p1 = [w - this._xAdj, this._yAdj]; } // draw the line ctx.moveTo( p0[0], p0[1] ); ctx.lineTo( p1[0], p1[1] ); ctx.stroke(); } /* // type is Dotted or Dashed this.createStippledStrokes = function(strokeVertices, strokeSize, slope, type, innerX, innerY) { var stippleLength = strokeSize; if (type === "Dotted") { stippleLength = this.DOT_LENGTH; } else if(type === "Dashed") { stippleLength = this.DASH_LENGTH; } var numStrokes = 0; var startPos = -innerX; var endPos = innerX; var gap = this.GAP_LENGTH; if(slope === "horizontal") { gap *= this._scaleX; stippleLength *= this._scaleX; } else if(slope === "vertical") { startPos = -innerY; endPos = innerY; } else { if(this._scaleX < 1) { startPos = -innerY; endPos = innerY; strokeSize = (strokeSize*this._scaleX)/2; // strokeSize *= this._scaleX; stippleLength *= this._scaleX; } else { strokeSize = strokeSize/2; gap *= this._scaleX; stippleLength *= this._scaleX; } } while(startPos + stippleLength < endPos) { if(slope === "horizontal") { strokeVertices.push(startPos); strokeVertices.push(-strokeSize); strokeVertices.push(0); strokeVertices.push(startPos); strokeVertices.push(strokeSize); strokeVertices.push(0); strokeVertices.push(startPos+stippleLength); strokeVertices.push(-strokeSize); strokeVertices.push(0); strokeVertices.push(startPos); strokeVertices.push(strokeSize); strokeVertices.push(0); strokeVertices.push(startPos+stippleLength); strokeVertices.push(-strokeSize); strokeVertices.push(0); strokeVertices.push(startPos+stippleLength); strokeVertices.push(strokeSize); strokeVertices.push(0); } else if(slope === "vertical") { strokeVertices.push(-strokeSize); strokeVertices.push(startPos); strokeVertices.push(0); strokeVertices.push(strokeSize); strokeVertices.push(startPos); strokeVertices.push(0); strokeVertices.push(-strokeSize); strokeVertices.push(startPos+stippleLength); strokeVertices.push(0); strokeVertices.push(strokeSize); strokeVertices.push(startPos); strokeVertices.push(0); strokeVertices.push(-strokeSize); strokeVertices.push(startPos+stippleLength); strokeVertices.push(0); strokeVertices.push(strokeSize); strokeVertices.push(startPos+stippleLength); strokeVertices.push(0); } else { strokeVertices.push(startPos); strokeVertices.push(startPos*-slope-strokeSize); strokeVertices.push(0); strokeVertices.push(startPos); strokeVertices.push(startPos*-slope+strokeSize); strokeVertices.push(0); strokeVertices.push(startPos+stippleLength); strokeVertices.push((startPos+stippleLength)*-slope-strokeSize); strokeVertices.push(0); strokeVertices.push(startPos); strokeVertices.push(startPos*-slope+strokeSize); strokeVertices.push(0); strokeVertices.push(startPos+stippleLength); strokeVertices.push((startPos+stippleLength)*-slope-strokeSize); strokeVertices.push(0); strokeVertices.push(startPos+stippleLength); strokeVertices.push((startPos+stippleLength)*-slope+strokeSize); strokeVertices.push(0); } numStrokes += 6; startPos += (stippleLength+gap); } // return numStrokes; } */ this.collidesWithPoint = function( x, y ) { if(x < this._xOffset) return false; if(x > (this._xOffset + this._width)) return false; if(y < this._yOffset) return false; if(y > (this._yOffset + this._height)) return false; return true; } }