From 82b6b752123022670c422b8a083c93d865c9533a Mon Sep 17 00:00:00 2001
From: Jose Antonio Marquez
Date: Fri, 9 Mar 2012 11:01:59 -0800
Subject: Adding webGL I/O runtime functionality
There is a problem that needs to be resolved in the CanvasRuntime.
---
assets/CanvasDataManager.js | 83 ---
assets/CanvasRuntime.js | 1338 +++++++++++++++++++++++++++++++++++++++++++
assets/descriptor.json | 2 +-
3 files changed, 1339 insertions(+), 84 deletions(-)
delete mode 100644 assets/CanvasDataManager.js
create mode 100644 assets/CanvasRuntime.js
(limited to 'assets')
diff --git a/assets/CanvasDataManager.js b/assets/CanvasDataManager.js
deleted file mode 100644
index 8afc9de0..00000000
--- a/assets/CanvasDataManager.js
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
-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.
- */
-
-
-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 GLRuntime = require("js/lib/rdge/runtime/GLRuntime").GLRuntime;
-
-///////////////////////////////////////////////////////////////////////
-// Class ShapeRuntime
-// Manages runtime shape display
-///////////////////////////////////////////////////////////////////////
-var CanvasDataManager = function CanvasDataManager()
-{
- this.loadGLData = function(root, valueArray )
- {
- var value = valueArray;
- var nWorlds = value.length;
- for (var i=0; i= 0)
- {
- var endIndex = importStr.indexOf( "\n", startIndex );
- if (endIndex > 0)
- {
- var id = importStr.substring( startIndex+4, endIndex );
- var canvas = this.findCanvasWithID( id, root );
- if (canvas)
- {
- var rt = new GLRuntime( canvas, importStr );
- }
- }
- }
- }
- }
-
- this.collectGLData = function( elt, dataArray )
- {
- if (elt.elementModel && elt.elementModel.shapeModel && elt.elementModel.shapeModel.GLWorld)
- {
- var data = elt.elementModel.shapeModel.GLWorld.export( true );
- dataArray.push( data );
- }
-
- if (elt.children)
- {
- var nKids = elt.children.length;
- for (var i=0; i
+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 ShapeRuntime
+// Manages runtime shape display
+///////////////////////////////////////////////////////////////////////
+function CanvasDataManager()
+{
+ this.loadGLData = function(root, valueArray )
+ {
+ var value = valueArray;
+ var nWorlds = value.length;
+ for (var i=0; i= 0)
+ {
+ var endIndex = importStr.indexOf( "\n", startIndex );
+ if (endIndex > 0)
+ {
+ var id = importStr.substring( startIndex+4, endIndex );
+ var canvas = this.findCanvasWithID( id, root );
+ if (canvas)
+ {
+ var rt = new GLRuntime( canvas, importStr );
+ }
+ }
+ }
+ }
+ }
+
+ this.collectGLData = function( elt, dataArray )
+ {
+ if (elt.elementModel && elt.elementModel.shapeModel && elt.elementModel.shapeModel.GLWorld)
+ {
+ var data = elt.elementModel.shapeModel.GLWorld.export( true );
+ dataArray.push( data );
+ }
+
+ if (elt.children)
+ {
+ var nKids = elt.children.length;
+ for (var i=0; i= 0)
+ {
+ this._useWebGL = true;
+
+ var rdgeStr = importStr.substr( index+11 );
+ var endIndex = rdgeStr.indexOf( "endscene\n" );
+ if (endIndex < 0) throw new Error( "ill-formed WebGL data" );
+ var len = endIndex - index + 11;
+ rdgeStr = rdgeStr.substr( 0, endIndex );
+
+ this.myScene.importJSON( rdgeStr );
+ this.importObjects( importStr );
+ this.linkMaterials( this._geomRoot );
+ this.initMaterials();
+ }
+ else
+ {
+ this._context = this._canvas.getContext( "2d" );
+ this.importObjects( importStr );
+ this.render();
+ }
+ }
+
+ this.init = function()
+ {
+ var ctx1 = g_Engine.ctxMan.handleToObject(this._canvas.rdgeCtxHandle),
+ ctx2 = g_Engine.getContext();
+ if (ctx1 != ctx2) console.log( "***** different contexts *****" );
+ this.renderer = ctx1.renderer;
+
+ // create a camera, set its perspective, and then point it at the origin
+ var cam = new camera();
+ this._camera = cam;
+ cam.setPerspective(this.getFOV(), this.getAspect(), this.getZNear(), this.getZFar());
+ cam.setLookAt([0, 0, this.getViewDistance()], [0, 0, 0], vec3.up());
+
+ // make this camera the active camera
+ this.renderer.cameraManager().setActiveCamera(cam);
+
+ // change clear color
+ this.renderer.setClearColor([1.0, 1.0, 1.0, 0.0]);
+
+ // create an empty scene graph
+ this.myScene = new SceneGraph();
+
+ // load the scene graph data
+ this.loadScene();
+
+ // Add the scene to the engine - necessary if you want the engine to draw for you
+ var name = "myScene" + this._canvas.getAttribute( "data-RDGE-id" );
+ g_Engine.AddScene(name, this.myScene);
+
+ this._initialized = true;
+ }
+
+ // main code for handling user interaction and updating the scene
+ this.update = function(dt)
+ {
+ if (this._initialized)
+ {
+ if (!dt) dt = 0.2;
+
+ dt = 0.01; // use our own internal throttle
+ this.elapsed += dt;
+
+ // changed the global position uniform of light 0, another way to change behavior of a light
+ rdgeGlobalParameters.u_light0Pos.set( [5*Math.cos(this.elapsed), 5*Math.sin(this.elapsed), 20]);
+
+ // orbit the light nodes around the boxes
+ //this.light.setPosition([1.2*Math.cos(this.elapsed*2.0), 1.2*Math.sin(this.elapsed*2.0), 1.2*Math.cos(this.elapsed*2.0)]);
+ //this.light2.setPosition([-1.2*Math.cos(this.elapsed*2.0), 1.2*Math.sin(this.elapsed*2.0), -1.2*Math.cos(this.elapsed)]);
+
+ this.updateMaterials();
+
+ // now update all the nodes in the scene
+ this.myScene.update(dt);
+ }
+ }
+
+ this.updateMaterials = function()
+ {
+ var nMats = this._materials.length;
+ for (var i=0; i= 0)
+ {
+ // update the string to the current object
+ importStr = importStr.substr( index+7 );
+
+ // read the next object
+ var obj = this.importObject( importStr, parent );
+
+ // determine if we have children
+ var endIndex = importStr.indexOf( "ENDOBJECT\n" ),
+ childIndex = importStr.indexOf( "OBJECT\n" );
+ if (endIndex < 0) throw new Error( "ill-formed object data" );
+ if ((childIndex >= 0) && (childIndex < endIndex))
+ {
+ importStr = importStr.substr( childIndex + 7 );
+ importStr = this.importObjects( importStr, obj );
+ endIndex = importStr.indexOf( "ENDOBJECT\n" )
+ }
+
+ // remove the string for the object(s) just created
+ importStr = importStr.substr( endIndex );
+
+ // get the location of the next object
+ index = importStr.indexOf( "OBJECT\n", endIndex );
+ }
+
+ return importStr;
+ }
+
+ this.importObject = function( objStr, parent )
+ {
+ var type = Number( getPropertyFromString( "type: ", objStr ) );
+
+ var obj;
+ switch (type)
+ {
+ case 1:
+ obj = new RuntimeRectangle();
+ obj.import( objStr, parent );
+ break;
+
+ case 2: // circle
+ obj = new RuntimeOval();
+ obj.import( objStr, parent );
+ break;
+
+ case 3: // line
+ obj = new RuntimeLine();
+ obj.import( objStr, parent );
+ break;
+
+ default:
+ throw new Error( "Attempting to load unrecognized object type: " + type );
+ break;
+ }
+
+ if (obj)
+ this.addObject( obj );
+
+ return obj;
+ }
+
+ this.addObject = function( obj, parent )
+ {
+ if (!obj) return;
+ obj.setWorld( this );
+
+ if (parent == null)
+ this._geomRoot = obj;
+ else
+ parent.addChild( obj );
+ }
+
+ this.linkMaterials = function( obj )
+ {
+ if (!obj) return;
+
+ // get the array of materials from the object
+ var matArray = obj._materials;
+ var nMats = matArray.length;
+ for (var i=0; i= 0);
+ if (this._useWebGL)
+ {
+ var id = canvas.getAttribute( "data-RDGE-id" );
+ canvas.rdgeid = id;
+ g_Engine.registerCanvas(canvas, this);
+ RDGEStart( canvas );
+ }
+ else
+ {
+ this.loadScene();
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+// Class RuntimeGeomObj
+// Super class for all geometry classes
+///////////////////////////////////////////////////////////////////////
+function RuntimeGeomObj()
+{
+ ///////////////////////////////////////////////////////////////////////
+ // 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;
+
+ ///////////////////////////////////////////////////////////////////////
+ // Instance variables
+ ///////////////////////////////////////////////////////////////////////
+ this._children;
+
+ // stroke and fill colors
+ this._strokeColor = [0,0,0,0];
+ this._fillColor = [0,0,0,0];
+
+ // array of materials
+ this._materials = [];
+
+ ///////////////////////////////////////////////////////////////////////
+ // Property accessors
+ ///////////////////////////////////////////////////////////////////////
+
+ this.geomType = function() { return this.GEOM_TYPE_UNDEFINED; }
+
+ this.setWorld = function(w) { this._world = w; }
+ this.getWorld = function() { return this._world; }
+
+ ///////////////////////////////////////////////////////////////////////
+ // Methods
+ ///////////////////////////////////////////////////////////////////////
+ this.makeStrokeMaterial = function()
+ {
+ }
+
+ this.makeFillMaterial = function()
+ {
+ }
+
+
+ this.render = function()
+ {
+ }
+
+ this.addChild = function( child )
+ {
+ if (!this._children) this._children = [];
+ this._children.push( child );
+ }
+
+ this.import = function()
+ {
+ }
+
+ this.importMaterials = function(importStr)
+ {
+ var nMaterials = Number( getPropertyFromString( "nMaterials: ", importStr ) );
+ for (var i=0; i= 0.001)
+ {
+ var scale = len/sum;
+ rtnVec = [];
+ for (var i=0; i= 0)
+ rtnStr = rtnStr.substr(0, index);
+
+ return rtnStr;
+}
+
+///////////////////////////////////////////////////////////////////////
+// Class RuntimeRectangle
+///////////////////////////////////////////////////////////////////////
+function RuntimeRectangle()
+{
+ // inherit the members of RuntimeGeomObj
+ this.inheritedFrom = RuntimeGeomObj;
+ this.inheritedFrom();
+
+ this.import = function( importStr )
+ {
+ this._xOffset = Number( getPropertyFromString( "xoff: ", importStr ) );
+ this._yOffset = Number( getPropertyFromString( "yoff: ", importStr ) );
+ this._width = Number( getPropertyFromString( "width: ", importStr ) );
+ this._height = Number( getPropertyFromString( "height: ", importStr ) );
+ this._strokeWidth = Number( getPropertyFromString( "strokeWidth: ", importStr ) );
+ this._innerRadius = Number( getPropertyFromString( "innerRadius: ", importStr ) );
+ this._strokeStyle = Number( getPropertyFromString( "strokeStyle: ", importStr ) );
+ var strokeMaterialName = getPropertyFromString( "strokeMat: ", importStr );
+ var fillMaterialName = getPropertyFromString( "fillMat: ", importStr );
+ this._strokeStyle = getPropertyFromString( "strokeStyle: ", importStr );
+ this._fillColor = eval( "[" + getPropertyFromString( "fillColor: ", importStr ) + "]" );
+ this._strokeColor = eval( "[" + getPropertyFromString( "strokeColor: ", importStr ) + "]" );
+ this._tlRadius = Number( getPropertyFromString( "tlRadius: ", importStr ) );
+ this._trRadius = Number( getPropertyFromString( "trRadius: ", importStr ) );
+ this._blRadius = Number( getPropertyFromString( "blRadius: ", importStr ) );
+ this._brRadius = Number( getPropertyFromString( "brRadius: ", importStr ) );
+
+ this.importMaterials( importStr );
+ }
+
+ this.renderPath = function( inset, ctx )
+ {
+ // various declarations
+ var pt, rad, ctr, startPt, bPts;
+ var width = Math.round(this._width),
+ height = Math.round(this._height);
+
+ pt = [inset, inset]; // top left corner
+
+ var tlRad = this._tlRadius; //top-left radius
+ var trRad = this._trRadius;
+ var blRad = this._blRadius;
+ var brRad = this._brRadius;
+
+ if ((tlRad <= 0) && (blRad <= 0) && (brRad <= 0) && (trRad <= 0))
+ {
+ ctx.rect(pt[0], pt[1], width - 2*inset, height - 2*inset);
+ }
+ else
+ {
+ // get the top left point
+ rad = tlRad - inset;
+ if (rad < 0) rad = 0;
+ pt[1] += rad;
+ if (Math.abs(rad) < 0.001) pt[1] = inset;
+ ctx.moveTo( pt[0], pt[1] );
+
+ // get the bottom left point
+ pt = [inset, height - inset];
+ rad = blRad - inset;
+ if (rad < 0) rad = 0;
+ pt[1] -= rad;
+ ctx.lineTo( pt[0], pt[1] );
+
+ // get the bottom left curve
+ if (rad > 0.001)
+ ctx.quadraticCurveTo( inset, height-inset, inset+rad, height-inset );
+
+ // do the bottom of the rectangle
+ pt = [width - inset, height - inset];
+ rad = brRad - inset;
+ if (rad < 0) rad = 0;
+ pt[0] -= rad;
+ ctx.lineTo( pt[0], pt[1] );
+
+ // get the bottom right arc
+ if (rad > 0.001)
+ ctx.quadraticCurveTo( width-inset, height-inset, width-inset, height-inset-rad );
+
+ // get the right of the rectangle
+ pt = [width - inset, inset];
+ rad = trRad - inset;
+ if (rad < 0) rad = 0;
+ pt[1] += rad;
+ ctx.lineTo( pt[0], pt[1] );
+
+ // do the top right corner
+ if (rad > 0.001)
+ ctx.quadraticCurveTo( width-inset, inset, width-inset-rad, inset );
+
+ // do the top of the rectangle
+ pt = [inset, inset]
+ rad = tlRad - inset;
+ if (rad < 0) rad = 0;
+ pt[0] += rad;
+ ctx.lineTo( pt[0], pt[1] );
+
+ // do the top left corner
+ if (rad > 0.001)
+ ctx.quadraticCurveTo( inset, inset, inset, inset+rad );
+ else
+ ctx.lineTo( inset, 2*inset );
+ }
+ }
+
+ 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;
+
+ // get some dimensions
+ var lw = this._strokeWidth;
+ var w = world.getViewportWidth(),
+ h = world.getViewportHeight();
+
+ // render the fill
+ ctx.beginPath();
+ if (this._fillColor)
+ {
+ var c = "rgba(" + 255*this._fillColor[0] + "," + 255*this._fillColor[1] + "," + 255*this._fillColor[2] + "," + this._fillColor[3] + ")";
+ ctx.fillStyle = c;
+
+ ctx.lineWidth = lw;
+ var inset = Math.ceil( lw ) + 0.5;
+ this.renderPath( inset, ctx );
+ ctx.fill();
+ ctx.closePath();
+ }
+
+ // render the stroke
+ ctx.beginPath();
+ if (this._strokeColor)
+ {
+ var c = "rgba(" + 255*this._strokeColor[0] + "," + 255*this._strokeColor[1] + "," + 255*this._strokeColor[2] + "," + this._strokeColor[3] + ")";
+ ctx.strokeStyle = c;
+
+ ctx.lineWidth = lw;
+ var inset = Math.ceil( 0.5*lw ) + 0.5;
+ this.renderPath( inset, ctx );
+ ctx.stroke();
+ ctx.closePath();
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////////////
+// Class RuntimeOval
+///////////////////////////////////////////////////////////////////////
+function RuntimeOval()
+{
+ // inherit the members of RuntimeGeomObj
+ this.inheritedFrom = RuntimeGeomObj;
+ this.inheritedFrom();
+
+ this.import = function( importStr )
+ {
+ this._xOffset = Number( getPropertyFromString( "xoff: ", importStr ) );
+ this._yOffset = Number( getPropertyFromString( "yoff: ", importStr ) );
+ this._width = Number( getPropertyFromString( "width: ", importStr ) );
+ this._height = Number( getPropertyFromString( "height: ", importStr ) );
+ this._strokeWidth = Number( getPropertyFromString( "strokeWidth: ", importStr ) );
+ this._innerRadius = Number( getPropertyFromString( "innerRadius: ", importStr ) );
+ this._strokeStyle = getPropertyFromString( "strokeStyle: ", importStr );
+ var strokeMaterialName = getPropertyFromString( "strokeMat: ", importStr );
+ var fillMaterialName = getPropertyFromString( "fillMat: ", importStr );
+ this._fillColor = eval( "[" + getPropertyFromString( "fillColor: ", importStr ) + "]" );
+ this._strokeColor = eval( "[" + getPropertyFromString( "strokeColor: ", importStr ) + "]" );
+
+ this.importMaterials( importStr );
+ }
+
+ 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;
+
+ // declare some variables
+ var p0, p1;
+ var x0, y1, x1, y1;
+
+ // create the matrix
+ var lineWidth = this._strokeWidth;
+ var innerRad = this._innerRadius;
+ var xScale = 0.5*this._width - lineWidth,
+ yScale = 0.5*this._height - lineWidth;
+
+ // translate
+ var xCtr = 0.5*world.getViewportWidth() + this._xOffset,
+ yCtr = 0.5*world.getViewportHeight() + this._yOffset;
+ var mat = Matrix.create( [
+ [ xScale, 0.0, 0.0, xCtr],
+ [ 0.0, yScale, 0.0, yCtr],
+ [ 0.0, 0.0, 1.0, 0.0],
+ [ 0.0, 0.0, 0.0, 1.0]
+ ] );
+
+ // get a bezier representation of the circle
+ var bezPts = this.circularArcToBezier( [0,0,0], [1,0,0], 2.0*Math.PI );
+ if (bezPts)
+ {
+ var n = bezPts.length;
+
+ // set up the fill style
+ ctx.beginPath();
+ ctx.lineWidth = 0;
+ if (this._fillColor)
+ {
+ var c = "rgba(" + 255*this._fillColor[0] + "," + 255*this._fillColor[1] + "," + 255*this._fillColor[2] + "," + this._fillColor[3] + ")";
+ ctx.fillStyle = c;
+
+ // draw the fill
+ ctx.beginPath();
+ var p = this.transformPoint( bezPts[0], mat );
+ ctx.moveTo( p[0], p[1] );
+ var index = 1;
+ while (index < n)
+ {
+ p0 = this.transformPoint( bezPts[index], mat );
+ p1 = this.transformPoint( bezPts[index+1], mat );
+
+ x0 = p0[0]; y0 = p0[1];
+ x1 = p1[0]; y1 = p1[1];
+ ctx.quadraticCurveTo( x0, y0, x1, y1 );
+ index += 2;
+ }
+
+ if ( innerRad > 0.001)
+ {
+ xScale = 0.5*innerRad*this._width;
+ yScale = 0.5*innerRad*this._height;
+ mat[0] = xScale;
+ mat[5] = yScale;
+
+ // get the bezier points
+ var bezPts = this.circularArcToBezier( Vector.create([0,0,0]), Vector.create([1,0,0]), -2.0*Math.PI );
+ if (bezPts)
+ {
+ var n = bezPts.length;
+ p = this.transformPoint( bezPts[0], mat );
+ ctx.moveTo( p[0], p[1] );
+ index = 1;
+ while (index < n)
+ {
+ p0 = this.transformPoint( bezPts[index], mat );
+ p1 = this.transformPoint( bezPts[index+1], mat );
+
+ var x0 = p0[0], y0 = p0[1],
+ x1 = p1[0], y1 = p1[1];
+ ctx.quadraticCurveTo( x0, y0, x1, y1 );
+ index += 2;
+ }
+ }
+ }
+
+ // fill the path
+ ctx.fill();
+ }
+
+ // calculate the stroke matrix
+ xScale = 0.5*this._width - 0.5*lineWidth;
+ yScale = 0.5*this._height - 0.5*lineWidth;
+ mat[0] = xScale;
+ mat[5] = yScale;
+
+ // set up the stroke style
+ ctx.beginPath();
+ ctx.lineWidth = lineWidth;
+ if (this._strokeColor)
+ {
+ var c = "rgba(" + 255*this._strokeColor[0] + "," + 255*this._strokeColor[1] + "," + 255*this._strokeColor[2] + "," + this._strokeColor[3] + ")";
+ ctx.strokeStyle = c;
+
+ // draw the stroke
+ p = this.transformPoint( bezPts[0], mat );
+ ctx.moveTo( p[0], p[1] );
+ index = 1;
+ while (index < n)
+ {
+ var p0 = this.transformPoint( bezPts[index], mat );
+ var p1 = this.transformPoint( bezPts[index+1], mat );
+
+ var x0 = p0[0], y0 = p0[1],
+ x1 = p1[0], y1 = p1[1];
+ ctx.quadraticCurveTo( x0, y0, x1, y1 );
+ index += 2;
+ }
+
+ if (innerRad > 0.01)
+ {
+ // calculate the stroke matrix
+ xScale = 0.5*innerRad*this._width - 0.5*lineWidth;
+ yScale = 0.5*innerRad*this._height - 0.5*lineWidth;
+ mat[0] = xScale;
+ mat[5] = yScale;
+
+ // draw the stroke
+ p = this.transformPoint( bezPts[0], mat );
+ ctx.moveTo( p[0], p[1] );
+ index = 1;
+ while (index < n)
+ {
+ var p0 = this.transformPoint( bezPts[index], mat );
+ var p1 = this.transformPoint( bezPts[index+1], mat );
+
+ var x0 = p0[0], y0 = p0[1],
+ x1 = p1[0], y1 = p1[1];
+ ctx.quadraticCurveTo( x0, y0, x1, y1 );
+ index += 2;
+ }
+ }
+
+ // render the stroke
+ ctx.stroke();
+ }
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+ // this function returns the quadratic Bezier approximation to the specified
+ // circular arc. The input can be 2D or 3D, determined by the minimum dimension
+ // of the center and start point.
+ // includedAngle is in radians, can be positiveor negative
+ this.circularArcToBezier= function( ctr_, startPt_, includedAngle )
+ {
+ var dimen = 3;
+ var ctr = ctr_.slice();
+ var startPt = startPt_.slice();
+
+ // make sure the start point is good
+ var pt = this.vecSubtract(dimen, startPt, ctr);
+ var rad = this.vecMag(dimen, pt);
+
+ if ((dimen != 3) || (rad <= 0) || (includedAngle === 0))
+ {
+ if (dimen != 3) console.log( "circularArcToBezier works for 3 dimensional points only. Was " + dimen );
+ return [ startPt.slice(0), startPt.slice(0), startPt.slice(0) ];
+ }
+
+ // determine the number of segments. 45 degree span maximum.
+ var nSegs = Math.ceil( Math.abs(includedAngle)/(0.25*Math.PI) );
+ if (nSegs <= 0) return [ startPt.slice(0), startPt.slice(0), startPt.slice(0) ];
+ var dAngle = includedAngle/nSegs;
+
+ // determine the length of the center control point from the circle center
+ var cs = Math.cos( 0.5*Math.abs(dAngle) ), sn = Math.sin( 0.5*Math.abs(dAngle) );
+ var c = rad*sn;
+ var h = c*sn/cs;
+ var d = rad*cs + h;
+
+ var rtnPts = [ this.vecAdd(dimen, pt, ctr) ];
+ var rotMat = Matrix.RotationZ( dAngle );
+ for ( var i=0; i= 0)
+ rtnStr = rtnStr.substr(0, index);
+
+ return rtnStr;
+ }
+
+}
+
+function RuntimeFlatMaterial()
+{
+ // inherit the members of RuntimeMaterial
+ this.inheritedFrom = RuntimeMaterial;
+ this.inheritedFrom();
+
+ this._name = "FlatMaterial";
+ this._shaderName = "flat";
+
+ // assign a default color
+ this._color = [1,0,0,1];
+
+ this.import = function( importStr )
+ {
+ var colorStr = this.getPropertyFromString( "color: ", importStr );
+ if (colorStr)
+ this._color = eval( "[" + colorStr + "]" );
+ };
+
+
+ this.init = function()
+ {
+ if (this._shader)
+ {
+ this._shader.colorMe["color"].set( this._color );
+ }
+ }
+}
+
+function RuntimePulseMaterial()
+{
+ // inherit the members of RuntimeMaterial
+ this.inheritedFrom = RuntimeMaterial;
+ this.inheritedFrom();
+
+ this._name = "PulseMaterial";
+ this._shaderName = "pulse";
+
+ this._texMap = 'assets/images/cubelight.png';
+
+ this.isAnimated = function() { return true; }
+
+
+ this.import = function( importStr )
+ {
+ this._texMap = this.getPropertyFromString( "texture: ", importStr );
+ }
+
+ this.init = function()
+ {
+ var material = this._materialNode;
+ if (material)
+ {
+ var technique = material.shaderProgram.default;
+ var renderer = g_Engine.getContext().renderer;
+ if (renderer && technique)
+ {
+ if (this._shader && this._shader.default)
+ {
+ var res = [ renderer.vpWidth, renderer.vpHeight ];
+ technique.u_resolution.set( res );
+
+ var wrap = 'REPEAT', mips = true;
+ var tex = renderer.getTextureByName(this._texMap, wrap, mips );
+ if (tex)
+ technique.u_tex0.set( tex );
+
+ this._shader.default.u_time.set( [this._time] );
+ }
+ }
+ }
+ }
+
+ // several materials inherit from pulse.
+ // they may share this update method
+ this.update = function( time )
+ {
+ var material = this._materialNode;
+ if (material)
+ {
+ var technique = material.shaderProgram.default;
+ var renderer = g_Engine.getContext().renderer;
+ if (renderer && technique)
+ {
+ if (this._shader && this._shader.default)
+ this._shader.default.u_time.set( [this._time] );
+ this._time += this._dTime;
+ if (this._time > 200.0) this._time = 0.0;
+ }
+ }
+ }
+}
+
+function RuntimeRadialGradientMaterial()
+{
+ // inherit the members of RuntimeMaterial
+ this.inheritedFrom = RuntimeMaterial;
+ this.inheritedFrom();
+
+ this._name = "RadialGradientMaterial";
+ this._shaderName = "radialGradient";
+
+ // setup default values
+ this._color1 = [1,0,0,1]; this._colorStop1 = 0.0;
+ this._color2 = [0,1,0,1]; this._colorStop2 = 0.3;
+ this._color3 = [0,1,0,1]; this._colorStop3 = 0.6;
+ this._color4 = [0,1,0,1]; this._colorStop4 = 1.0;
+
+ this.init = function()
+ {
+ var material = this._materialNode;
+ if (material)
+ {
+ var technique = material.shaderProgram.default;
+ var renderer = g_Engine.getContext().renderer;
+ if (renderer && technique)
+ {
+ if (this._shader && this._shader.default)
+ {
+ this._shader.default.u_color1.set( this._color1 );
+ this._shader.default.u_color2.set( this._color2 );
+ this._shader.default.u_color3.set( this._color3 );
+ this._shader.default.u_color4.set( this._color4 );
+
+ this._shader.default.u_colorStop1.set( [this._colorStop1] );
+ this._shader.default.u_colorStop2.set( [this._colorStop2] );
+ this._shader.default.u_colorStop3.set( [this._colorStop3] );
+ this._shader.default.u_colorStop4.set( [this._colorStop4] );
+
+ if (this._angle !== undefined)
+ this._shader.default.u_cos_sin_angle.set([Math.cos(this._angle), Math.sin(this._angle)]);
+ }
+ }
+ }
+ }
+
+ this.import = function( importStr )
+ {
+ var colorStr;
+ colorStr = this.getPropertyFromString( "color1: ", importStr );
+ this._color1 = eval( "[" + colorStr + "]" );
+ colorStr = this.getPropertyFromString( "color2: ", importStr );
+ this._color2 = eval( "[" + colorStr + "]" );
+ colorStr = this.getPropertyFromString( "color3: ", importStr );
+ this._color3 = eval( "[" + colorStr + "]" );
+ colorStr = this.getPropertyFromString( "color4: ", importStr );
+ this._color4 = eval( "[" + colorStr + "]" );
+
+ this._colorStop1 = Number( this.getPropertyFromString( "colorStop1: ", importStr ) );
+ this._colorStop2 = Number( this.getPropertyFromString( "colorStop2: ", importStr ) );
+ this._colorStop3 = Number( this.getPropertyFromString( "colorStop3: ", importStr ) );
+ this._colorStop4 = Number( this.getPropertyFromString( "colorStop4: ", importStr ) );
+
+ if (this._angle !== undefined)
+ this._angle = this.getPropertyFromString( "angle: ", importStr );
+ }
+
+}
+
+function RuntimeLinearGradientMaterial()
+{
+ // inherit the members of RuntimeMaterial
+ this.inheritedFrom = RuntimeRadialGradientMaterial;
+ this.inheritedFrom();
+
+ this._name = "LinearGradientMaterial";
+ this._shaderName = "linearGradient";
+
+ // the only difference between linear & radial gradient is the existance of an angle for linear.
+ this._angle = 0.0;
+}
+
+function RuntimeBumpMetalMaterial()
+{
+ // inherit the members of RuntimeMaterial
+ this.inheritedFrom = RuntimeMaterial;
+ this.inheritedFrom();
+
+ this._name = "BumpMetalMaterial";
+ this._shaderName = "bumpMetal";
+
+ this._lightDiff = [0.3, 0.3, 0.3, 1.0];
+ this._diffuseTexture = "assets/images/metal.png";
+ this._specularTexture = "assets/images/silver.png";
+ this._normalTexture = "assets/images/normalMap.png";
+
+ this.import = function( importStr )
+ {
+ this._lightDiff = eval( "[" + this.getPropertyFromString( "lightDiff: ", importStr ) + "]" );
+ this._diffuseTexture = this.getPropertyFromString( "diffuseTexture: ", importStr );
+ this._specularTexture = this.getPropertyFromString( "specularTexture: ", importStr );
+ this._normalTexture = this.getPropertyFromString( "normalMap: ", importStr );
+ }
+
+ this.init = function()
+ {
+ var material = this._materialNode;
+ if (material)
+ {
+ var technique = material.shaderProgram.default;
+ var renderer = g_Engine.getContext().renderer;
+ if (renderer && technique)
+ {
+ if (this._shader && this._shader.default)
+ {
+ technique.u_light0Diff.set( this._lightDiff );
+
+ var tex;
+ var wrap = 'REPEAT', mips = true;
+ if (this._diffuseTexture)
+ {
+ tex = renderer.getTextureByName(this._diffuseTexture, wrap, mips );
+ if (tex) technique.u_colMap.set( tex );
+
+ }
+ if (this._normalTexture)
+ {
+ tex = renderer.getTextureByName(this._normalTexture, wrap, mips );
+ if (tex) technique.u_normalMap.set( tex );
+ }
+ if (this._specularTexture)
+ {
+ tex = renderer.getTextureByName(this._specularTexture, wrap, mips );
+ technique.u_glowMap.set( tex );
+ }
+ }
+ }
+ }
+ }
+}
+
+function RuntimeUberMaterial()
+{
+}
+
+function RuntimePlasmaMaterial()
+{
+ // inherit the members of RuntimeMaterial
+ this.inheritedFrom = RuntimeMaterial;
+ this.inheritedFrom();
+
+ this.init = function( )
+ {
+ this.update();
+ }
+
+ this.update = function( time )
+ {
+ var material = this._materialNode;
+ if (material)
+ {
+ var technique = material.shaderProgram.default;
+ var renderer = g_Engine.getContext().renderer;
+ if (renderer && technique)
+ {
+ if (this._shader && this._shader.default)
+ this._shader.default.u_time.set( [this._time] );
+ this._time += this._dTime;
+ if (this._time > 200.0) this._time = 0.0;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/assets/descriptor.json b/assets/descriptor.json
index c3a3d934..fb56d208 100644
--- a/assets/descriptor.json
+++ b/assets/descriptor.json
@@ -4,7 +4,7 @@
"root": "/assets/",
"directories": [{"name": "images"}, {"name": "shaders"}],
"files": [
- "CanvasDataManager.js",
+ "CanvasRuntime.js",
"images/black.png",
"images/blue.png",
"images/BoxB2_AO.png",
--
cgit v1.2.3
From f83a04cda688cc9680749fffae6c0b9fa0c2087f Mon Sep 17 00:00:00 2001
From: hwc487
Date: Fri, 9 Mar 2012 13:29:01 -0800
Subject: Added asset folder replacement to runtime load.
---
assets/CanvasRuntime.js | 34 +++++++++++++++++++++++++++++-----
1 file changed, 29 insertions(+), 5 deletions(-)
(limited to 'assets')
diff --git a/assets/CanvasRuntime.js b/assets/CanvasRuntime.js
index d16613ca..5caf72ee 100644
--- a/assets/CanvasRuntime.js
+++ b/assets/CanvasRuntime.js
@@ -11,8 +11,10 @@ No rights, expressed or implied, whatsoever to this software are provided by Mot
///////////////////////////////////////////////////////////////////////
function CanvasDataManager()
{
- this.loadGLData = function(root, valueArray )
+ this.loadGLData = function(root, valueArray, assetPath )
{
+ this._assetPath = assetPath.slice();
+
var value = valueArray;
var nWorlds = value.length;
for (var i=0; i= 0)
+ {
+ rtnPath = url.substr( index + searchStr.length );
+ rtnPath = this._assetPath + rtnPath;
+ }
+ return rtnPath;
+ }
+
this.findMaterialNode = function( nodeName, node )
{
if (node.transformNode)
@@ -1121,7 +1141,7 @@ function RuntimePulseMaterial()
this._texMap = this.getPropertyFromString( "texture: ", importStr );
}
- this.init = function()
+ this.init = function( world )
{
var material = this._materialNode;
if (material)
@@ -1136,6 +1156,7 @@ function RuntimePulseMaterial()
technique.u_resolution.set( res );
var wrap = 'REPEAT', mips = true;
+ this._texMap = world.remapAssetFolder( this._texMap );
var tex = renderer.getTextureByName(this._texMap, wrap, mips );
if (tex)
technique.u_tex0.set( tex );
@@ -1284,17 +1305,20 @@ function RuntimeBumpMetalMaterial()
var wrap = 'REPEAT', mips = true;
if (this._diffuseTexture)
{
+ this._diffuseTexture = world.remapAssetFolder( this._diffuseTexture );
tex = renderer.getTextureByName(this._diffuseTexture, wrap, mips );
if (tex) technique.u_colMap.set( tex );
}
if (this._normalTexture)
{
+ this._normalTexture = world.remapAssetFolder( this._normalTexture );
tex = renderer.getTextureByName(this._normalTexture, wrap, mips );
if (tex) technique.u_normalMap.set( tex );
}
if (this._specularTexture)
{
+ this._specularTexture = world.remapAssetFolder( this._specularTexture );
tex = renderer.getTextureByName(this._specularTexture, wrap, mips );
technique.u_glowMap.set( tex );
}
--
cgit v1.2.3
From 5da69dfd30f353ff753cba9322744e2f33f32a1a Mon Sep 17 00:00:00 2001
From: Jose Antonio Marquez
Date: Fri, 9 Mar 2012 13:36:15 -0800
Subject: Adding missing file for webGL, still need a fix for runtime
---
assets/descriptor.json | 1 +
assets/rdge-compiled.js | 452 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 453 insertions(+)
create mode 100755 assets/rdge-compiled.js
(limited to 'assets')
diff --git a/assets/descriptor.json b/assets/descriptor.json
index fb56d208..2b955c40 100644
--- a/assets/descriptor.json
+++ b/assets/descriptor.json
@@ -5,6 +5,7 @@
"directories": [{"name": "images"}, {"name": "shaders"}],
"files": [
"CanvasRuntime.js",
+ "rdge-compiled.js",
"images/black.png",
"images/blue.png",
"images/BoxB2_AO.png",
diff --git a/assets/rdge-compiled.js b/assets/rdge-compiled.js
new file mode 100755
index 00000000..a211d17f
--- /dev/null
+++ b/assets/rdge-compiled.js
@@ -0,0 +1,452 @@
+vec2={string:function(a){return"{ "+a[0]+", "+a[1]+" }"},verify:function(a){return a==void 0||a.length==void 0||a.length<2?!1:typeof a[0]!="number"||typeof a[1]!="number"?!1:!0},copy:function(a){return a.length==void 0?[a,a]:[a[0],a[1]]},inplace_copy:function(a,b){a[0]=b[0];a[1]=b[1]},zero:function(){return[0,0]},up:function(){return[0,1]},right:function(){return[1,0]},add:function(a,b){return[a[0]+b[0],a[1]+b[1]]},sub:function(a,b){return[a[0]-b[0],a[1]-b[1]]},mul:function(a,b){return[a[0]*b[0],
+a[1]*b[1]]},addMul:function(a,b,f){return f.length!=void 0&&f.length>=2?[a[0]+b[0]*f[0],a[1]+b[1]*f[1]]:[a[0]+b[0]*f,a[1]+b[1]*f]},scale:function(a,b){return b.length!=void 0&&b.length>=2?[a[0]*b[0],a[1]*b[1]]:[a[0]*b,a[1]*b]},negate:function(a){return[-a[0],-a[1]]},normalize:function(a){var b=Math.sqrt(a[0]*a[0],a[1]*a[1]);return Math.abs(1-b)>1.0E-4?(b=1/b,[a[0]*b,a[1]*b]):a},dot:function(a,b){return a[0]*b[0]+a[1]*b[1]},perp:function(a){return[a[1],-a[0]]},lengthSq:function(a){return a[0]*a[0]+
+a[1]*a[1]},length:function(a){return Math.sqrt(a[0]*a[0]+a[1]*a[1])},min:function(a,b){return[Math.min(a[0],b[0]),Math.min(a[1],b[1])]},max:function(a,b){return[Math.max(a[0],b[0]),Math.max(a[1],b[1])]}};vec2.clamp=function(a,b,f){return vec2.min(f,vec2.max(a,b))};vec3={string:function(a){return"{ "+a[0]+", "+a[1]+", "+a[2]+" }"},verify:function(a){return a==void 0||a.length==void 0||a.length<3?!1:typeof a[0]!="number"||typeof a[1]!="number"||typeof a[2]!="number"?!1:!0},inplace_copy:function(a,b){a[0]=b[0];a[1]=b[1];a[2]=b[2]},copy:function(a){return a.length==void 0?[a,a,a]:[a[0],a[1],a[2]]},translation:function(a){return[a[12],a[13],a[14]]},basisX:function(a){return[a[0],a[1],a[2]]},basisY:function(a){return[a[4],a[5],a[6]]},basisZ:function(a){return[a[8],
+a[9],a[10]]},zero:function(){return[0,0,0]},up:function(){return[0,1,0]},forward:function(){return[0,0,1]},right:function(){return[1,0,0]},random:function(a,b){return[a[0]+(b[0]-a[0])*Math.random(),a[1]+(b[1]-a[1])*Math.random(),a[2]+(b[2]-a[2])*Math.random()]},xy:function(a){return[a[0],a[1]]},xz:function(a){return[a[0],a[2]]},add:function(a,b){return[a[0]+b[0],a[1]+b[1],a[2]+b[2]]},plusEqual:function(a,b){a[0]+=b[0];a[1]+=b[1];a[2]+=b[2]},sub:function(a,b){return[a[0]-b[0],a[1]-b[1],a[2]-b[2]]},
+mul:function(a,b){return[a[0]*b[0],a[1]*b[1],a[2]*b[2]]},addMul:function(a,b,f){return f.length!=void 0&&f.length>=3?[a[0]+b[0]*f[0],a[1]+b[1]*f[1],a[2]+b[2]*f[2]]:[a[0]+b[0]*f,a[1]+b[1]*f,a[2]+b[2]*f]},plusEqualMul:function(a,b,f){f.length!==void 0&&f.length>=3?(a[0]+=b[0]*f[0],a[1]+=b[1]*f[1],a[2]+=b[2]*f[2]):(a[0]+=b[0]*f,a[1]+=b[1]*f,a[2]+=b[2]*f)},scale:function(a,b){return b.length!==void 0&&b.length>=3?[a[0]*b[0],a[1]*b[1],a[2]*b[2]]:[a[0]*b,a[1]*b,a[2]*b]},inplace_scale:function(a,b){b.length!==
+void 0&&b.length>=3?(a[0]*=b[0],a[1]*=b[1],a[2]*=b[2]):(a[0]*=b,a[1]*=b,a[2]*=b)},negate:function(a){return[-a[0],-a[1],-a[2]]},inplace_negate:function(a){a[0]=-a[0];a[1]=-a[1];a[2]=-a[2]},normalize:function(a){var b=Math.sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]);return Math.abs(1-b)>1.0E-4?(b=1/b,[a[0]*b,a[1]*b,a[2]*b]):a},cross:function(a,b){return[a[1]*b[2]-b[1]*a[2],a[2]*b[0]-b[2]*a[0],a[0]*b[1]-b[0]*a[1]]},dot:function(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]},lengthSq:function(a){return a[0]*a[0]+
+a[1]*a[1]+a[2]*a[2]},length:function(a){return Math.sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2])},distanceSq:function(a,b){var f=[a[0]-b[0],a[1]-b[1],a[2]-b[2]];return f[0]*f[0]+f[1]*f[1]+f[2]*f[2]},distance:function(a,b){var f=[a[0]-b[0],a[1]-b[1],a[2]-b[2]];return Math.sqrt(f[0]*f[0]+f[1]*f[1]+f[2]*f[2])}};vec3.angle=function(a,b){return Math.acos(vec3.dot(a,b))/(vec3.length(a)*vec3.length(b))};vec3.direction=function(a,b){return vec3.normalize(vec3.sub(b,a))};
+vec3.abs=function(a){return[Math.abs(a[0]),Math.abs(a[1]),Math.abs(a[2])]};vec3.min=function(a,b){return[Math.min(a[0],b[0]),Math.min(a[1],b[1]),Math.min(a[2],b[2])]};vec3.max=function(a,b){return[Math.max(a[0],b[0]),Math.max(a[1],b[1]),Math.max(a[2],b[2])]};vec3.clamp=function(a,b,f){return vec3.min(f,vec3.max(a,b))};vec3.equal=function(a,b,f){f||(f=0.0010);return vec3.distanceSq(a,b)=4?[a[0]+b[0]*
+f[0],a[1]+b[1]*f[1],a[2]+b[2]*f[2],a[3]+b[3]*f[3]]:[a[0]+b[0]*f,a[1]+b[1]*f,a[2]+b[2]*f,a[3]+b[3]*f]},scale:function(a,b){return b.length!=void 0&&b.length>=4?[a[0]*b[0],a[1]*b[1],a[2]*b[2],a[3]*b[3]]:[a[0]*b,a[1]*b,a[2]*b,a[3]*b]},negate:function(a){return[-a[0],-a[1],-a[2],-a[3]]},dot:function(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3]},normalize:function(a){var b=Math.sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]+a[3]*a[3]);return Math.abs(1-b)>1.0E-4?(b=1/b,[a[0]*b,a[1]*b,a[2]*b,a[3]*b]):a},lengthSq:function(a){return a[0]*
+a[0]+a[1]*a[1]+a[2]*a[2]+a[3]*a[3]},length:function(a){return Math.sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]+a[3]*a[3])},abs:function(a){return[Math.abs(a[0]),Math.abs(a[1]),Math.abs(a[2]),Math.abs(a[3])]},min:function(a,b){return[Math.min(a[0],b[0]),Math.min(a[1],b[1]),Math.min(a[2],b[2]),Math.min(a[3],b[3])]},max:function(a,b){return[Math.max(a[0],b[0]),Math.max(a[1],b[1]),Math.max(a[2],b[2]),Math.min(a[3],b[3])]}};vec4.clamp=function(a,b,f){return vec4.min(f,vec4.max(a,b))};
+vec4.equal=function(a,b,f){f||(f=0.0010);return vec4.distanceSq(a,b)=4?b[3]:1;return[a[0]*f+a[4]*g+a[8]*h+a[12]*l,a[1]*f+a[5]*g+a[9]*h+a[13]*l,a[2]*f+a[6]*g+a[10]*h+a[14]*l,a[3]*f+a[7]*g+a[11]*h+a[15]*l]};mat4.transformVector=function(a,b){var a=mat4.inverse(a),f=b[0],g=b[1],h=b[2],l=b.length>=4?b[3]:0;return[a[0]*f+a[1]*g+a[2]*h+a[3]*l,a[4]*f+a[5]*g+a[6]*h+a[7]*l,a[8]*f+a[9]*g+a[10]*h+a[11]*l,a[12]*f+a[13]*g+a[14]*h+a[15]*l]};
+mat4.transformPoint4x3=function(a,b){var f=b[0],g=b[1],h=b[2];return[a[0]*f+a[4]*g+a[8]*h+a[12],a[1]*f+a[5]*g+a[9]*h+a[13],a[2]*f+a[6]*g+a[10]*h+a[14],1]};mat4.transformVector4x3=function(a,b){var a=mat4.inverse(a),f=b[0],g=b[1],h=b[2];return[a[0]*f+a[1]*g+a[2]*h,a[4]*f+a[5]*g+a[6]*h,a[8]*f+a[9]*g+a[10]*h,0]};mat4.getRow=function(a,b){b*=4;return[a[b],a[b+1],a[b+2],a[b+3]]};mat4.getCol=function(a,b){return[a[b],a[b+4],a[b+8],a[b+12]]};
+mat4.setRow=function(a,b,f){b*=4;a[b+0]=f[0];a[b+1]=f[1];a[b+2]=f[2];f.length>=4&&(a[b+3]=f[3]);return a};mat4.setCol=function(a,b,f){a[b+0]=f[0];a[b+4]=f[1];a[b+8]=f[2];f.length>=4&&(a[b+12]=f[3]);return a};mat4.rotate=function(a,b,f){return mat4.mul(a,mat4.angleAxis(b,f))};mat4.rotateX=function(a,b){return mat4.mul(a,mat4.angleAxis(b,vec3.basisX(a)))};mat4.rotateY=function(a,b){return mat4.mul(a,mat4.angleAxis(b,vec3.basisY(a)))};mat4.rotateZ=function(a,b){return mat4.mul(a,mat4.angleAxis(b,vec3.basisZ(a)))};
+mat4.scale=function(a,b){var f=mat4.identity();b.length==void 0&&(b=[b,b,b]);f[0]=b[0];f[5]=b[1];f[10]=b[2];return mat4.mul(a,f)};mat4.scaleX=function(a,b){return mat4.scale(a,[b,1,1])};mat4.scaleY=function(a,b){return mat4.scale(a,[1,b,1])};mat4.scaleZ=function(a,b){return mat4.scale(a,[1,1,b])};mat4.translate=function(a,b){matT=mat4.identity();matT[12]=b[0];matT[13]=b[1];matT[14]=b[2];return mat4.mul(a,matT)};mat4.translateX=function(a,b){return mat4.translate(a,[b,0,0])};
+mat4.translateY=function(a,b){return mat4.translate(a,[0,b,0])};mat4.translateZ=function(a,b){return mat4.translate(a,[0,0,b])};quat={string:function(a){return"{ "+a[0]+", "+a[1]+", "+a[2]+", "+a[3]+" }"},verify:function(a){return a==void 0||a.length==void 0||a.length<4?!1:typeof a[0]!="number"||typeof a[1]!="number"||typeof a[2]!="number"||typeof a[3]!="number"?!1:!0},identity:function(){return[0,0,0,1]},add:function(a,b){return[a[0]+b[0],a[1]+b[1],a[2]+b[2],a[3]+b[3]]},sub:function(a,b){return[a[0]-b[0],a[1]-b[1],a[2]-b[2],a[3]-b[3]]},mul:function(a,b){return[a[3]*b[3]-a[0]*b[0]-a[1]*b[1]-a[2]*b[2],a[3]*b[0]+a[0]*b[3]+a[1]*
+b[2]-a[2]*b[1],a[3]*b[1]-a[0]*b[2]+a[1]*b[3]+a[2]*b[0],a[3]*b[2]+a[0]*b[1]-a[1]*b[0]+a[2]*b[3]]},addMul:function(a,b,f){return f.length!=void 0&&f.length>=4?[a[0]+b[0]*f[0],a[1]+b[1]*f[1],a[2]+b[2]*f[2],a[3]+b[3]*f[3]]:[a[0]+b[0]*f,a[1]+b[1]*f,a[2]+b[2]*f,a[3]+b[3]*f]},scale:function(a,b){return b.length!=void 0&&b.length>=4?[a[0]*b[0],a[1]*a[1],a[2]*b[2],a[3]*b[3]]:[a[0]*b,a[1]*b,a[2]*b,a[3]*b]},lengthSq:function(a){return a[0]*a[0]+a[1]*a[1]+a[2]*a[2]+a[3]*a[3]},length:function(a){return Math.sqrt(a[0]*
+a[0]+a[1]*a[1]+a[2]*a[2]+a[3]*a[3])},normalize:function(a){var b=Math.sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]+a[3]*a[3]);return Math.abs(1-b)>1.0E-4?(b=1/b,[a[0]*b,a[1]*b,a[2]*b,a[3]*b]):a},inverse:function(a){var b=vec4.lengthSq(a);return b>1.0E-5?(b=1/b,[a[0]*-b,a[1]*-b,a[2]*-b,a[3]]):a},dot:function(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3]}};quat.applyRotation=function(a,b){return mat4.transformPoint(quat.toMatrix(a),b)};
+quat.lerp=function(a,b,f){return quat.normalize([a[0]+(b[0]-a[0])*f,a[1]+(b[1]-a[1])*f,a[2]+(b[2]-a[2])*f,a[3]+(b[3]-a[3])*f])};quat.slerp=function(a,b,f){var g=quat.dot(a,b);if(g>=0.9)return quat.lerp(a,b,f);var h=Math.sqrt(Math.abs(1-g*g));if(h<0.0010)return a;var g=g<0?-1:1,l=Math.asin(h),n=1/h,h=Math.sin((1-f)*l)*n,f=Math.sin(f*l)*n*g;quat.scale(a,h);quat.scale(b,f);return quat.normalize(quat.add(a,b))};
+quat.toMatrix=function(a){var b=2*a[0],f=2*a[1],g=2*a[2],h=b*a[3],l=f*a[3],n=g*a[3];b*=a[0];var o=f*a[0],p=g*a[0];f*=a[1];var q=g*a[1],a=g*a[2];return[1-(f+a),o+n,p-l,0,o-n,1-(b+a),q+h,0,p+l,q-h,1-(b+f),0,0,0,0,1]};var stat=function(){pages={};dlgId="";self=function(a,b,f,g,h){h==void 0&&(h=!0);category=!a?"default":a;pages[category]||(pages[category]=[]);pages[category].push(this);this.name=b;this.value=this.defValue=f;this.func=g;this.reset=h;this.reportInterval=500;stat.dirty=!0;stat.find=function(a,b){var f=pages[a];for(i=0;i";for(a in pages)pages[a]&&(g+=''+a+"");g+="";for(a in pages)pages[a]&&(g+='',g+="
");g+="";f.innerHTML=g;$("#stat_tabs").tabs();stat.dirty=!1}for(a in pages)f=document.getElementById(a),stat.report(f,a,b)};stat.report=function(a,b){b||(b="default");var f=pages[b];if(f){outputHTML='';var g=0;for(i=0;i',
+outputHTML+=f[i].func?f[i].name+" : "+f[i].func(f[i].value):f[i].name+" : "+f[i].value,outputHTML+="",g++>=3&&(outputHTML+="
",g=0),f[i].reset)f[i].value=f[i].defValue;outputHTML+="
";a.innerHTML=outputHTML}}};setInterval(function(){self.reportAll("RDGE_STATS")},500);return self}();
+dbCanvas=function(a,b){this.front=document.createElement("canvas");this.front.setAttribute("width",a);this.front.setAttribute("height",b);this.front.setAttribute("style","position:absolute; margin: 0.0em; padding: 0.0em;");this.front.ctx=this.front.getContext("2d");this.back=document.createElement("canvas");this.back.setAttribute("width",a);this.back.setAttribute("height",b);this.front.setAttribute("style","position:absolute; margin: