source: Dev/branches/rest-dojo-ui/client/dojox/gfx3d/scheduler.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 3.8 KB
Line 
1define([
2        "dojo/_base/lang",
3        "dojo/_base/array",     // dojo.forEach, dojo.every
4        "dojo/_base/declare",   // dojo.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: build the binary search tree, using binary space partition algorithm.
39                // The idea is for any polygon, for example, (a, b, c), the space is divided by
40                // the plane into two space: plus and minus.
41                //
42                // for any arbitary vertex p, if(p - a) dotProduct n = 0, p is inside the plane,
43                // > 0, p is in the plus space, vice versa for minus space.
44                // n is the normal vector that is perpendicular the plate, defined as:
45                //            n = ( b - a) crossProduct ( c - a )
46                //
47                // in this implementation, n is declared as normal, ,a is declared as orient.
48                //
49                // obj: object: 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 aggrasive 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.