From b89a7ee8b956c96a1dcee995ea840feddc5d4b27 Mon Sep 17 00:00:00 2001 From: Pierre Frisch Date: Thu, 22 Dec 2011 07:25:50 -0800 Subject: First commit of Ninja to ninja-internal Signed-off-by: Valerio Virgillito --- .../RDGE/src/core/script/util/dbgpanel.js | 237 +++++++++++++++ .../RDGE/src/core/script/util/fpsTracker.js | 51 ++++ .../RDGE/src/core/script/util/statTracker.js | 338 +++++++++++++++++++++ 3 files changed, 626 insertions(+) create mode 100644 js/helper-classes/RDGE/src/core/script/util/dbgpanel.js create mode 100644 js/helper-classes/RDGE/src/core/script/util/fpsTracker.js create mode 100644 js/helper-classes/RDGE/src/core/script/util/statTracker.js (limited to 'js/helper-classes/RDGE/src/core/script/util') diff --git a/js/helper-classes/RDGE/src/core/script/util/dbgpanel.js b/js/helper-classes/RDGE/src/core/script/util/dbgpanel.js new file mode 100644 index 00000000..f5b9d76d --- /dev/null +++ b/js/helper-classes/RDGE/src/core/script/util/dbgpanel.js @@ -0,0 +1,237 @@ +/* +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 g_dbgPanel = null; + +/** + * Implements an easy to use debugging panel. + * @param id - element id of a
to convert into a debug panel + * @param title - header title for the panel + */ +function utilDbgPanel(id, title) +{ + this.id = id; + this.root = '#' + id; + this.accordion = this.root + ' .dbgpanel-accordion'; + this.categories = {}; + this.counter = 0; + + $(this.root).addClass('dbgpanel-outer ui-widget-content'); + $(this.root).draggable({handle: this.root, containment: 'body'}); + $(this.root).resizable({minWidth: $(this.root).width(), minHeight: $(this.root).height()}); + + $(this.root).append('

' + title + '

'); + $(this.root).append('
'); + $(this.accordion).accordion({clearStyle: true}); +} + +/** + * Adds a label to the debug panel. + * @param category - category to which to append a label + */ +utilDbgPanel.prototype.appendLabel = function(category, label) +{ + var cat = this.getCategorySelector(category); + $(cat).append('

' + label + '

'); +} + +/** + * Adds a toggle button to the debug panel. + * @param category - category to which to append a toggle + * @param value - current value of the boolean + * @param label - button label + * @param onChange - function that receives an updated value upon a change + */ +utilDbgPanel.prototype.appendBoolean = function(category, value, label, onChange) +{ + var cat = this.getCategorySelector(category); + + var button = this.getUniqueID(); + $(cat).append('
'); + + $('#'+button).prop('checked', (value || (value != 0.0))); + $('#'+button).button({label: label}); + $('#'+button).change(function(e) { + if (e.target.checked) + value = (typeof value == "number") ? 1.0 : true; + else + value = (typeof value == "number") ? 0.0 : false; + + if(onChange) + onChange(value); + }); +} + +/** + * Adds a slider to the debug panel. + * @param category - category to which to append a slider + * @param value - current value of the number + * @param rangeMin - minimum permitted value + * @param rangeMax - maximum permitted value + * @param stepSize - granularity of allowable values + * @param onChange - function that receives an updated value upon a change + */ +utilDbgPanel.prototype.appendNumber = function(category, value, rangeMin, rangeMax, stepSize, onChange) +{ + var cat = this.getCategorySelector(category); + + var slider = this.getUniqueID(); + $(cat).append('
'); + + $('#'+slider).slider({ + min: rangeMin, max: rangeMax, + value: value, + step: stepSize, + slide: function(event, ui) { + value = ui.value; + if(onChange) + onChange(value); + }, + change: function(event, ui) { + value = ui.value; + if(onChange) + onChange(value); + } + }); +} + + +/** + * Returns a unique id that can be used with child elements of this debug panel. + */ +utilDbgPanel.prototype.getUniqueID = function() +{ + return this.id + '_' + this.counter++; +} + +/** + * Queries the jquery selector corresponding to the passed accordion category. + * @param category - category div for which to return a selector + */ +utilDbgPanel.prototype.getCategorySelector = function(category) +{ + var selector = this.categories[category]; + + if (selector == undefined) + { + // Generate a selector for this category + selector = this.getUniqueID(); + + // Add a new div to the accordion ui + $(this.accordion).accordion("destroy"); + $(this.accordion).append('

' + category + + '

'); + $(this.accordion).accordion({clearStyle: true}); + + // Store the selector + selector = '#' + selector; + this.categories[category] = selector; + } + + return selector; +} + +////////////////////////////////// +g_sg=null; +g_wireframe=false; +g_initializedDbgPanel=false; +g_showScene=true; +g_showBloom=true; +enableNormalMapping=true; +g_bloomIntensity1=0.7; +g_bloomIntensity2=0.5; +g_bloomIntensity3=1.0; +g_bloomIntensity4=0.2; +g_mainLight=null; +g_shadowLigthSize=7.93; +g_shadowColor=[1.0 - 0.922, 1.0 - 0.7373, 1.0 - 0.4824, 0.5]; +g_depthMapGenShader=null; +g_showSSAO=true; +g_enableShadowMapping=true; +g_sampleRadius=0.36; +g_intensity=0.75; +g_distScale=0.60; +g_bias=0.05; +g_animationRate=1.0; +////////////////////////////////// + +utilDbgPanel.prototype.enableFXDebug = function( ) +{ + this.appendBoolean("General",g_showScene,"Enable scene render",function(val) { g_showScene=val; }); + this.appendBoolean("General",g_wireframe,"Enable wireframe",function(val) { g_wireframe=val; }); + this.appendBoolean("General",true,"Enable frustum culling",function(val) { g_sg.frustumCulling=val; }); + this.appendBoolean("General",enableNormalMapping,"Enable normal mapping",function(val) { enableNormalMapping=val; }); + + + this.appendBoolean("Shadows",g_enableShadowMapping,"Enable shadow mapping",function(val) { var scene = g_Engine.getContext().getScene(); + scene.renderGraph.shadowDepthMap.visibility = (!val ? 0 : 1); + var scene = g_Engine.getContext().getScene(); + scene.renderGraph.finalPass.shader.screenQuad.u_shadowMap.set("assets/images/white"); + scene.renderGraph.finalPass.textures[2].enabled = val; + }); + this.appendLabel("Shadows","Light Size"); + this.appendNumber("Shadows",g_shadowLigthSize, 1.0, 32.0, 0.01, function(val) { var scene = g_Engine.getContext().getScene(); + scene.renderGraph.shadowMap.shader.shadowMap.u_lightSize.set([val]);}); + + this.appendLabel("Shadows","Color-R"); + this.appendNumber("Shadows",g_shadowColor[0], 0.0, 1.0, 0.001, function(val) { var scene = g_Engine.getContext().getScene(); + g_shadowColor[0] = 1.0 - val; + scene.renderGraph.shadowMap.shader.shadowMap.u_shadowColor.set(g_shadowColor);}); + this.appendLabel("Shadows","Color-G"); + this.appendNumber("Shadows",g_shadowColor[1], 0.0, 1.0, 0.001, function(val) { var scene = g_Engine.getContext().getScene(); + g_shadowColor[1] = 1.0 - val; + scene.renderGraph.shadowMap.shader.shadowMap.u_shadowColor.set(g_shadowColor);}); + this.appendLabel("Shadows","Color-B"); + this.appendNumber("Shadows",g_shadowColor[2], 0.0, 1.0, 0.001, function(val) { var scene = g_Engine.getContext().getScene(); + g_shadowColor[2] = 1.0 - val; + scene.renderGraph.shadowMap.shader.shadowMap.u_shadowColor.set(g_shadowColor);}); + this.appendLabel("Shadows","Color-A"); + this.appendNumber("Shadows",g_shadowColor[3], 0.0, 1.0, 0.001, function(val) { var scene = g_Engine.getContext().getScene(); + g_shadowColor[3] = val; + scene.renderGraph.shadowMap.shader.shadowMap.u_shadowColor.set(g_shadowColor);}); + + + this.appendLabel("Animation","Rate"); + this.appendNumber("Animation",g_animationRate,-4.0,4.0,0.1,function(val) { g_animationRate=val; }); + + this.appendBoolean("Bloom",g_showBloom,"Enable bloom",function(val) { var scene = g_Engine.getContext().getScene(); + scene.renderGraph.glowMap.visibility = (!val ? 0 : 1); + var scene = g_Engine.getContext().getScene(); + scene.renderGraph.finalPass.shader.screenQuad.u_glowFinal.set("assets/images/black"); + scene.renderGraph.finalPass.textures[0].enabled = val; + }); + this.appendLabel("Bloom","1024x1024 mip weight"); + this.appendNumber("Bloom",g_bloomIntensity1,0.0,1.5,0.01,function(val) { var scene = g_Engine.getContext().getScene(); + scene.renderGraph.blurFull.shader.gaussianBlur.u_weight.set([val]);}); + this.appendLabel("Bloom","256x256 mip weight"); + this.appendNumber("Bloom",g_bloomIntensity2,0.0,1.5,0.01,function(val) { var scene = g_Engine.getContext().getScene(); + scene.renderGraph.blurQuater.shader.gaussianBlur.u_weight.set([val]);}); + this.appendLabel("Bloom","128x128 mip weight"); + this.appendNumber("Bloom",g_bloomIntensity3,0.0,1.5,0.01,function(val) { var scene = g_Engine.getContext().getScene(); + scene.renderGraph.blurThreeQuater.shader.gaussianBlur.u_weight.set([val]);}); +// this.appendLabel("Bloom","64x64 mip weight"); +// this.appendNumber("Bloom",g_bloomIntensity4,0.0,1.5,0.01,function(val) { g_bloomIntensity4=val; }); + + this.appendBoolean("Ambient Occlusion",g_showSSAO,"Enable SSAO",function(val) { var scene = g_Engine.getContext().getScene(); + scene.renderGraph.depth_map.visibility = (!val ? 0 : 1); + var scene = g_Engine.getContext().getScene(); + scene.renderGraph.finalPass.shader.screenQuad.u_ssaoRT.set("assets/images/black"); + scene.renderGraph.finalPass.textures[1].enabled = val; + }); + this.appendLabel("Ambient Occlusion","Sampling radius"); + this.appendNumber("Ambient Occlusion",g_sampleRadius,0.0,5.0,0.0001,function(val) + { var scene = g_Engine.getContext().getScene(); + scene.renderGraph.SSAO.shader.ssao.u_artVals.data[0] = val;}) + this.appendLabel("Ambient Occlusion","Intensity"); + this.appendNumber("Ambient Occlusion",g_intensity,0.0,3.0,0.0001,function(val) { var scene = g_Engine.getContext().getScene(); + scene.renderGraph.SSAO.shader.ssao.u_artVals.data[1] = val;}); + this.appendLabel("Ambient Occlusion","Distance scaling"); + this.appendNumber("Ambient Occlusion",g_distScale,0.0,2.0,0.0001,function(val) { var scene = g_Engine.getContext().getScene(); + scene.renderGraph.SSAO.shader.ssao.u_artVals.data[2] = val;}); + this.appendLabel("Ambient Occlusion","Bias"); + this.appendNumber("Ambient Occlusion",g_bias,0.0,0.5,0.0001,function(val) { var scene = g_Engine.getContext().getScene(); + scene.renderGraph.SSAO.shader.ssao.u_artVals.data[3] = val;}); +} diff --git a/js/helper-classes/RDGE/src/core/script/util/fpsTracker.js b/js/helper-classes/RDGE/src/core/script/util/fpsTracker.js new file mode 100644 index 00000000..0b6cdd84 --- /dev/null +++ b/js/helper-classes/RDGE/src/core/script/util/fpsTracker.js @@ -0,0 +1,51 @@ +/* +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. +
*/ + +fpsTracker = function (id) { + this.id = id; + this.fpsRaw = new stat(id + "_fps", "raw", 0, null, false); + this.fpsAvg = new stat(id + "_fps", "avg", 0, null, false); + this.fpsMin = new stat(id + "_fps", "min", 0, null, false); + this.fpsMax = new stat(id + "_fps", "max", 0, null, false); + this.samples = []; + this.maxSamples = 10; + this.timeStampMS = 0.0; + this.reportInterval = 500; + + this.close = function() { + stat.pages[id + "_fps"] = null; + } + + this.sample = function() { + var currMS = new Date().getTime(); + this.samples.push(currMS - this.timeStampMS); + if (this.samples.length > this.maxSamples) { + this.samples.shift(); + } + this.timeStampMS = currMS; + var accum = 0.0; + var fmin = -1e10; + var fmax = 1e10; + var i = this.samples.length - 1; + while (i >= 0) { + accum += this.samples[i]; + fmin = Math.max(fmin, this.samples[i]); + fmax = Math.min(fmax, this.samples[i]); + i--; + } + var denom = this.samples.length > 0 ? accum / this.samples.length : 0; + var avgFPS = denom > 0 ? 1000 / denom : 0; + var minFPS = fmin > 0 ? 1000 / fmin : 0; + var maxFPS = fmax > 0 ? 1000 / fmax : 0; + var lastSample = this.samples[this.samples.length - 1]; + var rawFPS = (lastSample > 0) ? 1000 / lastSample : 0; + + this.fpsRaw.value = rawFPS.toFixed(2); + this.fpsAvg.value = avgFPS.toFixed(2); + this.fpsMin.value = minFPS.toFixed(2); + this.fpsMax.value = maxFPS.toFixed(2); + } +} \ No newline at end of file diff --git a/js/helper-classes/RDGE/src/core/script/util/statTracker.js b/js/helper-classes/RDGE/src/core/script/util/statTracker.js new file mode 100644 index 00000000..ea08e737 --- /dev/null +++ b/js/helper-classes/RDGE/src/core/script/util/statTracker.js @@ -0,0 +1,338 @@ +/* +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 stat = (function() { + pages = {}; + dlgId = ""; + + self = function(cat, name, value, func, reset) { + if (reset == undefined) { + reset = true; + } + category = (!cat) ? 'default' : cat; + if (!pages[category]) { + pages[category] = []; + } + pages[category].push(this); + this.name = name; + this.defValue = value; + this.value = value; + this.func = func; + this.reset = reset; + this.reportInterval = 500; + + stat.dirty = true; + stat.find = function(cat, name) { + var stats = pages[cat]; + for (i = 0; i < stats.length; ++i) { + if (stats[i].name == name) { + return stats[i]; + } + } + return null; + } + stat.closePage = function(id) { + pages[id] = null; + stat.dirty = true; + } + stat.reportAll = function(id) { + if (stat.dirty == true) { + var e = document.getElementById(id); + if (!e) { + return; + } + var str = "
"; + str += "
    "; + for (cat in pages) { + if (!pages[cat]) + continue; + str += "
  • " + cat + "
  • "; + } + str += "
"; + for (cat in pages) { + if (!pages[cat]) + continue; + str += "
"; + str += "
"; + } + str += "
"; + + e.innerHTML = str; + $("#stat_tabs").tabs(); + stat.dirty = false; + } + + for (cat in pages) { + var c = document.getElementById(cat); + stat.report(c, cat, id); + } + } + + stat.report = function(e, cat, id) { + if (!cat) { + cat = 'default'; + } + var stats = pages[cat]; + if (!stats) { + return; + } + outputHTML = ""; + var n = 0; + for (i = 0; i < stats.length; ++i) { + outputHTML += ""; + if (n++ >= 3) { + outputHTML += ""; + n = 0; + } + if (stats[i].reset) { + stats[i].value = stats[i].defValue; + } + } + outputHTML += "
"; + + if (stats[i].func) { + outputHTML += stats[i].name + " : " + stats[i].func(stats[i].value); + } else { + outputHTML += stats[i].name + " : " + stats[i].value; + } + outputHTML += "
"; + + e.innerHTML = outputHTML; + } + } + var fr = function() { self.reportAll("RDGE_STATS"); }; + setInterval(fr, 500); + return self; +} +)(); + +dbCanvas = function(width, height) { + this.front = document.createElement('canvas'); + this.front.setAttribute("width", width); + this.front.setAttribute("height", height); + 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", width); + this.back.setAttribute("height", height); + this.front.setAttribute("style", "position:absolute; margin: 0.0em; padding: 0.0em;"); + this.back.ctx = this.back.getContext("2d"); + this.swap = function() { + var tmp = this.front; + this.front = this.back; + this.back = tmp; + + this.front.style.visibility='visible'; + this.back.style.visibility='hidden'; + } +} + +function getCanvasDimensions(canvas) { + var canvas = canvas; + var dim = {}; + dim.x = 0.0; + dim.y = 0.0; + dim.width = canvas.width; + dim.height = canvas.height; + + var obj = canvas; + if ( obj.offsetParent ) { + do { + dim.x += obj.offsetLeft; + dim.y += obj.offsetTop; + } while (obj = obj.offsetParent); + } + return dim; +} + +graph2D = function(title, id, w, h, minRng, maxRng, style) { + this.style = style || { 'bgcolor' : "#000" }; + this.sampleRes = 512; + this.scale = 1.0; + this.rangeMin = minRng; + this.rangeMax = maxRng; + this.offsetY = 0.0; + this.canvas = document.createElement('canvas'); + this.canvas.setAttribute("width", w); + this.canvas.setAttribute("height", h-32); + this.canvas.setAttribute("style", "position:absolute; margin: 0.0em; padding: 0.0em;"); + self = this; + this.onclick = function(e) { + var dim = getCanvasDimensions(self.canvas); + var mx = e.clientX - dim.x; + var my = e.clientY - dim.y; + for( var i = 0; i < self.tracked.length; ++i) { + var cb = self.tracked[i].checkbox; + var l = cb.x; + var r = cb.x + cb.w; + var t = cb.y; + var b = cb.y + cb.h; + if( mx < l ) + continue; + if( mx > r ) + continue; + if( my > b ) + continue; + if( my < t ) + continue; + self.tracked[i].hide = !self.tracked[i].hide; + break; + } + } + this.canvas.onclick = this.onclick; + this.ctx = this.canvas.getContext("2d"); + + this.tracked = []; + this.addStat = function(label, stat, color, hidden) { + this.tracked.push({ 'label': label, 'stat': stat, 'color' : color, 'samples' : [], 'hide' : hidden, 'checkbox' : { 'x':0, 'y':0, 'w':12, 'h':12 } }); + } + + this.markers = []; + this.addMarker = function(label, v, color) { + if( ( v.slice ) && ( typeof v.slice === 'function' ) ) { + for( i = 0; i < v.length; ++i ) { + this.markers.push({ 'label' : label + i, 'value' : v[i], 'color' : color }); + } + } else if( typeof v === 'object' ) { + var rng = v.max - v.min; + var count = rng / v.interval; + var step = v.interval; + for( i = 0; i <= count; ++i ) { + this.markers.push({ 'label' : label + i, 'value' : ( i * step ) - v.min, 'color' : color }); + } + } else { + this.markers.push({ 'label' : label, 'value' : v, 'color' : color }); + } + } + + this.update = function() { + for( var i = 0; i < this.tracked.length; ++i) { + var t = this.tracked[i]; + + // sample + if(t.samples.length > this.sampleRes) { + t.samples.shift(); + } + t.samples.push(t.stat.value); + } + } + + this.draw = function() { + var cvs = this.canvas; + var ctx = this.ctx; + var w = cvs.width; + var h = cvs.height; + var minR = this.rangeMin * this.scale; + var maxR = this.rangeMax * this.scale; + var denom = 1.0 / ( maxR - minR ); + var numCols = 4; + var numRows = Math.floor( this.tracked.length / numCols + 0.5 ); + + var footerHeight = 16.0 + numRows * 16.0; + var offsetY = footerHeight; + + + ctx.fillStyle = this.style.bgcolor; + ctx.strokeStyle = this.style.bgcolor; + ctx.fillRect (0, 0, w, h-footerHeight); + + // draw marker lines + for( var i = 0; i < this.markers.length; ++i) { + var m = this.markers[i]; + + ctx.fillStyle = m.color; + ctx.strokeStyle = m.color; + + var y = h - ( offsetY + ( m.value - minR ) * denom * h ); + var dim = ctx.measureText(m.value); + + ctx.lineWidth = 1.0; + ctx.beginPath(); + ctx.moveTo(0, Math.round( y )); + ctx.lineTo(w, Math.round( y )); + ctx.stroke(); + ctx.closePath(); + } + + ctx.lineWidth = 1.0; + for( var i = 0; i < this.tracked.length; ++i) { + var t = this.tracked[i]; + + // don't draw it. + if(t.hide) + continue; + + var ratio = w / this.sampleRes; + + ctx.fillStyle = t.color; + ctx.beginPath(); + + var y = (t.samples[0] - minR)*denom*h; + ctx.moveTo(0, h - (offsetY + y)); + for (var x = 1; x < t.samples.length; x++) { + y = (t.samples[x] - minR)*denom*h; + ctx.lineTo(x * ratio, h - (offsetY + y)); + } + + ctx.strokeStyle = t.color; + ctx.stroke(); + ctx.closePath(); + } + + // draw marker text + var alpha = 0.25; + ctx.globalAlpha = alpha; + var r = w * 0.125 / this.scale; + ctx.fillStyle = "#044"; + + ctx.fillRect(w-r, 0, r, h); + for( var i = 0; i < this.markers.length; ++i) { + var m = this.markers[i]; + ctx.fillStyle = m.color; + ctx.strokeStyle = m.color; + var y = h - ( offsetY + ( m.value - minR ) * denom * h ); + ctx.font = Math.round( 10 / this.scale ) + "pt courier"; + var dim = ctx.measureText(m.value); + ctx.globalAlpha = 1.0; + ctx.fillText(m.value, w - dim.width - 5, y - 2, r); + ctx.globalAlpha = alpha; + } + + ctx.globalAlpha = 1.0; + ctx.lineWidth = 1.0; + ctx.fillStyle = "#0A0A0A"; + ctx.strokeStyle = "#8F8F8F"; + ctx.fillRect(0, h-footerHeight, w, footerHeight); + ctx.translate([0.5,0.5]); + var offset = w/numCols; + var xmargin = 16; + var ymargin = h-footerHeight+16;// + numRows * 16.0; + for( var i = 0; i < this.tracked.length; ++i) { + var t = this.tracked[i]; + ctx.font = "6pt Arial"; + ctx.fillStyle = t.color; + ctx.strokeStyle = t.color; + var index = (i+numCols)%numCols; + var row = Math.floor(i/numCols); + var ox = Math.floor(xmargin + offset * index); + var oy = Math.floor(ymargin + row * 16.0); + // update/render checkbox + t.checkbox.x = Math.floor( ox-t.checkbox.w/2 ); + t.checkbox.y = Math.floor( oy-t.checkbox.h/2 ); + if( t.hide ) { + ctx.strokeRect(t.checkbox.x, t.checkbox.y, t.checkbox.w, t.checkbox.h); + } else { + ctx.fillRect(t.checkbox.x, t.checkbox.y, t.checkbox.w, t.checkbox.h); + } + ctx.fillText(t.label, ox + 10, oy+4); + } + ctx.translate([-0.5,-0.5]); + } + + var self = this; + setInterval(function() { self.update(); self.draw(); }, 16); +} \ No newline at end of file -- cgit v1.2.3