]> git.pond.sub.org Git - eow/blob - 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
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");
6
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);
12                 });
13                 return buffer;
14         },
15
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);
22         },
23
24         // default implementation
25         order: function(it){
26                 return it.getZOrder();
27         },
28
29         outline: function(it){
30                 return it.getOutline();
31         }
32
33 });
34
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. 
40                 // 
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 )
45                 //
46                 // in this implementation, n is declared as normal, ,a is declared as orient.
47                 // 
48                 // obj: object: dojox.gfx3d.Object
49                 this.plus = null;
50                 this.minus = null;
51                 this.object = obj;
52
53                 var o = outline(obj);
54                 this.orient = o[0];
55                 this.normal = dojox.gfx3d.vector.normalize(o);
56         },
57
58         add: function(obj, outline){
59                 var epsilon = 0.5, o = outline(obj), v = dojox.gfx3d.vector, n = this.normal, a = this.orient;
60
61                 if(dojo.every(o, function(item){ return Math.floor(epsilon + v.dotProduct(n, v.substract(item, a))) <= 0; })){
62                         if(this.minus){
63                                 this.minus.add(obj, outline);
64                         } else {
65                                 this.minus = new dojox.gfx3d.scheduler.BinarySearchTree(obj, outline);
66                         }
67                 } else if(dojo.every(o, function(item){ return Math.floor(epsilon + v.dotProduct(n, v.substract(item, a))) >= 0; })){
68                         if(this.plus){
69                                 this.plus.add(obj, outline);
70                         } else {
71                                 this.plus = new dojox.gfx3d.scheduler.BinarySearchTree(obj, outline);
72                         }
73                 } else {
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";
76                 }
77         },
78
79         iterate: function(outline){
80                 var epsilon = 0.5;
81                 var v = dojox.gfx3d.vector;
82                 var sorted = [];
83                 var subs = null;
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];
88                 } else {
89                         subs = [this.minus, this.plus];
90                 }
91
92                 if(subs[0]){ 
93                         sorted = sorted.concat(subs[0].iterate());
94                 }
95                 sorted.push(this.object);
96                 if(subs[1]){ 
97                         sorted = sorted.concat(subs[1].iterate());
98                 }
99                 return sorted;
100         }
101
102 });
103
104 dojo.mixin(dojox.gfx3d.drawer, {
105         conservative: function(todos, objects, viewport){
106                 console.debug('conservative draw');
107                 dojo.forEach(this.objects, function(item){
108                         item.destroy();
109                 });
110                 dojo.forEach(objects, function(item){
111                         item.draw(viewport.lighting);
112                 });
113         },
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);
120                 });
121         }
122         // More aggrasive optimization may re-order the DOM nodes using the order 
123         // of objects, and only elements of todos call setShape.
124 });
125
126 }