Blame | Last modification | View Log | RSS feed
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 implementationorder: 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.Objectthis.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.});}