t3d-3dtiles 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/LICENSE +28 -0
  2. package/README.md +41 -0
  3. package/build/t3d.3dtiles.js +5418 -0
  4. package/build/t3d.3dtiles.min.js +2 -0
  5. package/build/t3d.3dtiles.module.js +6183 -0
  6. package/examples/jsm/CesiumIon.js +30 -0
  7. package/examples/jsm/Tiles3DDebugger.js +219 -0
  8. package/examples/jsm/Tiles3DUtils.js +32 -0
  9. package/examples/jsm/helpers/LineSegmentHelper.js +74 -0
  10. package/examples/jsm/helpers/OBBHelper.js +48 -0
  11. package/examples/jsm/helpers/Tiles3DHelper.js +135 -0
  12. package/examples/jsm/math/Intersects.js +100 -0
  13. package/examples/jsm/math/LineSegment.js +234 -0
  14. package/package.json +57 -0
  15. package/src/Tiles3D.js +402 -0
  16. package/src/libs/ImageBitmapLoader.js +56 -0
  17. package/src/libs/glTF/Constants.js +85 -0
  18. package/src/libs/glTF/GLTFLoader.js +169 -0
  19. package/src/libs/glTF/GLTFResource.js +28 -0
  20. package/src/libs/glTF/GLTFUtils.js +131 -0
  21. package/src/libs/glTF/extensions/EXT_meshopt_compression.js +35 -0
  22. package/src/libs/glTF/extensions/KHR_draco_mesh_compression.js +54 -0
  23. package/src/libs/glTF/extensions/KHR_lights_punctual.js +53 -0
  24. package/src/libs/glTF/extensions/KHR_materials_clearcoat.js +42 -0
  25. package/src/libs/glTF/extensions/KHR_materials_pbrSpecularGlossiness.js +53 -0
  26. package/src/libs/glTF/extensions/KHR_materials_unlit.js +13 -0
  27. package/src/libs/glTF/extensions/KHR_texture_basisu.js +14 -0
  28. package/src/libs/glTF/extensions/KHR_texture_transform.js +31 -0
  29. package/src/libs/glTF/parsers/AccessorParser.js +99 -0
  30. package/src/libs/glTF/parsers/AnimationParser.js +118 -0
  31. package/src/libs/glTF/parsers/BufferParser.js +35 -0
  32. package/src/libs/glTF/parsers/BufferViewParser.js +27 -0
  33. package/src/libs/glTF/parsers/ImageParser.js +97 -0
  34. package/src/libs/glTF/parsers/IndexParser.js +22 -0
  35. package/src/libs/glTF/parsers/MaterialParser.js +146 -0
  36. package/src/libs/glTF/parsers/NodeParser.js +145 -0
  37. package/src/libs/glTF/parsers/PrimitiveParser.js +289 -0
  38. package/src/libs/glTF/parsers/ReferenceParser.js +67 -0
  39. package/src/libs/glTF/parsers/SceneParser.js +41 -0
  40. package/src/libs/glTF/parsers/SkinParser.js +53 -0
  41. package/src/libs/glTF/parsers/TextureParser.js +71 -0
  42. package/src/libs/glTF/parsers/Validator.js +16 -0
  43. package/src/loaders/B3DMLoader.js +49 -0
  44. package/src/loaders/CMPTLoader.js +48 -0
  45. package/src/loaders/I3DMLoader.js +49 -0
  46. package/src/loaders/PNTSLoader.js +20 -0
  47. package/src/loaders/TileGLTFLoader.js +17 -0
  48. package/src/loaders/parsers/HeaderParser.js +104 -0
  49. package/src/loaders/parsers/LoadParser.js +22 -0
  50. package/src/loaders/parsers/TableParser.js +66 -0
  51. package/src/loaders/parsers/b3dm/B3DMParser.js +18 -0
  52. package/src/loaders/parsers/b3dm/B3DMRootParser.js +22 -0
  53. package/src/loaders/parsers/b3dm/MaterialParser.js +156 -0
  54. package/src/loaders/parsers/cmpt/CMPTParser.js +37 -0
  55. package/src/loaders/parsers/cmpt/CMPTRootParser.js +44 -0
  56. package/src/loaders/parsers/gltf/IndexParser.js +24 -0
  57. package/src/loaders/parsers/i3dm/I3DMParser.js +28 -0
  58. package/src/loaders/parsers/i3dm/I3DMRootParser.js +123 -0
  59. package/src/loaders/parsers/i3dm/MaterialParser.js +152 -0
  60. package/src/loaders/parsers/i3dm/PrimitiveParser.js +291 -0
  61. package/src/loaders/parsers/pnts/PNTSRootParser.js +69 -0
  62. package/src/main.js +14 -0
  63. package/src/materials/InstancedBasicMaterial.js +32 -0
  64. package/src/materials/InstancedPBRMaterial.js +32 -0
  65. package/src/materials/InstancedShaderChunks.js +23 -0
  66. package/src/math/Ellipsoid.js +41 -0
  67. package/src/math/EllipsoidRegion.js +160 -0
  68. package/src/math/FastFrustum.js +49 -0
  69. package/src/math/GeoUtils.js +31 -0
  70. package/src/math/OBB.js +395 -0
  71. package/src/math/TileBoundingVolume.js +172 -0
  72. package/src/math/TileOBB.js +103 -0
  73. package/src/utils/BatchTable.js +14 -0
  74. package/src/utils/CameraList.js +131 -0
  75. package/src/utils/FeatureTable.js +107 -0
  76. package/src/utils/IntersectionUtils.js +136 -0
  77. package/src/utils/LRUCache.js +159 -0
  78. package/src/utils/ModelLoader.js +150 -0
  79. package/src/utils/PriorityQueue.js +102 -0
  80. package/src/utils/RequestState.js +17 -0
  81. package/src/utils/TilesLoader.js +386 -0
  82. package/src/utils/TilesScheduler.js +375 -0
  83. package/src/utils/Utils.js +43 -0
@@ -0,0 +1,395 @@
1
+ import { Box3, Matrix3, Vector3 } from 't3d';
2
+
3
+ /**
4
+ * An oriented bounding box.
5
+ */
6
+ export class OBB {
7
+
8
+ /**
9
+ * Create a new OBB.
10
+ * @param {Box3} [box] - The axis-aligned bounding box.
11
+ * @param {Matrix3} [rotation] - The rotation matrix.
12
+ */
13
+ constructor(box = new Box3(), rotation = new Matrix3()) {
14
+ this.box = box;
15
+ this.rotation = rotation;
16
+ }
17
+
18
+ /**
19
+ * Set the OBB from a center point and axes with half sizes.
20
+ * @param {Vector3} center - The center of the OBB.
21
+ * @param {Vector3} axisX - The X axis with half size.
22
+ * @param {Vector3} axisY - The Y axis with half size.
23
+ * @param {Vector3} axisZ - The Z axis with half size.
24
+ * @return {OBB} A reference to this OBB.
25
+ */
26
+ setFromCenterAndAxes(center, axisX, axisY, axisZ) {
27
+ _vec3_1.copy(axisX);
28
+ _vec3_2.copy(axisY);
29
+ _vec3_3.copy(axisZ);
30
+
31
+ const scaleX = _vec3_1.getLength();
32
+ const scaleY = _vec3_2.getLength();
33
+ const scaleZ = _vec3_3.getLength();
34
+
35
+ _vec3_1.normalize();
36
+ _vec3_2.normalize();
37
+ _vec3_3.normalize();
38
+
39
+ // handle the case where the box has a dimension of 0 in one axis
40
+ if (scaleX === 0) {
41
+ _vec3_1.crossVectors(_vec3_2, _vec3_3);
42
+ }
43
+
44
+ if (scaleY === 0) {
45
+ _vec3_2.crossVectors(_vec3_1, _vec3_3);
46
+ }
47
+
48
+ if (scaleZ === 0) {
49
+ _vec3_3.crossVectors(_vec3_1, _vec3_2);
50
+ }
51
+
52
+ this.rotation.set(
53
+ _vec3_1.x, _vec3_2.x, _vec3_3.x,
54
+ _vec3_1.y, _vec3_2.y, _vec3_3.y,
55
+ _vec3_1.z, _vec3_2.z, _vec3_3.z
56
+ );
57
+
58
+ const halfSize = _vec3_1.set(scaleX, scaleY, scaleZ);
59
+ this.box.min.copy(center).sub(halfSize);
60
+ this.box.max.copy(center).add(halfSize);
61
+
62
+ return this;
63
+ }
64
+
65
+ /**
66
+ * Transforms this OBB with the supplied matrix.
67
+ * @param {Matrix4} matrix - The transformation matrix.
68
+ * @return {OBB} A reference to this OBB.
69
+ */
70
+ applyMatrix4(matrix) {
71
+ const e = matrix.elements;
72
+
73
+ let sx = _vec3_1.set(e[0], e[1], e[2]).getLength();
74
+ const sy = _vec3_1.set(e[4], e[5], e[6]).getLength();
75
+ const sz = _vec3_1.set(e[8], e[9], e[10]).getLength();
76
+
77
+ const det = matrix.determinant();
78
+ if (det < 0) sx = -sx;
79
+
80
+ _mat3_1.setFromMatrix4(matrix);
81
+
82
+ const invSX = 1 / sx;
83
+ const invSY = 1 / sy;
84
+ const invSZ = 1 / sz;
85
+
86
+ _mat3_1.elements[0] *= invSX;
87
+ _mat3_1.elements[1] *= invSX;
88
+ _mat3_1.elements[2] *= invSX;
89
+
90
+ _mat3_1.elements[3] *= invSY;
91
+ _mat3_1.elements[4] *= invSY;
92
+ _mat3_1.elements[5] *= invSY;
93
+
94
+ _mat3_1.elements[6] *= invSZ;
95
+ _mat3_1.elements[7] *= invSZ;
96
+ _mat3_1.elements[8] *= invSZ;
97
+
98
+ this.rotation.multiply(_mat3_1);
99
+
100
+ const center = this.box.getCenter(_vec3_1);
101
+ const halfSize = this.box.getSize(_vec3_2).multiplyScalar(0.5);
102
+
103
+ halfSize.x *= sx;
104
+ halfSize.y *= sy;
105
+ halfSize.z *= sz;
106
+
107
+ // https://github.com/mrdoob/three.js/issues/21753
108
+ center.applyMatrix4(matrix);
109
+
110
+ this.box.min.copy(center).sub(halfSize);
111
+ this.box.max.copy(center).add(halfSize);
112
+
113
+ return this;
114
+ }
115
+
116
+ /**
117
+ * Get the 8 corner points of the OBB.
118
+ * @param {Vector3[]} points - The array to store the points.
119
+ * @return {Vector3[]} The array of points.
120
+ */
121
+ getPoints(points) {
122
+ const center = this.box.getCenter(_vec3_1);
123
+ const min = _vec3_2.subVectors(this.box.min, center);
124
+ const max = _vec3_3.subVectors(this.box.max, center);
125
+
126
+ let index = 0;
127
+ for (let x = -1; x <= 1; x += 2) {
128
+ for (let y = -1; y <= 1; y += 2) {
129
+ for (let z = -1; z <= 1; z += 2) {
130
+ points[index]
131
+ .set(
132
+ x < 0 ? min.x : max.x,
133
+ y < 0 ? min.y : max.y,
134
+ z < 0 ? min.z : max.z
135
+ )
136
+ .applyMatrix3(this.rotation)
137
+ .add(center);
138
+ index++;
139
+ }
140
+ }
141
+ }
142
+
143
+ return points;
144
+ }
145
+
146
+ /**
147
+ * Get the 6 planes of the OBB.
148
+ * @param {Plane[]} planes - The array to store the planes.
149
+ * @return {Plane[]} The array of planes.
150
+ */
151
+ getPlanes(planes) {
152
+ const center = this.box.getCenter(_vec3_1);
153
+ const worldMin = _vec3_2.subVectors(this.box.min, center).applyMatrix3(this.rotation).add(center);
154
+ const worldMax = _vec3_3.subVectors(this.box.max, center).applyMatrix3(this.rotation).add(center);
155
+
156
+ _vec3_1.set(0, 0, 1).applyMatrix3(this.rotation).normalize();
157
+ planes[0].setFromNormalAndCoplanarPoint(_vec3_1, worldMin);
158
+ planes[1].setFromNormalAndCoplanarPoint(_vec3_1, worldMax);
159
+ planes[1].normal.negate();
160
+ planes[1].constant *= -1;
161
+
162
+ _vec3_1.set(0, 1, 0).applyMatrix3(this.rotation).normalize();
163
+ planes[2].setFromNormalAndCoplanarPoint(_vec3_1, worldMin);
164
+ planes[3].setFromNormalAndCoplanarPoint(_vec3_1, worldMax);
165
+ planes[3].normal.negate();
166
+ planes[3].constant *= -1;
167
+
168
+ _vec3_1.set(1, 0, 0).applyMatrix3(this.rotation).normalize();
169
+ planes[4].setFromNormalAndCoplanarPoint(_vec3_1, worldMin);
170
+ planes[5].setFromNormalAndCoplanarPoint(_vec3_1, worldMax);
171
+ planes[5].normal.negate();
172
+ planes[5].constant *= -1;
173
+
174
+ return planes;
175
+ }
176
+
177
+ containsPoint(point) {
178
+ const obbStruct = getOBBStruct(this, a);
179
+
180
+ const v = _vec3_1.subVectors(point, obbStruct.c);
181
+
182
+ // project _vec3_4 onto each axis and check if these points lie inside the OBB
183
+
184
+ return Math.abs(v.dot(obbStruct.u[0])) <= obbStruct.e[0] &&
185
+ Math.abs(v.dot(obbStruct.u[1])) <= obbStruct.e[1] &&
186
+ Math.abs(v.dot(obbStruct.u[2])) <= obbStruct.e[2];
187
+ }
188
+
189
+ /**
190
+ * Reference: Closest Point on OBB to Point in Real-Time Collision Detection
191
+ * by Christer Ericson (chapter 5.1.4)
192
+ */
193
+ clampPoint(point, result) {
194
+ const obbStruct = getOBBStruct(this, a);
195
+
196
+ const v = _vec3_1.subVectors(point, obbStruct.c);
197
+
198
+ // start at the center position of the OBB
199
+
200
+ result.copy(obbStruct.c);
201
+
202
+ // project the target onto the OBB axes and walk towards that point
203
+
204
+ const x = Math.max(Math.min(v.dot(obbStruct.u[0]), obbStruct.e[0]), -obbStruct.e[0]);
205
+ result.add(obbStruct.u[0].multiplyScalar(x));
206
+
207
+ const y = Math.max(Math.min(v.dot(obbStruct.u[1]), obbStruct.e[1]), -obbStruct.e[1]);
208
+ result.add(obbStruct.u[1].multiplyScalar(y));
209
+
210
+ const z = Math.max(Math.min(v.dot(obbStruct.u[2]), obbStruct.e[2]), -obbStruct.e[2]);
211
+ result.add(obbStruct.u[2].multiplyScalar(z));
212
+
213
+ return result;
214
+ }
215
+
216
+ intersectsSphere(sphere) {
217
+ // find the point on the OBB closest to the sphere center
218
+ this.clampPoint(sphere.center, closestPoint);
219
+ // if that point is inside the sphere, the OBB and sphere intersect
220
+ return closestPoint.distanceToSquared(sphere.center) <= (sphere.radius * sphere.radius);
221
+ }
222
+
223
+ intersectsOBB(obb, epsilon = Number.EPSILON) {
224
+ // prepare data structures (the code uses the same nomenclature like the reference)
225
+
226
+ getOBBStruct(this, a);
227
+ getOBBStruct(obb, b);
228
+
229
+ // compute rotation matrix expressing b in a's coordinate frame
230
+
231
+ for (let i = 0; i < 3; i++) {
232
+ for (let j = 0; j < 3; j++) {
233
+ R[i][j] = a.u[i].dot(b.u[j]);
234
+ }
235
+ }
236
+
237
+ // compute translation vector
238
+
239
+ const v1 = _vec3_1.subVectors(b.c, a.c);
240
+
241
+ // bring translation into a's coordinate frame
242
+
243
+ t[0] = v1.dot(a.u[0]);
244
+ t[1] = v1.dot(a.u[1]);
245
+ t[2] = v1.dot(a.u[2]);
246
+
247
+ // compute common subexpressions. Add in an epsilon term to
248
+ // counteract arithmetic errors when two edges are parallel and
249
+ // their cross product is (near) null
250
+
251
+ for (let i = 0; i < 3; i++) {
252
+ for (let j = 0; j < 3; j++) {
253
+ AbsR[i][j] = Math.abs(R[i][j]) + epsilon;
254
+ }
255
+ }
256
+
257
+ let ra, rb;
258
+
259
+ // test axes L = A0, L = A1, L = A2
260
+
261
+ for (let i = 0; i < 3; i++) {
262
+ ra = a.e[i];
263
+ rb = b.e[0] * AbsR[i][0] + b.e[1] * AbsR[i][1] + b.e[2] * AbsR[i][2];
264
+ if (Math.abs(t[i]) > ra + rb) return false;
265
+ }
266
+
267
+ // test axes L = B0, L = B1, L = B2
268
+
269
+ for (let i = 0; i < 3; i++) {
270
+ ra = a.e[0] * AbsR[0][i] + a.e[1] * AbsR[1][i] + a.e[2] * AbsR[2][i];
271
+ rb = b.e[i];
272
+ if (Math.abs(t[0] * R[0][i] + t[1] * R[1][i] + t[2] * R[2][i]) > ra + rb) return false;
273
+ }
274
+
275
+ // test axis L = A0 x B0
276
+
277
+ ra = a.e[1] * AbsR[2][0] + a.e[2] * AbsR[1][0];
278
+ rb = b.e[1] * AbsR[0][2] + b.e[2] * AbsR[0][1];
279
+ if (Math.abs(t[2] * R[1][0] - t[1] * R[2][0]) > ra + rb) return false;
280
+
281
+ // test axis L = A0 x B1
282
+
283
+ ra = a.e[1] * AbsR[2][1] + a.e[2] * AbsR[1][1];
284
+ rb = b.e[0] * AbsR[0][2] + b.e[2] * AbsR[0][0];
285
+ if (Math.abs(t[2] * R[1][1] - t[1] * R[2][1]) > ra + rb) return false;
286
+
287
+ // test axis L = A0 x B2
288
+
289
+ ra = a.e[1] * AbsR[2][2] + a.e[2] * AbsR[1][2];
290
+ rb = b.e[0] * AbsR[0][1] + b.e[1] * AbsR[0][0];
291
+ if (Math.abs(t[2] * R[1][2] - t[1] * R[2][2]) > ra + rb) return false;
292
+
293
+ // test axis L = A1 x B0
294
+
295
+ ra = a.e[0] * AbsR[2][0] + a.e[2] * AbsR[0][0];
296
+ rb = b.e[1] * AbsR[1][2] + b.e[2] * AbsR[1][1];
297
+ if (Math.abs(t[0] * R[2][0] - t[2] * R[0][0]) > ra + rb) return false;
298
+
299
+ // test axis L = A1 x B1
300
+
301
+ ra = a.e[0] * AbsR[2][1] + a.e[2] * AbsR[0][1];
302
+ rb = b.e[0] * AbsR[1][2] + b.e[2] * AbsR[1][0];
303
+ if (Math.abs(t[0] * R[2][1] - t[2] * R[0][1]) > ra + rb) return false;
304
+
305
+ // test axis L = A1 x B2
306
+
307
+ ra = a.e[0] * AbsR[2][2] + a.e[2] * AbsR[0][2];
308
+ rb = b.e[0] * AbsR[1][1] + b.e[1] * AbsR[1][0];
309
+ if (Math.abs(t[0] * R[2][2] - t[2] * R[0][2]) > ra + rb) return false;
310
+
311
+ // test axis L = A2 x B0
312
+
313
+ ra = a.e[0] * AbsR[1][0] + a.e[1] * AbsR[0][0];
314
+ rb = b.e[1] * AbsR[2][2] + b.e[2] * AbsR[2][1];
315
+ if (Math.abs(t[1] * R[0][0] - t[0] * R[1][0]) > ra + rb) return false;
316
+
317
+ // test axis L = A2 x B1
318
+
319
+ ra = a.e[0] * AbsR[1][1] + a.e[1] * AbsR[0][1];
320
+ rb = b.e[0] * AbsR[2][2] + b.e[2] * AbsR[2][0];
321
+ if (Math.abs(t[1] * R[0][1] - t[0] * R[1][1]) > ra + rb) return false;
322
+
323
+ // test axis L = A2 x B2
324
+
325
+ ra = a.e[0] * AbsR[1][2] + a.e[1] * AbsR[0][2];
326
+ rb = b.e[0] * AbsR[2][1] + b.e[1] * AbsR[2][0];
327
+ if (Math.abs(t[1] * R[0][2] - t[0] * R[1][2]) > ra + rb) return false;
328
+
329
+ // since no separating axis is found, the OBBs must be intersecting
330
+
331
+ return true;
332
+ }
333
+
334
+ /**
335
+ * To AABB with matrix4 transform.
336
+ * This method can ensure the AABB center is origin,
337
+ * and transform only contains rotation and offset.
338
+ * @param {Box3} box3 - The target box.
339
+ * @param {Matrix4} transform - The transformation matrix.
340
+ */
341
+ toBoundingBoxWithTransform(box3, transform) {
342
+ const center = this.box.getCenter(_vec3_1);
343
+
344
+ box3.min.copy(this.box.min).sub(center);
345
+ box3.max.copy(this.box.max).sub(center);
346
+
347
+ const e = this.rotation.elements;
348
+
349
+ transform.set(
350
+ e[0], e[3], e[6], center.x,
351
+ e[1], e[4], e[7], center.y,
352
+ e[2], e[5], e[8], center.z,
353
+ 0, 0, 0, 1
354
+ );
355
+ }
356
+
357
+ }
358
+
359
+ const closestPoint = new Vector3();
360
+
361
+ const _vec3_1 = new Vector3();
362
+ const _vec3_2 = new Vector3();
363
+ const _vec3_3 = new Vector3();
364
+ const _mat3_1 = new Matrix3();
365
+
366
+ const R = [[], [], []];
367
+ const AbsR = [[], [], []];
368
+ const t = [];
369
+
370
+ const _halfSize = new Vector3();
371
+
372
+ const a = {
373
+ c: new Vector3(), // center
374
+ u: [new Vector3(), new Vector3(), new Vector3()], // basis vectors
375
+ e: [] // half width
376
+ };
377
+
378
+ const b = {
379
+ c: new Vector3(), // center
380
+ u: [new Vector3(), new Vector3(), new Vector3()], // basis vectors
381
+ e: [] // half width
382
+ };
383
+
384
+ function getOBBStruct(obb, target) {
385
+ obb.box.getCenter(target.c);
386
+
387
+ const rotationElements = obb.rotation.elements;
388
+ target.u[0].fromArray(rotationElements, 0);
389
+ target.u[1].fromArray(rotationElements, 3);
390
+ target.u[2].fromArray(rotationElements, 6);
391
+
392
+ obb.box.getSize(_halfSize).multiplyScalar(0.5).toArray(target.e);
393
+
394
+ return target;
395
+ }
@@ -0,0 +1,172 @@
1
+ import { Sphere, Vector2, Vector3 } from 't3d';
2
+ import { TileOBB } from './TileOBB.js';
3
+ import { EllipsoidRegion } from './EllipsoidRegion.js';
4
+
5
+ export class TileBoundingVolume {
6
+
7
+ constructor() {
8
+ this.sphere = null;
9
+ this.obb = null;
10
+ this.region = null;
11
+ }
12
+
13
+ setOBBData(data, transform) {
14
+ const obb = new TileOBB();
15
+
16
+ obb.setFromCenterAndAxes(
17
+ _vec3_4.set(data[0], data[1], data[2]),
18
+ _vec3_1.set(data[3], data[4], data[5]),
19
+ _vec3_2.set(data[6], data[7], data[8]),
20
+ _vec3_3.set(data[9], data[10], data[11])
21
+ ).applyMatrix4(transform);
22
+ obb.updateCache();
23
+
24
+ this.obb = obb;
25
+ }
26
+
27
+ setSphereData(data, transform) {
28
+ const sphere = new Sphere();
29
+
30
+ sphere.center.set(data[0], data[1], data[2]);
31
+ sphere.radius = data[3];
32
+ sphere.applyMatrix4(transform);
33
+
34
+ this.sphere = sphere;
35
+ }
36
+
37
+ setRegionData(west, south, east, north, minHeight, maxHeight) {
38
+ const region = new EllipsoidRegion(
39
+ WGS84_RADIUS.clone(),
40
+ new Vector2(south, north),
41
+ new Vector2(west, east),
42
+ new Vector2(minHeight, maxHeight)
43
+ );
44
+ this.region = region;
45
+
46
+ const obb = new TileOBB();
47
+ region.getOrientedBoundingBox(obb);
48
+ obb.updateCache();
49
+ this.obb = obb;
50
+
51
+ // const sphere = new Sphere();
52
+ // obb.getBoundingSphere(sphere);
53
+ // this.sphere = sphere;
54
+ }
55
+
56
+ intersectsRay(ray) {
57
+ const sphere = this.sphere;
58
+ const obb = this.obb;
59
+
60
+ // Early out if we don't hit this tile sphere
61
+ if (sphere && !ray.intersectsSphere(sphere)) {
62
+ return false;
63
+ }
64
+
65
+ // Early out if we don't this this tile box
66
+ if (obb && !obb.intersectsRay(ray)) {
67
+ return false;
68
+ }
69
+
70
+ return true;
71
+ }
72
+
73
+ intersectRay(ray, target) {
74
+ const sphere = this.sphere;
75
+ const obb = this.obb;
76
+
77
+ let sphereDistSq = -Infinity;
78
+ let obbDistSq = -Infinity;
79
+
80
+ if (sphere) {
81
+ if (ray.intersectSphere(sphere, _vec3_1)) {
82
+ sphereDistSq = sphere.containsPoint(ray.origin) ? 0 : ray.origin.distanceToSquared(_vec3_1);
83
+ }
84
+ }
85
+
86
+ if (obb) {
87
+ if (obb.intersectRay(ray, _vec3_1)) {
88
+ obbDistSq = obb.containsPoint(ray.origin) ? 0 : ray.origin.distanceToSquared(_vec3_1);
89
+ }
90
+ }
91
+
92
+ // if we didn't hit anything then exit
93
+ const furthestDist = Math.max(sphereDistSq, obbDistSq);
94
+ if (furthestDist === -Infinity) {
95
+ return null;
96
+ }
97
+
98
+ // get the furthest hit point if needed
99
+ return ray.at(Math.sqrt(furthestDist), target);
100
+ }
101
+
102
+ distanceToPoint(point) {
103
+ const sphere = this.sphere;
104
+ const obb = this.obb;
105
+
106
+ let sphereDistance = -Infinity;
107
+ let obbDistance = -Infinity;
108
+
109
+ if (sphere) {
110
+ // Sphere#distanceToPoint is negative inside the sphere, whereas Box3#distanceToPoint is
111
+ // zero inside the box. Clipping the distance to a minimum of zero ensures that both
112
+ // types of bounding volume behave the same way.
113
+ sphereDistance = Math.max(sphere.distanceToPoint(point), 0);
114
+ }
115
+
116
+ if (obb) {
117
+ obbDistance = obb.distanceToPoint(point);
118
+ }
119
+
120
+ // return the further distance of the two volumes
121
+ return sphereDistance > obbDistance ? sphereDistance : obbDistance;
122
+ }
123
+
124
+ intersectsFrustum(frustum) {
125
+ const sphere = this.sphere;
126
+ if (sphere && !frustum.intersectsSphere(sphere)) {
127
+ return false;
128
+ }
129
+
130
+ const obb = this.obb;
131
+ if (obb && !obb.intersectsFrustum(frustum)) {
132
+ return false;
133
+ }
134
+
135
+ // if we don't have a sphere or obb then just say we did intersect
136
+ return Boolean(sphere || obb);
137
+ }
138
+
139
+ getOrientedBoundingBox(targetBox, targetMatrix) {
140
+ if (this.obb) {
141
+ targetBox.copy(this.obb._originBox);
142
+ targetMatrix.copy(this.obb._originBoxTransform);
143
+ } else {
144
+ this.getBoundingBox(targetBox);
145
+ targetMatrix.identity();
146
+ }
147
+ }
148
+
149
+ getBoundingBox(target) {
150
+ if (this.sphere) {
151
+ return this.sphere.getBoundingBox(target);
152
+ } else {
153
+ return this.obb.getBoundingBox(target);
154
+ }
155
+ }
156
+
157
+ getBoundingSphere(target) {
158
+ if (this.sphere) {
159
+ return target.copy(this.sphere);
160
+ } else {
161
+ return this.obb.getBoundingSphere(target);
162
+ }
163
+ }
164
+
165
+ }
166
+
167
+ const WGS84_RADIUS = new Vector3(6378137, 6378137, 6356752.3142451793);
168
+
169
+ const _vec3_1 = new Vector3();
170
+ const _vec3_2 = new Vector3();
171
+ const _vec3_3 = new Vector3();
172
+ const _vec3_4 = new Vector3();
@@ -0,0 +1,103 @@
1
+ import { Box3, Matrix4, Plane, Ray, Vector3 } from 't3d';
2
+ import { OBB } from './OBB.js';
3
+
4
+ export class TileOBB extends OBB {
5
+
6
+ constructor() {
7
+ super();
8
+
9
+ // cache obb points and planes
10
+ // to speed up intersection test with frustum
11
+ this._points = new Array(8).fill().map(() => new Vector3());
12
+ this._planes = new Array(6).fill().map(() => new Plane());
13
+
14
+ // cache obb origin box and transform matrix4x4
15
+ // to speed up intersection test with ray and error calculation
16
+ this._originBox = new Box3();
17
+ this._originBoxTransform = new Matrix4();
18
+ this._originBoxTransformInverse = new Matrix4();
19
+ }
20
+
21
+ updateCache() {
22
+ this.getPoints(this._points);
23
+ this.getPlanes(this._planes);
24
+
25
+ this.toBoundingBoxWithTransform(
26
+ this._originBox, this._originBoxTransform
27
+ );
28
+ this._originBoxTransformInverse.copy(this._originBoxTransform).inverse();
29
+ }
30
+
31
+ containsPoint(point) {
32
+ _vec3_1.copy(point).applyMatrix4(this._originBoxTransformInverse);
33
+ return this.box.containsPoint(_vec3_1);
34
+ }
35
+
36
+ intersectsRay(ray) {
37
+ _ray_1.copy(ray).applyMatrix4(this._originBoxTransformInverse);
38
+ return _ray_1.intersectsBox(this._originBox);
39
+ }
40
+
41
+ intersectRay(ray, target) {
42
+ _ray_1.copy(ray).applyMatrix4(this._originBoxTransformInverse);
43
+
44
+ if (_ray_1.intersectBox(this._originBox, target)) {
45
+ return target.applyMatrix4(this._originBoxTransform);
46
+ }
47
+
48
+ return null;
49
+ }
50
+
51
+ // optimized intersection test with frustum
52
+ intersectsFrustum(frustum) {
53
+ for (let i = 0; i < 6; i++) {
54
+ const plane = frustum.planes[i];
55
+ let maxDistance = -Infinity;
56
+ for (let j = 0; j < 8; j++) {
57
+ const v = this._points[j];
58
+ const dist = plane.distanceToPoint(v);
59
+ maxDistance = maxDistance < dist ? dist : maxDistance;
60
+ }
61
+
62
+ if (maxDistance < 0) {
63
+ return false;
64
+ }
65
+ }
66
+
67
+ // do the opposite check using the obb planes to avoid false positives
68
+ for (let i = 0; i < 6; i++) {
69
+ const plane = this._planes[i];
70
+ let maxDistance = -Infinity;
71
+ for (let j = 0; j < 8; j++) {
72
+ const v = frustum.points[j];
73
+ const dist = plane.distanceToPoint(v);
74
+ maxDistance = maxDistance < dist ? dist : maxDistance;
75
+ }
76
+
77
+ if (maxDistance < 0) {
78
+ return false;
79
+ }
80
+ }
81
+
82
+ return true;
83
+ }
84
+
85
+ distanceToPoint(point) {
86
+ // originBoxTransformInverse has no scale,
87
+ // so we don't need to scale the distance
88
+ _vec3_1.copy(point).applyMatrix4(this._originBoxTransformInverse);
89
+ return this._originBox.distanceToPoint(_vec3_1);
90
+ }
91
+
92
+ getBoundingSphere(target) {
93
+ return this.box.getBoundingSphere(target);
94
+ }
95
+
96
+ getBoundingBox(target) {
97
+ return target.setFromPoints(this._points);
98
+ }
99
+
100
+ }
101
+
102
+ const _ray_1 = new Ray();
103
+ const _vec3_1 = new Vector3();
@@ -0,0 +1,14 @@
1
+ import { FeatureTable } from './FeatureTable.js';
2
+
3
+ export class BatchTable extends FeatureTable {
4
+
5
+ constructor(buffer, batchSize, start, headerLength, binLength) {
6
+ super(buffer, start, headerLength, binLength);
7
+ this.batchSize = batchSize;
8
+ }
9
+
10
+ getData(key, componentType = null, type = null) {
11
+ return super.getData(key, this.batchSize, componentType, type);
12
+ }
13
+
14
+ }