three-base 2.0.137 → 2.0.145
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/DirectionalLight.d.ts +2 -2
- package/DirectionalLight.js +1 -1
- package/DirectionalLight.ts +70 -0
- package/EventMap.d.ts +103 -0
- package/EventMap.js +17 -0
- package/EventMap.ts +139 -0
- package/EventMesh.ts +60 -0
- package/ExtrudeMesh.js +1 -25
- package/ExtrudeMesh.ts +553 -0
- package/FPScontrol.d.ts +448 -15
- package/FPScontrol.js +1448 -266
- package/FPScontrol.ts +1855 -0
- package/Fire/Fire.d.ts +4 -4
- package/Fire/Fire.js +8 -7
- package/Fire/Fire.ts +89 -0
- package/Fire/{FireGromtry.d.ts → FireGeometry.d.ts} +2 -2
- package/Fire/{FireGromtry.js → FireGeometry.js} +1 -1
- package/Fire/FireGeometry.ts +40 -0
- package/Fire/FireMaterial.d.ts +3 -3
- package/Fire/FireMaterial.js +1 -1
- package/Fire/FireMaterial.ts +89 -0
- package/Fire/index.d.ts +1 -0
- package/Fire/index.js +1 -0
- package/Fire/index.ts +2 -0
- package/GLTFDracoLoader.d.ts +71 -0
- package/GLTFDracoLoader.js +266 -0
- package/GLTFDracoLoader.ts +430 -0
- package/Grass/Grass.d.ts +2 -2
- package/Grass/Grass.ts +38 -0
- package/Grass/index.d.ts +1 -0
- package/Grass/index.js +1 -0
- package/Grass/index.ts +2 -0
- package/Ground1/Ground1.d.ts +2 -3
- package/Ground1/Ground1.js +64 -60
- package/Ground1/Ground1.ts +114 -0
- package/Ground1/index.ts +1 -0
- package/MeshBase.d.ts +1 -0
- package/MeshBase.js +37 -13
- package/MeshBase.ts +253 -0
- package/Mirror.d.ts +3 -3
- package/Mirror.js +7 -3
- package/Mirror.ts +203 -0
- package/MktMesh/MktMesh.d.ts +301 -0
- package/MktMesh/MktMesh.js +1064 -0
- package/MktMesh/MktMesh.ts +1096 -0
- package/MktMesh/assetUrl.d.ts +59 -0
- package/MktMesh/assetUrl.js +154 -0
- package/MktMesh/assetUrl.ts +155 -0
- package/MktMesh/mktMappingShader.d.ts +12 -0
- package/MktMesh/mktMappingShader.js +139 -0
- package/MktMesh/mktMappingShader.ts +139 -0
- package/MktMesh/mktShader.d.ts +263 -0
- package/MktMesh/mktShader.js +1248 -0
- package/MktMesh/mktShader.ts +1344 -0
- package/MktMesh/panoBitmapTexture.d.ts +25 -0
- package/MktMesh/panoBitmapTexture.js +52 -0
- package/MktMesh/panoBitmapTexture.ts +54 -0
- package/MktMesh/panoSlotBind.d.ts +29 -0
- package/MktMesh/panoSlotBind.js +106 -0
- package/MktMesh/panoSlotBind.ts +153 -0
- package/MktMesh/panoSlotRoster.d.ts +22 -0
- package/MktMesh/panoSlotRoster.js +169 -0
- package/MktMesh/panoSlotRoster.ts +168 -0
- package/MktMesh/panoTileStitcher.d.ts +119 -0
- package/MktMesh/panoTileStitcher.js +533 -0
- package/MktMesh/panoTileStitcher.ts +616 -0
- package/MktMesh/types.d.ts +75 -0
- package/MktMesh/types.js +1 -0
- package/MktMesh/types.ts +87 -0
- package/MktMesh/wallCapTessellate.d.ts +33 -0
- package/MktMesh/wallCapTessellate.js +97 -0
- package/MktMesh/wallCapTessellate.ts +68 -0
- package/PipeMesh/PathGeometry.js +9 -2
- package/PipeMesh/PathGeometry.ts +343 -0
- package/PipeMesh/PathPoint.ts +36 -0
- package/PipeMesh/PathPointList.js +1 -0
- package/PipeMesh/PathPointList.ts +227 -0
- package/PipeMesh/PathTubeGeometry.ts +146 -0
- package/PipeMesh/PipeMesh.d.ts +1 -1
- package/PipeMesh/PipeMesh.js +1 -1
- package/PipeMesh/PipeMesh.ts +76 -0
- package/PipeMesh/index.ts +1 -0
- package/PlaneModal1/PlaneModal1.d.ts +16 -13
- package/PlaneModal1/PlaneModal1.js +4 -0
- package/PlaneModal1/PlaneModal1.ts +138 -0
- package/PlaneModal1/index.ts +1 -0
- package/PlaneText.d.ts +2 -14
- package/PlaneText.js +7 -2
- package/PlaneText.ts +55 -0
- package/PlaneWithHtml.d.ts +4 -2
- package/PlaneWithHtml.js +2 -1
- package/PlaneWithHtml.ts +70 -0
- package/PointLight/PointLight.d.ts +3 -4
- package/PointLight/PointLight.js +1 -7
- package/PointLight/PointLight.ts +67 -0
- package/PointLight/index.ts +1 -0
- package/README.md +110 -79
- package/Sky/Sky.ts +22 -0
- package/Sky/index.ts +1 -0
- package/SpotLight.d.ts +2 -2
- package/SpotLight.js +1 -1
- package/SpotLight.ts +74 -0
- package/SpriteModal1/SpriteModal1.d.ts +16 -13
- package/SpriteModal1/SpriteModal1.js +8 -2
- package/SpriteModal1/SpriteModal1.ts +146 -0
- package/SpriteModal1/index.ts +1 -0
- package/SpriteText.d.ts +14 -13
- package/SpriteText.js +22 -9
- package/SpriteText.ts +205 -0
- package/SpriteText2.d.ts +9 -8
- package/SpriteText2.js +57 -32
- package/SpriteText2.ts +258 -0
- package/SpriteText3.d.ts +86 -0
- package/SpriteText3.js +519 -0
- package/SpriteText3.ts +599 -0
- package/SpriteWithHtml.d.ts +4 -2
- package/SpriteWithHtml.ts +50 -0
- package/Text3D/Text3D.js +17 -21
- package/Text3D/Text3D.ts +77 -0
- package/Text3D/fontController.d.ts +10 -9
- package/Text3D/fontController.js +17 -50
- package/Text3D/fontController.ts +209 -0
- package/Text3D/index.ts +1 -0
- package/ThreeBase.d.ts +168 -31
- package/ThreeBase.js +663 -117
- package/ThreeBase.ts +1314 -0
- package/ThreeMouse.d.ts +20 -7
- package/ThreeMouse.js +78 -32
- package/ThreeMouse.ts +472 -0
- package/Transition.d.ts +12 -7
- package/Transition.js +26 -27
- package/Transition.ts +242 -0
- package/Water/Water.js +21 -3
- package/Water/Water.ts +45 -0
- package/Water/index.d.ts +2 -0
- package/Water/index.js +2 -0
- package/Water/index.ts +2 -0
- package/WaterFlow/FloatingDuck.d.ts +88 -0
- package/WaterFlow/FloatingDuck.js +307 -0
- package/WaterFlow/FloatingDuck.ts +445 -0
- package/WaterFlow/GPUFluidSimulation.d.ts +56 -0
- package/WaterFlow/GPUFluidSimulation.js +785 -0
- package/WaterFlow/GPUFluidSimulation.ts +827 -0
- package/WaterFlow/ReservoirSystem.d.ts +106 -0
- package/WaterFlow/ReservoirSystem.js +621 -0
- package/WaterFlow/ReservoirSystem.ts +754 -0
- package/WaterFlow/SPHField.d.ts +35 -0
- package/WaterFlow/SPHField.js +204 -0
- package/WaterFlow/SPHField.ts +228 -0
- package/WaterFlow/ScreenSpaceFluidPass.d.ts +69 -0
- package/WaterFlow/ScreenSpaceFluidPass.js +736 -0
- package/WaterFlow/ScreenSpaceFluidPass.ts +789 -0
- package/WaterFlow/ShallowWaterSurface.d.ts +45 -0
- package/WaterFlow/ShallowWaterSurface.js +441 -0
- package/WaterFlow/ShallowWaterSurface.ts +510 -0
- package/WaterFlow/WaterFlow.d.ts +87 -0
- package/WaterFlow/WaterFlow.js +171 -0
- package/WaterFlow/WaterFlow.ts +219 -0
- package/WaterFlow/types.d.ts +161 -0
- package/WaterFlow/types.js +1 -0
- package/WaterFlow/types.ts +189 -0
- package/WaterFlow/waterFlowPass.d.ts +3 -0
- package/WaterFlow/waterFlowPass.js +20 -0
- package/WaterFlow/waterFlowPass.ts +40 -0
- package/collisionOBB.d.ts +42 -0
- package/collisionOBB.js +112 -0
- package/collisionOBB.ts +108 -0
- package/declare.d.ts +25 -167
- package/index.js +0 -1
- package/index.ts +1 -0
- package/instanced/InstancedBatch.d.ts +57 -0
- package/instanced/InstancedBatch.js +348 -0
- package/instanced/InstancedBatch.ts +406 -0
- package/instanced/InstancedChild.d.ts +174 -0
- package/instanced/InstancedChild.js +264 -0
- package/instanced/InstancedChild.ts +327 -0
- package/instanced/InstancedGroup.d.ts +43 -0
- package/instanced/InstancedGroup.js +126 -0
- package/instanced/InstancedGroup.ts +137 -0
- package/{InstancedMeshBase.d.ts → instanced/InstancedMeshBase.d.ts} +6 -7
- package/{InstancedMeshBase.js → instanced/InstancedMeshBase.js} +36 -47
- package/instanced/InstancedMeshBase.ts +292 -0
- package/instanced/InstancedTemplate.d.ts +46 -0
- package/instanced/InstancedTemplate.js +125 -0
- package/instanced/InstancedTemplate.ts +188 -0
- package/keyControls.d.ts +29 -0
- package/{keyContorls.js → keyControls.js} +10 -7
- package/keyControls.ts +107 -0
- package/lensflare/LensFlare.d.ts +39 -0
- package/lensflare/LensFlare.js +373 -0
- package/lensflare/LensFlare.ts +448 -0
- package/lensflare/lensflare0.png +0 -0
- package/lensflare/lensflare3.png +0 -0
- package/lensflare/lensflare_custom.png +0 -0
- package/lensflare/lensflare_hex_ghost.png +0 -0
- package/lensflare/lensflare_hex_main.png +0 -0
- package/package.json +104 -25
- package/pass/bloom_pass.d.ts +1 -1
- package/pass/bloom_pass.js +127 -40
- package/pass/bloom_pass.ts +243 -0
- package/pass/cover_pass.d.ts +1 -1
- package/pass/cover_pass.js +55 -32
- package/pass/cover_pass.ts +182 -0
- package/pass/debugDepthState.d.ts +20 -0
- package/pass/debugDepthState.js +9 -0
- package/pass/debugDepthState.ts +22 -0
- package/pass/depthTestBias.d.ts +12 -0
- package/pass/depthTestBias.js +12 -0
- package/pass/depthTestBias.ts +12 -0
- package/pass/effectUserData.d.ts +27 -0
- package/pass/effectUserData.js +1 -0
- package/pass/effectUserData.ts +46 -0
- package/pass/frosted_glass_pass.d.ts +1 -1
- package/pass/frosted_glass_pass.js +45 -64
- package/pass/frosted_glass_pass.ts +288 -0
- package/pass/fsQuad.d.ts +2 -2
- package/pass/fsQuad.ts +34 -0
- package/pass/glow_pass.d.ts +1 -1
- package/pass/glow_pass.js +288 -72
- package/pass/glow_pass.ts +654 -0
- package/pass/screen_bloom_pass.d.ts +11 -0
- package/pass/screen_bloom_pass.js +235 -0
- package/pass/screen_bloom_pass.ts +263 -0
- package/pass/ssao_pass.d.ts +78 -3
- package/pass/ssao_pass.js +642 -206
- package/pass/ssao_pass.ts +918 -0
- package/pass/stroke_pass.d.ts +1 -1
- package/pass/stroke_pass.js +187 -116
- package/pass/stroke_pass.ts +638 -0
- package/shaders/FXAAShaderMaterial.js +5 -48
- package/shaders/FXAAShaderMaterial.ts +201 -0
- package/shaders/baseDepthVisShader.d.ts +11 -0
- package/shaders/baseDepthVisShader.js +36 -0
- package/shaders/baseDepthVisShader.ts +36 -0
- package/shaders/baseTextureToRenderShader.js +46 -51
- package/shaders/baseTextureToRenderShader.ts +232 -0
- package/shaders/copyShader.js +2 -3
- package/shaders/copyShader.ts +32 -0
- package/shaders/debugDepthCompareShader.d.ts +14 -0
- package/shaders/debugDepthCompareShader.js +49 -0
- package/shaders/debugDepthCompareShader.ts +50 -0
- package/shaders/debugDepthJudgeShader.d.ts +18 -0
- package/shaders/debugDepthJudgeShader.js +52 -0
- package/shaders/debugDepthJudgeShader.ts +54 -0
- package/shaders/debugExcludedShader.d.ts +13 -0
- package/shaders/debugExcludedShader.js +46 -0
- package/shaders/debugExcludedShader.ts +48 -0
- package/spriteTextBg.d.ts +1 -0
- package/spriteTextBg.js +20 -0
- package/spriteTextBg.ts +20 -0
- package/threeLoader.d.ts +8 -7
- package/threeLoader.js +58 -67
- package/threeLoader.ts +525 -0
- package/threeUtils.d.ts +2 -1
- package/threeUtils.js +24 -25
- package/threeUtils.ts +373 -0
- package/types.d.ts +2 -0
- package/types.js +6 -0
- package/types.ts +8 -0
- package/ApngTexture.d.ts +0 -13
- package/ApngTexture.js +0 -61
- package/ApngTextureManage.d.ts +0 -18
- package/ApngTextureManage.js +0 -87
- package/KeyFrameAnimation.d.ts +0 -25
- package/KeyFrameAnimation.js +0 -78
- package/keyContorls.d.ts +0 -25
- package/lib/draco/draco_decoder.js +0 -34
- package/lib/draco/draco_decoder.wasm +0 -0
- package/lib/draco/draco_wasm_wrapper.js +0 -117
- package/pass/emissive_ao_pass.d.ts +0 -13
- package/pass/emissive_ao_pass.js +0 -370
- package/shaders.d.ts +0 -5
- package/shaders.js +0 -93
package/threeLoader.ts
ADDED
|
@@ -0,0 +1,525 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @Author: xiaosihan
|
|
3
|
+
* @Date: 2022-04-07 16:42:26
|
|
4
|
+
* @Last Modified by: xiaosihan
|
|
5
|
+
* @Last Modified time: 2025-01-15 20:34:19
|
|
6
|
+
*/
|
|
7
|
+
import { CanvasTexture, DefaultLoadingManager, EventDispatcher, LinearFilter, LinearMipmapLinearFilter, Mesh, MeshStandardMaterial, Object3D, RepeatWrapping, SRGBColorSpace, Texture, TextureLoader, VideoTexture, Material } from "three";
|
|
8
|
+
import { MathUtils } from "three";
|
|
9
|
+
const { generateUUID } = MathUtils;
|
|
10
|
+
import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader";
|
|
11
|
+
import GLTFDracoLoader from "./GLTFDracoLoader";
|
|
12
|
+
import { MTLLoader } from "three/examples/jsm/loaders/MTLLoader";
|
|
13
|
+
import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader";
|
|
14
|
+
import { STLLoader } from "three/examples/jsm/loaders/STLLoader";
|
|
15
|
+
import { USDZLoader } from "three/examples/jsm/loaders/USDZLoader";
|
|
16
|
+
// 引入静态资源
|
|
17
|
+
import axios, { type AxiosResponse } from "axios";
|
|
18
|
+
import JSZip from "jszip";
|
|
19
|
+
import { isArray, isEmpty, isNull, isString, isUndefined } from "lodash";
|
|
20
|
+
import { PLYLoader, TGALoader } from "three/examples/jsm/Addons";
|
|
21
|
+
import threeUtils from "./threeUtils";
|
|
22
|
+
import type { ThreeLoaderEventMap } from "./EventMap";
|
|
23
|
+
|
|
24
|
+
DefaultLoadingManager.addHandler(/tga$/, new TGALoader());
|
|
25
|
+
|
|
26
|
+
// 加载器
|
|
27
|
+
class ThreeLoader extends EventDispatcher<ThreeLoaderEventMap> {
|
|
28
|
+
constructor() {
|
|
29
|
+
super();
|
|
30
|
+
DefaultLoadingManager.onStart = () => {
|
|
31
|
+
this.onload = false;
|
|
32
|
+
};
|
|
33
|
+
// 资源加载进度
|
|
34
|
+
DefaultLoadingManager.onProgress = (url: string, loaded: number, total: number) => {
|
|
35
|
+
if (loaded < total) {
|
|
36
|
+
this.dispatchEvent({ type: "loadding" });
|
|
37
|
+
}
|
|
38
|
+
else if (loaded === total) {
|
|
39
|
+
this.dispatchEvent({ type: "onLoad" });
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
DefaultLoadingManager.onLoad = () => {
|
|
43
|
+
this.onload = true;
|
|
44
|
+
};
|
|
45
|
+
// 资源替换
|
|
46
|
+
DefaultLoadingManager.setURLModifier((url: string) => {
|
|
47
|
+
//全路径匹配资源
|
|
48
|
+
if (this._blobs[url]) {
|
|
49
|
+
return this._blobs[url];
|
|
50
|
+
}
|
|
51
|
+
const filename = url
|
|
52
|
+
.replace(`blob:${location.origin}/`, "")
|
|
53
|
+
.replace(/^\.\//, "");
|
|
54
|
+
let new_url = this._blobs[filename] || url;
|
|
55
|
+
//如果全匹配没有匹配到资源,就尝试文件名匹配
|
|
56
|
+
if (!this._blobs[filename]) {
|
|
57
|
+
const blobKey = Object.keys(this._blobs).find((key) => this.getFilename(key) === this.getFilename(filename)) || "";
|
|
58
|
+
new_url = this._blobs[blobKey] || url;
|
|
59
|
+
}
|
|
60
|
+
return new_url;
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
// 从url 中提取文件名
|
|
64
|
+
getFilename(url: string): string {
|
|
65
|
+
// 移除URL的查询字符串和哈希部分
|
|
66
|
+
const path = url.split("?")[0].split("#")[0];
|
|
67
|
+
// 使用lastIndexOf和substring从路径中提取文件名
|
|
68
|
+
const filename = path.substring(path.lastIndexOf("/") + 1);
|
|
69
|
+
return filename;
|
|
70
|
+
}
|
|
71
|
+
uuid: string = generateUUID();
|
|
72
|
+
// 各向异性
|
|
73
|
+
anisotropy: number = 16;
|
|
74
|
+
// 设置各向异性 由渲染器来调用并设置
|
|
75
|
+
setAnisotropy(v: number): void {
|
|
76
|
+
this.anisotropy = v;
|
|
77
|
+
}
|
|
78
|
+
// 纹理对向缓存
|
|
79
|
+
textureMap: Map<string, Texture> = new Map();
|
|
80
|
+
// 纹理加载器
|
|
81
|
+
textureLoader: TextureLoader = new TextureLoader();
|
|
82
|
+
// 获取地址对应的单例纹理对象
|
|
83
|
+
getTexture(src: string | HTMLCanvasElement): Texture {
|
|
84
|
+
if (src instanceof HTMLCanvasElement) {
|
|
85
|
+
const canvasTexture = new CanvasTexture(src);
|
|
86
|
+
canvasTexture.wrapS = canvasTexture.wrapT = RepeatWrapping;
|
|
87
|
+
canvasTexture.anisotropy = this.anisotropy;
|
|
88
|
+
canvasTexture.colorSpace = SRGBColorSpace;
|
|
89
|
+
// 三线性 + 各向异性:贴图缩小时自动选 mip 层级,根治地面/路面等高频重复贴图的摩尔纹(零运行时成本)
|
|
90
|
+
canvasTexture.generateMipmaps = true;
|
|
91
|
+
canvasTexture.minFilter = LinearMipmapLinearFilter;
|
|
92
|
+
canvasTexture.magFilter = LinearFilter;
|
|
93
|
+
return canvasTexture;
|
|
94
|
+
}
|
|
95
|
+
let texture = this.textureMap.get(src);
|
|
96
|
+
if (!texture) {
|
|
97
|
+
if (/\.(mp4|mov)$/i.test(src)) {
|
|
98
|
+
const videoDom = document.createElement("video");
|
|
99
|
+
videoDom.autoplay = true;
|
|
100
|
+
videoDom.loop = true;
|
|
101
|
+
videoDom.muted = true;
|
|
102
|
+
videoDom.preload = "auto";
|
|
103
|
+
videoDom.playsInline = true;
|
|
104
|
+
videoDom.src = src;
|
|
105
|
+
videoDom.crossOrigin = "anonymous";
|
|
106
|
+
videoDom.play();
|
|
107
|
+
const firstOptoin = () => {
|
|
108
|
+
videoDom.pause();
|
|
109
|
+
videoDom.play();
|
|
110
|
+
document.removeEventListener("pointerup", firstOptoin);
|
|
111
|
+
document.removeEventListener("touchstart", firstOptoin);
|
|
112
|
+
};
|
|
113
|
+
document.addEventListener("pointerup", firstOptoin);
|
|
114
|
+
document.addEventListener("touchstart", firstOptoin);
|
|
115
|
+
texture = new VideoTexture(videoDom);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
texture = this.textureLoader.load(src, (tex) => {
|
|
119
|
+
tex.image.crossOrigin = "anonymous";
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
this.textureMap.set(src, texture);
|
|
123
|
+
}
|
|
124
|
+
texture.wrapS = texture.wrapT = RepeatWrapping;
|
|
125
|
+
texture.anisotropy = this.anisotropy;
|
|
126
|
+
texture.colorSpace = SRGBColorSpace;
|
|
127
|
+
// 三线性 + 各向异性:贴图缩小时自动选 mip 层级并沿视角方向保留细节,
|
|
128
|
+
// 根治地面 / 路面 / UV 等高频重复贴图缩小时的摩尔纹(GPU 原生能力,运行时几乎零成本)。
|
|
129
|
+
// 这是摩尔纹的"正确"解法,比 SSAA 暴力全屏超采样省几个数量级的填充量。
|
|
130
|
+
texture.generateMipmaps = true;
|
|
131
|
+
texture.minFilter = LinearMipmapLinearFilter;
|
|
132
|
+
texture.magFilter = LinearFilter;
|
|
133
|
+
return texture;
|
|
134
|
+
}
|
|
135
|
+
// 资源列表
|
|
136
|
+
_blobs: {
|
|
137
|
+
[key: string]: string;
|
|
138
|
+
} = {};
|
|
139
|
+
// fbx模型加载器
|
|
140
|
+
fbxLoader: FBXLoader = new FBXLoader();
|
|
141
|
+
//obj 加载器
|
|
142
|
+
objLoader: OBJLoader = new OBJLoader();
|
|
143
|
+
// stl 加载器
|
|
144
|
+
stlLoader: STLLoader = new STLLoader();
|
|
145
|
+
//ply加载器
|
|
146
|
+
plyLoader: PLYLoader = new PLYLoader();
|
|
147
|
+
// 材质加载器
|
|
148
|
+
mtlLoader: MTLLoader = new MTLLoader();
|
|
149
|
+
// gltf 加载器(内置 draco 解码器,无需外部 draco 依赖)
|
|
150
|
+
gltfLoader: GLTFDracoLoader = new GLTFDracoLoader();
|
|
151
|
+
//usdz加载器
|
|
152
|
+
usdzLoader: USDZLoader = new USDZLoader();
|
|
153
|
+
//把贴图的 flipy 设置为 fasle
|
|
154
|
+
setFlipYIsFalse<T extends Material | Material[]>(material: T): void {
|
|
155
|
+
if (material instanceof Array) {
|
|
156
|
+
material.map((m) => this.setFlipYIsFalse(m));
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
const m = material as Material;
|
|
160
|
+
const parame = [
|
|
161
|
+
"map",
|
|
162
|
+
"lightMap",
|
|
163
|
+
"aoMap",
|
|
164
|
+
"emissiveMap",
|
|
165
|
+
"bumpMap",
|
|
166
|
+
"normalMap",
|
|
167
|
+
"displacementMap",
|
|
168
|
+
"alphaMap",
|
|
169
|
+
"envMap",
|
|
170
|
+
] as const;
|
|
171
|
+
parame.map((param) => {
|
|
172
|
+
const t = m[param as keyof Material];
|
|
173
|
+
if (t && t instanceof Texture) {
|
|
174
|
+
t.flipY = false;
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/** 加载模型支持glb,gltf,fbx,stl,obj,usdz,dae,zip */
|
|
180
|
+
async loadModel(url: string | File | Array<File>, filename: string = ""): Promise<Object3D | undefined> {
|
|
181
|
+
if ((isString(url) || isArray(url)) &&
|
|
182
|
+
isEmpty(url) &&
|
|
183
|
+
isUndefined(url) &&
|
|
184
|
+
isNull(url)) {
|
|
185
|
+
throw new Error(`loadModel:无效的参数 url=${url}`);
|
|
186
|
+
}
|
|
187
|
+
// 本次需要销毁的bloburl,加载完成后就去销毁本次的文件
|
|
188
|
+
const revokeObjectfile: string[] = [];
|
|
189
|
+
// 获取模型文件的后缀
|
|
190
|
+
const suffix = await (async (): Promise<string> => {
|
|
191
|
+
if (isString(url)) {
|
|
192
|
+
return threeUtils.getSuffix(filename || url);
|
|
193
|
+
}
|
|
194
|
+
else if (url instanceof File) {
|
|
195
|
+
return threeUtils.getSuffix(filename || url.name);
|
|
196
|
+
}
|
|
197
|
+
else if (url instanceof Array) {
|
|
198
|
+
let suffix = "";
|
|
199
|
+
const suffixs = [
|
|
200
|
+
"zip",
|
|
201
|
+
"obj",
|
|
202
|
+
"glb",
|
|
203
|
+
"gltf",
|
|
204
|
+
"fbx",
|
|
205
|
+
"dae",
|
|
206
|
+
"stl",
|
|
207
|
+
"ply",
|
|
208
|
+
"usdz",
|
|
209
|
+
];
|
|
210
|
+
for (let file of url) {
|
|
211
|
+
suffix = threeUtils.getSuffix(file.name);
|
|
212
|
+
if (suffixs.includes(suffix)) {
|
|
213
|
+
break;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return threeUtils.getSuffix(filename || suffix);
|
|
217
|
+
}
|
|
218
|
+
return "";
|
|
219
|
+
})();
|
|
220
|
+
//获取模型文件的地址
|
|
221
|
+
const modelurl = await (async (): Promise<string> => {
|
|
222
|
+
if (isString(url)) {
|
|
223
|
+
// 如果是 / 开头的路径,补全为完整 URL(兼容 Vite base: "./" 的情况)
|
|
224
|
+
if (url.startsWith("/") && typeof location !== "undefined") {
|
|
225
|
+
return location.origin + url;
|
|
226
|
+
}
|
|
227
|
+
return url;
|
|
228
|
+
}
|
|
229
|
+
else if (url instanceof File) {
|
|
230
|
+
const bloburl = await threeUtils.fileToBloburl(url);
|
|
231
|
+
this._blobs[url.name] = bloburl;
|
|
232
|
+
revokeObjectfile.push(url.name);
|
|
233
|
+
return bloburl;
|
|
234
|
+
}
|
|
235
|
+
else if (url instanceof Array) {
|
|
236
|
+
let modelurl = "";
|
|
237
|
+
const suffixs = [
|
|
238
|
+
"zip",
|
|
239
|
+
"obj",
|
|
240
|
+
"glb",
|
|
241
|
+
"gltf",
|
|
242
|
+
"fbx",
|
|
243
|
+
"dae",
|
|
244
|
+
"stl",
|
|
245
|
+
"usdz",
|
|
246
|
+
];
|
|
247
|
+
for (let file of url) {
|
|
248
|
+
const bloburl = await threeUtils.fileToBloburl(file);
|
|
249
|
+
this._blobs[file.name] = bloburl;
|
|
250
|
+
revokeObjectfile.push(file.name);
|
|
251
|
+
if (suffixs.includes(threeUtils.getSuffix(file.name))) {
|
|
252
|
+
modelurl = file.name;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return modelurl;
|
|
256
|
+
}
|
|
257
|
+
return "";
|
|
258
|
+
})();
|
|
259
|
+
switch (suffix) {
|
|
260
|
+
case "zip":
|
|
261
|
+
const JSZip = (await import("jszip")).default;
|
|
262
|
+
let arrayBuffer: ArrayBuffer | File = isString(url)
|
|
263
|
+
? await axios
|
|
264
|
+
.get(url, {
|
|
265
|
+
responseType: "arraybuffer",
|
|
266
|
+
})
|
|
267
|
+
.then((res: AxiosResponse<ArrayBuffer>) => res.data)
|
|
268
|
+
: url instanceof File
|
|
269
|
+
? url
|
|
270
|
+
: url[0];
|
|
271
|
+
return await JSZip.loadAsync(arrayBuffer).then(async (zip: JSZip) => {
|
|
272
|
+
for (let filename in zip.files) {
|
|
273
|
+
if (!zip.files[filename].dir) {
|
|
274
|
+
// 不读文件夹
|
|
275
|
+
await zip
|
|
276
|
+
.file(filename)
|
|
277
|
+
.async("blob")
|
|
278
|
+
.then((blob: Blob) => {
|
|
279
|
+
var blobURL = URL.createObjectURL(blob);
|
|
280
|
+
this._blobs[filename] = blobURL;
|
|
281
|
+
revokeObjectfile.push(filename);
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
let objLoader = new OBJLoader();
|
|
286
|
+
// 如果有mtl文件就加载mtl文件
|
|
287
|
+
let mtl = Object.keys(zip.files).find((filename) => /\.mtl$/.test(filename));
|
|
288
|
+
if (mtl) {
|
|
289
|
+
const materials = await this.mtlLoader.loadAsync(mtl);
|
|
290
|
+
objLoader.setMaterials(materials);
|
|
291
|
+
}
|
|
292
|
+
//如果有obj就加载obj模型
|
|
293
|
+
let obj = Object.keys(zip.files).find((filename) => /\.obj$/.test(filename));
|
|
294
|
+
if (obj) {
|
|
295
|
+
const objObject3d = await objLoader.loadAsync(obj);
|
|
296
|
+
revokeObjectfile.map((filename) => {
|
|
297
|
+
URL.revokeObjectURL(this._blobs[filename]);
|
|
298
|
+
delete this._blobs[filename];
|
|
299
|
+
});
|
|
300
|
+
objObject3d.traverse((child: Object3D) => {
|
|
301
|
+
if (child instanceof Mesh) {
|
|
302
|
+
const mesh = child as Mesh;
|
|
303
|
+
// 如果obj没有材质就给默认的材质
|
|
304
|
+
if (!objLoader.materials) {
|
|
305
|
+
mesh.material = new MeshStandardMaterial({
|
|
306
|
+
metalness: 0.5,
|
|
307
|
+
roughness: 0.5,
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
const uv = mesh.geometry.getAttribute("uv");
|
|
311
|
+
if (uv) {
|
|
312
|
+
for (let i = 0; i < uv.count; i++) {
|
|
313
|
+
uv.setY(i, 1 - uv.getY(i));
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
// obj只翻转uv不翻转贴图
|
|
317
|
+
this.setFlipYIsFalse(mesh.material);
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
return objObject3d;
|
|
321
|
+
}
|
|
322
|
+
//如果有gltf文件就加载gltf文件
|
|
323
|
+
let gltf = Object.keys(zip.files).find((filename) => /\.(gltf|glb)$/.test(filename));
|
|
324
|
+
if (gltf) {
|
|
325
|
+
return await this.loadModel(gltf);
|
|
326
|
+
}
|
|
327
|
+
//如果有dae文件就加载dae文件
|
|
328
|
+
let dae = Object.keys(zip.files).find((filename) => /\.dae$/.test(filename));
|
|
329
|
+
if (dae) {
|
|
330
|
+
return await this.loadModel(dae);
|
|
331
|
+
}
|
|
332
|
+
//如果有fbx文件就加载fbx文件
|
|
333
|
+
let fbx = Object.keys(zip.files).find((filename) => /\.fbx$/.test(filename));
|
|
334
|
+
if (fbx) {
|
|
335
|
+
return await this.loadModel(fbx);
|
|
336
|
+
}
|
|
337
|
+
//如果有usdz文件就加载usdz文件
|
|
338
|
+
let usdz = Object.keys(zip.files).find((filename) => /\.usdz$/.test(filename));
|
|
339
|
+
if (usdz) {
|
|
340
|
+
return await this.loadModel(usdz);
|
|
341
|
+
}
|
|
342
|
+
//如果有stl文件就加载stl文件
|
|
343
|
+
let stl = Object.keys(zip.files).find((filename) => /\.stl$/.test(filename));
|
|
344
|
+
if (stl) {
|
|
345
|
+
return await this.loadModel(stl);
|
|
346
|
+
}
|
|
347
|
+
//如果有ply文件就加载ply文件
|
|
348
|
+
let ply = Object.keys(zip.files).find((filename) => /\.ply$/.test(filename));
|
|
349
|
+
if (ply) {
|
|
350
|
+
return await this.loadModel(ply);
|
|
351
|
+
}
|
|
352
|
+
//如果有zip文件就加载zip文件
|
|
353
|
+
let zipFile = Object.keys(zip.files).find((filename) => /\.zip$/.test(filename));
|
|
354
|
+
if (zipFile) {
|
|
355
|
+
return await this.loadModel(zipFile);
|
|
356
|
+
}
|
|
357
|
+
if ([obj, gltf, dae, fbx, usdz, stl, ply].every((v) => !v)) {
|
|
358
|
+
throw new Error(`${url}压缩包里没有obj.glb.gltf.dae.fbx.usde.stl,ply模型文件`);
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
case "fbx":
|
|
362
|
+
return await threeLoader.fbxLoader
|
|
363
|
+
.loadAsync(modelurl)
|
|
364
|
+
.then((res) => {
|
|
365
|
+
revokeObjectfile.map((filename) => {
|
|
366
|
+
URL.revokeObjectURL(this._blobs[filename]);
|
|
367
|
+
delete this._blobs[filename];
|
|
368
|
+
});
|
|
369
|
+
return res;
|
|
370
|
+
})
|
|
371
|
+
.catch(() => {
|
|
372
|
+
console.error(`${url},加载失败`);
|
|
373
|
+
return undefined;
|
|
374
|
+
});
|
|
375
|
+
case "gltf":
|
|
376
|
+
case "glb":
|
|
377
|
+
return await threeLoader.gltfLoader
|
|
378
|
+
.loadAsync(modelurl)
|
|
379
|
+
.then((res) => {
|
|
380
|
+
revokeObjectfile.map((filename) => {
|
|
381
|
+
URL.revokeObjectURL(this._blobs[filename]);
|
|
382
|
+
delete this._blobs[filename];
|
|
383
|
+
});
|
|
384
|
+
res.scene.animations = res.animations;
|
|
385
|
+
return res.scene;
|
|
386
|
+
})
|
|
387
|
+
.catch((err) => {
|
|
388
|
+
// 打印详细错误信息,方便调试
|
|
389
|
+
console.error(`${url},加载失败`, err);
|
|
390
|
+
return undefined;
|
|
391
|
+
});
|
|
392
|
+
case "stl":
|
|
393
|
+
return await threeLoader.stlLoader
|
|
394
|
+
.loadAsync(modelurl)
|
|
395
|
+
.then((geometry) => {
|
|
396
|
+
revokeObjectfile.map((filename) => {
|
|
397
|
+
URL.revokeObjectURL(this._blobs[filename]);
|
|
398
|
+
delete this._blobs[filename];
|
|
399
|
+
});
|
|
400
|
+
return new Mesh(geometry, new MeshStandardMaterial({
|
|
401
|
+
metalness: 0.5,
|
|
402
|
+
roughness: 0.5,
|
|
403
|
+
}));
|
|
404
|
+
})
|
|
405
|
+
.catch(() => {
|
|
406
|
+
console.error(`${url},加载失败`);
|
|
407
|
+
return undefined;
|
|
408
|
+
});
|
|
409
|
+
case "ply":
|
|
410
|
+
return await threeLoader.plyLoader
|
|
411
|
+
.loadAsync(modelurl)
|
|
412
|
+
.then(async (geometry) => {
|
|
413
|
+
revokeObjectfile.map((filename) => {
|
|
414
|
+
URL.revokeObjectURL(this._blobs[filename]);
|
|
415
|
+
delete this._blobs[filename];
|
|
416
|
+
});
|
|
417
|
+
// 没有法线就创建法线
|
|
418
|
+
if (!geometry.getAttribute("normal")) {
|
|
419
|
+
geometry.computeVertexNormals();
|
|
420
|
+
}
|
|
421
|
+
//是否需要绕x轴旋转
|
|
422
|
+
const plyNeedRotationX = await new Promise(async (resolve) => {
|
|
423
|
+
// 读取文件内容
|
|
424
|
+
const res = await axios.get(modelurl);
|
|
425
|
+
// if (res.match(/\b(Blender|binary_little_endian)\b/)) {
|
|
426
|
+
// resolve(true);
|
|
427
|
+
// } else {
|
|
428
|
+
// resolve(false);
|
|
429
|
+
// }
|
|
430
|
+
});
|
|
431
|
+
const plyMesh = new Mesh(geometry, new MeshStandardMaterial({
|
|
432
|
+
metalness: 0.5,
|
|
433
|
+
roughness: 0.5,
|
|
434
|
+
vertexColors: Boolean(geometry.getAttribute("color")),
|
|
435
|
+
}));
|
|
436
|
+
if (plyNeedRotationX) {
|
|
437
|
+
plyMesh.rotation.x = -Math.PI / 2;
|
|
438
|
+
}
|
|
439
|
+
return plyMesh;
|
|
440
|
+
})
|
|
441
|
+
.catch(() => {
|
|
442
|
+
console.error(`${url},加载失败`);
|
|
443
|
+
return undefined;
|
|
444
|
+
});
|
|
445
|
+
case "usdz":
|
|
446
|
+
return await threeLoader.usdzLoader
|
|
447
|
+
.loadAsync(modelurl)
|
|
448
|
+
.then((res) => {
|
|
449
|
+
revokeObjectfile.map((filename) => {
|
|
450
|
+
URL.revokeObjectURL(this._blobs[filename]);
|
|
451
|
+
delete this._blobs[filename];
|
|
452
|
+
});
|
|
453
|
+
res.traverse((child: Object3D) => {
|
|
454
|
+
if (child instanceof Mesh) {
|
|
455
|
+
const mesh = child as Mesh;
|
|
456
|
+
if (Array.isArray(mesh.material)) {
|
|
457
|
+
mesh.material.forEach((mat) => {
|
|
458
|
+
mat.transparent = true;
|
|
459
|
+
});
|
|
460
|
+
} else {
|
|
461
|
+
mesh.material.transparent = true;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
});
|
|
465
|
+
return res;
|
|
466
|
+
})
|
|
467
|
+
.catch((err) => {
|
|
468
|
+
console.error(`${url},加载失败`, err);
|
|
469
|
+
return undefined;
|
|
470
|
+
});
|
|
471
|
+
case "obj":
|
|
472
|
+
let objLoader = new OBJLoader();
|
|
473
|
+
// 如果有mtl文件就加载mtl文件
|
|
474
|
+
let mtl = revokeObjectfile.find((filename) => /\.mtl$/.test(filename));
|
|
475
|
+
if (mtl) {
|
|
476
|
+
const materials = await this.mtlLoader.loadAsync(mtl);
|
|
477
|
+
objLoader.setMaterials(materials);
|
|
478
|
+
}
|
|
479
|
+
const objObject3d = await objLoader.loadAsync(modelurl);
|
|
480
|
+
revokeObjectfile.map((filename) => {
|
|
481
|
+
URL.revokeObjectURL(this._blobs[filename]);
|
|
482
|
+
delete this._blobs[filename];
|
|
483
|
+
});
|
|
484
|
+
objObject3d.traverse((child: Object3D) => {
|
|
485
|
+
if (child instanceof Mesh) {
|
|
486
|
+
const mesh = child as Mesh;
|
|
487
|
+
// 如果obj没有材质就给默认的材质
|
|
488
|
+
if (!this.objLoader.materials) {
|
|
489
|
+
mesh.material = new MeshStandardMaterial({
|
|
490
|
+
metalness: 0.5,
|
|
491
|
+
roughness: 0.5,
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
const uv = mesh.geometry.getAttribute("uv");
|
|
495
|
+
if (uv) {
|
|
496
|
+
for (let i = 0; i < uv.count; i++) {
|
|
497
|
+
uv.setY(i, 1 - uv.getY(i));
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
// obj只翻转uv不翻转贴图
|
|
501
|
+
this.setFlipYIsFalse(mesh.material);
|
|
502
|
+
}
|
|
503
|
+
});
|
|
504
|
+
return objObject3d;
|
|
505
|
+
default:
|
|
506
|
+
revokeObjectfile.map((filename) => {
|
|
507
|
+
URL.revokeObjectURL(this._blobs[filename]);
|
|
508
|
+
delete this._blobs[filename];
|
|
509
|
+
});
|
|
510
|
+
if (suffix) {
|
|
511
|
+
console.warn(`${suffix},不支持的格式`);
|
|
512
|
+
}
|
|
513
|
+
else {
|
|
514
|
+
console.warn(`${url},不支持的格式,请尝试使用 suffix 参数来指定一下格式`);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
// 是否加载完成
|
|
519
|
+
onload: boolean = true;
|
|
520
|
+
}
|
|
521
|
+
const threeLoader = new ThreeLoader();
|
|
522
|
+
|
|
523
|
+
(window as unknown as Record<string, unknown>).threeLoader = threeLoader;
|
|
524
|
+
|
|
525
|
+
export default threeLoader;
|
package/threeUtils.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Box3, BufferGeometry, Clock, EventDispatcher, Material, Object3D, Vector3 } from "three";
|
|
2
|
-
|
|
2
|
+
import type { ThreeUtilsEventTypeMap } from "./EventMap";
|
|
3
|
+
declare class ThreeUtils extends EventDispatcher<ThreeUtilsEventTypeMap> {
|
|
3
4
|
constructor();
|
|
4
5
|
isProd: boolean;
|
|
5
6
|
isDev: boolean;
|
package/threeUtils.js
CHANGED
|
@@ -4,15 +4,17 @@
|
|
|
4
4
|
* @Last Modified by: xiaosihan
|
|
5
5
|
* @Last Modified time: 2023-05-03 00:36:18
|
|
6
6
|
*/
|
|
7
|
-
import { Box3, Clock, EventDispatcher, Material, MeshBasicMaterial, MeshLambertMaterial, Vector3 } from "three";
|
|
7
|
+
import { Box3, BufferGeometry, Clock, EventDispatcher, Material, Mesh, MeshBasicMaterial, MeshLambertMaterial, Object3D, Vector3 } from "three";
|
|
8
|
+
import { MathUtils } from "three";
|
|
9
|
+
const { generateUUID } = MathUtils;
|
|
8
10
|
import { GLTFExporter } from "three/examples/jsm/exporters/GLTFExporter";
|
|
9
11
|
class ThreeUtils extends EventDispatcher {
|
|
10
12
|
constructor() {
|
|
11
13
|
super();
|
|
12
14
|
this.requestAnimationFrame();
|
|
13
15
|
}
|
|
14
|
-
isProd = process.env
|
|
15
|
-
isDev = process.env
|
|
16
|
+
isProd = typeof process !== 'undefined' && process.env?.NODE_ENV === "production";
|
|
17
|
+
isDev = typeof process !== 'undefined' && process.env?.NODE_ENV === "development";
|
|
16
18
|
_timeTemp = performance.now();
|
|
17
19
|
_accumulate = 0; // 事件分发次数
|
|
18
20
|
_box3 = new Box3();
|
|
@@ -108,11 +110,11 @@ class ThreeUtils extends EventDispatcher {
|
|
|
108
110
|
}
|
|
109
111
|
// 获取中心点
|
|
110
112
|
getCenter(object3d) {
|
|
111
|
-
if (object3d
|
|
113
|
+
if (object3d instanceof Object3D) {
|
|
112
114
|
this._box3.setFromObject(object3d);
|
|
113
115
|
this._box3.getCenter(this._center);
|
|
114
116
|
}
|
|
115
|
-
else if (object3d
|
|
117
|
+
else if (object3d instanceof BufferGeometry) {
|
|
116
118
|
object3d.computeBoundingBox();
|
|
117
119
|
object3d.boundingBox.getCenter(this._center);
|
|
118
120
|
}
|
|
@@ -120,11 +122,11 @@ class ThreeUtils extends EventDispatcher {
|
|
|
120
122
|
}
|
|
121
123
|
// 获取模型大小
|
|
122
124
|
getSize(object3d) {
|
|
123
|
-
if (object3d
|
|
125
|
+
if (object3d instanceof Object3D) {
|
|
124
126
|
this._box3.setFromObject(object3d);
|
|
125
127
|
this._box3.getSize(this._size);
|
|
126
128
|
}
|
|
127
|
-
else if (object3d
|
|
129
|
+
else if (object3d instanceof BufferGeometry) {
|
|
128
130
|
object3d.computeBoundingBox();
|
|
129
131
|
object3d.boundingBox.getSize(this._size);
|
|
130
132
|
}
|
|
@@ -132,7 +134,7 @@ class ThreeUtils extends EventDispatcher {
|
|
|
132
134
|
}
|
|
133
135
|
// 模型对齐底面
|
|
134
136
|
alignBottom(object3d, y = 0) {
|
|
135
|
-
if (object3d
|
|
137
|
+
if (object3d instanceof Object3D) {
|
|
136
138
|
this._box3.setFromObject(object3d);
|
|
137
139
|
this._box3.getCenter(this._center);
|
|
138
140
|
this._box3.getSize(this._size);
|
|
@@ -140,20 +142,20 @@ class ThreeUtils extends EventDispatcher {
|
|
|
140
142
|
object3d.position.y += y;
|
|
141
143
|
object3d.updateMatrixWorld(true);
|
|
142
144
|
}
|
|
143
|
-
else if (object3d
|
|
145
|
+
else if (object3d instanceof BufferGeometry) {
|
|
144
146
|
object3d.computeBoundingBox();
|
|
145
147
|
object3d.translate(0, -object3d.boundingBox.min.y + y, 0);
|
|
146
148
|
}
|
|
147
149
|
}
|
|
148
150
|
// 居中对象
|
|
149
151
|
centerObject3D(object3d) {
|
|
150
|
-
if (object3d
|
|
152
|
+
if (object3d instanceof Object3D) {
|
|
151
153
|
this._box3.setFromObject(object3d);
|
|
152
154
|
this._box3.getCenter(this._center);
|
|
153
155
|
object3d.position.sub(this._center);
|
|
154
156
|
object3d.updateMatrixWorld(true);
|
|
155
157
|
}
|
|
156
|
-
else if (object3d
|
|
158
|
+
else if (object3d instanceof BufferGeometry) {
|
|
157
159
|
object3d.center();
|
|
158
160
|
}
|
|
159
161
|
}
|
|
@@ -181,7 +183,7 @@ class ThreeUtils extends EventDispatcher {
|
|
|
181
183
|
obj.position.set(0, 0, 0);
|
|
182
184
|
obj.rotation.set(0, 0, 0);
|
|
183
185
|
obj.scale.set(1, 1, 1);
|
|
184
|
-
if (obj
|
|
186
|
+
if (obj instanceof Mesh) {
|
|
185
187
|
obj.geometry.applyMatrix4(obj.matrixWorld);
|
|
186
188
|
}
|
|
187
189
|
});
|
|
@@ -210,9 +212,9 @@ class ThreeUtils extends EventDispatcher {
|
|
|
210
212
|
// 计算网格的体积
|
|
211
213
|
getVolume(geometry) {
|
|
212
214
|
if (!geometry.index)
|
|
213
|
-
return;
|
|
215
|
+
return 0;
|
|
214
216
|
if (!geometry.isBufferGeometry) {
|
|
215
|
-
console.
|
|
217
|
+
console.warn("'geometry' must be an indexed or non-indexed buffer geometry");
|
|
216
218
|
return 0;
|
|
217
219
|
}
|
|
218
220
|
const isIndexed = geometry.index !== null;
|
|
@@ -246,14 +248,13 @@ class ThreeUtils extends EventDispatcher {
|
|
|
246
248
|
//清理对象的网格和材质的缓存
|
|
247
249
|
dipose(object3d) {
|
|
248
250
|
object3d.traverse((obj) => {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
mesh.material.dispose();
|
|
251
|
+
if (obj instanceof Mesh) {
|
|
252
|
+
obj.geometry.dispose();
|
|
253
|
+
if (obj.material instanceof Material) {
|
|
254
|
+
obj.material.dispose();
|
|
254
255
|
}
|
|
255
|
-
else if (
|
|
256
|
-
|
|
256
|
+
else if (obj.material instanceof Array) {
|
|
257
|
+
obj.material.map((m) => {
|
|
257
258
|
m.dispose();
|
|
258
259
|
});
|
|
259
260
|
}
|
|
@@ -300,7 +301,6 @@ class ThreeUtils extends EventDispatcher {
|
|
|
300
301
|
if (!["type"].includes(i) &&
|
|
301
302
|
meshBasicMaterial.hasOwnProperty(i) &&
|
|
302
303
|
material.hasOwnProperty(i)) {
|
|
303
|
-
//@ts-ignore
|
|
304
304
|
meshBasicMaterial[i] = material[i];
|
|
305
305
|
}
|
|
306
306
|
}
|
|
@@ -308,10 +308,8 @@ class ThreeUtils extends EventDispatcher {
|
|
|
308
308
|
}
|
|
309
309
|
}
|
|
310
310
|
toMeshLambertMaterial(material) {
|
|
311
|
-
//@ts-ignore
|
|
312
311
|
if (material instanceof Array) {
|
|
313
|
-
|
|
314
|
-
return material.map((m) => toMeshLambertMaterial(m));
|
|
312
|
+
return material.map((m) => this.toMeshLambertMaterial(m));
|
|
315
313
|
}
|
|
316
314
|
else {
|
|
317
315
|
const meshLambertMaterial = new MeshLambertMaterial();
|
|
@@ -327,4 +325,5 @@ class ThreeUtils extends EventDispatcher {
|
|
|
327
325
|
}
|
|
328
326
|
}
|
|
329
327
|
const threeUtils = new ThreeUtils();
|
|
328
|
+
window.threeUtils = threeUtils;
|
|
330
329
|
export default threeUtils;
|