lythreeframe 1.2.50 → 1.2.52

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.
@@ -1,7 +1,6 @@
1
- import { MathUtils, Object3D, Vector3, Box3, Quaternion, Euler, Matrix4, Mesh, LoadingManager, BufferGeometry, Texture, FileLoader, Material, NearestFilter, WebGPURenderer, Vector2, Raycaster, OrthographicCamera, PerspectiveCamera, Clock, DirectionalLight, MeshStandardMaterial, BoxGeometry, MeshBasicMaterial, PlaneGeometry, SphereGeometry } from 'three/webgpu';
1
+ import { MathUtils, Object3D, Vector3, Box3, Quaternion, Euler, Matrix4, Mesh, LoadingManager, BufferGeometry, Texture, FileLoader, Material, NearestFilter, WebGPURenderer, PostProcessing, Color, Vector2, Raycaster, OrthographicCamera, PerspectiveCamera, Clock, DirectionalLight, AmbientLight, MeshStandardMaterial, BoxGeometry, MeshBasicMaterial, PlaneGeometry, SphereGeometry } from 'three/webgpu';
2
2
  import { GLTFLoader, DRACOLoader, CSS2DRenderer, OrbitControls } from 'three/examples/jsm/Addons.js';
3
- import { pass, mrt, output, uniform, metalness, transformedNormalView } from 'three/tsl';
4
- import { WebGLRenderer, PCFSoftShadowMap, Scene, AmbientLight, CatmullRomCurve3, Color, LineBasicMaterial, BufferGeometry as BufferGeometry$1, Line, Float32BufferAttribute } from 'three';
3
+ import { pass, mrt, output, uniform, metalness, transformedNormalView, time, oscSine } from 'three/tsl';
5
4
  import { dof } from 'three/addons/tsl/display/DepthOfFieldNode.js';
6
5
  import { bloom } from 'three/examples/jsm/tsl/display/BloomNode.js';
7
6
  import { denoise } from 'three/examples/jsm/tsl/display/DenoiseNode.js';
@@ -10,6 +9,7 @@ import { ao } from 'three/examples/jsm/tsl/display/GTAONode.js';
10
9
  import { outline } from 'three/examples/jsm/tsl/display/OutlineNode.js';
11
10
  import { smaa } from 'three/examples/jsm/tsl/display/SMAANode.js';
12
11
  import { gsap } from 'gsap';
12
+ import { Scene } from 'three';
13
13
  import { SkyMesh } from 'three/examples/jsm/objects/SkyMesh.js';
14
14
  import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer.js';
15
15
  import { PointerLockControls } from 'three/examples/jsm/controls/PointerLockControls.js';
@@ -928,16 +928,16 @@ class TAssetPointer extends TSmartPointer {
928
928
  value.userData["assetPointer"] = this;
929
929
  }
930
930
  release() {
931
- if (this.value) {
932
- this.referenceCount--;
933
- if (this.referenceCount === 0) {
934
- setTimeout(() => {
935
- this.value.dispose();
936
- this.value = null;
937
- }, 0);
938
- }
939
- }
940
- console.log("realease", this);
931
+ // if (this.value) {
932
+ // this.referenceCount--;
933
+ // if (this.referenceCount === 0) {
934
+ // setTimeout(() => {
935
+ // this.value!.dispose();
936
+ // this.value = null;
937
+ // }, 0);
938
+ // }
939
+ // }
940
+ // console.log("realease", this)
941
941
  }
942
942
  forceRelease() {
943
943
  console.log("forceRelease", this);
@@ -1043,63 +1043,58 @@ class AssetManager {
1043
1043
  }
1044
1044
  }
1045
1045
  convertThreeObjectToLYObject(parentLYComponent, threejsObject) {
1046
- let location = threejsObject.position.clone();
1047
- let rotation = threejsObject.rotation.clone();
1048
- let scale = threejsObject.scale.clone();
1046
+ const location = threejsObject.position.clone();
1047
+ const rotation = threejsObject.rotation.clone();
1048
+ const scale = threejsObject.scale.clone();
1049
1049
  let newComp = null;
1050
- let children = threejsObject.children;
1050
+ const children = threejsObject.children;
1051
1051
  threejsObject.children = [];
1052
1052
  if (threejsObject.type === "Group" || threejsObject.type === "Object3D") {
1053
- newComp = new SceneComponent(this.app, threejsObject);
1053
+ newComp = new SceneComponent(this.app, threejsObject.uuid);
1054
1054
  }
1055
1055
  else if (threejsObject.isMesh) {
1056
- let obj = threejsObject;
1056
+ const obj = threejsObject;
1057
1057
  newComp = new MeshComponent(this.app, obj.geometry, obj.material);
1058
- // assetManager.#collectMatAndGeoInMesh(threejsObject)
1059
1058
  threejsObject.layers.set(0);
1060
1059
  }
1061
1060
  else {
1062
- newComp = new SceneComponent(this.app, threejsObject);
1061
+ newComp = new SceneComponent(this.app, threejsObject.uuid);
1063
1062
  }
1064
1063
  if (newComp === null) {
1065
1064
  threejsObject.children = children;
1066
- //threejsObject.parent = parent
1067
- //console.log("Unprocess", threejsObject);
1068
1065
  return null;
1069
1066
  }
1070
1067
  parentLYComponent.addChildComponent(newComp);
1071
1068
  newComp.setPosition(location);
1072
1069
  newComp.setRotation(rotation);
1073
1070
  newComp.setScale(scale);
1074
- for (let i = 0; i < children.length; ++i) {
1075
- this.convertThreeObjectToLYObject(newComp, children[i]);
1071
+ for (const child of children) {
1072
+ this.convertThreeObjectToLYObject(newComp, child);
1076
1073
  }
1077
1074
  return newComp;
1078
1075
  }
1079
1076
  collectResourcesAndReferences(object) {
1080
- function countResource(map, resource) {
1081
- if (!map.has(resource)) {
1082
- map.set(resource, 1);
1083
- }
1084
- else {
1085
- map.set(resource, map.get(resource) + 1);
1086
- }
1087
- }
1077
+ const countResource = (map, resource) => {
1078
+ var _a;
1079
+ const currentCount = (_a = map.get(resource)) !== null && _a !== void 0 ? _a : 0;
1080
+ map.set(resource, currentCount + 1);
1081
+ };
1088
1082
  const resources = {
1089
1083
  geometries: new Map(),
1090
1084
  materials: new Map(),
1091
1085
  textures: new Map()
1092
1086
  };
1093
1087
  object.traverse((child) => {
1094
- if (child.geometry && child.geometry instanceof BufferGeometry) {
1095
- countResource(resources.geometries, child.geometry);
1088
+ const meshChild = child;
1089
+ if (meshChild.geometry instanceof BufferGeometry) {
1090
+ countResource(resources.geometries, meshChild.geometry);
1096
1091
  }
1097
- if (child.material) {
1098
- const mats = Array.isArray(child.material) ? child.material : [child.material];
1092
+ if (meshChild.material) {
1093
+ const mats = Array.isArray(meshChild.material) ? meshChild.material : [meshChild.material];
1099
1094
  mats.forEach((mat) => {
1100
1095
  if (mat) {
1101
1096
  countResource(resources.materials, mat);
1102
- Object.entries(mat).forEach(([key, value]) => {
1097
+ Object.values(mat).forEach((value) => {
1103
1098
  if (value instanceof Texture) {
1104
1099
  countResource(resources.textures, value);
1105
1100
  }
@@ -1108,49 +1103,36 @@ class AssetManager {
1108
1103
  });
1109
1104
  }
1110
1105
  });
1111
- function createPointer(manager, map) {
1112
- map.forEach((value, key) => {
1113
- manager.addAsset(key, value);
1114
- });
1115
- }
1116
- createPointer(this, resources.geometries);
1117
- createPointer(this, resources.materials);
1118
- createPointer(this, resources.textures);
1119
- // console.log('Geometries:', Array.from(resources.geometries.entries()));
1120
- // console.log('Materials:', Array.from(resources.materials.entries()));
1121
- // console.log('Textures:', Array.from(resources.textures.entries()));
1122
- // console.log('assetPointer:', this.assetPointer);
1106
+ resources.geometries.forEach((count, geometry) => this.addAsset(geometry, count));
1107
+ resources.materials.forEach((count, material) => this.addAsset(material, count));
1108
+ resources.textures.forEach((count, texture) => this.addAsset(texture, count));
1123
1109
  }
1124
1110
  checkMeshResource(mesh) {
1125
- if (mesh.geometry) {
1126
- if (!mesh.geometry.userData["assetPointer"]) {
1127
- this.addAsset(mesh.geometry);
1128
- }
1111
+ if (mesh.geometry && !mesh.geometry.userData["assetPointer"]) {
1112
+ this.addAsset(mesh.geometry);
1129
1113
  }
1130
1114
  if (mesh.material) {
1131
1115
  const mats = Array.isArray(mesh.material) ? mesh.material : [mesh.material];
1132
1116
  mats.forEach((material) => {
1133
- if (material) {
1134
- if (!material.userData["assetPointer"]) {
1135
- this.addAsset(material);
1136
- }
1137
- Object.entries(material).forEach(([key, value]) => {
1138
- if (value instanceof Texture) {
1139
- if (!(value.userData["assetPointer"])) {
1140
- this.addAsset(value);
1141
- }
1142
- }
1143
- });
1117
+ if (!material)
1118
+ return;
1119
+ if (!material.userData["assetPointer"]) {
1120
+ this.addAsset(material);
1144
1121
  }
1122
+ Object.values(material).forEach((value) => {
1123
+ if (value instanceof Texture && !value.userData["assetPointer"]) {
1124
+ this.addAsset(value);
1125
+ }
1126
+ });
1145
1127
  });
1146
1128
  }
1147
1129
  }
1148
1130
  async loadGltfFromPathAsync(path) {
1149
1131
  this.setupDracoLoader("/SceneResource/draco/");
1150
- let res = await this.gltfLoader.loadAsync(path);
1151
- return res;
1132
+ return await this.gltfLoader.loadAsync(path);
1152
1133
  }
1153
1134
  loadGltfFromPath(path, onLoadFinished) {
1135
+ this.setupDracoLoader("/SceneResource/draco/");
1154
1136
  this.gltfLoader.load(path, onLoadFinished);
1155
1137
  }
1156
1138
  loadGltfFromBuffer(data, path, onLoadFinished) {
@@ -1159,33 +1141,30 @@ class AssetManager {
1159
1141
  }
1160
1142
  loadFile(filepath = '', onLoadFinished) {
1161
1143
  const loader = new FileLoader();
1162
- loader.load(filepath, (data) => {
1163
- onLoadFinished(data);
1164
- });
1144
+ loader.load(filepath, onLoadFinished);
1165
1145
  }
1166
1146
  addAsset(asset, referenceCount = 0) {
1167
1147
  if (asset instanceof BufferGeometry) {
1168
1148
  return this.addGeometryAsset(asset, referenceCount);
1169
1149
  }
1170
- else if (asset instanceof Material) {
1150
+ if (asset instanceof Material) {
1171
1151
  return this.addMaterialAsset(asset, referenceCount);
1172
1152
  }
1173
- else if (asset instanceof Texture) {
1153
+ if (asset instanceof Texture) {
1174
1154
  return this.addTextureAsset(asset, referenceCount);
1175
1155
  }
1176
1156
  return undefined;
1177
1157
  }
1178
1158
  addMaterialAsset(asset, referenceCount = 0) {
1179
- let pointer = (asset.userData["assetPointer"]);
1159
+ let pointer = asset.userData["assetPointer"];
1180
1160
  if (!pointer) {
1181
- let textureMap = new Map();
1182
- for (let k in asset) {
1183
- const value = asset[k];
1161
+ const textureMap = new Map();
1162
+ Object.entries(asset).forEach(([key, value]) => {
1184
1163
  if (value instanceof Texture) {
1185
- let ptr = this.addTextureAsset(value, 1);
1186
- textureMap.set(k, ptr);
1164
+ const texturePointer = this.addTextureAsset(value, 1);
1165
+ textureMap.set(key, texturePointer);
1187
1166
  }
1188
- }
1167
+ });
1189
1168
  pointer = new MaterialAssetPointer(asset, textureMap, referenceCount);
1190
1169
  this.materialAssets.set(asset.uuid, pointer);
1191
1170
  }
@@ -1195,7 +1174,7 @@ class AssetManager {
1195
1174
  return pointer;
1196
1175
  }
1197
1176
  addTextureAsset(asset, referenceCount = 0) {
1198
- let pointer = (asset.userData["assetPointer"]);
1177
+ let pointer = asset.userData["assetPointer"];
1199
1178
  if (!pointer) {
1200
1179
  pointer = new TextureAssetPointer(asset, referenceCount);
1201
1180
  this.textureAssets.set(asset.uuid, pointer);
@@ -1206,7 +1185,7 @@ class AssetManager {
1206
1185
  return pointer;
1207
1186
  }
1208
1187
  addGeometryAsset(asset, referenceCount = 0) {
1209
- let pointer = (asset.userData["assetPointer"]);
1188
+ let pointer = asset.userData["assetPointer"];
1210
1189
  if (!pointer) {
1211
1190
  pointer = new GeometryAssetPointer(asset, referenceCount);
1212
1191
  this.geometryAssets.set(asset.uuid, pointer);
@@ -1217,34 +1196,21 @@ class AssetManager {
1217
1196
  return pointer;
1218
1197
  }
1219
1198
  releaseAsset(asset) {
1220
- // let uuid = asset.uuid
1221
- let p = asset.userData["assetPointer"];
1222
- if (p) {
1223
- p.release();
1199
+ const pointer = asset.userData["assetPointer"];
1200
+ if (pointer) {
1201
+ pointer.release();
1224
1202
  }
1225
1203
  else {
1226
1204
  asset.dispose();
1227
1205
  }
1228
1206
  }
1229
1207
  clearAssets() {
1230
- this.geometryAssets.forEach((p) => {
1231
- p.forceRelease();
1232
- });
1208
+ this.geometryAssets.forEach((pointer) => pointer.forceRelease());
1233
1209
  this.geometryAssets.clear();
1234
- this.materialAssets.forEach((p) => {
1235
- p.forceRelease();
1236
- });
1210
+ this.materialAssets.forEach((pointer) => pointer.forceRelease());
1237
1211
  this.materialAssets.clear();
1238
- this.textureAssets.forEach((p) => {
1239
- p.forceRelease();
1240
- });
1212
+ this.textureAssets.forEach((pointer) => pointer.forceRelease());
1241
1213
  this.textureAssets.clear();
1242
- // let pointers = Array.from(this.assetPointer.values());
1243
- // pointers.forEach((p) =>
1244
- // {
1245
- // p.forceRelease();
1246
- // });
1247
- // this.assetPointer.clear();
1248
1214
  }
1249
1215
  }
1250
1216
 
@@ -1519,12 +1485,7 @@ class Viewport {
1519
1485
  }
1520
1486
  get renderer() {
1521
1487
  if (!this._renderer) {
1522
- if (this._webGLRenderer) {
1523
- return this._webGLRenderer;
1524
- }
1525
- else {
1526
- throw Error("Renderer is not initialized");
1527
- }
1488
+ throw Error("Renderer is not initialized");
1528
1489
  }
1529
1490
  return this._renderer;
1530
1491
  }
@@ -1537,7 +1498,6 @@ class Viewport {
1537
1498
  constructor(app, viewportParam, rendererParam, postProcessParam) {
1538
1499
  this._uiDom = null;
1539
1500
  this._renderer = null;
1540
- this._webGLRenderer = null;
1541
1501
  this.labelRenderer = null;
1542
1502
  this._app = null;
1543
1503
  this.resizeObserver = null;
@@ -1551,7 +1511,6 @@ class Viewport {
1551
1511
  if (viewportParam.elementId) {
1552
1512
  this._outerContainer = document.getElementById(viewportParam.elementId);
1553
1513
  }
1554
- this.viewportParam = Object.assign({}, viewportParam);
1555
1514
  this.createRenderer(rendererParam);
1556
1515
  if (viewportParam.isLabelRendererNeeded) {
1557
1516
  this.createLabelRenderer();
@@ -1573,7 +1532,7 @@ class Viewport {
1573
1532
  this.setupPostProcess();
1574
1533
  });
1575
1534
  }
1576
- async createRenderer(rendererParam) {
1535
+ createRenderer(rendererParam) {
1577
1536
  if (this._outerContainer) {
1578
1537
  this._canvasContainer = document.createElement("div");
1579
1538
  this._canvasContainer.style.left = "0px";
@@ -1600,31 +1559,15 @@ class Viewport {
1600
1559
  renderP.logarithmicDepthBuffer = rendererParam.logarithmicDepthBuffer;
1601
1560
  renderP.samples = rendererParam.samples;
1602
1561
  renderP.colorBufferType = rendererParam.colorBufferType;
1603
- if (this.viewportParam.usingWebGLRenderer) {
1604
- this._webGLRenderer = new WebGLRenderer();
1605
- this._webGLRenderer.setPixelRatio(window.devicePixelRatio);
1606
- this._webGLRenderer.setSize(width, height);
1607
- this._webGLRenderer.shadowMap.enabled = rendererParam.shadowMapEnabled;
1608
- this._webGLRenderer.shadowMap.type = rendererParam.shadowMapType ? rendererParam.shadowMapType : PCFSoftShadowMap;
1609
- this._webGLRenderer.toneMapping = rendererParam.toneMapping;
1610
- this._webGLRenderer.toneMappingExposure = rendererParam.toneMappingExposure;
1611
- if (element) {
1612
- element.appendChild(this._webGLRenderer.domElement);
1613
- }
1614
- }
1615
- else {
1616
- this._renderer = new WebGPURenderer(renderP);
1617
- // WebGPU 需要异步初始化
1618
- await this._renderer.init();
1619
- this._renderer.setPixelRatio(window.devicePixelRatio);
1620
- this._renderer.setSize(width, height);
1621
- this._renderer.shadowMap.enabled = rendererParam.shadowMapEnabled;
1622
- this._renderer.shadowMap.type = rendererParam.shadowMapType;
1623
- this._renderer.toneMapping = rendererParam.toneMapping;
1624
- this._renderer.toneMappingExposure = rendererParam.toneMappingExposure;
1625
- if (element) {
1626
- element.appendChild(this._renderer.domElement);
1627
- }
1562
+ this._renderer = new WebGPURenderer(renderP);
1563
+ this._renderer.setPixelRatio(window.devicePixelRatio);
1564
+ this._renderer.setSize(width, height);
1565
+ this._renderer.shadowMap.enabled = rendererParam.shadowMapEnabled;
1566
+ this._renderer.shadowMap.type = rendererParam.shadowMapType;
1567
+ this._renderer.toneMapping = rendererParam.toneMapping;
1568
+ this._renderer.toneMappingExposure = rendererParam.toneMappingExposure;
1569
+ if (element) {
1570
+ element.appendChild(this._renderer.domElement);
1628
1571
  }
1629
1572
  }
1630
1573
  createLabelRenderer() {
@@ -1671,7 +1614,97 @@ class Viewport {
1671
1614
  this.setupPostProcess();
1672
1615
  }
1673
1616
  setupPostProcess() {
1674
- return;
1617
+ if (this.postProcessParam.steps.length === 0) {
1618
+ this.destroyPostProcess();
1619
+ this.markRenderStateDirty();
1620
+ return;
1621
+ }
1622
+ if (!this.postProcessing) {
1623
+ this.postProcessing = new PostProcessing(this.renderer);
1624
+ }
1625
+ const scenePass = WebGPUPostProcessFactory.constructScenePass(this.app.world.scene, this.app.camera);
1626
+ let finalNode = scenePass.getTextureNode('output');
1627
+ this.postProcessParam.steps.forEach((step) => {
1628
+ switch (step.type) {
1629
+ case PostProcessStepType.Bloom:
1630
+ {
1631
+ const bloomPass = WebGPUPostProcessFactory.constructBloomPass(scenePass, step);
1632
+ //console.log("[PostProcess] BloomPass 构建完成");
1633
+ finalNode = finalNode.add(bloomPass);
1634
+ break;
1635
+ }
1636
+ case PostProcessStepType.DepthOfField:
1637
+ {
1638
+ const dofPass = WebGPUPostProcessFactory.constructDOFPass(scenePass, step);
1639
+ //console.log("[PostProcess] DOFPass 构建完成");
1640
+ finalNode = finalNode.add(dofPass);
1641
+ break;
1642
+ }
1643
+ case PostProcessStepType.ScreenSpaceReflection:
1644
+ {
1645
+ console.warn("[PostProcess] SSR 目前存在技术问题,暂不支持。");
1646
+ // const ssrPass = WebGPUPostProcessFactory.constructSSRPass(scenePass, step as SSRParam);
1647
+ // console.log("[PostProcess] SSRPass 构建完成");
1648
+ //finalNode = blendColor(finalNode, ssrPass);
1649
+ break;
1650
+ }
1651
+ case PostProcessStepType.GroundTruthAmbientOcclusion:
1652
+ {
1653
+ console.warn("[PostProcess] AO 目前存在技术问题,暂不支持。");
1654
+ // const stepParam = step as GTAOParam
1655
+ // const GTAOPass = WebGPUPostProcessFactory.constructGTAOPass(scenePass, stepParam);
1656
+ // console.log("[PostProcess] GTAOPass 构建完成");
1657
+ // if (stepParam.denoised)
1658
+ // {
1659
+ // const denoiseGTAOPass = WebGPUPostProcessFactory.constructGTAODenoisePass(scenePass, GTAOPass, stepParam);
1660
+ // console.log("[PostProcess] GTAODenoisePass 构建完成");
1661
+ // finalNode = denoiseGTAOPass.mul(finalNode);
1662
+ // }
1663
+ // else
1664
+ // {
1665
+ // finalNode = GTAOPass.getTextureNode().mul(finalNode);
1666
+ // }
1667
+ break;
1668
+ }
1669
+ case PostProcessStepType.Outline:
1670
+ {
1671
+ const outlineParam = step;
1672
+ const outlinePass = WebGPUPostProcessFactory.constructOutlinePass(this.app.world.scene, scenePass.camera, this.outlineObjects, outlineParam);
1673
+ const { visibleEdge, hiddenEdge } = outlinePass;
1674
+ const pulsePeriod = uniform(outlineParam.pulsePeriod);
1675
+ const period = time.div(pulsePeriod).mul(2);
1676
+ const osc = oscSine(period).mul(.5).add(.5);
1677
+ const outlineColor = visibleEdge.mul(uniform(new Color(outlineParam.visibleEdgeColor))).add(hiddenEdge.mul(uniform(new Color(outlineParam.hiddenEdgeColor)))).mul(outlineParam.edgeStrength);
1678
+ const outlinePulse = pulsePeriod.greaterThan(0).select(outlineColor.mul(osc), outlineColor);
1679
+ // if(!this.denoiseOutlinePass)
1680
+ // {
1681
+ // this.denoiseOutlinePass = WebGPUPostProcessFactory.constructDenoisePass(this.scenePass, outlinePulse, DefaultDenoiseParam);
1682
+ // }
1683
+ // outlinePulse = this.denoiseOutlinePass.mul(outlinePulse)
1684
+ // finalNode = this.denoiseOutlinePass.mul(outlinePulse).add(finalNode);
1685
+ finalNode = outlinePulse.add(finalNode);
1686
+ //console.log("[PostProcess] OutlinePass 构建完成");
1687
+ break;
1688
+ }
1689
+ case PostProcessStepType.Antialiasing:
1690
+ {
1691
+ const aaParam = step;
1692
+ if (aaParam.method === "fxaa") {
1693
+ finalNode = WebGPUPostProcessFactory.constructFXAAPass(finalNode);
1694
+ //console.log("[PostProcess] FXAAPass 构建完成");
1695
+ }
1696
+ if (aaParam.method === "smaa") {
1697
+ finalNode = WebGPUPostProcessFactory.constructSMAAPass(finalNode);
1698
+ //console.log("[PostProcess] SMAAPass 构建完成");
1699
+ }
1700
+ break;
1701
+ }
1702
+ }
1703
+ });
1704
+ this.postProcessing.outputNode = finalNode;
1705
+ this.postProcessing.needsUpdate = true;
1706
+ //console.log("[PostProcess] setup complete", this.postProcessParam.steps);
1707
+ this.markRenderStateDirty();
1675
1708
  }
1676
1709
  updatePostProcess(steps) {
1677
1710
  this.postProcessParam.steps = steps;
@@ -1756,7 +1789,7 @@ class Viewport {
1756
1789
  return;
1757
1790
  }
1758
1791
  if (this.postProcessing) {
1759
- this.postProcessing.renderAsync();
1792
+ this.postProcessing.render();
1760
1793
  }
1761
1794
  else {
1762
1795
  this.renderer.render(this.app.world.scene, this.app.camera);
@@ -1773,13 +1806,7 @@ class Viewport {
1773
1806
  await this.postProcessing.renderAsync();
1774
1807
  }
1775
1808
  else {
1776
- if (this._renderer) {
1777
- await this._renderer.renderAsync(this.app.world.scene, this.app.camera);
1778
- }
1779
- else if (this._webGLRenderer) {
1780
- console.log("render with gl");
1781
- this._webGLRenderer.render(this.app.world.scene, this.app.camera);
1782
- }
1809
+ await this.renderer.renderAsync(this.app.world.scene, this.app.camera);
1783
1810
  }
1784
1811
  // 检查 renderer.domElement 的尺寸
1785
1812
  const sourceWidth = this.renderer.domElement.width;
@@ -2088,7 +2115,13 @@ class Controller {
2088
2115
  this.pawn.enabled = isPawnEnabled;
2089
2116
  }
2090
2117
  init() {
2091
- if (this.viewPort.canvas) ;
2118
+ if (this.viewPort.canvas) {
2119
+ this.viewPort.canvas.addEventListener("pointermove", this.onPointerMove);
2120
+ this.viewPort.canvas.addEventListener("pointerenter", this.onPointerEnter);
2121
+ this.viewPort.canvas.addEventListener("pointerleave", this.onPointerLeave);
2122
+ this.viewPort.canvas.addEventListener("pointerup", this.onPointerUp);
2123
+ this.viewPort.canvas.addEventListener("pointerdown", this.onPointerDown);
2124
+ }
2092
2125
  }
2093
2126
  tick(deltaTime) {
2094
2127
  this.pawn.tick(deltaTime);
@@ -2098,7 +2131,13 @@ class Controller {
2098
2131
  clearTimeout(this.leftClickTimer);
2099
2132
  this.leftClickTimer = null;
2100
2133
  }
2101
- if (this.viewPort.canvas) ;
2134
+ if (this.viewPort.canvas) {
2135
+ this.viewPort.canvas.removeEventListener("pointermove", this.onPointerMove);
2136
+ this.viewPort.canvas.removeEventListener("pointerenter", this.onPointerEnter);
2137
+ this.viewPort.canvas.removeEventListener("pointerleave", this.onPointerLeave);
2138
+ this.viewPort.canvas.removeEventListener("pointerup", this.onPointerUp);
2139
+ this.viewPort.canvas.removeEventListener("pointerdown", this.onPointerDown);
2140
+ }
2102
2141
  this.pawn.unpossess();
2103
2142
  this.pawn.destroy();
2104
2143
  this._pawn = null;
@@ -2220,14 +2259,6 @@ class Controller {
2220
2259
  focusTo(targetPos, targetQuat, distance, time, onGoing = null, onFinished = null) {
2221
2260
  this.pawn.focusTo(targetPos, targetQuat, distance, time, onGoing, onFinished);
2222
2261
  }
2223
- setPawn(pawn) {
2224
- if (this._pawn) {
2225
- this._pawn.unpossess();
2226
- this._pawn.destroy();
2227
- }
2228
- this._pawn = pawn;
2229
- this._pawn.possess();
2230
- }
2231
2262
  }
2232
2263
 
2233
2264
  class CameraFactory {
@@ -2253,7 +2284,7 @@ class CameraFactory {
2253
2284
  catch (error) {
2254
2285
  console.warn("[CameraFactory]Error occurred while creating camera: ", error);
2255
2286
  console.warn("[CameraFactory]Create default perspective camera instead");
2256
- return new PerspectiveCamera(50, 1, 0.1, 100000);
2287
+ return new PerspectiveCamera(50, 1, 0.1, 1000);
2257
2288
  }
2258
2289
  }
2259
2290
  static updataCamera(param, camera) {
@@ -2267,7 +2298,6 @@ class CameraFactory {
2267
2298
  camera.far = data.far;
2268
2299
  camera.fov = data.fov;
2269
2300
  camera.aspect = data.aspect;
2270
- camera.updateProjectionMatrix();
2271
2301
  return camera;
2272
2302
  }
2273
2303
  return new PerspectiveCamera(data.fov, data.aspect, data.near, data.far);
@@ -2282,7 +2312,6 @@ class CameraFactory {
2282
2312
  camera.right = data.right;
2283
2313
  camera.top = data.top;
2284
2314
  camera.bottom = data.bottom;
2285
- camera.updateProjectionMatrix();
2286
2315
  return camera;
2287
2316
  }
2288
2317
  return new OrthographicCamera(data.left, data.right, data.top, data.bottom, data.near, data.far);
@@ -2303,7 +2332,7 @@ class CameraFactory {
2303
2332
 
2304
2333
  const DefaultPerspectiveCameraParam = {
2305
2334
  near: 0.1,
2306
- far: 10000,
2335
+ far: 1000,
2307
2336
  type: "Perspective",
2308
2337
  fov: 50,
2309
2338
  aspect: 1,
@@ -2835,14 +2864,7 @@ const DefaultWorldParam = {
2835
2864
  levelActorClass: LevelActor,
2836
2865
  };
2837
2866
 
2838
- /** 动画循环启动延迟时间(毫秒) */
2839
- const ANIMATION_START_DELAY = 100;
2840
- /**
2841
- * Three.js应用程序主类
2842
- * 负责管理场景、视口、控制器和资源
2843
- */
2844
2867
  class ThreeJsApp {
2845
- // ========== 公共访问器 ==========
2846
2868
  get camera() {
2847
2869
  return this._camera;
2848
2870
  }
@@ -2867,132 +2889,67 @@ class ThreeJsApp {
2867
2889
  get onCameraChangedDelegate() {
2868
2890
  return this._onCameraChangedDelegate;
2869
2891
  }
2870
- /**
2871
- * 构造ThreeJs应用程序实例
2872
- * @param appParam 应用程序参数配置
2873
- */
2874
2892
  constructor(appParam = DefaultAppParam) {
2875
- var _a, _b, _c, _d, _e, _f;
2876
- // ========== 私有字段 ==========
2877
- this.animationFrameHandle = 0;
2878
2893
  this._tickingFunctions = [];
2879
2894
  this._appParam = { viewportParam: DefaultViewportParam };
2880
2895
  this._onCameraChangedDelegate = new Delegate();
2881
- // 初始化应用参数(使用空值合并运算符简化默认值处理)
2882
- this._appParam.cameraParam = (_a = appParam.cameraParam) !== null && _a !== void 0 ? _a : DefaultCameraParam;
2883
- this._appParam.renderParam = (_b = appParam.renderParam) !== null && _b !== void 0 ? _b : DefaultRendererParameters;
2884
- this._appParam.postProcessParam = (_c = appParam.postProcessParam) !== null && _c !== void 0 ? _c : DefaultPostProcessParam;
2885
- this._appParam.viewportParam = (_d = appParam.viewportParam) !== null && _d !== void 0 ? _d : DefaultViewportParam;
2886
- this._appParam.worldParam = (_e = appParam.worldParam) !== null && _e !== void 0 ? _e : DefaultWorldParam;
2887
- this._appParam.isRenderEveryFrame = appParam.isRenderEveryFrame;
2888
- this._appParam.classes = (_f = appParam.classes) !== null && _f !== void 0 ? _f : {
2896
+ this._appParam.cameraParam = appParam.cameraParam ? appParam.cameraParam : DefaultCameraParam;
2897
+ this._appParam.renderParam = appParam.renderParam ? appParam.renderParam : DefaultRendererParameters;
2898
+ this._appParam.postProcessParam = appParam.postProcessParam ? appParam.postProcessParam : DefaultPostProcessParam;
2899
+ this._appParam.viewportParam = appParam.viewportParam ? appParam.viewportParam : DefaultViewportParam;
2900
+ this._appParam.classes = appParam.classes ? appParam.classes : {
2889
2901
  assetManagerClass: AssetManager,
2890
2902
  controllerClass: Controller,
2891
2903
  worldClass: World,
2892
2904
  viewportClass: Viewport,
2893
2905
  };
2894
- // 初始化核心组件
2906
+ this._appParam.isRenderEveryFrame = appParam.isRenderEveryFrame;
2895
2907
  this._clock = new Clock();
2896
2908
  this._camera = CameraFactory.createCamera(this._appParam.cameraParam);
2897
- this._world = new this._appParam.classes.worldClass(this, this._appParam.worldParam);
2909
+ this._world = new this._appParam.classes.worldClass(this, this._appParam.worldParam ? this._appParam.worldParam : DefaultWorldParam);
2898
2910
  this._viewport = new this._appParam.classes.viewportClass(this, this._appParam.viewportParam, this._appParam.renderParam, this._appParam.postProcessParam);
2899
2911
  this._controller = new this._appParam.classes.controllerClass(this);
2900
2912
  this._assetManager = new this._appParam.classes.assetManagerClass(this);
2913
+ this.viewport.renderer.setAnimationLoop(() => {
2914
+ const delta = this._clock.getDelta();
2915
+ this.tick(delta);
2916
+ });
2901
2917
  this.postConstruct();
2902
- this.startAnimationLoop();
2903
2918
  }
2904
- /**
2905
- * 构造后初始化钩子
2906
- * 按顺序初始化控制器、世界和视口
2907
- */
2908
2919
  postConstruct() {
2909
2920
  this.controller.init();
2910
2921
  this.world.init();
2911
2922
  this.viewport.init();
2912
2923
  }
2913
- /**
2914
- * 公共初始化方法
2915
- * 可由子类重写以添加自定义初始化逻辑
2916
- */
2917
2924
  init() {
2918
- // 预留给子类实现
2919
- }
2920
- /**
2921
- * 启动动画循环
2922
- * 使用延迟启动以确保所有组件完全初始化
2923
- */
2924
- startAnimationLoop() {
2925
- const tick = () => {
2926
- this.animationFrameHandle = requestAnimationFrame(tick);
2927
- try {
2928
- const delta = this._clock.getDelta();
2929
- this.tick(delta);
2930
- }
2931
- catch (error) {
2932
- console.error('动画循环错误:', error);
2933
- }
2934
- };
2935
- setTimeout(() => {
2936
- tick();
2937
- }, ANIMATION_START_DELAY);
2938
- }
2939
- /**
2940
- * 每帧更新方法
2941
- * @param deltaTime 距离上一帧的时间增量(秒)
2942
- */
2925
+ }
2943
2926
  tick(deltaTime) {
2944
2927
  this._controller.tick(deltaTime);
2945
2928
  this.world.tick(deltaTime);
2946
- // 执行所有注册的tick函数
2947
2929
  this._tickingFunctions.forEach(func => {
2948
2930
  func(deltaTime);
2949
2931
  });
2950
- // 根据配置决定是否每帧都渲染
2951
2932
  if (this._appParam.isRenderEveryFrame) {
2952
2933
  this.viewport.markRenderStateDirty();
2953
2934
  }
2954
2935
  this.viewport.render();
2955
2936
  }
2956
- /**
2957
- * 添加每帧执行的函数
2958
- * @param func 接收deltaTime参数的回调函数
2959
- */
2960
2937
  addTickingFunction(func) {
2961
2938
  this._tickingFunctions.push(func);
2962
2939
  }
2963
- /**
2964
- * 移除已注册的tick函数
2965
- * @param func 要移除的函数引用
2966
- */
2967
2940
  removeTickingFunction(func) {
2968
2941
  const index = this._tickingFunctions.indexOf(func);
2969
2942
  if (index >= 0) {
2970
2943
  this._tickingFunctions.splice(index, 1);
2971
2944
  }
2972
2945
  }
2973
- /**
2974
- * 销毁应用程序并清理所有资源
2975
- */
2976
2946
  destroy() {
2977
- // 停止动画循环
2978
- if (this.animationFrameHandle) {
2979
- cancelAnimationFrame(this.animationFrameHandle);
2980
- this.animationFrameHandle = 0;
2981
- }
2982
- // 清理委托
2983
2947
  this.onCameraChangedDelegate.clear();
2984
- // 销毁各个组件
2985
2948
  this.controller.destroy();
2986
2949
  this.world.destroy();
2987
2950
  this.viewport.destroy();
2988
2951
  this._assetManager.clearAssets();
2989
- // 清空tick函数列表
2990
- this._tickingFunctions = [];
2991
2952
  }
2992
- /**
2993
- * 更新相机参数
2994
- * @param param 新的相机参数
2995
- */
2996
2953
  updateCamera(param) {
2997
2954
  const previousCam = this.camera;
2998
2955
  this._camera = CameraFactory.updataCamera(param, this.camera);
@@ -3003,31 +2960,16 @@ class ThreeJsApp {
3003
2960
  this._camera.updateProjectionMatrix();
3004
2961
  this.viewport.markRenderStateDirty();
3005
2962
  }
3006
- /**
3007
- * 窗口大小改变时的处理
3008
- * @param width 新的宽度
3009
- * @param height 新的高度
3010
- */
3011
2963
  onWindowResize(width, height) {
3012
2964
  if (this.camera instanceof PerspectiveCamera) {
3013
2965
  this.camera.aspect = width / height;
3014
2966
  }
3015
- // TODO: 实现正交相机的窗口缩放处理
3016
- // if (this.camera instanceof OrthographicCamera) {
3017
- // const aspect = width / height;
3018
- // this.camera.left = -width / 2;
3019
- // this.camera.right = width / 2;
3020
- // this.camera.top = height / 2;
3021
- // this.camera.bottom = -height / 2;
2967
+ // if(this.camera instanceof OrthographicCamera)
2968
+ // {
2969
+ // // to do
3022
2970
  // }
3023
2971
  this.camera.updateProjectionMatrix();
3024
2972
  }
3025
- /**
3026
- * 将当前场景渲染为图片
3027
- * @param width 图片宽度,默认1024
3028
- * @param height 图片高度,默认1024
3029
- * @returns 图片的DataURL
3030
- */
3031
2973
  async renderAsImage(width = 1024, height = 1024) {
3032
2974
  return await this.viewport.renderAsImage(width, height);
3033
2975
  }
@@ -3203,7 +3145,7 @@ class AmbientLightActor extends Actor {
3203
3145
  }
3204
3146
 
3205
3147
  class BoxComponent extends MeshComponent {
3206
- constructor(app, width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1, material = new MeshStandardMaterial({ color: 0x00ff00 }), uuid) {
3148
+ constructor(app, width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1, material = new MeshStandardMaterial(), uuid) {
3207
3149
  super(app, new BoxGeometry(width, height, depth, widthSegments, heightSegments, depthSegments), material, uuid);
3208
3150
  }
3209
3151
  }
@@ -3350,120 +3292,6 @@ class LabelComponent extends SceneComponent {
3350
3292
  // labelStyle.style.fontSize = "10px";
3351
3293
  // labelStyle.style.pointerEvents = 'auto';
3352
3294
 
3353
- class CurveComponent extends SceneComponent {
3354
- get threeObject() {
3355
- if (!this.obj) {
3356
- throw new Error("threeObject is null");
3357
- }
3358
- return this.obj;
3359
- }
3360
- set threeObject(newThreeObject) {
3361
- this.obj = newThreeObject;
3362
- if (this.obj) {
3363
- this.obj.userData["LYObject"] = this;
3364
- }
3365
- }
3366
- get material() {
3367
- return this.threeObject.material;
3368
- }
3369
- constructor(app, points, setup = { color: 0xffffff }, bCreateLine = true, uuid) {
3370
- var _a, _b, _c;
3371
- super(app, uuid);
3372
- this.closed = (_a = setup.closed) !== null && _a !== void 0 ? _a : false;
3373
- this.curveType = (_b = setup.type) !== null && _b !== void 0 ? _b : 'centripetal';
3374
- this.tension = (_c = setup.tension) !== null && _c !== void 0 ? _c : 0;
3375
- this.sourcePoints = points;
3376
- this.curve = new CatmullRomCurve3(points, this.closed, this.curveType, this.tension);
3377
- this.points = this.curve.getPoints(points.length * (this.tension === 0 ? 1 : 10) - 1);
3378
- this.material.color = new Color(setup.color);
3379
- this.bCreateLine = bCreateLine;
3380
- this.name = "CurveComponent";
3381
- if (this.bCreateLine) {
3382
- this.createLine();
3383
- }
3384
- }
3385
- isValid() {
3386
- return this.threeObject != null;
3387
- }
3388
- createDefaultObject() {
3389
- // 创建默认材质
3390
- const material = new LineBasicMaterial({
3391
- color: 0xffffff,
3392
- transparent: true,
3393
- opacity: 1
3394
- });
3395
- // 创建空的几何体和线对象
3396
- const geometry = new BufferGeometry$1();
3397
- const line = new Line(geometry, material);
3398
- return line;
3399
- }
3400
- resetPoints(points) {
3401
- this.sourcePoints = points;
3402
- this.curve = new CatmullRomCurve3(points, this.closed, this.curveType, this.tension);
3403
- this.points = this.curve.getPoints(points.length * (this.tension === 0 ? 1 : 10) - 1);
3404
- if (this.bCreateLine) {
3405
- this.createLine();
3406
- }
3407
- }
3408
- createLine() {
3409
- const positions = [];
3410
- for (let i = 0; i < this.points.length; ++i) {
3411
- positions.push(this.points[i].x);
3412
- positions.push(this.points[i].y);
3413
- positions.push(this.points[i].z);
3414
- }
3415
- const geometry = this.threeObject.geometry;
3416
- geometry.setAttribute('position', new Float32BufferAttribute(positions, 3));
3417
- }
3418
- destroy() {
3419
- if (this.isValid() && this.threeObject) {
3420
- if (this.threeObject.geometry) {
3421
- this.threeObject.geometry.dispose();
3422
- }
3423
- if (this.material) {
3424
- this.material.dispose();
3425
- }
3426
- }
3427
- super.destroy();
3428
- }
3429
- get SourcePoints() {
3430
- return this.sourcePoints;
3431
- }
3432
- get Curve() {
3433
- return this.curve;
3434
- }
3435
- get Points() {
3436
- return this.points;
3437
- }
3438
- getPointAt(u) {
3439
- return this.curve.getPointAt(u);
3440
- }
3441
- getTangentAt(u) {
3442
- return this.curve.getTangentAt(u);
3443
- }
3444
- // 返回曲线在参数 u 处的世界坐标点
3445
- getWorldPointAt(u) {
3446
- const p = this.curve.getPointAt(u).clone();
3447
- if (this.obj) {
3448
- this.obj.updateMatrixWorld(true);
3449
- return this.localToWorld(p);
3450
- }
3451
- return p;
3452
- }
3453
- // 返回曲线在参数 u 处的世界坐标系下的单位切线方向
3454
- getWorldTangentAt(u) {
3455
- const t = this.curve.getTangentAt(u).clone();
3456
- if (this.obj) {
3457
- this.obj.updateMatrixWorld(true);
3458
- t.transformDirection(this.obj.matrixWorld);
3459
- }
3460
- return t;
3461
- }
3462
- getLength() {
3463
- return this.curve.getLength();
3464
- }
3465
- }
3466
-
3467
3295
  const DefaultBloomParam = {
3468
3296
  type: PostProcessStepType.Bloom,
3469
3297
  threshold: 0,
@@ -3738,4 +3566,4 @@ class TransformGizmo extends Pawn {
3738
3566
  }
3739
3567
  }
3740
3568
 
3741
- export { Actor, AmbientLightActor, AmbientLightComponent, AssetManager, AttachmentRules, BoxActor, BoxComponent, Controller, CurveComponent, DefaultAAParams, DefaultAppParam, DefaultBloomParam, DefaultCameraParam, DefaultDOFParam, DefaultDenoiseParam, DefaultGTAOParam, DefaultOrthographicCameraParam, DefaultOutlineParams, DefaultPerspectiveCameraParam, DefaultPostProcessParam, DefaultRendererParameters, DefaultSSRParam, DefaultSkyParam, DefaultViewportParam, DefaultWorldParam, Delegate, DirectionalLightActor, DirectionalLightComponent, FirstPerson, GeometryAssetPointer, LabelComponent, LevelActor, LevelComponent, MaterialAssetPointer, MeshComponent, Orbital, Pawn, PlaneActor, PlaneComponent, PostProcessStepType, SceneComponent, SkyActor, SkyComponent, SphereComponent, TAssetPointer, TSmartPointer, TextureAssetPointer, ThreeJsApp, ThreeObjectLibrary, TransformGizmo, Viewport, WebGPUPostProcessFactory, World };
3569
+ export { Actor, AmbientLightActor, AmbientLightComponent, AssetManager, AttachmentRules, BoxActor, BoxComponent, Controller, DefaultAAParams, DefaultAppParam, DefaultBloomParam, DefaultCameraParam, DefaultDOFParam, DefaultDenoiseParam, DefaultGTAOParam, DefaultOrthographicCameraParam, DefaultOutlineParams, DefaultPerspectiveCameraParam, DefaultPostProcessParam, DefaultRendererParameters, DefaultSSRParam, DefaultSkyParam, DefaultViewportParam, DefaultWorldParam, Delegate, DirectionalLightActor, DirectionalLightComponent, FirstPerson, GeometryAssetPointer, LabelComponent, LevelActor, LevelComponent, MaterialAssetPointer, MeshComponent, Orbital, PlaneActor, PlaneComponent, PostProcessStepType, SceneComponent, SkyActor, SkyComponent, SphereComponent, TAssetPointer, TSmartPointer, TextureAssetPointer, ThreeJsApp, ThreeObjectLibrary, TransformGizmo, Viewport, WebGPUPostProcessFactory, World };