lythreeframe 1.2.52 → 1.2.53
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 +492 -354
- package/dist/bundle.esm.js +492 -356
- package/dist/index.d.ts +3 -1
- package/dist/lythreeframe/AssetManagement/AssetDefines.d.ts +59 -0
- package/dist/lythreeframe/AssetManagement/AssetPointer/AssetPointer.d.ts +14 -3
- package/dist/lythreeframe/AssetManagement/AssetPointer/Assets/MaterialAssetPointer.d.ts +15 -2
- package/dist/lythreeframe/Container/SmartPointer.d.ts +5 -0
- package/dist/lythreeframe/Frame/Controller.d.ts +59 -14
- package/dist/lythreeframe/Frame/Rendering/PostProcess.d.ts +23 -0
- package/dist/lythreeframe/Frame/Viewport.d.ts +2 -3
- package/package.json +1 -1
package/dist/bundle.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MathUtils, Object3D, Vector3, Box3, Quaternion, Euler, Matrix4, Mesh, LoadingManager, BufferGeometry, Texture, FileLoader, Material, NearestFilter,
|
|
1
|
+
import { MathUtils, Object3D, Vector3, Box3, Quaternion, Euler, Matrix4, Mesh, LoadingManager, BufferGeometry, Texture, FileLoader, Material, NearestFilter, PostProcessing, Color, WebGPURenderer, 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
3
|
import { pass, mrt, output, uniform, metalness, transformedNormalView, time, oscSine } from 'three/tsl';
|
|
4
4
|
import { dof } from 'three/addons/tsl/display/DepthOfFieldNode.js';
|
|
@@ -892,32 +892,48 @@ class TSmartPointer {
|
|
|
892
892
|
getRefCount() {
|
|
893
893
|
return this.referenceCount;
|
|
894
894
|
}
|
|
895
|
+
isValid() {
|
|
896
|
+
return this.value !== null;
|
|
897
|
+
}
|
|
895
898
|
addRef(count = 1) {
|
|
896
899
|
if (this.value !== null) {
|
|
897
900
|
this.referenceCount += count;
|
|
898
901
|
}
|
|
899
902
|
}
|
|
900
903
|
release() {
|
|
901
|
-
if (this.value !== null) {
|
|
904
|
+
if (this.value !== null && this.referenceCount > 0) {
|
|
902
905
|
this.referenceCount--;
|
|
903
|
-
//console.log(`Reference count decreased to: ${this.referenceCount}`);
|
|
904
906
|
if (this.referenceCount === 0) {
|
|
905
|
-
|
|
906
|
-
this.value = null;
|
|
907
|
+
this.dispose();
|
|
907
908
|
}
|
|
908
909
|
}
|
|
909
910
|
}
|
|
910
911
|
forceRelease() {
|
|
911
912
|
if (this.value !== null) {
|
|
912
|
-
this.
|
|
913
|
+
this.dispose();
|
|
913
914
|
this.referenceCount = 0;
|
|
914
915
|
}
|
|
915
916
|
}
|
|
917
|
+
/**
|
|
918
|
+
* 子类覆盖此方法以执行清理逻辑
|
|
919
|
+
*/
|
|
920
|
+
dispose() {
|
|
921
|
+
this.value = null;
|
|
922
|
+
}
|
|
916
923
|
getValue() {
|
|
917
924
|
return this.value;
|
|
918
925
|
}
|
|
919
926
|
}
|
|
920
927
|
|
|
928
|
+
/**
|
|
929
|
+
* userData 键名常量
|
|
930
|
+
*/
|
|
931
|
+
const ASSET_POINTER_KEY = 'assetPointer';
|
|
932
|
+
const EDITOR_ASSET_ID_KEY = 'editorAssetId';
|
|
933
|
+
/**
|
|
934
|
+
* Three.js 资源的智能指针
|
|
935
|
+
* 管理 BufferGeometry、Material、Texture 的生命周期
|
|
936
|
+
*/
|
|
921
937
|
class TAssetPointer extends TSmartPointer {
|
|
922
938
|
get uuid() {
|
|
923
939
|
return this._uuid;
|
|
@@ -925,40 +941,32 @@ class TAssetPointer extends TSmartPointer {
|
|
|
925
941
|
constructor(value, referenceCount = 0) {
|
|
926
942
|
super(value, referenceCount);
|
|
927
943
|
this._uuid = value.uuid;
|
|
928
|
-
value.userData[
|
|
944
|
+
value.userData[ASSET_POINTER_KEY] = this;
|
|
929
945
|
}
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
// setTimeout(() => {
|
|
935
|
-
// this.value!.dispose();
|
|
936
|
-
// this.value = null;
|
|
937
|
-
// }, 0);
|
|
938
|
-
// }
|
|
939
|
-
// }
|
|
940
|
-
// console.log("realease", this)
|
|
941
|
-
}
|
|
942
|
-
forceRelease() {
|
|
943
|
-
console.log("forceRelease", this);
|
|
946
|
+
/**
|
|
947
|
+
* 释放资源,清理 userData 并调用 Three.js 的 dispose
|
|
948
|
+
*/
|
|
949
|
+
dispose() {
|
|
944
950
|
if (this.value) {
|
|
945
|
-
|
|
946
|
-
|
|
951
|
+
// 清理 userData 中的引用
|
|
952
|
+
if (this.value.userData) {
|
|
953
|
+
delete this.value.userData[ASSET_POINTER_KEY];
|
|
954
|
+
delete this.value.userData[EDITOR_ASSET_ID_KEY];
|
|
947
955
|
}
|
|
956
|
+
// 调用 Three.js 资源的 dispose 方法
|
|
948
957
|
if (typeof this.value.dispose === "function") {
|
|
949
|
-
|
|
950
|
-
this.value.dispose();
|
|
951
|
-
this.value = null;
|
|
952
|
-
}, 0);
|
|
958
|
+
this.value.dispose();
|
|
953
959
|
}
|
|
954
|
-
setTimeout(() => {
|
|
955
|
-
//this.value = null;
|
|
956
|
-
this.referenceCount = 0;
|
|
957
|
-
}, 0);
|
|
958
960
|
}
|
|
961
|
+
// 调用父类清理 value = null
|
|
962
|
+
super.dispose();
|
|
959
963
|
}
|
|
960
964
|
}
|
|
961
965
|
|
|
966
|
+
/**
|
|
967
|
+
* 材质资产指针
|
|
968
|
+
* 管理材质及其关联的纹理引用
|
|
969
|
+
*/
|
|
962
970
|
class MaterialAssetPointer extends TAssetPointer {
|
|
963
971
|
constructor(value, usedTextures, referenceCount = 0) {
|
|
964
972
|
super(value, referenceCount);
|
|
@@ -967,41 +975,57 @@ class MaterialAssetPointer extends TAssetPointer {
|
|
|
967
975
|
get texturePointers() {
|
|
968
976
|
return this.textures;
|
|
969
977
|
}
|
|
978
|
+
/**
|
|
979
|
+
* 设置材质的纹理属性
|
|
980
|
+
*/
|
|
970
981
|
setTexture(name, texturePtr) {
|
|
971
|
-
|
|
972
|
-
|
|
982
|
+
const mat = this.getValue();
|
|
983
|
+
const texture = texturePtr.getValue();
|
|
973
984
|
if (!texture) {
|
|
974
985
|
throw new Error("Texture is null");
|
|
975
986
|
}
|
|
976
987
|
if (!mat) {
|
|
977
988
|
throw new Error("Material is null");
|
|
978
989
|
}
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
990
|
+
const oldTexture = this.textures.get(name);
|
|
991
|
+
if (oldTexture !== texturePtr) {
|
|
992
|
+
// 释放旧纹理引用
|
|
993
|
+
if (oldTexture) {
|
|
994
|
+
oldTexture.release();
|
|
995
|
+
}
|
|
996
|
+
// 设置新纹理
|
|
984
997
|
this.textures.set(name, texturePtr);
|
|
985
|
-
|
|
986
|
-
matAny[name] = texture;
|
|
998
|
+
mat[name] = texture;
|
|
987
999
|
texturePtr.addRef();
|
|
988
1000
|
mat.needsUpdate = true;
|
|
989
1001
|
}
|
|
990
|
-
catch (e) {
|
|
991
|
-
throw e;
|
|
992
|
-
}
|
|
993
1002
|
}
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
1003
|
+
/**
|
|
1004
|
+
* 移除纹理属性
|
|
1005
|
+
*/
|
|
1006
|
+
removeTexture(name) {
|
|
1007
|
+
const mat = this.getValue();
|
|
1008
|
+
const oldTexture = this.textures.get(name);
|
|
1009
|
+
if (oldTexture) {
|
|
1010
|
+
oldTexture.release();
|
|
1011
|
+
this.textures.delete(name);
|
|
1012
|
+
if (mat) {
|
|
1013
|
+
mat[name] = null;
|
|
1014
|
+
mat.needsUpdate = true;
|
|
1015
|
+
}
|
|
997
1016
|
}
|
|
998
|
-
super.release();
|
|
999
1017
|
}
|
|
1000
|
-
|
|
1001
|
-
|
|
1018
|
+
/**
|
|
1019
|
+
* 释放材质时同时释放所有关联的纹理引用
|
|
1020
|
+
*/
|
|
1021
|
+
dispose() {
|
|
1022
|
+
// 释放所有纹理引用
|
|
1023
|
+
for (const texture of this.textures.values()) {
|
|
1002
1024
|
texture.release();
|
|
1003
1025
|
}
|
|
1004
|
-
|
|
1026
|
+
this.textures.clear();
|
|
1027
|
+
// 调用父类清理材质
|
|
1028
|
+
super.dispose();
|
|
1005
1029
|
}
|
|
1006
1030
|
}
|
|
1007
1031
|
|
|
@@ -1214,6 +1238,54 @@ class AssetManager {
|
|
|
1214
1238
|
}
|
|
1215
1239
|
}
|
|
1216
1240
|
|
|
1241
|
+
/**
|
|
1242
|
+
* 资产类别 - 用于底层资产管理
|
|
1243
|
+
*/
|
|
1244
|
+
var AssetCategory;
|
|
1245
|
+
(function (AssetCategory) {
|
|
1246
|
+
AssetCategory["Geometry"] = "geometry";
|
|
1247
|
+
AssetCategory["Material"] = "material";
|
|
1248
|
+
AssetCategory["Texture"] = "texture";
|
|
1249
|
+
AssetCategory["Actor"] = "actor";
|
|
1250
|
+
AssetCategory["ActorManager"] = "actorManager";
|
|
1251
|
+
AssetCategory["Level"] = "level";
|
|
1252
|
+
AssetCategory["HTML"] = "html";
|
|
1253
|
+
AssetCategory["Code"] = "code";
|
|
1254
|
+
AssetCategory["Undefined"] = "undefined";
|
|
1255
|
+
})(AssetCategory || (AssetCategory = {}));
|
|
1256
|
+
/**
|
|
1257
|
+
* 资产加载状态
|
|
1258
|
+
*/
|
|
1259
|
+
var AssetLoadState;
|
|
1260
|
+
(function (AssetLoadState) {
|
|
1261
|
+
AssetLoadState["Unloaded"] = "unloaded";
|
|
1262
|
+
AssetLoadState["Loading"] = "loading";
|
|
1263
|
+
AssetLoadState["Loaded"] = "loaded";
|
|
1264
|
+
AssetLoadState["Error"] = "error";
|
|
1265
|
+
})(AssetLoadState || (AssetLoadState = {}));
|
|
1266
|
+
/**
|
|
1267
|
+
* 引用者类型
|
|
1268
|
+
*/
|
|
1269
|
+
var ReferenceType;
|
|
1270
|
+
(function (ReferenceType) {
|
|
1271
|
+
ReferenceType["Actor"] = "actor";
|
|
1272
|
+
ReferenceType["Component"] = "component";
|
|
1273
|
+
ReferenceType["Material"] = "material";
|
|
1274
|
+
ReferenceType["Level"] = "level";
|
|
1275
|
+
ReferenceType["AssetPointer"] = "assetPointer";
|
|
1276
|
+
ReferenceType["External"] = "external";
|
|
1277
|
+
})(ReferenceType || (ReferenceType = {}));
|
|
1278
|
+
/**
|
|
1279
|
+
* @deprecated 使用 AssetCategory 替代
|
|
1280
|
+
*/
|
|
1281
|
+
var AssetType;
|
|
1282
|
+
(function (AssetType) {
|
|
1283
|
+
AssetType[AssetType["geometry"] = 1] = "geometry";
|
|
1284
|
+
AssetType[AssetType["material"] = 2] = "material";
|
|
1285
|
+
AssetType[AssetType["texture"] = 3] = "texture";
|
|
1286
|
+
AssetType[AssetType["undefined"] = -1] = "undefined";
|
|
1287
|
+
})(AssetType || (AssetType = {}));
|
|
1288
|
+
|
|
1217
1289
|
class Delegate {
|
|
1218
1290
|
constructor() {
|
|
1219
1291
|
this.functions = [];
|
|
@@ -1473,6 +1545,142 @@ class WebGPUPostProcessFactory {
|
|
|
1473
1545
|
}
|
|
1474
1546
|
}
|
|
1475
1547
|
|
|
1548
|
+
class PostProcessManager {
|
|
1549
|
+
constructor(renderer, scene, camera, postProcessParam, onDirtyCallback) {
|
|
1550
|
+
this.postProcessing = null;
|
|
1551
|
+
this.outlineObjects = [];
|
|
1552
|
+
this.onDirtyCallback = null;
|
|
1553
|
+
this.renderer = renderer;
|
|
1554
|
+
this.scene = scene;
|
|
1555
|
+
this.camera = camera;
|
|
1556
|
+
this.postProcessParam = Object.assign({}, postProcessParam);
|
|
1557
|
+
this.onDirtyCallback = onDirtyCallback !== null && onDirtyCallback !== void 0 ? onDirtyCallback : null;
|
|
1558
|
+
}
|
|
1559
|
+
get processing() {
|
|
1560
|
+
return this.postProcessing;
|
|
1561
|
+
}
|
|
1562
|
+
updateCamera(camera) {
|
|
1563
|
+
this.camera = camera;
|
|
1564
|
+
}
|
|
1565
|
+
setup() {
|
|
1566
|
+
if (this.postProcessParam.steps.length === 0) {
|
|
1567
|
+
this.destroy();
|
|
1568
|
+
this.markDirty();
|
|
1569
|
+
return;
|
|
1570
|
+
}
|
|
1571
|
+
if (!this.postProcessing) {
|
|
1572
|
+
this.postProcessing = new PostProcessing(this.renderer);
|
|
1573
|
+
}
|
|
1574
|
+
const scenePass = WebGPUPostProcessFactory.constructScenePass(this.scene, this.camera);
|
|
1575
|
+
let finalNode = scenePass.getTextureNode('output');
|
|
1576
|
+
this.postProcessParam.steps.forEach((step) => {
|
|
1577
|
+
switch (step.type) {
|
|
1578
|
+
case PostProcessStepType.Bloom:
|
|
1579
|
+
{
|
|
1580
|
+
const bloomPass = WebGPUPostProcessFactory.constructBloomPass(scenePass, step);
|
|
1581
|
+
finalNode = finalNode.add(bloomPass);
|
|
1582
|
+
break;
|
|
1583
|
+
}
|
|
1584
|
+
case PostProcessStepType.DepthOfField:
|
|
1585
|
+
{
|
|
1586
|
+
const dofPass = WebGPUPostProcessFactory.constructDOFPass(scenePass, step);
|
|
1587
|
+
finalNode = finalNode.add(dofPass);
|
|
1588
|
+
break;
|
|
1589
|
+
}
|
|
1590
|
+
case PostProcessStepType.ScreenSpaceReflection:
|
|
1591
|
+
{
|
|
1592
|
+
console.warn("[PostProcess] SSR 目前存在技术问题,暂不支持。");
|
|
1593
|
+
break;
|
|
1594
|
+
}
|
|
1595
|
+
case PostProcessStepType.GroundTruthAmbientOcclusion:
|
|
1596
|
+
{
|
|
1597
|
+
console.warn("[PostProcess] AO 目前存在技术问题,暂不支持。");
|
|
1598
|
+
break;
|
|
1599
|
+
}
|
|
1600
|
+
case PostProcessStepType.Outline:
|
|
1601
|
+
{
|
|
1602
|
+
const outlineParam = step;
|
|
1603
|
+
const outlinePass = WebGPUPostProcessFactory.constructOutlinePass(this.scene, scenePass.camera, this.outlineObjects, outlineParam);
|
|
1604
|
+
const { visibleEdge, hiddenEdge } = outlinePass;
|
|
1605
|
+
const pulsePeriod = uniform(outlineParam.pulsePeriod);
|
|
1606
|
+
const period = time.div(pulsePeriod).mul(2);
|
|
1607
|
+
const osc = oscSine(period).mul(.5).add(.5);
|
|
1608
|
+
const outlineColor = visibleEdge
|
|
1609
|
+
.mul(uniform(new Color(outlineParam.visibleEdgeColor)))
|
|
1610
|
+
.add(hiddenEdge.mul(uniform(new Color(outlineParam.hiddenEdgeColor))))
|
|
1611
|
+
.mul(outlineParam.edgeStrength);
|
|
1612
|
+
const outlinePulse = pulsePeriod.greaterThan(0).select(outlineColor.mul(osc), outlineColor);
|
|
1613
|
+
finalNode = outlinePulse.add(finalNode);
|
|
1614
|
+
break;
|
|
1615
|
+
}
|
|
1616
|
+
case PostProcessStepType.Antialiasing:
|
|
1617
|
+
{
|
|
1618
|
+
const aaParam = step;
|
|
1619
|
+
if (aaParam.method === "fxaa") {
|
|
1620
|
+
finalNode = WebGPUPostProcessFactory.constructFXAAPass(finalNode);
|
|
1621
|
+
}
|
|
1622
|
+
if (aaParam.method === "smaa") {
|
|
1623
|
+
finalNode = WebGPUPostProcessFactory.constructSMAAPass(finalNode);
|
|
1624
|
+
}
|
|
1625
|
+
break;
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
});
|
|
1629
|
+
this.postProcessing.outputNode = finalNode;
|
|
1630
|
+
this.postProcessing.needsUpdate = true;
|
|
1631
|
+
this.markDirty();
|
|
1632
|
+
}
|
|
1633
|
+
updateSteps(steps) {
|
|
1634
|
+
this.postProcessParam.steps = steps;
|
|
1635
|
+
this.setup();
|
|
1636
|
+
}
|
|
1637
|
+
addOutlineObject(obj) {
|
|
1638
|
+
if (!this.outlineObjects.includes(obj)) {
|
|
1639
|
+
this.outlineObjects.push(obj);
|
|
1640
|
+
}
|
|
1641
|
+
this.markDirty();
|
|
1642
|
+
}
|
|
1643
|
+
setOutlineObjects(objects) {
|
|
1644
|
+
this.outlineObjects.length = 0;
|
|
1645
|
+
this.outlineObjects.push(...objects);
|
|
1646
|
+
this.markDirty();
|
|
1647
|
+
}
|
|
1648
|
+
removeOutlineObject(obj) {
|
|
1649
|
+
const index = this.outlineObjects.indexOf(obj);
|
|
1650
|
+
if (index > -1) {
|
|
1651
|
+
this.outlineObjects.splice(index, 1);
|
|
1652
|
+
}
|
|
1653
|
+
this.markDirty();
|
|
1654
|
+
}
|
|
1655
|
+
render() {
|
|
1656
|
+
if (this.postProcessing) {
|
|
1657
|
+
this.postProcessing.render();
|
|
1658
|
+
return true;
|
|
1659
|
+
}
|
|
1660
|
+
console.log("render false");
|
|
1661
|
+
return false;
|
|
1662
|
+
}
|
|
1663
|
+
async renderAsync() {
|
|
1664
|
+
if (this.postProcessing) {
|
|
1665
|
+
await this.postProcessing.renderAsync();
|
|
1666
|
+
return true;
|
|
1667
|
+
}
|
|
1668
|
+
return false;
|
|
1669
|
+
}
|
|
1670
|
+
destroy() {
|
|
1671
|
+
this.outlineObjects = [];
|
|
1672
|
+
if (this.postProcessing) {
|
|
1673
|
+
this.postProcessing.dispose();
|
|
1674
|
+
this.postProcessing = null;
|
|
1675
|
+
}
|
|
1676
|
+
}
|
|
1677
|
+
markDirty() {
|
|
1678
|
+
if (this.onDirtyCallback) {
|
|
1679
|
+
this.onDirtyCallback();
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
|
|
1476
1684
|
class Viewport {
|
|
1477
1685
|
get uiDom() {
|
|
1478
1686
|
return this._uiDom;
|
|
@@ -1504,8 +1712,7 @@ class Viewport {
|
|
|
1504
1712
|
this._outerContainer = null;
|
|
1505
1713
|
this._canvasContainer = null;
|
|
1506
1714
|
this.isRenderStateDirty = true;
|
|
1507
|
-
this.
|
|
1508
|
-
this.outlineObjects = [];
|
|
1715
|
+
this.postProcessManager = null;
|
|
1509
1716
|
this.postProcessParam = Object.assign({}, postProcessParam);
|
|
1510
1717
|
this._app = app;
|
|
1511
1718
|
if (viewportParam.elementId) {
|
|
@@ -1529,7 +1736,10 @@ class Viewport {
|
|
|
1529
1736
|
this.resizeObserver.observe(this._outerContainer);
|
|
1530
1737
|
}
|
|
1531
1738
|
this.app.onCameraChangedDelegate.add(() => {
|
|
1532
|
-
this.
|
|
1739
|
+
if (this.postProcessManager) {
|
|
1740
|
+
this.postProcessManager.updateCamera(this.app.camera);
|
|
1741
|
+
this.postProcessManager.setup();
|
|
1742
|
+
}
|
|
1533
1743
|
});
|
|
1534
1744
|
}
|
|
1535
1745
|
createRenderer(rendererParam) {
|
|
@@ -1614,159 +1824,39 @@ class Viewport {
|
|
|
1614
1824
|
this.setupPostProcess();
|
|
1615
1825
|
}
|
|
1616
1826
|
setupPostProcess() {
|
|
1617
|
-
if (this.
|
|
1618
|
-
this.
|
|
1619
|
-
this.markRenderStateDirty();
|
|
1620
|
-
return;
|
|
1621
|
-
}
|
|
1622
|
-
if (!this.postProcessing) {
|
|
1623
|
-
this.postProcessing = new PostProcessing(this.renderer);
|
|
1827
|
+
if (!this.postProcessManager) {
|
|
1828
|
+
this.postProcessManager = new PostProcessManager(this.renderer, this.app.world.scene, this.app.camera, this.postProcessParam, () => this.markRenderStateDirty());
|
|
1624
1829
|
}
|
|
1625
|
-
|
|
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();
|
|
1830
|
+
this.postProcessManager.setup();
|
|
1708
1831
|
}
|
|
1709
1832
|
updatePostProcess(steps) {
|
|
1710
|
-
this.
|
|
1711
|
-
|
|
1833
|
+
if (this.postProcessManager) {
|
|
1834
|
+
this.postProcessManager.updateSteps(steps);
|
|
1835
|
+
}
|
|
1712
1836
|
}
|
|
1713
1837
|
updateRendererSettings(data) {
|
|
1714
1838
|
this.createRenderer(data);
|
|
1715
1839
|
this.markRenderStateDirty();
|
|
1716
1840
|
}
|
|
1717
|
-
// updateBloomPass(params: BloomParam)
|
|
1718
|
-
// {
|
|
1719
|
-
// this.postProcessParam.bloom = { ...params };
|
|
1720
|
-
// this.setupPostProcess();
|
|
1721
|
-
// }
|
|
1722
|
-
// updateGTAOParam(params: GTAOParam)
|
|
1723
|
-
// {
|
|
1724
|
-
// this.postProcessParam.gtao = { ...params };
|
|
1725
|
-
// this.setupPostProcess();
|
|
1726
|
-
// }
|
|
1727
|
-
// updateDOFParam(params: DOFParam)
|
|
1728
|
-
// {
|
|
1729
|
-
// this.postProcessParam.dof = { ...params };
|
|
1730
|
-
// this.setupPostProcess();
|
|
1731
|
-
// }
|
|
1732
|
-
// updateSSRParam(params: SSRParam)
|
|
1733
|
-
// {
|
|
1734
|
-
// this.postProcessParam.ssr = { ...params };
|
|
1735
|
-
// this.setupPostProcess();
|
|
1736
|
-
// }
|
|
1737
|
-
// updateOutlineParam(params: OutlineParams)
|
|
1738
|
-
// {
|
|
1739
|
-
// this.postProcessParam.outline = { ...params }
|
|
1740
|
-
// this.setupPostProcess();
|
|
1741
|
-
// }
|
|
1742
|
-
// updateAAParam(params: AAParams)
|
|
1743
|
-
// {
|
|
1744
|
-
// this.postProcessParam.aa = { ...params };
|
|
1745
|
-
// this.setupPostProcess();
|
|
1746
|
-
// }
|
|
1747
1841
|
addOutlineObject(obj) {
|
|
1748
|
-
if (
|
|
1749
|
-
this.
|
|
1842
|
+
if (this.postProcessManager) {
|
|
1843
|
+
this.postProcessManager.addOutlineObject(obj);
|
|
1750
1844
|
}
|
|
1751
|
-
this.markRenderStateDirty();
|
|
1752
1845
|
}
|
|
1753
1846
|
setOutlineObjects(objects) {
|
|
1754
|
-
this.
|
|
1755
|
-
|
|
1756
|
-
|
|
1847
|
+
if (this.postProcessManager) {
|
|
1848
|
+
this.postProcessManager.setOutlineObjects(objects);
|
|
1849
|
+
}
|
|
1757
1850
|
}
|
|
1758
1851
|
removeOutlineObject(obj) {
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
this.outlineObjects.splice(index, 1);
|
|
1852
|
+
if (this.postProcessManager) {
|
|
1853
|
+
this.postProcessManager.removeOutlineObject(obj);
|
|
1762
1854
|
}
|
|
1763
|
-
this.markRenderStateDirty();
|
|
1764
1855
|
}
|
|
1765
1856
|
destroyPostProcess() {
|
|
1766
|
-
this.
|
|
1767
|
-
|
|
1768
|
-
this.
|
|
1769
|
-
this.postProcessing = null;
|
|
1857
|
+
if (this.postProcessManager) {
|
|
1858
|
+
this.postProcessManager.destroy();
|
|
1859
|
+
this.postProcessManager = null;
|
|
1770
1860
|
}
|
|
1771
1861
|
}
|
|
1772
1862
|
onWindowResize() {
|
|
@@ -1786,11 +1876,10 @@ class Viewport {
|
|
|
1786
1876
|
}
|
|
1787
1877
|
render() {
|
|
1788
1878
|
if (!this.isRenderStateDirty) {
|
|
1879
|
+
console.log("render clean retrn");
|
|
1789
1880
|
return;
|
|
1790
1881
|
}
|
|
1791
|
-
if (this.
|
|
1792
|
-
this.postProcessing.render();
|
|
1793
|
-
}
|
|
1882
|
+
if (this.postProcessManager && this.postProcessManager.render()) ;
|
|
1794
1883
|
else {
|
|
1795
1884
|
this.renderer.render(this.app.world.scene, this.app.camera);
|
|
1796
1885
|
}
|
|
@@ -1800,42 +1889,40 @@ class Viewport {
|
|
|
1800
1889
|
this.isRenderStateDirty = false;
|
|
1801
1890
|
}
|
|
1802
1891
|
async renderAsImage(width = 1024, height = 1024) {
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
await this.postProcessing.renderAsync();
|
|
1807
|
-
}
|
|
1808
|
-
else {
|
|
1809
|
-
await this.renderer.renderAsync(this.app.world.scene, this.app.camera);
|
|
1810
|
-
}
|
|
1811
|
-
// 检查 renderer.domElement 的尺寸
|
|
1812
|
-
const sourceWidth = this.renderer.domElement.width;
|
|
1813
|
-
const sourceHeight = this.renderer.domElement.height;
|
|
1814
|
-
// 如果源尺寸为0,则使用容器尺寸
|
|
1815
|
-
let actualWidth = sourceWidth || width;
|
|
1816
|
-
let actualHeight = sourceHeight || height;
|
|
1817
|
-
if (actualWidth <= 0 || actualHeight <= 0) {
|
|
1818
|
-
// 如果仍然无效,则使用默认值
|
|
1819
|
-
actualWidth = width;
|
|
1820
|
-
actualHeight = height;
|
|
1821
|
-
}
|
|
1822
|
-
const offscreenCanvas = document.createElement('canvas');
|
|
1823
|
-
offscreenCanvas.width = width;
|
|
1824
|
-
offscreenCanvas.height = height;
|
|
1825
|
-
const context = offscreenCanvas.getContext('2d');
|
|
1826
|
-
if (!context) {
|
|
1827
|
-
throw Error("Can not create context");
|
|
1828
|
-
}
|
|
1829
|
-
// 使用实际尺寸进行绘制
|
|
1830
|
-
context.drawImage(this.renderer.domElement, 0, 0, actualWidth, actualHeight, 0, 0, width, height);
|
|
1831
|
-
const ret = offscreenCanvas.toDataURL('image/jpeg');
|
|
1832
|
-
offscreenCanvas.remove();
|
|
1833
|
-
resolve(ret);
|
|
1892
|
+
try {
|
|
1893
|
+
if (this.postProcessManager && await this.postProcessManager.renderAsync()) {
|
|
1894
|
+
// Post processing rendered
|
|
1834
1895
|
}
|
|
1835
|
-
|
|
1836
|
-
|
|
1896
|
+
else {
|
|
1897
|
+
await this.renderer.renderAsync(this.app.world.scene, this.app.camera);
|
|
1837
1898
|
}
|
|
1838
|
-
|
|
1899
|
+
// 检查 renderer.domElement 的尺寸
|
|
1900
|
+
const sourceWidth = this.renderer.domElement.width;
|
|
1901
|
+
const sourceHeight = this.renderer.domElement.height;
|
|
1902
|
+
// 如果源尺寸为0,则使用容器尺寸
|
|
1903
|
+
let actualWidth = sourceWidth || width;
|
|
1904
|
+
let actualHeight = sourceHeight || height;
|
|
1905
|
+
if (actualWidth <= 0 || actualHeight <= 0) {
|
|
1906
|
+
// 如果仍然无效,则使用默认值
|
|
1907
|
+
actualWidth = width;
|
|
1908
|
+
actualHeight = height;
|
|
1909
|
+
}
|
|
1910
|
+
const offscreenCanvas = document.createElement('canvas');
|
|
1911
|
+
offscreenCanvas.width = width;
|
|
1912
|
+
offscreenCanvas.height = height;
|
|
1913
|
+
const context = offscreenCanvas.getContext('2d');
|
|
1914
|
+
if (!context) {
|
|
1915
|
+
throw Error("Can not create context");
|
|
1916
|
+
}
|
|
1917
|
+
// 使用实际尺寸进行绘制
|
|
1918
|
+
context.drawImage(this.renderer.domElement, 0, 0, actualWidth, actualHeight, 0, 0, width, height);
|
|
1919
|
+
const ret = offscreenCanvas.toDataURL('image/jpeg');
|
|
1920
|
+
offscreenCanvas.remove();
|
|
1921
|
+
return ret;
|
|
1922
|
+
}
|
|
1923
|
+
catch (error) {
|
|
1924
|
+
return "";
|
|
1925
|
+
}
|
|
1839
1926
|
}
|
|
1840
1927
|
setAlpha(alpha) {
|
|
1841
1928
|
if (!this._renderer) {
|
|
@@ -1886,7 +1973,6 @@ class Viewport {
|
|
|
1886
1973
|
this._renderer.stencil = stencil;
|
|
1887
1974
|
}
|
|
1888
1975
|
destroy() {
|
|
1889
|
-
var _a;
|
|
1890
1976
|
this.destroyPostProcess();
|
|
1891
1977
|
this.renderer.setAnimationLoop(null);
|
|
1892
1978
|
if (this.resizeObserver) {
|
|
@@ -1902,11 +1988,8 @@ class Viewport {
|
|
|
1902
1988
|
this._renderer.dispose();
|
|
1903
1989
|
this._renderer = null;
|
|
1904
1990
|
}
|
|
1905
|
-
(_a = this.postProcessing) === null || _a === void 0 ? void 0 : _a.dispose();
|
|
1906
1991
|
this._outerContainer = null;
|
|
1907
1992
|
this._app = null;
|
|
1908
|
-
this._renderer = null;
|
|
1909
|
-
this.outlineObjects = [];
|
|
1910
1993
|
}
|
|
1911
1994
|
}
|
|
1912
1995
|
|
|
@@ -2064,195 +2147,248 @@ class Orbital extends Pawn {
|
|
|
2064
2147
|
}
|
|
2065
2148
|
|
|
2066
2149
|
class Controller {
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
}
|
|
2070
|
-
get
|
|
2071
|
-
|
|
2072
|
-
}
|
|
2073
|
-
get
|
|
2074
|
-
|
|
2075
|
-
}
|
|
2150
|
+
// ==================== Getters ====================
|
|
2151
|
+
get camera() { return this._app.camera; }
|
|
2152
|
+
get world() { return this._app.world; }
|
|
2153
|
+
get viewPort() { return this._app.viewport; }
|
|
2154
|
+
get app() { return this._app; }
|
|
2155
|
+
get onClickNothingDelegate() { return this._onClickNothingDelegate; }
|
|
2156
|
+
get onComponentClickDelegate() { return this._onComponentClickDelegate; }
|
|
2157
|
+
get onComponentDoubleClickDelegate() { return this._onComponentDoubleClickDelegate; }
|
|
2158
|
+
get onComponentHoverBeginDelegate() { return this._onComponentHoverBeginDelegate; }
|
|
2159
|
+
get onComponentHoverEndDelegate() { return this._onComponentHoverEndDelegate; }
|
|
2160
|
+
get onComponentPointerDownDelegate() { return this._onComponentPointerDownDelegate; }
|
|
2076
2161
|
get pawn() {
|
|
2077
|
-
if (!this._pawn)
|
|
2162
|
+
if (!this._pawn)
|
|
2078
2163
|
throw Error("pawn is null");
|
|
2079
|
-
}
|
|
2080
2164
|
return this._pawn;
|
|
2081
2165
|
}
|
|
2082
|
-
get app() {
|
|
2083
|
-
return this._app;
|
|
2084
|
-
}
|
|
2085
|
-
get onClickNothingDelegate() {
|
|
2086
|
-
return this._onClickNothingDelegate;
|
|
2087
|
-
}
|
|
2088
2166
|
constructor(app) {
|
|
2089
|
-
this.prepareClickComponent = null;
|
|
2090
2167
|
this._pawn = null;
|
|
2091
|
-
this.
|
|
2092
|
-
this.
|
|
2093
|
-
this.onPointerLeave = (event) => { this.onPointerLeaveEvent(event); };
|
|
2094
|
-
this.onPointerUp = (event) => { this.onPointerUpEvent(event); };
|
|
2095
|
-
this.onPointerDown = (event) => { this.onPointerDownEvent(event); };
|
|
2096
|
-
this.pointerPosition = new Vector2();
|
|
2097
|
-
this.doubleClickDelay = 250; // 双击判定时间间隔(毫秒)
|
|
2098
|
-
this.leftClickTimer = null;
|
|
2099
|
-
this.pointerLeftDownPosition = new Vector2();
|
|
2168
|
+
this.prepareClickComponent = null;
|
|
2169
|
+
this.prepareClickHit = null;
|
|
2100
2170
|
this.hoveringComponent = null;
|
|
2101
2171
|
this._pointButtonIsDown = new Set();
|
|
2102
2172
|
this._onClickNothingDelegate = new Delegate();
|
|
2173
|
+
this._onComponentClickDelegate = new Delegate();
|
|
2174
|
+
this._onComponentDoubleClickDelegate = new Delegate();
|
|
2175
|
+
this._onComponentHoverBeginDelegate = new Delegate();
|
|
2176
|
+
this._onComponentHoverEndDelegate = new Delegate();
|
|
2177
|
+
this._onComponentPointerDownDelegate = new Delegate();
|
|
2178
|
+
// Pointer state
|
|
2179
|
+
this.pointerPosition = new Vector2();
|
|
2180
|
+
this.pointerLeftDownPosition = new Vector2();
|
|
2181
|
+
// Reusable objects to avoid GC pressure
|
|
2182
|
+
this._tempVec2 = new Vector2();
|
|
2183
|
+
this._raycastVec2 = new Vector2();
|
|
2184
|
+
// Double click detection
|
|
2185
|
+
this.doubleClickDelay = 250;
|
|
2186
|
+
this.leftClickTimer = null;
|
|
2187
|
+
// Event handlers (bound)
|
|
2188
|
+
this.onPointerMove = (e) => this.onPointerMoveEvent(e);
|
|
2189
|
+
this.onPointerEnter = (e) => this.onPointerEnterEvent(e);
|
|
2190
|
+
this.onPointerLeave = (e) => this.onPointerLeaveEvent(e);
|
|
2191
|
+
this.onPointerUp = (e) => this.onPointerUpEvent(e);
|
|
2192
|
+
this.onPointerDown = (e) => this.onPointerDownEvent(e);
|
|
2103
2193
|
this._app = app;
|
|
2104
2194
|
this._pawn = new Orbital(this);
|
|
2105
2195
|
this.pawn.possess();
|
|
2106
2196
|
this.raycaster = new Raycaster();
|
|
2107
2197
|
}
|
|
2198
|
+
init() {
|
|
2199
|
+
const canvas = this.viewPort.canvas;
|
|
2200
|
+
if (canvas) {
|
|
2201
|
+
canvas.addEventListener("pointerenter", this.onPointerEnter);
|
|
2202
|
+
canvas.addEventListener("pointerleave", this.onPointerLeave);
|
|
2203
|
+
this.addCorePointerListeners();
|
|
2204
|
+
}
|
|
2205
|
+
}
|
|
2108
2206
|
updateCamera() {
|
|
2109
2207
|
var _a, _b;
|
|
2110
|
-
|
|
2208
|
+
const isPawnEnabled = this.pawn.enabled;
|
|
2111
2209
|
(_a = this._pawn) === null || _a === void 0 ? void 0 : _a.unpossess();
|
|
2112
2210
|
(_b = this._pawn) === null || _b === void 0 ? void 0 : _b.destroy();
|
|
2113
2211
|
this._pawn = new Orbital(this);
|
|
2114
2212
|
this.pawn.possess();
|
|
2115
2213
|
this.pawn.enabled = isPawnEnabled;
|
|
2116
2214
|
}
|
|
2117
|
-
init() {
|
|
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
|
-
}
|
|
2125
|
-
}
|
|
2126
2215
|
tick(deltaTime) {
|
|
2127
2216
|
this.pawn.tick(deltaTime);
|
|
2128
2217
|
}
|
|
2129
2218
|
destroy() {
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
this.
|
|
2137
|
-
this.viewPort.canvas.removeEventListener("pointerleave", this.onPointerLeave);
|
|
2138
|
-
this.viewPort.canvas.removeEventListener("pointerup", this.onPointerUp);
|
|
2139
|
-
this.viewPort.canvas.removeEventListener("pointerdown", this.onPointerDown);
|
|
2219
|
+
this.clearClickTimer();
|
|
2220
|
+
this.clearHoveringComponent();
|
|
2221
|
+
const canvas = this.viewPort.canvas;
|
|
2222
|
+
if (canvas) {
|
|
2223
|
+
canvas.removeEventListener("pointerenter", this.onPointerEnter);
|
|
2224
|
+
canvas.removeEventListener("pointerleave", this.onPointerLeave);
|
|
2225
|
+
this.removeCorePointerListeners();
|
|
2140
2226
|
}
|
|
2141
2227
|
this.pawn.unpossess();
|
|
2142
2228
|
this.pawn.destroy();
|
|
2143
2229
|
this._pawn = null;
|
|
2144
2230
|
}
|
|
2145
2231
|
onPointerMoveEvent(event) {
|
|
2146
|
-
|
|
2147
|
-
if (!
|
|
2232
|
+
const canvas = this.viewPort.canvas;
|
|
2233
|
+
if (!canvas)
|
|
2148
2234
|
throw Error("canvas is null");
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
const offsetY = canvasRect.top;
|
|
2153
|
-
const pointer = new Vector2(((event.clientX - offsetX) / this.viewPort.canvas.clientWidth) * 2 - 1, 1 - ((event.clientY - offsetY) / this.viewPort.canvas.clientHeight) * 2);
|
|
2154
|
-
this.pointerPosition = pointer;
|
|
2155
|
-
if (this._pointButtonIsDown.size > 0) {
|
|
2235
|
+
const canvasRect = canvas.getBoundingClientRect();
|
|
2236
|
+
this.pointerPosition.set(((event.clientX - canvasRect.left) / canvas.clientWidth) * 2 - 1, 1 - ((event.clientY - canvasRect.top) / canvas.clientHeight) * 2);
|
|
2237
|
+
if (this._pointButtonIsDown.size > 0)
|
|
2156
2238
|
return;
|
|
2157
|
-
}
|
|
2158
2239
|
const hits = this.getHitResultUnderCursor();
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
this.
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2240
|
+
const component = hits === null || hits === void 0 ? void 0 : hits.object.userData["LYObject"];
|
|
2241
|
+
if (component !== this.hoveringComponent) {
|
|
2242
|
+
this.clearHoveringComponent();
|
|
2243
|
+
if (component instanceof SceneComponent && component.isHoverEnabled && hits) {
|
|
2244
|
+
this.fireHoverEvent(component, hits, true);
|
|
2245
|
+
}
|
|
2246
|
+
}
|
|
2247
|
+
}
|
|
2248
|
+
clearHoveringComponent() {
|
|
2249
|
+
if (this.hoveringComponent) {
|
|
2250
|
+
this.fireHoverEvent(this.hoveringComponent, null, false);
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
2253
|
+
fireHoverEvent(component, hit, isBegin) {
|
|
2254
|
+
const event = { component, hit, handled: false };
|
|
2255
|
+
if (isBegin) {
|
|
2256
|
+
this._onComponentHoverBeginDelegate.broadcast(event);
|
|
2257
|
+
if (!event.handled) {
|
|
2258
|
+
component.onHorveringBegin();
|
|
2168
2259
|
}
|
|
2260
|
+
this.hoveringComponent = component;
|
|
2169
2261
|
}
|
|
2170
2262
|
else {
|
|
2171
|
-
|
|
2263
|
+
this._onComponentHoverEndDelegate.broadcast(event);
|
|
2264
|
+
if (!event.handled) {
|
|
2265
|
+
component.onHorveringEnd();
|
|
2266
|
+
}
|
|
2172
2267
|
this.hoveringComponent = null;
|
|
2173
2268
|
}
|
|
2174
2269
|
}
|
|
2175
2270
|
onPointerUpEvent(event) {
|
|
2176
2271
|
this._pointButtonIsDown.delete(event.button);
|
|
2177
|
-
if (event.button
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
else {
|
|
2200
|
-
this._onClickNothingDelegate.broadcast();
|
|
2201
|
-
}
|
|
2202
|
-
}
|
|
2203
|
-
else {
|
|
2204
|
-
window.clearTimeout(this.leftClickTimer);
|
|
2272
|
+
if (event.button !== 0)
|
|
2273
|
+
return;
|
|
2274
|
+
// Check if pointer moved too much (drag instead of click)
|
|
2275
|
+
const pointerOffset = this._tempVec2.subVectors(this.pointerLeftDownPosition, this.pointerPosition).length();
|
|
2276
|
+
if (pointerOffset > 0.005) {
|
|
2277
|
+
this.clearClickTimer();
|
|
2278
|
+
return;
|
|
2279
|
+
}
|
|
2280
|
+
if (!this.leftClickTimer) {
|
|
2281
|
+
this.handleFirstClick();
|
|
2282
|
+
}
|
|
2283
|
+
else {
|
|
2284
|
+
this.handleDoubleClick();
|
|
2285
|
+
}
|
|
2286
|
+
}
|
|
2287
|
+
handleFirstClick() {
|
|
2288
|
+
const hit = this.getHitResultUnderCursor();
|
|
2289
|
+
const component = hit === null || hit === void 0 ? void 0 : hit.object.userData["LYObject"];
|
|
2290
|
+
if (component instanceof SceneComponent && component.isClickEnabled && hit) {
|
|
2291
|
+
this.prepareClickComponent = component;
|
|
2292
|
+
this.prepareClickHit = hit;
|
|
2293
|
+
this.leftClickTimer = window.setTimeout(() => {
|
|
2205
2294
|
this.leftClickTimer = null;
|
|
2206
|
-
if (this.prepareClickComponent) {
|
|
2207
|
-
this.prepareClickComponent.
|
|
2295
|
+
if (this.prepareClickComponent && this.prepareClickHit) {
|
|
2296
|
+
this.fireClickEvent(this.prepareClickComponent, this.prepareClickHit, false);
|
|
2297
|
+
this.prepareClickComponent = null;
|
|
2298
|
+
this.prepareClickHit = null;
|
|
2208
2299
|
}
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2300
|
+
}, this.doubleClickDelay);
|
|
2301
|
+
}
|
|
2302
|
+
else {
|
|
2303
|
+
this._onClickNothingDelegate.broadcast();
|
|
2304
|
+
}
|
|
2305
|
+
}
|
|
2306
|
+
handleDoubleClick() {
|
|
2307
|
+
this.clearClickTimer();
|
|
2308
|
+
if (this.prepareClickComponent && this.prepareClickHit) {
|
|
2309
|
+
this.fireClickEvent(this.prepareClickComponent, this.prepareClickHit, true);
|
|
2310
|
+
}
|
|
2311
|
+
else {
|
|
2312
|
+
this._onClickNothingDelegate.broadcast();
|
|
2313
|
+
}
|
|
2314
|
+
this.prepareClickComponent = null;
|
|
2315
|
+
this.prepareClickHit = null;
|
|
2316
|
+
}
|
|
2317
|
+
fireClickEvent(component, hit, isDoubleClick) {
|
|
2318
|
+
const event = { component, hit, handled: false };
|
|
2319
|
+
if (isDoubleClick) {
|
|
2320
|
+
this._onComponentDoubleClickDelegate.broadcast(event);
|
|
2321
|
+
if (!event.handled) {
|
|
2322
|
+
component.onDoubleClicked();
|
|
2213
2323
|
}
|
|
2214
2324
|
}
|
|
2325
|
+
else {
|
|
2326
|
+
this._onComponentClickDelegate.broadcast(event);
|
|
2327
|
+
if (!event.handled) {
|
|
2328
|
+
component.onClicked();
|
|
2329
|
+
}
|
|
2330
|
+
}
|
|
2331
|
+
}
|
|
2332
|
+
clearClickTimer() {
|
|
2333
|
+
if (this.leftClickTimer) {
|
|
2334
|
+
window.clearTimeout(this.leftClickTimer);
|
|
2335
|
+
this.leftClickTimer = null;
|
|
2336
|
+
}
|
|
2215
2337
|
}
|
|
2216
2338
|
onPointerDownEvent(event) {
|
|
2217
2339
|
this._pointButtonIsDown.add(event.button);
|
|
2218
2340
|
if (event.button === 0) {
|
|
2219
|
-
this.pointerLeftDownPosition
|
|
2341
|
+
this.pointerLeftDownPosition.copy(this.pointerPosition);
|
|
2342
|
+
}
|
|
2343
|
+
// 广播组件按下事件
|
|
2344
|
+
const hit = this.getHitResultUnderCursor();
|
|
2345
|
+
const component = hit === null || hit === void 0 ? void 0 : hit.object.userData["LYObject"];
|
|
2346
|
+
if (component instanceof SceneComponent && hit) {
|
|
2347
|
+
this.firePointerDownEvent(component, hit, event.button);
|
|
2220
2348
|
}
|
|
2221
2349
|
}
|
|
2350
|
+
firePointerDownEvent(component, hit, button) {
|
|
2351
|
+
const event = { component, hit, button, handled: false };
|
|
2352
|
+
this._onComponentPointerDownDelegate.broadcast(event);
|
|
2353
|
+
}
|
|
2222
2354
|
onPointerEnterEvent(event) {
|
|
2223
|
-
|
|
2224
|
-
throw Error("canvas is null");
|
|
2225
|
-
}
|
|
2226
|
-
this.viewPort.canvas.addEventListener("pointermove", this.onPointerMove);
|
|
2227
|
-
this.viewPort.canvas.addEventListener("pointerup", this.onPointerUp);
|
|
2228
|
-
this.viewPort.canvas.addEventListener("pointerdown", this.onPointerDown);
|
|
2355
|
+
this.addCorePointerListeners();
|
|
2229
2356
|
}
|
|
2230
2357
|
onPointerLeaveEvent(event) {
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
this.viewPort.canvas
|
|
2235
|
-
|
|
2236
|
-
|
|
2358
|
+
this.removeCorePointerListeners();
|
|
2359
|
+
}
|
|
2360
|
+
addCorePointerListeners() {
|
|
2361
|
+
const canvas = this.viewPort.canvas;
|
|
2362
|
+
if (!canvas)
|
|
2363
|
+
return;
|
|
2364
|
+
canvas.addEventListener("pointermove", this.onPointerMove);
|
|
2365
|
+
canvas.addEventListener("pointerup", this.onPointerUp);
|
|
2366
|
+
canvas.addEventListener("pointerdown", this.onPointerDown);
|
|
2367
|
+
}
|
|
2368
|
+
removeCorePointerListeners() {
|
|
2369
|
+
const canvas = this.viewPort.canvas;
|
|
2370
|
+
if (!canvas)
|
|
2371
|
+
return;
|
|
2372
|
+
canvas.removeEventListener("pointermove", this.onPointerMove);
|
|
2373
|
+
canvas.removeEventListener("pointerup", this.onPointerUp);
|
|
2374
|
+
canvas.removeEventListener("pointerdown", this.onPointerDown);
|
|
2237
2375
|
}
|
|
2238
2376
|
getHitResultUnderCursor() {
|
|
2239
2377
|
return this.getHitResultFromScreenPoint(this.pointerPosition.x, this.pointerPosition.y);
|
|
2240
2378
|
}
|
|
2241
2379
|
getHitResultFromScreenPoint(x, y) {
|
|
2242
|
-
this.
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2380
|
+
this._raycastVec2.set(x, y);
|
|
2381
|
+
this.raycaster.setFromCamera(this._raycastVec2, this.camera);
|
|
2382
|
+
const out = this.raycaster.intersectObjects(this.world.scene.children, true);
|
|
2383
|
+
for (const hit of out) {
|
|
2384
|
+
if (hit.object.userData["rayIgnored"])
|
|
2246
2385
|
continue;
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
if (!component) {
|
|
2386
|
+
const component = hit.object.userData["LYObject"];
|
|
2387
|
+
if (!component)
|
|
2250
2388
|
continue;
|
|
2251
|
-
|
|
2252
|
-
if (!component.isHoverEnabled && !component.isClickEnabled) {
|
|
2389
|
+
if (!component.isHoverEnabled && !component.isClickEnabled)
|
|
2253
2390
|
continue;
|
|
2254
|
-
|
|
2255
|
-
return out[i];
|
|
2391
|
+
return hit;
|
|
2256
2392
|
}
|
|
2257
2393
|
return null;
|
|
2258
2394
|
}
|
|
@@ -3566,4 +3702,4 @@ class TransformGizmo extends Pawn {
|
|
|
3566
3702
|
}
|
|
3567
3703
|
}
|
|
3568
3704
|
|
|
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 };
|
|
3705
|
+
export { ASSET_POINTER_KEY, Actor, AmbientLightActor, AmbientLightComponent, AssetCategory, AssetLoadState, AssetManager, AssetType, AttachmentRules, BoxActor, BoxComponent, Controller, DefaultAAParams, DefaultAppParam, DefaultBloomParam, DefaultCameraParam, DefaultDOFParam, DefaultDenoiseParam, DefaultGTAOParam, DefaultOrthographicCameraParam, DefaultOutlineParams, DefaultPerspectiveCameraParam, DefaultPostProcessParam, DefaultRendererParameters, DefaultSSRParam, DefaultSkyParam, DefaultViewportParam, DefaultWorldParam, Delegate, DirectionalLightActor, DirectionalLightComponent, EDITOR_ASSET_ID_KEY, FirstPerson, GeometryAssetPointer, LabelComponent, LevelActor, LevelComponent, MaterialAssetPointer, MeshComponent, Orbital, PlaneActor, PlaneComponent, PostProcessStepType, ReferenceType, SceneComponent, SkyActor, SkyComponent, SphereComponent, TAssetPointer, TSmartPointer, TextureAssetPointer, ThreeJsApp, ThreeObjectLibrary, TransformGizmo, Viewport, WebGPUPostProcessFactory, World };
|