three-base 2.0.84 → 2.0.85
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/PlaneText.d.ts +2 -2
- package/README.md +2 -3
- package/package.json +46 -45
- package/threeLoader.d.ts +6 -2
- package/threeLoader.js +205 -67
- package/threeLoader.ts +366 -176
- package/threeUtils.d.ts +2 -0
- package/threeUtils.js +32 -20
- package/threeUtils.ts +324 -280
package/threeLoader.ts
CHANGED
|
@@ -1,16 +1,27 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* @Author: xiaosihan
|
|
3
|
-
* @Date: 2022-04-07 16:42:26
|
|
2
|
+
* @Author: xiaosihan
|
|
3
|
+
* @Date: 2022-04-07 16:42:26
|
|
4
4
|
* @Last Modified by: xiaosihan
|
|
5
5
|
* @Last Modified time: 2023-02-07 11:11:48
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
CanvasTexture,
|
|
10
|
+
DefaultLoadingManager,
|
|
11
|
+
EventDispatcher,
|
|
12
|
+
Material,
|
|
13
|
+
Mesh,
|
|
14
|
+
MeshStandardMaterial,
|
|
15
|
+
RepeatWrapping,
|
|
16
|
+
Texture,
|
|
17
|
+
TextureLoader,
|
|
18
|
+
VideoTexture,
|
|
19
|
+
} from "three";
|
|
20
|
+
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
|
|
9
21
|
import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader";
|
|
10
22
|
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
|
|
11
23
|
import { MTLLoader } from "three/examples/jsm/loaders/MTLLoader";
|
|
12
24
|
import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader";
|
|
13
|
-
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
|
|
14
25
|
import { STLLoader } from "three/examples/jsm/loaders/STLLoader";
|
|
15
26
|
import { USDZLoader } from "three/examples/jsm/loaders/USDZLoader";
|
|
16
27
|
|
|
@@ -18,211 +29,390 @@ import { USDZLoader } from "three/examples/jsm/loaders/USDZLoader";
|
|
|
18
29
|
// import { IFCLoader } from 'web-ifc-three';
|
|
19
30
|
// import { IFCSPACE } from 'web-ifc';
|
|
20
31
|
|
|
21
|
-
|
|
22
32
|
// 引入静态资源
|
|
23
33
|
//@ts-ignore
|
|
24
34
|
import dracoWasmWrapperJS from "./lib/draco/draco_wasm_wrapper.js?url";
|
|
25
35
|
//@ts-ignore
|
|
26
36
|
import dracoDecoderJS from "./lib/draco/draco_decoder.js?url";
|
|
27
37
|
//@ts-ignore
|
|
38
|
+
import axios from "axios";
|
|
28
39
|
import dracoDecoderWASM from "./lib/draco/draco_decoder.wasm?url";
|
|
29
|
-
import
|
|
40
|
+
import threeUtils from "./threeUtils";
|
|
30
41
|
|
|
31
42
|
// 加载器
|
|
32
43
|
class ThreeLoader extends EventDispatcher {
|
|
44
|
+
constructor() {
|
|
45
|
+
super();
|
|
33
46
|
|
|
34
|
-
|
|
35
|
-
|
|
47
|
+
DefaultLoadingManager.onStart = () => {
|
|
48
|
+
this.onload = false;
|
|
49
|
+
};
|
|
36
50
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
51
|
+
// 有资源加载完成时通知渲染器
|
|
52
|
+
DefaultLoadingManager.onProgress = (
|
|
53
|
+
url: string,
|
|
54
|
+
loaded: number,
|
|
55
|
+
total: number
|
|
56
|
+
) => {
|
|
57
|
+
if (loaded < total) {
|
|
58
|
+
this.dispatchEvent({ type: "loadding" } as never);
|
|
59
|
+
} else if (loaded === total) {
|
|
60
|
+
this.dispatchEvent({ type: "onLoad" } as never);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
40
63
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
this.dispatchEvent({ type: "loadding" } as never);
|
|
45
|
-
} else if (loaded === total) {
|
|
46
|
-
this.dispatchEvent({ type: "onLoad" } as never);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
64
|
+
DefaultLoadingManager.onLoad = () => {
|
|
65
|
+
this.onload = true;
|
|
66
|
+
};
|
|
49
67
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
68
|
+
// 资源替换
|
|
69
|
+
DefaultLoadingManager.setURLModifier((url) => {
|
|
70
|
+
const filename = url
|
|
71
|
+
.replace(`blob:${location.origin}/`, "")
|
|
72
|
+
.replace(/^\.\//, "");
|
|
73
|
+
let new_url = this._blobs[filename] || url;
|
|
74
|
+
//如果全匹配没有匹配到资源,就尝试文件名匹配
|
|
75
|
+
if (!this._blobs[filename]) {
|
|
76
|
+
const blobKey =
|
|
77
|
+
Object.keys(this._blobs).find((key) =>
|
|
78
|
+
new RegExp(`${key}$`).test(filename)
|
|
79
|
+
) || "";
|
|
80
|
+
new_url = this._blobs[blobKey] || url;
|
|
81
|
+
}
|
|
82
|
+
return new_url;
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// 各向异性
|
|
87
|
+
anisotropy = 16;
|
|
88
|
+
|
|
89
|
+
// 设置各向异性 由渲染器来调用并设置
|
|
90
|
+
setAnisotropy(v: number) {
|
|
91
|
+
this.anisotropy = v;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// 纹理对向缓存
|
|
95
|
+
textureMap = new Map() as Map<string, Texture>;
|
|
96
|
+
|
|
97
|
+
// 纹理加载器
|
|
98
|
+
textureLoader = new TextureLoader();
|
|
99
|
+
|
|
100
|
+
// 获取地址对应的单例纹理对象
|
|
101
|
+
getTexture(src: string | HTMLCanvasElement) {
|
|
102
|
+
if (src instanceof HTMLCanvasElement) {
|
|
103
|
+
const canvasTexture = new CanvasTexture(src);
|
|
104
|
+
canvasTexture.wrapS = canvasTexture.wrapT = RepeatWrapping;
|
|
105
|
+
canvasTexture.anisotropy = this.anisotropy;
|
|
106
|
+
// canvasTexture.colorSpace = SRGBColorSpace;
|
|
107
|
+
|
|
108
|
+
return canvasTexture;
|
|
53
109
|
}
|
|
54
110
|
|
|
55
|
-
|
|
56
|
-
|
|
111
|
+
let texture = this.textureMap.get(src);
|
|
112
|
+
|
|
113
|
+
if (!texture) {
|
|
114
|
+
if (/\.(mp4|mov)$/i.test(src)) {
|
|
115
|
+
const videoDom = document.createElement("video");
|
|
116
|
+
videoDom.autoplay = true;
|
|
117
|
+
videoDom.loop = true;
|
|
118
|
+
videoDom.muted = true;
|
|
119
|
+
videoDom.preload = "auto";
|
|
120
|
+
videoDom.playsInline = true;
|
|
121
|
+
videoDom.src = src;
|
|
122
|
+
videoDom.crossOrigin = "anonymous";
|
|
123
|
+
videoDom.play();
|
|
124
|
+
const firstOptoin = () => {
|
|
125
|
+
videoDom.pause();
|
|
126
|
+
videoDom.play();
|
|
127
|
+
document.removeEventListener("pointerup", firstOptoin);
|
|
128
|
+
document.removeEventListener("touchstart", firstOptoin);
|
|
129
|
+
};
|
|
130
|
+
document.addEventListener("pointerup", firstOptoin);
|
|
131
|
+
document.addEventListener("touchstart", firstOptoin);
|
|
132
|
+
texture = new VideoTexture(videoDom);
|
|
133
|
+
} else {
|
|
134
|
+
texture = this.textureLoader.load(src, (tex) => {
|
|
135
|
+
tex.image.crossOrigin = "anonymous";
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
this.textureMap.set(src, texture);
|
|
140
|
+
}
|
|
57
141
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
};
|
|
142
|
+
texture.wrapS = texture.wrapT = RepeatWrapping;
|
|
143
|
+
texture.anisotropy = this.anisotropy;
|
|
144
|
+
// texture.colorSpace = SRGBColorSpace;
|
|
62
145
|
|
|
63
|
-
|
|
64
|
-
|
|
146
|
+
return texture as Texture;
|
|
147
|
+
}
|
|
65
148
|
|
|
66
|
-
|
|
67
|
-
|
|
149
|
+
// 资源列表
|
|
150
|
+
_blobs: { [key: string]: string } = {};
|
|
68
151
|
|
|
69
|
-
|
|
70
|
-
|
|
152
|
+
// fbx模型加载器
|
|
153
|
+
fbxLoader = new FBXLoader();
|
|
71
154
|
|
|
72
|
-
|
|
155
|
+
//obj 加载器
|
|
156
|
+
objLoader = new OBJLoader();
|
|
73
157
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
canvasTexture.anisotropy = this.anisotropy;
|
|
77
|
-
// canvasTexture.colorSpace = SRGBColorSpace;
|
|
158
|
+
// stl 加载器
|
|
159
|
+
stlLoader = new STLLoader();
|
|
78
160
|
|
|
79
|
-
|
|
80
|
-
|
|
161
|
+
// 材质加载器
|
|
162
|
+
mtlLoader = new MTLLoader();
|
|
81
163
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
164
|
+
// gltf 加载器
|
|
165
|
+
gltfLoader = (() => {
|
|
166
|
+
const loader = new GLTFLoader();
|
|
167
|
+
const dracoLoader = new (class ThreeBaseDRACOLoader extends DRACOLoader {
|
|
168
|
+
_loadLibrary(url: string, responseType: string) {
|
|
169
|
+
//@ts-ignore
|
|
170
|
+
let urlConf =
|
|
171
|
+
process.env.NODE_ENV === "development"
|
|
172
|
+
? {
|
|
173
|
+
"draco_decoder.js": "draco_decoder.js",
|
|
174
|
+
"draco_wasm_wrapper.js": "draco_wasm_wrapper.js",
|
|
175
|
+
"draco_decoder.wasm": "draco_decoder.wasm",
|
|
176
|
+
}
|
|
177
|
+
: {
|
|
178
|
+
"draco_decoder.js": dracoWasmWrapperJS,
|
|
179
|
+
"draco_wasm_wrapper.js": dracoDecoderJS,
|
|
180
|
+
"draco_decoder.wasm": dracoDecoderWASM,
|
|
181
|
+
};
|
|
182
|
+
//@ts-ignore
|
|
183
|
+
return super._loadLibrary(urlConf[url], responseType);
|
|
184
|
+
}
|
|
185
|
+
})();
|
|
186
|
+
//@ts-ignore
|
|
187
|
+
dracoLoader.setDecoderPath(
|
|
188
|
+
process.env.NODE_ENV === "development"
|
|
189
|
+
? "/node_modules/three/examples/jsm/libs/draco/"
|
|
190
|
+
: ""
|
|
191
|
+
);
|
|
192
|
+
loader.setDRACOLoader(dracoLoader);
|
|
193
|
+
return loader;
|
|
194
|
+
})();
|
|
195
|
+
|
|
196
|
+
//usdz加载器
|
|
197
|
+
usdzLoader = new USDZLoader();
|
|
198
|
+
|
|
199
|
+
//把贴图的 flipy 设置为 fasle
|
|
200
|
+
setFlipYIsFalse<T extends Material | Material[]>(material: T) {
|
|
201
|
+
if (material instanceof Array) {
|
|
202
|
+
material.map((m) => this.setFlipYIsFalse(m));
|
|
203
|
+
} else {
|
|
204
|
+
const m = material as MeshStandardMaterial;
|
|
205
|
+
const parame: Array<keyof MeshStandardMaterial> = [
|
|
206
|
+
"map",
|
|
207
|
+
"lightMap",
|
|
208
|
+
"aoMap",
|
|
209
|
+
"emissiveMap",
|
|
210
|
+
"bumpMap",
|
|
211
|
+
"normalMap",
|
|
212
|
+
"displacementMap",
|
|
213
|
+
"alphaMap",
|
|
214
|
+
"envMap",
|
|
215
|
+
];
|
|
216
|
+
parame.map((param) => {
|
|
217
|
+
const t = m[param] as Texture | undefined;
|
|
218
|
+
if (t) {
|
|
219
|
+
t.flipY = false;
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/** 加载模型支持glb,fbx,stl,obj */
|
|
226
|
+
async loadModel(url: string, filename: string = "") {
|
|
227
|
+
// 获取后缀
|
|
228
|
+
const suffix = threeUtils.getSuffix(filename || url);
|
|
229
|
+
|
|
230
|
+
switch (suffix) {
|
|
231
|
+
case "zip":
|
|
232
|
+
const JSZip = (await import("jszip")).default;
|
|
233
|
+
const arrayBuffer = await axios
|
|
234
|
+
.get(url, {
|
|
235
|
+
responseType: "arraybuffer",
|
|
236
|
+
})
|
|
237
|
+
.then((res) => res.data)
|
|
238
|
+
.catch((err) => {
|
|
239
|
+
throw new Error(`${url} 加载失败`);
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
return await JSZip.loadAsync(arrayBuffer).then(async (zip) => {
|
|
243
|
+
for (let filename in zip.files) {
|
|
244
|
+
if (!zip.files[filename].dir) {
|
|
245
|
+
// 不读文件夹
|
|
246
|
+
await zip
|
|
247
|
+
.file(filename)!
|
|
248
|
+
.async("blob")
|
|
249
|
+
.then((blob) => {
|
|
250
|
+
var blobURL = URL.createObjectURL(blob);
|
|
251
|
+
this._blobs[filename] = blobURL;
|
|
108
252
|
});
|
|
109
|
-
|
|
110
253
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
"draco_wasm_wrapper.js": "draco_wasm_wrapper.js",
|
|
144
|
-
"draco_decoder.wasm": "draco_decoder.wasm"
|
|
145
|
-
} : {
|
|
146
|
-
"draco_decoder.js": dracoWasmWrapperJS,
|
|
147
|
-
"draco_wasm_wrapper.js": dracoDecoderJS,
|
|
148
|
-
"draco_decoder.wasm": dracoDecoderWASM
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
let objLoader = new OBJLoader();
|
|
257
|
+
|
|
258
|
+
// 如果有mtl文件就加载mtl文件
|
|
259
|
+
let mtl = Object.keys(zip.files).find((filename) =>
|
|
260
|
+
/\.mtl$/.test(filename)
|
|
261
|
+
);
|
|
262
|
+
if (mtl) {
|
|
263
|
+
const materials = await this.mtlLoader.loadAsync(mtl);
|
|
264
|
+
objLoader.setMaterials(materials);
|
|
265
|
+
} else {
|
|
266
|
+
//@ts-ignore
|
|
267
|
+
objLoader.materials = null;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
//如果有obj就加载obj模型
|
|
271
|
+
let obj = Object.keys(zip.files).find((filename) =>
|
|
272
|
+
/\.obj$/.test(filename)
|
|
273
|
+
);
|
|
274
|
+
if (obj) {
|
|
275
|
+
const objObject3d = await objLoader.loadAsync(obj);
|
|
276
|
+
objObject3d.traverse((obj) => {
|
|
277
|
+
const mesh = obj as Mesh;
|
|
278
|
+
|
|
279
|
+
if (mesh.isMesh) {
|
|
280
|
+
// 如果obj没有材质就给默认的材质
|
|
281
|
+
if (!objLoader.materials) {
|
|
282
|
+
mesh.material = new MeshStandardMaterial({
|
|
283
|
+
metalness: 0.5,
|
|
284
|
+
roughness: 0.5,
|
|
285
|
+
});
|
|
149
286
|
}
|
|
150
|
-
//@ts-ignore
|
|
151
|
-
return super._loadLibrary(urlConf[url], responseType);
|
|
152
|
-
}
|
|
153
287
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
await
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
288
|
+
const uv = mesh.geometry.getAttribute("uv");
|
|
289
|
+
if (uv) {
|
|
290
|
+
for (let i = 0; i < uv.count; i++) {
|
|
291
|
+
uv.setY(i, 1 - uv.getY(i));
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
// obj只翻转uv不翻转贴图
|
|
295
|
+
this.setFlipYIsFalse(mesh.material);
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
return objObject3d;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
//如果有gltf文件就加载gltf文件
|
|
303
|
+
let gltf = Object.keys(zip.files).find((filename) =>
|
|
304
|
+
/\.(gltf|glb)$/.test(filename)
|
|
305
|
+
);
|
|
306
|
+
if (gltf) {
|
|
307
|
+
return await this.loadModel(gltf);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
//如果有dae文件就加载dae文件
|
|
311
|
+
let dae = Object.keys(zip.files).find((filename) =>
|
|
312
|
+
/\.dae$/.test(filename)
|
|
313
|
+
);
|
|
314
|
+
if (dae) {
|
|
315
|
+
return await this.loadModel(dae);
|
|
316
|
+
}
|
|
317
|
+
//如果有fbx文件就加载fbx文件
|
|
318
|
+
let fbx = Object.keys(zip.files).find((filename) =>
|
|
319
|
+
/\.fbx$/.test(filename)
|
|
320
|
+
);
|
|
321
|
+
if (fbx) {
|
|
322
|
+
return await this.loadModel(fbx);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
//如果有usdz文件就加载usdz文件
|
|
326
|
+
let usdz = Object.keys(zip.files).find((filename) =>
|
|
327
|
+
/\.usdz$/.test(filename)
|
|
328
|
+
);
|
|
329
|
+
if (usdz) {
|
|
330
|
+
return await this.loadModel(usdz);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
//如果有stl文件就加载stl文件
|
|
334
|
+
let stl = Object.keys(zip.files).find((filename) =>
|
|
335
|
+
/\.stl$/.test(filename)
|
|
336
|
+
);
|
|
337
|
+
if (stl) {
|
|
338
|
+
return await this.loadModel(stl);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
if ([obj, gltf, dae, fbx, usdz, stl].every((v) => !v)) {
|
|
342
|
+
throw new Error(
|
|
343
|
+
`${url}压缩包里没有obj.glb.gltf.dae.fbx.usde.stl等模型文件`
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
case "fbx":
|
|
349
|
+
return await threeLoader.fbxLoader
|
|
350
|
+
.loadAsync(url)
|
|
351
|
+
.then((res) => {
|
|
352
|
+
return res;
|
|
353
|
+
})
|
|
354
|
+
.catch(() => {
|
|
355
|
+
console.log(`${url},加载失败`);
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
case "gltf":
|
|
359
|
+
case "glb":
|
|
360
|
+
return await threeLoader.gltfLoader
|
|
361
|
+
.loadAsync(url)
|
|
362
|
+
.then((res) => {
|
|
363
|
+
res.scene.animations = res.animations;
|
|
364
|
+
return res.scene;
|
|
365
|
+
})
|
|
366
|
+
.catch(() => {
|
|
367
|
+
console.log(`${url},加载失败`);
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
case "stl":
|
|
371
|
+
return await threeLoader.stlLoader
|
|
372
|
+
.loadAsync(url)
|
|
373
|
+
.then((geometry) => {
|
|
374
|
+
return new Mesh(
|
|
375
|
+
geometry,
|
|
376
|
+
new MeshStandardMaterial({
|
|
377
|
+
metalness: 0.5,
|
|
378
|
+
roughness: 0.5,
|
|
379
|
+
})
|
|
380
|
+
);
|
|
381
|
+
})
|
|
382
|
+
.catch(() => {
|
|
383
|
+
console.log(`${url},加载失败`);
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
case "usdz":
|
|
387
|
+
return await threeLoader.usdzLoader
|
|
388
|
+
.loadAsync(url)
|
|
389
|
+
.then((res) => {
|
|
390
|
+
res.traverse((obj) => {
|
|
391
|
+
const mesh = obj as Mesh;
|
|
392
|
+
if (mesh.isMesh) {
|
|
393
|
+
(mesh.material as Material).transparent = true;
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
return res;
|
|
397
|
+
})
|
|
398
|
+
.catch((err) => {
|
|
399
|
+
console.log(`${url},加载失败`, err);
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
default:
|
|
403
|
+
if (suffix) {
|
|
404
|
+
console.log(`${suffix},不支持的格式`);
|
|
210
405
|
} else {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
console.error(`${url},不支持的格式,请尝试使用 suffix 参数来指定一下格式`);
|
|
215
|
-
}
|
|
406
|
+
console.log(
|
|
407
|
+
`${url},不支持的格式,请尝试使用 suffix 参数来指定一下格式`
|
|
408
|
+
);
|
|
216
409
|
}
|
|
217
|
-
|
|
218
|
-
return Object3d;
|
|
219
410
|
}
|
|
411
|
+
}
|
|
220
412
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
413
|
+
// 是否加载完成
|
|
414
|
+
onload = true;
|
|
224
415
|
}
|
|
225
416
|
|
|
226
417
|
const threeLoader = new ThreeLoader();
|
|
227
418
|
export default threeLoader;
|
|
228
|
-
|
package/threeUtils.d.ts
CHANGED
|
@@ -42,6 +42,8 @@ declare class ThreeUtils extends EventDispatcher {
|
|
|
42
42
|
getVolume(geometry: BufferGeometry): number;
|
|
43
43
|
signedVolumeOfTriangle(p1: Vector3, p2: Vector3, p3: Vector3): number;
|
|
44
44
|
dipose(object3d: Object3D): void;
|
|
45
|
+
getSuffix(filename: string): string;
|
|
46
|
+
getFilename(url: string): string;
|
|
45
47
|
}
|
|
46
48
|
declare const threeUtils: ThreeUtils;
|
|
47
49
|
export default threeUtils;
|