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 CHANGED
@@ -1,4 +1,4 @@
1
- import { AxesHelper, BufferGeometry, DepthTexture, EventDispatcher, GridHelper, Object3D, OrthographicCamera, PerspectiveCamera, Scene, Texture, Vector2, Vector3, WebGLRenderTarget, WebGLRenderer } from "three";
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, Mesh, NoBlending, NormalBlending, OrthographicCamera, PerspectiveCamera, RGBAFormat, ReinhardToneMapping, SRGBColorSpace, Scene, TOUCH, UnsignedShortType, Vector2, Vector3, WebGLRenderTarget, WebGLRenderer, } from "three";
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, clearShader, copyShader, fullScreenMesh, gaussBlurShader, strokeShader, } from "./shaders";
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.render();
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.render();
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
- _preMesh = new Mesh();
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "three-base",
3
- "version": "2.0.111",
3
+ "version": "2.0.112",
4
4
  "description": "three 3d three-base",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
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)