/public/javascripts/dojo/dojox/gfx3d/scheduler.js

http://enginey.googlecode.com/ · JavaScript · 122 lines · 91 code · 13 blank · 18 comment · 12 complexity · 46b7d2bb771acf0eb2fe528066c055a6 MD5 · raw file

  1. dojo.provide("dojox.gfx3d.scheduler");
  2. dojo.provide("dojox.gfx3d.drawer");
  3. dojo.require("dojox.gfx3d.vector");
  4. dojo.mixin(dojox.gfx3d.scheduler, {
  5. zOrder: function(buffer, order){
  6. order = order ? order : dojox.gfx3d.scheduler.order;
  7. buffer.sort(function(a, b){
  8. return order(b) - order(a);
  9. });
  10. return buffer;
  11. },
  12. bsp: function(buffer, outline){
  13. console.debug("BSP scheduler");
  14. outline = outline ? outline : dojox.gfx3d.scheduler.outline;
  15. var p = new dojox.gfx3d.scheduler.BinarySearchTree(buffer[0], outline);
  16. dojo.forEach(buffer.slice(1), function(item){ p.add(item, outline); });
  17. return p.iterate(outline);
  18. },
  19. // default implementation
  20. order: function(it){
  21. return it.getZOrder();
  22. },
  23. outline: function(it){
  24. return it.getOutline();
  25. }
  26. });
  27. dojo.declare("dojox.gfx3d.scheduler.BinarySearchTree", null, {
  28. constructor: function(obj, outline){
  29. // summary: build the binary search tree, using binary space partition algorithm.
  30. // The idea is for any polygon, for example, (a, b, c), the space is divided by
  31. // the plane into two space: plus and minus.
  32. //
  33. // for any arbitary vertex p, if(p - a) dotProduct n = 0, p is inside the plane,
  34. // > 0, p is in the plus space, vice versa for minus space.
  35. // n is the normal vector that is perpendicular the plate, defined as:
  36. // n = ( b - a) crossProduct ( c - a )
  37. //
  38. // in this implementation, n is declared as normal, ,a is declared as orient.
  39. //
  40. // obj: object: dojox.gfx3d.Object
  41. this.plus = null;
  42. this.minus = null;
  43. this.object = obj;
  44. var o = outline(obj);
  45. this.orient = o[0];
  46. this.normal = dojox.gfx3d.vector.normalize(o);
  47. },
  48. add: function(obj, outline){
  49. var epsilon = 0.5, o = outline(obj), v = dojox.gfx3d.vector, n = this.normal, a = this.orient;
  50. if(dojo.every(o, function(item){ return Math.floor(epsilon + v.dotProduct(n, v.substract(item, a))) <= 0; })){
  51. if(this.minus){
  52. this.minus.add(obj, outline);
  53. } else {
  54. this.minus = new dojox.gfx3d.scheduler.BinarySearchTree(obj, outline);
  55. }
  56. } else if(dojo.every(o, function(item){ return Math.floor(epsilon + v.dotProduct(n, v.substract(item, a))) >= 0; })){
  57. if(this.plus){
  58. this.plus.add(obj, outline);
  59. } else {
  60. this.plus = new dojox.gfx3d.scheduler.BinarySearchTree(obj, outline);
  61. }
  62. } else {
  63. dojo.forEach(o, function(item){ console.debug(v.dotProduct(n, v.substract(item, a))); });
  64. throw "The case: polygon cross siblings' plate is not implemneted yet";
  65. }
  66. },
  67. iterate: function(outline){
  68. var epsilon = 0.5;
  69. var v = dojox.gfx3d.vector;
  70. var sorted = [];
  71. var subs = null;
  72. // FIXME: using Infinity here?
  73. var view = {x: 0, y: 0, z: -10000};
  74. if(Math.floor( epsilon + v.dotProduct(this.normal, v.substract(view, this.orient))) <= 0){
  75. subs = [this.plus, this.minus];
  76. } else {
  77. subs = [this.minus, this.plus];
  78. }
  79. if(subs[0]){
  80. sorted = sorted.concat(subs[0].iterate());
  81. }
  82. sorted.push(this.object);
  83. if(subs[1]){
  84. sorted = sorted.concat(subs[1].iterate());
  85. }
  86. return sorted;
  87. }
  88. });
  89. dojo.mixin(dojox.gfx3d.drawer, {
  90. conservative: function(todos, objects, viewport){
  91. console.debug('conservative draw');
  92. dojo.forEach(this.objects, function(item){
  93. item.destroy();
  94. });
  95. dojo.forEach(objects, function(item){
  96. item.draw(viewport.lighting);
  97. });
  98. },
  99. chart: function(todos, objects, viewport){
  100. // NOTE: ondemand may require the todos' objects to use setShape
  101. // to redraw themselves to maintain the z-order.
  102. console.debug('chart draw');
  103. dojo.forEach(this.todos, function(item){
  104. item.draw(viewport.lighting);
  105. });
  106. }
  107. // More aggrasive optimization may re-order the DOM nodes using the order
  108. // of objects, and only elements of todos call setShape.
  109. });