three-base 2.0.111 → 2.0.112
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/ThreeBase.d.ts +1 -12
- package/ThreeBase.js +17 -119
- package/package.json +1 -1
- package/threeLoader.d.ts +2 -0
- package/threeLoader.js +47 -3
package/ThreeBase.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AxesHelper,
|
|
1
|
+
import { AxesHelper, DepthTexture, EventDispatcher, GridHelper, Object3D, OrthographicCamera, PerspectiveCamera, Scene, Texture, Vector2, Vector3, WebGLRenderTarget, WebGLRenderer } from "three";
|
|
2
2
|
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
|
|
3
3
|
import ThreeMouse from "./ThreeMouse";
|
|
4
4
|
import Transition from "./Transition";
|
|
@@ -75,17 +75,6 @@ export default class ThreeBase extends EventDispatcher {
|
|
|
75
75
|
getThumbBase64(): string;
|
|
76
76
|
getThumbFile(): Promise<File>;
|
|
77
77
|
download(fileName?: string): Promise<void>;
|
|
78
|
-
private _preMesh;
|
|
79
|
-
private _preRT;
|
|
80
|
-
preloadTexture(src: string): Promise<void>;
|
|
81
|
-
preloadGeometry(geometry: BufferGeometry): Promise<void>;
|
|
82
|
-
clearRendererTargte(rendererTarget: WebGLRenderTarget | null): void;
|
|
83
|
-
copyTextureToRenderTarget(texture: Texture, rendererTarget: WebGLRenderTarget | null, alpha?: boolean, opactity?: number): void;
|
|
84
|
-
object3dToRendererTarget(obj: Object3D, rendererTarget: WebGLRenderTarget): void;
|
|
85
|
-
rendererTagetAddStroke(rendererTarget: WebGLRenderTarget, strockWidth: number, color: string, opacity: number): void;
|
|
86
|
-
renderObject3dStroke(obj: Object3D, strockWidth: number, color: string, opacity: number): void;
|
|
87
|
-
renderTargetgaussBlur(rendererTarget: WebGLRenderTarget, radius: number, opacity: number): void;
|
|
88
|
-
renderTargetAddGlow(renderTarget: WebGLRenderTarget, width: number, color: string): void;
|
|
89
78
|
renderRendererTarget(renderTarget: WebGLRenderTarget): void;
|
|
90
79
|
renderTexture(texture: Texture, alpha?: boolean): void;
|
|
91
80
|
}
|
package/ThreeBase.js
CHANGED
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
* @Last Modified time: 2024-09-23 21:20:32
|
|
6
6
|
*/
|
|
7
7
|
import { round } from "lodash";
|
|
8
|
-
import { AxesHelper, Box3, DepthFormat, DepthTexture, EventDispatcher, GridHelper, LinearFilter, MOUSE,
|
|
8
|
+
import { AxesHelper, Box3, DepthFormat, DepthTexture, EventDispatcher, GridHelper, LinearFilter, MOUSE, NoBlending, NormalBlending, OrthographicCamera, PerspectiveCamera, RGBAFormat, ReinhardToneMapping, SRGBColorSpace, Scene, TOUCH, UnsignedShortType, Vector2, Vector3, WebGLRenderTarget, WebGLRenderer, } from "three";
|
|
9
9
|
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
|
|
10
10
|
import { degToRad, generateUUID } from "three/src/math/MathUtils";
|
|
11
11
|
import ThreeMouse from "./ThreeMouse";
|
|
12
12
|
import Transition from "./Transition";
|
|
13
13
|
import glow_pass from "./pass/glow_pass";
|
|
14
14
|
import stroke_pass from "./pass/stroke_pass";
|
|
15
|
-
import { baseTextureToRenderShader,
|
|
15
|
+
import { baseTextureToRenderShader, copyShader, fullScreenMesh, } from "./shaders";
|
|
16
16
|
import threeLoader from "./threeLoader";
|
|
17
17
|
import threeUtils from "./threeUtils";
|
|
18
18
|
import cover_pass from "./pass/cover_pass";
|
|
@@ -434,9 +434,10 @@ export default class ThreeBase extends EventDispatcher {
|
|
|
434
434
|
this.stopRender();
|
|
435
435
|
return;
|
|
436
436
|
}
|
|
437
|
+
// 相机的朝向
|
|
438
|
+
const center = new Vector3(...this.controls.target.toArray().map((v) => round(v, 3)));
|
|
437
439
|
//透视相机和正交相机参数的时时转换
|
|
438
440
|
if (this.cameraType === "perspectiveCamera") {
|
|
439
|
-
const { center } = this.getLookAt();
|
|
440
441
|
const { fov } = this.perspectiveCamera;
|
|
441
442
|
const distaned = this.perspectiveCamera.position
|
|
442
443
|
.clone()
|
|
@@ -450,7 +451,6 @@ export default class ThreeBase extends EventDispatcher {
|
|
|
450
451
|
.add(center);
|
|
451
452
|
}
|
|
452
453
|
else if (this.cameraType === "orthographicCamera") {
|
|
453
|
-
const { center } = this.getLookAt();
|
|
454
454
|
const { fov } = this.perspectiveCamera;
|
|
455
455
|
const { zoom } = this.orthographicCamera;
|
|
456
456
|
const distaned = 1 / zoom / Math.tan(degToRad(fov) / 2);
|
|
@@ -499,7 +499,12 @@ export default class ThreeBase extends EventDispatcher {
|
|
|
499
499
|
renderBindThis = this.render.bind(this);
|
|
500
500
|
//获取渲染图blob对象
|
|
501
501
|
async getThumbBlob() {
|
|
502
|
-
this.
|
|
502
|
+
this.renderer.setRenderTarget(this.baseRenderTarget);
|
|
503
|
+
this.renderer.clear();
|
|
504
|
+
this.renderer.render(this.scene, this.getCamera());
|
|
505
|
+
this.renderer.setRenderTarget(null);
|
|
506
|
+
this.renderer.clear();
|
|
507
|
+
this.renderRendererTarget(this.baseRenderTarget);
|
|
503
508
|
const blob = await new Promise((resolve, reject) => {
|
|
504
509
|
this.renderer.domElement.toBlob((blob) => {
|
|
505
510
|
resolve(blob);
|
|
@@ -509,7 +514,12 @@ export default class ThreeBase extends EventDispatcher {
|
|
|
509
514
|
}
|
|
510
515
|
//获取渲染图base64
|
|
511
516
|
getThumbBase64() {
|
|
512
|
-
this.
|
|
517
|
+
this.renderer.setRenderTarget(this.baseRenderTarget);
|
|
518
|
+
this.renderer.clear();
|
|
519
|
+
this.renderer.render(this.scene, this.getCamera());
|
|
520
|
+
this.renderer.setRenderTarget(null);
|
|
521
|
+
this.renderer.clear();
|
|
522
|
+
this.renderRendererTarget(this.baseRenderTarget);
|
|
513
523
|
const base64 = this.renderer.domElement.toDataURL("image/png");
|
|
514
524
|
return base64;
|
|
515
525
|
}
|
|
@@ -521,7 +531,6 @@ export default class ThreeBase extends EventDispatcher {
|
|
|
521
531
|
}
|
|
522
532
|
// 下载渲染图
|
|
523
533
|
async download(fileName = "download") {
|
|
524
|
-
this.render();
|
|
525
534
|
const blob = await this.getThumbBlob();
|
|
526
535
|
let saveLink = document.createElement("a");
|
|
527
536
|
saveLink.download = `${fileName}.png`;
|
|
@@ -529,118 +538,7 @@ export default class ThreeBase extends EventDispatcher {
|
|
|
529
538
|
document.body.append(saveLink);
|
|
530
539
|
saveLink.click();
|
|
531
540
|
}
|
|
532
|
-
|
|
533
|
-
_preRT = new WebGLRenderTarget(128, 128, {
|
|
534
|
-
minFilter: LinearFilter,
|
|
535
|
-
magFilter: LinearFilter,
|
|
536
|
-
format: RGBAFormat,
|
|
537
|
-
});
|
|
538
|
-
//预加载纹理图片
|
|
539
|
-
async preloadTexture(src) {
|
|
540
|
-
const texture = threeLoader.getTexture(src);
|
|
541
|
-
while ((texture && !texture.image) ||
|
|
542
|
-
!texture.image.complete) {
|
|
543
|
-
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
544
|
-
}
|
|
545
|
-
// 添加到计划任务中去
|
|
546
|
-
threeUtils.addWork(() => {
|
|
547
|
-
const originRenderTarget = this.renderer.getRenderTarget();
|
|
548
|
-
this.renderer.setRenderTarget(this._preRT);
|
|
549
|
-
this._preMesh.material.map = texture;
|
|
550
|
-
this.renderer.render(this._preMesh, this.perspectiveCamera);
|
|
551
|
-
this.renderer.setRenderTarget(originRenderTarget);
|
|
552
|
-
});
|
|
553
|
-
}
|
|
554
|
-
//预加载网格
|
|
555
|
-
async preloadGeometry(geometry) {
|
|
556
|
-
// 添加到计划任务中去
|
|
557
|
-
threeUtils.addWork(() => {
|
|
558
|
-
const originRenderTarget = this.renderer.getRenderTarget();
|
|
559
|
-
this.renderer.setRenderTarget(this._preRT);
|
|
560
|
-
this._preMesh.geometry = geometry;
|
|
561
|
-
this.renderer.render(this._preMesh, this.perspectiveCamera);
|
|
562
|
-
this.renderer.setRenderTarget(originRenderTarget);
|
|
563
|
-
});
|
|
564
|
-
}
|
|
565
|
-
// 清理渲染目标
|
|
566
|
-
clearRendererTargte(rendererTarget) {
|
|
567
|
-
const originTarget = this.renderer.getRenderTarget();
|
|
568
|
-
this.renderer.setRenderTarget(rendererTarget);
|
|
569
|
-
fullScreenMesh.render(this.renderer, clearShader);
|
|
570
|
-
this.renderer.clearDepth();
|
|
571
|
-
this.renderer.setRenderTarget(originTarget);
|
|
572
|
-
}
|
|
573
|
-
// 拷贝纹理到渲染目标
|
|
574
|
-
copyTextureToRenderTarget(texture, rendererTarget, alpha = false, opactity = 1) {
|
|
575
|
-
const originTarget = this.renderer.getRenderTarget();
|
|
576
|
-
if (rendererTarget) {
|
|
577
|
-
this.renderer.getSize(this.tempVector2);
|
|
578
|
-
rendererTarget.setSize(this.tempVector2.x, this.tempVector2.y);
|
|
579
|
-
}
|
|
580
|
-
this.renderer.setRenderTarget(rendererTarget);
|
|
581
|
-
copyShader.uniforms.map.value = texture;
|
|
582
|
-
copyShader.uniforms.opacity.value = opactity;
|
|
583
|
-
copyShader.blending = alpha ? NoBlending : NormalBlending;
|
|
584
|
-
fullScreenMesh.render(this.renderer, copyShader);
|
|
585
|
-
this.renderer.setRenderTarget(originTarget);
|
|
586
|
-
}
|
|
587
|
-
// 把对象绘制到渲染目标中
|
|
588
|
-
object3dToRendererTarget(obj, rendererTarget) {
|
|
589
|
-
this.clearRendererTargte(rendererTarget);
|
|
590
|
-
const originTarget = this.renderer.getRenderTarget();
|
|
591
|
-
this.renderer.setRenderTarget(rendererTarget);
|
|
592
|
-
this.renderer.getSize(this.tempVector2);
|
|
593
|
-
rendererTarget.setSize(this.tempVector2.x, this.tempVector2.y);
|
|
594
|
-
this.renderer.render(obj, this.getCamera());
|
|
595
|
-
this.renderer.setRenderTarget(originTarget);
|
|
596
|
-
}
|
|
597
|
-
// 给渲染目标的内容加描边
|
|
598
|
-
rendererTagetAddStroke(rendererTarget, strockWidth, color, opacity) {
|
|
599
|
-
const originTarget = this.renderer.getRenderTarget();
|
|
600
|
-
this.clearRendererTargte(this.renderTarget2);
|
|
601
|
-
this.renderer.setRenderTarget(this.renderTarget2);
|
|
602
|
-
this.renderer.getSize(this.tempVector2);
|
|
603
|
-
this.renderTarget2.setSize(this.tempVector2.x, this.tempVector2.y);
|
|
604
|
-
strokeShader.uniforms.map.value = rendererTarget.texture;
|
|
605
|
-
strokeShader.uniforms.resolution.value.set(this.tempVector2.x, this.tempVector2.y);
|
|
606
|
-
strokeShader.uniforms.strokeWidth.value = strockWidth;
|
|
607
|
-
strokeShader.uniforms.strokeColor.value.set(color);
|
|
608
|
-
strokeShader.uniforms.opacity.value = opacity;
|
|
609
|
-
fullScreenMesh.render(this.renderer, strokeShader);
|
|
610
|
-
this.copyTextureToRenderTarget(this.renderTarget2.texture, rendererTarget, true);
|
|
611
|
-
this.renderer.setRenderTarget(originTarget);
|
|
612
|
-
}
|
|
613
|
-
// 渲染对象的描边
|
|
614
|
-
renderObject3dStroke(obj, strockWidth, color, opacity) {
|
|
615
|
-
this.object3dToRendererTarget(obj, this.renderTarget);
|
|
616
|
-
this.rendererTagetAddStroke(this.renderTarget, strockWidth, color, opacity);
|
|
617
|
-
this.copyTextureToRenderTarget(this.renderTarget.texture, null);
|
|
618
|
-
}
|
|
619
|
-
//给渲染目标加上高斯模糊计算
|
|
620
|
-
renderTargetgaussBlur(rendererTarget, radius, opacity) {
|
|
621
|
-
const originTarget = this.renderer.getRenderTarget();
|
|
622
|
-
this.clearRendererTargte(this.renderTarget2);
|
|
623
|
-
this.renderer.setRenderTarget(this.renderTarget2);
|
|
624
|
-
this.renderer.getSize(this.tempVector2);
|
|
625
|
-
this.renderTarget2.setSize(this.tempVector2.x, this.tempVector2.y);
|
|
626
|
-
gaussBlurShader.uniforms.map.value = rendererTarget.texture;
|
|
627
|
-
gaussBlurShader.uniforms.radius.value = radius;
|
|
628
|
-
gaussBlurShader.uniforms.opacity.value = opacity;
|
|
629
|
-
gaussBlurShader.uniforms.resolution.value.set(this.tempVector2.x, this.tempVector2.y);
|
|
630
|
-
fullScreenMesh.render(this.renderer, gaussBlurShader);
|
|
631
|
-
this.copyTextureToRenderTarget(this.renderTarget2.texture, rendererTarget, true);
|
|
632
|
-
this.renderer.setRenderTarget(originTarget);
|
|
633
|
-
}
|
|
634
|
-
// 渲染目标上的纹理添加辉光效果
|
|
635
|
-
renderTargetAddGlow(renderTarget, width, color) {
|
|
636
|
-
this.rendererTagetAddStroke(renderTarget, 1 * width, color, 0.3);
|
|
637
|
-
this.rendererTagetAddStroke(renderTarget, 2 * width, color, 0.2);
|
|
638
|
-
this.rendererTagetAddStroke(renderTarget, 3 * width, color, 0.05);
|
|
639
|
-
this.renderTargetgaussBlur(renderTarget, 1, 1);
|
|
640
|
-
this.renderTargetgaussBlur(renderTarget, 1, 1);
|
|
641
|
-
this.renderTargetgaussBlur(renderTarget, 1, 1);
|
|
642
|
-
}
|
|
643
|
-
// 需要做抗锯齿处理 渲染 渲染目标
|
|
541
|
+
//把渲染目标渲染到canvas上
|
|
644
542
|
renderRendererTarget(renderTarget) {
|
|
645
543
|
baseTextureToRenderShader.uniforms.map.value = renderTarget.texture;
|
|
646
544
|
baseTextureToRenderShader.uniforms.opacity.value = 1.0;
|
package/package.json
CHANGED
package/threeLoader.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { MTLLoader } from "three/examples/jsm/loaders/MTLLoader";
|
|
|
5
5
|
import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader";
|
|
6
6
|
import { STLLoader } from "three/examples/jsm/loaders/STLLoader";
|
|
7
7
|
import { USDZLoader } from "three/examples/jsm/loaders/USDZLoader";
|
|
8
|
+
import { PLYLoader } from "three/examples/jsm/Addons.js";
|
|
8
9
|
declare class ThreeLoader extends EventDispatcher {
|
|
9
10
|
constructor();
|
|
10
11
|
getFilename(url: string): string;
|
|
@@ -20,6 +21,7 @@ declare class ThreeLoader extends EventDispatcher {
|
|
|
20
21
|
fbxLoader: FBXLoader;
|
|
21
22
|
objLoader: OBJLoader;
|
|
22
23
|
stlLoader: STLLoader;
|
|
24
|
+
plyLoader: PLYLoader;
|
|
23
25
|
mtlLoader: MTLLoader;
|
|
24
26
|
gltfLoader: GLTFLoader;
|
|
25
27
|
usdzLoader: USDZLoader;
|
package/threeLoader.js
CHANGED
|
@@ -26,7 +26,7 @@ import { isArray, isEmpty, isNull, isString, isUndefined } from "lodash";
|
|
|
26
26
|
import { generateUUID } from "three/src/math/MathUtils";
|
|
27
27
|
import dracoDecoderWASM from "./lib/draco/draco_decoder.wasm?url";
|
|
28
28
|
import threeUtils from "./threeUtils";
|
|
29
|
-
import { TGALoader } from "three/examples/jsm/Addons.js";
|
|
29
|
+
import { PLYLoader, TGALoader } from "three/examples/jsm/Addons.js";
|
|
30
30
|
DefaultLoadingManager.addHandler(/tga$/, new TGALoader());
|
|
31
31
|
// 加载器
|
|
32
32
|
class ThreeLoader extends EventDispatcher {
|
|
@@ -135,6 +135,8 @@ class ThreeLoader extends EventDispatcher {
|
|
|
135
135
|
objLoader = new OBJLoader();
|
|
136
136
|
// stl 加载器
|
|
137
137
|
stlLoader = new STLLoader();
|
|
138
|
+
//ply加载器
|
|
139
|
+
plyLoader = new PLYLoader();
|
|
138
140
|
// 材质加载器
|
|
139
141
|
mtlLoader = new MTLLoader();
|
|
140
142
|
// gltf 加载器
|
|
@@ -221,6 +223,7 @@ class ThreeLoader extends EventDispatcher {
|
|
|
221
223
|
"fbx",
|
|
222
224
|
"dae",
|
|
223
225
|
"stl",
|
|
226
|
+
"ply",
|
|
224
227
|
"usdz",
|
|
225
228
|
];
|
|
226
229
|
for (let file of url) {
|
|
@@ -358,13 +361,18 @@ class ThreeLoader extends EventDispatcher {
|
|
|
358
361
|
if (stl) {
|
|
359
362
|
return await this.loadModel(stl);
|
|
360
363
|
}
|
|
364
|
+
//如果有ply文件就加载ply文件
|
|
365
|
+
let ply = Object.keys(zip.files).find((filename) => /\.ply$/.test(filename));
|
|
366
|
+
if (ply) {
|
|
367
|
+
return await this.loadModel(ply);
|
|
368
|
+
}
|
|
361
369
|
//如果有zip文件就加载zip文件
|
|
362
370
|
let zipFile = Object.keys(zip.files).find((filename) => /\.zip$/.test(filename));
|
|
363
371
|
if (zipFile) {
|
|
364
372
|
return await this.loadModel(zipFile);
|
|
365
373
|
}
|
|
366
|
-
if ([obj, gltf, dae, fbx, usdz, stl].every((v) => !v)) {
|
|
367
|
-
throw new Error(`${url}压缩包里没有obj.glb.gltf.dae.fbx.usde.stl
|
|
374
|
+
if ([obj, gltf, dae, fbx, usdz, stl, ply].every((v) => !v)) {
|
|
375
|
+
throw new Error(`${url}压缩包里没有obj.glb.gltf.dae.fbx.usde.stl,ply模型文件`);
|
|
368
376
|
}
|
|
369
377
|
});
|
|
370
378
|
case "fbx":
|
|
@@ -411,6 +419,42 @@ class ThreeLoader extends EventDispatcher {
|
|
|
411
419
|
.catch(() => {
|
|
412
420
|
console.log(`${url},加载失败`);
|
|
413
421
|
});
|
|
422
|
+
case "ply":
|
|
423
|
+
return await threeLoader.plyLoader
|
|
424
|
+
.loadAsync(modelurl)
|
|
425
|
+
.then(async (geometry) => {
|
|
426
|
+
revokeObjectfile.map((filename) => {
|
|
427
|
+
URL.revokeObjectURL(this._blobs[filename]);
|
|
428
|
+
delete this._blobs[filename];
|
|
429
|
+
});
|
|
430
|
+
// 没有法线就创建法线
|
|
431
|
+
if (!geometry.getAttribute("normal")) {
|
|
432
|
+
geometry.computeVertexNormals();
|
|
433
|
+
}
|
|
434
|
+
//是否需要绕x轴旋转
|
|
435
|
+
const plyNeedRotationX = await new Promise(async (resolve) => {
|
|
436
|
+
// 读取文件内容
|
|
437
|
+
const res = await axios.get(modelurl);
|
|
438
|
+
debugger;
|
|
439
|
+
// if (res.match(/\b(Blender|binary_little_endian)\b/)) {
|
|
440
|
+
// resolve(true);
|
|
441
|
+
// } else {
|
|
442
|
+
// resolve(false);
|
|
443
|
+
// }
|
|
444
|
+
});
|
|
445
|
+
const plyMesh = new Mesh(geometry, new MeshStandardMaterial({
|
|
446
|
+
metalness: 0.5,
|
|
447
|
+
roughness: 0.5,
|
|
448
|
+
vertexColors: Boolean(geometry.getAttribute("color")),
|
|
449
|
+
}));
|
|
450
|
+
if (plyNeedRotationX) {
|
|
451
|
+
plyMesh.rotation.x = -Math.PI / 2;
|
|
452
|
+
}
|
|
453
|
+
return plyMesh;
|
|
454
|
+
})
|
|
455
|
+
.catch(() => {
|
|
456
|
+
console.log(`${url},加载失败`);
|
|
457
|
+
});
|
|
414
458
|
case "usdz":
|
|
415
459
|
return await threeLoader.usdzLoader
|
|
416
460
|
.loadAsync(modelurl)
|