/* <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> */ var MaterialsModel = require("js/models/materials-model").MaterialsModel; var FlatMaterial = require("js/lib/rdge/materials/flat-material").FlatMaterial; var LinearGradientMaterial = require("js/lib/rdge/materials/linear-gradient-material").LinearGradientMaterial; var RadialGradientMaterial = require("js/lib/rdge/materials/radial-gradient-material").RadialGradientMaterial; var BumpMetalMaterial = require("js/lib/rdge/materials/bump-metal-material").BumpMetalMaterial; var UberMaterial = require("js/lib/rdge/materials/uber-material").UberMaterial; var RadialBlurMaterial = require("js/lib/rdge/materials/radial-blur-material").RadialBlurMaterial; var PlasmaMaterial = require("js/lib/rdge/materials/plasma-material").PlasmaMaterial; var PulseMaterial = require("js/lib/rdge/materials/pulse-material").PulseMaterial; var TunnelMaterial = require("js/lib/rdge/materials/tunnel-material").TunnelMaterial; var ReliefTunnelMaterial = require("js/lib/rdge/materials/relief-tunnel-material").ReliefTunnelMaterial; var SquareTunnelMaterial = require("js/lib/rdge/materials/square-tunnel-material").SquareTunnelMaterial; var FlyMaterial = require("js/lib/rdge/materials/fly-material").FlyMaterial; var WaterMaterial = require("js/lib/rdge/materials/water-material").WaterMaterial; var ZInvertMaterial = require("js/lib/rdge/materials/z-invert-material").ZInvertMaterial; var DeformMaterial = require("js/lib/rdge/materials/deform-material").DeformMaterial; var StarMaterial = require("js/lib/rdge/materials/star-material").StarMaterial; var TwistMaterial = require("js/lib/rdge/materials/twist-material").TwistMaterial; var JuliaMaterial = require("js/lib/rdge/materials/julia-material").JuliaMaterial; var KeleidoscopeMaterial = require("js/lib/rdge/materials/keleidoscope-material").KeleidoscopeMaterial; var MandelMaterial = require("js/lib/rdge/materials/mandel-material").MandelMaterial; /////////////////////////////////////////////////////////////////////// // Class GLGeomObj // Super class for all geometry classes /////////////////////////////////////////////////////////////////////// var GeomObj = function GLGeomObj() { /////////////////////////////////////////////////////////////////////// // Constants /////////////////////////////////////////////////////////////////////// this.GEOM_TYPE_RECTANGLE = 1; this.GEOM_TYPE_CIRCLE = 2; this.GEOM_TYPE_LINE = 3; this.GEOM_TYPE_PATH = 4; this.GEOM_TYPE_CUBIC_BEZIER = 5; this.GEOM_TYPE_UNDEFINED = -1; // Needed for calculating dashed/dotted strokes this.DASH_LENGTH = 0.15; this.DOT_LENGTH = 0.05; this.GAP_LENGTH = 0.05; /////////////////////////////////////////////////////////////////////// // Instance variables /////////////////////////////////////////////////////////////////////// this._matrix = Matrix.I(4); this._next = undefined; this._prev = undefined; this._child = undefined; this._parent = undefined; this.m_world = null; // stroke and fill colors this._strokeColor = [0,0,0,0]; this._fillColor = [0,0,0,0]; // stroke and fill materials this._fillMaterial = null; this._strokeMaterial = null; // array of primitives - used in RDGE this._primArray = []; this._materialNodeArray = []; this._materialArray = []; this._materialTypeArray = []; // the transform node used by RDGE this._trNode = null; /////////////////////////////////////////////////////////////////////// // Property accessors /////////////////////////////////////////////////////////////////////// this.setWorld = function( world ) { this.m_world = world; }; this.getWorld = function() { return this.m_world; }; this.getMatrix = function() { return this._matrix.slice(0); }; this.setMatrix = function(m) { this._matrix = m.slice(0); }; this.setNext = function( next ) { this._next = next; }; this.getNext = function() { return this._next; }; this.setPrev = function( prev ) { this._prev = prev; }; this.getPrev = function() { return this._prev; }; this.setChild = function( child ) { this._child = child; }; this.getChild = function() { return this._child; }; this.setParent = function( parent ) { this._parent = parent; }; this.getParent = function() { return this._parent; }; this.geomType = function() { return this.GEOM_TYPE_UNDEFINED; }; this.getPrimitiveArray = function() { return this._primArray; }; this.getMaterialNodeArray = function() { return this._materialNodeArray; }; this.getMaterialArray = function() { return this._materialArray; }; this.getTransformNode = function() { return this._trNode; }; this.setTransformNode = function(t) { this._trNode = t; }; this.setFillColor = function(c) { this.setMaterialColor(c, "fill"); }; this.setStrokeColor = function(c) { this.setMaterialColor(c, "stroke"); }; /////////////////////////////////////////////////////////////////////// // Methods /////////////////////////////////////////////////////////////////////// this.setMaterialColor = function(c, type) { var i = 0, nMats = 0; if(c.gradientMode) { // Gradient support if (this._materialArray && this._materialTypeArray) { nMats = this._materialArray.length; } var stops = [], colors = c.color; var len = colors.length; // TODO - Current shaders only support 4 color stops if(len > 4) { len = 4; } for(var n=0; n<len; n++) { var position = colors[n].position/100; var cs = colors[n].value; var stop = [cs.r/255, cs.g/255, cs.b/255, cs.a]; stops.push(stop); if (nMats === this._materialTypeArray.length) { for (i=0; i<nMats; i++) { if (this._materialTypeArray[i] == type) { this._materialArray[i].setProperty( "color"+(n+1), stop.slice(0) ); this._materialArray[i].setProperty( "colorStop"+(n+1), position ); } } } } if (type === "fill") { this._fillColor = c; } else { this._strokeColor = c; } } else { if (type === "fill") { this._fillColor = c.slice(0); } else { this._strokeColor = c.slice(0); } if (this._materialArray && this._materialTypeArray) { nMats = this._materialArray.length; if (nMats === this._materialTypeArray.length) { for (i=0; i<nMats; i++) { if (this._materialTypeArray[i] == type) { this._materialArray[i].setProperty( "color", c.slice(0) ); } } } } } var world = this.getWorld(); if (world) { world.restartRenderLoop(); } }; this.makeStrokeMaterial = function() { var strokeMaterial; if (this.getStrokeMaterial()){ strokeMaterial = this.getStrokeMaterial().dup(); } else { strokeMaterial = MaterialsModel.exportFlatMaterial(); } if (strokeMaterial) { strokeMaterial.init( this.getWorld() ); } this._materialArray.push( strokeMaterial ); this._materialTypeArray.push( "stroke" ); if(this._strokeColor) { this.setStrokeColor(this._strokeColor); } return strokeMaterial; }; this.makeFillMaterial = function() { var fillMaterial; if (this.getFillMaterial()) { fillMaterial = this.getFillMaterial().dup(); } else { fillMaterial = MaterialsModel.exportFlatMaterial(); } if (fillMaterial) { fillMaterial.init( this.getWorld() ); } this._materialArray.push( fillMaterial ); this._materialTypeArray.push( "fill" ); if (this._fillColor) { this.setFillColor(this._fillColor); } return fillMaterial; }; this.exportMaterials = function() { var rtnStr = ""; if (this._materialArray && this._materialNodeArray) { var nMats = this._materialArray.length; rtnStr += "nMaterials: " + nMats + "\n"; for (var i=0; i<nMats; i++) { var matNode = this._materialNodeArray[i]; rtnStr += "materialNodeName: " + matNode.name + "\n"; var material = this._materialArray[i]; rtnStr += material.export(); } } else rtnStr += "nMaterials: 0\n" ; return rtnStr; } this.importMaterials = function(importStr) { var nMaterials = Number( this.getPropertyFromString( "nMaterials: ", importStr ) ); for (var i=0; i<nMaterials; i++) { var mat; var materialType = this.getPropertyFromString( "material: ", importStr ); switch (materialType) { case "flat": mat = new FlatMaterial(); break; case "radialGradient": mat = new RadialGradientMaterial(); break; case "linearGradient": mat = new LinearGradientMaterial(); break; case "bumpMetal": mat = new BumpMetalMaterial(); break; case "uber": mat = new UberMaterial(); break; case "plasma": mat = new PlasmaMaterial(); break; case "deform": mat = new DeformMaterial(); break; case "water": mat = new WaterMaterial(); break; case "tunnel": mat = new TunnelMaterial(); break; case "reliefTunnel": mat = new ReliefTunnelMaterial(); break; case "squareTunnel": mat = new SquareTunnelMaterial(); break; case "twist": mat = new TwiseMaterial(); break; case "fly": mat = new FlyMaterial(); break; case "julia": mat = new JuliaMaterial(); break; case "mandel": mat = new MandelMaterial(); break; case "star": mat = new StarMaterial(); break; case "zinvert": mat = new ZInvertMaterial(); break; case "keleidoscope": mat = new KeleidoscopeMaterial(); break; case "radialBlur": mat = new RadialBlurMaterial(); break; case "pulse": mat = new PulseMaterial(); break; default: console.log( "material type: " + materialType + " is not supported" ); break; } if (mat) mat.import( importStr ); // pull off the end of the material var endMat = "endMaterial\n"; var endIndex = importStr.indexOf( endMat ); if (endIndex < 0) break; importStr = importStr.substr( endIndex + endMat.length ); } } this.translate = function(v) { var mat = Matrix.Translation( v ); //var mat2 = mat.multiply( this._matrix ); //this._matrix = mat2; glmat4.multiply(mat, this._matrix, this._matrix); }; this.transform = function( mat ) { if (mat) { //this._matrix = mat.multiply( this._matrix ); glmat4.multiply(mat, this._matrix, this._matrix); } }; this.setMatrix = function(mat) { var gl = this.getWorld().getGLContext(); if (gl) { gl.uniformMatrix4fv(this.getWorld().getShaderProgram().mvMatrixUniform, false, new Float32Array(mat)); } }; this.buildBuffers = function() { // this function must be overridden by the base class alert( "GLGeomObj.buildBuffers must be overridden by base class" ); }; this.render = function() { alert( "GLGeomObj.render method must be overridden by sub class" ); }; this.collidesWithPoint = function( x, y ) { alert( "GLGeomObj.collidesWithPoint method must be overridden by sub class" ); }; this.getNearPoint = function( pt, dir ) { // the alert is not displayed. Objects may choose not to implement this method. //alert( "GLGeomObj.getNearPoint method must be overridden by sub class" ); }; this.getNearVertex = function( pt, dir ) { // this should be overridden by objects (such as rectangles) that have corners }; this.containsPoint = function( pt, dir ) { // the alert is not displayed. Objects may choose not to implement this method. //alert( "GLGeomObj.containsPoint method must be overridden by sub class" ); }; this.getPropertyFromString = function( prop, str ) { var index = str.indexOf( prop ); if (index < 0) throw new Error( "property " + prop + " not found in string: " + str); var rtnStr = str.substr( index+prop.length ); index = rtnStr.indexOf( "\n" ); if (index >= 0) { rtnStr = rtnStr.substr(0, index); } return rtnStr; }; // Gradient stops for rgba(255,0,0,1) at 0%; rgba(0,255,0,1) at 33%; rgba(0,0,255,1) at 100% will return // 255,0,0,1@0;0,255,0,1@33;0,0,255,1@100 this.gradientToString = function(colors) { var rtnStr = ""; if(colors && colors.length) { var c = colors[0], len = colors.length; rtnStr += String(c.value.r + "," + c.value.g + "," + c.value.b + "," + c.value.a + "@" + c.position); for(var i=1; i<len; i++) { c = colors[i]; rtnStr += ";" + String(c.value.r + "," + c.value.g + "," + c.value.b + "," + c.value.a + "@" + c.position); } } return rtnStr; }; // Given a gradientStr "255,0,0,1@0;0,255,0,1@33;0,0,255,1@100" will return: // colors array [{position:0, value:{r:255, g:0, b:0, a:1}}, // {position:33, value:{r:0, g:255, b:0, a:1}}, // {position:100, value:{r:0, g:0, b:255, a:1}} // ] this.stringToGradient = function(gradientStr) { var rtnArr = []; var i, len, stops, stop, c; stops = gradientStr.split(";"); len = stops.length; for(i=0; i<len; i++) { stop = stops[i].split("@"); c = stop[0].split(","); rtnArr.push({ position: Number(stop[1]), value:{r:Number(c[0]), g:Number(c[1]), b:Number(c[2]), a:Number(c[3])} }); } return rtnArr; }; /* this.export = function() { var rtnStr; return rtnStr; } */ }; if (typeof exports === "object") { exports.GeomObj = GeomObj; }