Explorar el Código

Add 3d-tiles-renderer package plugins and examples.

master
Palash Bansal hace 1 año
padre
commit
e581362ab8
No account linked to committer's email address
Se han modificado 40 ficheros con 2642 adiciones y 21 borrados
  1. 2
    0
      .idea/threepipe.iml
  2. 5
    4
      README.md
  3. 36
    0
      examples/3d-tiles-renderer/index.html
  4. 44
    0
      examples/3d-tiles-renderer/script.ts
  5. 69
    0
      examples/b3dm-load/index.html
  6. 65
    0
      examples/cmpt-load/index.html
  7. 69
    0
      examples/dzi-load/index.html
  8. 58
    0
      examples/i3dm-load/index.html
  9. 12
    3
      examples/index.html
  10. 1
    0
      examples/model-viewer/index.html
  11. 30
    7
      examples/model-viewer/script.ts
  12. 36
    0
      examples/ogc-tiles-google-maps-3d/index.html
  13. 57
    0
      examples/ogc-tiles-google-maps-3d/script.ts
  14. 36
    0
      examples/ogc-tiles-google-maps/index.html
  15. 61
    0
      examples/ogc-tiles-google-maps/script.ts
  16. 36
    0
      examples/ogc-tiles-mars/index.html
  17. 67
    0
      examples/ogc-tiles-mars/script.ts
  18. 59
    0
      examples/pnts-load/index.html
  19. 76
    0
      examples/slippy-map-tiles/index.html
  20. 1
    0
      examples/tweakpane-editor/index.html
  21. 23
    3
      examples/tweakpane-editor/script.ts
  22. 402
    0
      plugins/3d-tiles-renderer/package-lock.json
  23. 77
    0
      plugins/3d-tiles-renderer/package.json
  24. 64
    0
      plugins/3d-tiles-renderer/src/B3DMLoadPlugin.ts
  25. 144
    0
      plugins/3d-tiles-renderer/src/CMPTLoadPlugin.ts
  26. 49
    0
      plugins/3d-tiles-renderer/src/DeepZoomImageLoadPlugin.ts
  27. 65
    0
      plugins/3d-tiles-renderer/src/I3DMLoadPlugin.ts
  28. 137
    0
      plugins/3d-tiles-renderer/src/PNTSLoadPlugin.ts
  29. 50
    0
      plugins/3d-tiles-renderer/src/SlippyMapTilesLoadPlugin.ts
  30. 339
    0
      plugins/3d-tiles-renderer/src/TilesRendererPlugin.ts
  31. 40
    0
      plugins/3d-tiles-renderer/src/global.d.ts
  32. 40
    0
      plugins/3d-tiles-renderer/src/gltf.ts
  33. 14
    0
      plugins/3d-tiles-renderer/src/index.ts
  34. 41
    0
      plugins/3d-tiles-renderer/tsconfig.json
  35. 10
    0
      plugins/3d-tiles-renderer/typedoc.json
  36. 100
    0
      plugins/3d-tiles-renderer/vite.config.js
  37. 4
    3
      website/.vitepress/config.ts
  38. 2
    0
      website/guide/threepipe-packages.md
  39. 217
    0
      website/package/plugin-3d-tiles-renderer.md
  40. 4
    1
      website/package/plugin-svg-renderer.md

+ 2
- 0
.idea/threepipe.iml Ver fichero

@@ -23,6 +23,8 @@
<excludeFolder url="file://$MODULE_DIR$/plugins/svg-renderer/docs" />
<excludeFolder url="file://$MODULE_DIR$/plugins/tweakpane-editor/docs" />
<excludeFolder url="file://$MODULE_DIR$/website/.vitepress/dist" />
<excludeFolder url="file://$MODULE_DIR$/plugins/3d-tiles-renderer/dist" />
<excludeFolder url="file://$MODULE_DIR$/plugins/3d-tiles-renderer/docs" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />

+ 5
- 4
README.md Ver fichero

@@ -323,10 +323,11 @@ Many features will be added but the core API will not change significantly in fu
- [@threepipe/plugins-extra-importers](https://threepipe.org/package/plugins-extra-importers.html) - Plugin for loading more file types supported by loaders in three.js
- [@threepipe/plugin-blend-importer](https://threepipe.org/package/plugin-blend-importer.html) - Add support for loading .blend file. (Partial/WIP) ([Blender](https://www.blender.org/))
- [@threepipe/plugin-geometry-generator](https://threepipe.org/package/plugin-geometry-generator.html) - Generate parametric geometry types that can be re-generated from UI/API.
- [@threepipe/plugin-gaussian-splatting](https://threepipe.org/package/plugin-gaussian-splatting.html) - Gaussian Splatting plugin for loading and rendering splat files
- [@threepipe/plugin-network](https://threepipe.org/package/plugin-network.html) - Network/Cloud related plugin implementations for Threepipe.
- [@threepipe/plugin-svg-renderer](https://threepipe.org/package/plugin-svg-renderer.html) - Add support for exporting 3d scene as SVG.
- [@threepipe/webgi-plugins](https://webgi.dev) - Realistic rendering plugin pack for threepipe (SSR, SSRTAO, HDR Bloom, TAA, Depth of Field, SSGI, etc.)
- [@threepipe/plugin-gaussian-splatting](https://threepipe.org/package/plugin-gaussian-splatting.html) - [3D Gaussian Splatting](https://repo-sam.inria.fr/fungraph/3d-gaussian-splatting/) plugin for loading and rendering splat files
- [@threepipe/plugin-network](https://threepipe.org/package/plugin-network.html) - Network/Cloud related plugin implementations for Threepipe
- [@threepipe/plugin-svg-renderer](https://threepipe.org/package/plugin-svg-renderer.html) - Add support for exporting a 3d scene as SVG using [three-svg-renderer](https://www.npmjs.com/package/three-svg-renderer)
- [@threepipe/plugin-3d-tiles-renderer](https://threepipe.org/package/plugin-3d-tiles-renderer.html) - Plugins for [3d-tiles-renderer](https://github.com/NASA-AMMOS/3DTilesRendererJS), b3dm, i3dm, cmpt, pnts, dzi, slippy maps importers.
- [@threepipe/webgi-plugins](https://webgi.dev) - Web [Global Illumination](https://en.wikipedia.org/wiki/Global_illumination) - Realistic rendering plugin pack (SSR, SSRTAO, HDR Bloom, TAA, Depth of Field, SSGI, etc.)

## Documentation


+ 36
- 0
examples/3d-tiles-renderer/index.html Ver fichero

@@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>3d Tiles Renderer</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>

<script type="importmap">
{
"imports": {
"threepipe": "./../../dist/index.mjs",
"@threepipe/plugin-tweakpane": "./../../plugins/tweakpane/dist/index.mjs",
"@threepipe/plugin-3d-tiles-renderer": "./../../plugins/3d-tiles-renderer/dist/index.mjs"
}
}
</script>
<style id="example-style">
html, body, #canvas-container, #mcanvas {
width: 100%;
height: 100%;
margin: 0;
overflow: hidden;
}
</style>
<script type="module" src="../examples-utils/simple-code-preview.mjs"></script>
<script id="example-script" type="module" src="./script.js" data-scripts="./script.ts;./script.js"></script>
</head>
<body>
<div id="canvas-container">
<canvas id="mcanvas"></canvas>
</div>

</body>

+ 44
- 0
examples/3d-tiles-renderer/script.ts Ver fichero

@@ -0,0 +1,44 @@
import {_testFinish, LoadingScreenPlugin, ThreeViewer} from 'threepipe'
import {TilesRendererPlugin} from '@threepipe/plugin-3d-tiles-renderer'

async function init() {

const viewer = new ThreeViewer({
canvas: document.getElementById('mcanvas') as HTMLCanvasElement,
msaa: false,
debug: true,
renderScale: 'auto',
dropzone: {
allowedExtensions: ['gltf', 'glb', 'hdr', 'bin', 'png', 'jpeg', 'webp', 'jpg', 'exr', 'json'],
addOptions: {
disposeSceneObjects: true,
autoSetEnvironment: true, // when hdr is dropped
autoSetBackground: true,
},
},
})

viewer.scene.mainCamera.position.set(3, 3, 4)
// viewer.scene.mainCamera.position.set(300, 300, 300)
// viewer.scene.mainCamera.autoNearFar = false
// viewer.scene.mainCamera.minNearPlane = 1
// viewer.scene.mainCamera.maxFarPlane = 1000

const tiles = viewer.addPluginSync(TilesRendererPlugin)

viewer.addPluginSync(LoadingScreenPlugin)

// await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr', {
// setBackground: true,
// })

const result = await tiles.load('https://raw.githubusercontent.com/NASA-AMMOS/3DTilesRendererJS/c7a9a7f7607e8759d16c26fb83815ad1cd1fd865/example/data/tileset.json', {
autoCenter: true,
autoScale: true,
// autoScaleRadius: 100,
})
console.log(result)

}

init().finally(_testFinish)

+ 69
- 0
examples/b3dm-load/index.html Ver fichero

@@ -0,0 +1,69 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>B3DM (Batched 3D Model, OGC Tiles) Load</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>

<script type="importmap">
{
"imports": {
"threepipe": "./../../dist/index.mjs",
"@threepipe/plugin-3d-tiles-renderer": "./../../plugins/3d-tiles-renderer/dist/index.mjs"
}
}

</script>
<style id="example-style">
html, body, #canvas-container, #mcanvas {
width: 100%;
height: 100%;
margin: 0;
overflow: hidden;
}
</style>
<script type="module" src="../examples-utils/simple-code-preview.mjs"></script>
<script id="example-script" type="module">
import {_testFinish, LoadingScreenPlugin, ThreeViewer, Vector3} from 'threepipe'
import {B3DMLoadPlugin} from '@threepipe/plugin-3d-tiles-renderer'

const viewer = new ThreeViewer({canvas: document.getElementById('mcanvas')})
viewer.addPluginsSync([B3DMLoadPlugin, LoadingScreenPlugin])

async function init() {

viewer.scene.backgroundColor.set(0)

viewer.scene.mainCamera.position.set(2,2,3)
viewer.scene.mainCamera.setDirty()

await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr')

// https://github.com/CesiumGS/3d-tiles-samples
// from https://github.com/NASA-AMMOS/3DTilesRendererJS/blob/master/example/data/root.b3dm
const result = await viewer.load('https://asset-samples.threepipe.org/minimal/root-tile.b3dm', {
autoCenter: true,
autoScale: true,
})
const result2 = await viewer.load('https://raw.githubusercontent.com/CesiumGS/cesium/main/Apps/SampleData/Cesium3DTiles/Hierarchy/BatchTableHierarchy/tile.b3dm', {
autoCenter: true,
autoScale: true,
autoScaleRadius: 1.5,
})
console.log(result2)
result2.position.set(0, .25, 0)
result2.setDirty()
}

init().finally(_testFinish)
</script>
</head>
<body>
<div id="canvas-container">
<canvas id="mcanvas"></canvas>
</div>

</body>

+ 65
- 0
examples/cmpt-load/index.html Ver fichero

@@ -0,0 +1,65 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CMPT (Composite 3D Model, OGC Tiles) Load</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>

<script type="importmap">
{
"imports": {
"threepipe": "./../../dist/index.mjs",
"@threepipe/plugin-3d-tiles-renderer": "./../../plugins/3d-tiles-renderer/dist/index.mjs"
}
}

</script>
<style id="example-style">
html, body, #canvas-container, #mcanvas {
width: 100%;
height: 100%;
margin: 0;
overflow: hidden;
}
</style>
<script type="module" src="../examples-utils/simple-code-preview.mjs"></script>
<script id="example-script" type="module">
import {_testFinish, LoadingScreenPlugin, ThreeViewer, Vector3, Box3B} from 'threepipe'
import {CMPTLoadPlugin} from '@threepipe/plugin-3d-tiles-renderer'

const viewer = new ThreeViewer({canvas: document.getElementById('mcanvas')})
viewer.addPluginsSync([CMPTLoadPlugin, LoadingScreenPlugin])

async function init() {

viewer.scene.backgroundColor.set(0)
//
// viewer.scene.mainCamera.position.set(2,2,3)
// viewer.scene.mainCamera.setDirty()

await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr')

// https://github.com/CesiumGS/3d-tiles-tools
// https://github.com/NASA-AMMOS/3DTilesRendererJS/blob/master/example/data/root.b3dm
const result2 = await viewer.load('https://raw.githubusercontent.com/CesiumGS/3d-tiles-tools/main/specs/data/contentTypes/content.cmpt', {
autoCenter: true,
autoScale: true,
// autoScaleRadius: 1.5,
})
console.log(result2)
result2.setDirty()
console.log(new Box3B(result2).getCenter(new Vector3())) // todo why is this is NaN?
}

init().finally(_testFinish)
</script>
</head>
<body>
<div id="canvas-container">
<canvas id="mcanvas"></canvas>
</div>

</body>

+ 69
- 0
examples/dzi-load/index.html Ver fichero

@@ -0,0 +1,69 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DZI (Deep Zoom Image) Load</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>

<script type="importmap">
{
"imports": {
"threepipe": "./../../dist/index.mjs",
"@threepipe/plugin-3d-tiles-renderer": "./../../plugins/3d-tiles-renderer/dist/index.mjs"
}
}

</script>
<style id="example-style">
html, body, #canvas-container, #mcanvas {
width: 100%;
height: 100%;
margin: 0;
overflow: hidden;
}
</style>
<script type="module" src="../examples-utils/simple-code-preview.mjs"></script>
<script id="example-script" type="module" lang="ts">
import {_testFinish, LoadingScreenPlugin, ThreeViewer, SSAAPlugin} from 'threepipe'
import {DeepZoomImageLoadPlugin} from '@threepipe/plugin-3d-tiles-renderer'

const viewer = new ThreeViewer({canvas: document.getElementById('mcanvas'), msaa: true, renderScale: window.devicePixelRatio, tonemap: false})
viewer.addPluginsSync([DeepZoomImageLoadPlugin, LoadingScreenPlugin, SSAAPlugin])

// todo why is camera change required here to start rendering?

async function init() {

viewer.scene.mainCamera.position.set(0,0, 20)
viewer.scene.mainCamera.minNearPlane = 0.1
viewer.scene.mainCamera.setDirty()

// https://github.com/CesiumGS/3d-tiles-samples
// from https://github.com/NASA-AMMOS/3DTilesRendererJS/blob/master/example/data/root.b3dm
const result = await viewer.load('https://openseadragon.github.io/example-images/duomo/duomo.dzi', {
autoCenter: true,
autoScale: true,
autoScaleRadius: 30,
tiles: {
DeepZoomImagePlugin: {
center: true
},
errorTarget: 1,
}
})
viewer.setDirty()
console.log(result)
}

init().finally(_testFinish)
</script>
</head>
<body>
<div id="canvas-container">
<canvas id="mcanvas"></canvas>
</div>

</body>

+ 58
- 0
examples/i3dm-load/index.html Ver fichero

@@ -0,0 +1,58 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>I3DM (Instanced 3D Model, OGC Tiles) Load</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>

<script type="importmap">
{
"imports": {
"threepipe": "./../../dist/index.mjs",
"@threepipe/plugin-3d-tiles-renderer": "./../../plugins/3d-tiles-renderer/dist/index.mjs"
}
}

</script>
<style id="example-style">
html, body, #canvas-container, #mcanvas {
width: 100%;
height: 100%;
margin: 0;
overflow: hidden;
}
</style>
<script type="module" src="../examples-utils/simple-code-preview.mjs"></script>
<script id="example-script" type="module">
import {_testFinish, LoadingScreenPlugin, ThreeViewer, Vector3} from 'threepipe'
import {I3DMLoadPlugin} from '@threepipe/plugin-3d-tiles-renderer'

const viewer = new ThreeViewer({canvas: document.getElementById('mcanvas'), msaa: true})
viewer.addPluginsSync([I3DMLoadPlugin, LoadingScreenPlugin])

async function init() {

await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr')

// https://github.com/CesiumGS/3d-tiles-samples
// https://github.com/NASA-AMMOS/3DTilesRendererJS/blob/master/example/data/root.b3dm
const result = await viewer.load('https://raw.githubusercontent.com/CesiumGS/3d-tiles-samples/main/1.0/TilesetWithTreeBillboards/tree.i3dm', {
autoCenter: true,
autoScale: true,
autoScaleRadius: 5,
})
console.log(result)
}

init().finally(_testFinish)
</script>
</head>
<body>
<div id="canvas-container">
<canvas id="mcanvas"></canvas>
</div>

</body>

+ 12
- 3
examples/index.html Ver fichero

@@ -373,6 +373,7 @@
<li><a href="./virtual-camera/">Virtual Camera (Animated) </a></li>
<li><a href="./basic-svg-renderer-plugin/">Basic SVG Renderer Plugin </a></li>
<li><a href="./three-svg-renderer-plugin/">Three SVG Renderer Plugin </a></li>
<li><a href="./3d-tiles-renderer/">3D Tiles Renderer </a></li>
</ul>
<h2 class="category">Realistic Rendering (<a class="brand-link webgi-link" href="https://webgi.dev/" target="_blank">webgi</a>)</h2>
<ul>
@@ -429,7 +430,7 @@
<li><a href="./drc-load/">DRACO(DRC) Load </a></li>
<li><a href="./hdr-load/">HDR Load </a></li>
<li><a href="./exr-load/">EXR Load </a></li>
<li><a href="./image-load/">Image(png, jpeg, svg, ico, webp, avif) Load </a></li>
<li><a href="./image-load/">Image (png, jpeg, svg, ico, webp, avif) Load </a></li>
<li><a href="./usdz-load/">USDZ, USDA Load </a></li>
<li><a href="./ply-load/">PLY Load </a></li>
<li><a href="./stl-load/">STL Load </a></li>
@@ -437,8 +438,16 @@
<li><a href="./ktx-load/">KTX Load </a></li>
<li><a href="./blend-load/">BLEND Load </a></li>
<li><a href="./splat-load/">SPLAT Load<br/>(Gaussian Splatting) </a></li>
<li><a href="./extra-importer-plugins/">Extra(3ds, 3mf, collada, amf, bvh, vox, gcode, mdd, pcd, tilt, wrl, ldraw, vtk, xyz) Load </a></li>
<li><a href="./extra-importer-plugins/">Extra (3ds, 3mf, collada, amf, bvh, vox, gcode, mdd, pcd, tilt, wrl, ldraw, vtk, xyz) Load </a></li>
<li><a href="./gltf-meshopt-compression/">glTF MeshOpt Decode (Compression Extension) </a></li>
<li><a href="./b3dm-load/">B3DM Load (3D Tile) </a></li>
<li><a href="./i3dm-load/">I3DM Load (3D Tile) </a></li>
<li><a href="./pnts-load/">PNTS Load (3D Points) </a></li>
<li><a href="./cmpt-load/">CMPT Load (3D Tiles) </a></li>
<li><a href="./dzi-load/">DZI Load (DeepZoomImage) </a></li>
<li><a href="./slippy-map-tiles/">Slippy Map Tiles Load<br/>(OpenStreetMap ZYX) </a></li>
<li><a href="./ogc-tiles-google-maps/">Google Maps Globe (OGC Tiles)</a></li>
<li><a href="./ogc-tiles-google-maps-3d/">Google Maps 3D (OGC Tiles)</a></li>
</ul>
<h2 class="category">Export</h2>
<ul>
@@ -471,7 +480,7 @@
<li><a href="./react-tsx-sample/">React/TSX Sample </a></li>
<li><a href="./vue-html-sample/">Vue/HTML Sample </a></li>
<li><a href="./vue-sfc-sample/">Vue/SFC Sample </a></li>
<li><a href="./svelte-sample/">Svelte Sample </a></li>
<li><a href="./svelte-sample/">Svelte 4 Sample </a></li>
</ul>
<h2 class="category">Material Extensions</h2>
<ul>

+ 1
- 0
examples/model-viewer/index.html Ver fichero

@@ -18,6 +18,7 @@
"@threepipe/plugin-configurator": "./../../plugins/configurator/dist/index.mjs",
"@threepipe/plugin-network": "./../../plugins/network/dist/index.mjs",
"@threepipe/plugin-gaussian-splatting": "./../../plugins/gaussian-splatting/dist/index.mjs",
"@threepipe/plugin-plugin-3d-tiles-renderer": "./../../plugins/plugin-3d-tiles-renderer/dist/index.mjs",
"@threepipe/webgi-plugins": "https://unpkg.com/@threepipe/webgi-plugins@0.4.1/dist/index.mjs"
}
}

+ 30
- 7
examples/model-viewer/script.ts Ver fichero

@@ -51,26 +51,44 @@ import {MaterialConfiguratorPlugin, SwitchNodePlugin} from '@threepipe/plugin-co
import {BlendLoadPlugin} from '@threepipe/plugin-blend-importer'
import {extraImportPlugins} from '@threepipe/plugins-extra-importers'
import {AWSClientPlugin} from '@threepipe/plugin-network'
import {
B3DMLoadPlugin,
CMPTLoadPlugin,
DeepZoomImageLoadPlugin,
I3DMLoadPlugin,
PNTSLoadPlugin,
TilesRendererPlugin,
} from '@threepipe/plugin-3d-tiles-renderer'
// @ts-expect-error todo fix import
import {BloomPlugin, DepthOfFieldPlugin, SSContactShadowsPlugin, SSReflectionPlugin, TemporalAAPlugin, VelocityBufferPlugin, SSGIPlugin, AnisotropyPlugin} from '@threepipe/webgi-plugins'

function checkQuery(key: string, def = true) {
return !['false', 'no', 'f'].includes(getUrlQueryParam(key, def ? 'yes' : 'no').toLowerCase())
}

async function init() {

const viewer = new ThreeViewer({
canvas: document.getElementById('mcanvas') as HTMLCanvasElement,
renderScale: 'auto',
msaa: true,
rgbm: true,
zPrepass: false, // set it to true if you only have opaque objects in the scene to get better performance.
msaa: checkQuery('msaa', true),
rgbm: checkQuery('rgbm', true),
debug: checkQuery('debug', false),
assetManager: {
storage: checkQuery('cache', true),
},
// set it to true if you only have opaque objects in the scene to get better performance.
zPrepass: checkQuery('depthPrepass', checkQuery('zPrepass', false)),
modelRootScale: parseFloat(getUrlQueryParam('modelRootScale', '1')),
dropzone: { // this can also be set to true and configured by getting a reference to the DropzonePlugin
// allowedExtensions: ['gltf', 'glb', 'hdr', 'bin', 'png', 'jpeg', 'webp', 'jpg', 'exr', 'fbx', 'obj'], // only allow these file types. If undefined, all files are allowed.
addOptions: {
disposeSceneObjects: true, // auto dispose of old scene objects
autoSetEnvironment: true, // when hdr is dropped
autoSetBackground: true, // when any image is dropped
autoCenter: true, // auto center the object
autoScale: true, // auto scale according to radius
autoScaleRadius: 2,
autoScale: checkQuery('autoScale', true), // auto scale according to radius
autoCenter: checkQuery('autoCenter', true), // auto center the object
autoScaleRadius: parseFloat(getUrlQueryParam('autoScaleRadius', '2')),
// license: 'Imported from dropzone', // Any license to set on imported objects
importConfig: true, // import config from file
},
@@ -138,6 +156,8 @@ async function init() {
MaterialConfiguratorPlugin,
SwitchNodePlugin,
AWSClientPlugin,
B3DMLoadPlugin, I3DMLoadPlugin, PNTSLoadPlugin, CMPTLoadPlugin,
TilesRendererPlugin, DeepZoomImageLoadPlugin, /* SlippyMapTilesLoadPlugin,*/
])

const hemiLight = viewer.scene.addObject(new HemisphereLight(0xffffff, 0x444444, 5), {addToRoot: true})
@@ -147,7 +167,10 @@ async function init() {

const model = getUrlQueryParam('m') || getUrlQueryParam('model')
if (model) {
await viewer.load(model)
const ext = getUrlQueryParam('ext') || getUrlQueryParam('model-extension')
const loader = viewer.getPlugin(DropzonePlugin) ?? viewer
const obj = await loader.load(model, {fileExtension: ext})
console.log(obj)
const promptDiv = document.getElementById('prompt-div')!
promptDiv.style.display = 'none'
}

+ 36
- 0
examples/ogc-tiles-google-maps-3d/index.html Ver fichero

@@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>3d Tiles Renderer</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>

<script type="importmap">
{
"imports": {
"threepipe": "./../../dist/index.mjs",
"@threepipe/plugin-tweakpane": "./../../plugins/tweakpane/dist/index.mjs",
"@threepipe/plugin-3d-tiles-renderer": "./../../plugins/3d-tiles-renderer/dist/index.mjs"
}
}
</script>
<style id="example-style">
html, body, #canvas-container, #mcanvas {
width: 100%;
height: 100%;
margin: 0;
overflow: hidden;
}
</style>
<script type="module" src="../examples-utils/simple-code-preview.mjs"></script>
<script id="example-script" type="module" src="./script.js" data-scripts="./script.ts;./script.js"></script>
</head>
<body>
<div id="canvas-container">
<canvas id="mcanvas"></canvas>
</div>

</body>

+ 57
- 0
examples/ogc-tiles-google-maps-3d/script.ts Ver fichero

@@ -0,0 +1,57 @@
import {_testFinish, LoadingScreenPlugin, MathUtils, OrbitControls3, ThreeViewer} from 'threepipe'
import {TilesRendererPlugin, UnloadTilesPlugin, TileCompressionPlugin} from '@threepipe/plugin-3d-tiles-renderer'

async function init() {

const viewer = new ThreeViewer({
canvas: document.getElementById('mcanvas') as HTMLCanvasElement,
msaa: false,
debug: true,
renderScale: 'auto',
})

// viewer.scene.mainCamera.position.set(4800000, 2570000, 14720000 )
viewer.scene.mainCamera.position.set(500, 500, 500)
viewer.scene.mainCamera.autoNearFar = false
viewer.scene.mainCamera.minNearPlane = 1
viewer.scene.mainCamera.maxFarPlane = 1600000
viewer.scene.mainCamera.fov = 60
const controls = viewer.scene.mainCamera.controls as OrbitControls3
controls.minDistance = 1
controls.maxDistance = 1e4 * 2
controls.minPolarAngle = 0
controls.maxPolarAngle = 3 * Math.PI / 8
controls.enableDamping = true
controls.autoRotate = true
controls.autoRotateSpeed = 0.5
controls.enablePan = false

const tiles = viewer.addPluginSync(TilesRendererPlugin)

viewer.addPluginSync(LoadingScreenPlugin)

const result = await tiles.loadCesiumIon({
assetId: '2275207',
apiToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI0M2VkOWIxYy00NGEyLTQ1N2QtOWYxYy01ZDNlYjdkN2U4N2MiLCJpZCI6Mjk5NTY5LCJpYXQiOjE3NDY0MzE1NTl9.iOdIsjY4zSnTfIXBx0Pl-yfsG24OuHTt2CQnIP5JRrQ',
autoRefreshToken: true,
}, {
autoCenter: false,
tiles: {
TilesFadePlugin: true,
plugins: [
()=>new TileCompressionPlugin(),
()=>new UnloadTilesPlugin(),
],
},
})
if (result) {
result.rotateX(-Math.PI / 2)
// @ts-expect-error deprecated?
result.tilesRenderer.setLatLonToYUp(35.6586 * MathUtils.DEG2RAD, 139.7454 * MathUtils.DEG2RAD) // Tokyo Tower
result.tilesRenderer.errorTarget = 1
}
console.log(result)

}

init().finally(_testFinish)

+ 36
- 0
examples/ogc-tiles-google-maps/index.html Ver fichero

@@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>3d Tiles Renderer</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>

<script type="importmap">
{
"imports": {
"threepipe": "./../../dist/index.mjs",
"@threepipe/plugin-tweakpane": "./../../plugins/tweakpane/dist/index.mjs",
"@threepipe/plugin-3d-tiles-renderer": "./../../plugins/3d-tiles-renderer/dist/index.mjs"
}
}
</script>
<style id="example-style">
html, body, #canvas-container, #mcanvas {
width: 100%;
height: 100%;
margin: 0;
overflow: hidden;
}
</style>
<script type="module" src="../examples-utils/simple-code-preview.mjs"></script>
<script id="example-script" type="module" src="./script.js" data-scripts="./script.ts;./script.js"></script>
</head>
<body>
<div id="canvas-container">
<canvas id="mcanvas"></canvas>
</div>

</body>

+ 61
- 0
examples/ogc-tiles-google-maps/script.ts Ver fichero

@@ -0,0 +1,61 @@
import {_testFinish, LoadingScreenPlugin, OrbitControls3, ThreeViewer} from 'threepipe'
import {TileCompressionPlugin, TilesRendererPlugin, UnloadTilesPlugin} from '@threepipe/plugin-3d-tiles-renderer'

async function init() {

const viewer = new ThreeViewer({
canvas: document.getElementById('mcanvas') as HTMLCanvasElement,
msaa: false,
debug: true,
renderScale: 'auto',
zPrepass: false,
rgbm: false,
// modelRootScale: 0.01,
})

viewer.scene.mainCamera.position.set(4800000, 2570000, 14720000)
// viewer.scene.mainCamera.position.set(300, 300, 300)
viewer.scene.mainCamera.autoNearFar = false
viewer.scene.mainCamera.minNearPlane = 1
viewer.scene.mainCamera.maxFarPlane = 160000000
viewer.scene.mainCamera.fov = 60
const controls = viewer.scene.mainCamera.controls as OrbitControls3
controls.minDistance = 6.379e6
controls.maxDistance = 160000000
controls.clampMax.set(160000000, 160000000, 160000000)
// controls.minPolarAngle = 0
// controls.maxPolarAngle = 3 * Math.PI / 8
controls.enableDamping = true
// controls.autoRotate = true
// controls.autoRotateSpeed = 0.5
// controls.enablePan = false

const tiles = viewer.addPluginSync(TilesRendererPlugin)

viewer.addPluginSync(LoadingScreenPlugin)

const result = await tiles.loadCesiumIon({
assetId: '2275207',
apiToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI0M2VkOWIxYy00NGEyLTQ1N2QtOWYxYy01ZDNlYjdkN2U4N2MiLCJpZCI6Mjk5NTY5LCJpYXQiOjE3NDY0MzE1NTl9.iOdIsjY4zSnTfIXBx0Pl-yfsG24OuHTt2CQnIP5JRrQ',
autoRefreshToken: true,
}, {
autoCenter: false,
autoScale: false,
// autoScaleRadius: 300,
tiles: {
TilesFadePlugin: true,
plugins: [
()=>new UnloadTilesPlugin(),
()=>new TileCompressionPlugin(),
],
},
})
if (result) {
result.rotateX(-Math.PI / 2)
result.tilesRenderer.errorTarget = 40
}
console.log(result)

}

init().finally(_testFinish)

+ 36
- 0
examples/ogc-tiles-mars/index.html Ver fichero

@@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>OGC 3D Tiles Mars</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>

<script type="importmap">
{
"imports": {
"threepipe": "./../../dist/index.mjs",
"@threepipe/plugin-tweakpane": "./../../plugins/tweakpane/dist/index.mjs",
"@threepipe/plugin-3d-tiles-renderer": "./../../plugins/3d-tiles-renderer/dist/index.mjs"
}
}
</script>
<style id="example-style">
html, body, #canvas-container, #mcanvas {
width: 100%;
height: 100%;
margin: 0;
overflow: hidden;
}
</style>
<script type="module" src="../examples-utils/simple-code-preview.mjs"></script>
<script id="example-script" type="module" src="./script.js" data-scripts="./script.ts;./script.js"></script>
</head>
<body>
<div id="canvas-container">
<canvas id="mcanvas"></canvas>
</div>

</body>

+ 67
- 0
examples/ogc-tiles-mars/script.ts Ver fichero

@@ -0,0 +1,67 @@
import {_testFinish, FrameFadePlugin, LoadingScreenPlugin, SSAAPlugin, ThreeViewer} from 'threepipe'
import {TilesRendererPlugin} from '@threepipe/plugin-3d-tiles-renderer'
import {TweakpaneUiPlugin} from '@threepipe/plugin-tweakpane'

async function init() {

const viewer = new ThreeViewer({
canvas: document.getElementById('mcanvas') as HTMLCanvasElement,
msaa: false,
debug: false,
renderScale: 'auto',
dropzone: {
allowedExtensions: ['gltf', 'glb', 'hdr', 'bin', 'png', 'jpeg', 'webp', 'jpg', 'exr', 'json'],
addOptions: {
disposeSceneObjects: true,
autoSetEnvironment: true, // when hdr is dropped
autoSetBackground: false,
},
},
plugins: [LoadingScreenPlugin, FrameFadePlugin, SSAAPlugin],
})

viewer.scene.mainCamera.position.set(30, 30, 40)
// viewer.scene.mainCamera.position.set(300, 300, 300)
// viewer.scene.mainCamera.autoNearFar = false
// viewer.scene.mainCamera.minNearPlane = 1
// viewer.scene.mainCamera.maxFarPlane = 1000

const tiles = viewer.addPluginSync(TilesRendererPlugin)

tiles.load('https://raw.githubusercontent.com/NASA-AMMOS/3DTilesSampleData/master/msl-dingo-gap/0528_0260184_to_s64o256_colorize/0528_0260184_to_s64o256_colorize/0528_0260184_to_s64o256_colorize_tileset.json', {
autoCenter: false,
autoScale: true,
autoScaleRadius: 30,
tiles: {
TilesFadePlugin: {
fadeDuration: 2,
fadeRootTiles: true,
},
},
}).then(group => {
if (group) {
group.rotateX(Math.PI / 2)
group.tilesRenderer.errorTarget = 12
group.tilesRenderer.lruCache.minSize = 900
group.tilesRenderer.lruCache.maxSize = 1300
}
})

tiles.load('https://raw.githubusercontent.com/NASA-AMMOS/3DTilesSampleData/master/msl-dingo-gap/0528_0260184_to_s64o256_colorize/0528_0260184_to_s64o256_sky/0528_0260184_to_s64o256_sky_tileset.json', {
autoCenter: false,
autoScale: true,
autoScaleRadius: 30,
}).then(group => {
if (group) {
group.rotateX(Math.PI / 2)
// result.tilesRenderer.errorTarget = 12
}
})

const ui = viewer.addPluginSync(TweakpaneUiPlugin)
ui.setupPluginUi(TilesRendererPlugin)
// ui.setupPluginUi(PickingPlugin)

}

init().finally(_testFinish)

+ 59
- 0
examples/pnts-load/index.html Ver fichero

@@ -0,0 +1,59 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>PNTS Load</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>

<script type="importmap">
{
"imports": {
"threepipe": "./../../dist/index.mjs",
"@threepipe/plugin-3d-tiles-renderer": "./../../plugins/3d-tiles-renderer/dist/index.mjs"
}
}

</script>
<style id="example-style">
html, body, #canvas-container, #mcanvas {
width: 100%;
height: 100%;
margin: 0;
overflow: hidden;
}
</style>
<script type="module" src="../examples-utils/simple-code-preview.mjs"></script>
<script id="example-script" type="module">
import {_testFinish, LoadingScreenPlugin, ThreeViewer, Vector3} from 'threepipe'
import {PNTSLoadPlugin} from '@threepipe/plugin-3d-tiles-renderer'

const viewer = new ThreeViewer({canvas: document.getElementById('mcanvas')})
viewer.addPluginsSync([PNTSLoadPlugin, LoadingScreenPlugin])

async function init() {

viewer.scene.backgroundColor.set(0)

// await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr')

// https://github.com/CesiumGS/3d-tiles-samples
// https://github.com/NASA-AMMOS/3DTilesRendererJS
const result = await viewer.load('https://raw.githubusercontent.com/CesiumGS/3d-tiles-samples/main/1.0/TilesetWithRequestVolume/points.pnts', {
autoCenter: true,
autoScale: true,
})
console.log(result)
}

init().finally(_testFinish)
</script>
</head>
<body>
<div id="canvas-container">
<canvas id="mcanvas"></canvas>
</div>

</body>

+ 76
- 0
examples/slippy-map-tiles/index.html Ver fichero

@@ -0,0 +1,76 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Slippy Map Tiles (3D Tiles Renderer)</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>

<script type="importmap">
{
"imports": {
"threepipe": "./../../dist/index.mjs",
"@threepipe/plugin-3d-tiles-renderer": "./../../plugins/3d-tiles-renderer/dist/index.mjs"
}
}

</script>
<style id="example-style">
html, body, #canvas-container, #mcanvas {
width: 100%;
height: 100%;
margin: 0;
overflow: hidden;
}
</style>
<script type="module" src="../examples-utils/simple-code-preview.mjs"></script>
<script id="example-script" type="module" lang="ts">
import {_testFinish, LoadingScreenPlugin, ThreeViewer, SSAAPlugin} from 'threepipe'
import {SlippyMapTilesLoadPlugin} from '@threepipe/plugin-3d-tiles-renderer'

const viewer = new ThreeViewer({
canvas: document.getElementById('mcanvas'),
msaa: true, renderScale: window.devicePixelRatio,
tonemap: false,
})
viewer.addPluginsSync([SlippyMapTilesLoadPlugin, LoadingScreenPlugin, SSAAPlugin])

// todo once loaded small tiles, its not loading back the bigger ones on zoom out
// also getting weird behaviour sometimes

async function init() {

viewer.scene.mainCamera.position.set(0,0, 20)
viewer.scene.mainCamera.minNearPlane = 0.1
viewer.scene.mainCamera.setDirty()

// https://github.com/CesiumGS/3d-tiles-samples
// from https://github.com/NASA-AMMOS/3DTilesRendererJS/blob/master/example/data/root.b3dm
const result = await viewer.load('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
autoCenter: true,
autoScale: true,
autoScaleRadius: 30,
fileExtension: SlippyMapTilesLoadPlugin.DUMMY_EXT,
tiles: {
errorTarget: 1,
XYZTilesPlugin: {
projection: 'planar',
center: true
},
}
})
viewer.setDirty()
console.log(result)
// result.rotation.x = - Math.PI / 2;
}
init().finally(_testFinish)
</script>
</head>
<body>
<div id="canvas-container">
<canvas id="mcanvas"></canvas>
</div>

</body>

+ 1
- 0
examples/tweakpane-editor/index.html Ver fichero

@@ -26,6 +26,7 @@
"@threepipe/plugin-network": "./../../plugins/network/dist/index.mjs",
"@threepipe/plugin-gltf-transform": "./../../plugins/gltf-transform/dist/index.mjs",
"@threepipe/plugin-gaussian-splatting": "./../../plugins/gaussian-splatting/dist/index.mjs",
"@threepipe/plugin-3d-tiles-renderer": "./../../plugins/3d-tiles-renderer/dist/index.mjs",
"@threepipe/webgi-plugins": "https://unpkg.com/@threepipe/webgi-plugins@0.4.1/dist/index.mjs"
}
}

+ 23
- 3
examples/tweakpane-editor/script.ts Ver fichero

@@ -65,11 +65,19 @@ import {GaussianSplattingPlugin} from '@threepipe/plugin-gaussian-splatting'
import {MaterialConfiguratorPlugin, SwitchNodePlugin} from '@threepipe/plugin-configurator'
import {AWSClientPlugin, TransfrSharePlugin} from '@threepipe/plugin-network'
import {GLTFDracoExportPlugin} from '@threepipe/plugin-gltf-transform'
import {
B3DMLoadPlugin,
CMPTLoadPlugin,
DeepZoomImageLoadPlugin,
I3DMLoadPlugin,
PNTSLoadPlugin,
TilesRendererPlugin,
} from '@threepipe/plugin-3d-tiles-renderer'
// @ts-expect-error todo fix import
import {BloomPlugin, DepthOfFieldPlugin, SSContactShadowsPlugin, SSReflectionPlugin, TemporalAAPlugin, VelocityBufferPlugin, OutlinePlugin, SSGIPlugin, AnisotropyPlugin} from '@threepipe/webgi-plugins'

function checkQuery(key: string, def = true) {
return !['false', 'no', 'f'].includes(getUrlQueryParam(key, def ? 'yes' : 'no').toLowerCase())
return !['false', 'no', 'f', '0'].includes(getUrlQueryParam(key, def ? 'yes' : 'no').toLowerCase())
}

async function init() {
@@ -85,11 +93,16 @@ async function init() {
},
// set it to true if you only have opaque objects in the scene to get better performance.
zPrepass: checkQuery('depthPrepass', checkQuery('zPrepass', false)),
modelRootScale: parseFloat(getUrlQueryParam('modelRootScale', '1')),
dropzone: {
autoImport: true,
autoAdd: true,
addOptions: {
clearSceneObjects: false, // clear the scene before adding new objects on drop.
autoScale: checkQuery('autoScale', true),
autoCenter: checkQuery('autoCenter', true),
autoScaleRadius: parseFloat(getUrlQueryParam('autoScaleRadius', '2')),
clearSceneObjects: checkQuery('clearSceneObjectsOnDrop', false), // clear the scene before adding new objects on drop.
license: getUrlQueryParam('licenseText') ?? undefined, // Any license to set on imported objects
},
},
})
@@ -166,6 +179,10 @@ async function init() {
SwitchNodePlugin,
AWSClientPlugin,
TransfrSharePlugin,

// todo add these to blueprint editor, 3dviewer.xyz
B3DMLoadPlugin, I3DMLoadPlugin, PNTSLoadPlugin, CMPTLoadPlugin,
TilesRendererPlugin, DeepZoomImageLoadPlugin, /* SlippyMapTilesLoadPlugin,*/
])

KTX2LoadPlugin.SAVE_SOURCE_BLOBS = true // so that ktx files can be exported. todo - add this to blueprint editor init as well
@@ -210,7 +227,10 @@ async function init() {

const model = getUrlQueryParam('m') || getUrlQueryParam('model')
if (model) {
await viewer.load(model)
const ext = getUrlQueryParam('ext') || getUrlQueryParam('model-extension')
const loader = viewer.getPlugin(DropzonePlugin) ?? viewer
const obj = await loader.load(model, {fileExtension: ext})
console.log(obj)
}

// const result = await viewer.load<IObject3D>('https://cdn.jsdelivr.net/gh/KhronosGroup/glTF-Blender-Exporter@master/polly/project_polly.gltf', {

+ 402
- 0
plugins/3d-tiles-renderer/package-lock.json Ver fichero

@@ -0,0 +1,402 @@
{
"name": "@threepipe/plugin-3d-tiles-renderer",
"version": "0.1.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@threepipe/plugin-3d-tiles-renderer",
"version": "0.1.0",
"license": "Apache-2.0",
"dependencies": {
"three": "file:./../../src/",
"threepipe": "file:./../../src/"
},
"devDependencies": {
"3d-tiles-renderer": "^0.4.8"
}
},
"../../src": {},
"../tweakpane/src": {
"extraneous": true
},
"node_modules/@babel/runtime": {
"version": "7.27.0",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz",
"integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
"regenerator-runtime": "^0.14.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@types/react": {
"version": "19.1.2",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.2.tgz",
"integrity": "sha512-oxLPMytKchWGbnQM9O7D67uPa9paTNxO7jVoNMXgkkErULBPhPARCfkKL9ytcIJJRGjbsVwW4ugJzyFFvm/Tiw==",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
"csstype": "^3.0.2"
}
},
"node_modules/@types/react-reconciler": {
"version": "0.26.7",
"resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.26.7.tgz",
"integrity": "sha512-mBDYl8x+oyPX/VBb3E638N0B7xG+SPk/EAMcVPeexqus/5aTpTphQi0curhhshOqRrc9t6OPoJfEUkbymse/lQ==",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
"@types/react": "*"
}
},
"node_modules/@types/webxr": {
"version": "0.5.22",
"resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.22.tgz",
"integrity": "sha512-Vr6Stjv5jPRqH690f5I5GLjVk8GSsoQSYJ2FVd/3jJF7KaqfwPi3ehfBS96mlQ2kPCwZaX6U0rG2+NGHBKkA/A==",
"dev": true,
"license": "MIT",
"optional": true
},
"node_modules/3d-tiles-renderer": {
"version": "0.4.8",
"resolved": "https://registry.npmjs.org/3d-tiles-renderer/-/3d-tiles-renderer-0.4.8.tgz",
"integrity": "sha512-hMulyUC1aB6Z20XzhWaQ3jNhwmt8XFNwceFx+ynWzJx9soZpApolSib9MEdW4Yyc2m+WSIwWhe6GVmOo8LDnlQ==",
"dev": true,
"license": "Apache-2.0",
"optionalDependencies": {
"@react-three/fiber": "^8.17.9",
"react": "^18.3.1",
"react-dom": "^18.3.1"
},
"peerDependencies": {
"three": ">=0.166.0"
}
},
"node_modules/3d-tiles-renderer/node_modules/@react-three/fiber": {
"version": "8.18.0",
"resolved": "https://registry.npmjs.org/@react-three/fiber/-/fiber-8.18.0.tgz",
"integrity": "sha512-FYZZqD0UUHUswKz3LQl2Z7H24AhD14XGTsIRw3SJaXUxyfVMi+1yiZGmqTcPt/CkPpdU7rrxqcyQ1zJE5DjvIQ==",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
"@babel/runtime": "^7.17.8",
"@types/react-reconciler": "^0.26.7",
"@types/webxr": "*",
"base64-js": "^1.5.1",
"buffer": "^6.0.3",
"its-fine": "^1.0.6",
"react-reconciler": "^0.27.0",
"react-use-measure": "^2.1.7",
"scheduler": "^0.21.0",
"suspend-react": "^0.1.3",
"zustand": "^3.7.1"
},
"peerDependencies": {
"expo": ">=43.0",
"expo-asset": ">=8.4",
"expo-file-system": ">=11.0",
"expo-gl": ">=11.0",
"react": ">=18 <19",
"react-dom": ">=18 <19",
"react-native": ">=0.64",
"three": ">=0.133"
},
"peerDependenciesMeta": {
"expo": {
"optional": true
},
"expo-asset": {
"optional": true
},
"expo-file-system": {
"optional": true
},
"expo-gl": {
"optional": true
},
"react-dom": {
"optional": true
},
"react-native": {
"optional": true
}
}
},
"node_modules/3d-tiles-renderer/node_modules/scheduler": {
"version": "0.21.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz",
"integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
"loose-envify": "^1.1.0"
}
},
"node_modules/base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT",
"optional": true
},
"node_modules/buffer": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT",
"optional": true,
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.2.1"
}
},
"node_modules/csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
"dev": true,
"license": "MIT",
"optional": true
},
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "BSD-3-Clause",
"optional": true
},
"node_modules/its-fine": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/its-fine/-/its-fine-1.2.5.tgz",
"integrity": "sha512-fXtDA0X0t0eBYAGLVM5YsgJGsJ5jEmqZEPrGbzdf5awjv0xE7nqv3TVnvtUF060Tkes15DbDAKW/I48vsb6SyA==",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
"@types/react-reconciler": "^0.28.0"
},
"peerDependencies": {
"react": ">=18.0"
}
},
"node_modules/its-fine/node_modules/@types/react-reconciler": {
"version": "0.28.9",
"resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.28.9.tgz",
"integrity": "sha512-HHM3nxyUZ3zAylX8ZEyrDNd2XZOnQ0D5XfunJF5FLQnZbHHYq4UWvW1QfelQNXv1ICNkwYhfxjwfnqivYB6bFg==",
"dev": true,
"license": "MIT",
"optional": true,
"peerDependencies": {
"@types/react": "*"
}
},
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"dev": true,
"license": "MIT",
"optional": true
},
"node_modules/loose-envify": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
"js-tokens": "^3.0.0 || ^4.0.0"
},
"bin": {
"loose-envify": "cli.js"
}
},
"node_modules/react": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
"loose-envify": "^1.1.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/react-dom": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
"loose-envify": "^1.1.0",
"scheduler": "^0.23.2"
},
"peerDependencies": {
"react": "^18.3.1"
}
},
"node_modules/react-reconciler": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.27.0.tgz",
"integrity": "sha512-HmMDKciQjYmBRGuuhIaKA1ba/7a+UsM5FzOZsMO2JYHt9Jh8reCb7j1eDC95NOyUlKM9KRyvdx0flBuDvYSBoA==",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
"loose-envify": "^1.1.0",
"scheduler": "^0.21.0"
},
"engines": {
"node": ">=0.10.0"
},
"peerDependencies": {
"react": "^18.0.0"
}
},
"node_modules/react-reconciler/node_modules/scheduler": {
"version": "0.21.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz",
"integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
"loose-envify": "^1.1.0"
}
},
"node_modules/react-use-measure": {
"version": "2.1.7",
"resolved": "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.1.7.tgz",
"integrity": "sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg==",
"dev": true,
"license": "MIT",
"optional": true,
"peerDependencies": {
"react": ">=16.13",
"react-dom": ">=16.13"
},
"peerDependenciesMeta": {
"react-dom": {
"optional": true
}
}
},
"node_modules/regenerator-runtime": {
"version": "0.14.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
"integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
"dev": true,
"license": "MIT",
"optional": true
},
"node_modules/scheduler": {
"version": "0.23.2",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
"integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
"dev": true,
"license": "MIT",
"optional": true,
"dependencies": {
"loose-envify": "^1.1.0"
}
},
"node_modules/suspend-react": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/suspend-react/-/suspend-react-0.1.3.tgz",
"integrity": "sha512-aqldKgX9aZqpoDp3e8/BZ8Dm7x1pJl+qI3ZKxDN0i/IQTWUwBx/ManmlVJ3wowqbno6c2bmiIfs+Um6LbsjJyQ==",
"dev": true,
"license": "MIT",
"optional": true,
"peerDependencies": {
"react": ">=17.0"
}
},
"node_modules/three": {
"resolved": "../../src",
"link": true
},
"node_modules/threepipe": {
"resolved": "../../src",
"link": true
},
"node_modules/zustand": {
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz",
"integrity": "sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==",
"dev": true,
"license": "MIT",
"optional": true,
"engines": {
"node": ">=12.7.0"
},
"peerDependencies": {
"react": ">=16.8"
},
"peerDependenciesMeta": {
"react": {
"optional": true
}
}
}
}
}

+ 77
- 0
plugins/3d-tiles-renderer/package.json Ver fichero

@@ -0,0 +1,77 @@
{
"name": "@threepipe/plugin-3d-tiles-renderer",
"description": "Interface for 3d-tiles-renderer",
"version": "0.1.0",
"devDependencies": {
"3d-tiles-renderer": "^0.4.8"
},
"dependencies": {
"three": "file:./../../src/",
"threepipe": "file:./../../src/"
},
"overrides": {
"threepipe": "$threepipe",
"three": "$three",
"@types/three": "$@types/three"
},
"clean-package": {
"remove": [
"clean-package",
"scripts",
"devDependencies",
"//",
"markdown-to-html"
],
"replace": {
"dependencies": {},
"peerDependencies": {
"threepipe": "^0.0.41"
}
}
},
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.js"
},
"./dist/": {
"import": "./dist/",
"require": "./dist/"
}
},
"type": "module",
"main": "dist/index.js",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"files": [
"dist",
"src"
],
"scripts": {
"new:pack": "npm run prepare && clean-package && npm pack && clean-package restore",
"new:publish": "git diff --exit-code --name-only HEAD * && npm run prepare && clean-package && npm publish --access public && clean-package restore && git tag $npm_package_name-$npm_package_version",
"prepare": "npm run build && npm run docs",
"build": "rimraf dist && vite build",
"dev": "NODE_ENV=development vite build --watch",
"docs": "rimraf docs && npx typedoc"
},
"author": "repalash <palash@shaders.app>",
"license": "Apache-2.0",
"keywords": [
"three",
"three.js",
"threepipe",
"3d-tiles",
"maps"
],
"bugs": {
"url": "https://github.com/repalash/threepipe/issues"
},
"homepage": "https://github.com/repalash/threepipe#readme",
"repository": {
"type": "git",
"url": "git://github.com/repalash/threepipe.git",
"directory": "plugins/tiles-renderer-3d"
}
}

+ 64
- 0
plugins/3d-tiles-renderer/src/B3DMLoadPlugin.ts Ver fichero

@@ -0,0 +1,64 @@
import {
BaseImporterPlugin,
generateUUID,
GLTFLoader2,
IAssetImporter,
ILoader, ImportAddOptions,
Importer,
LoadingManager,
ThreeViewer,
} from 'threepipe'
import type {B3DMResult} from '3d-tiles-renderer/src/three/loaders/B3DMLoader'
import {B3DMLoader, B3DMScene, LoaderBase} from '3d-tiles-renderer'
import {GLTF} from 'three/examples/jsm/loaders/GLTFLoader'

/**
* Adds support for loading .b3dm files and data uris.
* Batched 3D Model (b3dm) file format is part of OGC 3D Tiles.
* Specification - https://www.ogc.org/standards/3dtiles/
*/
export class B3DMLoadPlugin extends BaseImporterPlugin {
public static readonly PluginType = 'B3DMLoadPlugin'
protected _importer = new Importer(B3DMLoader2, ['b3dm'], ['model/b3dm'], false)

onAdded(viewer: ThreeViewer) {
super.onAdded(viewer)
this._importer.onCtor = (l, ai) => {
if (l) l.ai = ai
return l
}
}
}

// todo no need to extend GLTFLoader2 for just transform function, it can be called manually or rewritten
export class B3DMLoader2 extends GLTFLoader2 implements ILoader<B3DMResult, B3DMScene> {
loader
ai?: IAssetImporter

constructor(manager: LoadingManager) {
super(manager)
this.loader = new B3DMLoader(manager)
}

transform(res: B3DMResult, options: ImportAddOptions): B3DMScene {
return super.transform(res, options) as any
}

parse(data: ArrayBuffer, _path: string, onLoad: (gltf: GLTF) => void, onError?: (event: ErrorEvent) => void, _url?: string) {
if (!this.ai) {
console.error('[B3DMLoader] load failed, IAssetImporter not set')
}
const tmpFile = generateUUID() + '.gltf'
this.ai?.registerFile(tmpFile) // to set the gltf loader in manager

;(this.loader as LoaderBase).workingPath = _path

this.loader.parse(data)
.then(onLoad)
.catch(onError)
.finally(() => {
if (tmpFile) this.ai?.unregisterFile(tmpFile)
})
// super.parse(data, path, onLoad, onError, url)
}
}

+ 144
- 0
plugins/3d-tiles-renderer/src/CMPTLoadPlugin.ts Ver fichero

@@ -0,0 +1,144 @@
import {
AnyOptions,
BaseImporterPlugin,
FileLoader, generateUUID,
Group,
IAssetImporter,
ILoader,
Importer,
Loader,
LoaderUtils,
LoadingManager,
ThreeViewer,
} from 'threepipe'
import type {CMPTResult} from '3d-tiles-renderer/src/three/loaders/CMPTLoader'
import {CMPTLoader, LoaderBase} from '3d-tiles-renderer'

/**
* Adds support for loading .cmpt files and data uris.
* Composite (cmpt) file format is part of OGC 3D Tiles.
* Specification - https://www.ogc.org/standards/3dtiles/
*/
export class CMPTLoadPlugin extends BaseImporterPlugin {
public static readonly PluginType = 'CMPTLoadPlugin'
protected _importer = new Importer(CMPTLoader2, ['cmpt'], ['model/cmpt'], false)

onAdded(viewer: ThreeViewer) {
super.onAdded(viewer)
this._importer.onCtor = (l, ai) => {
if (l) l.ai = ai
return l
}
}
}

export class CMPTLoader2 extends Loader implements ILoader<CMPTResult, Group> {
loader
ai?: IAssetImporter

constructor(manager: LoadingManager) {
super(manager)
this.loader = new CMPTLoader(manager)
}


load(url: string, onLoad: (data: unknown) => void, onProgress?: (event: ProgressEvent) => void, onError?: (err: unknown) => void) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const scope = this

let resourcePath

if (this.resourcePath !== '') {

resourcePath = this.resourcePath

} else if (this.path !== '') {

resourcePath = this.path

} else {

resourcePath = LoaderUtils.extractUrlBase(url)

}

// Tells the LoadingManager to track an extra item, which resolves after
// the model is fully loaded. This means the count of items loaded will
// be incorrect, but ensures manager.onLoad() does not fire early.
this.manager.itemStart(url)

// eslint-disable-next-line @typescript-eslint/naming-convention
const _onError = function(e: any) {

if (onError) {

onError(e)

} else {

console.error(e)

}

scope.manager.itemError(url)
scope.manager.itemEnd(url)

}

const loader = new FileLoader(this.manager)

loader.setPath(this.path)
loader.setResponseType('arraybuffer')
loader.setRequestHeader(this.requestHeader)
loader.setWithCredentials(this.withCredentials)

loader.load(url, function(data) {

try {

scope.parse(data as any, resourcePath, function(gltf) {

onLoad(gltf)

scope.manager.itemEnd(url)

}, _onError, url)

} catch (e) {

_onError(e)

}

}, onProgress, _onError)

}

transform(res: CMPTResult, _options: AnyOptions): Group {
return res.scene
}

parse(data: ArrayBuffer, _path: string, onLoad: (res: CMPTResult) => void, onError?: (event: ErrorEvent) => void, _url?: string) {
if (!this.ai) {
console.error('[CMPTLoader] load failed, IAssetImporter not set')
}
// todo register draco for inside pnts files

const tmpFile = generateUUID()
this.ai?.registerFile(tmpFile + '.gltf') // to set the gltf loader in manager
this.ai?.registerFile(tmpFile + '.drc') // to set the draco loader in manager

;(this.loader as LoaderBase).workingPath = _path

this.loader.parse(data)
.then(onLoad)
.catch(onError)
.finally(() => {
if (tmpFile && this.ai) {
this.ai.unregisterFile(tmpFile + '.gltf')
this.ai.unregisterFile(tmpFile + '.drc')
}
})
// super.parse(data, path, onLoad, onError, url)
}
}

+ 49
- 0
plugins/3d-tiles-renderer/src/DeepZoomImageLoadPlugin.ts Ver fichero

@@ -0,0 +1,49 @@
import {BaseImporterPlugin, Importer, LoadingManager, ThreeViewer} from 'threepipe'
// @ts-expect-error moduleResolution issue
import {DeepZoomImagePlugin} from '3d-tiles-renderer/plugins'
import {TilesRendererLoader, TilesRendererPlugin} from './TilesRendererPlugin'

/**
* Adds support for loading .dzi files and data uris.
* Deep Zoom Image (dzi) file format - https://openseadragon.github.io/
*/
export class DeepZoomImageLoadPlugin extends BaseImporterPlugin {
public static readonly PluginType = 'DeepZoomImageLoadPlugin'
protected _importer = new Importer(DeepZoomImageLoader, ['dzi'], ['image/dzi'], false)

dependencies = [TilesRendererPlugin]

onAdded(viewer: ThreeViewer) {
super.onAdded(viewer)
this._importer.onCtor = (l, ai) => {
if (l) l.ai = ai
return l
}
}
}

export class DeepZoomImageLoader extends TilesRendererLoader {
constructor(manager: LoadingManager) {
super(manager)
this.plugins.push(
(opts)=>{
if (opts?.DeepZoomImagePlugin === false) return undefined
const op = typeof opts?.DeepZoomImagePlugin === 'object' ? opts.DeepZoomImagePlugin : {}
return new DeepZoomImagePlugin({
// center: true,
...op,
})
},
)
}
}

declare module 'TilesRendererPlugin'{
interface TilesImportOptions {
DeepZoomImagePlugin?: boolean | {
center?: boolean,
pixelSize?: number,
useRecommendedSettings?: boolean,
}
}
}

+ 65
- 0
plugins/3d-tiles-renderer/src/I3DMLoadPlugin.ts Ver fichero

@@ -0,0 +1,65 @@
import {
BaseImporterPlugin,
generateUUID,
GLTF,
GLTFLoader2,
IAssetImporter,
ILoader,
ImportAddOptions,
Importer,
LoadingManager,
ThreeViewer,
} from 'threepipe'
import type {I3DMResult} from '3d-tiles-renderer/src/three/loaders/I3DMLoader'
import {I3DMLoader, I3DMScene, LoaderBase} from '3d-tiles-renderer'

/**
* Adds support for loading .i3dm files and data uris.
* Instanced 3D Model (i3dm) file format is part of OGC 3D Tiles.
* Specification - https://www.ogc.org/standards/3dtiles/
*/
export class I3DMLoadPlugin extends BaseImporterPlugin {
public static readonly PluginType = 'I3DMLoadPlugin'
protected _importer = new Importer(I3DMLoader2, ['i3dm'], ['model/i3dm'], false)

onAdded(viewer: ThreeViewer) {
super.onAdded(viewer)
this._importer.onCtor = (l, ai) => {
if (l) l.ai = ai
return l
}
}
}

// todo no need to extend GLTFLoader2 for just transform function, it can be called manually or rewritten
export class I3DMLoader2 extends GLTFLoader2 implements ILoader<I3DMResult, I3DMScene> {
loader
ai?: IAssetImporter

constructor(manager: LoadingManager) {
super(manager)
this.loader = new I3DMLoader(manager)
}

transform(res: I3DMResult, options: ImportAddOptions): I3DMScene {
return super.transform(res, options) as any
}

parse(data: ArrayBuffer, _path: string, onLoad: (gltf: GLTF) => void, onError?: (event: ErrorEvent) => void, _url?: string) {
if (!this.ai) {
console.error('[I3DMLoader] load failed, IAssetImporter not set')
}
const tmpFile = generateUUID() + '.gltf'
this.ai?.registerFile(tmpFile) // to set the gltf loader in manager

;(this.loader as LoaderBase).workingPath = _path

this.loader.parse(data)
.then(onLoad)
.catch(onError)
.finally(() => {
if (tmpFile) this.ai?.unregisterFile(tmpFile)
})
// super.parse(data, path, onLoad, onError, url)
}
}

+ 137
- 0
plugins/3d-tiles-renderer/src/PNTSLoadPlugin.ts Ver fichero

@@ -0,0 +1,137 @@
import {
AnyOptions,
BaseImporterPlugin,
FileLoader, generateUUID,
IAssetImporter,
ILoader,
Importer,
Loader,
LoaderUtils,
LoadingManager,
ThreeViewer,
} from 'threepipe'
import type {PNTSResult} from '3d-tiles-renderer/src/three/loaders/PNTSLoader'
import {LoaderBase, PNTSLoader, PNTSScene} from '3d-tiles-renderer'

/**
* Adds support for loading .pnts files and data uris.
* Point Cloud (pnts) file format is part of OGC 3D Tiles.
* Specification - https://www.ogc.org/standards/3dtiles/
*/
export class PNTSLoadPlugin extends BaseImporterPlugin {
public static readonly PluginType = 'PNTSLoadPlugin'
protected _importer = new Importer(PNTSLoader2, ['pnts'], ['model/pnts'], false)

onAdded(viewer: ThreeViewer) {
super.onAdded(viewer)
this._importer.onCtor = (l, ai) => {
if (l) l.ai = ai
return l
}
}
}

export class PNTSLoader2 extends Loader implements ILoader<PNTSResult, PNTSScene> {
loader
ai?: IAssetImporter

constructor(manager: LoadingManager) {
super(manager)
this.loader = new PNTSLoader(manager)
}

load(url: string, onLoad: (data: unknown) => void, onProgress?: (event: ProgressEvent) => void, onError?: (err: unknown) => void) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const scope = this

let resourcePath

if (this.resourcePath !== '') {

resourcePath = this.resourcePath

} else if (this.path !== '') {

resourcePath = this.path

} else {

resourcePath = LoaderUtils.extractUrlBase(url)

}

// Tells the LoadingManager to track an extra item, which resolves after
// the model is fully loaded. This means the count of items loaded will
// be incorrect, but ensures manager.onLoad() does not fire early.
this.manager.itemStart(url)

// eslint-disable-next-line @typescript-eslint/naming-convention
const _onError = function(e: any) {

if (onError) {

onError(e)

} else {

console.error(e)

}

scope.manager.itemError(url)
scope.manager.itemEnd(url)

}

const loader = new FileLoader(this.manager)

loader.setPath(this.path)
loader.setResponseType('arraybuffer')
loader.setRequestHeader(this.requestHeader)
loader.setWithCredentials(this.withCredentials)

loader.load(url, function(data) {

try {

scope.parse(data as any, resourcePath, function(gltf) {

onLoad(gltf)

scope.manager.itemEnd(url)

}, _onError, url)

} catch (e) {

_onError(e)

}

}, onProgress, _onError)

}

transform(res: PNTSResult, _options: AnyOptions): PNTSScene {
return res.scene
}

parse(data: ArrayBuffer, _path: string, onLoad: (res: PNTSResult) => void, onError?: (event: ErrorEvent) => void, _url?: string) {
if (!this.ai) {
console.error('[PNTSLoader] load failed, IAssetImporter not set')
}

const tmpFile = generateUUID() + '.drc'
this.ai?.registerFile(tmpFile) // to set the draco loader in manager

;(this.loader as LoaderBase).workingPath = _path

this.loader.parse(data)
.then(onLoad)
.catch(onError)
.finally(() => {
if (tmpFile) this.ai?.unregisterFile(tmpFile)
})
// super.parse(data, path, onLoad, onError, url)
}
}

+ 50
- 0
plugins/3d-tiles-renderer/src/SlippyMapTilesLoadPlugin.ts Ver fichero

@@ -0,0 +1,50 @@
import {BaseImporterPlugin, Importer, LoadingManager, ThreeViewer} from 'threepipe'
// @ts-expect-error moduleResolution issue
import {XYZTilesPlugin} from '3d-tiles-renderer/plugins'
import {TilesRendererLoader, TilesRendererPlugin} from './TilesRendererPlugin'

/**
* Adds support for loading slippy map tiles(OpenStreetMap) in png format
* https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
*/
export class SlippyMapTilesLoadPlugin extends BaseImporterPlugin {
public static readonly PluginType = 'SlippyMapTilesLoadPlugin'
static readonly DUMMY_EXT = 'xyztiles'
protected _importer = new Importer(SlippyMapTilesLoader, [SlippyMapTilesLoadPlugin.DUMMY_EXT], [], false)

dependencies = [TilesRendererPlugin]

onAdded(viewer: ThreeViewer) {
super.onAdded(viewer)
this._importer.onCtor = (l, ai) => {
if (l) l.ai = ai
return l
}
}
}

export class SlippyMapTilesLoader extends TilesRendererLoader {
constructor(manager: LoadingManager) {
super(manager)
this.plugins.push(
(opts)=>{
if (opts?.XYZTilesPlugin === false) return undefined
const op = typeof opts?.XYZTilesPlugin === 'object' ? opts.XYZTilesPlugin : {}
return new XYZTilesPlugin(op)
},
)
}
}

declare module 'TilesRendererPlugin'{
interface TilesImportOptions {
XYZTilesPlugin?: boolean | {
levels: number // default = 20,
tileDimension: number // default = 256,
pixelSize: number // default = 1e-5,
center?: boolean,
projection?: 'ellipsoid' | 'planar',
useRecommendedSettings?: boolean,
}
}
}

+ 339
- 0
plugins/3d-tiles-renderer/src/TilesRendererPlugin.ts Ver fichero

@@ -0,0 +1,339 @@
import {
AViewerPluginEventMap,
AViewerPluginSync,
Box3B,
EventListener2,
generateUUID,
IAssetImporter,
ILoader,
Importer,
IObject3D,
iObjectCommons,
IRenderManager,
IRenderManagerEventMap,
IScene,
ISceneEventMap,
Loader,
ImportAddOptions,
LoadingManager,
ThreeViewer,
} from 'threepipe'
import {TilesGroup, TilesRenderer} from '3d-tiles-renderer'
import {gltfCesiumRTCExtension, gltfMeshFeaturesExtension, gltfStructuralMetadataExtension} from './gltf'
// @ts-expect-error moduleResolution issue
import {ImplicitTilingPlugin, TilesFadePlugin, UpdateOnChangePlugin, CesiumIonAuthPlugin} from '3d-tiles-renderer/plugins'
import {Sphere} from 'three'

export type TilesRendererGroup = TilesGroup & IObject3D

export interface TilesRendererPluginEventMap extends AViewerPluginEventMap {
addTile: {group: TilesRendererGroup}
removeTile: {group: TilesRendererGroup}
}

/**
* TilesRendererPlugin is a plugin for loading and rendering OGC 3D Tiles using [3d-tiles-renderer](https://github.com/NASA-AMMOS/3DTilesRendererJS) package.
*
* Specification - https://www.ogc.org/standards/3dtiles/
*/
export class TilesRendererPlugin extends AViewerPluginSync<TilesRendererPluginEventMap> {
public static readonly PluginType: string = 'TilesRendererPlugin'
enabled = true
dependencies = []

static readonly DUMMY_EXT = 'tileset'

objects: TilesRendererGroup[] = []

protected _importer = new Importer(TilesRendererLoader, [TilesRendererPlugin.DUMMY_EXT, TilesRendererPlugin.DUMMY_EXT + '.json'], [], false)

constructor() {
super()
}

async load(url: string, options?: ImportAddOptions) {
if (!this._viewer) {
console.warn('TilesRendererPlugin: viewer not set')
return
}
const temp = generateUUID() + '.' + TilesRendererPlugin.DUMMY_EXT
const importer = this._viewer.assetManager.importer.registerFile(temp) as TilesRendererLoader
if (!importer.isTilesRendererLoader) {
console.warn('TilesRendererPlugin: TilesRendererLoader not registered')
return
}
return await this._viewer.load<TilesRendererGroup>(url, {
...options,
fileExtension: TilesRendererPlugin.DUMMY_EXT,
fileHandler: importer,
})
}

async loadCesiumIon(info: TilesImportOptions['CesiumIonAuthPlugin'], options?: ImportAddOptions) {
const file = generateUUID() + '.' + TilesRendererPlugin.DUMMY_EXT
return this.load(file, {
...options,
tiles: {
CesiumIonAuthPlugin: info,
...options?.tiles,
},
})
}

onAdded(viewer: ThreeViewer) {
super.onAdded(viewer)
this._importer.onCtor = (l, ai) => {
if (l) l.ai = ai
return l
}
viewer.assetManager.registerGltfExtension(gltfCesiumRTCExtension)
viewer.assetManager.registerGltfExtension(gltfStructuralMetadataExtension)
viewer.assetManager.registerGltfExtension(gltfMeshFeaturesExtension)
viewer.assetManager.importer.addImporter(this._importer)
viewer.scene.addEventListener('addSceneObject', this._addSceneObject)
// viewer.scene.addEventListener('mainCameraChange', this._mainCameraChange)
// viewer.scene.addEventListener('mainCameraUpdate', this._mainCameraUpdate)
viewer.renderManager.addEventListener('preRender', this._preRender) // note - adding to renderManager preRender, not viewer. So its fired for each camera render
viewer.renderManager.addEventListener('resize', this._resize)
}

onRemove(viewer: ThreeViewer) {
viewer.assetManager.importer.removeImporter(this._importer)
viewer.assetManager.unregisterGltfExtension(gltfCesiumRTCExtension.name)
viewer.assetManager.unregisterGltfExtension(gltfStructuralMetadataExtension.name)
viewer.assetManager.unregisterGltfExtension(gltfMeshFeaturesExtension.name)
viewer.scene.removeEventListener('addSceneObject', this._addSceneObject)
// viewer.scene.removeEventListener('mainCameraChange', this._mainCameraChange)
// viewer.scene.removeEventListener('mainCameraUpdate', this._mainCameraUpdate)
viewer.renderManager.removeEventListener('preRender', this._preRender)
viewer.renderManager.removeEventListener('resize', this._resize)
// todo dispose all tiles renderers?
super.onRemove(viewer)
}

private _preRender/* : EventListener2<'preRender', ThreeViewerEventMap, ThreeViewer>*/ = () => {
const camera = this._viewer?.scene.renderCamera
if (!this._viewer || !camera) return
if (this._viewer.renderManager.frameCount > 0) return // from ProgressivePlugin
camera.updateProjectionMatrix()
camera.updateMatrixWorld()
for (const group of this.objects) {
// todo do we need to do this every frame for every camera?
group.tilesRenderer.setCamera(camera)
group.tilesRenderer.setResolutionFromRenderer(camera, this._viewer.renderManager.webglRenderer)
// group.tilesRenderer.frameCount = 0
// console.log('update tiles renderer')
group.tilesRenderer.update()
}
}

// private _mainCameraUpdate: EventListener2<'mainCameraUpdate', ISceneEventMap, IScene> = (e) => {
// const camera = e.camera ?? this._viewer?.scene.mainCamera
// if (!this._viewer || !camera) return
// camera.updateProjectionMatrix()
// camera.updateMatrixWorld()
// for (const group of this.objects) {
// group.tilesRenderer.update()
// }
// }
//
// private _mainCameraChange: EventListener2<'mainCameraChange', ISceneEventMap, IScene> = (e) => {
// const camera = e.camera
// if (!this._viewer) return
// for (const group of this.objects) {
// // todo deleteCamera?
// group.tilesRenderer.setCamera(camera)
// group.tilesRenderer.setResolutionFromRenderer(camera, this._viewer.renderManager.webglRenderer)
// }
// }

private _resize: EventListener2<'resize', IRenderManagerEventMap, IRenderManager> = () => {
if (!this._viewer) return
for (const group of this.objects) {
group.tilesRenderer.setResolutionFromRenderer(this._viewer.scene.mainCamera, this._viewer.renderManager.webglRenderer)
}
}

private _cachedRefs?: Pick<TilesRenderer, 'lruCache' | 'downloadQueue' | 'parseQueue'/* | 'processNodeQueue'*/>

private _addSceneObject: EventListener2<'addSceneObject', ISceneEventMap, IScene> = (e)=>{
const object = e.object
const group = object as TilesRendererGroup
// console.log(e)
if (!group || !group.tilesRenderer || !this._viewer) return

// set the second renderer to share the cache and queues from the first
if (!this._cachedRefs) {
this._cachedRefs = {
lruCache: group.tilesRenderer.lruCache,
downloadQueue: group.tilesRenderer.downloadQueue,
parseQueue: group.tilesRenderer.parseQueue,
// @ts-expect-error not in ts
processNodeQueue: group.tilesRenderer.processNodeQueue,
}
} else {
group.tilesRenderer.lruCache = this._cachedRefs.lruCache
group.tilesRenderer.downloadQueue = this._cachedRefs.downloadQueue
group.tilesRenderer.parseQueue = this._cachedRefs.parseQueue
// @ts-expect-error not in ts
group.tilesRenderer.processNodeQueue = this._cachedRefs.processNodeQueue
}

this.objects.push(group)

group.tilesRenderer.registerPlugin({
dispose: () => {
const index = this.objects.indexOf(group)
if (index !== -1) this.objects.splice(index, 1)
this.dispatchEvent({type: 'removeTile', group})
},
})
group.tilesRenderer.setCamera(this._viewer.scene.mainCamera)
group.tilesRenderer.setResolutionFromRenderer(this._viewer.scene.mainCamera, this._viewer.renderManager.webglRenderer)
group.tilesRenderer.update()
group.addEventListener('dispose', ()=>{
group.tilesRenderer.dispose()
})

this.dispatchEvent({type: 'addTile', group})
}

}

export class TilesRendererLoader extends Loader implements ILoader<TilesRendererGroup> {
isTilesRendererLoader = true
ai?: IAssetImporter
importOptions?: ImportAddOptions

plugins: ((o: TilesImportOptions, group: TilesRendererGroup)=>object|undefined)[] = [
()=>new UpdateOnChangePlugin(),
(opts)=>opts?.ImplicitTilingPlugin !== false ? new ImplicitTilingPlugin() : undefined,
(opts)=>opts?.TilesFadePlugin !== false ? new TilesFadePlugin(typeof opts?.TilesFadePlugin === 'object' ? opts.TilesFadePlugin : undefined) : undefined,
(opts)=>opts?.CesiumIonAuthPlugin ? new CesiumIonAuthPlugin(typeof opts?.CesiumIonAuthPlugin === 'object' ? opts.CesiumIonAuthPlugin : undefined) : undefined,
]

constructor(manager: LoadingManager) {
super(manager)
}

protected _createTilesRenderer(url: string) {

const tiles = new TilesRenderer(url)
tiles.manager = this.manager
tiles.fetchOptions.headers = new Headers(this.requestHeader)
tiles.fetchOptions.credentials = this.withCredentials ? 'include' : 'same-origin'
tiles.fetchOptions.mode = 'cors'

return tiles
}

load(url: string, onLoad: (data: unknown) => void, _onProgress?: (event: ProgressEvent) => void, _onError?: (err: unknown) => void) {
// todo
// let resourcePath = this.resourcePath || this.path || LoaderUtils.extractUrlBase(url)

const tiles = this._createTilesRenderer(url)
const group = iObjectCommons.upgradeObject3D.call(tiles.group) as TilesRendererGroup
group.autoUpgradeChildren = false

const opts = this.importOptions?.tiles ?? {}
tiles.errorTarget = opts.errorTarget ?? 1
const plugins = [...this.plugins, ...opts.plugins ?? []]
for (const plugin of plugins) {
const p = plugin(opts, group)
if (p) tiles.registerPlugin(p)
}

// bounds, similar to InstancedMesh
group.boundingBox = null
group.boundingSphere = null
group.computeBoundingBox = ()=>{
if (!group.boundingBox) group.boundingBox = new Box3B()
tiles.getBoundingBox(group.boundingBox)
}
group.computeBoundingSphere = ()=>{
if (!group.boundingSphere) group.boundingSphere = new Sphere()
tiles.getBoundingSphere(group.boundingSphere)
}
tiles.addEventListener('load-tile-set', (_e) => {
group.computeBoundingBox!()
group.computeBoundingSphere!()
})

// Save promise to tell the viewer/scene when the load is finished, it can then autoScale, autoCenter etc
let resolve: any
// let reject: any
group._loadingPromise = new Promise<void>((res, _rej) => {
resolve = res
// reject = _rej
})
tiles.addEventListener('load-tile-set', (e) => {
const isRoot = e.tileSet === tiles.rootTileSet
if (isRoot && resolve) resolve()
})

const ai = this.ai
if (ai) {
const tmpFile = generateUUID()
ai.registerFile(tmpFile + '.gltf') // to set the gltf loader in manager
ai.registerFile(tmpFile + '.drc') // to set the draco loader in manager

const preprocessUrl = (url1: string) => {
if (tiles.preprocessURL) return tiles.preprocessURL(url1)
return url1
}
ai.addURLModifier(preprocessUrl)
tiles.registerPlugin({
dispose: () => {
if (ai) {
ai.unregisterFile(tmpFile + '.gltf')
ai.unregisterFile(tmpFile + '.drc')
ai.removeURLModifier(preprocessUrl)
}
},
})

}

tiles.addEventListener('tile-visibility-change', (_e) => {
// console.log(e)
})

const setDirty = (_e: any)=>{
// console.log(e)
group.setDirty({frameFade: false})
}
tiles.addEventListener('load-content', setDirty)
tiles.addEventListener('load-tile-set', setDirty)
tiles.addEventListener('force-rerender', setDirty)

// tiles.update()
onLoad(group)

}

}

export interface TilesImportOptions{
/**
* @default 1
*/
errorTarget?: number
ImplicitTilingPlugin?: boolean
TilesFadePlugin?: boolean | {
maximumFadeOutTiles?: number,
fadeRootTiles?: boolean,
fadeDuration?: number,
}
CesiumIonAuthPlugin?: boolean | {
apiToken: string,
assetId?: string | null,
autoRefreshToken?: boolean
}
plugins?: ((opts: TilesImportOptions, group: TilesRendererGroup)=>object|undefined)[]
}

declare module 'threepipe'{
interface ImportAddOptions {
tiles?: TilesImportOptions
}
}

+ 40
- 0
plugins/3d-tiles-renderer/src/global.d.ts Ver fichero

@@ -0,0 +1,40 @@
declare module '*.txt' {
const content: string
export default content
}
declare module '*.glsl' {
const content: string
export default content
}
declare module '*.vert' {
const content: string
export default content
}
declare module '*.frag' {
const content: string
export default content
}
declare module '*.module.scss' {
const content: any
export default content
export const stylesheet: string
}
declare module '*.module.css' {
const content: any
export default content
export const stylesheet: string
}
declare module '*.css' {
const content: string
export default content
}
declare module '*.css?inline' { // for vite
const content: string
export default content
}

// export {}

// hack for typedoc
// eslint-disable-next-line @typescript-eslint/naming-convention
// declare type OffscreenCanvas = HTMLCanvasElement

+ 40
- 0
plugins/3d-tiles-renderer/src/gltf.ts Ver fichero

@@ -0,0 +1,40 @@
import {
GLTFCesiumRTCExtension,
GLTFMeshFeaturesExtension,
GLTFStructuralMetadataExtension,
// @ts-expect-error moduleResolution issue
} from '3d-tiles-renderer/plugins'
import {AssetManager} from 'threepipe'

export const gltfCesiumRTCExtension = {
name: 'CESIUM_RTC' satisfies GLTFCesiumRTCExtension['name'],
import: (_p)=>new GLTFCesiumRTCExtension(),
export: (_w)=>({
// todo - save center in userData and access to write back as extension value
}),
textures: undefined,
} satisfies AssetManager['gltfExtensions'][number]

export const gltfStructuralMetadataExtension = {
name: 'EXT_structural_metadata' satisfies GLTFStructuralMetadataExtension['name'],
import: (_p)=>new GLTFStructuralMetadataExtension(),
export: (_w)=>({
// todo
// beforeParse: ()=>{
// throw new Error('not implemented')
// },
}),
textures: undefined,
} satisfies AssetManager['gltfExtensions'][number]

export const gltfMeshFeaturesExtension = {
name: 'EXT_mesh_features' satisfies GLTFMeshFeaturesExtension['name'],
import: (_p)=>new GLTFMeshFeaturesExtension(),
export: (_w)=>({
// todo
// beforeParse: ()=>{
// throw new Error('not implemented')
// },
}),
// textures: undefined, // todo
} satisfies AssetManager['gltfExtensions'][number]

+ 14
- 0
plugins/3d-tiles-renderer/src/index.ts Ver fichero

@@ -0,0 +1,14 @@
export {TilesRendererPlugin, TilesRendererLoader, type TilesRendererGroup, type TilesImportOptions} from './TilesRendererPlugin'
export {B3DMLoadPlugin} from './B3DMLoadPlugin'
export {I3DMLoadPlugin} from './I3DMLoadPlugin'
export {PNTSLoadPlugin} from './PNTSLoadPlugin'
export {CMPTLoadPlugin} from './CMPTLoadPlugin'
export {DeepZoomImageLoadPlugin} from './DeepZoomImageLoadPlugin'
export {SlippyMapTilesLoadPlugin} from './SlippyMapTilesLoadPlugin'
export {
CesiumIonAuthPlugin,
ReorientationPlugin,
DebugTilesPlugin, GoogleCloudAuthPlugin,
LoadRegionPlugin, UnloadTilesPlugin, TileCompressionPlugin,
// @ts-expect-error moduleResolution issue
} from '3d-tiles-renderer/plugins'

+ 41
- 0
plugins/3d-tiles-renderer/tsconfig.json Ver fichero

@@ -0,0 +1,41 @@
{
"compilerOptions": {
"baseUrl": "./src",
"rootDir": "./src",
"allowJs": true,
"checkJs": false,
"skipLibCheck": true,
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
"isolatedModules": true,
"module": "es2020",
"noImplicitAny": true,
"declaration": true,
"declarationMap": true,
"declarationDir": "dist",
"outDir": "dist",
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"removeComments": false,
"preserveConstEnums": true,
"moduleResolution": "node",
"emitDecoratorMetadata": false,
"sourceMap": true,
"target": "ES2021",
"strictNullChecks": true,
"lib": [
"es2020",
"esnext",
"dom"
]
},
"include": [
"src/**/*"
],
"exclude": [
"node_modules",
"**/*.spec.ts",
"dist"
]
}

+ 10
- 0
plugins/3d-tiles-renderer/typedoc.json Ver fichero

@@ -0,0 +1,10 @@
{
"extends": [
"../../typedoc.json"
],
"entryPoints": [
"src/index.ts"
],
"name": "Threepipe 3D Tiles Renderer and Importer Plugins",
"readme": "none"
}

+ 100
- 0
plugins/3d-tiles-renderer/vite.config.js Ver fichero

@@ -0,0 +1,100 @@
import {defineConfig} from 'vite'
import json from '@rollup/plugin-json';
import dts from 'vite-plugin-dts'
import packageJson from './package.json';
import license from 'rollup-plugin-license';
import replace from '@rollup/plugin-replace';
import glsl from 'rollup-plugin-glsl';
import path from 'node:path';

const isProd = process.env.NODE_ENV === 'production'
const { name, version, author } = packageJson
const {main, module, browser} = packageJson

const globals = {
'three': 'threepipe', // just incase someone uses three
'threepipe': 'threepipe',
}

export default defineConfig({
optimizeDeps: {
exclude: ['uiconfig.js', 'ts-browser-helpers'],
},
base: '',
// define: {
// 'process.env': process.env
// },
build: {
sourcemap: true,
minify: false,
cssMinify: isProd,
cssCodeSplit: false,
watch: !isProd ? {
buildDelay: 1000,
} : null,
lib: {
entry: 'src/index.ts',
formats: isProd ? ['es', 'umd'] : ['es'],
name: name,
fileName: (format) => (format === 'umd' ? main : module).replace('dist/', ''),
},
outDir: 'dist',
emptyOutDir: isProd,
commonjsOptions: {
exclude: [/uiconfig.js/, /ts-browser-helpers/],
},
rollupOptions: {
output: {
// inlineDynamicImports: false,
globals,
},
external: Object.keys(globals),

},
},
plugins: [
isProd ? dts({tsconfigPath: './tsconfig.json'}) : null,
replace({
'from \'three\'': 'from \'threepipe\'',
// 'from \'three/examples/jsm/.*\'': 'from \'threepipe\'', // todo regex doesnt work...
'from \'three/examples/jsm/loaders/GLTFLoader.js\'': 'from \'threepipe\'',
'from \'three/examples/jsm/postprocessing/Pass.js\'': 'from \'threepipe\'',
'from \'three/examples/jsm/utils/BufferGeometryUtils.js\'': 'from \'threepipe\'',
delimiters: ['', ''],
preventAssignment: true,
}),
replace({ // this is added to throw an error, in that case, add it to above
'from \'three/': 'from \'unknown/',
delimiters: ['', ''],
preventAssignment: true,
}),
replace({
'process.env.NODE_ENV': JSON.stringify(isProd ? 'production' : 'development'),
preventAssignment: true,
}),
glsl({ // todo: minify glsl.
include: 'src/**/*.glsl',
}),
json(),
// postcss({
// modules: false,
// autoModules: true, // todo; issues with typescript import css, because inject is false
// inject: false,
// minimize: isProduction,
// // Or with custom options for `postcss-modules`
// }),
license({
banner: `
@license
${name} v${version}
Copyright 2022<%= moment().format('YYYY') > 2022 ? '-' + moment().format('YYYY') : null %> ${author}
${packageJson.license} License
See ./dependencies.txt for any bundled third-party dependencies and licenses.
`,
thirdParty: {
output: path.join(__dirname, 'dist', 'dependencies.txt'),
includePrivate: true, // Default is false.
},
}),
],
})

+ 4
- 3
website/.vitepress/config.ts Ver fichero

@@ -168,13 +168,14 @@ export default defineConfig({
{text: 'Blueprint.js Plugin', link: 'package/plugin-blueprintjs'},
{text: 'Tweakpane Editor Plugin', link: 'package/plugin-tweakpane-editor'},
{text: 'Configurator Plugins', link: 'package/plugin-configurator'},
{text: 'Network Plugin', link: 'package/plugin-network'},
{text: 'Geometry Generator Plugin', link: 'package/plugin-geometry-generator'},
{text: 'glTF Transform Plugin', link: 'package/plugin-gltf-transform'},
{text: 'svg-renderer Plugin', link: 'package/plugin-svg-renderer'},
{text: 'Extra Importers Plugins', link: 'package/plugins-extra-importers'},
{text: 'Gaussian Splatting Plugin', link: 'package/plugin-gaussian-splatting'},
{text: 'Network Plugin', link: 'package/plugin-network'},
{text: 'Blend Importer Plugin', link: 'package/plugin-blend-importer'},
{text: 'Gaussian Splatting Plugin', link: 'package/plugin-gaussian-splatting'},
{text: 'svg-renderer Plugin', link: 'package/plugin-svg-renderer'},
{text: 'Tiles (OGC) Renderer Plugin', link: 'package/plugin-3d-tiles-renderer'},
]
},
],

+ 2
- 0
website/guide/threepipe-packages.md Ver fichero

@@ -29,3 +29,5 @@ Checkout the [model-viewer](https://threepipe.org/examples/#model-viewer) or [tw
- [@threepipe/plugin-blend-importer](../package/plugin-blend-importer) - Add support for loading .blend file. (Partial/WIP) ([Blender](https://www.blender.org/))
- [@threepipe/plugin-gaussian-splatting](../package/plugin-gaussian-splatting) - [3D Gaussian Splatting](https://repo-sam.inria.fr/fungraph/3d-gaussian-splatting/) plugin for loading and rendering splat files
- [@threepipe/plugin-svg-renderer](../package/plugin-svg-renderer) - Add support for exporting 3d scene as SVG (WIP) using [three-svg-renderer](https://www.npmjs.com/package/three-svg-renderer).
- [@threepipe/plugin-3d-tiles-renderer](https://threepipe.org/package/plugin-3d-tiles-renderer.html) - Plugins for [3d-tiles-renderer](https://github.com/NASA-AMMOS/3DTilesRendererJS), b3dm, i3dm, cmpt, pnts importers.
- [@threepipe/webgi-plugins](https://webgi.dev) - Web [Global Illumination](https://en.wikipedia.org/wiki/Global_illumination) - Realistic rendering plugin pack (SSR, SSRTAO, HDR Bloom, TAA, Depth of Field, SSGI, etc.)

+ 217
- 0
website/package/plugin-3d-tiles-renderer.md Ver fichero

@@ -0,0 +1,217 @@
---
prev:
text: '@threepipe/plugin-svg-renderer'
link: './plugin-svg-renderer'

next: false
---

# @threepipe/plugin-3d-tiles-renderer

Exports
- [TilesRendererPlugin](https://threepipe.org/plugins/3d-tiles-renderer/docs/classes/TilesRendererPlugin.html) - adds support for loading and rendering [OGC 3D Tiles](https://www.ogc.org/standards/3dtiles/) json files.
- [B3DMLoadPlugin](https://threepipe.org/plugins/3d-tiles-renderer/docs/classes/B3DMLoadPlugin.html) - adds support for loading b3dm(Batched 3D Model) files using the Asset Manager.
- [CMPTLoadPlugin](https://threepipe.org/plugins/3d-tiles-renderer/docs/classes/CMPTLoadPlugin.html) - adds support for loading cmpt(Composite Model) files using the Asset Manager.
- [I3DMLoadPlugin](https://threepipe.org/plugins/3d-tiles-renderer/docs/classes/I3DMLoadPlugin.html) - adds support for loading i3dm(Instanced 3D Model) files using the Asset Manager.
- [PNTSLoadPlugin](https://threepipe.org/plugins/3d-tiles-renderer/docs/classes/PNTSLoadPlugin.html) - adds support for loading pnts(Point Cloud) files using the Asset Manager.
- [DeepZoomImageLoadPlugin](https://threepipe.org/plugins/3d-tiles-renderer/docs/classes/DeepZoomImageLoadPlugin.html) - adds support for loading dzi(Deep Zoom Image) files.
- [SlippyMapTilesLoadPlugin](https://threepipe.org/plugins/3d-tiles-renderer/docs/classes/SlippyMapTilesLoadPlugin.html) - adds support for loading slippy map tiles (open street map).

This package acts as an interface to the [`3d-tiles-renderer`](https://github.com/NASA-AMMOS/3DTilesRendererJS) package.

[Example](https://threepipe.org/examples/#3d-tiles-renderer/) &mdash;
[Source Code](https://github.com/repalash/threepipe/blob/master/plugins/3d-tiles-renderer/src/index.ts) &mdash;
[API Reference](https://threepipe.org/plugins/3d-tiles-renderer/docs)

[![NPM Package](https://img.shields.io/npm/v/@threepipe/plugin-3d-tiles-renderer.svg)](https://www.npmjs.com/package/@threepipe/plugin-3d-tiles-renderer)

```bash
npm install @threepipe/plugin-3d-tiles-renderer
```

::: warning Note
This is still a WIP.
:::

## Sample Usage

### Load and render tileset
To import a tileset, simply add the `TilesRendererPlugin` and load the root json with the plugin or the viewer.

The near, far plane of the camera can be set based on the file.

```typescript
import {ThreeViewer} from 'threepipe'
import {TilesRendererPlugin, TilesRendererGroup} from '@threepipe/plugin-3d-tiles-renderer'

const viewer = new ThreeViewer({...})
viewer.addPluginSync(TilesRendererPlugin)

viewer.scene.mainCamera.position.set(300, 300, 300)
viewer.scene.mainCamera.autoNearFar = false
viewer.scene.mainCamera.minNearPlane = 1
viewer.scene.mainCamera.maxFarPlane = 1000

// Now load any tileset json file.
const group = await tiles.load('https://raw.githubusercontent.com/NASA-AMMOS/3DTilesRendererJS/c7a9a7f7607e8759d16c26fb83815ad1cd1fd865/example/data/tileset.json', {
autoScale: true,
autoCenter: true,
autoScaleRadius: 100,
})

// or load directly from the viewer. A custom fileExtension or fileHandler must be passed, to tell the viewer the type of the json file.
const group1 = await viewer.load<TilesRendererGroup>('https://raw.githubusercontent.com/NASA-AMMOS/3DTilesRendererJS/c7a9a7f7607e8759d16c26fb83815ad1cd1fd865/example/data/tileset.json', {
fileExtension: TilesRendererPlugin.DUMMY_EXT,
autoScale: true,
autoCenter: true,
autoScaleRadius: 100,
})

```

Check the [3d-tiles-renderer](https://threepipe.com/examples/#3d-tiles-renderer/), [ogc-tiles-mars](https://threepipe.com/examples/#ogc-tiles-mars/) examples for a live demo.

### Add TilesRenderer Plugins

Some plugins are used by default in the `TilesRendererPlugin` to load and render the tileset. These can be disabled/configured when loading a file and more can be added.
Custom plugins can be added to the individual `TilesRenderer` when loading a tileset file.
```typescript
import {UnloadTilesPlugin, TileCompressionPlugin} from '@threepipe/plugin-3d-tiles-renderer'
const result = await tiles.load('url', {
autoCenter: true,
autoScale: false,
tiles: {
TilesFadePlugin: {
fadeDuration: 0.5,
},
plugins: [
()=>new UnloadTilesPlugin(),
()=>new TileCompressionPlugin(),
],
},
})
```

### Loading Cesium Ion Assets

Cesium Ion assets like Google Maps can be loaded with the `loadCesiumIon` function in the plugin, or by passing a custom plugin in the viewer.

```typescript
const tiles = viewer.getPlugin(TilesRendererPlugin)
const result = await tiles.loadCesiumIon({
assetId: '2275207',
apiToken: CESIUM_ION_API_TOKEN,
autoRefreshToken: true,
}, {
autoCenter: false,
// more options
tiles: {
TilesFadePlugin: true,
plugins: [
()=>new TileCompressionPlugin(),
()=>new UnloadTilesPlugin(),
],
},
})

// or
const result2 = await viewer.load('file.tileset', {
tiles: {
CesiumIonAuthPlugin: {
assetId: '2275207',
apiToken: CESIUM_ION_API_TOKEN,
autoRefreshToken: true,
},
TilesFadePlugin: true,
plugins: [
()=>new TileCompressionPlugin(),
()=>new UnloadTilesPlugin(),
],
},
})
```

Note - `TilesRendererPlugin.DUMMY_EXT` = `tileset`

:::info
Get the `CESIUM_ION_API_TOKEN` for free from [cesium ion](https://ion.cesium.com/)
:::

Check the Google Maps examples - [ogc-tiles-google-maps](https://threepipe.com/examples/#ogc-tiles-google-maps/), [ogc-tiles-google-maps-3d](https://threepipe.com/examples/#ogc-tiles-google-maps-3d/) examples for sample usage

### Loading 3d tiles files

To load any individual tile file format, add the plugin to the viewer and load the file directly as you would with any other file. The plugin will automatically detect the type of the file and load it.
```typescript
import {ThreeViewer} from 'threepipe'
import {B3DMLoadPlugin, CMPTLoadPlugin, I3DMLoadPlugin, PNTSLoadPlugin} from '@threepipe/plugin-3d-tiles-renderer'

const viewer = new ThreeViewer({...})
viewer.addPluginsSync([B3DMLoadPlugin, CMPTLoadPlugin, I3DMLoadPlugin, PNTSLoadPlugin, LoadingScreenPlugin])

// Now load any file
const b3dm = await viewer.load<IObject3D>('https://example.com/file.b3dm')
const cmpt = await viewer.load<IObject3D>('https://example.com/file.cmpt')
const i3dm = await viewer.load<IObject3D>('https://example.com/file.i3dm')
const pnts = await viewer.load<IObject3D>('https://example.com/file.pnts')

// Load file by data url
const model = await viewer.load<IObject3D>('data:application/octet-stream;base64,...', {
fileExtension: 'b3dm',
})
// or by using `model/<extension>` mime type
const model2 = await viewer.load<IObject3D>('data:model/b3dm;base64,...')
```

The asset importer will automatically detect the type of the file and load it.

Checkout the examples [b3dm-load](https://threepipe.org/examples/#b3dm-load/),
[cmpt-load](https://threepipe.org/examples/#cmpt-load/),
[pnts-load](https://threepipe.org/examples/#pnts-load/),
[i3dm-load](https://threepipe.org/examples/#i3dm-load/) for more details.

### Loading Image tiles

The package exports plugins `DeepZoomImageLoadPlugin` and `SlippyMapTilesLoadPlugin` to load deep zoom images and slippy map tiles respectively.
They add and use the `TilesRendererPlugin` automatically.

The plugins can be added to the viewer and files can be loaded directly from the viewer or asset manager.

```typescript
import {ThreeViewer} from 'threepipe'
import {TilesRendererPlugin, DeepZoomImageLoadPlugin, SlippyMapTilesLoadPlugin} from '@threepipe/plugin-3d-tiles-renderer'

const viewer = new ThreeViewer({...})

viewer.addPluginsSync([TilesRendererPlugin, DeepZoomImageLoadPlugin, SlippyMapTilesLoadPlugin])

// Load deep zoom image
const result = await viewer.load('https://openseadragon.github.io/example-images/duomo/duomo.dzi', {
autoCenter: true,
autoScale: true,
autoScaleRadius: 30,
tiles: {
DeepZoomImagePlugin: {
center: true
},
errorTarget: 1,
}
})

const result2 = await viewer.load('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
autoCenter: true,
autoScale: true,
autoScaleRadius: 30,
fileExtension: SlippyMapTilesLoadPlugin.DUMMY_EXT,
tiles: {
errorTarget: 1,
XYZTilesPlugin: {
projection: 'planar',
center: true
},
}
})
```

Checkout the examples [dzi-load](https://threepipe.org/examples/#dzi-load/),
[slippy-map-tiles](https://threepipe.org/examples/#slippy-map-tiles/) for a demo.

+ 4
- 1
website/package/plugin-svg-renderer.md Ver fichero

@@ -3,7 +3,10 @@ prev:
text: '@threepipe/plugin-gaussian-splatting'
link: './plugin-gaussian-splatting'

next: false
next:
text: '@threepipe/plugin-3d-tiles-renderer'
link: './plugin-3d-tiles-renderer'

---

# @threepipe/plugin-svg-renderer

Cargando…
Cancelar
Guardar