From ec10bf44c711e9c552780d2cd9ac0baef21de445 Mon Sep 17 00:00:00 2001 From: hwc487 Date: Mon, 5 Mar 2012 15:16:52 -0800 Subject: WebGL & Canvas2D file IO --- js/helper-classes/RDGE/GLCircle.js | 3 +- js/helper-classes/RDGE/GLWorld.js | 17 +- .../RDGE/Materials/BumpMetalMaterial.js | 2 +- .../RDGE/Materials/RadialGradientMaterial.js | 4 +- js/helper-classes/RDGE/runtime/GLRuntime.js | 4 +- js/helper-classes/RDGE/runtime/RuntimeGeomObj.js | 331 ++++++++++++++++++++- js/helper-classes/RDGE/runtime/RuntimeMaterial.js | 103 ++++++- 7 files changed, 433 insertions(+), 31 deletions(-) diff --git a/js/helper-classes/RDGE/GLCircle.js b/js/helper-classes/RDGE/GLCircle.js index 15ed6b6d..59d0bdaf 100755 --- a/js/helper-classes/RDGE/GLCircle.js +++ b/js/helper-classes/RDGE/GLCircle.js @@ -381,7 +381,6 @@ function GLCircle() // translate var xCtr = 0.5*world.getViewportWidth() + this._xOffset, yCtr = 0.5*world.getViewportHeight() + this._yOffset; - //ctx.setTransform( xScale, 0.0, 0.0, yScale, xCtr, yCtr ); var mat = Matrix.create( [ [ xScale, 0.0, 0.0, xCtr], [ 0.0, yScale, 0.0, yCtr], @@ -538,6 +537,8 @@ function GLCircle() rtnStr += "flatMaterial"; rtnStr += "\n"; + rtnStr += this.exportMaterials(); + return rtnStr; } diff --git a/js/helper-classes/RDGE/GLWorld.js b/js/helper-classes/RDGE/GLWorld.js index 3a779b92..ce5f0516 100755 --- a/js/helper-classes/RDGE/GLWorld.js +++ b/js/helper-classes/RDGE/GLWorld.js @@ -379,10 +379,12 @@ function GLWorld( canvas, use3D ) return false; } - - // END RDGE - //////////////////////////////////////////////////////////////////////////////////// - + this.generateUniqueNodeID = function() + { + var str = String( this._nodeCounter ); + this._nodeCounter++; + return str; + } // 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 @@ -395,13 +397,6 @@ function GLWorld( canvas, use3D ) RDGEStart( this._canvas ); this._canvas.task.stop() } - - this.generateUniqueNodeID = function() - { - var str = String( this._nodeCounter ); - this._nodeCounter++; - return str; - } } diff --git a/js/helper-classes/RDGE/Materials/BumpMetalMaterial.js b/js/helper-classes/RDGE/Materials/BumpMetalMaterial.js index 1a6c54c9..52332ab8 100755 --- a/js/helper-classes/RDGE/Materials/BumpMetalMaterial.js +++ b/js/helper-classes/RDGE/Materials/BumpMetalMaterial.js @@ -65,7 +65,7 @@ function BumpMetalMaterial() this.setProperty = function( prop, value ) { // every material should do something with the "color" property - if (prop === "color") prop = "lightDiff"; + if (prop === "color") return; //prop = "lightDiff"; // make sure we have legitimate imput var ok = this.validateProperty( prop, value ); diff --git a/js/helper-classes/RDGE/Materials/RadialGradientMaterial.js b/js/helper-classes/RDGE/Materials/RadialGradientMaterial.js index 4ebb1f30..45b260ef 100755 --- a/js/helper-classes/RDGE/Materials/RadialGradientMaterial.js +++ b/js/helper-classes/RDGE/Materials/RadialGradientMaterial.js @@ -146,8 +146,10 @@ function RadialGradientMaterial() // duplcate method requirde this.dup = function() { return new RadialGradientMaterial(); } - this.init = function() + this.init = function( world ) { + this.setWorld( world ); + // set up the shader this._shader = new jshader(); this._shader.def = radialGradientMaterialDef; diff --git a/js/helper-classes/RDGE/runtime/GLRuntime.js b/js/helper-classes/RDGE/runtime/GLRuntime.js index e0fff4a8..58cb4e33 100644 --- a/js/helper-classes/RDGE/runtime/GLRuntime.js +++ b/js/helper-classes/RDGE/runtime/GLRuntime.js @@ -131,7 +131,7 @@ function GLRuntime( canvas, importStr ) 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]); + 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)]); @@ -328,6 +328,8 @@ function GLRuntime( canvas, importStr ) } // start RDGE or load Canvas 2D objects + var index = importStr.indexOf( "scenedata: " ); + this._useWebGL = (index >= 0); if (this._useWebGL) { var id = canvas.getAttribute( "data-RDGE-id" ); diff --git a/js/helper-classes/RDGE/runtime/RuntimeGeomObj.js b/js/helper-classes/RDGE/runtime/RuntimeGeomObj.js index 2539abc1..253154f9 100644 --- a/js/helper-classes/RDGE/runtime/RuntimeGeomObj.js +++ b/js/helper-classes/RDGE/runtime/RuntimeGeomObj.js @@ -80,9 +80,9 @@ function RuntimeGeomObj() switch (materialType) { case "flat": mat = new RuntimeFlatMaterial(); break; - - case "radialGradient": + case "radialGradient": mat = new RuntimeRadialGradientMaterial(); break; case "linearGradient": mat = new RuntimeLinearGradientMaterial(); break; + case "bumpMetal": mat = new RuntimeBumpMetalMaterial(); break; case "water": case "tunnel": @@ -113,6 +113,101 @@ function RuntimeGeomObj() importStr = importStr.substr( endIndex ); } } + + //////////////////////////////////////////////////////////////////// + // vector function + + this.vecAdd = function( dimen, a, b ) + { + var rtnVec; + if ((a.length < dimen) || (b.length < dimen)) + { + throw new Error( "dimension error in vecAdd" ); + } + + rtnVec = []; + for (var i=0; i= 0.001) + { + var scale = len/sum; + rtnVec = []; + for (var i=0; i 0) + if (rad > 0.001) ctx.quadraticCurveTo( inset, height-inset, inset+rad, height-inset ); // do the bottom of the rectangle @@ -205,7 +300,7 @@ function RuntimeRectangle() ctx.lineTo( pt[0], pt[1] ); // get the bottom right arc - if (MathUtils.fpSign(rad) > 0) + if (rad > 0.001) ctx.quadraticCurveTo( width-inset, height-inset, width-inset, height-inset-rad ); // get the right of the rectangle @@ -216,7 +311,7 @@ function RuntimeRectangle() ctx.lineTo( pt[0], pt[1] ); // do the top right corner - if (MathUtils.fpSign(rad) > 0) + if (rad > 0.001) ctx.quadraticCurveTo( width-inset, inset, width-inset-rad, inset ); // do the top of the rectangle @@ -227,7 +322,7 @@ function RuntimeRectangle() ctx.lineTo( pt[0], pt[1] ); // do the top left corner - if (MathUtils.fpSign(rad) > 0) + if (rad > 0.001) ctx.quadraticCurveTo( inset, inset, inset, inset+rad ); else ctx.lineTo( inset, 2*inset ); @@ -287,5 +382,227 @@ 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 200.0) this._time = 0.0; + } + } + } + */ +} + + -- cgit v1.2.3