@jdultra/threedtiles 6.0.4 → 7.0.1
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.
- package/README.md +11 -14
- package/package.json +1 -1
- package/src/decoder/B3DMDecoder.js +9 -2
- package/src/geometry/obb.js +4 -4
- package/src/index.js +68 -32
- package/src/tileset/OGC3DTile.js +12 -9
- package/src/tileset/instanced/InstancedTile.js +5 -3
- package/threedtiles.js +23060 -0
- package/webpack.config.js +6 -1
package/README.md
CHANGED
|
@@ -6,12 +6,16 @@ The fastest 3DTiles viewer for three.js
|
|
|
6
6
|
|
|
7
7
|
[Photogrametry (OBJ conversion)](https://ebeaufay.github.io/ThreedTilesViewer.github.io/)
|
|
8
8
|
|
|
9
|
+
[Point cloud vs Mesh](https://www.jdultra.com/pointmeshing/index.html)
|
|
10
|
+
|
|
9
11
|
[PBR material (GlTF conversion)](https://www.jdultra.com/pbr/)
|
|
10
12
|
|
|
11
13
|
[Occlusion culling (IFC conversion)](https://www.jdultra.com/occlusion/index.html)
|
|
12
14
|
|
|
13
15
|
[Instanced Tileset (pilot a swarm of highly detailed spaceships)](https://www.jdultra.com/instanced/index.html)
|
|
14
16
|
|
|
17
|
+
NPM dependency: "@jdultra/threedtiles": "^6.0.4"
|
|
18
|
+
|
|
15
19
|
Adding a tileset to a scene is as easy as :
|
|
16
20
|
|
|
17
21
|
```
|
|
@@ -44,6 +48,13 @@ Unzip and run :
|
|
|
44
48
|
|
|
45
49
|
> npm run dev
|
|
46
50
|
|
|
51
|
+
## Mesh to 3DTiles Converter
|
|
52
|
+
|
|
53
|
+
If you need to convert meshes to 3DTiles, from small assets to gigabytes of data, contact me for a trial on UltraMesh tool.
|
|
54
|
+
It works for all types of meshes: photogrametry, BIM, colored or textured meshes with a single texture atlas or many individual textures.
|
|
55
|
+
There's support for OBJ, IFC and glTF meshes and las/laz point clouds.
|
|
56
|
+
I aim for optimal quality in terms of mesh, texture and tileset structure for optimal streaming.
|
|
57
|
+
Contact: emeric.beaufays@jdultra.com
|
|
47
58
|
|
|
48
59
|
## Features
|
|
49
60
|
|
|
@@ -339,17 +350,3 @@ setInterval(() => {
|
|
|
339
350
|
```
|
|
340
351
|
|
|
341
352
|
window#requestIdleCallback is also a good option but the rate of updates becomes slightly unpredictable.
|
|
342
|
-
|
|
343
|
-
# Projects that use this library
|
|
344
|
-
https://github.com/ebeaufay/UltraGlobe allows displaying a globe with multi resolution imagery, elevation and 3DTiles.
|
|
345
|
-
|
|
346
|
-
If you have a project that stems from this code. I'd love to link to it here and I'm always open to implementing extra features.
|
|
347
|
-
Contact: emeric.beaufays@jdultra.com
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
# Mesh to 3DTiles Converter
|
|
351
|
-
|
|
352
|
-
I also have code to convert meshes to 3DTiles with no limit to the size of the dataset relative to faces or textures.
|
|
353
|
-
It works for all types of meshes: photogrametry, BIM, colored or textured meshes with a single texture atlas or many individual textures.
|
|
354
|
-
The code is not open source but feel free to contact me for a trial.
|
|
355
|
-
Contact: emeric.beaufays@jdultra.com
|
package/package.json
CHANGED
|
@@ -26,8 +26,8 @@ function parseB3DM(arrayBuffer, meshCallback, geometricError, zUpToYUp) {
|
|
|
26
26
|
String.fromCharCode(dataView.getUint8(3));
|
|
27
27
|
console.assert(magic === 'b3dm');
|
|
28
28
|
|
|
29
|
-
const version = dataView.getUint32(4, true);
|
|
30
|
-
console.assert(version === 1);
|
|
29
|
+
//const version = dataView.getUint32(4, true);
|
|
30
|
+
//console.assert(version === 1);
|
|
31
31
|
|
|
32
32
|
const byteLength = dataView.getUint32(8, true);
|
|
33
33
|
console.assert(byteLength === arrayBuffer.byteLength);
|
|
@@ -70,6 +70,13 @@ function parseB3DM(arrayBuffer, meshCallback, geometricError, zUpToYUp) {
|
|
|
70
70
|
if (rtcCenter) {
|
|
71
71
|
tempMatrix.makeTranslation(rtcCenter[0], rtcCenter[1], rtcCenter[2])
|
|
72
72
|
model.scene.applyMatrix4(tempMatrix);
|
|
73
|
+
}else if(!!model.userData.gltfExtensions && !!model.userData.gltfExtensions.CESIUM_RTC){
|
|
74
|
+
tempMatrix.makeTranslation(model.userData.gltfExtensions.CESIUM_RTC.center[0], model.userData.gltfExtensions.CESIUM_RTC.center[1], model.userData.gltfExtensions.CESIUM_RTC.center[2])
|
|
75
|
+
model.scene.applyMatrix4(tempMatrix);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if(!zUpToYUp){
|
|
79
|
+
model.scene.applyMatrix4(zUpToYUpMatrix);
|
|
73
80
|
}
|
|
74
81
|
|
|
75
82
|
model.scene.traverse((o) => {
|
package/src/geometry/obb.js
CHANGED
|
@@ -2,10 +2,10 @@ import { Matrix3, Sphere, Vector3 } from "three";
|
|
|
2
2
|
|
|
3
3
|
class OBB {
|
|
4
4
|
constructor(values) {
|
|
5
|
-
this.center = new Vector3(values[0], values[
|
|
6
|
-
var e1 = new Vector3(values[3], values[
|
|
7
|
-
var e2 = new Vector3(values[6], values[
|
|
8
|
-
var e3 = new Vector3(values[9], values[
|
|
5
|
+
this.center = new Vector3(values[0], values[1], values[2]);
|
|
6
|
+
var e1 = new Vector3(values[3], values[4], values[4]);
|
|
7
|
+
var e2 = new Vector3(values[6], values[7], values[8]);
|
|
8
|
+
var e3 = new Vector3(values[9], values[10], values[11]);
|
|
9
9
|
|
|
10
10
|
this.halfWidth = e1.length();
|
|
11
11
|
this.halfHeight = e2.length();
|
package/src/index.js
CHANGED
|
@@ -8,11 +8,10 @@ import { setIntervalAsync } from 'set-interval-async/dynamic';
|
|
|
8
8
|
import { OcclusionCullingService } from "./tileset/OcclusionCullingService";
|
|
9
9
|
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer';
|
|
10
10
|
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js';
|
|
11
|
-
import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass.js';
|
|
12
|
-
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
|
|
13
11
|
|
|
14
12
|
import { InstancedOGC3DTile } from "./tileset/instanced/InstancedOGC3DTile.js"
|
|
15
13
|
import { InstancedTileLoader } from "./tileset/instanced/InstancedTileLoader.js"
|
|
14
|
+
import { Sky } from 'three/addons/objects/Sky.js';
|
|
16
15
|
|
|
17
16
|
|
|
18
17
|
const occlusionCullingService = new OcclusionCullingService();
|
|
@@ -23,10 +22,7 @@ const domContainer = initDomContainer("screen");
|
|
|
23
22
|
const camera = initCamera(domContainer.offsetWidth, domContainer.offsetHeight);
|
|
24
23
|
const stats = initStats(domContainer);
|
|
25
24
|
const renderer = initRenderer(camera, domContainer);
|
|
26
|
-
const ogc3DTiles = initTileset(scene,
|
|
27
|
-
|
|
28
|
-
//const instancedTileLoader = createInstancedTileLoader(scene);
|
|
29
|
-
//initInstancedTilesets(instancedTileLoader);
|
|
25
|
+
const ogc3DTiles = initTileset(scene, 2.0);
|
|
30
26
|
|
|
31
27
|
const controller = initController(camera, domContainer);
|
|
32
28
|
|
|
@@ -34,7 +30,41 @@ const composer = initComposer(scene, camera, renderer);
|
|
|
34
30
|
|
|
35
31
|
animate();
|
|
36
32
|
|
|
33
|
+
let sky, sun;
|
|
34
|
+
initSky();
|
|
35
|
+
function initSky() {
|
|
36
|
+
sky = new Sky();
|
|
37
|
+
sky.scale.setScalar(450000);
|
|
38
|
+
scene.add(sky);
|
|
39
|
+
|
|
40
|
+
sun = new THREE.Vector3();
|
|
41
|
+
|
|
42
|
+
const effectController = {
|
|
43
|
+
turbidity: 10,
|
|
44
|
+
rayleigh: 1,
|
|
45
|
+
mieCoefficient: 0.005,
|
|
46
|
+
mieDirectionalG: 0.3,
|
|
47
|
+
elevation: 5,
|
|
48
|
+
azimuth: 40,
|
|
49
|
+
exposure: renderer.toneMappingExposure
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const uniforms = sky.material.uniforms;
|
|
53
|
+
uniforms['turbidity'].value = effectController.turbidity;
|
|
54
|
+
uniforms['rayleigh'].value = effectController.rayleigh;
|
|
55
|
+
uniforms['mieCoefficient'].value = effectController.mieCoefficient;
|
|
56
|
+
uniforms['mieDirectionalG'].value = effectController.mieDirectionalG;
|
|
57
|
+
|
|
58
|
+
const phi = THREE.MathUtils.degToRad(90 - effectController.elevation);
|
|
59
|
+
const theta = THREE.MathUtils.degToRad(effectController.azimuth);
|
|
60
|
+
|
|
61
|
+
sun.setFromSphericalCoords(1, phi, theta);
|
|
37
62
|
|
|
63
|
+
uniforms['sunPosition'].value.copy(sun);
|
|
64
|
+
|
|
65
|
+
renderer.toneMappingExposure = effectController.exposure;
|
|
66
|
+
renderer.render(scene, camera);
|
|
67
|
+
}
|
|
38
68
|
function initComposer(scene, camera, renderer) {
|
|
39
69
|
const renderScene = new RenderPass(scene, camera);
|
|
40
70
|
//const bloomPass = new UnrealBloomPass(new THREE.Vector2(window.innerWidth, window.innerHeight), 0.4, 0.5, 0);
|
|
@@ -49,9 +79,14 @@ function initScene() {
|
|
|
49
79
|
const scene = new THREE.Scene();
|
|
50
80
|
scene.matrixAutoUpdate = false;
|
|
51
81
|
//scene.matrixWorldAutoUpdate = false;
|
|
52
|
-
scene.background = new THREE.Color(
|
|
53
|
-
|
|
54
|
-
|
|
82
|
+
scene.background = new THREE.Color(0xE5E3E4);
|
|
83
|
+
const dirLight = new THREE.DirectionalLight(0xFFFFFF, 1.0);
|
|
84
|
+
dirLight.position.set(100,100,100);
|
|
85
|
+
dirLight.lookAt(new THREE.Vector3(0,0,0));
|
|
86
|
+
//scene.add(new THREE.AmbientLight(0xFFFFFF, 1.0));
|
|
87
|
+
|
|
88
|
+
scene.add(dirLight)
|
|
89
|
+
|
|
55
90
|
/* const light = new THREE.PointLight(0xbbbbff, 2, 5000);
|
|
56
91
|
const sphere = new THREE.SphereGeometry(2, 16, 8);
|
|
57
92
|
light.add(new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({ color: 0xbbbbff })));
|
|
@@ -111,14 +146,7 @@ function initStats(dom) {
|
|
|
111
146
|
}
|
|
112
147
|
|
|
113
148
|
|
|
114
|
-
function initCamera(width, height) {
|
|
115
|
-
const camera = new THREE.PerspectiveCamera(60, width / height, 0.1, 1000);
|
|
116
|
-
camera.position.set(-0.5,-0.7,10);
|
|
117
|
-
camera.lookAt(0,0,0);
|
|
118
149
|
|
|
119
|
-
camera.matrixAutoUpdate = true;
|
|
120
|
-
return camera;
|
|
121
|
-
}
|
|
122
150
|
|
|
123
151
|
function initTileset(scene, gem) {
|
|
124
152
|
|
|
@@ -126,32 +154,32 @@ function initTileset(scene, gem) {
|
|
|
126
154
|
//// Insert code to be called on every newly decoded mesh e.g.:
|
|
127
155
|
mesh.material.wireframe = false;
|
|
128
156
|
mesh.material.side = THREE.DoubleSide;
|
|
129
|
-
mesh.material.metalness = 0.0
|
|
130
|
-
}, points=>{
|
|
131
|
-
points.material.size = Math.min(1.0,0.5*Math.sqrt(points.geometricError));
|
|
157
|
+
//mesh.material.metalness = 0.0
|
|
158
|
+
}, points => {
|
|
159
|
+
points.material.size = Math.min(1.0, 0.5 * Math.sqrt(points.geometricError));
|
|
132
160
|
points.material.sizeAttenuation = true;
|
|
133
161
|
});
|
|
134
162
|
|
|
135
163
|
const ogc3DTile = new OGC3DTile({
|
|
136
|
-
url: "https://storage.googleapis.com/ogc-3d-tiles/baltimore/tileset.json",
|
|
137
|
-
//url: "http://localhost:8080/tileset.json",
|
|
138
164
|
//url: "https://storage.googleapis.com/ogc-3d-tiles/berlinTileset/tileset.json",
|
|
165
|
+
//url: "https://storage.googleapis.com/ogc-3d-tiles/ayutthaya/tiledWithSkirts/tileset.json",
|
|
166
|
+
url: "http://localhost:8080/tileset.json",
|
|
139
167
|
geometricErrorMultiplier: 1,
|
|
140
|
-
loadOutsideView:
|
|
168
|
+
loadOutsideView: true,
|
|
141
169
|
tileLoader: tileLoader,
|
|
142
170
|
//occlusionCullingService: occlusionCullingService,
|
|
143
171
|
static: false,
|
|
144
|
-
centerModel:true,
|
|
145
|
-
renderer: renderer
|
|
146
|
-
|
|
172
|
+
centerModel: true,
|
|
173
|
+
renderer: renderer
|
|
174
|
+
|
|
147
175
|
});
|
|
148
176
|
setIntervalAsync(function () {
|
|
149
177
|
ogc3DTile.update(camera);
|
|
150
178
|
}, 10);
|
|
151
179
|
|
|
152
|
-
|
|
180
|
+
//ogc3DTile.scale.set(0.1,0.1,0.1)
|
|
153
181
|
|
|
154
|
-
//ogc3DTile.rotateOnAxis(new THREE.Vector3(1, 0, 0), Math.PI *
|
|
182
|
+
//ogc3DTile.rotateOnAxis(new THREE.Vector3(1, 0, 0), -Math.PI * 0.5) // Z-UP to Y-UP
|
|
155
183
|
//ogc3DTile.translateOnAxis(new THREE.Vector3(0, 0, 1), 1)
|
|
156
184
|
/*
|
|
157
185
|
ogc3DTile.translateOnAxis(new THREE.Vector3(0, 0, 1), 10) // Z-UP to Y-UP
|
|
@@ -181,13 +209,13 @@ function initInstancedTilesets(instancedTileLoader) {
|
|
|
181
209
|
|
|
182
210
|
|
|
183
211
|
const tileset = new InstancedOGC3DTile({
|
|
184
|
-
url: "https://storage.googleapis.com/ogc-3d-tiles/berlinTileset/tileset.json",
|
|
185
|
-
|
|
212
|
+
//url: "https://storage.googleapis.com/ogc-3d-tiles/berlinTileset/tileset.json",
|
|
213
|
+
url: "http://localhost:8080/tileset.json",
|
|
186
214
|
geometricErrorMultiplier: 0.1,
|
|
187
215
|
loadOutsideView: true,
|
|
188
216
|
tileLoader: instancedTileLoader,
|
|
189
217
|
static: false,
|
|
190
|
-
centerModel:true,
|
|
218
|
+
centerModel: true,
|
|
191
219
|
renderer: renderer
|
|
192
220
|
});
|
|
193
221
|
//tileset.rotateOnAxis(new THREE.Vector3(1, 0, 0), Math.PI * -0.5) // Z-UP to Y-UP
|
|
@@ -227,15 +255,23 @@ function initLODMultiplierSlider(instancedTilesets) {
|
|
|
227
255
|
}
|
|
228
256
|
}
|
|
229
257
|
|
|
258
|
+
function initCamera(width, height) {
|
|
259
|
+
const camera = new THREE.PerspectiveCamera(60, width / height, 0.1, 20000);
|
|
260
|
+
camera.position.set(50, 50, 50);
|
|
261
|
+
camera.lookAt(0, 0, 0);
|
|
262
|
+
|
|
263
|
+
camera.matrixAutoUpdate = true;
|
|
264
|
+
return camera;
|
|
265
|
+
}
|
|
230
266
|
function initController(camera, dom) {
|
|
231
267
|
const controller = new OrbitControls(camera, dom);
|
|
232
268
|
|
|
233
269
|
//controller.target.set(4629210.73133627, 435359.7901640832, 4351492.357788198);
|
|
234
|
-
controller.target.set(0,0,0);
|
|
270
|
+
controller.target.set(0, 0, 0);
|
|
235
271
|
|
|
236
272
|
|
|
237
273
|
controller.minDistance = 0.1;
|
|
238
|
-
controller.maxDistance =
|
|
274
|
+
controller.maxDistance = 10000;
|
|
239
275
|
controller.update();
|
|
240
276
|
return controller;
|
|
241
277
|
}
|
package/src/tileset/OGC3DTile.js
CHANGED
|
@@ -90,7 +90,7 @@ class OGC3DTile extends THREE.Object3D {
|
|
|
90
90
|
this.level = properties.level ? properties.level : 0;
|
|
91
91
|
this.hasMeshContent = false; // true when the provided json has a content field pointing to a B3DM file
|
|
92
92
|
this.hasUnloadedJSONContent = false; // true when the provided json has a content field pointing to a JSON file that is not yet loaded
|
|
93
|
-
|
|
93
|
+
this.centerModel = properties.centerModel;
|
|
94
94
|
this.abortController = new AbortController();
|
|
95
95
|
this.layers.disable(0);
|
|
96
96
|
|
|
@@ -106,7 +106,7 @@ class OGC3DTile extends THREE.Object3D {
|
|
|
106
106
|
result.json().then(json => {
|
|
107
107
|
self.setup({ rootPath: path.dirname(properties.url), json: json });
|
|
108
108
|
if (properties.onLoadCallback) properties.onLoadCallback(self);
|
|
109
|
-
if (!!
|
|
109
|
+
if (!!self.centerModel) {
|
|
110
110
|
const tempSphere = new THREE.Sphere();
|
|
111
111
|
if (self.boundingVolume instanceof OBB) {
|
|
112
112
|
// box
|
|
@@ -162,12 +162,14 @@ class OGC3DTile extends THREE.Object3D {
|
|
|
162
162
|
} else {
|
|
163
163
|
this.geometricError = properties.parentGeometricError;
|
|
164
164
|
}
|
|
165
|
+
|
|
165
166
|
// decode transform
|
|
166
|
-
if (!!this.json.transform) {
|
|
167
|
+
if (!!this.json.transform && !this.centerModel) {
|
|
167
168
|
let mat = new THREE.Matrix4();
|
|
168
169
|
mat.elements = this.json.transform;
|
|
169
170
|
this.applyMatrix4(mat);
|
|
170
171
|
}
|
|
172
|
+
|
|
171
173
|
// decode volume
|
|
172
174
|
if (!!this.json.boundingVolume) {
|
|
173
175
|
if (!!this.json.boundingVolume.box) {
|
|
@@ -180,7 +182,7 @@ class OGC3DTile extends THREE.Object3D {
|
|
|
180
182
|
this.boundingVolume = new THREE.Sphere(new THREE.Vector3(tempVec1.x, tempVec1.y, tempVec1.z), tempVec1.distanceTo(tempVec2));
|
|
181
183
|
} else if (!!this.json.boundingVolume.sphere) {
|
|
182
184
|
const sphere = this.json.boundingVolume.sphere;
|
|
183
|
-
this.boundingVolume = new THREE.Sphere(new THREE.Vector3(sphere[0], sphere[
|
|
185
|
+
this.boundingVolume = new THREE.Sphere(new THREE.Vector3(sphere[0], sphere[1], sphere[2]), sphere[3]);
|
|
184
186
|
} else {
|
|
185
187
|
this.boundingVolume = properties.parentBoundingVolume;
|
|
186
188
|
}
|
|
@@ -188,6 +190,8 @@ class OGC3DTile extends THREE.Object3D {
|
|
|
188
190
|
this.boundingVolume = properties.parentBoundingVolume;
|
|
189
191
|
}
|
|
190
192
|
|
|
193
|
+
|
|
194
|
+
|
|
191
195
|
if (!!this.json.content) { //if there is a content, json or otherwise, schedule it to be loaded
|
|
192
196
|
if (!!this.json.content.uri && this.json.content.uri.includes("json")) {
|
|
193
197
|
this.hasUnloadedJSONContent = true;
|
|
@@ -222,9 +226,7 @@ class OGC3DTile extends THREE.Object3D {
|
|
|
222
226
|
if (!!url) {
|
|
223
227
|
if (url.includes(".b3dm") || url.includes(".glb") || url.includes(".gltf")) {
|
|
224
228
|
self.contentURL = url;
|
|
225
|
-
|
|
226
|
-
//self.applyMatrix4(zUpToYUp);
|
|
227
|
-
}
|
|
229
|
+
|
|
228
230
|
self.tileLoader.get(self.abortController, this.uuid, url, mesh => {
|
|
229
231
|
if (!!self.deleted) return;
|
|
230
232
|
mesh.traverse((o) => {
|
|
@@ -423,7 +425,8 @@ class OGC3DTile extends THREE.Object3D {
|
|
|
423
425
|
cameraOnLoad: camera,
|
|
424
426
|
occlusionCullingService: self.occlusionCullingService,
|
|
425
427
|
renderer: self.renderer,
|
|
426
|
-
static: self.static
|
|
428
|
+
static: self.static,
|
|
429
|
+
centerModel: false
|
|
427
430
|
});
|
|
428
431
|
self.childrenTiles.push(childTile);
|
|
429
432
|
self.add(childTile);
|
|
@@ -535,7 +538,7 @@ class OGC3DTile extends THREE.Object3D {
|
|
|
535
538
|
}
|
|
536
539
|
self.materialVisibility = visibility
|
|
537
540
|
|
|
538
|
-
self.meshDisplayed =
|
|
541
|
+
self.meshDisplayed = true;
|
|
539
542
|
if (!!self.meshContent.traverse) {
|
|
540
543
|
self.meshContent.traverse(function (element) {
|
|
541
544
|
if (element.material) setMeshVisibility(element, visibility);
|
|
@@ -65,6 +65,7 @@ class InstancedTile extends THREE.Object3D {
|
|
|
65
65
|
this.level = properties.level ? properties.level : 0;
|
|
66
66
|
this.hasMeshContent = false; // true when the provided json has a content field pointing to a B3DM file
|
|
67
67
|
this.hasUnloadedJSONContent = false; // true when the provided json has a content field pointing to a JSON file that is not yet loaded
|
|
68
|
+
this.centerModel = properties.centerModel;
|
|
68
69
|
|
|
69
70
|
this.deleted = false;
|
|
70
71
|
this.abortController = new AbortController();
|
|
@@ -82,7 +83,7 @@ class InstancedTile extends THREE.Object3D {
|
|
|
82
83
|
//json = JSON.parse(JSON.stringify(json))
|
|
83
84
|
const p = path.dirname(url);
|
|
84
85
|
self.setup({ rootPath: p, json: json });
|
|
85
|
-
if (!!
|
|
86
|
+
if (!!self.centerModel) {
|
|
86
87
|
const tempSphere = new THREE.Sphere();
|
|
87
88
|
if (self.boundingVolume instanceof OBB) {
|
|
88
89
|
// box
|
|
@@ -155,7 +156,7 @@ class InstancedTile extends THREE.Object3D {
|
|
|
155
156
|
this.geometricError = properties.parentGeometricError;
|
|
156
157
|
}
|
|
157
158
|
// decode transform
|
|
158
|
-
if (!!this.json.transform) {
|
|
159
|
+
if (!!this.json.transform && !this.centerModel) {
|
|
159
160
|
let mat = new THREE.Matrix4();
|
|
160
161
|
mat.elements = this.json.transform;
|
|
161
162
|
this.master.applyMatrix4(mat);
|
|
@@ -374,7 +375,8 @@ class InstancedTile extends THREE.Object3D {
|
|
|
374
375
|
level: self.level + 1,
|
|
375
376
|
tileLoader: self.tileLoader,
|
|
376
377
|
cameraOnLoad: camera,
|
|
377
|
-
master: self.master
|
|
378
|
+
master: self.master,
|
|
379
|
+
centerModel: false
|
|
378
380
|
});
|
|
379
381
|
self.childrenTiles.push(childTile);
|
|
380
382
|
//self.add(childTile);
|