TileTree.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. import * as THREE from "../../../../libs/three.js/build/three.module.js";
  2. function Node(e, t) {
  3. this.tree = e, //所属树(TileTree)
  4. this.parent = t,
  5. this.children = [],
  6. this.id = ++u;
  7. }
  8. function o(e, t, i, r, a, s, l, h) {
  9. if (e) {
  10. l = l || TileTree.TraversalType.PreOrder;
  11. var u = r * c + i;
  12. if (l === TileTree.TraversalType.PreOrder && (a && a(e, t, u, i, r),
  13. s && s.push(e)),
  14. e.children && 0 !== e.children.length) {
  15. for (var d = r * c, p = i * c, f = 0; f < c; f++)
  16. for (var g = 0; g < c; g++)
  17. o(e.children[g * c + f], t + 1, p + f, d + g, a, s, l, h);
  18. l === TileTree.TraversalType.PostOrder && (a && a(e, t, u, i, r),
  19. s && s.push(e))
  20. }
  21. }
  22. }
  23. function Plant(seed) {
  24. seed.root = Branch(seed, null, 0)
  25. }
  26. function Branch(seed, parent, level) {
  27. if (level > seed.levels)
  28. return null;
  29. var node = new Node(seed, parent);
  30. seed.allNodes.push(node);
  31. for (var o = 0; o < h; o++)
  32. node.children[o] = Branch(seed, node, level + 1);
  33. return node
  34. }
  35. function l(parent, t, level, n, r) {
  36. if (!parent)
  37. return null;
  38. if (0 === level)
  39. return parent;
  40. if (!parent.children || 0 === parent.children.length)
  41. return null;
  42. var o = Math.pow(c, level),
  43. a = o / c,
  44. s = n % a,
  45. h = r % a,
  46. u = Math.floor(r / a),
  47. d = Math.floor(n / a),
  48. p = u * c + d,
  49. f = parent.children[p];
  50. return l(f, t + 1, level - 1, s, h)
  51. }
  52. /* cube每个面都有一个分层树 用于代表瓦片图的细分?
  53. 树4096的分为三层,每层有4个子节点。(最后一层的四个子节点都是null)
  54. */
  55. var c = 2,
  56. h = c * c; //4个子节点
  57. var u = 0;
  58. export default class TileTree {
  59. constructor(e, t) {
  60. this.levels = t,
  61. this.tileSize = e,
  62. this.root = null,
  63. this.allNodes = [],
  64. Plant(this);
  65. }
  66. getSubNode(e, t, i) {
  67. (!t || e < this.tileSize) && (t = 0),
  68. (!i || e < this.tileSize) && (i = 0),
  69. e < this.tileSize && (e = this.tileSize);
  70. var level = TileTree.getLevelCountForSize(this.tileSize, e),
  71. o = l(this.root, 0, level, t, i);
  72. return o
  73. }
  74. breadthFirst(e) {//广度优先搜索
  75. e = e || {};
  76. var t = !!e.nullLevelEnd,
  77. i = e.maxLevel,
  78. n = e.minLevel,
  79. r = e.callback,
  80. o = e.saveVisited,
  81. a = [],
  82. s = {},
  83. l = 0,
  84. c = 0;
  85. for (a.push(this.root),
  86. a.push(s); a.length > 0 && !(i && l > i);) {
  87. var h = a.shift();
  88. if (h === s)
  89. (!n || l >= n) && (r && t && r(null),
  90. o && t && o.push(null)),
  91. a.length > 0 && a.push(s),
  92. l++,
  93. c = 0;
  94. else {
  95. if (h.children)
  96. for (var u = 0; u < h.children.length; u++) {
  97. var d = h.children[u];
  98. d && a.push(h.children[u])
  99. }
  100. var p = this.getFaceIndexFromNode(h);
  101. (!n || l >= n) && (r && r(h, l, p),
  102. o && o.push(h)),
  103. c++
  104. }
  105. }
  106. }
  107. getFaceIndexFromNode(e) {
  108. if (!e)
  109. return -1;
  110. for (var t = 1, i = e, n = 0, r = 0;;) {
  111. var o = i.parent;
  112. if (!o)
  113. break;
  114. for (var a = -1, s = 0; s < o.children.length; s++)
  115. o.children[s] === i && (a = s);
  116. var l = a % c,
  117. h = Math.floor(a / c);
  118. n = l * t + n,
  119. r = h * t + r,
  120. t *= c,
  121. i = o
  122. }
  123. return r * t + n
  124. }
  125. depthFirst(e, t, i) {
  126. o(this.root, 0, 0, 0, e, t, i, this.tileSize)
  127. }
  128. }
  129. TileTree.TraversalType = Object.freeze({
  130. PreOrder: 0,
  131. PostOrder: 1
  132. });
  133. TileTree.getLevelCountForSize = function(tileSize, size) {//512->0 2024->1
  134. var i = 0;
  135. for (size < tileSize && (size = tileSize);;) {
  136. if (size /= c,
  137. size < tileSize)
  138. break;
  139. i++
  140. }
  141. return i
  142. };
  143. TileTree.getSizeForLevel = function(e, t) {
  144. return Math.pow(c, t) * e
  145. };