@jdultra/threedtiles 11.1.7 → 11.1.9
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/dist/docs/InstancedOGC3DTile.html +3 -0
- package/dist/docs/InstancedTile.html +3 -0
- package/dist/docs/InstancedTileLoader.html +3 -0
- package/dist/docs/OGC3DTile.html +3 -0
- package/dist/docs/OGC3DTile.js.html +1451 -0
- package/dist/docs/OcclusionCullingService.html +3 -0
- package/dist/docs/OcclusionCullingService.js.html +84 -0
- package/dist/docs/TileLoader.html +3 -0
- package/dist/docs/TileLoader.js.html +550 -0
- package/dist/docs/data/search.json +1 -0
- package/dist/docs/fonts/Inconsolata-Regular.ttf +0 -0
- package/dist/docs/fonts/OpenSans-Regular.ttf +0 -0
- package/dist/docs/fonts/WorkSans-Bold.ttf +0 -0
- package/dist/docs/global.html +3 -0
- package/dist/docs/index.html +338 -0
- package/dist/docs/instanced_InstancedOGC3DTile.js.html +106 -0
- package/dist/docs/instanced_InstancedTile.js.html +701 -0
- package/dist/docs/instanced_InstancedTileLoader.js.html +497 -0
- package/dist/docs/scripts/core.js +726 -0
- package/dist/docs/scripts/core.min.js +23 -0
- package/dist/docs/scripts/resize.js +90 -0
- package/dist/docs/scripts/search.js +265 -0
- package/dist/docs/scripts/search.min.js +6 -0
- package/dist/docs/scripts/third-party/Apache-License-2.0.txt +202 -0
- package/dist/docs/scripts/third-party/fuse.js +9 -0
- package/dist/docs/scripts/third-party/hljs-line-num-original.js +369 -0
- package/dist/docs/scripts/third-party/hljs-line-num.js +1 -0
- package/dist/docs/scripts/third-party/hljs-original.js +5171 -0
- package/dist/docs/scripts/third-party/hljs.js +1 -0
- package/dist/docs/scripts/third-party/popper.js +5 -0
- package/dist/docs/scripts/third-party/tippy.js +1 -0
- package/dist/docs/scripts/third-party/tocbot.js +672 -0
- package/dist/docs/scripts/third-party/tocbot.min.js +1 -0
- package/dist/docs/styles/clean-jsdoc-theme-base.css +1159 -0
- package/dist/docs/styles/clean-jsdoc-theme-dark.css +412 -0
- package/dist/docs/styles/clean-jsdoc-theme-light.css +482 -0
- package/dist/docs/styles/clean-jsdoc-theme-scrollbar.css +30 -0
- package/dist/docs/styles/clean-jsdoc-theme-without-scrollbar.min.css +1 -0
- package/dist/docs/styles/clean-jsdoc-theme.min.css +1 -0
- package/dist/entry.d.ts +1 -1
- package/dist/threedtiles.min.js +1 -1
- package/dist/threedtiles.min.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
<!DOCTYPE html><html lang="en" style="font-size:16px"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Home</title><!--[if lt IE 9]>
|
|
2
|
+
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
|
3
|
+
<![endif]--><script src="scripts/third-party/hljs.js" defer="defer"></script><script src="scripts/third-party/hljs-line-num.js" defer="defer"></script><script src="scripts/third-party/popper.js" defer="defer"></script><script src="scripts/third-party/tippy.js" defer="defer"></script><script src="scripts/third-party/tocbot.min.js"></script><script>var baseURL="/",locationPathname="";baseURL=(locationPathname=document.location.pathname).substr(0,locationPathname.lastIndexOf("/")+1)</script><link rel="stylesheet" href="styles/clean-jsdoc-theme.min.css"><svg aria-hidden="true" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="display:none"><defs><symbol id="copy-icon" viewbox="0 0 488.3 488.3"><g><path d="M314.25,85.4h-227c-21.3,0-38.6,17.3-38.6,38.6v325.7c0,21.3,17.3,38.6,38.6,38.6h227c21.3,0,38.6-17.3,38.6-38.6V124 C352.75,102.7,335.45,85.4,314.25,85.4z M325.75,449.6c0,6.4-5.2,11.6-11.6,11.6h-227c-6.4,0-11.6-5.2-11.6-11.6V124 c0-6.4,5.2-11.6,11.6-11.6h227c6.4,0,11.6,5.2,11.6,11.6V449.6z"/><path d="M401.05,0h-227c-21.3,0-38.6,17.3-38.6,38.6c0,7.5,6,13.5,13.5,13.5s13.5-6,13.5-13.5c0-6.4,5.2-11.6,11.6-11.6h227 c6.4,0,11.6,5.2,11.6,11.6v325.7c0,6.4-5.2,11.6-11.6,11.6c-7.5,0-13.5,6-13.5,13.5s6,13.5,13.5,13.5c21.3,0,38.6-17.3,38.6-38.6 V38.6C439.65,17.3,422.35,0,401.05,0z"/></g></symbol><symbol id="search-icon" viewBox="0 0 512 512"><g><g><path d="M225.474,0C101.151,0,0,101.151,0,225.474c0,124.33,101.151,225.474,225.474,225.474 c124.33,0,225.474-101.144,225.474-225.474C450.948,101.151,349.804,0,225.474,0z M225.474,409.323 c-101.373,0-183.848-82.475-183.848-183.848S124.101,41.626,225.474,41.626s183.848,82.475,183.848,183.848 S326.847,409.323,225.474,409.323z"/></g></g><g><g><path d="M505.902,476.472L386.574,357.144c-8.131-8.131-21.299-8.131-29.43,0c-8.131,8.124-8.131,21.306,0,29.43l119.328,119.328 c4.065,4.065,9.387,6.098,14.715,6.098c5.321,0,10.649-2.033,14.715-6.098C514.033,497.778,514.033,484.596,505.902,476.472z"/></g></g></symbol><symbol id="font-size-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M11.246 15H4.754l-2 5H.6L7 4h2l6.4 16h-2.154l-2-5zm-.8-2L8 6.885 5.554 13h4.892zM21 12.535V12h2v8h-2v-.535a4 4 0 1 1 0-6.93zM19 18a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"/></symbol><symbol id="add-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"/></symbol><symbol id="minus-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M5 11h14v2H5z"/></symbol><symbol id="dark-theme-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M10 7a7 7 0 0 0 12 4.9v.1c0 5.523-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2h.1A6.979 6.979 0 0 0 10 7zm-6 5a8 8 0 0 0 15.062 3.762A9 9 0 0 1 8.238 4.938 7.999 7.999 0 0 0 4 12z"/></symbol><symbol id="light-theme-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 18a6 6 0 1 1 0-12 6 6 0 0 1 0 12zm0-2a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM11 1h2v3h-2V1zm0 19h2v3h-2v-3zM3.515 4.929l1.414-1.414L7.05 5.636 5.636 7.05 3.515 4.93zM16.95 18.364l1.414-1.414 2.121 2.121-1.414 1.414-2.121-2.121zm2.121-14.85l1.414 1.415-2.121 2.121-1.414-1.414 2.121-2.121zM5.636 16.95l1.414 1.414-2.121 2.121-1.414-1.414 2.121-2.121zM23 11v2h-3v-2h3zM4 11v2H1v-2h3z"/></symbol><symbol id="reset-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M18.537 19.567A9.961 9.961 0 0 1 12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10c0 2.136-.67 4.116-1.81 5.74L17 12h3a8 8 0 1 0-2.46 5.772l.997 1.795z"/></symbol><symbol id="down-icon" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M12.7803 6.21967C13.0732 6.51256 13.0732 6.98744 12.7803 7.28033L8.53033 11.5303C8.23744 11.8232 7.76256 11.8232 7.46967 11.5303L3.21967 7.28033C2.92678 6.98744 2.92678 6.51256 3.21967 6.21967C3.51256 5.92678 3.98744 5.92678 4.28033 6.21967L8 9.93934L11.7197 6.21967C12.0126 5.92678 12.4874 5.92678 12.7803 6.21967Z"></path></symbol><symbol id="codepen-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M16.5 13.202L13 15.535v3.596L19.197 15 16.5 13.202zM14.697 12L12 10.202 9.303 12 12 13.798 14.697 12zM20 10.869L18.303 12 20 13.131V10.87zM19.197 9L13 4.869v3.596l3.5 2.333L19.197 9zM7.5 10.798L11 8.465V4.869L4.803 9 7.5 10.798zM4.803 15L11 19.131v-3.596l-3.5-2.333L4.803 15zM4 13.131L5.697 12 4 10.869v2.262zM2 9a1 1 0 0 1 .445-.832l9-6a1 1 0 0 1 1.11 0l9 6A1 1 0 0 1 22 9v6a1 1 0 0 1-.445.832l-9 6a1 1 0 0 1-1.11 0l-9-6A1 1 0 0 1 2 15V9z"/></symbol><symbol id="close-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z"/></symbol><symbol id="menu-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M3 4h18v2H3V4zm0 7h18v2H3v-2zm0 7h18v2H3v-2z"/></symbol></defs></svg></head><body data-theme="dark"><div class="sidebar-container"><div class="sidebar" id="sidebar"><div class="sidebar-items-container"><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-classes"><div>Classes</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="InstancedOGC3DTile.html">InstancedOGC3DTile</a></div><div class="sidebar-section-children"><a href="InstancedTile.html">InstancedTile</a></div><div class="sidebar-section-children"><a href="InstancedTileLoader.html">InstancedTileLoader</a></div><div class="sidebar-section-children"><a href="OGC3DTile.html">OGC3DTile</a></div><div class="sidebar-section-children"><a href="OcclusionCullingService.html">OcclusionCullingService</a></div><div class="sidebar-section-children"><a href="TileLoader.html">TileLoader</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-global"><div>Global</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="global.html#getOGC3DTilesCopyrightInfo">getOGC3DTilesCopyrightInfo</a></div></div></div></div></div><div class="navbar-container" id="VuAckcnZhf"><nav class="navbar"><div class="navbar-left-items"></div><div class="navbar-right-items"><div class="navbar-right-item"><button class="icon-button search-button" aria-label="open-search"><svg><use xlink:href="#search-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button theme-toggle" aria-label="toggle-theme"><svg><use class="theme-svg-use" xlink:href="#light-theme-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button font-size" aria-label="change-font-size"><svg><use xlink:href="#font-size-icon"></use></svg></button></div></div><nav></nav></nav></div><div class="toc-container"><div class="toc-content"><span class="bold">On this page</span><div id="eed4d2a0bfd64539bb9df78095dec881"></div></div></div><div class="body-wrapper"><div class="main-content"><div class="main-wrapper"><section class="readme"><article><p><a href="https://npmjs.com/package/@jdultra/threedtiles"><img src="https://img.shields.io/npm/v/@jdultra/threedtiles?style=flat&colorA=000000&colorB=000000" alt="Version"></a><a href="https://npmjs.com/package/@jdultra/threedtiles"><img src="https://img.shields.io/npm/dt/@jdultra/threedtiles.svg?style=flat&colorA=000000&colorB=000000" alt="Downloads"></a></p><h1 id="t-h-r-e-e-d-t-i-l-e-s-%3A-http%3A%2F%2Fwww.jdultra.com%2F">T H R E E D T I L E S : http://www.jdultra.com/</h1><p>A faster 3DTiles viewer for three.js, now with OGC3DTiles 1.1 support</p><h2 id="sample-getting-started-projects">sample getting started projects</h2><p><a href="https://drive.google.com/file/d/14lipb5eUqfad-n7EUgXuXul-drPdLifV/view?usp=sharing">Getting started vanilla js</a></p><p><a href="https://drive.google.com/file/d/1C102qriCsnra9EUbb8WzO4jZStp-eEah/view?usp=sharing">Getting started react-three-fiber</a></p><h2 id="demos">Demos</h2><p><a href="https://www.jdultra.com/overlay/index.html">Google Tiles overlay</a> overlay high quality meshes over google tiles with some shader magic to avoid overlap</p><p><a href="https://github.com/ebeaufay/desktop-3dtiles-viewer">Windows desktop viewer</a> A viewer for windows based on flutter and this library</p><p><a href="https://www.jdultra.com/google-tiles/index.html">Google Map Tile API</a> google tiles in a geospatial framework <a href="https://github.com/ebeaufay/UltraGlobe">ULTRAGLOBE</a></p><p><a href="https://ebeaufay.github.io/ThreedTilesViewer.github.io/">Photogrametry</a> Some tiles converted from OBJ via proprietary ULTRAMESH tool</p><p><a href="https://www.jdultra.com/pointmeshing/index.html">Point cloud vs Mesh</a></p><p><a href="https://www.jdultra.com/pbr/">PBR material (GlTF conversion)</a></p><p><a href="https://www.jdultra.com/occlusion/index.html">Occlusion culling (IFC conversion)</a> Occlusion culling applied at the tile-loading level. This isn't just GPU occlusion culling, hidden tiles aren't even downloaded.</p><p><a href="https://www.jdultra.com/instanced/index.html">Instanced Tileset</a> A multitude of identical meshes, each with its own LOD hiearchy but duplicate tiles are instanced</p><h2 id="getting-started">Getting started</h2><h3 id="doc">DOC</h3><p><a href="https://www.jdultra.com/threedtiles/docs/">JSDOC</a></p><p>install the library:</p><pre class="prettyprint source"><code>npm install three @jdultra/threedtiles
|
|
4
|
+
</code></pre><p>Adding a tileset to a scene is as easy as :</p><pre class="prettyprint source"><code>import { OGC3DTile } from '@jdultra/threedtiles';
|
|
5
|
+
|
|
6
|
+
...
|
|
7
|
+
|
|
8
|
+
const ogc3DTile = new OGC3DTile({
|
|
9
|
+
url: "https://storage.googleapis.com/ogc-3d-tiles/ayutthaya/tileset.json",
|
|
10
|
+
renderer: renderer
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
scene.add(ogc3DTile);
|
|
14
|
+
</code></pre><p>It's up to the user to call updates on the tileset.</p><pre class="prettyprint source"><code>function animate() {
|
|
15
|
+
requestAnimationFrame(animate);
|
|
16
|
+
|
|
17
|
+
ogc3DTile.update(camera); // computes what tiles need to be refined and what tiles can be disposed.
|
|
18
|
+
ogc3DTile.tileLoader.update(); // downloads, loads and caches tiles in optimal order.
|
|
19
|
+
|
|
20
|
+
...
|
|
21
|
+
|
|
22
|
+
}
|
|
23
|
+
</code></pre><p>It is discouraged to call the update functions outside the render loop in a setInterval for example. While that may work fine on desktop, mobile browsers tend to block an entire frame when a timeout triggers in it.</p><h2 id="mesh-to-3dtiles-converter">Mesh to 3DTiles Converter</h2><p>If you need to convert meshes to 3DTiles, from small assets to gigabytes of data, contact me for a trial on UltraMesh tool. It works for all types of meshes: photogrametry, BIM, colored or textured meshes with a single texture atlas or many individual textures. There's support for OBJ, IFC, Collada and glTF meshes and las/laz point clouds. I aim for optimal quality in terms of mesh, texture and tileset structure and for optimal streaming speed, with no limit to the size of the input data. Contact: emeric.beaufays@jdultra.com</p><h2 id="features">Features</h2><ul><li>Handles nested tileset.json files which are loaded on the fly (a tileset.json may point to another tileset.json file as its child).</li><li>Allows tilesets transformations. Translate, scale and rotate a tilesets in real-time.</li><li>callback on loaded geometry to assign a custom material or use the meshes for computations.</li><li>Optionally load low detail tiles outside of view frustum for correct shadows and basic mesh present when the camera moves quickly.</li><li>Share a cache between tileset instances</li><li>Optimal tile load order</li><li>Occlusion culling</li><li>Instanced tilesets</li><li>Center tileset and re-orient geolocated data</li><li>quantization, draco, mshopt and ktx2 compression support</li><li>point clouds (only through gltf/glb tiles)</li><li>loading strategy options ("incremental" or "immediate")</li></ul><p>OGC3DTiles 1.1 are supported. There is no plan to support .pnts, .i3dm or .cmpt tiles as these formats are deprecated in favor of glb/gltf tiles.</p><h3 id="geometric-error-multiplier">geometric Error Multiplier</h3><p>The geometric error multiplier allows you to multiply the geometric error by a factor.</p><pre class="prettyprint source"><code>tileset.setGeometricErrorMultiplier(1.5);
|
|
24
|
+
</code></pre><p>you may also set this value at initialization:</p><pre class="prettyprint source"><code>const ogc3DTile = new OGC3DTile({
|
|
25
|
+
url: "https://storage.googleapis.com/ogc-3d-tiles/ayutthaya/tileset.json",
|
|
26
|
+
renderer: renderer,
|
|
27
|
+
geometricErrorMultiplier: 2.0
|
|
28
|
+
});
|
|
29
|
+
</code></pre><p>A lower value will result in lower detail tiles being loaded and a higher value results in higher detail tiles being loaded. A value of 1.0 is the default.</p><h4 id="geometricerrormultiplier-vs-maxscreenspaceerror">geometricErrorMultiplier vs maxScreenSpaceError</h4><p>Many viewers use the maxScreenSpaceError instead of a geometric error multiplier and there is a direct correspondance. A geometricErrorMultiplier of 1 corresponds to a maxScreenSpaceError of 16. A geometricErrorMultiplier of 0.5 corresponds to a maxScreenSpaceError of 32.</p><h4 id="distance-bias">distance bias</h4><p>The distance bias allows loading more or less detail close to the camera relative to further away. The distance bias simply applies an exponent on tile distance to the camera so you have to balance it out manually with the geometricErrorMultiplier.</p><p>For example, if you want to load more detail close to the camera, you might do something like this:</p><pre class="prettyprint source"><code>const ogc3DTile = new OGC3DTile({
|
|
30
|
+
url: "https://storage.googleapis.com/ogc-3d-tiles/ayutthaya/tileset.json",
|
|
31
|
+
renderer: renderer,
|
|
32
|
+
geometricErrorMultiplier: 10.0,
|
|
33
|
+
distanceBias: 1.5
|
|
34
|
+
});
|
|
35
|
+
</code></pre><p>In this case the higher distance bias will cause less detail to be loaded overall since all calculated distances get raised to the power 1.5. To compensate, the geometricErrorMultiplier is set at a higher value.</p><p>These values need to be adjusted manually based on what is considered relatively close or far from the camera and truly depends on your scene and the relative distance of the camera to the tiles during normal navigation. In other words, it's impossible to have magic bullet values the LOD switch distance can be fine-tuned through those parameters.</p><p>You can change the distance bias for a tileset at any time:</p><pre class="prettyprint source"><code>tileset.setDistanceBias(1.5);
|
|
36
|
+
</code></pre><h3 id="loading-strategy">loading strategy</h3><h4 id="incremental">Incremental</h4><p>Incremental loading is the default and loads all intermediate levels incrementally and keeps them in memory. While this gives a direct feedback on loading progress, the CPU memory footprint is large and overall loading speed is slower than with "immediate" mode.</p><p>To explicitely set the incremental loading strategy:</p><pre class="prettyprint source"><code>const ogc3DTile = new OGC3DTile({
|
|
37
|
+
url: "https://storage.googleapis.com/ogc-3d-tiles/ayutthaya/tileset.json",
|
|
38
|
+
renderer: renderer,
|
|
39
|
+
loadingStrategy: "INTERMEDIATE"
|
|
40
|
+
});
|
|
41
|
+
</code></pre><h4 id="immediate">Immediate</h4><p>Immediate loading skips intermediate LODs and immediately loads the ideal LOD. Less data is downloaded (faster load time) and less data is kept in CPU memory but holes will appear until the tiles are loaded.</p><p>To set the immediate loading strategy:</p><pre class="prettyprint source"><code>const ogc3DTile = new OGC3DTile({
|
|
42
|
+
url: "https://storage.googleapis.com/ogc-3d-tiles/ayutthaya/tileset.json",
|
|
43
|
+
renderer: renderer,
|
|
44
|
+
loadingStrategy: "IMMEDIATE"
|
|
45
|
+
});
|
|
46
|
+
</code></pre><h3 id="load-tiles-outside-of-view">load tiles outside of view</h3><p>By default, only the tiles that intersect the view frustum are loaded. When the camera moves, the scene will have to load the missing tiles and the user might see some holes in the model. Instead of this behaviour, you can force the lowest possible LODs to be loaded for tiles outside the view so that there are no gaps in the mesh when the camera moves. This also allows displaying shadows from parts of the scene that are not in the view.</p><pre class="prettyprint source"><code>const ogc3DTile = new OGC3DTile({
|
|
47
|
+
url: "https://storage.googleapis.com/ogc-3d-tiles/ayutthaya/tileset.json",
|
|
48
|
+
renderer: renderer,
|
|
49
|
+
loadOutsideView: true
|
|
50
|
+
});
|
|
51
|
+
</code></pre><h3 id="draw-bounding-volume">draw bounding volume</h3><p>Draw bounding volumes around visible tiles</p><pre class="prettyprint source"><code>const ogc3DTile = new OGC3DTile({
|
|
52
|
+
url: "https://storage.googleapis.com/ogc-3d-tiles/ayutthaya/tileset.json",
|
|
53
|
+
renderer: renderer,
|
|
54
|
+
drawBoundingVolume: true
|
|
55
|
+
});
|
|
56
|
+
</code></pre><h3 id="google-maps-3d-tiles">Google Maps 3D Tiles</h3><p>Google maps 3DTiles can be loaded similarly. The API key mechanism requires that a token be passed as a query param to all fetched tiles.</p><pre class="prettyprint source"><code>const ogc3DTile = new OGC3DTile({
|
|
57
|
+
url: "https://tile.googleapis.com/v1/3dtiles/root.json",
|
|
58
|
+
queryParams: { key: "Insert your own google maps API key here" },
|
|
59
|
+
yUp: false, // this value is normally true by default
|
|
60
|
+
renderer: renderer,
|
|
61
|
+
loadOutsideView: true
|
|
62
|
+
});
|
|
63
|
+
</code></pre><h4 id="copyright-info">Copyright info</h4><p>This is mostly specific to google tiles but may be used by other vendors.</p><p>Google requires that, copyright info for producers of the 3D data be displayed. A global function #getOGC3DTilesCopyrightInfo returns the list of vendors that need to be displayed.</p><pre class="prettyprint source"><code>import { OGC3DTile, getOGC3DTilesCopyrightInfo } from "./tileset/OGC3DTile";
|
|
64
|
+
|
|
65
|
+
...
|
|
66
|
+
|
|
67
|
+
animate(){
|
|
68
|
+
requestAnimationFrame( animate );
|
|
69
|
+
googleTiles.update(camera);
|
|
70
|
+
tileLoader.update();
|
|
71
|
+
...
|
|
72
|
+
console.log(getOGC3DTilesCopyrightInfo());
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
</code></pre><h3 id="callback">Callback</h3><h4 id="onloadcallback">onLoadCallback</h4><p>Add a callback that is called once when the first tile is loaded and geometry is available. This can be useful to position the tileset at a specific location when it is not centered on origin for example.</p><pre class="prettyprint source"><code>const ogc3DTile = new OGC3DTile({
|
|
76
|
+
url: "https://storage.googleapis.com/ogc-3d-tiles/ayutthaya/tileset.json",
|
|
77
|
+
renderer: renderer,
|
|
78
|
+
onLoadCallback: tileset => {
|
|
79
|
+
console.log(tileset.json.boundingVolume);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
</code></pre><p>Note that the callback is called with the OGC3DTile object as parameter and that this object has a "json" property giving you access to the original tileset.json with it's transform, geometric error, bounding volume, etc...</p><h4 id="mesh-callback">Mesh callback</h4><p>Add a callback on loaded tiles in order to set a material or do some logic on the meshes.</p><pre class="prettyprint source"><code>const ogc3DTile = new OGC3DTile({
|
|
83
|
+
url: "https://storage.googleapis.com/ogc-3d-tiles/ayutthaya/tileset.json",
|
|
84
|
+
renderer: renderer,
|
|
85
|
+
meshCallback: mesh => {
|
|
86
|
+
mesh.material.wireframe = true;
|
|
87
|
+
mesh.material.side = THREE.DoubleSide;
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
</code></pre><h4 id="update">Update</h4><p>Calling OGC3DTile#update gives a direct feedback on the state of the tileset:</p><pre class="prettyprint source"><code>function animate() {
|
|
91
|
+
requestAnimationFrame(animate);
|
|
92
|
+
|
|
93
|
+
ogc3DTile.update(camera); // computes what tiles need to be refined and what tiles can be disposed.
|
|
94
|
+
const state = ogc3DTile.tileLoader.update(); // downloads, loads and caches tiles in optimal order.
|
|
95
|
+
}
|
|
96
|
+
</code></pre><p>In the example above, the "state" object may look like this:</p><pre class="prettyprint source"><code>{
|
|
97
|
+
numTilesLoaded: 82,
|
|
98
|
+
numTilesRendered: 82,
|
|
99
|
+
maxLOD: 9,
|
|
100
|
+
percentageLoaded: 1
|
|
101
|
+
}
|
|
102
|
+
</code></pre><ul><li>"numTilesLoaded" gives the number of tiles in the tileset that are loaded and should be visible (including intermediate LODs for the "incremental" loading strategy).</li><li>"numTilesRendered gives the number of tiles currently rendered.</li><li>"maxLOD" highest LOD currently rendered</li><li>"percentageLoaded" property gives an indication of the loading progress. Note that the loading progress may go back and forth a bit while the tree is being expanded but a value of 1 means the tileset is loaded.</li></ul><h4 id="points-callback">Points callback</h4><p>Add a callback on loaded point tiles in order to set a material or do some logic on the points.</p><pre class="prettyprint source"><code>const ogc3DTile = new OGC3DTile({
|
|
103
|
+
url: "https://storage.googleapis.com/ogc-3d-tiles/ayutthaya/tileset.json",
|
|
104
|
+
renderer: renderer,
|
|
105
|
+
pointsCallback: points => {
|
|
106
|
+
points.material.size = 0.1;
|
|
107
|
+
points.material.sizeAttenuation = true;
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
</code></pre><p>If using a shared cache between tilesets, check out the next section.</p><h3 id="cache-and-tileloader">Cache and TileLoader</h3><p>The Tile loader handles the loading strategy, managing a cache and the order for tile downloads and loads.</p><p>You may re-use the Tile loader for several or all your tilesets. The limitation is that all the tilesets using the same TileLoader will have the same mesh/points callback.</p><p>The TileLoader takes an optional object as argument: @param {Object} [options] - Optional configuration object. @param {number} [options.maxCachedItems=100] - the cache size. @param {function} [options.meshCallback] - A callback to call on newly decoded meshes. @param {function} [options.pointsCallback] - A callback to call on newly decoded points. @param {renderer} [options.renderer] - The renderer, this is required for KTX2 support.</p><pre class="prettyprint source"><code>import { TileLoader } from '@jdultra/threedtiles';
|
|
111
|
+
|
|
112
|
+
const tileLoader = new TileLoader({
|
|
113
|
+
renderer: renderer,
|
|
114
|
+
maxCachedItems: 100,
|
|
115
|
+
meshCallback: (mesh, geometricError) => {
|
|
116
|
+
//// Insert code to be called on every newly decoded mesh e.g.:
|
|
117
|
+
mesh.material.wireframe = false;
|
|
118
|
+
mesh.material.side = THREE.DoubleSide;
|
|
119
|
+
//mesh.material.metalness = 0.0
|
|
120
|
+
},
|
|
121
|
+
pointsCallback: (points, geometricError) => {
|
|
122
|
+
points.material.size = Math.min(1.0, 0.5 * Math.sqrt(geometricError));
|
|
123
|
+
points.material.sizeAttenuation = true;
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
const ogc3DTile1 = new OGC3DTile({
|
|
127
|
+
url: "...",
|
|
128
|
+
renderer: renderer,
|
|
129
|
+
tileLoader: tileLoader,
|
|
130
|
+
meshCallback: mesh => { mesh.material.wireframe = true;} // This callback will not be used as the callback provided to the TileLoader takes priority
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const ogc3DTile2 = new OGC3DTile({
|
|
134
|
+
url: "...",
|
|
135
|
+
renderer: renderer,
|
|
136
|
+
tileLoader: tileLoader
|
|
137
|
+
});
|
|
138
|
+
</code></pre><p>If you use the same tile loader for several tilesets, you can call update on it just once per frame:</p><pre class="prettyprint source"><code>function animate() {
|
|
139
|
+
requestAnimationFrame(animate);
|
|
140
|
+
|
|
141
|
+
ogc3DTile1.update(camera);
|
|
142
|
+
ogc3DTile2.update(camera);
|
|
143
|
+
tileLoader.update(); // important! since v10
|
|
144
|
+
|
|
145
|
+
...
|
|
146
|
+
|
|
147
|
+
}
|
|
148
|
+
</code></pre><h3 id="transformations">Transformations</h3><p>The OGC 3DTile object is a regular three.js Object3D so it can be transformed via the standard three.js API:</p><pre class="prettyprint source"><code>const ogc3DTile = new OGC3DTile({
|
|
149
|
+
url: "https://ebeaufay.github.io/ThreedTilesViewer.github.io/momoyama/tileset.json"
|
|
150
|
+
renderer: renderer,
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
ogc3DTile.translateOnAxis(new THREE.Vector3(0,1,0), -450);
|
|
154
|
+
ogc3DTile.rotateOnAxis(new THREE.Vector3(1,0,0), -Math.PI*0.5);
|
|
155
|
+
</code></pre><h3 id="occlusion-culling">Occlusion culling</h3><p>Occlusion culling prevents the refinment of data that is hidden by other data, like a wall. It can have a big impact on frame-rate and loading speed for interior scenes.</p><p>A word of warning: activating occlusion culling has an impact on frame-rate. It will be most beneficial on interior scenes where most of the data is occluded by walls. All the tiles that don't need to be downloaded or drawn will balance out the cost of the occlusion logic.</p><p>First, instantiate an OcclusionCullingService:</p><pre class="prettyprint source"><code>import { OcclusionCullingService } from '@jdultra/threedtiles';
|
|
156
|
+
|
|
157
|
+
const occlusionCullingService = new OcclusionCullingService();
|
|
158
|
+
</code></pre><p>This service must be passed to every OGC3DTiles object like so:</p><pre class="prettyprint source"><code>const ogc3DTile = new OGC3DTile({
|
|
159
|
+
url: "path/to/tileset.json",
|
|
160
|
+
renderer: renderer,
|
|
161
|
+
occlusionCullingService: occlusionCullingService
|
|
162
|
+
});
|
|
163
|
+
</code></pre><p>Then, you must update the occlusionCullingService within your render loop:</p><pre class="prettyprint source"><code>function animate() {
|
|
164
|
+
ogc3DTile.update(camera);
|
|
165
|
+
ogc3DTile.tileLoader.update();
|
|
166
|
+
requestAnimationFrame(animate);
|
|
167
|
+
renderer.render(scene, camera);
|
|
168
|
+
occlusionCullingService.update(scene, renderer, camera)
|
|
169
|
+
}
|
|
170
|
+
</code></pre><p>Finally, if you are drawing the back-side of faces or both-sides (see Callback section), you'll need to specify it for the occlusion pass too. By default, THREE.FrontSide is used:</p><pre class="prettyprint source"><code>const occlusionCullingService = new OcclusionCullingService();
|
|
171
|
+
occlusionCullingService.setSide(THREE.DoubleSide);
|
|
172
|
+
</code></pre><h3 id="instanced-tilesets">Instanced Tilesets</h3><p align="center"><img src="https://storage.googleapis.com/jdultra-website/assets/instancedPic.png" width="800" style="display:block;margin:0 auto"></p><p>Using InstancedTileLoader and InstancedOGC3DTile allows displaying the same Tileset at many different places with little impact on performance. Each Tileset is independent in terms of it's position, orientation and level of detail but each tile is created as an "InstancedMesh" giving much higher performance when displaying the same Tileset many times.</p><pre class="prettyprint source"><code>import { InstancedOGC3DTile, InstancedTileLoader } from '@jdultra/threedtiles';
|
|
173
|
+
|
|
174
|
+
// First create the InstancedTileLoader that will manage caching
|
|
175
|
+
const instancedTileLoader = new InstancedTileLoader(
|
|
176
|
+
scene,
|
|
177
|
+
{
|
|
178
|
+
renderer: renderer,
|
|
179
|
+
maxCachedItems : 100,
|
|
180
|
+
maxInstances : 1,
|
|
181
|
+
meshCallback: mesh => {
|
|
182
|
+
//// Insert code to be called on every newly decoded mesh e.g.:
|
|
183
|
+
mesh.material.wireframe = false;
|
|
184
|
+
mesh.material.side = THREE.DoubleSide;
|
|
185
|
+
},
|
|
186
|
+
pointsCallback: points => {
|
|
187
|
+
points.material.size = Math.min(1.0, 0.5 * Math.sqrt(points.geometricError));
|
|
188
|
+
points.material.sizeAttenuation = true;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
// then create some tilesets
|
|
194
|
+
const instancedTilesets = [];
|
|
195
|
+
for (let i = 0; i < 100; i++) {
|
|
196
|
+
const tileset = new InstancedOGC3DTile({
|
|
197
|
+
url: "https://storage.googleapis.com/ogc-3d-tiles/droneship/tileset.json",
|
|
198
|
+
renderer: renderer,
|
|
199
|
+
geometricErrorMultiplier: 1.0,
|
|
200
|
+
loadOutsideView: false,
|
|
201
|
+
tileLoader: instancedTileLoader,
|
|
202
|
+
static: true // when static is set to true, you must call InstancedOGC3DTile#updateMatrix manually
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
tileset.translateOnAxis(new THREE.Vector3(1, 0, 0), 50 * i);
|
|
206
|
+
tileset.updateMatrices(); // important when static property is true (different from the Object3D#updateMatrix API)
|
|
207
|
+
scene.add(tileset);
|
|
208
|
+
instancedTilesets.push(tileset);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
//setup an update loop for the LODs
|
|
212
|
+
setInterval(() => {
|
|
213
|
+
instancedTilesets[updateIndex].update(camera);
|
|
214
|
+
updateIndex= (updateIndex+1)%instancedTilesets.length;
|
|
215
|
+
},50);
|
|
216
|
+
|
|
217
|
+
//in the animate function, you also need to update the instancedTileLoader
|
|
218
|
+
function animate() {
|
|
219
|
+
requestAnimationFrame(animate);
|
|
220
|
+
instancedTileLoader.update();
|
|
221
|
+
|
|
222
|
+
... // rest of render loop
|
|
223
|
+
}
|
|
224
|
+
animate();
|
|
225
|
+
|
|
226
|
+
</code></pre><h3 id="center-tileset-and-re-orient-geolocated-data">Center tileset and re-orient geolocated data</h3><p>OGC3DTiles data is not necessarily centered on the origin and when it's georeferenced, it's also rotated relative to the cartesian coordinate system. The optional property "centerModel" will center the model on the origin. In the case of georeferenced models, identified as those using the "region" bounding volume, it will also rotate it so that it's up-axis alligns with the y axis.</p><pre class="prettyprint source"><code>const ogc3DTile = new OGC3DTile({
|
|
227
|
+
url: "https://storage.googleapis.com/ogc-3d-tiles/ayutthaya/tileset.json",
|
|
228
|
+
renderer: renderer,
|
|
229
|
+
centerModel:true
|
|
230
|
+
});
|
|
231
|
+
</code></pre><p>This property is also available for instanced models.</p><h3 id="performance-tips">Performance tips</h3><h4 id="static-tilesets">static tilesets</h4><p>When you know your tileset will be static or move rarely, you can specify it in the OGC3DTile object constructor parameter. This will skip recalculating the transformation matrix of every tile each frame and give a few extra frames per second.</p><p>However, you'll need to manually call #updateMatrix and #updateMatrixWorld on the OGC3DTile object whenever you apply a transformation.</p><pre class="prettyprint source"><code>const ogc3DTile = new OGC3DTile({
|
|
232
|
+
url: "path/to/tileset.json",
|
|
233
|
+
renderer: renderer,
|
|
234
|
+
static: true
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
setTimeout(()=>{
|
|
238
|
+
|
|
239
|
+
ogc3DTile.rotateOnAxis(new THREE.Vector3(1, 0, 0), Math.PI * -0.5);
|
|
240
|
+
ogc3DTile.updateMatrices(); // different from the Object3D#updateMatrix API
|
|
241
|
+
},1000)
|
|
242
|
+
</code></pre><p>For InstancedOGC3DTile objects, You need to call instancedOgc3DTile#updateMatrix() and the gains will be much less significant.</p><pre class="prettyprint source"><code>const ogc3DTile = new InstancedOGC3DTile({
|
|
243
|
+
...
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
setTimeout(()=>{
|
|
247
|
+
ogc3DTile.rotateOnAxis(new THREE.Vector3(1, 0, 0), Math.PI * -0.5);
|
|
248
|
+
ogc3DTile.updateMatrix();
|
|
249
|
+
},1000)
|
|
250
|
+
</code></pre><h3 id="meshopt%2C-draco-and-ktx2">Meshopt, Draco and Ktx2</h3><p>Compressed meshes via Draco and compressed textures in Ktx2 format are supported automatically using the threejs plugins by passing the renderer at initialization. The ktx and draco loader can also be passed manually.</p><p>The Meshopt decoder doesn't need to be specified, it'll be loaded automatically.</p><h4 id="when-using-a-tileloader-(recommended)%3A">when using a tileLoader (recommended):</h4><pre class="prettyprint source"><code>const dracoLoader = new DRACOLoader();
|
|
251
|
+
dracoLoader.setDecoderPath('node_modules/three/examples/jsm/libs/draco/');
|
|
252
|
+
|
|
253
|
+
const ktx2Loader = new KTX2Loader();
|
|
254
|
+
ktx2Loader.setTranscoderPath('node_modules/three/examples/jsm/libs/basis/').detectSupport(renderer);
|
|
255
|
+
|
|
256
|
+
const tileLoader = new TileLoader({
|
|
257
|
+
ktx2Loader: ktx2Loader,
|
|
258
|
+
dracoLoader: dracoLoader,
|
|
259
|
+
maxCachedItems: 100,
|
|
260
|
+
...
|
|
261
|
+
});
|
|
262
|
+
const ogc3DTile = new OGC3DTile({
|
|
263
|
+
url: "...",
|
|
264
|
+
tileLoader: tileLoader,
|
|
265
|
+
...
|
|
266
|
+
});
|
|
267
|
+
</code></pre><h4 id="when-using-a-tileloader-fallback-to-web-wasms-loaded-through-http%3A">when using a tileLoader fallback to web wasms loaded through http:</h4><pre class="prettyprint source"><code>
|
|
268
|
+
const tileLoader = new TileLoader({
|
|
269
|
+
renderer: renderer
|
|
270
|
+
maxCachedItems: 100,
|
|
271
|
+
...
|
|
272
|
+
});
|
|
273
|
+
const ogc3DTile = new OGC3DTile({
|
|
274
|
+
url: "...",
|
|
275
|
+
tileLoader: tileLoader,
|
|
276
|
+
...
|
|
277
|
+
});
|
|
278
|
+
</code></pre><h4 id="when-not-using-a-tileloader%3A">when not using a TileLoader:</h4><pre class="prettyprint source"><code>const dracoLoader = new DRACOLoader();
|
|
279
|
+
dracoLoader.setDecoderPath('node_modules/three/examples/jsm/libs/draco/');
|
|
280
|
+
|
|
281
|
+
const ktx2Loader = new KTX2Loader();
|
|
282
|
+
ktx2Loader.setTranscoderPath('node_modules/three/examples/jsm/libs/basis/').detectSupport(renderer);
|
|
283
|
+
|
|
284
|
+
const ogc3DTile = new OGC3DTile({
|
|
285
|
+
url: "...",
|
|
286
|
+
ktx2Loader: ktx2Loader,
|
|
287
|
+
dracoLoader: dracoLoader,
|
|
288
|
+
...
|
|
289
|
+
});
|
|
290
|
+
</code></pre><h4 id="when-not-using-a-tileloader-and-using-fallback-wasms-loaded-from-web%3A">when not using a TileLoader and using fallback wasms loaded from web:</h4><pre class="prettyprint source"><code>const ogc3DTile = new OGC3DTile({
|
|
291
|
+
url: "...",
|
|
292
|
+
renderer: renderer,
|
|
293
|
+
...
|
|
294
|
+
});
|
|
295
|
+
</code></pre><h3 id="tileset-update-loop">tileset update loop</h3><p>Updating a single tileset via OGC3DTile#update or InstancedOGC3DTile#update is quite fast, even when the tree is deep. For a single tileset, it's safe to call it on every frame:</p><pre class="prettyprint source"><code>function animate() {
|
|
296
|
+
requestAnimationFrame(animate);
|
|
297
|
+
ogc3DTile.update(camera);
|
|
298
|
+
ogc3DTile.tileLoader.update();
|
|
299
|
+
|
|
300
|
+
... // rest of render loop
|
|
301
|
+
}
|
|
302
|
+
animate();
|
|
303
|
+
</code></pre><p>However, if you have several OGC3DTiles loaded or when you use instancedTilesets, you may have hundreds or even thousands of LOD trees that need to be updated individually. In order to preserve frame-rate, you'll want to avoid updating every single tileset on every frame.</p><h3 id="memory">Memory</h3><p>This is especially important for iOS that limits the memory per tab quite harshly and doesn't allow growing the memory allocated to a tab.</p><p>Once a mesh is loaded, the mesh and texture data stays in CPU memory which isn't necessary unless one intends to modify it. A nice trick is to allow this data to be garbage collected. However, three.js doesn't have API for this and the internal references are hard to find but this code seems to free a limited amount of memory:</p><pre class="prettyprint source"><code>const tileLoader = new TileLoader({
|
|
304
|
+
...
|
|
305
|
+
const previousOnAfterRender = mesh.onAfterRender;
|
|
306
|
+
mesh.onAfterRender = () => {
|
|
307
|
+
if(previousOnAfterRender) previousOnAfterRender();
|
|
308
|
+
if(mesh.geometry && mesh.geometry.attributes){
|
|
309
|
+
if (mesh.geometry.attributes.position) {
|
|
310
|
+
mesh.geometry.attributes.position.array = undefined;
|
|
311
|
+
if (mesh.geometry.attributes.position.data) {
|
|
312
|
+
mesh.geometry.attributes.position.data.array = undefined;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
if (mesh.geometry.attributes.uv){
|
|
316
|
+
mesh.geometry.attributes.uv.array = undefined;
|
|
317
|
+
if (mesh.geometry.attributes.uv.data) {
|
|
318
|
+
mesh.geometry.attributes.uv.data.array = undefined;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
if (mesh.geometry.attributes.normal) {
|
|
322
|
+
mesh.geometry.attributes.normal.array = undefined;
|
|
323
|
+
if (mesh.geometry.attributes.normal.data) {
|
|
324
|
+
mesh.geometry.attributes.normal.data.array = undefined;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
if (mesh.material && mesh.material.map) {
|
|
329
|
+
mesh.material.map.mipmaps = undefined;
|
|
330
|
+
if (mesh.material.map.source) {
|
|
331
|
+
mesh.material.map.source.data = undefined;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
mesh.onAfterRender = previousOnAfterRender;
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
</code></pre><p>Be sure to call this in the mesh onAfterRender callback to make sure the data is already on GPU.</p><p>Depending on the mesh and texture type, different properties might hold data to be nullified so it can be garbage collected. It's up to the user to debug and see what geometry or material properties hold references to large data.</p></article></section></div></div></div><div class="search-container" id="PkfLWpAbet" style="display:none"><div class="wrapper" id="iCxFxjkHbP"><button class="icon-button search-close-button" id="VjLlGakifb" aria-label="close search"><svg><use xlink:href="#close-icon"></use></svg></button><div class="search-box-c"><svg><use xlink:href="#search-icon"></use></svg> <input type="text" id="vpcKVYIppa" class="search-input" placeholder="Search..." autofocus></div><div class="search-result-c" id="fWwVHRuDuN"><span class="search-result-c-text">Type anything to view search result</span></div></div></div><div class="mobile-menu-icon-container"><button class="icon-button" id="mobile-menu" data-isopen="false" aria-label="menu"><svg><use xlink:href="#menu-icon"></use></svg></button></div><div id="mobile-sidebar" class="mobile-sidebar-container"><div class="mobile-sidebar-wrapper"><div class="mobile-nav-links"></div><div class="mobile-sidebar-items-c"><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-classes"><div>Classes</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="InstancedOGC3DTile.html">InstancedOGC3DTile</a></div><div class="sidebar-section-children"><a href="InstancedTile.html">InstancedTile</a></div><div class="sidebar-section-children"><a href="InstancedTileLoader.html">InstancedTileLoader</a></div><div class="sidebar-section-children"><a href="OGC3DTile.html">OGC3DTile</a></div><div class="sidebar-section-children"><a href="OcclusionCullingService.html">OcclusionCullingService</a></div><div class="sidebar-section-children"><a href="TileLoader.html">TileLoader</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-global"><div>Global</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="global.html#getOGC3DTilesCopyrightInfo">getOGC3DTilesCopyrightInfo</a></div></div></div><div class="mobile-navbar-actions"><div class="navbar-right-item"><button class="icon-button search-button" aria-label="open-search"><svg><use xlink:href="#search-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button theme-toggle" aria-label="toggle-theme"><svg><use class="theme-svg-use" xlink:href="#light-theme-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button font-size" aria-label="change-font-size"><svg><use xlink:href="#font-size-icon"></use></svg></button></div></div></div></div><script type="text/javascript" src="scripts/core.min.js"></script><script src="scripts/search.min.js" defer="defer"></script><script src="scripts/third-party/fuse.js" defer="defer"></script><script type="text/javascript">var tocbotInstance=tocbot.init({tocSelector:"#eed4d2a0bfd64539bb9df78095dec881",contentSelector:".main-content",headingSelector:"h1, h2, h3",hasInnerContainers:!0,scrollContainer:".main-content",headingsOffset:130,onClick:bringLinkToView})</script></body></html>
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
<!DOCTYPE html><html lang="en" style="font-size:16px"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Source: instanced/InstancedOGC3DTile.js</title><!--[if lt IE 9]>
|
|
2
|
+
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
|
3
|
+
<![endif]--><script src="scripts/third-party/hljs.js" defer="defer"></script><script src="scripts/third-party/hljs-line-num.js" defer="defer"></script><script src="scripts/third-party/popper.js" defer="defer"></script><script src="scripts/third-party/tippy.js" defer="defer"></script><script src="scripts/third-party/tocbot.min.js"></script><script>var baseURL="/",locationPathname="";baseURL=(locationPathname=document.location.pathname).substr(0,locationPathname.lastIndexOf("/")+1)</script><link rel="stylesheet" href="styles/clean-jsdoc-theme.min.css"><svg aria-hidden="true" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="display:none"><defs><symbol id="copy-icon" viewbox="0 0 488.3 488.3"><g><path d="M314.25,85.4h-227c-21.3,0-38.6,17.3-38.6,38.6v325.7c0,21.3,17.3,38.6,38.6,38.6h227c21.3,0,38.6-17.3,38.6-38.6V124 C352.75,102.7,335.45,85.4,314.25,85.4z M325.75,449.6c0,6.4-5.2,11.6-11.6,11.6h-227c-6.4,0-11.6-5.2-11.6-11.6V124 c0-6.4,5.2-11.6,11.6-11.6h227c6.4,0,11.6,5.2,11.6,11.6V449.6z"/><path d="M401.05,0h-227c-21.3,0-38.6,17.3-38.6,38.6c0,7.5,6,13.5,13.5,13.5s13.5-6,13.5-13.5c0-6.4,5.2-11.6,11.6-11.6h227 c6.4,0,11.6,5.2,11.6,11.6v325.7c0,6.4-5.2,11.6-11.6,11.6c-7.5,0-13.5,6-13.5,13.5s6,13.5,13.5,13.5c21.3,0,38.6-17.3,38.6-38.6 V38.6C439.65,17.3,422.35,0,401.05,0z"/></g></symbol><symbol id="search-icon" viewBox="0 0 512 512"><g><g><path d="M225.474,0C101.151,0,0,101.151,0,225.474c0,124.33,101.151,225.474,225.474,225.474 c124.33,0,225.474-101.144,225.474-225.474C450.948,101.151,349.804,0,225.474,0z M225.474,409.323 c-101.373,0-183.848-82.475-183.848-183.848S124.101,41.626,225.474,41.626s183.848,82.475,183.848,183.848 S326.847,409.323,225.474,409.323z"/></g></g><g><g><path d="M505.902,476.472L386.574,357.144c-8.131-8.131-21.299-8.131-29.43,0c-8.131,8.124-8.131,21.306,0,29.43l119.328,119.328 c4.065,4.065,9.387,6.098,14.715,6.098c5.321,0,10.649-2.033,14.715-6.098C514.033,497.778,514.033,484.596,505.902,476.472z"/></g></g></symbol><symbol id="font-size-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M11.246 15H4.754l-2 5H.6L7 4h2l6.4 16h-2.154l-2-5zm-.8-2L8 6.885 5.554 13h4.892zM21 12.535V12h2v8h-2v-.535a4 4 0 1 1 0-6.93zM19 18a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"/></symbol><symbol id="add-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"/></symbol><symbol id="minus-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M5 11h14v2H5z"/></symbol><symbol id="dark-theme-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M10 7a7 7 0 0 0 12 4.9v.1c0 5.523-4.477 10-10 10S2 17.523 2 12 6.477 2 12 2h.1A6.979 6.979 0 0 0 10 7zm-6 5a8 8 0 0 0 15.062 3.762A9 9 0 0 1 8.238 4.938 7.999 7.999 0 0 0 4 12z"/></symbol><symbol id="light-theme-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 18a6 6 0 1 1 0-12 6 6 0 0 1 0 12zm0-2a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM11 1h2v3h-2V1zm0 19h2v3h-2v-3zM3.515 4.929l1.414-1.414L7.05 5.636 5.636 7.05 3.515 4.93zM16.95 18.364l1.414-1.414 2.121 2.121-1.414 1.414-2.121-2.121zm2.121-14.85l1.414 1.415-2.121 2.121-1.414-1.414 2.121-2.121zM5.636 16.95l1.414 1.414-2.121 2.121-1.414-1.414 2.121-2.121zM23 11v2h-3v-2h3zM4 11v2H1v-2h3z"/></symbol><symbol id="reset-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M18.537 19.567A9.961 9.961 0 0 1 12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10c0 2.136-.67 4.116-1.81 5.74L17 12h3a8 8 0 1 0-2.46 5.772l.997 1.795z"/></symbol><symbol id="down-icon" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M12.7803 6.21967C13.0732 6.51256 13.0732 6.98744 12.7803 7.28033L8.53033 11.5303C8.23744 11.8232 7.76256 11.8232 7.46967 11.5303L3.21967 7.28033C2.92678 6.98744 2.92678 6.51256 3.21967 6.21967C3.51256 5.92678 3.98744 5.92678 4.28033 6.21967L8 9.93934L11.7197 6.21967C12.0126 5.92678 12.4874 5.92678 12.7803 6.21967Z"></path></symbol><symbol id="codepen-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M16.5 13.202L13 15.535v3.596L19.197 15 16.5 13.202zM14.697 12L12 10.202 9.303 12 12 13.798 14.697 12zM20 10.869L18.303 12 20 13.131V10.87zM19.197 9L13 4.869v3.596l3.5 2.333L19.197 9zM7.5 10.798L11 8.465V4.869L4.803 9 7.5 10.798zM4.803 15L11 19.131v-3.596l-3.5-2.333L4.803 15zM4 13.131L5.697 12 4 10.869v2.262zM2 9a1 1 0 0 1 .445-.832l9-6a1 1 0 0 1 1.11 0l9 6A1 1 0 0 1 22 9v6a1 1 0 0 1-.445.832l-9 6a1 1 0 0 1-1.11 0l-9-6A1 1 0 0 1 2 15V9z"/></symbol><symbol id="close-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z"/></symbol><symbol id="menu-icon" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M3 4h18v2H3V4zm0 7h18v2H3v-2zm0 7h18v2H3v-2z"/></symbol></defs></svg></head><body data-theme="dark"><div class="sidebar-container"><div class="sidebar" id="sidebar"><div class="sidebar-items-container"><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-classes"><div>Classes</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="InstancedOGC3DTile.html">InstancedOGC3DTile</a></div><div class="sidebar-section-children"><a href="InstancedTile.html">InstancedTile</a></div><div class="sidebar-section-children"><a href="InstancedTileLoader.html">InstancedTileLoader</a></div><div class="sidebar-section-children"><a href="OGC3DTile.html">OGC3DTile</a></div><div class="sidebar-section-children"><a href="OcclusionCullingService.html">OcclusionCullingService</a></div><div class="sidebar-section-children"><a href="TileLoader.html">TileLoader</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-global"><div>Global</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="global.html#getOGC3DTilesCopyrightInfo">getOGC3DTilesCopyrightInfo</a></div></div></div></div></div><div class="navbar-container" id="VuAckcnZhf"><nav class="navbar"><div class="navbar-left-items"></div><div class="navbar-right-items"><div class="navbar-right-item"><button class="icon-button search-button" aria-label="open-search"><svg><use xlink:href="#search-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button theme-toggle" aria-label="toggle-theme"><svg><use class="theme-svg-use" xlink:href="#light-theme-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button font-size" aria-label="change-font-size"><svg><use xlink:href="#font-size-icon"></use></svg></button></div></div><nav></nav></nav></div><div class="toc-container"><div class="toc-content"><span class="bold">On this page</span><div id="eed4d2a0bfd64539bb9df78095dec881"></div></div></div><div class="body-wrapper"><div class="main-content"><div class="main-wrapper"><section id="source-page" class="source-page"><header><h1 id="title" class="has-anchor">instanced_InstancedOGC3DTile.js</h1></header><article><pre class="prettyprint source lang-js"><code>import * as THREE from 'three';
|
|
4
|
+
import {InstancedTile} from "./InstancedTile.js"
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Similarly to {@link OGC3DTile}, this class that extends THREE.Object3D loads a tiled and multileveled OGC3DTiles 1.0 or 1.1 dataset.
|
|
8
|
+
* The difference is that tiles are instanced. This is useful when one wants to load the same tileset hundreds or even thousands of times.
|
|
9
|
+
* Imagine rendering hundreds of very high detail cars driving in a city.
|
|
10
|
+
* Each tile content is instanced but each {@link InstancedOGC3DTile} object also has it's own LOD tree making this scenario very efficient.
|
|
11
|
+
* @class
|
|
12
|
+
*/
|
|
13
|
+
class InstancedOGC3DTile extends THREE.Object3D {
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
*
|
|
17
|
+
* @param {Object} [properties] - the properties for this tileset
|
|
18
|
+
* @param {Object} [properties.url] - the url to the parent tileset.json
|
|
19
|
+
* @param {Object} [properties.pathParams] - optional, path params to add to individual tile urls (starts with "?").
|
|
20
|
+
* @param {Object} [properties.geometricErrorMultiplier] - the geometric error of the parent. 1.0 by default corresponds to a maxScreenSpaceError of 16
|
|
21
|
+
* @param {Object} [properties.loadOutsideView] - if truthy, tiles otside the camera frustum will be loaded with the least possible amount of detail
|
|
22
|
+
* @param {Object} [properties.tileLoader] - A tile loader that can be shared among tilesets in order to share a common cache.
|
|
23
|
+
* @param {Object} [properties.pointsCallback] - A callback function that will be called on every points
|
|
24
|
+
* @param {Object} [properties.onLoadCallback] - A callback function that will be called when the root tile has been loaded
|
|
25
|
+
* @param {Object} [properties.occlusionCullingService] - A service that handles occlusion culling
|
|
26
|
+
* @param {Object} [properties.centerModel] - If true, the tileset will be centered on 0,0,0 and in the case of georeferenced tilesets that use the "region" bounding volume, it will also be rotated so that the up axis matched the world y axis.
|
|
27
|
+
* @param {Object} [properties.static] - If true, the tileset is considered static which improves performance but the tileset cannot be moved
|
|
28
|
+
* @param {Object} [properties.rootPath] - optional the root path for fetching children
|
|
29
|
+
* @param {Object} [properties.json] - optional json object representing the tileset sub-tree
|
|
30
|
+
* @param {Object} [properties.parentGeometricError] - optional geometric error of the parent
|
|
31
|
+
* @param {Object} [properties.parentBoundingVolume] - optional bounding volume of the parent
|
|
32
|
+
* @param {Object} [properties.parentRefinement] - optional refinement strategy of the parent of the parent
|
|
33
|
+
* @param {Object} [properties.cameraOnLoad] - optional the camera used when loading this particular sub-tile
|
|
34
|
+
* @param {Object} [properties.parentTile] - optional the OGC3DTile object that loaded this tile as a child
|
|
35
|
+
* @param {Number} [properties.domWidth = 1000] - optional the canvas width (used to calculate geometric error). If a renderer is provided, it'll be used instead, else a default value is used.
|
|
36
|
+
* @param {Number} [properties.domHeight = 1000] - optional the canvas height (used to calculate geometric error). If a renderer is provided, it'll be used instead, else a default value is used.
|
|
37
|
+
* @param {Object} [properties.renderer = undefined] - optional the renderer is used to infer the canvas size and compute tiles geometric error.
|
|
38
|
+
* @param {Number} [properties.distanceBias] - optional a bias that allows loading more or less detail closer to the camera relative to far away. The value should be a positive number. A value below 1 loads less detail near the camera and a value above 1 loads more detail near the camera. This needs to be compensated by the geometricErrorMultiplier in order to load a reasonable number of tiles.
|
|
39
|
+
*/
|
|
40
|
+
constructor(properties) {
|
|
41
|
+
super();
|
|
42
|
+
properties.master = this;
|
|
43
|
+
|
|
44
|
+
if(!!properties.domWidth && !!properties.domHeight){
|
|
45
|
+
this.rendererSize = new THREE.Vector2(properties.domWidth, properties.domHeight);
|
|
46
|
+
}else{
|
|
47
|
+
this.rendererSize = new THREE.Vector2(1000, 1000);
|
|
48
|
+
}
|
|
49
|
+
this.renderer = properties.renderer;
|
|
50
|
+
this.distanceBias = Math.max(0.0001,properties.distanceBias? properties.distanceBias:1);
|
|
51
|
+
|
|
52
|
+
this.geometricErrorMultiplier = properties.geometricErrorMultiplier? properties.geometricErrorMultiplier:1.0;
|
|
53
|
+
this.tileset = new InstancedTile(properties);
|
|
54
|
+
if (properties.static) {
|
|
55
|
+
this.matrixAutoUpdate = false;
|
|
56
|
+
}
|
|
57
|
+
this.tileLoader = properties.tileLoader;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
_renderSize(size){
|
|
61
|
+
if(!!this.renderer){
|
|
62
|
+
this.renderer.getDrawingBufferSize(size);
|
|
63
|
+
}else{
|
|
64
|
+
size.copy(this.rendererSize);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Call this to specify the canvas width/height when it changes (used to compute tiles geometric error that controls tile refinement).
|
|
71
|
+
* It's unnecessary to call this when the {@link OGC3DTile} is instantiated with the renderer.
|
|
72
|
+
*
|
|
73
|
+
* @param {Number} width
|
|
74
|
+
* @param {Number} height
|
|
75
|
+
*/
|
|
76
|
+
setCanvasSize(width, height){
|
|
77
|
+
this.rendererSize.set(width, height);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* To be called in the render loop.
|
|
81
|
+
* @param {Three.Camera} camera a camera that the tileset will be rendered with.
|
|
82
|
+
*/
|
|
83
|
+
update(camera, frustum){
|
|
84
|
+
if(!!frustum){
|
|
85
|
+
this.tileset._update(camera, frustum);
|
|
86
|
+
}else{
|
|
87
|
+
const frustum = new THREE.Frustum();
|
|
88
|
+
frustum.setFromProjectionMatrix(new THREE.Matrix4().multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse));
|
|
89
|
+
this.tileset._update(camera, frustum);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Set the Geometric Error Multiplier for the tileset.
|
|
96
|
+
* the {@param geometricErrorMultiplier} can be a number between 1 and infinity.
|
|
97
|
+
* A {@param geometricErrorMultiplier} of 1 (default) corresponds to a max ScreenSpace error (MSE) of 16.
|
|
98
|
+
* A lower {@param geometricErrorMultiplier} loads less detail (higher MSE) and a higher {@param geometricErrorMultiplier} loads more detail (lower MSE)
|
|
99
|
+
*
|
|
100
|
+
* @param {Number} geometricErrorMultiplier set the LOD multiplier for the entire tileset
|
|
101
|
+
*/
|
|
102
|
+
setGeometricErrorMultiplier(geometricErrorMultiplier) {
|
|
103
|
+
this.geometricErrorMultiplier = geometricErrorMultiplier?geometricErrorMultiplier:1.0;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
export { InstancedOGC3DTile };</code></pre></article></section></div></div></div><div class="search-container" id="PkfLWpAbet" style="display:none"><div class="wrapper" id="iCxFxjkHbP"><button class="icon-button search-close-button" id="VjLlGakifb" aria-label="close search"><svg><use xlink:href="#close-icon"></use></svg></button><div class="search-box-c"><svg><use xlink:href="#search-icon"></use></svg> <input type="text" id="vpcKVYIppa" class="search-input" placeholder="Search..." autofocus></div><div class="search-result-c" id="fWwVHRuDuN"><span class="search-result-c-text">Type anything to view search result</span></div></div></div><div class="mobile-menu-icon-container"><button class="icon-button" id="mobile-menu" data-isopen="false" aria-label="menu"><svg><use xlink:href="#menu-icon"></use></svg></button></div><div id="mobile-sidebar" class="mobile-sidebar-container"><div class="mobile-sidebar-wrapper"><div class="mobile-nav-links"></div><div class="mobile-sidebar-items-c"><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-classes"><div>Classes</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="InstancedOGC3DTile.html">InstancedOGC3DTile</a></div><div class="sidebar-section-children"><a href="InstancedTile.html">InstancedTile</a></div><div class="sidebar-section-children"><a href="InstancedTileLoader.html">InstancedTileLoader</a></div><div class="sidebar-section-children"><a href="OGC3DTile.html">OGC3DTile</a></div><div class="sidebar-section-children"><a href="OcclusionCullingService.html">OcclusionCullingService</a></div><div class="sidebar-section-children"><a href="TileLoader.html">TileLoader</a></div></div><div class="sidebar-section-title with-arrow" data-isopen="false" id="sidebar-global"><div>Global</div><svg><use xlink:href="#down-icon"></use></svg></div><div class="sidebar-section-children-container"><div class="sidebar-section-children"><a href="global.html#getOGC3DTilesCopyrightInfo">getOGC3DTilesCopyrightInfo</a></div></div></div><div class="mobile-navbar-actions"><div class="navbar-right-item"><button class="icon-button search-button" aria-label="open-search"><svg><use xlink:href="#search-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button theme-toggle" aria-label="toggle-theme"><svg><use class="theme-svg-use" xlink:href="#light-theme-icon"></use></svg></button></div><div class="navbar-right-item"><button class="icon-button font-size" aria-label="change-font-size"><svg><use xlink:href="#font-size-icon"></use></svg></button></div></div></div></div><script type="text/javascript" src="scripts/core.min.js"></script><script src="scripts/search.min.js" defer="defer"></script><script src="scripts/third-party/fuse.js" defer="defer"></script><script type="text/javascript">var tocbotInstance=tocbot.init({tocSelector:"#eed4d2a0bfd64539bb9df78095dec881",contentSelector:".main-content",headingSelector:"h1, h2, h3",hasInnerContainers:!0,scrollContainer:".main-content",headingsOffset:130,onClick:bringLinkToView})</script></body></html>
|