]> git.pond.sub.org Git - eow/blobdiff - static/dojo-release-1.1.1/dojox/gfx3d/scheduler.js
add Dojo 1.1.1
[eow] / static / dojo-release-1.1.1 / dojox / gfx3d / scheduler.js
diff --git a/static/dojo-release-1.1.1/dojox/gfx3d/scheduler.js b/static/dojo-release-1.1.1/dojox/gfx3d/scheduler.js
new file mode 100644 (file)
index 0000000..951970c
--- /dev/null
@@ -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.
+});
+
+}