@onerjs/core 8.28.0 → 8.28.2
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/Behaviors/Meshes/handConstraintBehavior.js.map +1 -1
- package/Collisions/gpuPicker.d.ts +40 -16
- package/Collisions/gpuPicker.js +216 -95
- package/Collisions/gpuPicker.js.map +1 -1
- package/Decorators/nodeDecorator.d.ts +5 -1
- package/Decorators/nodeDecorator.js +4 -0
- package/Decorators/nodeDecorator.js.map +1 -1
- package/Engines/abstractEngine.js +2 -2
- package/Engines/abstractEngine.js.map +1 -1
- package/FrameGraph/Node/Blocks/PostProcesses/colorCorrectionPostProcessBlock.d.ts +30 -0
- package/FrameGraph/Node/Blocks/PostProcesses/colorCorrectionPostProcessBlock.js +56 -0
- package/FrameGraph/Node/Blocks/PostProcesses/colorCorrectionPostProcessBlock.js.map +1 -0
- package/FrameGraph/Node/Blocks/PostProcesses/filterPostProcessBlock.d.ts +32 -0
- package/FrameGraph/Node/Blocks/PostProcesses/filterPostProcessBlock.js +62 -0
- package/FrameGraph/Node/Blocks/PostProcesses/filterPostProcessBlock.js.map +1 -0
- package/FrameGraph/Node/Blocks/PostProcesses/tonemapPostProcessBlock.d.ts +36 -0
- package/FrameGraph/Node/Blocks/PostProcesses/tonemapPostProcessBlock.js +88 -0
- package/FrameGraph/Node/Blocks/PostProcesses/tonemapPostProcessBlock.js.map +1 -0
- package/FrameGraph/Node/Blocks/index.d.ts +3 -0
- package/FrameGraph/Node/Blocks/index.js +3 -0
- package/FrameGraph/Node/Blocks/index.js.map +1 -1
- package/FrameGraph/Tasks/PostProcesses/colorCorrectionTask.d.ts +17 -0
- package/FrameGraph/Tasks/PostProcesses/colorCorrectionTask.js +18 -0
- package/FrameGraph/Tasks/PostProcesses/colorCorrectionTask.js.map +1 -0
- package/FrameGraph/Tasks/PostProcesses/filterTask.d.ts +16 -0
- package/FrameGraph/Tasks/PostProcesses/filterTask.js +17 -0
- package/FrameGraph/Tasks/PostProcesses/filterTask.js.map +1 -0
- package/FrameGraph/Tasks/PostProcesses/tonemapTask.d.ts +16 -0
- package/FrameGraph/Tasks/PostProcesses/tonemapTask.js +17 -0
- package/FrameGraph/Tasks/PostProcesses/tonemapTask.js.map +1 -0
- package/FrameGraph/index.d.ts +3 -0
- package/FrameGraph/index.js +3 -0
- package/FrameGraph/index.js.map +1 -1
- package/Materials/Textures/texture.js +9 -2
- package/Materials/Textures/texture.js.map +1 -1
- package/Materials/effect.d.ts +1 -0
- package/Materials/effect.js +7 -1
- package/Materials/effect.js.map +1 -1
- package/Particles/gpuParticleSystem.js +2 -1
- package/Particles/gpuParticleSystem.js.map +1 -1
- package/Particles/thinParticleSystem.js +4 -3
- package/Particles/thinParticleSystem.js.map +1 -1
- package/Physics/v2/physicsAggregate.js +4 -3
- package/Physics/v2/physicsAggregate.js.map +1 -1
- package/PostProcesses/colorCorrectionPostProcess.d.ts +3 -3
- package/PostProcesses/colorCorrectionPostProcess.js +21 -21
- package/PostProcesses/colorCorrectionPostProcess.js.map +1 -1
- package/PostProcesses/filterPostProcess.d.ts +4 -2
- package/PostProcesses/filterPostProcess.js +22 -15
- package/PostProcesses/filterPostProcess.js.map +1 -1
- package/PostProcesses/index.d.ts +3 -0
- package/PostProcesses/index.js +3 -0
- package/PostProcesses/index.js.map +1 -1
- package/PostProcesses/thinColorCorrectionPostProcess.d.ts +30 -0
- package/PostProcesses/thinColorCorrectionPostProcess.js +52 -0
- package/PostProcesses/thinColorCorrectionPostProcess.js.map +1 -0
- package/PostProcesses/thinFilterPostProcess.d.ts +29 -0
- package/PostProcesses/thinFilterPostProcess.js +51 -0
- package/PostProcesses/thinFilterPostProcess.js.map +1 -0
- package/PostProcesses/thinTonemapPostProcess.d.ts +52 -0
- package/PostProcesses/thinTonemapPostProcess.js +83 -0
- package/PostProcesses/thinTonemapPostProcess.js.map +1 -0
- package/PostProcesses/tonemapPostProcess.d.ts +23 -21
- package/PostProcesses/tonemapPostProcess.js +55 -46
- package/PostProcesses/tonemapPostProcess.js.map +1 -1
- package/Rendering/geometryBufferRenderer.js +6 -1
- package/Rendering/geometryBufferRenderer.js.map +1 -1
- package/Shaders/geometry.fragment.js +3 -1
- package/Shaders/geometry.fragment.js.map +1 -1
- package/Shaders/geometry.vertex.js +10 -2
- package/Shaders/geometry.vertex.js.map +1 -1
- package/Shaders/picking.fragment.js +20 -6
- package/Shaders/picking.fragment.js.map +1 -1
- package/Shaders/picking.vertex.js +4 -3
- package/Shaders/picking.vertex.js.map +1 -1
- package/ShadersWGSL/geometry.fragment.js +3 -1
- package/ShadersWGSL/geometry.fragment.js.map +1 -1
- package/ShadersWGSL/geometry.vertex.js +10 -2
- package/ShadersWGSL/geometry.vertex.js.map +1 -1
- package/ShadersWGSL/picking.fragment.js +11 -6
- package/ShadersWGSL/picking.fragment.js.map +1 -1
- package/ShadersWGSL/picking.vertex.js +4 -3
- package/ShadersWGSL/picking.vertex.js.map +1 -1
- package/XR/features/WebXRAnchorSystem.d.ts +1 -1
- package/XR/features/WebXRBackgroundRemover.d.ts +1 -1
- package/XR/features/WebXRControllerMovement.d.ts +1 -1
- package/XR/features/WebXRControllerPhysics.d.ts +1 -1
- package/XR/features/WebXRControllerPointerSelection.d.ts +1 -1
- package/XR/features/WebXRControllerTeleportation.d.ts +1 -1
- package/XR/features/WebXRDOMOverlay.d.ts +1 -1
- package/XR/features/WebXRDepthSensing.d.ts +1 -1
- package/XR/features/WebXREyeTracking.d.ts +1 -1
- package/XR/features/WebXRFeaturePointSystem.d.ts +1 -1
- package/XR/features/WebXRHandTracking.d.ts +1 -1
- package/XR/features/WebXRHitTest.d.ts +1 -1
- package/XR/features/WebXRHitTestLegacy.d.ts +1 -1
- package/XR/features/WebXRImageTracking.d.ts +1 -1
- package/XR/features/WebXRLayers.d.ts +1 -1
- package/XR/features/WebXRLightEstimation.d.ts +1 -1
- package/XR/features/WebXRMeshDetector.d.ts +1 -1
- package/XR/features/WebXRNearInteraction.d.ts +1 -1
- package/XR/features/WebXRPlaneDetector.d.ts +1 -1
- package/XR/features/WebXRRawCameraAccess.d.ts +1 -1
- package/XR/features/WebXRSpaceWarp.d.ts +1 -1
- package/XR/webXRDefaultExperience.js +1 -1
- package/XR/webXRDefaultExperience.js.map +1 -1
- package/XR/webXRFeaturesManager.d.ts +116 -27
- package/XR/webXRFeaturesManager.js.map +1 -1
- package/package.json +1 -1
package/Collisions/gpuPicker.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
import { RenderTargetTexture } from "../Materials/Textures/renderTargetTexture.js";
|
|
3
3
|
import { ShaderMaterial } from "../Materials/shaderMaterial.js";
|
|
4
|
-
import {
|
|
4
|
+
import { Color4 } from "../Maths/math.color.js";
|
|
5
5
|
import { VertexBuffer } from "../Meshes/buffer.js";
|
|
6
6
|
import { Logger } from "../Misc/logger.js";
|
|
7
7
|
/**
|
|
@@ -13,14 +13,20 @@ export class GPUPicker {
|
|
|
13
13
|
this._pickingTexture = null;
|
|
14
14
|
this._idMap = [];
|
|
15
15
|
this._thinIdMap = [];
|
|
16
|
-
this.
|
|
16
|
+
this._meshUniqueIdToPickerId = [];
|
|
17
|
+
this._idWarningIssued = false;
|
|
18
|
+
this._cachedScene = null;
|
|
19
|
+
this._engine = null;
|
|
20
|
+
this._pickingMaterialCache = new Array(9).fill(null);
|
|
21
|
+
this._pickableMeshes = [];
|
|
17
22
|
this._meshMaterialMap = new Map();
|
|
23
|
+
this._readbuffer = null;
|
|
18
24
|
this._meshRenderingCount = 0;
|
|
19
|
-
this.
|
|
20
|
-
this._warningIssued = false;
|
|
25
|
+
this._renderWarningIssued = false;
|
|
21
26
|
this._renderPickingTexture = false;
|
|
22
27
|
this._sceneBeforeRenderObserver = null;
|
|
23
|
-
this.
|
|
28
|
+
this._pickingTextureAfterRenderObserver = null;
|
|
29
|
+
this._nextFreeId = 1;
|
|
24
30
|
/** Shader language used by the generator */
|
|
25
31
|
this._shaderLanguage = 0 /* ShaderLanguage.GLSL */;
|
|
26
32
|
this._pickingInProgress = false;
|
|
@@ -38,15 +44,12 @@ export class GPUPicker {
|
|
|
38
44
|
return this._pickingInProgress;
|
|
39
45
|
}
|
|
40
46
|
/**
|
|
41
|
-
* Gets the default render
|
|
47
|
+
* Gets the default render materials used by the picker.
|
|
48
|
+
*
|
|
49
|
+
* index is Material filling mode
|
|
42
50
|
*/
|
|
43
|
-
get
|
|
44
|
-
return this.
|
|
45
|
-
}
|
|
46
|
-
static _IdToRgb(id) {
|
|
47
|
-
GPUPicker._TempColor.r = (id & 0xff0000) >> 16;
|
|
48
|
-
GPUPicker._TempColor.g = (id & 0x00ff00) >> 8;
|
|
49
|
-
GPUPicker._TempColor.b = (id & 0x0000ff) >> 0;
|
|
51
|
+
get defaultRenderMaterials() {
|
|
52
|
+
return this._pickingMaterialCache;
|
|
50
53
|
}
|
|
51
54
|
_getColorIdFromReadBuffer(offset) {
|
|
52
55
|
const r = this._readbuffer[offset];
|
|
@@ -54,12 +57,6 @@ export class GPUPicker {
|
|
|
54
57
|
const b = this._readbuffer[offset + 2];
|
|
55
58
|
return (r << 16) + (g << 8) + b;
|
|
56
59
|
}
|
|
57
|
-
static _SetColorData(buffer, i, r, g, b) {
|
|
58
|
-
buffer[i] = r / 255.0;
|
|
59
|
-
buffer[i + 1] = g / 255.0;
|
|
60
|
-
buffer[i + 2] = b / 255.0;
|
|
61
|
-
buffer[i + 3] = 1.0;
|
|
62
|
-
}
|
|
63
60
|
_createRenderTarget(scene, width, height) {
|
|
64
61
|
if (this._cachedScene && this._pickingTexture) {
|
|
65
62
|
const index = this._cachedScene.customRenderTargets.indexOf(this._pickingTexture);
|
|
@@ -71,21 +68,36 @@ export class GPUPicker {
|
|
|
71
68
|
if (this._pickingTexture) {
|
|
72
69
|
this._pickingTexture.dispose();
|
|
73
70
|
}
|
|
74
|
-
this._pickingTexture = new RenderTargetTexture("pickingTexure", { width: width, height: height }, scene,
|
|
71
|
+
this._pickingTexture = new RenderTargetTexture("pickingTexure", { width: width, height: height }, scene, {
|
|
72
|
+
generateMipMaps: false,
|
|
73
|
+
type: 0,
|
|
74
|
+
samplingMode: 1,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
_clearPickingMaterials() {
|
|
78
|
+
for (let i = 0; i < this._pickingMaterialCache.length; i++) {
|
|
79
|
+
const material = this._pickingMaterialCache[i];
|
|
80
|
+
if (material !== null) {
|
|
81
|
+
material.dispose();
|
|
82
|
+
this._pickingMaterialCache[i] = null;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
75
85
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
86
|
+
_getPickingMaterial(scene, fillMode) {
|
|
87
|
+
if (fillMode < 0 || 8 < fillMode) {
|
|
88
|
+
fillMode = 0;
|
|
89
|
+
}
|
|
90
|
+
const cachedMaterial = this._pickingMaterialCache[fillMode];
|
|
91
|
+
if (cachedMaterial) {
|
|
92
|
+
return cachedMaterial;
|
|
80
93
|
}
|
|
81
|
-
this._defaultRenderMaterial = null;
|
|
82
94
|
const engine = scene.getEngine();
|
|
83
95
|
if (engine.isWebGPU) {
|
|
84
96
|
this._shaderLanguage = 1 /* ShaderLanguage.WGSL */;
|
|
85
97
|
}
|
|
86
98
|
const defines = [];
|
|
87
99
|
const options = {
|
|
88
|
-
attributes: [VertexBuffer.PositionKind,
|
|
100
|
+
attributes: [VertexBuffer.PositionKind, GPUPicker._AttributeName],
|
|
89
101
|
uniforms: ["world", "viewProjection", "meshID"],
|
|
90
102
|
needAlphaBlending: false,
|
|
91
103
|
defines: defines,
|
|
@@ -100,8 +112,11 @@ export class GPUPicker {
|
|
|
100
112
|
}
|
|
101
113
|
},
|
|
102
114
|
};
|
|
103
|
-
|
|
104
|
-
|
|
115
|
+
const newMaterial = new ShaderMaterial("pickingShader", scene, "picking", options, false);
|
|
116
|
+
newMaterial.fillMode = fillMode;
|
|
117
|
+
newMaterial.onBindObservable.add(this._materialBindCallback, undefined, undefined, this);
|
|
118
|
+
this._pickingMaterialCache[fillMode] = newMaterial;
|
|
119
|
+
return newMaterial;
|
|
105
120
|
}
|
|
106
121
|
_materialBindCallback(mesh) {
|
|
107
122
|
if (!mesh) {
|
|
@@ -109,39 +124,18 @@ export class GPUPicker {
|
|
|
109
124
|
}
|
|
110
125
|
const material = this._meshMaterialMap.get(mesh);
|
|
111
126
|
if (!material) {
|
|
112
|
-
if (!this.
|
|
113
|
-
this.
|
|
127
|
+
if (!this._renderWarningIssued) {
|
|
128
|
+
this._renderWarningIssued = true;
|
|
114
129
|
Logger.Warn("GPUPicker issue: Mesh not found in the material map. This may happen when the root mesh of an instance is not in the picking list.");
|
|
115
130
|
}
|
|
116
131
|
return;
|
|
117
132
|
}
|
|
118
133
|
const effect = material.getEffect();
|
|
119
|
-
if (!mesh.hasInstances && !mesh.isAnInstance && !mesh.hasThinInstances && this.
|
|
120
|
-
effect.
|
|
134
|
+
if (!mesh.hasInstances && !mesh.isAnInstance && !mesh.hasThinInstances && this._meshUniqueIdToPickerId[mesh.uniqueId] !== undefined) {
|
|
135
|
+
effect.setFloat("meshID", this._meshUniqueIdToPickerId[mesh.uniqueId]);
|
|
121
136
|
}
|
|
122
137
|
this._meshRenderingCount++;
|
|
123
138
|
}
|
|
124
|
-
_generateColorData(instanceCount, id, r, g, b, onInstance) {
|
|
125
|
-
const colorData = new Float32Array(4 * (instanceCount + 1));
|
|
126
|
-
GPUPicker._SetColorData(colorData, 0, r, g, b);
|
|
127
|
-
for (let i = 0; i < instanceCount; i++) {
|
|
128
|
-
GPUPicker._IdToRgb(id);
|
|
129
|
-
onInstance(i, id);
|
|
130
|
-
GPUPicker._SetColorData(colorData, (i + 1) * 4, GPUPicker._TempColor.r, GPUPicker._TempColor.g, GPUPicker._TempColor.b);
|
|
131
|
-
id++;
|
|
132
|
-
}
|
|
133
|
-
return colorData;
|
|
134
|
-
}
|
|
135
|
-
_generateThinInstanceColorData(instanceCount, id, onInstance) {
|
|
136
|
-
const colorData = new Float32Array(4 * instanceCount);
|
|
137
|
-
for (let i = 0; i < instanceCount; i++) {
|
|
138
|
-
GPUPicker._IdToRgb(id);
|
|
139
|
-
onInstance(i, id);
|
|
140
|
-
GPUPicker._SetColorData(colorData, i * 4, GPUPicker._TempColor.r, GPUPicker._TempColor.g, GPUPicker._TempColor.b);
|
|
141
|
-
id++;
|
|
142
|
-
}
|
|
143
|
-
return colorData;
|
|
144
|
-
}
|
|
145
139
|
/**
|
|
146
140
|
* Set the list of meshes to pick from
|
|
147
141
|
* Set that value to null to clear the list (and avoid leaks)
|
|
@@ -149,21 +143,37 @@ export class GPUPicker {
|
|
|
149
143
|
* @param list defines the list of meshes to pick from
|
|
150
144
|
*/
|
|
151
145
|
setPickingList(list) {
|
|
146
|
+
this.clearPickingList();
|
|
147
|
+
if (!list || list.length === 0) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
this._pickableMeshes = list;
|
|
151
|
+
// Prepare target
|
|
152
|
+
const scene = ("mesh" in list[0] ? list[0].mesh : list[0]).getScene();
|
|
153
|
+
if (!this._cachedScene || this._cachedScene !== scene) {
|
|
154
|
+
this._clearPickingMaterials();
|
|
155
|
+
}
|
|
156
|
+
this.addPickingList(list);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Clear the current picking list and free resources
|
|
160
|
+
*/
|
|
161
|
+
clearPickingList() {
|
|
152
162
|
if (this._pickableMeshes) {
|
|
153
163
|
// Cleanup
|
|
154
164
|
for (let index = 0; index < this._pickableMeshes.length; index++) {
|
|
155
165
|
const mesh = this._pickableMeshes[index];
|
|
156
166
|
if (mesh.hasInstances) {
|
|
157
|
-
mesh.removeVerticesData(
|
|
167
|
+
mesh.removeVerticesData(GPUPicker._AttributeName);
|
|
158
168
|
}
|
|
159
169
|
if (mesh.hasThinInstances) {
|
|
160
|
-
mesh.thinInstanceSetBuffer(
|
|
170
|
+
mesh.thinInstanceSetBuffer(GPUPicker._AttributeName, null);
|
|
161
171
|
}
|
|
162
172
|
if (this._pickingTexture) {
|
|
163
173
|
this._pickingTexture.setMaterialForRendering(mesh, undefined);
|
|
164
174
|
}
|
|
165
175
|
const material = this._meshMaterialMap.get(mesh);
|
|
166
|
-
if (
|
|
176
|
+
if (!this._pickingMaterialCache.includes(material)) {
|
|
167
177
|
material.onBindObservable.removeCallback(this._materialBindCallback);
|
|
168
178
|
}
|
|
169
179
|
}
|
|
@@ -171,15 +181,21 @@ export class GPUPicker {
|
|
|
171
181
|
this._meshMaterialMap.clear();
|
|
172
182
|
this._idMap.length = 0;
|
|
173
183
|
this._thinIdMap.length = 0;
|
|
174
|
-
this.
|
|
184
|
+
this._meshUniqueIdToPickerId.length = 0;
|
|
175
185
|
if (this._pickingTexture) {
|
|
176
186
|
this._pickingTexture.renderList = [];
|
|
177
187
|
}
|
|
178
188
|
}
|
|
189
|
+
this._nextFreeId = 1;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Add array of meshes to the current picking list
|
|
193
|
+
* @param list defines the array of meshes to add to the current picking list
|
|
194
|
+
*/
|
|
195
|
+
addPickingList(list) {
|
|
179
196
|
if (!list || list.length === 0) {
|
|
180
197
|
return;
|
|
181
198
|
}
|
|
182
|
-
this._pickableMeshes = list;
|
|
183
199
|
// Prepare target
|
|
184
200
|
const scene = ("mesh" in list[0] ? list[0].mesh : list[0]).getScene();
|
|
185
201
|
const engine = scene.getEngine();
|
|
@@ -201,29 +217,39 @@ export class GPUPicker {
|
|
|
201
217
|
this._cachedScene.activeCamera = null;
|
|
202
218
|
}
|
|
203
219
|
});
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
220
|
+
this._cachedScene = scene;
|
|
221
|
+
this._engine = scene.getEngine();
|
|
222
|
+
if (!this._pickingTexture.renderList) {
|
|
223
|
+
this._pickingTexture.renderList = [];
|
|
207
224
|
}
|
|
225
|
+
const newPickableMeshes = new Array(list.length);
|
|
226
|
+
const pickableMeshOffset = this._pickableMeshes?.length ?? 0;
|
|
208
227
|
this._cachedScene = scene;
|
|
209
228
|
this._engine = scene.getEngine();
|
|
210
229
|
for (let i = 0; i < list.length; i++) {
|
|
211
230
|
const item = list[i];
|
|
212
231
|
if ("mesh" in item) {
|
|
213
232
|
this._meshMaterialMap.set(item.mesh, item.material);
|
|
214
|
-
|
|
233
|
+
newPickableMeshes[i] = item.mesh;
|
|
215
234
|
}
|
|
216
235
|
else {
|
|
217
|
-
this.
|
|
236
|
+
const material = this._getPickingMaterial(scene, item.material?.fillMode ?? 0);
|
|
237
|
+
this._meshMaterialMap.set(item, material);
|
|
238
|
+
newPickableMeshes[i] = item;
|
|
218
239
|
}
|
|
219
240
|
}
|
|
220
|
-
this.
|
|
241
|
+
if (this._pickableMeshes !== null) {
|
|
242
|
+
this._pickableMeshes = [...this._pickableMeshes, ...newPickableMeshes];
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
this._pickableMeshes = newPickableMeshes;
|
|
246
|
+
}
|
|
221
247
|
// We will affect colors and create vertex color buffers
|
|
222
|
-
let
|
|
223
|
-
for (let index = 0; index <
|
|
224
|
-
const mesh =
|
|
248
|
+
let nextFreeid = this._nextFreeId;
|
|
249
|
+
for (let index = 0; index < newPickableMeshes.length; index++) {
|
|
250
|
+
const mesh = newPickableMeshes[index];
|
|
225
251
|
const material = this._meshMaterialMap.get(mesh);
|
|
226
|
-
if (
|
|
252
|
+
if (!this._pickingMaterialCache.includes(material)) {
|
|
227
253
|
material.onBindObservable.add(this._materialBindCallback, undefined, undefined, this);
|
|
228
254
|
}
|
|
229
255
|
this._pickingTexture.setMaterialForRendering(mesh, material);
|
|
@@ -231,33 +257,54 @@ export class GPUPicker {
|
|
|
231
257
|
if (mesh.isAnInstance) {
|
|
232
258
|
continue; // This will be handled by the source mesh
|
|
233
259
|
}
|
|
234
|
-
|
|
260
|
+
const globalIndex = index + pickableMeshOffset;
|
|
235
261
|
if (mesh.hasThinInstances) {
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
262
|
+
const thinInstanceCount = mesh.thinInstanceCount;
|
|
263
|
+
const instanceIdData = new Float32Array(thinInstanceCount);
|
|
264
|
+
for (let i = 0; i < thinInstanceCount; i++) {
|
|
265
|
+
instanceIdData[i] = nextFreeid;
|
|
266
|
+
this._thinIdMap[nextFreeid] = { meshId: globalIndex, thinId: i };
|
|
267
|
+
nextFreeid++;
|
|
268
|
+
}
|
|
269
|
+
mesh.thinInstanceSetBuffer(GPUPicker._AttributeName, instanceIdData, 1);
|
|
241
270
|
}
|
|
242
271
|
else {
|
|
243
|
-
|
|
244
|
-
|
|
272
|
+
const currentMeshId = nextFreeid;
|
|
273
|
+
this._idMap[currentMeshId] = globalIndex;
|
|
274
|
+
nextFreeid++;
|
|
245
275
|
if (mesh.hasInstances) {
|
|
246
|
-
|
|
247
|
-
const
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
276
|
+
// find index of instances of that mesh
|
|
277
|
+
const instancesForPick = [];
|
|
278
|
+
for (let pickableMeshIndex = 0; pickableMeshIndex < newPickableMeshes.length; ++pickableMeshIndex) {
|
|
279
|
+
const m = newPickableMeshes[pickableMeshIndex];
|
|
280
|
+
if (m.isAnInstance && m.sourceMesh === mesh) {
|
|
281
|
+
instancesForPick.push(pickableMeshIndex);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
const instanceIdData = new Float32Array(instancesForPick.length + 1); // +1 for the source mesh
|
|
285
|
+
instanceIdData[0] = currentMeshId;
|
|
286
|
+
for (let i = 0; i < instancesForPick.length; i++) {
|
|
287
|
+
instanceIdData[i + 1] = nextFreeid;
|
|
288
|
+
const globalInstanceIndex = instancesForPick[i] + pickableMeshOffset;
|
|
289
|
+
this._idMap[nextFreeid] = globalInstanceIndex;
|
|
290
|
+
nextFreeid++;
|
|
291
|
+
}
|
|
252
292
|
const engine = mesh.getEngine();
|
|
253
|
-
const buffer = new VertexBuffer(engine,
|
|
293
|
+
const buffer = new VertexBuffer(engine, instanceIdData, GPUPicker._AttributeName, false, false, 1, true);
|
|
254
294
|
mesh.setVerticesBuffer(buffer, true);
|
|
255
295
|
}
|
|
256
296
|
else {
|
|
257
|
-
this.
|
|
297
|
+
this._meshUniqueIdToPickerId[mesh.uniqueId] = currentMeshId;
|
|
258
298
|
}
|
|
259
299
|
}
|
|
260
300
|
}
|
|
301
|
+
if (GPUPicker._MaxPickingId < nextFreeid - 1) {
|
|
302
|
+
if (!this._idWarningIssued) {
|
|
303
|
+
this._idWarningIssued = true;
|
|
304
|
+
Logger.Warn(`GPUPicker maximum number of pickable meshes and instances is ${GPUPicker._MaxPickingId}. Some meshes or instances won't be pickable.`);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
this._nextFreeId = nextFreeid;
|
|
261
308
|
}
|
|
262
309
|
/**
|
|
263
310
|
* Execute a picking operation
|
|
@@ -332,6 +379,40 @@ export class GPUPicker {
|
|
|
332
379
|
this._preparePickingBuffer(this._engine, rttSizeW, rttSizeH, minX, partialCutH, w, h);
|
|
333
380
|
return await this._executeMultiPickingAsync(processedXY, minX, maxY, rttSizeH, w, h, disposeWhenDone);
|
|
334
381
|
}
|
|
382
|
+
/**
|
|
383
|
+
* Execute a picking operation on box defined by two screen coordinates
|
|
384
|
+
* @param x1 defines the X coordinate of the first corner of the box where to run the pick
|
|
385
|
+
* @param y1 defines the Y coordinate of the first corner of the box where to run the pick
|
|
386
|
+
* @param x2 defines the X coordinate of the opposite corner of the box where to run the pick
|
|
387
|
+
* @param y2 defines the Y coordinate of the opposite corner of the box where to run the pick
|
|
388
|
+
* @param disposeWhenDone defines a boolean indicating we do not want to keep resources alive (false by default)
|
|
389
|
+
* @returns A promise with the picking results. Always returns an array with the same length as the number of coordinates. The mesh or null at the index where no mesh was picked.
|
|
390
|
+
*/
|
|
391
|
+
async boxPickAsync(x1, y1, x2, y2, disposeWhenDone = false) {
|
|
392
|
+
if (this._pickingInProgress) {
|
|
393
|
+
return null;
|
|
394
|
+
}
|
|
395
|
+
if (!this._pickableMeshes || this._pickableMeshes.length === 0) {
|
|
396
|
+
return null;
|
|
397
|
+
}
|
|
398
|
+
this._pickingInProgress = true;
|
|
399
|
+
const { rttSizeW, rttSizeH, devicePixelRatio } = this._getRenderInfo();
|
|
400
|
+
const { x: adjustedX1, y: adjustedY1 } = this._prepareForPicking(x1, y1, devicePixelRatio);
|
|
401
|
+
const { x: adjustedX2, y: adjustedY2 } = this._prepareForPicking(x2, y2, devicePixelRatio);
|
|
402
|
+
const minX = Math.max(Math.min(adjustedX1, adjustedX2), 0);
|
|
403
|
+
const maxX = Math.min(Math.max(adjustedX1, adjustedX2), rttSizeW - 1);
|
|
404
|
+
const minY = Math.max(Math.min(adjustedY1, adjustedY2), 0);
|
|
405
|
+
const maxY = Math.min(Math.max(adjustedY1, adjustedY2), rttSizeH - 1);
|
|
406
|
+
if (minX >= rttSizeW || minY >= rttSizeH || maxX < 0 || maxY < 0) {
|
|
407
|
+
this._pickingInProgress = false;
|
|
408
|
+
return null;
|
|
409
|
+
}
|
|
410
|
+
const w = Math.max(maxX - minX, 1);
|
|
411
|
+
const h = Math.max(maxY - minY, 1);
|
|
412
|
+
const partialCutH = rttSizeH - maxY - 1;
|
|
413
|
+
this._preparePickingBuffer(this._engine, rttSizeW, rttSizeH, minX, partialCutH, w, h);
|
|
414
|
+
return await this._executeBoxPickingAsync(minX, partialCutH, w, h, disposeWhenDone);
|
|
415
|
+
}
|
|
335
416
|
_getRenderInfo() {
|
|
336
417
|
const engine = this._cachedScene.getEngine();
|
|
337
418
|
const rttSizeW = engine.getRenderWidth();
|
|
@@ -362,8 +443,8 @@ export class GPUPicker {
|
|
|
362
443
|
this._pickingTexture.onBeforeRender = () => {
|
|
363
444
|
this._enableScissor(x, y, w, h);
|
|
364
445
|
};
|
|
365
|
-
this.
|
|
366
|
-
this.
|
|
446
|
+
this._pickingTextureAfterRenderObserver?.remove();
|
|
447
|
+
this._pickingTextureAfterRenderObserver = this._pickingTexture.onAfterRenderObservable.add(() => {
|
|
367
448
|
this._disableScissor();
|
|
368
449
|
});
|
|
369
450
|
this._cachedScene.customRenderTargets.push(this._pickingTexture);
|
|
@@ -445,6 +526,50 @@ export class GPUPicker {
|
|
|
445
526
|
};
|
|
446
527
|
});
|
|
447
528
|
}
|
|
529
|
+
// pick box area
|
|
530
|
+
async _executeBoxPickingAsync(x, y, w, h, disposeWhenDone) {
|
|
531
|
+
return await new Promise((resolve, reject) => {
|
|
532
|
+
if (!this._pickingTexture) {
|
|
533
|
+
this._pickingInProgress = false;
|
|
534
|
+
reject(new Error("Picking texture not created"));
|
|
535
|
+
return;
|
|
536
|
+
}
|
|
537
|
+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
538
|
+
this._pickingTexture.onAfterRender = async () => {
|
|
539
|
+
if (this._checkRenderStatus()) {
|
|
540
|
+
this._pickingTexture.onAfterRender = null;
|
|
541
|
+
const pickedMeshes = [];
|
|
542
|
+
const thinInstanceIndexes = [];
|
|
543
|
+
if (await this._readTexturePixelsAsync(x, y, w, h)) {
|
|
544
|
+
for (let offsetY = 0; offsetY < h; ++offsetY) {
|
|
545
|
+
for (let offsetX = 0; offsetX < w; ++offsetX) {
|
|
546
|
+
const colorId = this._getColorIdFromReadBuffer((offsetY * w + offsetX) * 4);
|
|
547
|
+
if (colorId > 0) {
|
|
548
|
+
// Thin?
|
|
549
|
+
if (this._thinIdMap[colorId]) {
|
|
550
|
+
const pickedMesh = this._pickableMeshes[this._thinIdMap[colorId].meshId];
|
|
551
|
+
const thinInstanceIndex = this._thinIdMap[colorId].thinId;
|
|
552
|
+
pickedMeshes.push(pickedMesh);
|
|
553
|
+
thinInstanceIndexes.push(thinInstanceIndex);
|
|
554
|
+
}
|
|
555
|
+
else {
|
|
556
|
+
const pickedMesh = this._pickableMeshes[this._idMap[colorId]];
|
|
557
|
+
pickedMeshes.push(pickedMesh);
|
|
558
|
+
thinInstanceIndexes.push(0);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
if (disposeWhenDone) {
|
|
565
|
+
this.dispose();
|
|
566
|
+
}
|
|
567
|
+
this._pickingInProgress = false;
|
|
568
|
+
resolve({ meshes: pickedMeshes, thinInstanceIndexes: thinInstanceIndexes });
|
|
569
|
+
}
|
|
570
|
+
};
|
|
571
|
+
});
|
|
572
|
+
}
|
|
448
573
|
_enableScissor(x, y, w = 1, h = 1) {
|
|
449
574
|
if (this._engine.enableScissor) {
|
|
450
575
|
this._engine.enableScissor(x, y, w, h);
|
|
@@ -459,8 +584,8 @@ export class GPUPicker {
|
|
|
459
584
|
* @returns true if rendering if the picking texture has finished, otherwise false
|
|
460
585
|
*/
|
|
461
586
|
_checkRenderStatus() {
|
|
462
|
-
const
|
|
463
|
-
if (
|
|
587
|
+
const wasSuccessful = this._meshRenderingCount > 0;
|
|
588
|
+
if (wasSuccessful) {
|
|
464
589
|
// Remove from the active RTTs
|
|
465
590
|
const index = this._cachedScene.customRenderTargets.indexOf(this._pickingTexture);
|
|
466
591
|
if (index > -1) {
|
|
@@ -516,15 +641,11 @@ export class GPUPicker {
|
|
|
516
641
|
// Cleaning up
|
|
517
642
|
this._pickingTexture?.dispose();
|
|
518
643
|
this._pickingTexture = null;
|
|
519
|
-
this.
|
|
520
|
-
this._defaultRenderMaterial = null;
|
|
644
|
+
this._clearPickingMaterials();
|
|
521
645
|
this._sceneBeforeRenderObserver?.remove();
|
|
522
646
|
this._sceneBeforeRenderObserver = null;
|
|
523
647
|
}
|
|
524
648
|
}
|
|
525
|
-
GPUPicker.
|
|
526
|
-
|
|
527
|
-
g: 0,
|
|
528
|
-
b: 0,
|
|
529
|
-
};
|
|
649
|
+
GPUPicker._AttributeName = "instanceMeshID";
|
|
650
|
+
GPUPicker._MaxPickingId = 0x00ffffff; // 24 bits unsigned integer max
|
|
530
651
|
//# sourceMappingURL=gpuPicker.js.map
|