lythreeframe 1.2.49 → 1.2.50

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.
@@ -1575,7 +1575,7 @@ class Viewport {
1575
1575
  this.setupPostProcess();
1576
1576
  });
1577
1577
  }
1578
- createRenderer(rendererParam) {
1578
+ async createRenderer(rendererParam) {
1579
1579
  if (this._outerContainer) {
1580
1580
  this._canvasContainer = document.createElement("div");
1581
1581
  this._canvasContainer.style.left = "0px";
@@ -1616,6 +1616,8 @@ class Viewport {
1616
1616
  }
1617
1617
  else {
1618
1618
  this._renderer = new webgpu.WebGPURenderer(renderP);
1619
+ // WebGPU 需要异步初始化
1620
+ await this._renderer.init();
1619
1621
  this._renderer.setPixelRatio(window.devicePixelRatio);
1620
1622
  this._renderer.setSize(width, height);
1621
1623
  this._renderer.shadowMap.enabled = rendererParam.shadowMapEnabled;
@@ -1756,7 +1758,7 @@ class Viewport {
1756
1758
  return;
1757
1759
  }
1758
1760
  if (this.postProcessing) {
1759
- this.postProcessing.render();
1761
+ this.postProcessing.renderAsync();
1760
1762
  }
1761
1763
  else {
1762
1764
  this.renderer.render(this.app.world.scene, this.app.camera);
@@ -2088,13 +2090,7 @@ class Controller {
2088
2090
  this.pawn.enabled = isPawnEnabled;
2089
2091
  }
2090
2092
  init() {
2091
- if (this.viewPort.canvas) {
2092
- this.viewPort.canvas.addEventListener("pointermove", this.onPointerMove);
2093
- this.viewPort.canvas.addEventListener("pointerenter", this.onPointerEnter);
2094
- this.viewPort.canvas.addEventListener("pointerleave", this.onPointerLeave);
2095
- this.viewPort.canvas.addEventListener("pointerup", this.onPointerUp);
2096
- this.viewPort.canvas.addEventListener("pointerdown", this.onPointerDown);
2097
- }
2093
+ if (this.viewPort.canvas) ;
2098
2094
  }
2099
2095
  tick(deltaTime) {
2100
2096
  this.pawn.tick(deltaTime);
@@ -2104,13 +2100,7 @@ class Controller {
2104
2100
  clearTimeout(this.leftClickTimer);
2105
2101
  this.leftClickTimer = null;
2106
2102
  }
2107
- if (this.viewPort.canvas) {
2108
- this.viewPort.canvas.removeEventListener("pointermove", this.onPointerMove);
2109
- this.viewPort.canvas.removeEventListener("pointerenter", this.onPointerEnter);
2110
- this.viewPort.canvas.removeEventListener("pointerleave", this.onPointerLeave);
2111
- this.viewPort.canvas.removeEventListener("pointerup", this.onPointerUp);
2112
- this.viewPort.canvas.removeEventListener("pointerdown", this.onPointerDown);
2113
- }
2103
+ if (this.viewPort.canvas) ;
2114
2104
  this.pawn.unpossess();
2115
2105
  this.pawn.destroy();
2116
2106
  this._pawn = null;
@@ -2265,7 +2255,7 @@ class CameraFactory {
2265
2255
  catch (error) {
2266
2256
  console.warn("[CameraFactory]Error occurred while creating camera: ", error);
2267
2257
  console.warn("[CameraFactory]Create default perspective camera instead");
2268
- return new webgpu.PerspectiveCamera(50, 1, 0.1, 1000);
2258
+ return new webgpu.PerspectiveCamera(50, 1, 0.1, 100000);
2269
2259
  }
2270
2260
  }
2271
2261
  static updataCamera(param, camera) {
@@ -2279,6 +2269,7 @@ class CameraFactory {
2279
2269
  camera.far = data.far;
2280
2270
  camera.fov = data.fov;
2281
2271
  camera.aspect = data.aspect;
2272
+ camera.updateProjectionMatrix();
2282
2273
  return camera;
2283
2274
  }
2284
2275
  return new webgpu.PerspectiveCamera(data.fov, data.aspect, data.near, data.far);
@@ -2293,6 +2284,7 @@ class CameraFactory {
2293
2284
  camera.right = data.right;
2294
2285
  camera.top = data.top;
2295
2286
  camera.bottom = data.bottom;
2287
+ camera.updateProjectionMatrix();
2296
2288
  return camera;
2297
2289
  }
2298
2290
  return new webgpu.OrthographicCamera(data.left, data.right, data.top, data.bottom, data.near, data.far);
@@ -2313,7 +2305,7 @@ class CameraFactory {
2313
2305
 
2314
2306
  const DefaultPerspectiveCameraParam = {
2315
2307
  near: 0.1,
2316
- far: 1000,
2308
+ far: 10000,
2317
2309
  type: "Perspective",
2318
2310
  fov: 50,
2319
2311
  aspect: 1,
@@ -2845,7 +2837,14 @@ const DefaultWorldParam = {
2845
2837
  levelActorClass: LevelActor,
2846
2838
  };
2847
2839
 
2840
+ /** 动画循环启动延迟时间(毫秒) */
2841
+ const ANIMATION_START_DELAY = 100;
2842
+ /**
2843
+ * Three.js应用程序主类
2844
+ * 负责管理场景、视口、控制器和资源
2845
+ */
2848
2846
  class ThreeJsApp {
2847
+ // ========== 公共访问器 ==========
2849
2848
  get camera() {
2850
2849
  return this._camera;
2851
2850
  }
@@ -2870,67 +2869,132 @@ class ThreeJsApp {
2870
2869
  get onCameraChangedDelegate() {
2871
2870
  return this._onCameraChangedDelegate;
2872
2871
  }
2872
+ /**
2873
+ * 构造ThreeJs应用程序实例
2874
+ * @param appParam 应用程序参数配置
2875
+ */
2873
2876
  constructor(appParam = DefaultAppParam) {
2877
+ var _a, _b, _c, _d, _e, _f;
2878
+ // ========== 私有字段 ==========
2879
+ this.animationFrameHandle = 0;
2874
2880
  this._tickingFunctions = [];
2875
2881
  this._appParam = { viewportParam: DefaultViewportParam };
2876
2882
  this._onCameraChangedDelegate = new Delegate();
2877
- this._appParam.cameraParam = appParam.cameraParam ? appParam.cameraParam : DefaultCameraParam;
2878
- this._appParam.renderParam = appParam.renderParam ? appParam.renderParam : DefaultRendererParameters;
2879
- this._appParam.postProcessParam = appParam.postProcessParam ? appParam.postProcessParam : DefaultPostProcessParam;
2880
- this._appParam.viewportParam = appParam.viewportParam ? appParam.viewportParam : DefaultViewportParam;
2881
- this._appParam.classes = appParam.classes ? appParam.classes : {
2883
+ // 初始化应用参数(使用空值合并运算符简化默认值处理)
2884
+ this._appParam.cameraParam = (_a = appParam.cameraParam) !== null && _a !== void 0 ? _a : DefaultCameraParam;
2885
+ this._appParam.renderParam = (_b = appParam.renderParam) !== null && _b !== void 0 ? _b : DefaultRendererParameters;
2886
+ this._appParam.postProcessParam = (_c = appParam.postProcessParam) !== null && _c !== void 0 ? _c : DefaultPostProcessParam;
2887
+ this._appParam.viewportParam = (_d = appParam.viewportParam) !== null && _d !== void 0 ? _d : DefaultViewportParam;
2888
+ this._appParam.worldParam = (_e = appParam.worldParam) !== null && _e !== void 0 ? _e : DefaultWorldParam;
2889
+ this._appParam.isRenderEveryFrame = appParam.isRenderEveryFrame;
2890
+ this._appParam.classes = (_f = appParam.classes) !== null && _f !== void 0 ? _f : {
2882
2891
  assetManagerClass: AssetManager,
2883
2892
  controllerClass: Controller,
2884
2893
  worldClass: World,
2885
2894
  viewportClass: Viewport,
2886
2895
  };
2887
- this._appParam.isRenderEveryFrame = appParam.isRenderEveryFrame;
2896
+ // 初始化核心组件
2888
2897
  this._clock = new webgpu.Clock();
2889
2898
  this._camera = CameraFactory.createCamera(this._appParam.cameraParam);
2890
- this._world = new this._appParam.classes.worldClass(this, this._appParam.worldParam ? this._appParam.worldParam : DefaultWorldParam);
2899
+ this._world = new this._appParam.classes.worldClass(this, this._appParam.worldParam);
2891
2900
  this._viewport = new this._appParam.classes.viewportClass(this, this._appParam.viewportParam, this._appParam.renderParam, this._appParam.postProcessParam);
2892
2901
  this._controller = new this._appParam.classes.controllerClass(this);
2893
2902
  this._assetManager = new this._appParam.classes.assetManagerClass(this);
2894
- this.viewport.renderer.setAnimationLoop(() => {
2895
- const delta = this._clock.getDelta();
2896
- this.tick(delta);
2897
- });
2898
2903
  this.postConstruct();
2904
+ this.startAnimationLoop();
2899
2905
  }
2906
+ /**
2907
+ * 构造后初始化钩子
2908
+ * 按顺序初始化控制器、世界和视口
2909
+ */
2900
2910
  postConstruct() {
2901
2911
  this.controller.init();
2902
2912
  this.world.init();
2903
2913
  this.viewport.init();
2904
2914
  }
2915
+ /**
2916
+ * 公共初始化方法
2917
+ * 可由子类重写以添加自定义初始化逻辑
2918
+ */
2905
2919
  init() {
2906
- }
2920
+ // 预留给子类实现
2921
+ }
2922
+ /**
2923
+ * 启动动画循环
2924
+ * 使用延迟启动以确保所有组件完全初始化
2925
+ */
2926
+ startAnimationLoop() {
2927
+ const tick = () => {
2928
+ this.animationFrameHandle = requestAnimationFrame(tick);
2929
+ try {
2930
+ const delta = this._clock.getDelta();
2931
+ this.tick(delta);
2932
+ }
2933
+ catch (error) {
2934
+ console.error('动画循环错误:', error);
2935
+ }
2936
+ };
2937
+ setTimeout(() => {
2938
+ tick();
2939
+ }, ANIMATION_START_DELAY);
2940
+ }
2941
+ /**
2942
+ * 每帧更新方法
2943
+ * @param deltaTime 距离上一帧的时间增量(秒)
2944
+ */
2907
2945
  tick(deltaTime) {
2908
2946
  this._controller.tick(deltaTime);
2909
2947
  this.world.tick(deltaTime);
2948
+ // 执行所有注册的tick函数
2910
2949
  this._tickingFunctions.forEach(func => {
2911
2950
  func(deltaTime);
2912
2951
  });
2952
+ // 根据配置决定是否每帧都渲染
2913
2953
  if (this._appParam.isRenderEveryFrame) {
2914
2954
  this.viewport.markRenderStateDirty();
2915
2955
  }
2916
2956
  this.viewport.render();
2917
2957
  }
2958
+ /**
2959
+ * 添加每帧执行的函数
2960
+ * @param func 接收deltaTime参数的回调函数
2961
+ */
2918
2962
  addTickingFunction(func) {
2919
2963
  this._tickingFunctions.push(func);
2920
2964
  }
2965
+ /**
2966
+ * 移除已注册的tick函数
2967
+ * @param func 要移除的函数引用
2968
+ */
2921
2969
  removeTickingFunction(func) {
2922
2970
  const index = this._tickingFunctions.indexOf(func);
2923
2971
  if (index >= 0) {
2924
2972
  this._tickingFunctions.splice(index, 1);
2925
2973
  }
2926
2974
  }
2975
+ /**
2976
+ * 销毁应用程序并清理所有资源
2977
+ */
2927
2978
  destroy() {
2979
+ // 停止动画循环
2980
+ if (this.animationFrameHandle) {
2981
+ cancelAnimationFrame(this.animationFrameHandle);
2982
+ this.animationFrameHandle = 0;
2983
+ }
2984
+ // 清理委托
2928
2985
  this.onCameraChangedDelegate.clear();
2986
+ // 销毁各个组件
2929
2987
  this.controller.destroy();
2930
2988
  this.world.destroy();
2931
2989
  this.viewport.destroy();
2932
2990
  this._assetManager.clearAssets();
2991
+ // 清空tick函数列表
2992
+ this._tickingFunctions = [];
2933
2993
  }
2994
+ /**
2995
+ * 更新相机参数
2996
+ * @param param 新的相机参数
2997
+ */
2934
2998
  updateCamera(param) {
2935
2999
  const previousCam = this.camera;
2936
3000
  this._camera = CameraFactory.updataCamera(param, this.camera);
@@ -2941,16 +3005,31 @@ class ThreeJsApp {
2941
3005
  this._camera.updateProjectionMatrix();
2942
3006
  this.viewport.markRenderStateDirty();
2943
3007
  }
3008
+ /**
3009
+ * 窗口大小改变时的处理
3010
+ * @param width 新的宽度
3011
+ * @param height 新的高度
3012
+ */
2944
3013
  onWindowResize(width, height) {
2945
3014
  if (this.camera instanceof webgpu.PerspectiveCamera) {
2946
3015
  this.camera.aspect = width / height;
2947
3016
  }
2948
- // if(this.camera instanceof OrthographicCamera)
2949
- // {
2950
- // // to do
3017
+ // TODO: 实现正交相机的窗口缩放处理
3018
+ // if (this.camera instanceof OrthographicCamera) {
3019
+ // const aspect = width / height;
3020
+ // this.camera.left = -width / 2;
3021
+ // this.camera.right = width / 2;
3022
+ // this.camera.top = height / 2;
3023
+ // this.camera.bottom = -height / 2;
2951
3024
  // }
2952
3025
  this.camera.updateProjectionMatrix();
2953
3026
  }
3027
+ /**
3028
+ * 将当前场景渲染为图片
3029
+ * @param width 图片宽度,默认1024
3030
+ * @param height 图片高度,默认1024
3031
+ * @returns 图片的DataURL
3032
+ */
2954
3033
  async renderAsImage(width = 1024, height = 1024) {
2955
3034
  return await this.viewport.renderAsImage(width, height);
2956
3035
  }
@@ -3273,6 +3352,120 @@ class LabelComponent extends SceneComponent {
3273
3352
  // labelStyle.style.fontSize = "10px";
3274
3353
  // labelStyle.style.pointerEvents = 'auto';
3275
3354
 
3355
+ class CurveComponent extends SceneComponent {
3356
+ get threeObject() {
3357
+ if (!this.obj) {
3358
+ throw new Error("threeObject is null");
3359
+ }
3360
+ return this.obj;
3361
+ }
3362
+ set threeObject(newThreeObject) {
3363
+ this.obj = newThreeObject;
3364
+ if (this.obj) {
3365
+ this.obj.userData["LYObject"] = this;
3366
+ }
3367
+ }
3368
+ get material() {
3369
+ return this.threeObject.material;
3370
+ }
3371
+ constructor(app, points, setup = { color: 0xffffff }, bCreateLine = true, uuid) {
3372
+ var _a, _b, _c;
3373
+ super(app, uuid);
3374
+ this.closed = (_a = setup.closed) !== null && _a !== void 0 ? _a : false;
3375
+ this.curveType = (_b = setup.type) !== null && _b !== void 0 ? _b : 'centripetal';
3376
+ this.tension = (_c = setup.tension) !== null && _c !== void 0 ? _c : 0;
3377
+ this.sourcePoints = points;
3378
+ this.curve = new three.CatmullRomCurve3(points, this.closed, this.curveType, this.tension);
3379
+ this.points = this.curve.getPoints(points.length * (this.tension === 0 ? 1 : 10) - 1);
3380
+ this.material.color = new three.Color(setup.color);
3381
+ this.bCreateLine = bCreateLine;
3382
+ this.name = "CurveComponent";
3383
+ if (this.bCreateLine) {
3384
+ this.createLine();
3385
+ }
3386
+ }
3387
+ isValid() {
3388
+ return this.threeObject != null;
3389
+ }
3390
+ createDefaultObject() {
3391
+ // 创建默认材质
3392
+ const material = new three.LineBasicMaterial({
3393
+ color: 0xffffff,
3394
+ transparent: true,
3395
+ opacity: 1
3396
+ });
3397
+ // 创建空的几何体和线对象
3398
+ const geometry = new three.BufferGeometry();
3399
+ const line = new three.Line(geometry, material);
3400
+ return line;
3401
+ }
3402
+ resetPoints(points) {
3403
+ this.sourcePoints = points;
3404
+ this.curve = new three.CatmullRomCurve3(points, this.closed, this.curveType, this.tension);
3405
+ this.points = this.curve.getPoints(points.length * (this.tension === 0 ? 1 : 10) - 1);
3406
+ if (this.bCreateLine) {
3407
+ this.createLine();
3408
+ }
3409
+ }
3410
+ createLine() {
3411
+ const positions = [];
3412
+ for (let i = 0; i < this.points.length; ++i) {
3413
+ positions.push(this.points[i].x);
3414
+ positions.push(this.points[i].y);
3415
+ positions.push(this.points[i].z);
3416
+ }
3417
+ const geometry = this.threeObject.geometry;
3418
+ geometry.setAttribute('position', new three.Float32BufferAttribute(positions, 3));
3419
+ }
3420
+ destroy() {
3421
+ if (this.isValid() && this.threeObject) {
3422
+ if (this.threeObject.geometry) {
3423
+ this.threeObject.geometry.dispose();
3424
+ }
3425
+ if (this.material) {
3426
+ this.material.dispose();
3427
+ }
3428
+ }
3429
+ super.destroy();
3430
+ }
3431
+ get SourcePoints() {
3432
+ return this.sourcePoints;
3433
+ }
3434
+ get Curve() {
3435
+ return this.curve;
3436
+ }
3437
+ get Points() {
3438
+ return this.points;
3439
+ }
3440
+ getPointAt(u) {
3441
+ return this.curve.getPointAt(u);
3442
+ }
3443
+ getTangentAt(u) {
3444
+ return this.curve.getTangentAt(u);
3445
+ }
3446
+ // 返回曲线在参数 u 处的世界坐标点
3447
+ getWorldPointAt(u) {
3448
+ const p = this.curve.getPointAt(u).clone();
3449
+ if (this.obj) {
3450
+ this.obj.updateMatrixWorld(true);
3451
+ return this.localToWorld(p);
3452
+ }
3453
+ return p;
3454
+ }
3455
+ // 返回曲线在参数 u 处的世界坐标系下的单位切线方向
3456
+ getWorldTangentAt(u) {
3457
+ const t = this.curve.getTangentAt(u).clone();
3458
+ if (this.obj) {
3459
+ this.obj.updateMatrixWorld(true);
3460
+ t.transformDirection(this.obj.matrixWorld);
3461
+ }
3462
+ return t;
3463
+ }
3464
+ getLength() {
3465
+ return this.curve.getLength();
3466
+ }
3467
+ }
3468
+
3276
3469
  const DefaultBloomParam = {
3277
3470
  type: exports.PostProcessStepType.Bloom,
3278
3471
  threshold: 0,
@@ -3554,6 +3747,7 @@ exports.AssetManager = AssetManager;
3554
3747
  exports.BoxActor = BoxActor;
3555
3748
  exports.BoxComponent = BoxComponent;
3556
3749
  exports.Controller = Controller;
3750
+ exports.CurveComponent = CurveComponent;
3557
3751
  exports.DefaultAAParams = DefaultAAParams;
3558
3752
  exports.DefaultAppParam = DefaultAppParam;
3559
3753
  exports.DefaultBloomParam = DefaultBloomParam;
@@ -1,7 +1,7 @@
1
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';
2
2
  import { GLTFLoader, DRACOLoader, CSS2DRenderer, OrbitControls } from 'three/examples/jsm/Addons.js';
3
3
  import { pass, mrt, output, uniform, metalness, transformedNormalView } from 'three/tsl';
4
- import { WebGLRenderer, PCFSoftShadowMap, Scene, AmbientLight } from 'three';
4
+ import { WebGLRenderer, PCFSoftShadowMap, Scene, AmbientLight, CatmullRomCurve3, Color, LineBasicMaterial, BufferGeometry as BufferGeometry$1, Line, Float32BufferAttribute } from 'three';
5
5
  import { dof } from 'three/addons/tsl/display/DepthOfFieldNode.js';
6
6
  import { bloom } from 'three/examples/jsm/tsl/display/BloomNode.js';
7
7
  import { denoise } from 'three/examples/jsm/tsl/display/DenoiseNode.js';
@@ -1573,7 +1573,7 @@ class Viewport {
1573
1573
  this.setupPostProcess();
1574
1574
  });
1575
1575
  }
1576
- createRenderer(rendererParam) {
1576
+ async createRenderer(rendererParam) {
1577
1577
  if (this._outerContainer) {
1578
1578
  this._canvasContainer = document.createElement("div");
1579
1579
  this._canvasContainer.style.left = "0px";
@@ -1614,6 +1614,8 @@ class Viewport {
1614
1614
  }
1615
1615
  else {
1616
1616
  this._renderer = new WebGPURenderer(renderP);
1617
+ // WebGPU 需要异步初始化
1618
+ await this._renderer.init();
1617
1619
  this._renderer.setPixelRatio(window.devicePixelRatio);
1618
1620
  this._renderer.setSize(width, height);
1619
1621
  this._renderer.shadowMap.enabled = rendererParam.shadowMapEnabled;
@@ -1754,7 +1756,7 @@ class Viewport {
1754
1756
  return;
1755
1757
  }
1756
1758
  if (this.postProcessing) {
1757
- this.postProcessing.render();
1759
+ this.postProcessing.renderAsync();
1758
1760
  }
1759
1761
  else {
1760
1762
  this.renderer.render(this.app.world.scene, this.app.camera);
@@ -2086,13 +2088,7 @@ class Controller {
2086
2088
  this.pawn.enabled = isPawnEnabled;
2087
2089
  }
2088
2090
  init() {
2089
- if (this.viewPort.canvas) {
2090
- this.viewPort.canvas.addEventListener("pointermove", this.onPointerMove);
2091
- this.viewPort.canvas.addEventListener("pointerenter", this.onPointerEnter);
2092
- this.viewPort.canvas.addEventListener("pointerleave", this.onPointerLeave);
2093
- this.viewPort.canvas.addEventListener("pointerup", this.onPointerUp);
2094
- this.viewPort.canvas.addEventListener("pointerdown", this.onPointerDown);
2095
- }
2091
+ if (this.viewPort.canvas) ;
2096
2092
  }
2097
2093
  tick(deltaTime) {
2098
2094
  this.pawn.tick(deltaTime);
@@ -2102,13 +2098,7 @@ class Controller {
2102
2098
  clearTimeout(this.leftClickTimer);
2103
2099
  this.leftClickTimer = null;
2104
2100
  }
2105
- if (this.viewPort.canvas) {
2106
- this.viewPort.canvas.removeEventListener("pointermove", this.onPointerMove);
2107
- this.viewPort.canvas.removeEventListener("pointerenter", this.onPointerEnter);
2108
- this.viewPort.canvas.removeEventListener("pointerleave", this.onPointerLeave);
2109
- this.viewPort.canvas.removeEventListener("pointerup", this.onPointerUp);
2110
- this.viewPort.canvas.removeEventListener("pointerdown", this.onPointerDown);
2111
- }
2101
+ if (this.viewPort.canvas) ;
2112
2102
  this.pawn.unpossess();
2113
2103
  this.pawn.destroy();
2114
2104
  this._pawn = null;
@@ -2263,7 +2253,7 @@ class CameraFactory {
2263
2253
  catch (error) {
2264
2254
  console.warn("[CameraFactory]Error occurred while creating camera: ", error);
2265
2255
  console.warn("[CameraFactory]Create default perspective camera instead");
2266
- return new PerspectiveCamera(50, 1, 0.1, 1000);
2256
+ return new PerspectiveCamera(50, 1, 0.1, 100000);
2267
2257
  }
2268
2258
  }
2269
2259
  static updataCamera(param, camera) {
@@ -2277,6 +2267,7 @@ class CameraFactory {
2277
2267
  camera.far = data.far;
2278
2268
  camera.fov = data.fov;
2279
2269
  camera.aspect = data.aspect;
2270
+ camera.updateProjectionMatrix();
2280
2271
  return camera;
2281
2272
  }
2282
2273
  return new PerspectiveCamera(data.fov, data.aspect, data.near, data.far);
@@ -2291,6 +2282,7 @@ class CameraFactory {
2291
2282
  camera.right = data.right;
2292
2283
  camera.top = data.top;
2293
2284
  camera.bottom = data.bottom;
2285
+ camera.updateProjectionMatrix();
2294
2286
  return camera;
2295
2287
  }
2296
2288
  return new OrthographicCamera(data.left, data.right, data.top, data.bottom, data.near, data.far);
@@ -2311,7 +2303,7 @@ class CameraFactory {
2311
2303
 
2312
2304
  const DefaultPerspectiveCameraParam = {
2313
2305
  near: 0.1,
2314
- far: 1000,
2306
+ far: 10000,
2315
2307
  type: "Perspective",
2316
2308
  fov: 50,
2317
2309
  aspect: 1,
@@ -2843,7 +2835,14 @@ const DefaultWorldParam = {
2843
2835
  levelActorClass: LevelActor,
2844
2836
  };
2845
2837
 
2838
+ /** 动画循环启动延迟时间(毫秒) */
2839
+ const ANIMATION_START_DELAY = 100;
2840
+ /**
2841
+ * Three.js应用程序主类
2842
+ * 负责管理场景、视口、控制器和资源
2843
+ */
2846
2844
  class ThreeJsApp {
2845
+ // ========== 公共访问器 ==========
2847
2846
  get camera() {
2848
2847
  return this._camera;
2849
2848
  }
@@ -2868,67 +2867,132 @@ class ThreeJsApp {
2868
2867
  get onCameraChangedDelegate() {
2869
2868
  return this._onCameraChangedDelegate;
2870
2869
  }
2870
+ /**
2871
+ * 构造ThreeJs应用程序实例
2872
+ * @param appParam 应用程序参数配置
2873
+ */
2871
2874
  constructor(appParam = DefaultAppParam) {
2875
+ var _a, _b, _c, _d, _e, _f;
2876
+ // ========== 私有字段 ==========
2877
+ this.animationFrameHandle = 0;
2872
2878
  this._tickingFunctions = [];
2873
2879
  this._appParam = { viewportParam: DefaultViewportParam };
2874
2880
  this._onCameraChangedDelegate = new Delegate();
2875
- this._appParam.cameraParam = appParam.cameraParam ? appParam.cameraParam : DefaultCameraParam;
2876
- this._appParam.renderParam = appParam.renderParam ? appParam.renderParam : DefaultRendererParameters;
2877
- this._appParam.postProcessParam = appParam.postProcessParam ? appParam.postProcessParam : DefaultPostProcessParam;
2878
- this._appParam.viewportParam = appParam.viewportParam ? appParam.viewportParam : DefaultViewportParam;
2879
- this._appParam.classes = appParam.classes ? appParam.classes : {
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 : {
2880
2889
  assetManagerClass: AssetManager,
2881
2890
  controllerClass: Controller,
2882
2891
  worldClass: World,
2883
2892
  viewportClass: Viewport,
2884
2893
  };
2885
- this._appParam.isRenderEveryFrame = appParam.isRenderEveryFrame;
2894
+ // 初始化核心组件
2886
2895
  this._clock = new Clock();
2887
2896
  this._camera = CameraFactory.createCamera(this._appParam.cameraParam);
2888
- this._world = new this._appParam.classes.worldClass(this, this._appParam.worldParam ? this._appParam.worldParam : DefaultWorldParam);
2897
+ this._world = new this._appParam.classes.worldClass(this, this._appParam.worldParam);
2889
2898
  this._viewport = new this._appParam.classes.viewportClass(this, this._appParam.viewportParam, this._appParam.renderParam, this._appParam.postProcessParam);
2890
2899
  this._controller = new this._appParam.classes.controllerClass(this);
2891
2900
  this._assetManager = new this._appParam.classes.assetManagerClass(this);
2892
- this.viewport.renderer.setAnimationLoop(() => {
2893
- const delta = this._clock.getDelta();
2894
- this.tick(delta);
2895
- });
2896
2901
  this.postConstruct();
2902
+ this.startAnimationLoop();
2897
2903
  }
2904
+ /**
2905
+ * 构造后初始化钩子
2906
+ * 按顺序初始化控制器、世界和视口
2907
+ */
2898
2908
  postConstruct() {
2899
2909
  this.controller.init();
2900
2910
  this.world.init();
2901
2911
  this.viewport.init();
2902
2912
  }
2913
+ /**
2914
+ * 公共初始化方法
2915
+ * 可由子类重写以添加自定义初始化逻辑
2916
+ */
2903
2917
  init() {
2904
- }
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
+ */
2905
2943
  tick(deltaTime) {
2906
2944
  this._controller.tick(deltaTime);
2907
2945
  this.world.tick(deltaTime);
2946
+ // 执行所有注册的tick函数
2908
2947
  this._tickingFunctions.forEach(func => {
2909
2948
  func(deltaTime);
2910
2949
  });
2950
+ // 根据配置决定是否每帧都渲染
2911
2951
  if (this._appParam.isRenderEveryFrame) {
2912
2952
  this.viewport.markRenderStateDirty();
2913
2953
  }
2914
2954
  this.viewport.render();
2915
2955
  }
2956
+ /**
2957
+ * 添加每帧执行的函数
2958
+ * @param func 接收deltaTime参数的回调函数
2959
+ */
2916
2960
  addTickingFunction(func) {
2917
2961
  this._tickingFunctions.push(func);
2918
2962
  }
2963
+ /**
2964
+ * 移除已注册的tick函数
2965
+ * @param func 要移除的函数引用
2966
+ */
2919
2967
  removeTickingFunction(func) {
2920
2968
  const index = this._tickingFunctions.indexOf(func);
2921
2969
  if (index >= 0) {
2922
2970
  this._tickingFunctions.splice(index, 1);
2923
2971
  }
2924
2972
  }
2973
+ /**
2974
+ * 销毁应用程序并清理所有资源
2975
+ */
2925
2976
  destroy() {
2977
+ // 停止动画循环
2978
+ if (this.animationFrameHandle) {
2979
+ cancelAnimationFrame(this.animationFrameHandle);
2980
+ this.animationFrameHandle = 0;
2981
+ }
2982
+ // 清理委托
2926
2983
  this.onCameraChangedDelegate.clear();
2984
+ // 销毁各个组件
2927
2985
  this.controller.destroy();
2928
2986
  this.world.destroy();
2929
2987
  this.viewport.destroy();
2930
2988
  this._assetManager.clearAssets();
2989
+ // 清空tick函数列表
2990
+ this._tickingFunctions = [];
2931
2991
  }
2992
+ /**
2993
+ * 更新相机参数
2994
+ * @param param 新的相机参数
2995
+ */
2932
2996
  updateCamera(param) {
2933
2997
  const previousCam = this.camera;
2934
2998
  this._camera = CameraFactory.updataCamera(param, this.camera);
@@ -2939,16 +3003,31 @@ class ThreeJsApp {
2939
3003
  this._camera.updateProjectionMatrix();
2940
3004
  this.viewport.markRenderStateDirty();
2941
3005
  }
3006
+ /**
3007
+ * 窗口大小改变时的处理
3008
+ * @param width 新的宽度
3009
+ * @param height 新的高度
3010
+ */
2942
3011
  onWindowResize(width, height) {
2943
3012
  if (this.camera instanceof PerspectiveCamera) {
2944
3013
  this.camera.aspect = width / height;
2945
3014
  }
2946
- // if(this.camera instanceof OrthographicCamera)
2947
- // {
2948
- // // to do
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;
2949
3022
  // }
2950
3023
  this.camera.updateProjectionMatrix();
2951
3024
  }
3025
+ /**
3026
+ * 将当前场景渲染为图片
3027
+ * @param width 图片宽度,默认1024
3028
+ * @param height 图片高度,默认1024
3029
+ * @returns 图片的DataURL
3030
+ */
2952
3031
  async renderAsImage(width = 1024, height = 1024) {
2953
3032
  return await this.viewport.renderAsImage(width, height);
2954
3033
  }
@@ -3271,6 +3350,120 @@ class LabelComponent extends SceneComponent {
3271
3350
  // labelStyle.style.fontSize = "10px";
3272
3351
  // labelStyle.style.pointerEvents = 'auto';
3273
3352
 
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
+
3274
3467
  const DefaultBloomParam = {
3275
3468
  type: PostProcessStepType.Bloom,
3276
3469
  threshold: 0,
@@ -3545,4 +3738,4 @@ class TransformGizmo extends Pawn {
3545
3738
  }
3546
3739
  }
3547
3740
 
3548
- 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, Pawn, PlaneActor, PlaneComponent, PostProcessStepType, SceneComponent, SkyActor, SkyComponent, SphereComponent, TAssetPointer, TSmartPointer, TextureAssetPointer, ThreeJsApp, ThreeObjectLibrary, TransformGizmo, Viewport, WebGPUPostProcessFactory, World };
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 };
package/dist/index.d.ts CHANGED
@@ -37,6 +37,8 @@ export { DirectionalLightComponent } from "./lythreeframe/Object/Components/Ligh
37
37
  export { AmbientLightComponent } from './lythreeframe/Object/Components/Light/AmbientLight/AmbientLightComponent';
38
38
  export { LabelComponent } from "./lythreeframe/Object/Components/2D/2DComponent";
39
39
  export { SkyComponent } from "./lythreeframe/Object/Components/Sky/SkyComponent";
40
+ export { CurveComponent } from './lythreeframe/Object/Components/Curve/CurveComponent';
41
+ export type { CurveComponetSetup } from './lythreeframe/Object/Components/Curve/CurveComponent';
40
42
  export type { SkyComponentParam } from "./lythreeframe/Object/Components/Sky/SkyComponent";
41
43
  export { DefaultSkyParam } from "./lythreeframe/Object/Components/Sky/SkyComponent";
42
44
  export { WebGPUPostProcessFactory } from "./lythreeframe/PostProcess/WebGPUPostProcessFactory";
@@ -25,7 +25,7 @@ export declare class Viewport {
25
25
  private viewportParam;
26
26
  private outlineObjects;
27
27
  constructor(app: ThreeJsApp, viewportParam: ViewportParam, rendererParam: RendererParameters, postProcessParam: PostProcessParam);
28
- protected createRenderer(rendererParam: RendererParameters): void;
28
+ protected createRenderer(rendererParam: RendererParameters): Promise<void>;
29
29
  protected createLabelRenderer(): void;
30
30
  protected createUILayer(): void;
31
31
  init(): void;
@@ -0,0 +1,35 @@
1
+ import { ThreeJsApp } from 'lythreeframe/lythreeframe/ThreeJsApp';
2
+ import { SceneComponent } from './../SceneComponent';
3
+ import { CatmullRomCurve3, ColorRepresentation, Line, LineBasicMaterial, Vector3 } from 'three';
4
+ export interface CurveComponetSetup {
5
+ type?: 'centripetal' | 'chordal' | 'catmullrom';
6
+ tension?: number;
7
+ closed?: boolean;
8
+ color?: ColorRepresentation;
9
+ }
10
+ export declare class CurveComponent extends SceneComponent {
11
+ private points;
12
+ private curve;
13
+ private closed;
14
+ private curveType;
15
+ private tension;
16
+ private bCreateLine;
17
+ private sourcePoints;
18
+ get threeObject(): Line;
19
+ protected set threeObject(newThreeObject: Line);
20
+ get material(): LineBasicMaterial;
21
+ constructor(app: ThreeJsApp, points: Vector3[], setup?: CurveComponetSetup, bCreateLine?: boolean, uuid?: string);
22
+ isValid(): boolean;
23
+ protected createDefaultObject(): Line;
24
+ resetPoints(points: Vector3[]): void;
25
+ createLine(): void;
26
+ destroy(): void;
27
+ get SourcePoints(): Vector3[];
28
+ get Curve(): CatmullRomCurve3;
29
+ get Points(): Vector3[];
30
+ getPointAt(u: number): Vector3;
31
+ getTangentAt(u: number): Vector3;
32
+ getWorldPointAt(u: number): Vector3;
33
+ getWorldTangentAt(u: number): Vector3;
34
+ getLength(): number;
35
+ }
@@ -1,4 +1,4 @@
1
- import { PostProcessStepParam, PostProcessStepType } from "../PostProcessParam";
1
+ import { PostProcessStepType, type PostProcessStepParam } from "../PostProcessParam";
2
2
  export interface AAParams extends PostProcessStepParam {
3
3
  type: PostProcessStepType.Antialiasing;
4
4
  method: "fxaa" | "smaa";
@@ -1,4 +1,4 @@
1
- import { PostProcessStepParam, PostProcessStepType } from "../PostProcessParam";
1
+ import { type PostProcessStepParam, PostProcessStepType } from "../PostProcessParam";
2
2
  export interface BloomParam extends PostProcessStepParam {
3
3
  type: PostProcessStepType.Bloom;
4
4
  threshold: number;
@@ -1,4 +1,4 @@
1
- import { PostProcessStepParam, PostProcessStepType } from "../PostProcessParam";
1
+ import { type PostProcessStepParam, PostProcessStepType } from "../PostProcessParam";
2
2
  export interface DOFParam extends PostProcessStepParam {
3
3
  type: PostProcessStepType.DepthOfField;
4
4
  focus: number;
@@ -1,4 +1,4 @@
1
- import { PostProcessStepParam, PostProcessStepType } from "../PostProcessParam";
1
+ import { type PostProcessStepParam, PostProcessStepType } from "../PostProcessParam";
2
2
  export interface DenoiseParam {
3
3
  denoiseRadius: number;
4
4
  lumaPhi: number;
@@ -1,5 +1,5 @@
1
- import { ColorRepresentation } from "three/webgpu";
2
- import { PostProcessStepParam, PostProcessStepType } from "../PostProcessParam";
1
+ import type { ColorRepresentation } from "three";
2
+ import { type PostProcessStepParam, PostProcessStepType } from "../PostProcessParam";
3
3
  export interface OutlineParams extends PostProcessStepParam {
4
4
  type: PostProcessStepType.Outline;
5
5
  edgeStrength: number;
@@ -1,4 +1,4 @@
1
- import { PostProcessStepParam, PostProcessStepType } from "../PostProcessParam";
1
+ import { type PostProcessStepParam, PostProcessStepType } from "../PostProcessParam";
2
2
  export interface SSRParam extends PostProcessStepParam {
3
3
  type: PostProcessStepType.ScreenSpaceReflection;
4
4
  maxDistance: number;
@@ -1,10 +1,10 @@
1
- import { OutlineParams } from './Param/Outline';
1
+ import { type OutlineParams } from './Param/Outline';
2
2
  import { Scene, Camera, Object3D, PassNode, Node } from "three/webgpu";
3
- import { BloomParam } from "./Param/Bloom";
4
- import { DOFParam } from "./Param/DOF";
5
- import { GTAOParam } from "./Param/GTAO";
6
- import { SSRParam } from "./Param/SSR";
7
- import { DenoiseParam } from './Param/GTAO';
3
+ import { type BloomParam } from "./Param/Bloom";
4
+ import { type DOFParam } from "./Param/DOF";
5
+ import { type GTAOParam } from "./Param/GTAO";
6
+ import { type SSRParam } from "./Param/SSR";
7
+ import { type DenoiseParam } from './Param/GTAO';
8
8
  import { ShaderNodeObject, NodeRepresentation } from 'three/tsl';
9
9
  import DepthOfFieldNode from 'three/addons/tsl/display/DepthOfFieldNode.js';
10
10
  import BloomNode from 'three/examples/jsm/tsl/display/BloomNode.js';
@@ -6,13 +6,12 @@ import { Delegate } from './Delegate';
6
6
  import { CameraParam } from './Frame/Parameters/CameraParameter';
7
7
  import { AppParam } from './Frame/Parameters/AppParameter';
8
8
  import { AssetManager } from './AssetManagement/AssetManager';
9
+ /**
10
+ * Three.js应用程序主类
11
+ * 负责管理场景、视口、控制器和资源
12
+ */
9
13
  export declare class ThreeJsApp {
10
- get camera(): PerspectiveCamera | OrthographicCamera;
11
- get clock(): Clock;
12
- get world(): World;
13
- get viewport(): Viewport;
14
- get controller(): Controller;
15
- get assetManager(): AssetManager;
14
+ private animationFrameHandle;
16
15
  protected _clock: Clock;
17
16
  protected _camera: PerspectiveCamera | OrthographicCamera;
18
17
  protected _world: World;
@@ -20,18 +19,71 @@ export declare class ThreeJsApp {
20
19
  protected _controller: Controller;
21
20
  protected _assetManager: AssetManager;
22
21
  protected _tickingFunctions: Array<(delta: number) => void>;
23
- get appParam(): AppParam;
24
22
  protected _appParam: AppParam;
25
- get onCameraChangedDelegate(): Delegate<[void]>;
26
23
  protected _onCameraChangedDelegate: Delegate<[void]>;
24
+ get camera(): PerspectiveCamera | OrthographicCamera;
25
+ get clock(): Clock;
26
+ get world(): World;
27
+ get viewport(): Viewport;
28
+ get controller(): Controller;
29
+ get assetManager(): AssetManager;
30
+ get appParam(): AppParam;
31
+ get onCameraChangedDelegate(): Delegate<[void]>;
32
+ /**
33
+ * 构造ThreeJs应用程序实例
34
+ * @param appParam 应用程序参数配置
35
+ */
27
36
  constructor(appParam?: AppParam);
37
+ /**
38
+ * 构造后初始化钩子
39
+ * 按顺序初始化控制器、世界和视口
40
+ */
28
41
  protected postConstruct(): void;
42
+ /**
43
+ * 公共初始化方法
44
+ * 可由子类重写以添加自定义初始化逻辑
45
+ */
29
46
  init(): void;
47
+ /**
48
+ * 启动动画循环
49
+ * 使用延迟启动以确保所有组件完全初始化
50
+ */
51
+ protected startAnimationLoop(): void;
52
+ /**
53
+ * 每帧更新方法
54
+ * @param deltaTime 距离上一帧的时间增量(秒)
55
+ */
30
56
  protected tick(deltaTime: number): void;
57
+ /**
58
+ * 添加每帧执行的函数
59
+ * @param func 接收deltaTime参数的回调函数
60
+ */
31
61
  addTickingFunction(func: (deltaTime: number) => void): void;
62
+ /**
63
+ * 移除已注册的tick函数
64
+ * @param func 要移除的函数引用
65
+ */
32
66
  removeTickingFunction(func: (deltaTime: number) => void): void;
67
+ /**
68
+ * 销毁应用程序并清理所有资源
69
+ */
33
70
  destroy(): void;
71
+ /**
72
+ * 更新相机参数
73
+ * @param param 新的相机参数
74
+ */
34
75
  updateCamera(param: CameraParam): void;
76
+ /**
77
+ * 窗口大小改变时的处理
78
+ * @param width 新的宽度
79
+ * @param height 新的高度
80
+ */
35
81
  onWindowResize(width: number, height: number): void;
82
+ /**
83
+ * 将当前场景渲染为图片
84
+ * @param width 图片宽度,默认1024
85
+ * @param height 图片高度,默认1024
86
+ * @returns 图片的DataURL
87
+ */
36
88
  renderAsImage(width?: number, height?: number): Promise<string>;
37
89
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lythreeframe",
3
- "version": "1.2.49",
3
+ "version": "1.2.50",
4
4
  "description": "Three.js 封装",
5
5
  "main": "dist/bundle.cjs.js",
6
6
  "module": "dist/bundle.esm.js",