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