lythreeframe 1.2.48 → 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.
- package/dist/bundle.cjs.js +278 -138
- package/dist/bundle.esm.js +278 -140
- package/dist/index.d.ts +3 -0
- package/dist/lythreeframe/Frame/Controller.d.ts +1 -0
- package/dist/lythreeframe/Frame/Parameters/AppParameter.d.ts +2 -0
- package/dist/lythreeframe/Frame/Parameters/ControllerParameters.d.ts +2 -0
- package/dist/lythreeframe/Frame/Parameters/ViewportParameters.d.ts +1 -0
- package/dist/lythreeframe/Frame/Viewport.d.ts +7 -3
- package/dist/lythreeframe/Object/Components/Curve/CurveComponent.d.ts +35 -0
- package/dist/lythreeframe/Object/Components/Light/AmbientLight/AmbientLightComponent.d.ts +1 -1
- package/dist/lythreeframe/PostProcess/Param/AAParam.d.ts +1 -1
- package/dist/lythreeframe/PostProcess/Param/Bloom.d.ts +1 -1
- package/dist/lythreeframe/PostProcess/Param/DOF.d.ts +1 -1
- package/dist/lythreeframe/PostProcess/Param/GTAO.d.ts +1 -1
- package/dist/lythreeframe/PostProcess/Param/Outline.d.ts +2 -2
- package/dist/lythreeframe/PostProcess/Param/SSR.d.ts +1 -1
- package/dist/lythreeframe/PostProcess/WebGPUPostProcessFactory.d.ts +6 -6
- package/dist/lythreeframe/ThreeJsApp.d.ts +60 -8
- package/package.json +1 -1
package/dist/bundle.esm.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { MathUtils, Object3D, Vector3, Box3, Quaternion, Euler, Matrix4, Mesh, LoadingManager, BufferGeometry, Texture, FileLoader, Material, NearestFilter, WebGPURenderer,
|
|
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
|
-
import { pass, mrt, output, uniform, metalness, transformedNormalView
|
|
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';
|
|
4
5
|
import { dof } from 'three/addons/tsl/display/DepthOfFieldNode.js';
|
|
5
6
|
import { bloom } from 'three/examples/jsm/tsl/display/BloomNode.js';
|
|
6
7
|
import { denoise } from 'three/examples/jsm/tsl/display/DenoiseNode.js';
|
|
@@ -9,7 +10,6 @@ import { ao } from 'three/examples/jsm/tsl/display/GTAONode.js';
|
|
|
9
10
|
import { outline } from 'three/examples/jsm/tsl/display/OutlineNode.js';
|
|
10
11
|
import { smaa } from 'three/examples/jsm/tsl/display/SMAANode.js';
|
|
11
12
|
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';
|
|
@@ -1519,7 +1519,12 @@ class Viewport {
|
|
|
1519
1519
|
}
|
|
1520
1520
|
get renderer() {
|
|
1521
1521
|
if (!this._renderer) {
|
|
1522
|
-
|
|
1522
|
+
if (this._webGLRenderer) {
|
|
1523
|
+
return this._webGLRenderer;
|
|
1524
|
+
}
|
|
1525
|
+
else {
|
|
1526
|
+
throw Error("Renderer is not initialized");
|
|
1527
|
+
}
|
|
1523
1528
|
}
|
|
1524
1529
|
return this._renderer;
|
|
1525
1530
|
}
|
|
@@ -1532,6 +1537,7 @@ class Viewport {
|
|
|
1532
1537
|
constructor(app, viewportParam, rendererParam, postProcessParam) {
|
|
1533
1538
|
this._uiDom = null;
|
|
1534
1539
|
this._renderer = null;
|
|
1540
|
+
this._webGLRenderer = null;
|
|
1535
1541
|
this.labelRenderer = null;
|
|
1536
1542
|
this._app = null;
|
|
1537
1543
|
this.resizeObserver = null;
|
|
@@ -1545,6 +1551,7 @@ class Viewport {
|
|
|
1545
1551
|
if (viewportParam.elementId) {
|
|
1546
1552
|
this._outerContainer = document.getElementById(viewportParam.elementId);
|
|
1547
1553
|
}
|
|
1554
|
+
this.viewportParam = Object.assign({}, viewportParam);
|
|
1548
1555
|
this.createRenderer(rendererParam);
|
|
1549
1556
|
if (viewportParam.isLabelRendererNeeded) {
|
|
1550
1557
|
this.createLabelRenderer();
|
|
@@ -1566,7 +1573,7 @@ class Viewport {
|
|
|
1566
1573
|
this.setupPostProcess();
|
|
1567
1574
|
});
|
|
1568
1575
|
}
|
|
1569
|
-
createRenderer(rendererParam) {
|
|
1576
|
+
async createRenderer(rendererParam) {
|
|
1570
1577
|
if (this._outerContainer) {
|
|
1571
1578
|
this._canvasContainer = document.createElement("div");
|
|
1572
1579
|
this._canvasContainer.style.left = "0px";
|
|
@@ -1593,15 +1600,31 @@ class Viewport {
|
|
|
1593
1600
|
renderP.logarithmicDepthBuffer = rendererParam.logarithmicDepthBuffer;
|
|
1594
1601
|
renderP.samples = rendererParam.samples;
|
|
1595
1602
|
renderP.colorBufferType = rendererParam.colorBufferType;
|
|
1596
|
-
this.
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
element
|
|
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
|
+
}
|
|
1605
1628
|
}
|
|
1606
1629
|
}
|
|
1607
1630
|
createLabelRenderer() {
|
|
@@ -1648,97 +1671,7 @@ class Viewport {
|
|
|
1648
1671
|
this.setupPostProcess();
|
|
1649
1672
|
}
|
|
1650
1673
|
setupPostProcess() {
|
|
1651
|
-
|
|
1652
|
-
this.destroyPostProcess();
|
|
1653
|
-
this.markRenderStateDirty();
|
|
1654
|
-
return;
|
|
1655
|
-
}
|
|
1656
|
-
if (!this.postProcessing) {
|
|
1657
|
-
this.postProcessing = new PostProcessing(this.renderer);
|
|
1658
|
-
}
|
|
1659
|
-
const scenePass = WebGPUPostProcessFactory.constructScenePass(this.app.world.scene, this.app.camera);
|
|
1660
|
-
let finalNode = scenePass.getTextureNode('output');
|
|
1661
|
-
this.postProcessParam.steps.forEach((step) => {
|
|
1662
|
-
switch (step.type) {
|
|
1663
|
-
case PostProcessStepType.Bloom:
|
|
1664
|
-
{
|
|
1665
|
-
const bloomPass = WebGPUPostProcessFactory.constructBloomPass(scenePass, step);
|
|
1666
|
-
//console.log("[PostProcess] BloomPass 构建完成");
|
|
1667
|
-
finalNode = finalNode.add(bloomPass);
|
|
1668
|
-
break;
|
|
1669
|
-
}
|
|
1670
|
-
case PostProcessStepType.DepthOfField:
|
|
1671
|
-
{
|
|
1672
|
-
const dofPass = WebGPUPostProcessFactory.constructDOFPass(scenePass, step);
|
|
1673
|
-
//console.log("[PostProcess] DOFPass 构建完成");
|
|
1674
|
-
finalNode = finalNode.add(dofPass);
|
|
1675
|
-
break;
|
|
1676
|
-
}
|
|
1677
|
-
case PostProcessStepType.ScreenSpaceReflection:
|
|
1678
|
-
{
|
|
1679
|
-
console.warn("[PostProcess] SSR 目前存在技术问题,暂不支持。");
|
|
1680
|
-
// const ssrPass = WebGPUPostProcessFactory.constructSSRPass(scenePass, step as SSRParam);
|
|
1681
|
-
// console.log("[PostProcess] SSRPass 构建完成");
|
|
1682
|
-
//finalNode = blendColor(finalNode, ssrPass);
|
|
1683
|
-
break;
|
|
1684
|
-
}
|
|
1685
|
-
case PostProcessStepType.GroundTruthAmbientOcclusion:
|
|
1686
|
-
{
|
|
1687
|
-
console.warn("[PostProcess] AO 目前存在技术问题,暂不支持。");
|
|
1688
|
-
// const stepParam = step as GTAOParam
|
|
1689
|
-
// const GTAOPass = WebGPUPostProcessFactory.constructGTAOPass(scenePass, stepParam);
|
|
1690
|
-
// console.log("[PostProcess] GTAOPass 构建完成");
|
|
1691
|
-
// if (stepParam.denoised)
|
|
1692
|
-
// {
|
|
1693
|
-
// const denoiseGTAOPass = WebGPUPostProcessFactory.constructGTAODenoisePass(scenePass, GTAOPass, stepParam);
|
|
1694
|
-
// console.log("[PostProcess] GTAODenoisePass 构建完成");
|
|
1695
|
-
// finalNode = denoiseGTAOPass.mul(finalNode);
|
|
1696
|
-
// }
|
|
1697
|
-
// else
|
|
1698
|
-
// {
|
|
1699
|
-
// finalNode = GTAOPass.getTextureNode().mul(finalNode);
|
|
1700
|
-
// }
|
|
1701
|
-
break;
|
|
1702
|
-
}
|
|
1703
|
-
case PostProcessStepType.Outline:
|
|
1704
|
-
{
|
|
1705
|
-
const outlineParam = step;
|
|
1706
|
-
const outlinePass = WebGPUPostProcessFactory.constructOutlinePass(this.app.world.scene, scenePass.camera, this.outlineObjects, outlineParam);
|
|
1707
|
-
const { visibleEdge, hiddenEdge } = outlinePass;
|
|
1708
|
-
const pulsePeriod = uniform(outlineParam.pulsePeriod);
|
|
1709
|
-
const period = time.div(pulsePeriod).mul(2);
|
|
1710
|
-
const osc = oscSine(period).mul(.5).add(.5);
|
|
1711
|
-
const outlineColor = visibleEdge.mul(uniform(new Color(outlineParam.visibleEdgeColor))).add(hiddenEdge.mul(uniform(new Color(outlineParam.hiddenEdgeColor)))).mul(outlineParam.edgeStrength);
|
|
1712
|
-
const outlinePulse = pulsePeriod.greaterThan(0).select(outlineColor.mul(osc), outlineColor);
|
|
1713
|
-
// if(!this.denoiseOutlinePass)
|
|
1714
|
-
// {
|
|
1715
|
-
// this.denoiseOutlinePass = WebGPUPostProcessFactory.constructDenoisePass(this.scenePass, outlinePulse, DefaultDenoiseParam);
|
|
1716
|
-
// }
|
|
1717
|
-
// outlinePulse = this.denoiseOutlinePass.mul(outlinePulse)
|
|
1718
|
-
// finalNode = this.denoiseOutlinePass.mul(outlinePulse).add(finalNode);
|
|
1719
|
-
finalNode = outlinePulse.add(finalNode);
|
|
1720
|
-
//console.log("[PostProcess] OutlinePass 构建完成");
|
|
1721
|
-
break;
|
|
1722
|
-
}
|
|
1723
|
-
case PostProcessStepType.Antialiasing:
|
|
1724
|
-
{
|
|
1725
|
-
const aaParam = step;
|
|
1726
|
-
if (aaParam.method === "fxaa") {
|
|
1727
|
-
finalNode = WebGPUPostProcessFactory.constructFXAAPass(finalNode);
|
|
1728
|
-
//console.log("[PostProcess] FXAAPass 构建完成");
|
|
1729
|
-
}
|
|
1730
|
-
if (aaParam.method === "smaa") {
|
|
1731
|
-
finalNode = WebGPUPostProcessFactory.constructSMAAPass(finalNode);
|
|
1732
|
-
//console.log("[PostProcess] SMAAPass 构建完成");
|
|
1733
|
-
}
|
|
1734
|
-
break;
|
|
1735
|
-
}
|
|
1736
|
-
}
|
|
1737
|
-
});
|
|
1738
|
-
this.postProcessing.outputNode = finalNode;
|
|
1739
|
-
this.postProcessing.needsUpdate = true;
|
|
1740
|
-
//console.log("[PostProcess] setup complete", this.postProcessParam.steps);
|
|
1741
|
-
this.markRenderStateDirty();
|
|
1674
|
+
return;
|
|
1742
1675
|
}
|
|
1743
1676
|
updatePostProcess(steps) {
|
|
1744
1677
|
this.postProcessParam.steps = steps;
|
|
@@ -1823,7 +1756,7 @@ class Viewport {
|
|
|
1823
1756
|
return;
|
|
1824
1757
|
}
|
|
1825
1758
|
if (this.postProcessing) {
|
|
1826
|
-
this.postProcessing.
|
|
1759
|
+
this.postProcessing.renderAsync();
|
|
1827
1760
|
}
|
|
1828
1761
|
else {
|
|
1829
1762
|
this.renderer.render(this.app.world.scene, this.app.camera);
|
|
@@ -1840,7 +1773,13 @@ class Viewport {
|
|
|
1840
1773
|
await this.postProcessing.renderAsync();
|
|
1841
1774
|
}
|
|
1842
1775
|
else {
|
|
1843
|
-
|
|
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
|
+
}
|
|
1844
1783
|
}
|
|
1845
1784
|
// 检查 renderer.domElement 的尺寸
|
|
1846
1785
|
const sourceWidth = this.renderer.domElement.width;
|
|
@@ -2149,13 +2088,7 @@ class Controller {
|
|
|
2149
2088
|
this.pawn.enabled = isPawnEnabled;
|
|
2150
2089
|
}
|
|
2151
2090
|
init() {
|
|
2152
|
-
if (this.viewPort.canvas)
|
|
2153
|
-
this.viewPort.canvas.addEventListener("pointermove", this.onPointerMove);
|
|
2154
|
-
this.viewPort.canvas.addEventListener("pointerenter", this.onPointerEnter);
|
|
2155
|
-
this.viewPort.canvas.addEventListener("pointerleave", this.onPointerLeave);
|
|
2156
|
-
this.viewPort.canvas.addEventListener("pointerup", this.onPointerUp);
|
|
2157
|
-
this.viewPort.canvas.addEventListener("pointerdown", this.onPointerDown);
|
|
2158
|
-
}
|
|
2091
|
+
if (this.viewPort.canvas) ;
|
|
2159
2092
|
}
|
|
2160
2093
|
tick(deltaTime) {
|
|
2161
2094
|
this.pawn.tick(deltaTime);
|
|
@@ -2165,13 +2098,7 @@ class Controller {
|
|
|
2165
2098
|
clearTimeout(this.leftClickTimer);
|
|
2166
2099
|
this.leftClickTimer = null;
|
|
2167
2100
|
}
|
|
2168
|
-
if (this.viewPort.canvas)
|
|
2169
|
-
this.viewPort.canvas.removeEventListener("pointermove", this.onPointerMove);
|
|
2170
|
-
this.viewPort.canvas.removeEventListener("pointerenter", this.onPointerEnter);
|
|
2171
|
-
this.viewPort.canvas.removeEventListener("pointerleave", this.onPointerLeave);
|
|
2172
|
-
this.viewPort.canvas.removeEventListener("pointerup", this.onPointerUp);
|
|
2173
|
-
this.viewPort.canvas.removeEventListener("pointerdown", this.onPointerDown);
|
|
2174
|
-
}
|
|
2101
|
+
if (this.viewPort.canvas) ;
|
|
2175
2102
|
this.pawn.unpossess();
|
|
2176
2103
|
this.pawn.destroy();
|
|
2177
2104
|
this._pawn = null;
|
|
@@ -2293,6 +2220,14 @@ class Controller {
|
|
|
2293
2220
|
focusTo(targetPos, targetQuat, distance, time, onGoing = null, onFinished = null) {
|
|
2294
2221
|
this.pawn.focusTo(targetPos, targetQuat, distance, time, onGoing, onFinished);
|
|
2295
2222
|
}
|
|
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
|
+
}
|
|
2296
2231
|
}
|
|
2297
2232
|
|
|
2298
2233
|
class CameraFactory {
|
|
@@ -2318,7 +2253,7 @@ class CameraFactory {
|
|
|
2318
2253
|
catch (error) {
|
|
2319
2254
|
console.warn("[CameraFactory]Error occurred while creating camera: ", error);
|
|
2320
2255
|
console.warn("[CameraFactory]Create default perspective camera instead");
|
|
2321
|
-
return new PerspectiveCamera(50, 1, 0.1,
|
|
2256
|
+
return new PerspectiveCamera(50, 1, 0.1, 100000);
|
|
2322
2257
|
}
|
|
2323
2258
|
}
|
|
2324
2259
|
static updataCamera(param, camera) {
|
|
@@ -2332,6 +2267,7 @@ class CameraFactory {
|
|
|
2332
2267
|
camera.far = data.far;
|
|
2333
2268
|
camera.fov = data.fov;
|
|
2334
2269
|
camera.aspect = data.aspect;
|
|
2270
|
+
camera.updateProjectionMatrix();
|
|
2335
2271
|
return camera;
|
|
2336
2272
|
}
|
|
2337
2273
|
return new PerspectiveCamera(data.fov, data.aspect, data.near, data.far);
|
|
@@ -2346,6 +2282,7 @@ class CameraFactory {
|
|
|
2346
2282
|
camera.right = data.right;
|
|
2347
2283
|
camera.top = data.top;
|
|
2348
2284
|
camera.bottom = data.bottom;
|
|
2285
|
+
camera.updateProjectionMatrix();
|
|
2349
2286
|
return camera;
|
|
2350
2287
|
}
|
|
2351
2288
|
return new OrthographicCamera(data.left, data.right, data.top, data.bottom, data.near, data.far);
|
|
@@ -2366,7 +2303,7 @@ class CameraFactory {
|
|
|
2366
2303
|
|
|
2367
2304
|
const DefaultPerspectiveCameraParam = {
|
|
2368
2305
|
near: 0.1,
|
|
2369
|
-
far:
|
|
2306
|
+
far: 10000,
|
|
2370
2307
|
type: "Perspective",
|
|
2371
2308
|
fov: 50,
|
|
2372
2309
|
aspect: 1,
|
|
@@ -2898,7 +2835,14 @@ const DefaultWorldParam = {
|
|
|
2898
2835
|
levelActorClass: LevelActor,
|
|
2899
2836
|
};
|
|
2900
2837
|
|
|
2838
|
+
/** 动画循环启动延迟时间(毫秒) */
|
|
2839
|
+
const ANIMATION_START_DELAY = 100;
|
|
2840
|
+
/**
|
|
2841
|
+
* Three.js应用程序主类
|
|
2842
|
+
* 负责管理场景、视口、控制器和资源
|
|
2843
|
+
*/
|
|
2901
2844
|
class ThreeJsApp {
|
|
2845
|
+
// ========== 公共访问器 ==========
|
|
2902
2846
|
get camera() {
|
|
2903
2847
|
return this._camera;
|
|
2904
2848
|
}
|
|
@@ -2923,67 +2867,132 @@ class ThreeJsApp {
|
|
|
2923
2867
|
get onCameraChangedDelegate() {
|
|
2924
2868
|
return this._onCameraChangedDelegate;
|
|
2925
2869
|
}
|
|
2870
|
+
/**
|
|
2871
|
+
* 构造ThreeJs应用程序实例
|
|
2872
|
+
* @param appParam 应用程序参数配置
|
|
2873
|
+
*/
|
|
2926
2874
|
constructor(appParam = DefaultAppParam) {
|
|
2875
|
+
var _a, _b, _c, _d, _e, _f;
|
|
2876
|
+
// ========== 私有字段 ==========
|
|
2877
|
+
this.animationFrameHandle = 0;
|
|
2927
2878
|
this._tickingFunctions = [];
|
|
2928
2879
|
this._appParam = { viewportParam: DefaultViewportParam };
|
|
2929
2880
|
this._onCameraChangedDelegate = new Delegate();
|
|
2930
|
-
|
|
2931
|
-
this._appParam.
|
|
2932
|
-
this._appParam.
|
|
2933
|
-
this._appParam.
|
|
2934
|
-
this._appParam.
|
|
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 : {
|
|
2935
2889
|
assetManagerClass: AssetManager,
|
|
2936
2890
|
controllerClass: Controller,
|
|
2937
2891
|
worldClass: World,
|
|
2938
2892
|
viewportClass: Viewport,
|
|
2939
2893
|
};
|
|
2940
|
-
|
|
2894
|
+
// 初始化核心组件
|
|
2941
2895
|
this._clock = new Clock();
|
|
2942
2896
|
this._camera = CameraFactory.createCamera(this._appParam.cameraParam);
|
|
2943
|
-
this._world = new this._appParam.classes.worldClass(this, this._appParam.worldParam
|
|
2897
|
+
this._world = new this._appParam.classes.worldClass(this, this._appParam.worldParam);
|
|
2944
2898
|
this._viewport = new this._appParam.classes.viewportClass(this, this._appParam.viewportParam, this._appParam.renderParam, this._appParam.postProcessParam);
|
|
2945
2899
|
this._controller = new this._appParam.classes.controllerClass(this);
|
|
2946
2900
|
this._assetManager = new this._appParam.classes.assetManagerClass(this);
|
|
2947
|
-
this.viewport.renderer.setAnimationLoop(() => {
|
|
2948
|
-
const delta = this._clock.getDelta();
|
|
2949
|
-
this.tick(delta);
|
|
2950
|
-
});
|
|
2951
2901
|
this.postConstruct();
|
|
2902
|
+
this.startAnimationLoop();
|
|
2952
2903
|
}
|
|
2904
|
+
/**
|
|
2905
|
+
* 构造后初始化钩子
|
|
2906
|
+
* 按顺序初始化控制器、世界和视口
|
|
2907
|
+
*/
|
|
2953
2908
|
postConstruct() {
|
|
2954
2909
|
this.controller.init();
|
|
2955
2910
|
this.world.init();
|
|
2956
2911
|
this.viewport.init();
|
|
2957
2912
|
}
|
|
2913
|
+
/**
|
|
2914
|
+
* 公共初始化方法
|
|
2915
|
+
* 可由子类重写以添加自定义初始化逻辑
|
|
2916
|
+
*/
|
|
2958
2917
|
init() {
|
|
2959
|
-
|
|
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
|
+
*/
|
|
2960
2943
|
tick(deltaTime) {
|
|
2961
2944
|
this._controller.tick(deltaTime);
|
|
2962
2945
|
this.world.tick(deltaTime);
|
|
2946
|
+
// 执行所有注册的tick函数
|
|
2963
2947
|
this._tickingFunctions.forEach(func => {
|
|
2964
2948
|
func(deltaTime);
|
|
2965
2949
|
});
|
|
2950
|
+
// 根据配置决定是否每帧都渲染
|
|
2966
2951
|
if (this._appParam.isRenderEveryFrame) {
|
|
2967
2952
|
this.viewport.markRenderStateDirty();
|
|
2968
2953
|
}
|
|
2969
2954
|
this.viewport.render();
|
|
2970
2955
|
}
|
|
2956
|
+
/**
|
|
2957
|
+
* 添加每帧执行的函数
|
|
2958
|
+
* @param func 接收deltaTime参数的回调函数
|
|
2959
|
+
*/
|
|
2971
2960
|
addTickingFunction(func) {
|
|
2972
2961
|
this._tickingFunctions.push(func);
|
|
2973
2962
|
}
|
|
2963
|
+
/**
|
|
2964
|
+
* 移除已注册的tick函数
|
|
2965
|
+
* @param func 要移除的函数引用
|
|
2966
|
+
*/
|
|
2974
2967
|
removeTickingFunction(func) {
|
|
2975
2968
|
const index = this._tickingFunctions.indexOf(func);
|
|
2976
2969
|
if (index >= 0) {
|
|
2977
2970
|
this._tickingFunctions.splice(index, 1);
|
|
2978
2971
|
}
|
|
2979
2972
|
}
|
|
2973
|
+
/**
|
|
2974
|
+
* 销毁应用程序并清理所有资源
|
|
2975
|
+
*/
|
|
2980
2976
|
destroy() {
|
|
2977
|
+
// 停止动画循环
|
|
2978
|
+
if (this.animationFrameHandle) {
|
|
2979
|
+
cancelAnimationFrame(this.animationFrameHandle);
|
|
2980
|
+
this.animationFrameHandle = 0;
|
|
2981
|
+
}
|
|
2982
|
+
// 清理委托
|
|
2981
2983
|
this.onCameraChangedDelegate.clear();
|
|
2984
|
+
// 销毁各个组件
|
|
2982
2985
|
this.controller.destroy();
|
|
2983
2986
|
this.world.destroy();
|
|
2984
2987
|
this.viewport.destroy();
|
|
2985
2988
|
this._assetManager.clearAssets();
|
|
2989
|
+
// 清空tick函数列表
|
|
2990
|
+
this._tickingFunctions = [];
|
|
2986
2991
|
}
|
|
2992
|
+
/**
|
|
2993
|
+
* 更新相机参数
|
|
2994
|
+
* @param param 新的相机参数
|
|
2995
|
+
*/
|
|
2987
2996
|
updateCamera(param) {
|
|
2988
2997
|
const previousCam = this.camera;
|
|
2989
2998
|
this._camera = CameraFactory.updataCamera(param, this.camera);
|
|
@@ -2994,16 +3003,31 @@ class ThreeJsApp {
|
|
|
2994
3003
|
this._camera.updateProjectionMatrix();
|
|
2995
3004
|
this.viewport.markRenderStateDirty();
|
|
2996
3005
|
}
|
|
3006
|
+
/**
|
|
3007
|
+
* 窗口大小改变时的处理
|
|
3008
|
+
* @param width 新的宽度
|
|
3009
|
+
* @param height 新的高度
|
|
3010
|
+
*/
|
|
2997
3011
|
onWindowResize(width, height) {
|
|
2998
3012
|
if (this.camera instanceof PerspectiveCamera) {
|
|
2999
3013
|
this.camera.aspect = width / height;
|
|
3000
3014
|
}
|
|
3001
|
-
//
|
|
3002
|
-
// {
|
|
3003
|
-
//
|
|
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;
|
|
3004
3022
|
// }
|
|
3005
3023
|
this.camera.updateProjectionMatrix();
|
|
3006
3024
|
}
|
|
3025
|
+
/**
|
|
3026
|
+
* 将当前场景渲染为图片
|
|
3027
|
+
* @param width 图片宽度,默认1024
|
|
3028
|
+
* @param height 图片高度,默认1024
|
|
3029
|
+
* @returns 图片的DataURL
|
|
3030
|
+
*/
|
|
3007
3031
|
async renderAsImage(width = 1024, height = 1024) {
|
|
3008
3032
|
return await this.viewport.renderAsImage(width, height);
|
|
3009
3033
|
}
|
|
@@ -3179,7 +3203,7 @@ class AmbientLightActor extends Actor {
|
|
|
3179
3203
|
}
|
|
3180
3204
|
|
|
3181
3205
|
class BoxComponent extends MeshComponent {
|
|
3182
|
-
constructor(app, width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1, material = new MeshStandardMaterial(), uuid) {
|
|
3206
|
+
constructor(app, width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1, material = new MeshStandardMaterial({ color: 0x00ff00 }), uuid) {
|
|
3183
3207
|
super(app, new BoxGeometry(width, height, depth, widthSegments, heightSegments, depthSegments), material, uuid);
|
|
3184
3208
|
}
|
|
3185
3209
|
}
|
|
@@ -3326,6 +3350,120 @@ class LabelComponent extends SceneComponent {
|
|
|
3326
3350
|
// labelStyle.style.fontSize = "10px";
|
|
3327
3351
|
// labelStyle.style.pointerEvents = 'auto';
|
|
3328
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
|
+
|
|
3329
3467
|
const DefaultBloomParam = {
|
|
3330
3468
|
type: PostProcessStepType.Bloom,
|
|
3331
3469
|
threshold: 0,
|
|
@@ -3600,4 +3738,4 @@ class TransformGizmo extends Pawn {
|
|
|
3600
3738
|
}
|
|
3601
3739
|
}
|
|
3602
3740
|
|
|
3603
|
-
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 };
|
|
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";
|
|
@@ -58,6 +60,7 @@ export { DefaultSSRParam } from "./lythreeframe/PostProcess/Param/SSR";
|
|
|
58
60
|
export type { SSRParam } from "./lythreeframe/PostProcess/Param/SSR";
|
|
59
61
|
export { DefaultAAParams } from "./lythreeframe/PostProcess/Param/AAParam";
|
|
60
62
|
export type { AAParams } from "./lythreeframe/PostProcess/Param/AAParam";
|
|
63
|
+
export { Pawn } from "./lythreeframe/Object/PawnV2/Pawn";
|
|
61
64
|
export { Orbital } from "./lythreeframe/Object/PawnV2/Oribital";
|
|
62
65
|
export { FirstPerson } from "./lythreeframe/Object/PawnV2/FirstPerson";
|
|
63
66
|
export type { ITransforming } from "./lythreeframe/Object/PawnV2/TransformControl";
|
|
@@ -40,4 +40,5 @@ export declare class Controller {
|
|
|
40
40
|
getHitResultUnderCursor(): Intersection | null;
|
|
41
41
|
getHitResultFromScreenPoint(x: number, y: number): Intersection | null;
|
|
42
42
|
focusTo(targetPos: Vector3, targetQuat: Quaternion | Euler, distance: number, time: number, onGoing?: (() => void) | null, onFinished?: (() => void) | null): void;
|
|
43
|
+
setPawn(pawn: Pawn): void;
|
|
43
44
|
}
|
|
@@ -7,6 +7,7 @@ import { ViewportParam } from "./ViewportParameters";
|
|
|
7
7
|
import { AssetManager } from "../../AssetManagement/AssetManager";
|
|
8
8
|
import { PostProcessParam } from "../../PostProcess/PostProcessParam";
|
|
9
9
|
import { RendererParameters } from "./RendererParameters";
|
|
10
|
+
import { ControllerParameters } from "./ControllerParameters";
|
|
10
11
|
export interface AppClass {
|
|
11
12
|
assetManagerClass: typeof AssetManager;
|
|
12
13
|
controllerClass: typeof Controller;
|
|
@@ -19,6 +20,7 @@ export interface AppParam {
|
|
|
19
20
|
postProcessParam?: PostProcessParam;
|
|
20
21
|
worldParam?: WorldParam;
|
|
21
22
|
viewportParam: ViewportParam;
|
|
23
|
+
controllerParam?: ControllerParameters;
|
|
22
24
|
classes?: AppClass;
|
|
23
25
|
isRenderEveryFrame?: boolean;
|
|
24
26
|
}
|