source: Dev/trunk/src/client/dojox/gfx3d/scheduler.js @ 529

Last change on this file since 529 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 3.8 KB
Line 
1define([
2        "dojo/_base/lang",
3        "dojo/_base/array",     // dojo.forEach, dojo.every
4        "dojo/_base/declare",   // declare
5        "./_base",
6        "./vector"
7], function(lang, arrayUtil, declare, gfx3d, vectorUtil){
8
9gfx3d.scheduler = {
10        zOrder: function(buffer, order){
11                order = order ? order : gfx3d.scheduler.order;
12                buffer.sort(function(a, b){
13                        return order(b) - order(a);
14                });
15                return buffer;
16        },
17
18        bsp: function(buffer, outline){
19                // console.debug("BSP scheduler");
20                outline = outline ? outline : gfx3d.scheduler.outline;
21                var p = new gfx3d.scheduler.BinarySearchTree(buffer[0], outline);
22                arrayUtil.forEach(buffer.slice(1), function(item){ p.add(item, outline); });
23                return p.iterate(outline);
24        },
25
26        // default implementation
27        order: function(it){
28                return it.getZOrder();
29        },
30
31        outline: function(it){
32                return it.getOutline();
33        }
34};
35
36var BST = declare("dojox.gfx3d.scheduler.BinarySearchTree", null, {
37        constructor: function(obj, outline){
38                // summary:
39                //              build the binary search tree, using binary space partition algorithm.
40                //              The idea is for any polygon, for example, (a, b, c), the space is divided by
41                //              the plane into two space: plus and minus.
42                //             
43                //              for any arbitrary vertex p, if(p - a) dotProduct n = 0, p is inside the plane,
44                //              > 0, p is in the plus space, vice versa for minus space.
45                //              n is the normal vector that is perpendicular the plate, defined as:
46                // |            n = ( b - a) crossProduct ( c - a )
47                //             
48                //              in this implementation, n is declared as normal, ,a is declared as orient.
49                // obj: dojox.gfx3d.Object
50                this.plus = null;
51                this.minus = null;
52                this.object = obj;
53
54                var o = outline(obj);
55                this.orient = o[0];
56                this.normal = vectorUtil.normalize(o);
57        },
58
59        add: function(obj, outline){
60                var epsilon = 0.5,
61                        o = outline(obj),
62                        v = vectorUtil,
63                        n = this.normal,
64                        a = this.orient,
65                        BST = gfx3d.scheduler.BinarySearchTree;
66
67                if(
68                        arrayUtil.every(o, function(item){
69                                return Math.floor(epsilon + v.dotProduct(n, v.substract(item, a))) <= 0;
70                        })
71                ){
72                        if(this.minus){
73                                this.minus.add(obj, outline);
74                        }else{
75                                this.minus = new BST(obj, outline);
76                        }
77                }else if(
78                        arrayUtil.every(o, function(item){
79                                return Math.floor(epsilon + v.dotProduct(n, v.substract(item, a))) >= 0;
80                        })
81                ){
82                        if(this.plus){
83                                this.plus.add(obj, outline);
84                        } else {
85                                this.plus = new BST(obj, outline);
86                        }
87                }else{
88                        /*
89                        arrayUtil.forEach(o, function(item){
90                                console.debug(v.dotProduct(n, v.substract(item, a)));
91                        });
92                        */
93                        throw "The case: polygon cross siblings' plate is not implemented yet";
94                }
95        },
96
97        iterate: function(outline){
98                var epsilon = 0.5;
99                var v = vectorUtil;
100                var sorted = [];
101                var subs = null;
102                // FIXME: using Infinity here?
103                var view = {x: 0, y: 0, z: -10000};
104                if(Math.floor( epsilon + v.dotProduct(this.normal, v.substract(view, this.orient))) <= 0){
105                        subs = [this.plus, this.minus];
106                }else{
107                        subs = [this.minus, this.plus];
108                }
109
110                if(subs[0]){
111                        sorted = sorted.concat(subs[0].iterate());
112                }
113
114                sorted.push(this.object);
115
116                if(subs[1]){
117                        sorted = sorted.concat(subs[1].iterate());
118                }
119                return sorted;
120        }
121
122});
123
124gfx3d.drawer = {
125        conservative: function(todos, objects, viewport){
126                // console.debug('conservative draw');
127                arrayUtil.forEach(this.objects, function(item){
128                        item.destroy();
129                });
130                arrayUtil.forEach(objects, function(item){
131                        item.draw(viewport.lighting);
132                });
133        },
134        chart: function(todos, objects, viewport){
135                // NOTE: ondemand may require the todos' objects to use setShape
136                // to redraw themselves to maintain the z-order.
137
138                // console.debug('chart draw');
139                arrayUtil.forEach(this.todos, function(item){
140                        item.draw(viewport.lighting);
141                });
142        }
143        // More aggressive optimization may re-order the DOM nodes using the order
144        // of objects, and only elements of todos call setShape.
145};
146
147var api = {
148        scheduler: gfx3d.scheduler,
149        drawer: gfx3d.drawer,
150        BinarySearchTree: BST
151};
152
153return api;
154});
Note: See TracBrowser for help on using the repository browser.