spoint 0.1.0 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +134 -209
- package/SKILL.md +95 -0
- package/apps/environment/index.js +200 -1
- package/apps/environment/models/decorative/.gitkeep +0 -0
- package/apps/environment/models/hazards/.gitkeep +0 -0
- package/apps/environment/models/interactive/.gitkeep +0 -0
- package/apps/environment/models/structures/.gitkeep +0 -0
- package/apps/environment/smartObjects.js +114 -0
- package/apps/interactable/index.js +155 -0
- package/apps/physics-crate/index.js +15 -9
- package/apps/power-crate/index.js +18 -12
- package/apps/tps-game/$GDUPI.vrm +0 -0
- package/apps/tps-game/Cleetus.vrm +0 -0
- package/apps/tps-game/index.js +185 -27
- package/apps/world/index.js +68 -22
- package/bin/create-app.js +337 -0
- package/client/ARControls.js +301 -0
- package/client/LoadingManager.js +117 -0
- package/client/MobileControls.js +1122 -0
- package/client/anim-lib.glb +0 -0
- package/client/animation.js +306 -0
- package/client/app.js +1341 -65
- package/client/camera.js +191 -33
- package/client/createLoadingScreen.js +69 -0
- package/client/editor/bridge.js +113 -0
- package/client/editor/css/main.css +794 -0
- package/client/editor/images/rotate.svg +4 -0
- package/client/editor/images/scale.svg +4 -0
- package/client/editor/images/translate.svg +4 -0
- package/client/editor/index.html +103 -0
- package/client/editor/js/Command.js +41 -0
- package/client/editor/js/Config.js +81 -0
- package/client/editor/js/Editor.js +785 -0
- package/client/editor/js/EditorControls.js +438 -0
- package/client/editor/js/History.js +321 -0
- package/client/editor/js/Loader.js +987 -0
- package/client/editor/js/LoaderUtils.js +90 -0
- package/client/editor/js/Menubar.Add.js +510 -0
- package/client/editor/js/Menubar.Edit.js +145 -0
- package/client/editor/js/Menubar.File.js +466 -0
- package/client/editor/js/Menubar.Help.js +73 -0
- package/client/editor/js/Menubar.Status.js +51 -0
- package/client/editor/js/Menubar.View.js +183 -0
- package/client/editor/js/Menubar.js +27 -0
- package/client/editor/js/Player.js +53 -0
- package/client/editor/js/Resizer.js +58 -0
- package/client/editor/js/Script.js +503 -0
- package/client/editor/js/Selector.js +102 -0
- package/client/editor/js/Sidebar.Geometry.BoxGeometry.js +121 -0
- package/client/editor/js/Sidebar.Geometry.BufferGeometry.js +115 -0
- package/client/editor/js/Sidebar.Geometry.CapsuleGeometry.js +97 -0
- package/client/editor/js/Sidebar.Geometry.CircleGeometry.js +97 -0
- package/client/editor/js/Sidebar.Geometry.CylinderGeometry.js +121 -0
- package/client/editor/js/Sidebar.Geometry.DodecahedronGeometry.js +73 -0
- package/client/editor/js/Sidebar.Geometry.ExtrudeGeometry.js +196 -0
- package/client/editor/js/Sidebar.Geometry.IcosahedronGeometry.js +73 -0
- package/client/editor/js/Sidebar.Geometry.LatheGeometry.js +98 -0
- package/client/editor/js/Sidebar.Geometry.Modifiers.js +73 -0
- package/client/editor/js/Sidebar.Geometry.OctahedronGeometry.js +74 -0
- package/client/editor/js/Sidebar.Geometry.PlaneGeometry.js +97 -0
- package/client/editor/js/Sidebar.Geometry.RingGeometry.js +121 -0
- package/client/editor/js/Sidebar.Geometry.ShapeGeometry.js +76 -0
- package/client/editor/js/Sidebar.Geometry.SphereGeometry.js +133 -0
- package/client/editor/js/Sidebar.Geometry.TetrahedronGeometry.js +74 -0
- package/client/editor/js/Sidebar.Geometry.TorusGeometry.js +109 -0
- package/client/editor/js/Sidebar.Geometry.TorusKnotGeometry.js +121 -0
- package/client/editor/js/Sidebar.Geometry.TubeGeometry.js +135 -0
- package/client/editor/js/Sidebar.Geometry.js +332 -0
- package/client/editor/js/Sidebar.Material.BooleanProperty.js +60 -0
- package/client/editor/js/Sidebar.Material.ColorProperty.js +87 -0
- package/client/editor/js/Sidebar.Material.ConstantProperty.js +62 -0
- package/client/editor/js/Sidebar.Material.MapProperty.js +249 -0
- package/client/editor/js/Sidebar.Material.NumberProperty.js +60 -0
- package/client/editor/js/Sidebar.Material.Program.js +73 -0
- package/client/editor/js/Sidebar.Material.RangeValueProperty.js +63 -0
- package/client/editor/js/Sidebar.Material.js +751 -0
- package/client/editor/js/Sidebar.Object.Animation.js +102 -0
- package/client/editor/js/Sidebar.Object.js +898 -0
- package/client/editor/js/Sidebar.Project.App.js +165 -0
- package/client/editor/js/Sidebar.Project.Image.js +225 -0
- package/client/editor/js/Sidebar.Project.Materials.js +82 -0
- package/client/editor/js/Sidebar.Project.Renderer.js +144 -0
- package/client/editor/js/Sidebar.Project.Video.js +242 -0
- package/client/editor/js/Sidebar.Project.js +31 -0
- package/client/editor/js/Sidebar.Properties.js +73 -0
- package/client/editor/js/Sidebar.Scene.js +585 -0
- package/client/editor/js/Sidebar.Script.js +129 -0
- package/client/editor/js/Sidebar.Settings.History.js +146 -0
- package/client/editor/js/Sidebar.Settings.Shortcuts.js +175 -0
- package/client/editor/js/Sidebar.Settings.js +60 -0
- package/client/editor/js/Sidebar.js +41 -0
- package/client/editor/js/Storage.js +98 -0
- package/client/editor/js/Strings.js +2028 -0
- package/client/editor/js/Toolbar.js +84 -0
- package/client/editor/js/Viewport.Controls.js +92 -0
- package/client/editor/js/Viewport.Info.js +136 -0
- package/client/editor/js/Viewport.Pathtracer.js +91 -0
- package/client/editor/js/Viewport.ViewHelper.js +39 -0
- package/client/editor/js/Viewport.XR.js +222 -0
- package/client/editor/js/Viewport.js +900 -0
- package/client/editor/js/commands/AddObjectCommand.js +68 -0
- package/client/editor/js/commands/AddScriptCommand.js +75 -0
- package/client/editor/js/commands/Commands.js +23 -0
- package/client/editor/js/commands/MoveObjectCommand.js +111 -0
- package/client/editor/js/commands/MultiCmdsCommand.js +85 -0
- package/client/editor/js/commands/RemoveObjectCommand.js +88 -0
- package/client/editor/js/commands/RemoveScriptCommand.js +81 -0
- package/client/editor/js/commands/SetColorCommand.js +73 -0
- package/client/editor/js/commands/SetGeometryCommand.js +87 -0
- package/client/editor/js/commands/SetGeometryValueCommand.js +70 -0
- package/client/editor/js/commands/SetMaterialColorCommand.js +86 -0
- package/client/editor/js/commands/SetMaterialCommand.js +79 -0
- package/client/editor/js/commands/SetMaterialMapCommand.js +143 -0
- package/client/editor/js/commands/SetMaterialRangeCommand.js +91 -0
- package/client/editor/js/commands/SetMaterialValueCommand.js +90 -0
- package/client/editor/js/commands/SetMaterialVectorCommand.js +79 -0
- package/client/editor/js/commands/SetPositionCommand.js +84 -0
- package/client/editor/js/commands/SetRotationCommand.js +84 -0
- package/client/editor/js/commands/SetScaleCommand.js +84 -0
- package/client/editor/js/commands/SetSceneCommand.js +103 -0
- package/client/editor/js/commands/SetScriptValueCommand.js +80 -0
- package/client/editor/js/commands/SetShadowValueCommand.js +73 -0
- package/client/editor/js/commands/SetUuidCommand.js +70 -0
- package/client/editor/js/commands/SetValueCommand.js +75 -0
- package/client/editor/js/libs/acorn/acorn.js +3236 -0
- package/client/editor/js/libs/acorn/acorn_loose.js +1299 -0
- package/client/editor/js/libs/acorn/walk.js +344 -0
- package/client/editor/js/libs/app/index.html +57 -0
- package/client/editor/js/libs/app.js +251 -0
- package/client/editor/js/libs/codemirror/addon/dialog.css +32 -0
- package/client/editor/js/libs/codemirror/addon/dialog.js +163 -0
- package/client/editor/js/libs/codemirror/addon/show-hint.css +36 -0
- package/client/editor/js/libs/codemirror/addon/show-hint.js +529 -0
- package/client/editor/js/libs/codemirror/addon/tern.css +87 -0
- package/client/editor/js/libs/codemirror/addon/tern.js +750 -0
- package/client/editor/js/libs/codemirror/codemirror.css +344 -0
- package/client/editor/js/libs/codemirror/codemirror.js +9849 -0
- package/client/editor/js/libs/codemirror/mode/glsl.js +233 -0
- package/client/editor/js/libs/codemirror/mode/javascript.js +959 -0
- package/client/editor/js/libs/codemirror/theme/monokai.css +41 -0
- package/client/editor/js/libs/esprima.js +6401 -0
- package/client/editor/js/libs/jsonlint.js +453 -0
- package/client/editor/js/libs/signals.min.js +14 -0
- package/client/editor/js/libs/tern-threejs/threejs.js +5031 -0
- package/client/editor/js/libs/ternjs/comment.js +87 -0
- package/client/editor/js/libs/ternjs/def.js +588 -0
- package/client/editor/js/libs/ternjs/doc_comment.js +401 -0
- package/client/editor/js/libs/ternjs/infer.js +1635 -0
- package/client/editor/js/libs/ternjs/polyfill.js +80 -0
- package/client/editor/js/libs/ternjs/signal.js +26 -0
- package/client/editor/js/libs/ternjs/tern.js +993 -0
- package/client/editor/js/libs/ui.js +1346 -0
- package/client/editor/js/libs/ui.three.js +855 -0
- package/client/facial-animation.js +455 -0
- package/client/index.html +7 -4
- package/client/loading.css +147 -0
- package/client/loading.html +25 -0
- package/client/style.css +251 -0
- package/package.json +7 -3
- package/server.js +9 -1
- package/src/apps/AppContext.js +1 -1
- package/src/apps/AppLoader.js +50 -37
- package/src/apps/AppRuntime.js +32 -8
- package/src/client/InputHandler.js +233 -0
- package/src/client/JitterBuffer.js +207 -0
- package/src/client/KalmanFilter.js +125 -0
- package/src/client/MessageHandler.js +101 -0
- package/src/client/PhysicsNetworkClient.js +141 -68
- package/src/client/ReconnectManager.js +62 -0
- package/src/client/SmoothInterpolation.js +127 -0
- package/src/client/SnapshotProcessor.js +144 -0
- package/src/connection/ConnectionManager.js +21 -3
- package/src/connection/SessionStore.js +13 -3
- package/src/index.client.js +4 -6
- package/src/netcode/EventLog.js +29 -15
- package/src/netcode/LagCompensator.js +25 -26
- package/src/netcode/NetworkState.js +4 -1
- package/src/netcode/PhysicsIntegration.js +20 -6
- package/src/netcode/PlayerManager.js +10 -2
- package/src/netcode/SnapshotEncoder.js +66 -19
- package/src/netcode/TickSystem.js +13 -4
- package/src/physics/World.js +66 -13
- package/src/protocol/msgpack.js +90 -63
- package/src/sdk/ReloadHandlers.js +12 -2
- package/src/sdk/ReloadManager.js +5 -0
- package/src/sdk/ServerHandlers.js +50 -11
- package/src/sdk/StaticHandler.js +22 -6
- package/src/sdk/TickHandler.js +101 -34
- package/src/sdk/scaffold.js +28 -0
- package/src/sdk/server.js +59 -33
- package/src/shared/movement.js +2 -1
- package/src/spatial/Octree.js +5 -0
- package/apps/interactive-door/index.js +0 -33
- package/apps/patrol-npc/index.js +0 -37
- package/src/connection/QualityMonitor.js +0 -46
- package/src/debug/StateInspector.js +0 -42
- package/src/index.js +0 -1
- package/src/index.server.js +0 -27
- package/src/protocol/Codec.js +0 -60
- package/src/protocol/SequenceTracker.js +0 -71
- package/src/sdk/ClientMessageHandler.js +0 -80
- package/src/sdk/client.js +0 -122
- package/world/kaira.glb +0 -0
- package/world/schwust.glb +0 -0
|
@@ -0,0 +1,987 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
|
|
3
|
+
import { TGALoader } from 'three/addons/loaders/TGALoader.js';
|
|
4
|
+
|
|
5
|
+
import { AddObjectCommand } from './commands/AddObjectCommand.js';
|
|
6
|
+
|
|
7
|
+
import { LoaderUtils } from './LoaderUtils.js';
|
|
8
|
+
|
|
9
|
+
import { unzipSync, strFromU8 } from 'three/addons/libs/fflate.module.js';
|
|
10
|
+
|
|
11
|
+
function Loader( editor ) {
|
|
12
|
+
|
|
13
|
+
const scope = this;
|
|
14
|
+
|
|
15
|
+
this.texturePath = '';
|
|
16
|
+
|
|
17
|
+
this.loadItemList = function ( items ) {
|
|
18
|
+
|
|
19
|
+
LoaderUtils.getFilesFromItemList( items, function ( files, filesMap ) {
|
|
20
|
+
|
|
21
|
+
scope.loadFiles( files, filesMap );
|
|
22
|
+
|
|
23
|
+
} );
|
|
24
|
+
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
this.loadFiles = function ( files, filesMap ) {
|
|
28
|
+
|
|
29
|
+
if ( files.length > 0 ) {
|
|
30
|
+
|
|
31
|
+
filesMap = filesMap || LoaderUtils.createFilesMap( files );
|
|
32
|
+
|
|
33
|
+
const manager = new THREE.LoadingManager();
|
|
34
|
+
manager.setURLModifier( function ( url ) {
|
|
35
|
+
|
|
36
|
+
url = url.replace( /^(\.?\/)/, '' ); // remove './'
|
|
37
|
+
|
|
38
|
+
const file = filesMap[ url ];
|
|
39
|
+
|
|
40
|
+
if ( file ) {
|
|
41
|
+
|
|
42
|
+
console.log( 'Loading', url );
|
|
43
|
+
|
|
44
|
+
return URL.createObjectURL( file );
|
|
45
|
+
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return url;
|
|
49
|
+
|
|
50
|
+
} );
|
|
51
|
+
|
|
52
|
+
manager.addHandler( /\.tga$/i, new TGALoader() );
|
|
53
|
+
|
|
54
|
+
for ( let i = 0; i < files.length; i ++ ) {
|
|
55
|
+
|
|
56
|
+
scope.loadFile( files[ i ], manager );
|
|
57
|
+
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
this.loadFile = function ( file, manager ) {
|
|
65
|
+
|
|
66
|
+
const filename = file.name;
|
|
67
|
+
const extension = filename.split( '.' ).pop().toLowerCase();
|
|
68
|
+
|
|
69
|
+
const reader = new FileReader();
|
|
70
|
+
reader.addEventListener( 'progress', function ( event ) {
|
|
71
|
+
|
|
72
|
+
const size = '(' + editor.utils.formatNumber( Math.floor( event.total / 1000 ) ) + ' KB)';
|
|
73
|
+
const progress = Math.floor( ( event.loaded / event.total ) * 100 ) + '%';
|
|
74
|
+
|
|
75
|
+
console.log( 'Loading', filename, size, progress );
|
|
76
|
+
|
|
77
|
+
} );
|
|
78
|
+
|
|
79
|
+
switch ( extension ) {
|
|
80
|
+
|
|
81
|
+
case '3dm':
|
|
82
|
+
|
|
83
|
+
{
|
|
84
|
+
|
|
85
|
+
reader.addEventListener( 'load', async function ( event ) {
|
|
86
|
+
|
|
87
|
+
const contents = event.target.result;
|
|
88
|
+
|
|
89
|
+
const { Rhino3dmLoader } = await import( 'three/addons/loaders/3DMLoader.js' );
|
|
90
|
+
|
|
91
|
+
const loader = new Rhino3dmLoader();
|
|
92
|
+
loader.setLibraryPath( '../examples/jsm/libs/rhino3dm/' );
|
|
93
|
+
loader.parse( contents, function ( object ) {
|
|
94
|
+
|
|
95
|
+
object.name = filename;
|
|
96
|
+
|
|
97
|
+
editor.execute( new AddObjectCommand( editor, object ) );
|
|
98
|
+
|
|
99
|
+
}, function ( error ) {
|
|
100
|
+
|
|
101
|
+
console.error( error );
|
|
102
|
+
|
|
103
|
+
} );
|
|
104
|
+
|
|
105
|
+
}, false );
|
|
106
|
+
reader.readAsArrayBuffer( file );
|
|
107
|
+
|
|
108
|
+
break;
|
|
109
|
+
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
case '3ds':
|
|
113
|
+
|
|
114
|
+
{
|
|
115
|
+
|
|
116
|
+
reader.addEventListener( 'load', async function ( event ) {
|
|
117
|
+
|
|
118
|
+
const { TDSLoader } = await import( 'three/addons/loaders/TDSLoader.js' );
|
|
119
|
+
|
|
120
|
+
const loader = new TDSLoader();
|
|
121
|
+
const object = loader.parse( event.target.result );
|
|
122
|
+
|
|
123
|
+
editor.execute( new AddObjectCommand( editor, object ) );
|
|
124
|
+
|
|
125
|
+
}, false );
|
|
126
|
+
reader.readAsArrayBuffer( file );
|
|
127
|
+
|
|
128
|
+
break;
|
|
129
|
+
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
case '3mf':
|
|
133
|
+
|
|
134
|
+
{
|
|
135
|
+
|
|
136
|
+
reader.addEventListener( 'load', async function ( event ) {
|
|
137
|
+
|
|
138
|
+
const { ThreeMFLoader } = await import( 'three/addons/loaders/3MFLoader.js' );
|
|
139
|
+
|
|
140
|
+
const loader = new ThreeMFLoader();
|
|
141
|
+
const object = loader.parse( event.target.result );
|
|
142
|
+
|
|
143
|
+
editor.execute( new AddObjectCommand( editor, object ) );
|
|
144
|
+
|
|
145
|
+
}, false );
|
|
146
|
+
reader.readAsArrayBuffer( file );
|
|
147
|
+
|
|
148
|
+
break;
|
|
149
|
+
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
case 'amf':
|
|
153
|
+
|
|
154
|
+
{
|
|
155
|
+
|
|
156
|
+
reader.addEventListener( 'load', async function ( event ) {
|
|
157
|
+
|
|
158
|
+
const { AMFLoader } = await import( 'three/addons/loaders/AMFLoader.js' );
|
|
159
|
+
|
|
160
|
+
const loader = new AMFLoader();
|
|
161
|
+
const amfobject = loader.parse( event.target.result );
|
|
162
|
+
|
|
163
|
+
editor.execute( new AddObjectCommand( editor, amfobject ) );
|
|
164
|
+
|
|
165
|
+
}, false );
|
|
166
|
+
reader.readAsArrayBuffer( file );
|
|
167
|
+
|
|
168
|
+
break;
|
|
169
|
+
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
case 'dae':
|
|
173
|
+
|
|
174
|
+
{
|
|
175
|
+
|
|
176
|
+
reader.addEventListener( 'load', async function ( event ) {
|
|
177
|
+
|
|
178
|
+
const contents = event.target.result;
|
|
179
|
+
|
|
180
|
+
const { ColladaLoader } = await import( 'three/addons/loaders/ColladaLoader.js' );
|
|
181
|
+
|
|
182
|
+
const loader = new ColladaLoader( manager );
|
|
183
|
+
const collada = loader.parse( contents );
|
|
184
|
+
|
|
185
|
+
collada.scene.name = filename;
|
|
186
|
+
|
|
187
|
+
editor.execute( new AddObjectCommand( editor, collada.scene ) );
|
|
188
|
+
|
|
189
|
+
}, false );
|
|
190
|
+
reader.readAsText( file );
|
|
191
|
+
|
|
192
|
+
break;
|
|
193
|
+
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
case 'drc':
|
|
197
|
+
|
|
198
|
+
{
|
|
199
|
+
|
|
200
|
+
reader.addEventListener( 'load', async function ( event ) {
|
|
201
|
+
|
|
202
|
+
const contents = event.target.result;
|
|
203
|
+
|
|
204
|
+
const { DRACOLoader } = await import( 'three/addons/loaders/DRACOLoader.js' );
|
|
205
|
+
|
|
206
|
+
const loader = new DRACOLoader();
|
|
207
|
+
loader.setDecoderPath( '../examples/jsm/libs/draco/' );
|
|
208
|
+
loader.parse( contents, function ( geometry ) {
|
|
209
|
+
|
|
210
|
+
let object;
|
|
211
|
+
|
|
212
|
+
if ( geometry.index !== null ) {
|
|
213
|
+
|
|
214
|
+
const material = new THREE.MeshStandardMaterial();
|
|
215
|
+
|
|
216
|
+
object = new THREE.Mesh( geometry, material );
|
|
217
|
+
object.name = filename;
|
|
218
|
+
|
|
219
|
+
} else {
|
|
220
|
+
|
|
221
|
+
const material = new THREE.PointsMaterial( { size: 0.01 } );
|
|
222
|
+
material.vertexColors = geometry.hasAttribute( 'color' );
|
|
223
|
+
|
|
224
|
+
object = new THREE.Points( geometry, material );
|
|
225
|
+
object.name = filename;
|
|
226
|
+
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
loader.dispose();
|
|
230
|
+
editor.execute( new AddObjectCommand( editor, object ) );
|
|
231
|
+
|
|
232
|
+
} );
|
|
233
|
+
|
|
234
|
+
}, false );
|
|
235
|
+
reader.readAsArrayBuffer( file );
|
|
236
|
+
|
|
237
|
+
break;
|
|
238
|
+
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
case 'fbx':
|
|
242
|
+
|
|
243
|
+
{
|
|
244
|
+
|
|
245
|
+
reader.addEventListener( 'load', async function ( event ) {
|
|
246
|
+
|
|
247
|
+
const contents = event.target.result;
|
|
248
|
+
|
|
249
|
+
const { FBXLoader } = await import( 'three/addons/loaders/FBXLoader.js' );
|
|
250
|
+
|
|
251
|
+
const loader = new FBXLoader( manager );
|
|
252
|
+
const object = loader.parse( contents );
|
|
253
|
+
|
|
254
|
+
editor.execute( new AddObjectCommand( editor, object ) );
|
|
255
|
+
|
|
256
|
+
}, false );
|
|
257
|
+
reader.readAsArrayBuffer( file );
|
|
258
|
+
|
|
259
|
+
break;
|
|
260
|
+
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
case 'glb':
|
|
264
|
+
|
|
265
|
+
{
|
|
266
|
+
|
|
267
|
+
reader.addEventListener( 'load', async function ( event ) {
|
|
268
|
+
|
|
269
|
+
const contents = event.target.result;
|
|
270
|
+
|
|
271
|
+
const loader = await createGLTFLoader();
|
|
272
|
+
|
|
273
|
+
loader.parse( contents, '', function ( result ) {
|
|
274
|
+
|
|
275
|
+
const scene = result.scene;
|
|
276
|
+
scene.name = filename;
|
|
277
|
+
|
|
278
|
+
scene.animations.push( ...result.animations );
|
|
279
|
+
editor.execute( new AddObjectCommand( editor, scene ) );
|
|
280
|
+
|
|
281
|
+
loader.dracoLoader.dispose();
|
|
282
|
+
loader.ktx2Loader.dispose();
|
|
283
|
+
|
|
284
|
+
} );
|
|
285
|
+
|
|
286
|
+
}, false );
|
|
287
|
+
reader.readAsArrayBuffer( file );
|
|
288
|
+
|
|
289
|
+
break;
|
|
290
|
+
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
case 'gltf':
|
|
294
|
+
|
|
295
|
+
{
|
|
296
|
+
|
|
297
|
+
reader.addEventListener( 'load', async function ( event ) {
|
|
298
|
+
|
|
299
|
+
const contents = event.target.result;
|
|
300
|
+
|
|
301
|
+
const loader = await createGLTFLoader( manager );
|
|
302
|
+
|
|
303
|
+
loader.parse( contents, '', function ( result ) {
|
|
304
|
+
|
|
305
|
+
const scene = result.scene;
|
|
306
|
+
scene.name = filename;
|
|
307
|
+
|
|
308
|
+
scene.animations.push( ...result.animations );
|
|
309
|
+
editor.execute( new AddObjectCommand( editor, scene ) );
|
|
310
|
+
|
|
311
|
+
loader.dracoLoader.dispose();
|
|
312
|
+
loader.ktx2Loader.dispose();
|
|
313
|
+
|
|
314
|
+
} );
|
|
315
|
+
|
|
316
|
+
}, false );
|
|
317
|
+
reader.readAsArrayBuffer( file );
|
|
318
|
+
|
|
319
|
+
break;
|
|
320
|
+
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
case 'js':
|
|
324
|
+
case 'json':
|
|
325
|
+
|
|
326
|
+
{
|
|
327
|
+
|
|
328
|
+
reader.addEventListener( 'load', function ( event ) {
|
|
329
|
+
|
|
330
|
+
const contents = event.target.result;
|
|
331
|
+
|
|
332
|
+
// 2.0
|
|
333
|
+
|
|
334
|
+
if ( contents.indexOf( 'postMessage' ) !== - 1 ) {
|
|
335
|
+
|
|
336
|
+
const blob = new Blob( [ contents ], { type: 'text/javascript' } );
|
|
337
|
+
const url = URL.createObjectURL( blob );
|
|
338
|
+
|
|
339
|
+
const worker = new Worker( url );
|
|
340
|
+
|
|
341
|
+
worker.onmessage = function ( event ) {
|
|
342
|
+
|
|
343
|
+
event.data.metadata = { version: 2 };
|
|
344
|
+
handleJSON( event.data );
|
|
345
|
+
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
worker.postMessage( Date.now() );
|
|
349
|
+
|
|
350
|
+
return;
|
|
351
|
+
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// >= 3.0
|
|
355
|
+
|
|
356
|
+
let data;
|
|
357
|
+
|
|
358
|
+
try {
|
|
359
|
+
|
|
360
|
+
data = JSON.parse( contents );
|
|
361
|
+
|
|
362
|
+
} catch ( error ) {
|
|
363
|
+
|
|
364
|
+
alert( error );
|
|
365
|
+
return;
|
|
366
|
+
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
handleJSON( data );
|
|
370
|
+
|
|
371
|
+
}, false );
|
|
372
|
+
reader.readAsText( file );
|
|
373
|
+
|
|
374
|
+
break;
|
|
375
|
+
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
case 'kmz':
|
|
379
|
+
|
|
380
|
+
{
|
|
381
|
+
|
|
382
|
+
reader.addEventListener( 'load', async function ( event ) {
|
|
383
|
+
|
|
384
|
+
const { KMZLoader } = await import( 'three/addons/loaders/KMZLoader.js' );
|
|
385
|
+
|
|
386
|
+
const loader = new KMZLoader();
|
|
387
|
+
const collada = loader.parse( event.target.result );
|
|
388
|
+
|
|
389
|
+
collada.scene.name = filename;
|
|
390
|
+
|
|
391
|
+
editor.execute( new AddObjectCommand( editor, collada.scene ) );
|
|
392
|
+
|
|
393
|
+
}, false );
|
|
394
|
+
reader.readAsArrayBuffer( file );
|
|
395
|
+
|
|
396
|
+
break;
|
|
397
|
+
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
case 'ldr':
|
|
401
|
+
case 'mpd':
|
|
402
|
+
|
|
403
|
+
{
|
|
404
|
+
|
|
405
|
+
reader.addEventListener( 'load', async function ( event ) {
|
|
406
|
+
|
|
407
|
+
const { LDrawLoader } = await import( 'three/addons/loaders/LDrawLoader.js' );
|
|
408
|
+
|
|
409
|
+
const loader = new LDrawLoader();
|
|
410
|
+
loader.setPath( '../../examples/models/ldraw/officialLibrary/' );
|
|
411
|
+
loader.parse( event.target.result, function ( group ) {
|
|
412
|
+
|
|
413
|
+
group.name = filename;
|
|
414
|
+
// Convert from LDraw coordinates: rotate 180 degrees around OX
|
|
415
|
+
group.rotation.x = Math.PI;
|
|
416
|
+
|
|
417
|
+
editor.execute( new AddObjectCommand( editor, group ) );
|
|
418
|
+
|
|
419
|
+
} );
|
|
420
|
+
|
|
421
|
+
}, false );
|
|
422
|
+
reader.readAsText( file );
|
|
423
|
+
|
|
424
|
+
break;
|
|
425
|
+
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
case 'md2':
|
|
429
|
+
|
|
430
|
+
{
|
|
431
|
+
|
|
432
|
+
reader.addEventListener( 'load', async function ( event ) {
|
|
433
|
+
|
|
434
|
+
const contents = event.target.result;
|
|
435
|
+
|
|
436
|
+
const { MD2Loader } = await import( 'three/addons/loaders/MD2Loader.js' );
|
|
437
|
+
|
|
438
|
+
const geometry = new MD2Loader().parse( contents );
|
|
439
|
+
const material = new THREE.MeshStandardMaterial();
|
|
440
|
+
|
|
441
|
+
const mesh = new THREE.Mesh( geometry, material );
|
|
442
|
+
mesh.mixer = new THREE.AnimationMixer( mesh );
|
|
443
|
+
mesh.name = filename;
|
|
444
|
+
|
|
445
|
+
mesh.animations.push( ...geometry.animations );
|
|
446
|
+
editor.execute( new AddObjectCommand( editor, mesh ) );
|
|
447
|
+
|
|
448
|
+
}, false );
|
|
449
|
+
reader.readAsArrayBuffer( file );
|
|
450
|
+
|
|
451
|
+
break;
|
|
452
|
+
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
case 'obj':
|
|
456
|
+
|
|
457
|
+
{
|
|
458
|
+
|
|
459
|
+
reader.addEventListener( 'load', async function ( event ) {
|
|
460
|
+
|
|
461
|
+
const contents = event.target.result;
|
|
462
|
+
|
|
463
|
+
const { OBJLoader } = await import( 'three/addons/loaders/OBJLoader.js' );
|
|
464
|
+
|
|
465
|
+
const object = new OBJLoader().parse( contents );
|
|
466
|
+
object.name = filename;
|
|
467
|
+
|
|
468
|
+
editor.execute( new AddObjectCommand( editor, object ) );
|
|
469
|
+
|
|
470
|
+
}, false );
|
|
471
|
+
reader.readAsText( file );
|
|
472
|
+
|
|
473
|
+
break;
|
|
474
|
+
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
case 'pcd':
|
|
478
|
+
|
|
479
|
+
{
|
|
480
|
+
|
|
481
|
+
reader.addEventListener( 'load', async function ( event ) {
|
|
482
|
+
|
|
483
|
+
const contents = event.target.result;
|
|
484
|
+
|
|
485
|
+
const { PCDLoader } = await import( 'three/addons/loaders/PCDLoader.js' );
|
|
486
|
+
|
|
487
|
+
const points = new PCDLoader().parse( contents );
|
|
488
|
+
points.name = filename;
|
|
489
|
+
|
|
490
|
+
editor.execute( new AddObjectCommand( editor, points ) );
|
|
491
|
+
|
|
492
|
+
}, false );
|
|
493
|
+
reader.readAsArrayBuffer( file );
|
|
494
|
+
|
|
495
|
+
break;
|
|
496
|
+
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
case 'ply':
|
|
500
|
+
|
|
501
|
+
{
|
|
502
|
+
|
|
503
|
+
reader.addEventListener( 'load', async function ( event ) {
|
|
504
|
+
|
|
505
|
+
const contents = event.target.result;
|
|
506
|
+
|
|
507
|
+
const { PLYLoader } = await import( 'three/addons/loaders/PLYLoader.js' );
|
|
508
|
+
|
|
509
|
+
const geometry = new PLYLoader().parse( contents );
|
|
510
|
+
let object;
|
|
511
|
+
|
|
512
|
+
if ( geometry.index !== null ) {
|
|
513
|
+
|
|
514
|
+
const material = new THREE.MeshStandardMaterial();
|
|
515
|
+
|
|
516
|
+
object = new THREE.Mesh( geometry, material );
|
|
517
|
+
object.name = filename;
|
|
518
|
+
|
|
519
|
+
} else {
|
|
520
|
+
|
|
521
|
+
const material = new THREE.PointsMaterial( { size: 0.01 } );
|
|
522
|
+
material.vertexColors = geometry.hasAttribute( 'color' );
|
|
523
|
+
|
|
524
|
+
object = new THREE.Points( geometry, material );
|
|
525
|
+
object.name = filename;
|
|
526
|
+
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
editor.execute( new AddObjectCommand( editor, object ) );
|
|
530
|
+
|
|
531
|
+
}, false );
|
|
532
|
+
reader.readAsArrayBuffer( file );
|
|
533
|
+
|
|
534
|
+
break;
|
|
535
|
+
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
case 'stl':
|
|
539
|
+
|
|
540
|
+
{
|
|
541
|
+
|
|
542
|
+
reader.addEventListener( 'load', async function ( event ) {
|
|
543
|
+
|
|
544
|
+
const contents = event.target.result;
|
|
545
|
+
|
|
546
|
+
const { STLLoader } = await import( 'three/addons/loaders/STLLoader.js' );
|
|
547
|
+
|
|
548
|
+
const geometry = new STLLoader().parse( contents );
|
|
549
|
+
const material = new THREE.MeshStandardMaterial();
|
|
550
|
+
|
|
551
|
+
const mesh = new THREE.Mesh( geometry, material );
|
|
552
|
+
mesh.name = filename;
|
|
553
|
+
|
|
554
|
+
editor.execute( new AddObjectCommand( editor, mesh ) );
|
|
555
|
+
|
|
556
|
+
}, false );
|
|
557
|
+
|
|
558
|
+
if ( reader.readAsBinaryString !== undefined ) {
|
|
559
|
+
|
|
560
|
+
reader.readAsBinaryString( file );
|
|
561
|
+
|
|
562
|
+
} else {
|
|
563
|
+
|
|
564
|
+
reader.readAsArrayBuffer( file );
|
|
565
|
+
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
break;
|
|
569
|
+
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
case 'svg':
|
|
573
|
+
|
|
574
|
+
{
|
|
575
|
+
|
|
576
|
+
reader.addEventListener( 'load', async function ( event ) {
|
|
577
|
+
|
|
578
|
+
const contents = event.target.result;
|
|
579
|
+
|
|
580
|
+
const { SVGLoader } = await import( 'three/addons/loaders/SVGLoader.js' );
|
|
581
|
+
|
|
582
|
+
const loader = new SVGLoader();
|
|
583
|
+
const paths = loader.parse( contents ).paths;
|
|
584
|
+
|
|
585
|
+
//
|
|
586
|
+
|
|
587
|
+
const group = new THREE.Group();
|
|
588
|
+
group.name = filename;
|
|
589
|
+
group.scale.multiplyScalar( 0.1 );
|
|
590
|
+
group.scale.y *= - 1;
|
|
591
|
+
|
|
592
|
+
for ( let i = 0; i < paths.length; i ++ ) {
|
|
593
|
+
|
|
594
|
+
const path = paths[ i ];
|
|
595
|
+
|
|
596
|
+
const material = new THREE.MeshBasicMaterial( {
|
|
597
|
+
color: path.color,
|
|
598
|
+
depthWrite: false
|
|
599
|
+
} );
|
|
600
|
+
|
|
601
|
+
const shapes = SVGLoader.createShapes( path );
|
|
602
|
+
|
|
603
|
+
for ( let j = 0; j < shapes.length; j ++ ) {
|
|
604
|
+
|
|
605
|
+
const shape = shapes[ j ];
|
|
606
|
+
|
|
607
|
+
const geometry = new THREE.ShapeGeometry( shape );
|
|
608
|
+
const mesh = new THREE.Mesh( geometry, material );
|
|
609
|
+
|
|
610
|
+
group.add( mesh );
|
|
611
|
+
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
editor.execute( new AddObjectCommand( editor, group ) );
|
|
617
|
+
|
|
618
|
+
}, false );
|
|
619
|
+
reader.readAsText( file );
|
|
620
|
+
|
|
621
|
+
break;
|
|
622
|
+
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
case 'usdz':
|
|
626
|
+
|
|
627
|
+
{
|
|
628
|
+
|
|
629
|
+
reader.addEventListener( 'load', async function ( event ) {
|
|
630
|
+
|
|
631
|
+
const contents = event.target.result;
|
|
632
|
+
|
|
633
|
+
const { USDZLoader } = await import( 'three/addons/loaders/USDZLoader.js' );
|
|
634
|
+
|
|
635
|
+
const group = new USDZLoader().parse( contents );
|
|
636
|
+
group.name = filename;
|
|
637
|
+
|
|
638
|
+
editor.execute( new AddObjectCommand( editor, group ) );
|
|
639
|
+
|
|
640
|
+
}, false );
|
|
641
|
+
reader.readAsArrayBuffer( file );
|
|
642
|
+
|
|
643
|
+
break;
|
|
644
|
+
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
case 'vox':
|
|
648
|
+
|
|
649
|
+
{
|
|
650
|
+
|
|
651
|
+
reader.addEventListener( 'load', async function ( event ) {
|
|
652
|
+
|
|
653
|
+
const contents = event.target.result;
|
|
654
|
+
|
|
655
|
+
const { VOXLoader, VOXMesh } = await import( 'three/addons/loaders/VOXLoader.js' );
|
|
656
|
+
|
|
657
|
+
const chunks = new VOXLoader().parse( contents );
|
|
658
|
+
|
|
659
|
+
const group = new THREE.Group();
|
|
660
|
+
group.name = filename;
|
|
661
|
+
|
|
662
|
+
for ( let i = 0; i < chunks.length; i ++ ) {
|
|
663
|
+
|
|
664
|
+
const chunk = chunks[ i ];
|
|
665
|
+
|
|
666
|
+
const mesh = new VOXMesh( chunk );
|
|
667
|
+
group.add( mesh );
|
|
668
|
+
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
editor.execute( new AddObjectCommand( editor, group ) );
|
|
672
|
+
|
|
673
|
+
}, false );
|
|
674
|
+
reader.readAsArrayBuffer( file );
|
|
675
|
+
|
|
676
|
+
break;
|
|
677
|
+
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
case 'vtk':
|
|
681
|
+
case 'vtp':
|
|
682
|
+
|
|
683
|
+
{
|
|
684
|
+
|
|
685
|
+
reader.addEventListener( 'load', async function ( event ) {
|
|
686
|
+
|
|
687
|
+
const contents = event.target.result;
|
|
688
|
+
|
|
689
|
+
const { VTKLoader } = await import( 'three/addons/loaders/VTKLoader.js' );
|
|
690
|
+
|
|
691
|
+
const geometry = new VTKLoader().parse( contents );
|
|
692
|
+
const material = new THREE.MeshStandardMaterial();
|
|
693
|
+
|
|
694
|
+
const mesh = new THREE.Mesh( geometry, material );
|
|
695
|
+
mesh.name = filename;
|
|
696
|
+
|
|
697
|
+
editor.execute( new AddObjectCommand( editor, mesh ) );
|
|
698
|
+
|
|
699
|
+
}, false );
|
|
700
|
+
reader.readAsArrayBuffer( file );
|
|
701
|
+
|
|
702
|
+
break;
|
|
703
|
+
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
case 'wrl':
|
|
707
|
+
|
|
708
|
+
{
|
|
709
|
+
|
|
710
|
+
reader.addEventListener( 'load', async function ( event ) {
|
|
711
|
+
|
|
712
|
+
const contents = event.target.result;
|
|
713
|
+
|
|
714
|
+
const { VRMLLoader } = await import( 'three/addons/loaders/VRMLLoader.js' );
|
|
715
|
+
|
|
716
|
+
const result = new VRMLLoader().parse( contents );
|
|
717
|
+
|
|
718
|
+
editor.execute( new AddObjectCommand( editor, result ) );
|
|
719
|
+
|
|
720
|
+
}, false );
|
|
721
|
+
reader.readAsText( file );
|
|
722
|
+
|
|
723
|
+
break;
|
|
724
|
+
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
case 'xyz':
|
|
728
|
+
|
|
729
|
+
{
|
|
730
|
+
|
|
731
|
+
reader.addEventListener( 'load', async function ( event ) {
|
|
732
|
+
|
|
733
|
+
const contents = event.target.result;
|
|
734
|
+
|
|
735
|
+
const { XYZLoader } = await import( 'three/addons/loaders/XYZLoader.js' );
|
|
736
|
+
|
|
737
|
+
const geometry = new XYZLoader().parse( contents );
|
|
738
|
+
|
|
739
|
+
const material = new THREE.PointsMaterial();
|
|
740
|
+
material.vertexColors = geometry.hasAttribute( 'color' );
|
|
741
|
+
|
|
742
|
+
const points = new THREE.Points( geometry, material );
|
|
743
|
+
points.name = filename;
|
|
744
|
+
|
|
745
|
+
editor.execute( new AddObjectCommand( editor, points ) );
|
|
746
|
+
|
|
747
|
+
}, false );
|
|
748
|
+
reader.readAsText( file );
|
|
749
|
+
|
|
750
|
+
break;
|
|
751
|
+
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
case 'zip':
|
|
755
|
+
|
|
756
|
+
{
|
|
757
|
+
|
|
758
|
+
reader.addEventListener( 'load', function ( event ) {
|
|
759
|
+
|
|
760
|
+
handleZIP( event.target.result );
|
|
761
|
+
|
|
762
|
+
}, false );
|
|
763
|
+
reader.readAsArrayBuffer( file );
|
|
764
|
+
|
|
765
|
+
break;
|
|
766
|
+
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
default:
|
|
770
|
+
|
|
771
|
+
console.error( 'Unsupported file format (' + extension + ').' );
|
|
772
|
+
|
|
773
|
+
break;
|
|
774
|
+
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
};
|
|
778
|
+
|
|
779
|
+
function handleJSON( data ) {
|
|
780
|
+
|
|
781
|
+
if ( data.metadata === undefined ) { // 2.0
|
|
782
|
+
|
|
783
|
+
data.metadata = { type: 'Geometry' };
|
|
784
|
+
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
if ( data.metadata.type === undefined ) { // 3.0
|
|
788
|
+
|
|
789
|
+
data.metadata.type = 'Geometry';
|
|
790
|
+
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
if ( data.metadata.formatVersion !== undefined ) {
|
|
794
|
+
|
|
795
|
+
data.metadata.version = data.metadata.formatVersion;
|
|
796
|
+
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
switch ( data.metadata.type.toLowerCase() ) {
|
|
800
|
+
|
|
801
|
+
case 'buffergeometry':
|
|
802
|
+
|
|
803
|
+
{
|
|
804
|
+
|
|
805
|
+
const loader = new THREE.BufferGeometryLoader();
|
|
806
|
+
const result = loader.parse( data );
|
|
807
|
+
|
|
808
|
+
const mesh = new THREE.Mesh( result );
|
|
809
|
+
|
|
810
|
+
editor.execute( new AddObjectCommand( editor, mesh ) );
|
|
811
|
+
|
|
812
|
+
break;
|
|
813
|
+
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
case 'geometry':
|
|
817
|
+
|
|
818
|
+
console.error( 'Loader: "Geometry" is no longer supported.' );
|
|
819
|
+
|
|
820
|
+
break;
|
|
821
|
+
|
|
822
|
+
case 'object':
|
|
823
|
+
|
|
824
|
+
{
|
|
825
|
+
|
|
826
|
+
const loader = new THREE.ObjectLoader();
|
|
827
|
+
loader.setResourcePath( scope.texturePath );
|
|
828
|
+
|
|
829
|
+
loader.parse( data, function ( result ) {
|
|
830
|
+
|
|
831
|
+
editor.execute( new AddObjectCommand( editor, result ) );
|
|
832
|
+
|
|
833
|
+
} );
|
|
834
|
+
|
|
835
|
+
break;
|
|
836
|
+
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
case 'app':
|
|
840
|
+
|
|
841
|
+
editor.fromJSON( data );
|
|
842
|
+
|
|
843
|
+
break;
|
|
844
|
+
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
async function handleZIP( contents ) {
|
|
850
|
+
|
|
851
|
+
const zip = unzipSync( new Uint8Array( contents ) );
|
|
852
|
+
|
|
853
|
+
const manager = new THREE.LoadingManager();
|
|
854
|
+
manager.setURLModifier( function ( url ) {
|
|
855
|
+
|
|
856
|
+
const file = zip[ url ];
|
|
857
|
+
|
|
858
|
+
if ( file ) {
|
|
859
|
+
|
|
860
|
+
console.log( 'Loading', url );
|
|
861
|
+
|
|
862
|
+
const blob = new Blob( [ file.buffer ], { type: 'application/octet-stream' } );
|
|
863
|
+
return URL.createObjectURL( blob );
|
|
864
|
+
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
return url;
|
|
868
|
+
|
|
869
|
+
} );
|
|
870
|
+
|
|
871
|
+
// Poly
|
|
872
|
+
|
|
873
|
+
if ( zip[ 'model.obj' ] && zip[ 'materials.mtl' ] ) {
|
|
874
|
+
|
|
875
|
+
const { MTLLoader } = await import( 'three/addons/loaders/MTLLoader.js' );
|
|
876
|
+
const { OBJLoader } = await import( 'three/addons/loaders/OBJLoader.js' );
|
|
877
|
+
|
|
878
|
+
const materials = new MTLLoader( manager ).parse( strFromU8( zip[ 'materials.mtl' ] ) );
|
|
879
|
+
const object = new OBJLoader().setMaterials( materials ).parse( strFromU8( zip[ 'model.obj' ] ) );
|
|
880
|
+
|
|
881
|
+
editor.execute( new AddObjectCommand( editor, object ) );
|
|
882
|
+
return;
|
|
883
|
+
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
//
|
|
887
|
+
|
|
888
|
+
for ( const path in zip ) {
|
|
889
|
+
|
|
890
|
+
const file = zip[ path ];
|
|
891
|
+
|
|
892
|
+
const extension = path.split( '.' ).pop().toLowerCase();
|
|
893
|
+
|
|
894
|
+
switch ( extension ) {
|
|
895
|
+
|
|
896
|
+
case 'fbx':
|
|
897
|
+
|
|
898
|
+
{
|
|
899
|
+
|
|
900
|
+
const { FBXLoader } = await import( 'three/addons/loaders/FBXLoader.js' );
|
|
901
|
+
|
|
902
|
+
const loader = new FBXLoader( manager );
|
|
903
|
+
const object = loader.parse( file.buffer );
|
|
904
|
+
|
|
905
|
+
editor.execute( new AddObjectCommand( editor, object ) );
|
|
906
|
+
|
|
907
|
+
break;
|
|
908
|
+
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
case 'glb':
|
|
912
|
+
|
|
913
|
+
{
|
|
914
|
+
|
|
915
|
+
const loader = await createGLTFLoader();
|
|
916
|
+
|
|
917
|
+
loader.parse( file.buffer, '', function ( result ) {
|
|
918
|
+
|
|
919
|
+
const scene = result.scene;
|
|
920
|
+
|
|
921
|
+
scene.animations.push( ...result.animations );
|
|
922
|
+
editor.execute( new AddObjectCommand( editor, scene ) );
|
|
923
|
+
|
|
924
|
+
loader.dracoLoader.dispose();
|
|
925
|
+
loader.ktx2Loader.dispose();
|
|
926
|
+
|
|
927
|
+
} );
|
|
928
|
+
|
|
929
|
+
break;
|
|
930
|
+
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
case 'gltf':
|
|
934
|
+
|
|
935
|
+
{
|
|
936
|
+
|
|
937
|
+
const loader = await createGLTFLoader( manager );
|
|
938
|
+
|
|
939
|
+
loader.parse( strFromU8( file ), '', function ( result ) {
|
|
940
|
+
|
|
941
|
+
const scene = result.scene;
|
|
942
|
+
|
|
943
|
+
scene.animations.push( ...result.animations );
|
|
944
|
+
editor.execute( new AddObjectCommand( editor, scene ) );
|
|
945
|
+
|
|
946
|
+
loader.dracoLoader.dispose();
|
|
947
|
+
loader.ktx2Loader.dispose();
|
|
948
|
+
|
|
949
|
+
} );
|
|
950
|
+
|
|
951
|
+
break;
|
|
952
|
+
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
async function createGLTFLoader( manager ) {
|
|
962
|
+
|
|
963
|
+
const { GLTFLoader } = await import( 'three/addons/loaders/GLTFLoader.js' );
|
|
964
|
+
const { DRACOLoader } = await import( 'three/addons/loaders/DRACOLoader.js' );
|
|
965
|
+
const { KTX2Loader } = await import( 'three/addons/loaders/KTX2Loader.js' );
|
|
966
|
+
const { MeshoptDecoder } = await import( 'three/addons/libs/meshopt_decoder.module.js' );
|
|
967
|
+
|
|
968
|
+
const dracoLoader = new DRACOLoader();
|
|
969
|
+
dracoLoader.setDecoderPath( '../examples/jsm/libs/draco/gltf/' );
|
|
970
|
+
|
|
971
|
+
const ktx2Loader = new KTX2Loader( manager );
|
|
972
|
+
ktx2Loader.setTranscoderPath( '../examples/jsm/libs/basis/' );
|
|
973
|
+
|
|
974
|
+
editor.signals.rendererDetectKTX2Support.dispatch( ktx2Loader );
|
|
975
|
+
|
|
976
|
+
const loader = new GLTFLoader( manager );
|
|
977
|
+
loader.setDRACOLoader( dracoLoader );
|
|
978
|
+
loader.setKTX2Loader( ktx2Loader );
|
|
979
|
+
loader.setMeshoptDecoder( MeshoptDecoder );
|
|
980
|
+
|
|
981
|
+
return loader;
|
|
982
|
+
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
export { Loader };
|