/* <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> */
///////////////////////////////////////////////////////////////////////
//Loading webGL/canvas data
function initWebGl (rootElement, directory) {
var cvsDataMngr, ninjaWebGlData = JSON.parse((document.querySelectorAll(['script[data-ninja-webgl]'])[0].innerHTML.replace('(', '')).replace(')', ''));
if (ninjaWebGlData && ninjaWebGlData.data) {
for (var n=0; ninjaWebGlData.data[n]; n++) {
ninjaWebGlData.data[n] = unescape(ninjaWebGlData.data[n]);
}
}
//Creating data manager
cvsDataMngr = new CanvasDataManager();
//Loading data to canvas(es)
cvsDataMngr.loadGLData(rootElement, ninjaWebGlData.data, directory);
}
///////////////////////////////////////////////////////////////////////
// Class ShapeRuntime
// Manages runtime shape display
///////////////////////////////////////////////////////////////////////
function CanvasDataManager()
{
this.loadGLData = function(root, valueArray, assetPath )
{
if (assetPath)
this._assetPath = assetPath.slice();
var value = valueArray;
var nWorlds = value.length;
for (var i=0; i<nWorlds; i++)
{
var importStr = value[i];
var startIndex = importStr.indexOf( "id: " );
if (startIndex >= 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, assetPath );
}
}
}
}
}
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<nKids; i++)
{
var child = elt.children[i];
this.collectGLData( child, dataArray );
}
}
}
this.findCanvasWithID = function( id, elt )
{
var cid = elt.getAttribute( "data-RDGE-id" );
if (cid == id) return elt;
if (elt.children)
{
var nKids = elt.children.length;
for (var i=0; i<nKids; i++)
{
var child = elt.children[i];
var foundElt = this.findCanvasWithID( id, child );
if (foundElt) return foundElt;
}
}
}
}
///////////////////////////////////////////////////////////////////////
// Class GLRuntime
// Manages runtime fora WebGL canvas
///////////////////////////////////////////////////////////////////////
function GLRuntime( canvas, importStr, assetPath )
{
///////////////////////////////////////////////////////////////////////
// Instance variables
///////////////////////////////////////////////////////////////////////
this._canvas = canvas;
this._context = null;
this._importStr = importStr;
this.renderer = null;
this.myScene = null;
this.light = null;
this.light2 = null;
this._rootNode = null;
this._firstRender = true;
this._initialized = false;
this._useWebGL = false;
// view parameters
this._fov = 45.0;
this._zNear = 0.1;
this._zFar = 100.0;
this._viewDist = 5.0;
this.elapsed = 0;
this._aspect = canvas.width/canvas.height;
this._geomRoot = null;
// all "live" materials
this._materials = [];
// provide the mapping for the asset directory
if (assetPath)
{
this._assetPath = assetPath.slice();
if (this._assetPath[this._assetPath.length-1] != '/')
this._assetPath += '/';
}
///////////////////////////////////////////////////////////////////////
// accessors
///////////////////////////////////////////////////////////////////////
this.getZNear = function() { return this._zNear; }
this.getZFar = function() { return this._zFar; }
this.getFOV = function() { return this._fov; }
this.getAspect = function() { return this._aspect; }
this.getViewDistance = function() { return this._viewDist; }
this.get2DContext = function() { return this._context; }
this.getViewportWidth = function() { return this._canvas.width; }
this.getViewportHeight = function() { return this._canvas.height; }
///////////////////////////////////////////////////////////////////////
// accessors
///////////////////////////////////////////////////////////////////////
this.loadScene = function()
{
// parse the data
// the GL runtime must start with a "sceneData: "
var index = importStr.indexOf( "scenedata: " );
if (index >= 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();
this.linkLights();
}
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
if (this.light ) 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)]);
if (this.light2) 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<nMats; i++)
{
var mat = this._materials[i];
mat.update();
}
}
// defining the draw function to control how the scene is rendered
this.draw = function()
{
if (this._initialized)
{
g_Engine.setContext( this._canvas.rdgeid );
var ctx = g_Engine.getContext();
var renderer = ctx.renderer;
if (renderer.unloadedTextureCount <= 0)
{
renderer.disableCulling();
renderer._clear();
this.myScene.render();
if (this._firstRender)
{
if (this._canva
|