summaryrefslogtreecommitdiff
path: root/js/dojo-1.7.2/dojox/gfx3d/scheduler.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/dojo-1.7.2/dojox/gfx3d/scheduler.js')
-rw-r--r--js/dojo-1.7.2/dojox/gfx3d/scheduler.js155
1 files changed, 155 insertions, 0 deletions
diff --git a/js/dojo-1.7.2/dojox/gfx3d/scheduler.js b/js/dojo-1.7.2/dojox/gfx3d/scheduler.js
new file mode 100644
index 0000000..1fda86f
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/gfx3d/scheduler.js
@@ -0,0 +1,155 @@
+//>>built
+define("dojox/gfx3d/scheduler", [
+ "dojo/_base/lang",
+ "dojo/_base/array", // dojo.forEach, dojo.every
+ "dojo/_base/declare", // dojo.declare
+ "./_base",
+ "./vector"
+], function(lang, arrayUtil, declare, gfx3d, vectorUtil){
+
+gfx3d.scheduler = {
+ zOrder: function(buffer, order){
+ order = order ? order : 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 : gfx3d.scheduler.outline;
+ var p = new gfx3d.scheduler.BinarySearchTree(buffer[0], outline);
+ arrayUtil.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();
+ }
+};
+
+var BST = 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 = vectorUtil.normalize(o);
+ },
+
+ add: function(obj, outline){
+ var epsilon = 0.5,
+ o = outline(obj),
+ v = vectorUtil,
+ n = this.normal,
+ a = this.orient,
+ BST = gfx3d.scheduler.BinarySearchTree;
+
+ if(
+ arrayUtil.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 BST(obj, outline);
+ }
+ }else if(
+ arrayUtil.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 BST(obj, outline);
+ }
+ }else{
+ /*
+ arrayUtil.forEach(o, function(item){
+ console.debug(v.dotProduct(n, v.substract(item, a)));
+ });
+ */
+ throw "The case: polygon cross siblings' plate is not implemented yet";
+ }
+ },
+
+ iterate: function(outline){
+ var epsilon = 0.5;
+ var v = vectorUtil;
+ 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;
+ }
+
+});
+
+gfx3d.drawer = {
+ conservative: function(todos, objects, viewport){
+ // console.debug('conservative draw');
+ arrayUtil.forEach(this.objects, function(item){
+ item.destroy();
+ });
+ arrayUtil.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');
+ arrayUtil.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.
+};
+
+var api = {
+ scheduler: gfx3d.scheduler,
+ drawer: gfx3d.drawer,
+ BinarySearchTree: BST
+};
+
+return api;
+}); \ No newline at end of file