scheduler.js 4.1 KB

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