@threepipe/plugin-3d-tiles-renderer 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/B3DMLoadPlugin.d.ts +22 -0
- package/dist/B3DMLoadPlugin.d.ts.map +1 -0
- package/dist/CMPTLoadPlugin.d.ts +22 -0
- package/dist/CMPTLoadPlugin.d.ts.map +1 -0
- package/dist/DeepZoomImageLoadPlugin.d.ts +25 -0
- package/dist/DeepZoomImageLoadPlugin.d.ts.map +1 -0
- package/dist/EnvironmentControlsPlugin.d.ts +29 -0
- package/dist/EnvironmentControlsPlugin.d.ts.map +1 -0
- package/dist/GlobeControlsPlugin.d.ts +33 -0
- package/dist/GlobeControlsPlugin.d.ts.map +1 -0
- package/dist/I3DMLoadPlugin.d.ts +21 -0
- package/dist/I3DMLoadPlugin.d.ts.map +1 -0
- package/dist/PNTSLoadPlugin.d.ts +22 -0
- package/dist/PNTSLoadPlugin.d.ts.map +1 -0
- package/dist/SlippyMapTilesLoadPlugin.d.ts +29 -0
- package/dist/SlippyMapTilesLoadPlugin.d.ts.map +1 -0
- package/dist/TilesRendererPlugin.d.ts +67 -0
- package/dist/TilesRendererPlugin.d.ts.map +1 -0
- package/dist/dependencies.txt +212 -0
- package/dist/gltf.d.ts +18 -0
- package/dist/gltf.d.ts.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10873 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +10856 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +51 -0
- package/src/B3DMLoadPlugin.ts +64 -0
- package/src/CMPTLoadPlugin.ts +144 -0
- package/src/DeepZoomImageLoadPlugin.ts +49 -0
- package/src/EnvironmentControlsPlugin.ts +52 -0
- package/src/GlobeControlsPlugin.ts +75 -0
- package/src/I3DMLoadPlugin.ts +65 -0
- package/src/PNTSLoadPlugin.ts +137 -0
- package/src/SlippyMapTilesLoadPlugin.ts +50 -0
- package/src/TilesRendererPlugin.ts +354 -0
- package/src/global.d.ts +40 -0
- package/src/gltf.ts +40 -0
- package/src/index.ts +16 -0
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@threepipe/plugin-3d-tiles-renderer",
|
|
3
|
+
"description": "Interface for 3d-tiles-renderer",
|
|
4
|
+
"version": "0.2.0",
|
|
5
|
+
"dependencies": {},
|
|
6
|
+
"overrides": {
|
|
7
|
+
"threepipe": "$threepipe",
|
|
8
|
+
"three": "$three",
|
|
9
|
+
"@types/three": "$@types/three"
|
|
10
|
+
},
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.mjs",
|
|
15
|
+
"require": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./dist/": {
|
|
18
|
+
"import": "./dist/",
|
|
19
|
+
"require": "./dist/"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"type": "module",
|
|
23
|
+
"main": "dist/index.js",
|
|
24
|
+
"module": "dist/index.mjs",
|
|
25
|
+
"types": "dist/index.d.ts",
|
|
26
|
+
"files": [
|
|
27
|
+
"dist",
|
|
28
|
+
"src"
|
|
29
|
+
],
|
|
30
|
+
"author": "repalash <palash@shaders.app>",
|
|
31
|
+
"license": "Apache-2.0",
|
|
32
|
+
"keywords": [
|
|
33
|
+
"three",
|
|
34
|
+
"three.js",
|
|
35
|
+
"threepipe",
|
|
36
|
+
"3d-tiles",
|
|
37
|
+
"maps"
|
|
38
|
+
],
|
|
39
|
+
"bugs": {
|
|
40
|
+
"url": "https://github.com/repalash/threepipe/issues"
|
|
41
|
+
},
|
|
42
|
+
"homepage": "https://github.com/repalash/threepipe#readme",
|
|
43
|
+
"repository": {
|
|
44
|
+
"type": "git",
|
|
45
|
+
"url": "git://github.com/repalash/threepipe.git",
|
|
46
|
+
"directory": "plugins/tiles-renderer-3d"
|
|
47
|
+
},
|
|
48
|
+
"peerDependencies": {
|
|
49
|
+
"threepipe": "^0.0.43"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BaseImporterPlugin,
|
|
3
|
+
generateUUID,
|
|
4
|
+
GLTFLoader2,
|
|
5
|
+
IAssetImporter,
|
|
6
|
+
ILoader, ImportAddOptions,
|
|
7
|
+
Importer,
|
|
8
|
+
LoadingManager,
|
|
9
|
+
ThreeViewer,
|
|
10
|
+
} from 'threepipe'
|
|
11
|
+
import type {B3DMResult} from '3d-tiles-renderer/src/three/loaders/B3DMLoader'
|
|
12
|
+
import {B3DMLoader, B3DMScene, LoaderBase} from '3d-tiles-renderer'
|
|
13
|
+
import {GLTF} from 'three/examples/jsm/loaders/GLTFLoader'
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Adds support for loading .b3dm files and data uris.
|
|
17
|
+
* Batched 3D Model (b3dm) file format is part of OGC 3D Tiles.
|
|
18
|
+
* Specification - https://www.ogc.org/standards/3dtiles/
|
|
19
|
+
*/
|
|
20
|
+
export class B3DMLoadPlugin extends BaseImporterPlugin {
|
|
21
|
+
public static readonly PluginType = 'B3DMLoadPlugin'
|
|
22
|
+
protected _importer = new Importer(B3DMLoader2, ['b3dm'], ['model/b3dm'], false)
|
|
23
|
+
|
|
24
|
+
onAdded(viewer: ThreeViewer) {
|
|
25
|
+
super.onAdded(viewer)
|
|
26
|
+
this._importer.onCtor = (l, ai) => {
|
|
27
|
+
if (l) l.ai = ai
|
|
28
|
+
return l
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// todo no need to extend GLTFLoader2 for just transform function, it can be called manually or rewritten
|
|
34
|
+
export class B3DMLoader2 extends GLTFLoader2 implements ILoader<B3DMResult, B3DMScene> {
|
|
35
|
+
loader
|
|
36
|
+
ai?: IAssetImporter
|
|
37
|
+
|
|
38
|
+
constructor(manager: LoadingManager) {
|
|
39
|
+
super(manager)
|
|
40
|
+
this.loader = new B3DMLoader(manager)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
transform(res: B3DMResult, options: ImportAddOptions): B3DMScene {
|
|
44
|
+
return super.transform(res, options) as any
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
parse(data: ArrayBuffer, _path: string, onLoad: (gltf: GLTF) => void, onError?: (event: ErrorEvent) => void, _url?: string) {
|
|
48
|
+
if (!this.ai) {
|
|
49
|
+
console.error('[B3DMLoader] load failed, IAssetImporter not set')
|
|
50
|
+
}
|
|
51
|
+
const tmpFile = generateUUID() + '.gltf'
|
|
52
|
+
this.ai?.registerFile(tmpFile) // to set the gltf loader in manager
|
|
53
|
+
|
|
54
|
+
;(this.loader as LoaderBase).workingPath = _path
|
|
55
|
+
|
|
56
|
+
this.loader.parse(data)
|
|
57
|
+
.then(onLoad)
|
|
58
|
+
.catch(onError)
|
|
59
|
+
.finally(() => {
|
|
60
|
+
if (tmpFile) this.ai?.unregisterFile(tmpFile)
|
|
61
|
+
})
|
|
62
|
+
// super.parse(data, path, onLoad, onError, url)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AnyOptions,
|
|
3
|
+
BaseImporterPlugin,
|
|
4
|
+
FileLoader, generateUUID,
|
|
5
|
+
Group,
|
|
6
|
+
IAssetImporter,
|
|
7
|
+
ILoader,
|
|
8
|
+
Importer,
|
|
9
|
+
Loader,
|
|
10
|
+
LoaderUtils,
|
|
11
|
+
LoadingManager,
|
|
12
|
+
ThreeViewer,
|
|
13
|
+
} from 'threepipe'
|
|
14
|
+
import type {CMPTResult} from '3d-tiles-renderer/src/three/loaders/CMPTLoader'
|
|
15
|
+
import {CMPTLoader, LoaderBase} from '3d-tiles-renderer'
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Adds support for loading .cmpt files and data uris.
|
|
19
|
+
* Composite (cmpt) file format is part of OGC 3D Tiles.
|
|
20
|
+
* Specification - https://www.ogc.org/standards/3dtiles/
|
|
21
|
+
*/
|
|
22
|
+
export class CMPTLoadPlugin extends BaseImporterPlugin {
|
|
23
|
+
public static readonly PluginType = 'CMPTLoadPlugin'
|
|
24
|
+
protected _importer = new Importer(CMPTLoader2, ['cmpt'], ['model/cmpt'], false)
|
|
25
|
+
|
|
26
|
+
onAdded(viewer: ThreeViewer) {
|
|
27
|
+
super.onAdded(viewer)
|
|
28
|
+
this._importer.onCtor = (l, ai) => {
|
|
29
|
+
if (l) l.ai = ai
|
|
30
|
+
return l
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export class CMPTLoader2 extends Loader implements ILoader<CMPTResult, Group> {
|
|
36
|
+
loader
|
|
37
|
+
ai?: IAssetImporter
|
|
38
|
+
|
|
39
|
+
constructor(manager: LoadingManager) {
|
|
40
|
+
super(manager)
|
|
41
|
+
this.loader = new CMPTLoader(manager)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
load(url: string, onLoad: (data: unknown) => void, onProgress?: (event: ProgressEvent) => void, onError?: (err: unknown) => void) {
|
|
46
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
47
|
+
const scope = this
|
|
48
|
+
|
|
49
|
+
let resourcePath
|
|
50
|
+
|
|
51
|
+
if (this.resourcePath !== '') {
|
|
52
|
+
|
|
53
|
+
resourcePath = this.resourcePath
|
|
54
|
+
|
|
55
|
+
} else if (this.path !== '') {
|
|
56
|
+
|
|
57
|
+
resourcePath = this.path
|
|
58
|
+
|
|
59
|
+
} else {
|
|
60
|
+
|
|
61
|
+
resourcePath = LoaderUtils.extractUrlBase(url)
|
|
62
|
+
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Tells the LoadingManager to track an extra item, which resolves after
|
|
66
|
+
// the model is fully loaded. This means the count of items loaded will
|
|
67
|
+
// be incorrect, but ensures manager.onLoad() does not fire early.
|
|
68
|
+
this.manager.itemStart(url)
|
|
69
|
+
|
|
70
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
71
|
+
const _onError = function(e: any) {
|
|
72
|
+
|
|
73
|
+
if (onError) {
|
|
74
|
+
|
|
75
|
+
onError(e)
|
|
76
|
+
|
|
77
|
+
} else {
|
|
78
|
+
|
|
79
|
+
console.error(e)
|
|
80
|
+
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
scope.manager.itemError(url)
|
|
84
|
+
scope.manager.itemEnd(url)
|
|
85
|
+
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const loader = new FileLoader(this.manager)
|
|
89
|
+
|
|
90
|
+
loader.setPath(this.path)
|
|
91
|
+
loader.setResponseType('arraybuffer')
|
|
92
|
+
loader.setRequestHeader(this.requestHeader)
|
|
93
|
+
loader.setWithCredentials(this.withCredentials)
|
|
94
|
+
|
|
95
|
+
loader.load(url, function(data) {
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
|
|
99
|
+
scope.parse(data as any, resourcePath, function(gltf) {
|
|
100
|
+
|
|
101
|
+
onLoad(gltf)
|
|
102
|
+
|
|
103
|
+
scope.manager.itemEnd(url)
|
|
104
|
+
|
|
105
|
+
}, _onError, url)
|
|
106
|
+
|
|
107
|
+
} catch (e) {
|
|
108
|
+
|
|
109
|
+
_onError(e)
|
|
110
|
+
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
}, onProgress, _onError)
|
|
114
|
+
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
transform(res: CMPTResult, _options: AnyOptions): Group {
|
|
118
|
+
return res.scene
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
parse(data: ArrayBuffer, _path: string, onLoad: (res: CMPTResult) => void, onError?: (event: ErrorEvent) => void, _url?: string) {
|
|
122
|
+
if (!this.ai) {
|
|
123
|
+
console.error('[CMPTLoader] load failed, IAssetImporter not set')
|
|
124
|
+
}
|
|
125
|
+
// todo register draco for inside pnts files
|
|
126
|
+
|
|
127
|
+
const tmpFile = generateUUID()
|
|
128
|
+
this.ai?.registerFile(tmpFile + '.gltf') // to set the gltf loader in manager
|
|
129
|
+
this.ai?.registerFile(tmpFile + '.drc') // to set the draco loader in manager
|
|
130
|
+
|
|
131
|
+
;(this.loader as LoaderBase).workingPath = _path
|
|
132
|
+
|
|
133
|
+
this.loader.parse(data)
|
|
134
|
+
.then(onLoad)
|
|
135
|
+
.catch(onError)
|
|
136
|
+
.finally(() => {
|
|
137
|
+
if (tmpFile && this.ai) {
|
|
138
|
+
this.ai.unregisterFile(tmpFile + '.gltf')
|
|
139
|
+
this.ai.unregisterFile(tmpFile + '.drc')
|
|
140
|
+
}
|
|
141
|
+
})
|
|
142
|
+
// super.parse(data, path, onLoad, onError, url)
|
|
143
|
+
}
|
|
144
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import {BaseImporterPlugin, Importer, LoadingManager, ThreeViewer} from 'threepipe'
|
|
2
|
+
// @ts-expect-error moduleResolution issue
|
|
3
|
+
import {DeepZoomImagePlugin} from '3d-tiles-renderer/plugins'
|
|
4
|
+
import {TilesRendererLoader, TilesRendererPlugin} from './TilesRendererPlugin'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Adds support for loading .dzi files and data uris.
|
|
8
|
+
* Deep Zoom Image (dzi) file format - https://openseadragon.github.io/
|
|
9
|
+
*/
|
|
10
|
+
export class DeepZoomImageLoadPlugin extends BaseImporterPlugin {
|
|
11
|
+
public static readonly PluginType = 'DeepZoomImageLoadPlugin'
|
|
12
|
+
protected _importer = new Importer(DeepZoomImageLoader, ['dzi'], ['image/dzi'], false)
|
|
13
|
+
|
|
14
|
+
dependencies = [TilesRendererPlugin]
|
|
15
|
+
|
|
16
|
+
onAdded(viewer: ThreeViewer) {
|
|
17
|
+
super.onAdded(viewer)
|
|
18
|
+
this._importer.onCtor = (l, ai) => {
|
|
19
|
+
if (l) l.ai = ai
|
|
20
|
+
return l
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export class DeepZoomImageLoader extends TilesRendererLoader {
|
|
26
|
+
constructor(manager: LoadingManager) {
|
|
27
|
+
super(manager)
|
|
28
|
+
this.plugins.push(
|
|
29
|
+
(opts)=>{
|
|
30
|
+
if (opts?.DeepZoomImagePlugin === false) return undefined
|
|
31
|
+
const op = typeof opts?.DeepZoomImagePlugin === 'object' ? opts.DeepZoomImagePlugin : {}
|
|
32
|
+
return new DeepZoomImagePlugin({
|
|
33
|
+
// center: true,
|
|
34
|
+
...op,
|
|
35
|
+
})
|
|
36
|
+
},
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
declare module 'TilesRendererPlugin'{
|
|
42
|
+
interface TilesImportOptions {
|
|
43
|
+
DeepZoomImagePlugin?: boolean | {
|
|
44
|
+
center?: boolean,
|
|
45
|
+
pixelSize?: number,
|
|
46
|
+
useRecommendedSettings?: boolean,
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ACameraControlsPlugin,
|
|
3
|
+
Camera,
|
|
4
|
+
serialize,
|
|
5
|
+
TControlsCtor,
|
|
6
|
+
uiFolderContainer,
|
|
7
|
+
uiInput,
|
|
8
|
+
uiToggle,
|
|
9
|
+
uiVector,
|
|
10
|
+
Vector3,
|
|
11
|
+
} from 'threepipe'
|
|
12
|
+
import {EnvironmentControls} from '3d-tiles-renderer'
|
|
13
|
+
import {UiObjectConfig} from 'uiconfig.js'
|
|
14
|
+
|
|
15
|
+
export class EnvironmentControlsPlugin extends ACameraControlsPlugin {
|
|
16
|
+
public static readonly PluginType = 'EnvironmentControlsPlugin'
|
|
17
|
+
readonly controlsKey = 'environment'
|
|
18
|
+
|
|
19
|
+
protected _controlsCtor: TControlsCtor = (object, domElement) => {
|
|
20
|
+
return new EnvironmentControls2(object.parent ?? undefined, object, !domElement?.ownerDocument ? (domElement || document).documentElement : domElement)
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@uiFolderContainer('Environment Controls')
|
|
25
|
+
export class EnvironmentControls2 extends EnvironmentControls {
|
|
26
|
+
@uiToggle() @serialize() declare enabled: boolean
|
|
27
|
+
@uiInput() @serialize() declare cameraRadius: number
|
|
28
|
+
@uiInput() @serialize() declare rotationSpeed: number
|
|
29
|
+
@uiInput() @serialize() declare minAltitude: number
|
|
30
|
+
@uiInput() @serialize() declare maxAltitude: number
|
|
31
|
+
@uiInput() @serialize() declare minDistance: number
|
|
32
|
+
@uiInput() @serialize() maxDistance = 1e9 // should be Infinity but this breaks the UI
|
|
33
|
+
@uiInput() @serialize() declare minZoom: number
|
|
34
|
+
@uiInput() @serialize() maxZoom = 1e9 // should be Infinity but this breaks the UI
|
|
35
|
+
@uiInput() @serialize() declare zoomSpeed: number
|
|
36
|
+
@uiToggle() @serialize() declare adjustHeight: boolean
|
|
37
|
+
@uiToggle() @serialize() declare enableDamping: boolean
|
|
38
|
+
@uiInput() @serialize() declare dampingFactor: number
|
|
39
|
+
@uiToggle() @serialize() declare useFallbackPlane: boolean
|
|
40
|
+
|
|
41
|
+
@uiVector() @serialize() declare pivotPoint: Vector3
|
|
42
|
+
|
|
43
|
+
// does nothing right now, required so autoLookAtTarget is not used
|
|
44
|
+
target = new Vector3()
|
|
45
|
+
|
|
46
|
+
get object() {
|
|
47
|
+
// @ts-expect-error not in ts
|
|
48
|
+
return this.camera as Camera/* |null*/
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
declare uiConfig: UiObjectConfig<void, 'folder'>
|
|
52
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ACameraControlsPlugin, ICamera,
|
|
3
|
+
OrthographicCamera2,
|
|
4
|
+
PerspectiveCamera2,
|
|
5
|
+
serialize,
|
|
6
|
+
TControlsCtor,
|
|
7
|
+
uiFolderContainer,
|
|
8
|
+
uiInput,
|
|
9
|
+
uiToggle,
|
|
10
|
+
uiVector,
|
|
11
|
+
Vector3,
|
|
12
|
+
} from 'threepipe'
|
|
13
|
+
import {GlobeControls} from '3d-tiles-renderer'
|
|
14
|
+
import {UiObjectConfig} from 'uiconfig.js'
|
|
15
|
+
|
|
16
|
+
export class GlobeControlsPlugin extends ACameraControlsPlugin {
|
|
17
|
+
public static readonly PluginType = 'GlobeControlsPlugin'
|
|
18
|
+
readonly controlsKey = 'globe'
|
|
19
|
+
|
|
20
|
+
protected _controlsCtor: TControlsCtor = (object, domElement) => {
|
|
21
|
+
if ((object as ICamera).userData.autoNearFar) {
|
|
22
|
+
console.warn('GlobeControlsPlugin: autoNearFar is not supported with GlobeControlsPlugin, it will be disabled, use EnvironmentControlsPlugin instead to keep default behaviour')
|
|
23
|
+
;(object as ICamera).userData.autoNearFar = false
|
|
24
|
+
}
|
|
25
|
+
return new GlobeControls2(object.parent ?? undefined, object, !domElement?.ownerDocument ? (domElement || document).documentElement : domElement)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@uiFolderContainer('Globe Controls')
|
|
30
|
+
export class GlobeControls2 extends GlobeControls {
|
|
31
|
+
@uiToggle() @serialize() declare enabled: boolean
|
|
32
|
+
@uiInput() @serialize() declare cameraRadius: number
|
|
33
|
+
@uiInput() @serialize() declare rotationSpeed: number
|
|
34
|
+
@uiInput() @serialize() declare minAltitude: number
|
|
35
|
+
@uiInput() @serialize() declare maxAltitude: number
|
|
36
|
+
@uiInput() @serialize() declare minDistance: number
|
|
37
|
+
@uiInput() @serialize() maxDistance = 1e9 // should be Infinity but this breaks the UI
|
|
38
|
+
@uiInput() @serialize() declare minZoom: number
|
|
39
|
+
@uiInput() @serialize() maxZoom = 1e9 // should be Infinity but this breaks the UI
|
|
40
|
+
@uiInput() @serialize() declare zoomSpeed: number
|
|
41
|
+
@uiToggle() @serialize() declare adjustHeight: boolean
|
|
42
|
+
@uiToggle() @serialize() declare enableDamping: boolean
|
|
43
|
+
@uiInput() @serialize() declare dampingFactor: number
|
|
44
|
+
@uiToggle() @serialize() declare useFallbackPlane: boolean
|
|
45
|
+
|
|
46
|
+
@uiToggle() @serialize() declare nearMargin: number
|
|
47
|
+
@uiToggle() @serialize() declare farMargin: number
|
|
48
|
+
|
|
49
|
+
@uiVector() @serialize() declare pivotPoint: Vector3
|
|
50
|
+
|
|
51
|
+
declare camera: PerspectiveCamera2 | OrthographicCamera2
|
|
52
|
+
// does nothing right now, required so autoLookAtTarget is not used
|
|
53
|
+
target = new Vector3()
|
|
54
|
+
|
|
55
|
+
get object() {
|
|
56
|
+
return this.camera
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
declare uiConfig: UiObjectConfig<void, 'folder'>
|
|
60
|
+
|
|
61
|
+
// this is a workaround required because GlobeControls changes the near, far and we need it in minNear and minFar
|
|
62
|
+
update(deltaTime?: number) {
|
|
63
|
+
const {near, far} = this.camera
|
|
64
|
+
super.update(deltaTime)
|
|
65
|
+
if (this.camera.userData.autoNearFar || this.camera.userData.autoNearFar === undefined) return
|
|
66
|
+
if (this.camera.near !== near || this.camera.far !== far) {
|
|
67
|
+
this.camera.userData.minNearPlane = this.camera.near // dont set without userData, as that will trigger setDirty
|
|
68
|
+
this.camera.userData.maxFarPlane = this.camera.far
|
|
69
|
+
this.camera.near = near
|
|
70
|
+
this.camera.far = far
|
|
71
|
+
this.camera.updateProjectionMatrix()
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BaseImporterPlugin,
|
|
3
|
+
generateUUID,
|
|
4
|
+
GLTF,
|
|
5
|
+
GLTFLoader2,
|
|
6
|
+
IAssetImporter,
|
|
7
|
+
ILoader,
|
|
8
|
+
ImportAddOptions,
|
|
9
|
+
Importer,
|
|
10
|
+
LoadingManager,
|
|
11
|
+
ThreeViewer,
|
|
12
|
+
} from 'threepipe'
|
|
13
|
+
import type {I3DMResult} from '3d-tiles-renderer/src/three/loaders/I3DMLoader'
|
|
14
|
+
import {I3DMLoader, I3DMScene, LoaderBase} from '3d-tiles-renderer'
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Adds support for loading .i3dm files and data uris.
|
|
18
|
+
* Instanced 3D Model (i3dm) file format is part of OGC 3D Tiles.
|
|
19
|
+
* Specification - https://www.ogc.org/standards/3dtiles/
|
|
20
|
+
*/
|
|
21
|
+
export class I3DMLoadPlugin extends BaseImporterPlugin {
|
|
22
|
+
public static readonly PluginType = 'I3DMLoadPlugin'
|
|
23
|
+
protected _importer = new Importer(I3DMLoader2, ['i3dm'], ['model/i3dm'], false)
|
|
24
|
+
|
|
25
|
+
onAdded(viewer: ThreeViewer) {
|
|
26
|
+
super.onAdded(viewer)
|
|
27
|
+
this._importer.onCtor = (l, ai) => {
|
|
28
|
+
if (l) l.ai = ai
|
|
29
|
+
return l
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// todo no need to extend GLTFLoader2 for just transform function, it can be called manually or rewritten
|
|
35
|
+
export class I3DMLoader2 extends GLTFLoader2 implements ILoader<I3DMResult, I3DMScene> {
|
|
36
|
+
loader
|
|
37
|
+
ai?: IAssetImporter
|
|
38
|
+
|
|
39
|
+
constructor(manager: LoadingManager) {
|
|
40
|
+
super(manager)
|
|
41
|
+
this.loader = new I3DMLoader(manager)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
transform(res: I3DMResult, options: ImportAddOptions): I3DMScene {
|
|
45
|
+
return super.transform(res, options) as any
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
parse(data: ArrayBuffer, _path: string, onLoad: (gltf: GLTF) => void, onError?: (event: ErrorEvent) => void, _url?: string) {
|
|
49
|
+
if (!this.ai) {
|
|
50
|
+
console.error('[I3DMLoader] load failed, IAssetImporter not set')
|
|
51
|
+
}
|
|
52
|
+
const tmpFile = generateUUID() + '.gltf'
|
|
53
|
+
this.ai?.registerFile(tmpFile) // to set the gltf loader in manager
|
|
54
|
+
|
|
55
|
+
;(this.loader as LoaderBase).workingPath = _path
|
|
56
|
+
|
|
57
|
+
this.loader.parse(data)
|
|
58
|
+
.then(onLoad)
|
|
59
|
+
.catch(onError)
|
|
60
|
+
.finally(() => {
|
|
61
|
+
if (tmpFile) this.ai?.unregisterFile(tmpFile)
|
|
62
|
+
})
|
|
63
|
+
// super.parse(data, path, onLoad, onError, url)
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AnyOptions,
|
|
3
|
+
BaseImporterPlugin,
|
|
4
|
+
FileLoader, generateUUID,
|
|
5
|
+
IAssetImporter,
|
|
6
|
+
ILoader,
|
|
7
|
+
Importer,
|
|
8
|
+
Loader,
|
|
9
|
+
LoaderUtils,
|
|
10
|
+
LoadingManager,
|
|
11
|
+
ThreeViewer,
|
|
12
|
+
} from 'threepipe'
|
|
13
|
+
import type {PNTSResult} from '3d-tiles-renderer/src/three/loaders/PNTSLoader'
|
|
14
|
+
import {LoaderBase, PNTSLoader, PNTSScene} from '3d-tiles-renderer'
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Adds support for loading .pnts files and data uris.
|
|
18
|
+
* Point Cloud (pnts) file format is part of OGC 3D Tiles.
|
|
19
|
+
* Specification - https://www.ogc.org/standards/3dtiles/
|
|
20
|
+
*/
|
|
21
|
+
export class PNTSLoadPlugin extends BaseImporterPlugin {
|
|
22
|
+
public static readonly PluginType = 'PNTSLoadPlugin'
|
|
23
|
+
protected _importer = new Importer(PNTSLoader2, ['pnts'], ['model/pnts'], false)
|
|
24
|
+
|
|
25
|
+
onAdded(viewer: ThreeViewer) {
|
|
26
|
+
super.onAdded(viewer)
|
|
27
|
+
this._importer.onCtor = (l, ai) => {
|
|
28
|
+
if (l) l.ai = ai
|
|
29
|
+
return l
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export class PNTSLoader2 extends Loader implements ILoader<PNTSResult, PNTSScene> {
|
|
35
|
+
loader
|
|
36
|
+
ai?: IAssetImporter
|
|
37
|
+
|
|
38
|
+
constructor(manager: LoadingManager) {
|
|
39
|
+
super(manager)
|
|
40
|
+
this.loader = new PNTSLoader(manager)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
load(url: string, onLoad: (data: unknown) => void, onProgress?: (event: ProgressEvent) => void, onError?: (err: unknown) => void) {
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
45
|
+
const scope = this
|
|
46
|
+
|
|
47
|
+
let resourcePath
|
|
48
|
+
|
|
49
|
+
if (this.resourcePath !== '') {
|
|
50
|
+
|
|
51
|
+
resourcePath = this.resourcePath
|
|
52
|
+
|
|
53
|
+
} else if (this.path !== '') {
|
|
54
|
+
|
|
55
|
+
resourcePath = this.path
|
|
56
|
+
|
|
57
|
+
} else {
|
|
58
|
+
|
|
59
|
+
resourcePath = LoaderUtils.extractUrlBase(url)
|
|
60
|
+
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Tells the LoadingManager to track an extra item, which resolves after
|
|
64
|
+
// the model is fully loaded. This means the count of items loaded will
|
|
65
|
+
// be incorrect, but ensures manager.onLoad() does not fire early.
|
|
66
|
+
this.manager.itemStart(url)
|
|
67
|
+
|
|
68
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
69
|
+
const _onError = function(e: any) {
|
|
70
|
+
|
|
71
|
+
if (onError) {
|
|
72
|
+
|
|
73
|
+
onError(e)
|
|
74
|
+
|
|
75
|
+
} else {
|
|
76
|
+
|
|
77
|
+
console.error(e)
|
|
78
|
+
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
scope.manager.itemError(url)
|
|
82
|
+
scope.manager.itemEnd(url)
|
|
83
|
+
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const loader = new FileLoader(this.manager)
|
|
87
|
+
|
|
88
|
+
loader.setPath(this.path)
|
|
89
|
+
loader.setResponseType('arraybuffer')
|
|
90
|
+
loader.setRequestHeader(this.requestHeader)
|
|
91
|
+
loader.setWithCredentials(this.withCredentials)
|
|
92
|
+
|
|
93
|
+
loader.load(url, function(data) {
|
|
94
|
+
|
|
95
|
+
try {
|
|
96
|
+
|
|
97
|
+
scope.parse(data as any, resourcePath, function(gltf) {
|
|
98
|
+
|
|
99
|
+
onLoad(gltf)
|
|
100
|
+
|
|
101
|
+
scope.manager.itemEnd(url)
|
|
102
|
+
|
|
103
|
+
}, _onError, url)
|
|
104
|
+
|
|
105
|
+
} catch (e) {
|
|
106
|
+
|
|
107
|
+
_onError(e)
|
|
108
|
+
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
}, onProgress, _onError)
|
|
112
|
+
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
transform(res: PNTSResult, _options: AnyOptions): PNTSScene {
|
|
116
|
+
return res.scene
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
parse(data: ArrayBuffer, _path: string, onLoad: (res: PNTSResult) => void, onError?: (event: ErrorEvent) => void, _url?: string) {
|
|
120
|
+
if (!this.ai) {
|
|
121
|
+
console.error('[PNTSLoader] load failed, IAssetImporter not set')
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const tmpFile = generateUUID() + '.drc'
|
|
125
|
+
this.ai?.registerFile(tmpFile) // to set the draco loader in manager
|
|
126
|
+
|
|
127
|
+
;(this.loader as LoaderBase).workingPath = _path
|
|
128
|
+
|
|
129
|
+
this.loader.parse(data)
|
|
130
|
+
.then(onLoad)
|
|
131
|
+
.catch(onError)
|
|
132
|
+
.finally(() => {
|
|
133
|
+
if (tmpFile) this.ai?.unregisterFile(tmpFile)
|
|
134
|
+
})
|
|
135
|
+
// super.parse(data, path, onLoad, onError, url)
|
|
136
|
+
}
|
|
137
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import {BaseImporterPlugin, Importer, LoadingManager, ThreeViewer} from 'threepipe'
|
|
2
|
+
// @ts-expect-error moduleResolution issue
|
|
3
|
+
import {XYZTilesPlugin} from '3d-tiles-renderer/plugins'
|
|
4
|
+
import {TilesRendererLoader, TilesRendererPlugin} from './TilesRendererPlugin'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Adds support for loading slippy map tiles(OpenStreetMap) in png format
|
|
8
|
+
* https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
|
|
9
|
+
*/
|
|
10
|
+
export class SlippyMapTilesLoadPlugin extends BaseImporterPlugin {
|
|
11
|
+
public static readonly PluginType = 'SlippyMapTilesLoadPlugin'
|
|
12
|
+
static readonly DUMMY_EXT = 'xyztiles'
|
|
13
|
+
protected _importer = new Importer(SlippyMapTilesLoader, [SlippyMapTilesLoadPlugin.DUMMY_EXT], [], false)
|
|
14
|
+
|
|
15
|
+
dependencies = [TilesRendererPlugin]
|
|
16
|
+
|
|
17
|
+
onAdded(viewer: ThreeViewer) {
|
|
18
|
+
super.onAdded(viewer)
|
|
19
|
+
this._importer.onCtor = (l, ai) => {
|
|
20
|
+
if (l) l.ai = ai
|
|
21
|
+
return l
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export class SlippyMapTilesLoader extends TilesRendererLoader {
|
|
27
|
+
constructor(manager: LoadingManager) {
|
|
28
|
+
super(manager)
|
|
29
|
+
this.plugins.push(
|
|
30
|
+
(opts)=>{
|
|
31
|
+
if (opts?.XYZTilesPlugin === false) return undefined
|
|
32
|
+
const op = typeof opts?.XYZTilesPlugin === 'object' ? opts.XYZTilesPlugin : {}
|
|
33
|
+
return new XYZTilesPlugin(op)
|
|
34
|
+
},
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
declare module 'TilesRendererPlugin'{
|
|
40
|
+
interface TilesImportOptions {
|
|
41
|
+
XYZTilesPlugin?: boolean | {
|
|
42
|
+
levels: number // default = 20,
|
|
43
|
+
tileDimension: number // default = 256,
|
|
44
|
+
pixelSize: number // default = 1e-5,
|
|
45
|
+
center?: boolean,
|
|
46
|
+
projection?: 'ellipsoid' | 'planar',
|
|
47
|
+
useRecommendedSettings?: boolean,
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|