1 if(!dojo._hasResource["dojox.gfx3d.scheduler"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2 dojo._hasResource["dojox.gfx3d.scheduler"] = true;
3 dojo.provide("dojox.gfx3d.scheduler");
4 dojo.provide("dojox.gfx3d.drawer");
5 dojo.require("dojox.gfx3d.vector");
7 dojo.mixin(dojox.gfx3d.scheduler, {
8 zOrder: function(buffer, order){
9 order = order ? order : dojox.gfx3d.scheduler.order;
10 buffer.sort(function(a, b){
11 return order(b) - order(a);
16 bsp: function(buffer, outline){
17 console.debug("BSP scheduler");
18 outline = outline ? outline : dojox.gfx3d.scheduler.outline;
19 var p = new dojox.gfx3d.scheduler.BinarySearchTree(buffer[0], outline);
20 dojo.forEach(buffer.slice(1), function(item){ p.add(item, outline); });
21 return p.iterate(outline);
24 // default implementation
26 return it.getZOrder();
29 outline: function(it){
30 return it.getOutline();
35 dojo.declare("dojox.gfx3d.scheduler.BinarySearchTree", null, {
36 constructor: function(obj, outline){
37 // summary: build the binary search tree, using binary space partition algorithm.
38 // The idea is for any polygon, for example, (a, b, c), the space is divided by
39 // the plane into two space: plus and minus.
41 // for any arbitary vertex p, if(p - a) dotProduct n = 0, p is inside the plane,
42 // > 0, p is in the plus space, vice versa for minus space.
43 // n is the normal vector that is perpendicular the plate, defined as:
44 // n = ( b - a) crossProduct ( c - a )
46 // in this implementation, n is declared as normal, ,a is declared as orient.
48 // obj: object: dojox.gfx3d.Object
55 this.normal = dojox.gfx3d.vector.normalize(o);
58 add: function(obj, outline){
59 var epsilon = 0.5, o = outline(obj), v = dojox.gfx3d.vector, n = this.normal, a = this.orient;
61 if(dojo.every(o, function(item){ return Math.floor(epsilon + v.dotProduct(n, v.substract(item, a))) <= 0; })){
63 this.minus.add(obj, outline);
65 this.minus = new dojox.gfx3d.scheduler.BinarySearchTree(obj, outline);
67 } else if(dojo.every(o, function(item){ return Math.floor(epsilon + v.dotProduct(n, v.substract(item, a))) >= 0; })){
69 this.plus.add(obj, outline);
71 this.plus = new dojox.gfx3d.scheduler.BinarySearchTree(obj, outline);
74 dojo.forEach(o, function(item){ console.debug(v.dotProduct(n, v.substract(item, a))); });
75 throw "The case: polygon cross siblings' plate is not implemneted yet";
79 iterate: function(outline){
81 var v = dojox.gfx3d.vector;
84 // FIXME: using Infinity here?
85 var view = {x: 0, y: 0, z: -10000};
86 if(Math.floor( epsilon + v.dotProduct(this.normal, v.substract(view, this.orient))) <= 0){
87 subs = [this.plus, this.minus];
89 subs = [this.minus, this.plus];
93 sorted = sorted.concat(subs[0].iterate());
95 sorted.push(this.object);
97 sorted = sorted.concat(subs[1].iterate());
104 dojo.mixin(dojox.gfx3d.drawer, {
105 conservative: function(todos, objects, viewport){
106 console.debug('conservative draw');
107 dojo.forEach(this.objects, function(item){
110 dojo.forEach(objects, function(item){
111 item.draw(viewport.lighting);
114 chart: function(todos, objects, viewport){
115 // NOTE: ondemand may require the todos' objects to use setShape
116 // to redraw themselves to maintain the z-order.
117 console.debug('chart draw');
118 dojo.forEach(this.todos, function(item){
119 item.draw(viewport.lighting);
122 // More aggrasive optimization may re-order the DOM nodes using the order
123 // of objects, and only elements of todos call setShape.