diff options
Diffstat (limited to 'includes/js/dojox/gfx3d/scheduler.js')
-rw-r--r-- | includes/js/dojox/gfx3d/scheduler.js | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/includes/js/dojox/gfx3d/scheduler.js b/includes/js/dojox/gfx3d/scheduler.js new file mode 100644 index 0000000..951970c --- /dev/null +++ b/includes/js/dojox/gfx3d/scheduler.js @@ -0,0 +1,126 @@ +if(!dojo._hasResource["dojox.gfx3d.scheduler"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.gfx3d.scheduler"] = true; +dojo.provide("dojox.gfx3d.scheduler"); +dojo.provide("dojox.gfx3d.drawer"); +dojo.require("dojox.gfx3d.vector"); + +dojo.mixin(dojox.gfx3d.scheduler, { + zOrder: function(buffer, order){ + order = order ? order : dojox.gfx3d.scheduler.order; + buffer.sort(function(a, b){ + return order(b) - order(a); + }); + return buffer; + }, + + bsp: function(buffer, outline){ + console.debug("BSP scheduler"); + outline = outline ? outline : dojox.gfx3d.scheduler.outline; + var p = new dojox.gfx3d.scheduler.BinarySearchTree(buffer[0], outline); + dojo.forEach(buffer.slice(1), function(item){ p.add(item, outline); }); + return p.iterate(outline); + }, + + // default implementation + order: function(it){ + return it.getZOrder(); + }, + + outline: function(it){ + return it.getOutline(); + } + +}); + +dojo.declare("dojox.gfx3d.scheduler.BinarySearchTree", null, { + constructor: function(obj, outline){ + // summary: build the binary search tree, using binary space partition algorithm. + // The idea is for any polygon, for example, (a, b, c), the space is divided by + // the plane into two space: plus and minus. + // + // for any arbitary vertex p, if(p - a) dotProduct n = 0, p is inside the plane, + // > 0, p is in the plus space, vice versa for minus space. + // n is the normal vector that is perpendicular the plate, defined as: + // n = ( b - a) crossProduct ( c - a ) + // + // in this implementation, n is declared as normal, ,a is declared as orient. + // + // obj: object: dojox.gfx3d.Object + this.plus = null; + this.minus = null; + this.object = obj; + + var o = outline(obj); + this.orient = o[0]; + this.normal = dojox.gfx3d.vector.normalize(o); + }, + + add: function(obj, outline){ + var epsilon = 0.5, o = outline(obj), v = dojox.gfx3d.vector, n = this.normal, a = this.orient; + + if(dojo.every(o, function(item){ return Math.floor(epsilon + v.dotProduct(n, v.substract(item, a))) <= 0; })){ + if(this.minus){ + this.minus.add(obj, outline); + } else { + this.minus = new dojox.gfx3d.scheduler.BinarySearchTree(obj, outline); + } + } else if(dojo.every(o, function(item){ return Math.floor(epsilon + v.dotProduct(n, v.substract(item, a))) >= 0; })){ + if(this.plus){ + this.plus.add(obj, outline); + } else { + this.plus = new dojox.gfx3d.scheduler.BinarySearchTree(obj, outline); + } + } else { + dojo.forEach(o, function(item){ console.debug(v.dotProduct(n, v.substract(item, a))); }); + throw "The case: polygon cross siblings' plate is not implemneted yet"; + } + }, + + iterate: function(outline){ + var epsilon = 0.5; + var v = dojox.gfx3d.vector; + var sorted = []; + var subs = null; + // FIXME: using Infinity here? + var view = {x: 0, y: 0, z: -10000}; + if(Math.floor( epsilon + v.dotProduct(this.normal, v.substract(view, this.orient))) <= 0){ + subs = [this.plus, this.minus]; + } else { + subs = [this.minus, this.plus]; + } + + if(subs[0]){ + sorted = sorted.concat(subs[0].iterate()); + } + sorted.push(this.object); + if(subs[1]){ + sorted = sorted.concat(subs[1].iterate()); + } + return sorted; + } + +}); + +dojo.mixin(dojox.gfx3d.drawer, { + conservative: function(todos, objects, viewport){ + console.debug('conservative draw'); + dojo.forEach(this.objects, function(item){ + item.destroy(); + }); + dojo.forEach(objects, function(item){ + item.draw(viewport.lighting); + }); + }, + chart: function(todos, objects, viewport){ + // NOTE: ondemand may require the todos' objects to use setShape + // to redraw themselves to maintain the z-order. + console.debug('chart draw'); + dojo.forEach(this.todos, function(item){ + item.draw(viewport.lighting); + }); + } + // More aggrasive optimization may re-order the DOM nodes using the order + // of objects, and only elements of todos call setShape. +}); + +} |