@onerjs/core 8.34.4 → 8.34.6
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/Animations/animationGroup.d.ts +5 -0
- package/Animations/animationGroup.js +9 -0
- package/Animations/animationGroup.js.map +1 -1
- package/Cameras/Inputs/geospatialCameraKeyboardInput.js +6 -10
- package/Cameras/Inputs/geospatialCameraKeyboardInput.js.map +1 -1
- package/Cameras/Inputs/geospatialCameraMouseWheelInput.js +1 -1
- package/Cameras/Inputs/geospatialCameraMouseWheelInput.js.map +1 -1
- package/Cameras/Limits/geospatialLimits.d.ts +4 -22
- package/Cameras/Limits/geospatialLimits.js +4 -36
- package/Cameras/Limits/geospatialLimits.js.map +1 -1
- package/Cameras/geospatialCamera.d.ts +15 -4
- package/Cameras/geospatialCamera.js +72 -16
- package/Cameras/geospatialCamera.js.map +1 -1
- package/Cameras/geospatialCameraMovement.d.ts +1 -3
- package/Cameras/geospatialCameraMovement.js +13 -49
- package/Cameras/geospatialCameraMovement.js.map +1 -1
- package/Collisions/collisionCoordinator.d.ts +2 -2
- package/Collisions/collisionCoordinator.js +1 -0
- package/Collisions/collisionCoordinator.js.map +1 -1
- package/Engines/Extensions/engine.debugging.d.ts +3 -5
- package/Engines/Extensions/engine.debugging.js +3 -4
- package/Engines/Extensions/engine.debugging.js.map +1 -1
- package/Engines/WebGPU/Extensions/engine.debugging.js +15 -65
- package/Engines/WebGPU/Extensions/engine.debugging.js.map +1 -1
- package/Engines/WebGPU/webgpuTextureManager.js +9 -9
- package/Engines/WebGPU/webgpuTextureManager.js.map +1 -1
- package/Engines/abstractEngine.d.ts +2 -0
- package/Engines/abstractEngine.js +2 -0
- package/Engines/abstractEngine.js.map +1 -1
- package/Engines/thinWebGPUEngine.d.ts +0 -2
- package/Engines/thinWebGPUEngine.js +0 -8
- package/Engines/thinWebGPUEngine.js.map +1 -1
- package/Engines/webgpuEngine.d.ts +1 -3
- package/Engines/webgpuEngine.js +4 -10
- package/Engines/webgpuEngine.js.map +1 -1
- package/FrameGraph/Passes/renderPass.js +4 -9
- package/FrameGraph/Passes/renderPass.js.map +1 -1
- package/FrameGraph/Tasks/PostProcesses/postProcessTask.js +3 -0
- package/FrameGraph/Tasks/PostProcesses/postProcessTask.js.map +1 -1
- package/FrameGraph/Tasks/Rendering/geometryRendererTask.d.ts +1 -1
- package/FrameGraph/Tasks/Rendering/geometryRendererTask.js +4 -1
- package/FrameGraph/Tasks/Rendering/geometryRendererTask.js.map +1 -1
- package/FrameGraph/Tasks/Rendering/objectRendererTask.d.ts +2 -1
- package/FrameGraph/Tasks/Rendering/objectRendererTask.js +31 -7
- package/FrameGraph/Tasks/Rendering/objectRendererTask.js.map +1 -1
- package/FrameGraph/frameGraph.js +2 -2
- package/FrameGraph/frameGraph.js.map +1 -1
- package/FrameGraph/frameGraphContext.d.ts +9 -0
- package/FrameGraph/frameGraphContext.js +13 -2
- package/FrameGraph/frameGraphContext.js.map +1 -1
- package/FrameGraph/frameGraphObjectList.js.map +1 -1
- package/FrameGraph/frameGraphRenderContext.d.ts +9 -8
- package/FrameGraph/frameGraphRenderContext.js +23 -20
- package/FrameGraph/frameGraphRenderContext.js.map +1 -1
- package/FrameGraph/frameGraphTask.d.ts +2 -0
- package/FrameGraph/frameGraphTask.js +14 -4
- package/FrameGraph/frameGraphTask.js.map +1 -1
- package/Lights/Shadows/cascadedShadowGenerator.js +4 -1
- package/Lights/Shadows/cascadedShadowGenerator.js.map +1 -1
- package/Lights/Shadows/shadowGenerator.js +8 -3
- package/Lights/Shadows/shadowGenerator.js.map +1 -1
- package/Lights/lightingVolume.js +11 -6
- package/Lights/lightingVolume.js.map +1 -1
- package/Materials/Node/Blocks/Input/inputBlock.js +3 -0
- package/Materials/Node/Blocks/Input/inputBlock.js.map +1 -1
- package/Materials/Node/nodeMaterial.d.ts +1 -0
- package/Materials/Node/nodeMaterial.js +4 -0
- package/Materials/Node/nodeMaterial.js.map +1 -1
- package/Materials/Node/nodeMaterialBuildStateSharedData.d.ts +6 -0
- package/Materials/Node/nodeMaterialBuildStateSharedData.js +4 -0
- package/Materials/Node/nodeMaterialBuildStateSharedData.js.map +1 -1
- package/Materials/Textures/Loaders/iesTextureLoader.js +1 -1
- package/Materials/Textures/Loaders/iesTextureLoader.js.map +1 -1
- package/Materials/Textures/Procedurals/proceduralTexture.js +7 -2
- package/Materials/Textures/Procedurals/proceduralTexture.js.map +1 -1
- package/Materials/Textures/baseTexture.d.ts +5 -0
- package/Materials/Textures/baseTexture.js +9 -5
- package/Materials/Textures/baseTexture.js.map +1 -1
- package/Materials/Textures/internalTexture.d.ts +6 -4
- package/Materials/Textures/internalTexture.js +6 -4
- package/Materials/Textures/internalTexture.js.map +1 -1
- package/Materials/Textures/renderTargetTexture.js +2 -2
- package/Materials/Textures/renderTargetTexture.js.map +1 -1
- package/Materials/Textures/textureSampler.d.ts +3 -3
- package/Materials/Textures/textureSampler.js.map +1 -1
- package/Materials/material.d.ts +5 -0
- package/Materials/material.js +8 -0
- package/Materials/material.js.map +1 -1
- package/Misc/minMaxReducer.js +2 -2
- package/Misc/minMaxReducer.js.map +1 -1
- package/Particles/IParticleSystem.d.ts +4 -0
- package/Particles/IParticleSystem.js.map +1 -1
- package/Particles/baseParticleSystem.d.ts +5 -0
- package/Particles/baseParticleSystem.js +7 -0
- package/Particles/baseParticleSystem.js.map +1 -1
- package/Particles/gpuParticleSystem.js +1 -0
- package/Particles/gpuParticleSystem.js.map +1 -1
- package/Particles/thinParticleSystem.d.ts +0 -1
- package/Particles/thinParticleSystem.js +1 -1
- package/Particles/thinParticleSystem.js.map +1 -1
- package/PostProcesses/RenderPipeline/Pipelines/taaMaterialManager.js +4 -1
- package/PostProcesses/RenderPipeline/Pipelines/taaMaterialManager.js.map +1 -1
- package/Probes/reflectionProbe.js +9 -2
- package/Probes/reflectionProbe.js.map +1 -1
- package/Rendering/depthRenderer.js +7 -2
- package/Rendering/depthRenderer.js.map +1 -1
- package/Shaders/particles.vertex.js +8 -1
- package/Shaders/particles.vertex.js.map +1 -1
- package/ShadersWGSL/particles.vertex.js +6 -0
- package/ShadersWGSL/particles.vertex.js.map +1 -1
- package/package.json +1 -1
|
@@ -113,71 +113,35 @@ export class GeospatialCameraMovement extends CameraMovement {
|
|
|
113
113
|
this._panSpeedMultiplier = 1;
|
|
114
114
|
}
|
|
115
115
|
// If a pan drag is occurring, stop zooming.
|
|
116
|
+
let zoomTargetDistance;
|
|
116
117
|
if (this.isDragging) {
|
|
117
118
|
this._zoomSpeedMultiplier = 0;
|
|
118
119
|
this._zoomVelocity = 0;
|
|
119
120
|
}
|
|
120
121
|
else {
|
|
121
|
-
|
|
122
|
-
|
|
122
|
+
zoomTargetDistance = this.computedPerFrameZoomPickPoint ? Vector3Distance(this._cameraPosition, this.computedPerFrameZoomPickPoint) : undefined;
|
|
123
|
+
// Scales zoom movement speed based on camera distance to zoom target.
|
|
124
|
+
this._zoomSpeedMultiplier = (zoomTargetDistance ?? Vector3Distance(this._cameraPosition, cameraCenter)) * 0.01;
|
|
123
125
|
}
|
|
124
|
-
// Before zero-ing out pixel deltas, capture if we have any active zoom in this frame (compared to zoom from inertia)
|
|
125
|
-
const activeZoom = Math.abs(this.zoomAccumulatedPixels) > 0;
|
|
126
126
|
super.computeCurrentFrameDeltas();
|
|
127
|
-
this._handleZoom(activeZoom);
|
|
128
127
|
}
|
|
129
128
|
get isDragging() {
|
|
130
129
|
return this._hitPointRadius !== undefined;
|
|
131
130
|
}
|
|
132
|
-
|
|
133
|
-
if (
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
pickDistance = this._storedZoomPickDistance;
|
|
131
|
+
handleZoom(zoomDelta, toCursor) {
|
|
132
|
+
if (zoomDelta !== 0) {
|
|
133
|
+
this.zoomAccumulatedPixels += zoomDelta;
|
|
134
|
+
const pickResult = this._scene.pick(this._scene.pointerX, this._scene.pointerY, this.pickPredicate);
|
|
135
|
+
if (toCursor && pickResult.hit && pickResult.pickedPoint && pickResult.ray && this.zoomToCursor) {
|
|
136
|
+
this.computedPerFrameZoomPickPoint = pickResult.pickedPoint;
|
|
139
137
|
}
|
|
140
138
|
else {
|
|
141
|
-
//
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
// Store both the zoom picked point and the pick distance for use during inertia
|
|
145
|
-
pickDistance = pickResult.distance;
|
|
146
|
-
this._storedZoomPickDistance = pickDistance;
|
|
147
|
-
this.computedPerFrameZoomPickPoint = pickResult.pickedPoint;
|
|
148
|
-
}
|
|
149
|
-
else {
|
|
150
|
-
// If no hit under cursor, zoom along lookVector instead
|
|
151
|
-
const lookPickResult = this.pickAlongVector(this._cameraLookAt);
|
|
152
|
-
pickDistance = lookPickResult?.distance;
|
|
153
|
-
this._storedZoomPickDistance = pickDistance;
|
|
154
|
-
this.computedPerFrameZoomPickPoint = undefined;
|
|
155
|
-
}
|
|
139
|
+
// If no hit under cursor or explicitly told not to zoom to cursor, zoom along lookVector instead
|
|
140
|
+
const lookPickResult = this.pickAlongVector(this._cameraLookAt);
|
|
141
|
+
this.computedPerFrameZoomPickPoint = lookPickResult?.pickedPoint ?? undefined;
|
|
156
142
|
}
|
|
157
|
-
// Clamp distance based on limits and update center
|
|
158
|
-
this._clampZoomDistance(this.zoomDeltaCurrentFrame, pickDistance);
|
|
159
143
|
}
|
|
160
144
|
}
|
|
161
|
-
_clampZoomDistance(requestedDistance, pickResultDistance) {
|
|
162
|
-
// If pickResult is defined
|
|
163
|
-
if (requestedDistance > 0) {
|
|
164
|
-
if (pickResultDistance !== undefined) {
|
|
165
|
-
// If there is a pick, allow movement up to pick - minAltitude
|
|
166
|
-
if (pickResultDistance - this.limits.altitudeMin < 0) {
|
|
167
|
-
this.zoomDeltaCurrentFrame = 0;
|
|
168
|
-
}
|
|
169
|
-
this.zoomDeltaCurrentFrame = Math.min(requestedDistance, pickResultDistance - this.limits.altitudeMin);
|
|
170
|
-
}
|
|
171
|
-
else {
|
|
172
|
-
this.zoomDeltaCurrentFrame = requestedDistance;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
if (requestedDistance < 0) {
|
|
176
|
-
const maxZoomOut = this.limits.radiusMax ? this.limits.radiusMax - this._cameraPosition.length() : Number.POSITIVE_INFINITY;
|
|
177
|
-
this.zoomDeltaCurrentFrame = Math.max(requestedDistance, -maxZoomOut);
|
|
178
|
-
}
|
|
179
|
-
return this.zoomDeltaCurrentFrame;
|
|
180
|
-
}
|
|
181
145
|
pickAlongVector(vector) {
|
|
182
146
|
this._tempPickingRay.origin.copyFrom(this._cameraPosition);
|
|
183
147
|
this._tempPickingRay.direction.copyFrom(vector);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"geospatialCameraMovement.js","sourceRoot":"","sources":["../../../../dev/core/src/Cameras/geospatialCameraMovement.ts"],"names":[],"mappings":"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","sourcesContent":["import { CameraMovement } from \"./cameraMovement\";\r\nimport { Epsilon } from \"../Maths/math.constants\";\r\nimport type { GeospatialLimits } from \"./Limits/geospatialLimits\";\r\nimport { Matrix, TmpVectors, Vector3 } from \"../Maths/math.vector\";\r\nimport type { MeshPredicate } from \"../Culling/ray.core\";\r\nimport { Plane } from \"../Maths/math.plane\";\r\nimport { Ray } from \"../Culling/ray\";\r\nimport type { Scene } from \"../scene\";\r\nimport { Vector3Distance } from \"../Maths/math.vector.functions\";\r\nimport { Clamp } from \"../Maths/math.scalar.functions\";\r\nimport type { PickingInfo } from \"../Collisions/pickingInfo\";\r\nimport type { Nullable } from \"../types\";\r\nimport type { InterpolatingBehavior } from \"../Behaviors/Cameras/interpolatingBehavior\";\r\nimport type { GeospatialCamera } from \"./geospatialCamera\";\r\n\r\n/**\r\n * @experimental\r\n * This class is subject to change as the geospatial camera evolves.\r\n *\r\n * Geospatial-specific camera movement system that extends the base movement with\r\n * raycasting and altitude-aware zoom constraints.\r\n *\r\n * This class encapsulates geospatial camera movement logic:\r\n * - Dragging in a way which keeps cursor anchored to globe\r\n * - Latitude-based pan speed dampening\r\n * - Zoom speed scaling based on distance to center\r\n * - Raycasting to determine zoom constraints based on terrain/globe\r\n * - Altitude-based zoom clamping\r\n * - Zoom direction calculation (towards cursor vs along look vector)\r\n */\r\nexport class GeospatialCameraMovement extends CameraMovement {\r\n /** Predicate function to determine which meshes to pick against (e.g., globe mesh) */\r\n public pickPredicate?: MeshPredicate;\r\n\r\n /** World-space picked point under cursor for zoom-to-cursor behavior (may be undefined) */\r\n public computedPerFrameZoomPickPoint?: Vector3;\r\n\r\n public zoomToCursor: boolean = true;\r\n\r\n private _tempPickingRay: Ray;\r\n private _storedZoomPickDistance: number | undefined;\r\n\r\n private _hitPointRadius?: number = undefined;\r\n private _dragPlane: Plane = new Plane(0, 0, 0, 0);\r\n private _dragPlaneNormal: Vector3 = Vector3.Zero();\r\n private _dragPlaneOriginPointEcef: Vector3 = Vector3.Zero();\r\n private _dragPlaneHitPointLocal: Vector3 = Vector3.Zero();\r\n private _previousDragPlaneHitPointLocal: Vector3 = Vector3.Zero();\r\n\r\n constructor(\r\n scene: Scene,\r\n public limits: GeospatialLimits,\r\n cameraPosition: Vector3,\r\n private _cameraCenter: Vector3,\r\n private _cameraLookAt: Vector3,\r\n pickPredicate?: MeshPredicate,\r\n behavior?: InterpolatingBehavior<GeospatialCamera>\r\n ) {\r\n super(scene, cameraPosition, behavior);\r\n this.pickPredicate = pickPredicate;\r\n this._tempPickingRay = new Ray(this._cameraPosition, this._cameraLookAt);\r\n this.panInertia = 0;\r\n this.rotationInertia = 0;\r\n this.rotationXSpeed = Math.PI / 500; // Move 1/500th of a half circle per pixel\r\n this.rotationYSpeed = Math.PI / 500; // Move 1/500th of a half circle per pixel\r\n }\r\n\r\n public startDrag(pointerX: number, pointerY: number) {\r\n const pickResult = this._scene.pick(pointerX, pointerY, this.pickPredicate);\r\n if (pickResult.pickedPoint && pickResult.ray) {\r\n // Store radius from earth center to pickedPoint, used when calculating drag plane\r\n this._hitPointRadius = pickResult.pickedPoint.length();\r\n\r\n this._recalculateDragPlaneHitPoint(this._hitPointRadius, pickResult.ray, TmpVectors.Matrix[0]);\r\n this._previousDragPlaneHitPointLocal.copyFrom(this._dragPlaneHitPointLocal);\r\n } else {\r\n this._hitPointRadius = undefined; // can't drag without a hit on the globe\r\n }\r\n }\r\n\r\n public stopDrag() {\r\n this._hitPointRadius = undefined;\r\n }\r\n\r\n /**\r\n * The previous drag plane hit point in local space is stored to compute the movement delta.\r\n * As the drag movement occurs, we will continuously recalculate this point. The delta between the previous and current hit points is the delta we will apply to the camera's localtranslation\r\n * @param hitPointRadius The distance between the world origin (center of globe) and the initial drag hit point\r\n * @param ray The ray from the camera to the new cursor location\r\n * @param localToEcefResult The matrix to convert from local to ECEF space\r\n */\r\n private _recalculateDragPlaneHitPoint(hitPointRadius: number, ray: Ray, localToEcefResult: Matrix): void {\r\n // Use the camera's geocentric normal to find the dragPlaneOriginPoint which lives at hitPointRadius along the camera's geocentric normal\r\n this._cameraPosition.normalizeToRef(this._dragPlaneNormal);\r\n this._dragPlaneNormal.scaleToRef(hitPointRadius, this._dragPlaneOriginPointEcef);\r\n\r\n // The dragPlaneOffsetVector will later be recalculated when drag occurs, and the delta between the offset vectors will be applied to localTranslation\r\n ComputeLocalBasisToRefs(this._dragPlaneOriginPointEcef, TmpVectors.Vector3[0], TmpVectors.Vector3[1], TmpVectors.Vector3[2]);\r\n const localToEcef = Matrix.FromXYZAxesToRef(TmpVectors.Vector3[0], TmpVectors.Vector3[1], TmpVectors.Vector3[2], localToEcefResult);\r\n localToEcef.setTranslationFromFloats(this._dragPlaneOriginPointEcef.x, this._dragPlaneOriginPointEcef.y, this._dragPlaneOriginPointEcef.z);\r\n const ecefToLocal = localToEcef.invertToRef(TmpVectors.Matrix[1]);\r\n\r\n // Now create a plane at that point, perpendicular to the camera's geocentric normal\r\n Plane.FromPositionAndNormalToRef(this._dragPlaneOriginPointEcef, this._dragPlaneNormal, this._dragPlane);\r\n\r\n // Lastly, find the _dragPlaneHitPoint where the ray intersects the _dragPlane.\r\n if (IntersectRayWithPlaneToRef(ray, this._dragPlane, this._dragPlaneHitPointLocal)) {\r\n // If hit, convert the drag plane hit point into the local space.\r\n Vector3.TransformCoordinatesToRef(this._dragPlaneHitPointLocal, ecefToLocal, this._dragPlaneHitPointLocal);\r\n }\r\n }\r\n\r\n public handleDrag(pointerX: number, pointerY: number) {\r\n if (this._hitPointRadius) {\r\n const pickResult = this._scene.pick(pointerX, pointerY);\r\n if (pickResult.ray) {\r\n const localToEcef = TmpVectors.Matrix[0];\r\n this._recalculateDragPlaneHitPoint(this._hitPointRadius, pickResult.ray, localToEcef);\r\n\r\n const delta = this._dragPlaneHitPointLocal.subtractToRef(this._previousDragPlaneHitPointLocal, TmpVectors.Vector3[6]);\r\n this._previousDragPlaneHitPointLocal.copyFrom(this._dragPlaneHitPointLocal);\r\n\r\n Vector3.TransformNormalToRef(delta, localToEcef, delta);\r\n this._dragPlaneOriginPointEcef.addInPlace(delta);\r\n\r\n this.panAccumulatedPixels.subtractInPlace(delta);\r\n }\r\n }\r\n }\r\n\r\n /** @override */\r\n public override computeCurrentFrameDeltas(): void {\r\n const cameraCenter = this._cameraCenter;\r\n\r\n // Slows down panning near the poles\r\n if (this.panAccumulatedPixels.lengthSquared() > Epsilon) {\r\n const centerRadius = cameraCenter.length(); // distance from planet origin to camera center\r\n const currentRadius = this._cameraPosition.length();\r\n // Dampen the pan speed based on latitude (slower near poles)\r\n const sineOfSphericalLat = centerRadius === 0 ? 0 : cameraCenter.z / centerRadius;\r\n const cosOfSphericalLat = Math.sqrt(1 - Math.min(1, sineOfSphericalLat * sineOfSphericalLat));\r\n const latitudeDampening = Math.sqrt(Math.abs(cosOfSphericalLat)); // sqrt here reduces effect near equator\r\n\r\n // Reduce the dampening effect near surface (so that at ground level, pan speed is not affected by latitude)\r\n const height = Math.max(currentRadius - centerRadius, Epsilon);\r\n const latitudeDampeningScale = Math.max(1, centerRadius / height);\r\n\r\n this._panSpeedMultiplier = Clamp(latitudeDampeningScale * latitudeDampening, 0, 1);\r\n } else {\r\n this._panSpeedMultiplier = 1;\r\n }\r\n\r\n // If a pan drag is occurring, stop zooming.\r\n if (this.isDragging) {\r\n this._zoomSpeedMultiplier = 0;\r\n this._zoomVelocity = 0;\r\n } else {\r\n // Scales zoom movement speed based on camera distance to origin (so long as no active pan is occurring)\r\n this._zoomSpeedMultiplier = Vector3Distance(this._cameraPosition, cameraCenter) * 0.01;\r\n }\r\n\r\n // Before zero-ing out pixel deltas, capture if we have any active zoom in this frame (compared to zoom from inertia)\r\n const activeZoom = Math.abs(this.zoomAccumulatedPixels) > 0;\r\n super.computeCurrentFrameDeltas();\r\n\r\n this._handleZoom(activeZoom);\r\n }\r\n\r\n public get isDragging() {\r\n return this._hitPointRadius !== undefined;\r\n }\r\n\r\n private _handleZoom(activeZoom: boolean) {\r\n if (Math.abs(this.zoomDeltaCurrentFrame) > Epsilon) {\r\n let pickDistance: number | undefined;\r\n\r\n if (!activeZoom) {\r\n // During inertia, use the previously stored pick distance\r\n // TODO fix this to work with raycasting\r\n pickDistance = this._storedZoomPickDistance;\r\n } else {\r\n // Active zoom - pick and store the distance\r\n const pickResult = this._scene.pick(this._scene.pointerX, this._scene.pointerY, this.pickPredicate);\r\n\r\n if (pickResult.hit && pickResult.pickedPoint && pickResult.ray && this.zoomToCursor) {\r\n // Store both the zoom picked point and the pick distance for use during inertia\r\n pickDistance = pickResult.distance;\r\n this._storedZoomPickDistance = pickDistance;\r\n this.computedPerFrameZoomPickPoint = pickResult.pickedPoint;\r\n } else {\r\n // If no hit under cursor, zoom along lookVector instead\r\n const lookPickResult = this.pickAlongVector(this._cameraLookAt);\r\n pickDistance = lookPickResult?.distance;\r\n this._storedZoomPickDistance = pickDistance;\r\n this.computedPerFrameZoomPickPoint = undefined;\r\n }\r\n }\r\n\r\n // Clamp distance based on limits and update center\r\n this._clampZoomDistance(this.zoomDeltaCurrentFrame, pickDistance);\r\n }\r\n }\r\n\r\n private _clampZoomDistance(requestedDistance: number, pickResultDistance: number | undefined): number {\r\n // If pickResult is defined\r\n if (requestedDistance > 0) {\r\n if (pickResultDistance !== undefined) {\r\n // If there is a pick, allow movement up to pick - minAltitude\r\n if (pickResultDistance - this.limits.altitudeMin < 0) {\r\n this.zoomDeltaCurrentFrame = 0;\r\n }\r\n this.zoomDeltaCurrentFrame = Math.min(requestedDistance, pickResultDistance - this.limits.altitudeMin);\r\n } else {\r\n this.zoomDeltaCurrentFrame = requestedDistance;\r\n }\r\n }\r\n\r\n if (requestedDistance < 0) {\r\n const maxZoomOut = this.limits.radiusMax ? this.limits.radiusMax - this._cameraPosition.length() : Number.POSITIVE_INFINITY;\r\n this.zoomDeltaCurrentFrame = Math.max(requestedDistance, -maxZoomOut);\r\n }\r\n\r\n return this.zoomDeltaCurrentFrame;\r\n }\r\n\r\n public pickAlongVector(vector: Vector3): Nullable<PickingInfo> {\r\n this._tempPickingRay.origin.copyFrom(this._cameraPosition);\r\n this._tempPickingRay.direction.copyFrom(vector);\r\n return this._scene.pickWithRay(this._tempPickingRay, this.pickPredicate);\r\n }\r\n}\r\n\r\nexport function ClampCenterFromPolesInPlace(center: Vector3) {\r\n const sineOfSphericalLatitudeLimit = 0.998749218; // ~90 degrees\r\n const centerMagnitude = center.length(); // distance from planet origin\r\n if (centerMagnitude > Epsilon) {\r\n const sineSphericalLat = centerMagnitude === 0 ? 0 : center.z / centerMagnitude;\r\n if (Math.abs(sineSphericalLat) > sineOfSphericalLatitudeLimit) {\r\n // Clamp the spherical latitude (and derive longitude)\r\n const sineOfClampedSphericalLat = Clamp(sineSphericalLat, -sineOfSphericalLatitudeLimit, sineOfSphericalLatitudeLimit);\r\n const cosineOfClampedSphericalLat = Math.sqrt(1 - sineOfClampedSphericalLat * sineOfClampedSphericalLat);\r\n const longitude = Math.atan2(center.y, center.x);\r\n\r\n // Spherical to Cartesian\r\n const newX = centerMagnitude * Math.cos(longitude) * cosineOfClampedSphericalLat;\r\n const newY = centerMagnitude * Math.sin(longitude) * cosineOfClampedSphericalLat;\r\n const newZ = centerMagnitude * sineOfClampedSphericalLat;\r\n\r\n center.set(newX, newY, newZ);\r\n }\r\n }\r\n return center;\r\n}\r\n\r\nfunction IntersectRayWithPlaneToRef(ray: Ray, plane: Plane, ref: Vector3): boolean {\r\n // Distance along the ray to the plane; null if no hit\r\n const dist = ray.intersectsPlane(plane);\r\n\r\n if (dist !== null && dist >= 0) {\r\n ray.origin.addToRef(ray.direction.scaleToRef(dist, TmpVectors.Vector3[0]), ref);\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Helper to build east/north/up basis vectors at a world position.\r\n * @internal\r\n */\r\nexport function ComputeLocalBasisToRefs(worldPos: Vector3, refEast: Vector3, refNorth: Vector3, refUp: Vector3) {\r\n // up = normalized position (geocentric normal)\r\n refUp.copyFrom(worldPos).normalize();\r\n\r\n // east = normalize(worldNorth × up)\r\n // (cross product of Earth rotation axis with up gives east except near poles)\r\n const worldNorth = Vector3.LeftHandedForwardReadOnly; // (0,0,1)\r\n Vector3.CrossToRef(worldNorth, refUp, refEast);\r\n\r\n // at poles, cross with worldRight instead\r\n if (refEast.lengthSquared() < Epsilon) {\r\n Vector3.CrossToRef(Vector3.Right(), refUp, refEast);\r\n }\r\n refEast.normalize();\r\n\r\n // north = up × east (completes right-handed basis)\r\n Vector3.CrossToRef(refUp, refEast, refNorth);\r\n refNorth.normalize();\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"geospatialCameraMovement.js","sourceRoot":"","sources":["../../../../dev/core/src/Cameras/geospatialCameraMovement.ts"],"names":[],"mappings":"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","sourcesContent":["import { CameraMovement } from \"./cameraMovement\";\r\nimport { Epsilon } from \"../Maths/math.constants\";\r\nimport type { GeospatialLimits } from \"./Limits/geospatialLimits\";\r\nimport { Matrix, TmpVectors, Vector3 } from \"../Maths/math.vector\";\r\nimport type { MeshPredicate } from \"../Culling/ray.core\";\r\nimport { Plane } from \"../Maths/math.plane\";\r\nimport { Ray } from \"../Culling/ray\";\r\nimport type { Scene } from \"../scene\";\r\nimport { Vector3Distance } from \"../Maths/math.vector.functions\";\r\nimport { Clamp } from \"../Maths/math.scalar.functions\";\r\nimport type { PickingInfo } from \"../Collisions/pickingInfo\";\r\nimport type { Nullable } from \"../types\";\r\nimport type { InterpolatingBehavior } from \"../Behaviors/Cameras/interpolatingBehavior\";\r\nimport type { GeospatialCamera } from \"./geospatialCamera\";\r\n\r\n/**\r\n * @experimental\r\n * This class is subject to change as the geospatial camera evolves.\r\n *\r\n * Geospatial-specific camera movement system that extends the base movement with\r\n * raycasting and altitude-aware zoom constraints.\r\n *\r\n * This class encapsulates geospatial camera movement logic:\r\n * - Dragging in a way which keeps cursor anchored to globe\r\n * - Latitude-based pan speed dampening\r\n * - Zoom speed scaling based on distance to center\r\n * - Raycasting to determine zoom constraints based on terrain/globe\r\n * - Altitude-based zoom clamping\r\n * - Zoom direction calculation (towards cursor vs along look vector)\r\n */\r\nexport class GeospatialCameraMovement extends CameraMovement {\r\n /** Predicate function to determine which meshes to pick against (e.g., globe mesh) */\r\n public pickPredicate?: MeshPredicate;\r\n\r\n /** World-space picked point under cursor for zoom-to-cursor behavior (may be undefined) */\r\n public computedPerFrameZoomPickPoint?: Vector3;\r\n\r\n public zoomToCursor: boolean = true;\r\n\r\n private _tempPickingRay: Ray;\r\n\r\n private _hitPointRadius?: number = undefined;\r\n private _dragPlane: Plane = new Plane(0, 0, 0, 0);\r\n private _dragPlaneNormal: Vector3 = Vector3.Zero();\r\n private _dragPlaneOriginPointEcef: Vector3 = Vector3.Zero();\r\n private _dragPlaneHitPointLocal: Vector3 = Vector3.Zero();\r\n private _previousDragPlaneHitPointLocal: Vector3 = Vector3.Zero();\r\n\r\n constructor(\r\n scene: Scene,\r\n public limits: GeospatialLimits,\r\n cameraPosition: Vector3,\r\n private _cameraCenter: Vector3,\r\n private _cameraLookAt: Vector3,\r\n pickPredicate?: MeshPredicate,\r\n behavior?: InterpolatingBehavior<GeospatialCamera>\r\n ) {\r\n super(scene, cameraPosition, behavior);\r\n this.pickPredicate = pickPredicate;\r\n this._tempPickingRay = new Ray(this._cameraPosition, this._cameraLookAt);\r\n this.panInertia = 0;\r\n this.rotationInertia = 0;\r\n this.rotationXSpeed = Math.PI / 500; // Move 1/500th of a half circle per pixel\r\n this.rotationYSpeed = Math.PI / 500; // Move 1/500th of a half circle per pixel\r\n }\r\n\r\n public startDrag(pointerX: number, pointerY: number) {\r\n const pickResult = this._scene.pick(pointerX, pointerY, this.pickPredicate);\r\n if (pickResult.pickedPoint && pickResult.ray) {\r\n // Store radius from earth center to pickedPoint, used when calculating drag plane\r\n this._hitPointRadius = pickResult.pickedPoint.length();\r\n\r\n this._recalculateDragPlaneHitPoint(this._hitPointRadius, pickResult.ray, TmpVectors.Matrix[0]);\r\n this._previousDragPlaneHitPointLocal.copyFrom(this._dragPlaneHitPointLocal);\r\n } else {\r\n this._hitPointRadius = undefined; // can't drag without a hit on the globe\r\n }\r\n }\r\n\r\n public stopDrag() {\r\n this._hitPointRadius = undefined;\r\n }\r\n\r\n /**\r\n * The previous drag plane hit point in local space is stored to compute the movement delta.\r\n * As the drag movement occurs, we will continuously recalculate this point. The delta between the previous and current hit points is the delta we will apply to the camera's localtranslation\r\n * @param hitPointRadius The distance between the world origin (center of globe) and the initial drag hit point\r\n * @param ray The ray from the camera to the new cursor location\r\n * @param localToEcefResult The matrix to convert from local to ECEF space\r\n */\r\n private _recalculateDragPlaneHitPoint(hitPointRadius: number, ray: Ray, localToEcefResult: Matrix): void {\r\n // Use the camera's geocentric normal to find the dragPlaneOriginPoint which lives at hitPointRadius along the camera's geocentric normal\r\n this._cameraPosition.normalizeToRef(this._dragPlaneNormal);\r\n this._dragPlaneNormal.scaleToRef(hitPointRadius, this._dragPlaneOriginPointEcef);\r\n\r\n // The dragPlaneOffsetVector will later be recalculated when drag occurs, and the delta between the offset vectors will be applied to localTranslation\r\n ComputeLocalBasisToRefs(this._dragPlaneOriginPointEcef, TmpVectors.Vector3[0], TmpVectors.Vector3[1], TmpVectors.Vector3[2]);\r\n const localToEcef = Matrix.FromXYZAxesToRef(TmpVectors.Vector3[0], TmpVectors.Vector3[1], TmpVectors.Vector3[2], localToEcefResult);\r\n localToEcef.setTranslationFromFloats(this._dragPlaneOriginPointEcef.x, this._dragPlaneOriginPointEcef.y, this._dragPlaneOriginPointEcef.z);\r\n const ecefToLocal = localToEcef.invertToRef(TmpVectors.Matrix[1]);\r\n\r\n // Now create a plane at that point, perpendicular to the camera's geocentric normal\r\n Plane.FromPositionAndNormalToRef(this._dragPlaneOriginPointEcef, this._dragPlaneNormal, this._dragPlane);\r\n\r\n // Lastly, find the _dragPlaneHitPoint where the ray intersects the _dragPlane.\r\n if (IntersectRayWithPlaneToRef(ray, this._dragPlane, this._dragPlaneHitPointLocal)) {\r\n // If hit, convert the drag plane hit point into the local space.\r\n Vector3.TransformCoordinatesToRef(this._dragPlaneHitPointLocal, ecefToLocal, this._dragPlaneHitPointLocal);\r\n }\r\n }\r\n\r\n public handleDrag(pointerX: number, pointerY: number) {\r\n if (this._hitPointRadius) {\r\n const pickResult = this._scene.pick(pointerX, pointerY);\r\n if (pickResult.ray) {\r\n const localToEcef = TmpVectors.Matrix[0];\r\n this._recalculateDragPlaneHitPoint(this._hitPointRadius, pickResult.ray, localToEcef);\r\n\r\n const delta = this._dragPlaneHitPointLocal.subtractToRef(this._previousDragPlaneHitPointLocal, TmpVectors.Vector3[6]);\r\n this._previousDragPlaneHitPointLocal.copyFrom(this._dragPlaneHitPointLocal);\r\n\r\n Vector3.TransformNormalToRef(delta, localToEcef, delta);\r\n this._dragPlaneOriginPointEcef.addInPlace(delta);\r\n\r\n this.panAccumulatedPixels.subtractInPlace(delta);\r\n }\r\n }\r\n }\r\n\r\n /** @override */\r\n public override computeCurrentFrameDeltas(): void {\r\n const cameraCenter = this._cameraCenter;\r\n\r\n // Slows down panning near the poles\r\n if (this.panAccumulatedPixels.lengthSquared() > Epsilon) {\r\n const centerRadius = cameraCenter.length(); // distance from planet origin to camera center\r\n const currentRadius = this._cameraPosition.length();\r\n // Dampen the pan speed based on latitude (slower near poles)\r\n const sineOfSphericalLat = centerRadius === 0 ? 0 : cameraCenter.z / centerRadius;\r\n const cosOfSphericalLat = Math.sqrt(1 - Math.min(1, sineOfSphericalLat * sineOfSphericalLat));\r\n const latitudeDampening = Math.sqrt(Math.abs(cosOfSphericalLat)); // sqrt here reduces effect near equator\r\n\r\n // Reduce the dampening effect near surface (so that at ground level, pan speed is not affected by latitude)\r\n const height = Math.max(currentRadius - centerRadius, Epsilon);\r\n const latitudeDampeningScale = Math.max(1, centerRadius / height);\r\n\r\n this._panSpeedMultiplier = Clamp(latitudeDampeningScale * latitudeDampening, 0, 1);\r\n } else {\r\n this._panSpeedMultiplier = 1;\r\n }\r\n\r\n // If a pan drag is occurring, stop zooming.\r\n let zoomTargetDistance: number | undefined;\r\n if (this.isDragging) {\r\n this._zoomSpeedMultiplier = 0;\r\n this._zoomVelocity = 0;\r\n } else {\r\n zoomTargetDistance = this.computedPerFrameZoomPickPoint ? Vector3Distance(this._cameraPosition, this.computedPerFrameZoomPickPoint) : undefined;\r\n\r\n // Scales zoom movement speed based on camera distance to zoom target.\r\n this._zoomSpeedMultiplier = (zoomTargetDistance ?? Vector3Distance(this._cameraPosition, cameraCenter)) * 0.01;\r\n }\r\n\r\n super.computeCurrentFrameDeltas();\r\n }\r\n\r\n public get isDragging() {\r\n return this._hitPointRadius !== undefined;\r\n }\r\n\r\n public handleZoom(zoomDelta: number, toCursor: boolean) {\r\n if (zoomDelta !== 0) {\r\n this.zoomAccumulatedPixels += zoomDelta;\r\n\r\n const pickResult = this._scene.pick(this._scene.pointerX, this._scene.pointerY, this.pickPredicate);\r\n\r\n if (toCursor && pickResult.hit && pickResult.pickedPoint && pickResult.ray && this.zoomToCursor) {\r\n this.computedPerFrameZoomPickPoint = pickResult.pickedPoint;\r\n } else {\r\n // If no hit under cursor or explicitly told not to zoom to cursor, zoom along lookVector instead\r\n const lookPickResult = this.pickAlongVector(this._cameraLookAt);\r\n this.computedPerFrameZoomPickPoint = lookPickResult?.pickedPoint ?? undefined;\r\n }\r\n }\r\n }\r\n\r\n public pickAlongVector(vector: Vector3): Nullable<PickingInfo> {\r\n this._tempPickingRay.origin.copyFrom(this._cameraPosition);\r\n this._tempPickingRay.direction.copyFrom(vector);\r\n return this._scene.pickWithRay(this._tempPickingRay, this.pickPredicate);\r\n }\r\n}\r\n\r\nexport function ClampCenterFromPolesInPlace(center: Vector3) {\r\n const sineOfSphericalLatitudeLimit = 0.998749218; // ~90 degrees\r\n const centerMagnitude = center.length(); // distance from planet origin\r\n if (centerMagnitude > Epsilon) {\r\n const sineSphericalLat = centerMagnitude === 0 ? 0 : center.z / centerMagnitude;\r\n if (Math.abs(sineSphericalLat) > sineOfSphericalLatitudeLimit) {\r\n // Clamp the spherical latitude (and derive longitude)\r\n const sineOfClampedSphericalLat = Clamp(sineSphericalLat, -sineOfSphericalLatitudeLimit, sineOfSphericalLatitudeLimit);\r\n const cosineOfClampedSphericalLat = Math.sqrt(1 - sineOfClampedSphericalLat * sineOfClampedSphericalLat);\r\n const longitude = Math.atan2(center.y, center.x);\r\n\r\n // Spherical to Cartesian\r\n const newX = centerMagnitude * Math.cos(longitude) * cosineOfClampedSphericalLat;\r\n const newY = centerMagnitude * Math.sin(longitude) * cosineOfClampedSphericalLat;\r\n const newZ = centerMagnitude * sineOfClampedSphericalLat;\r\n\r\n center.set(newX, newY, newZ);\r\n }\r\n }\r\n return center;\r\n}\r\n\r\nfunction IntersectRayWithPlaneToRef(ray: Ray, plane: Plane, ref: Vector3): boolean {\r\n // Distance along the ray to the plane; null if no hit\r\n const dist = ray.intersectsPlane(plane);\r\n\r\n if (dist !== null && dist >= 0) {\r\n ray.origin.addToRef(ray.direction.scaleToRef(dist, TmpVectors.Vector3[0]), ref);\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Helper to build east/north/up basis vectors at a world position.\r\n * @internal\r\n */\r\nexport function ComputeLocalBasisToRefs(worldPos: Vector3, refEast: Vector3, refNorth: Vector3, refUp: Vector3) {\r\n // up = normalized position (geocentric normal)\r\n refUp.copyFrom(worldPos).normalize();\r\n\r\n // east = normalize(worldNorth × up)\r\n // (cross product of Earth rotation axis with up gives east except near poles)\r\n const worldNorth = Vector3.LeftHandedForwardReadOnly; // (0,0,1)\r\n Vector3.CrossToRef(worldNorth, refUp, refEast);\r\n\r\n // at poles, cross with worldRight instead\r\n if (refEast.lengthSquared() < Epsilon) {\r\n Vector3.CrossToRef(Vector3.Right(), refUp, refEast);\r\n }\r\n refEast.normalize();\r\n\r\n // north = up × east (completes right-handed basis)\r\n Vector3.CrossToRef(refUp, refEast, refNorth);\r\n refNorth.normalize();\r\n}\r\n"]}
|
|
@@ -6,7 +6,7 @@ import type { AbstractMesh } from "../Meshes/abstractMesh.js";
|
|
|
6
6
|
/** @internal */
|
|
7
7
|
export interface ICollisionCoordinator {
|
|
8
8
|
createCollider(): Collider;
|
|
9
|
-
getNewPosition(position: Vector3, displacement: Vector3, collider: Collider, maximumRetry: number, excludedMesh: Nullable<AbstractMesh>, onNewPosition: (collisionIndex: number, newPosition: Vector3, collidedMesh: Nullable<AbstractMesh>) => void, collisionIndex: number, slideOnCollide?: boolean):
|
|
9
|
+
getNewPosition(position: Vector3, displacement: Vector3, collider: Collider, maximumRetry: number, excludedMesh: Nullable<AbstractMesh>, onNewPosition: (collisionIndex: number, newPosition: Vector3, collidedMesh: Nullable<AbstractMesh>) => void, collisionIndex: number, slideOnCollide?: boolean): Vector3;
|
|
10
10
|
init(scene: Scene): void;
|
|
11
11
|
}
|
|
12
12
|
/** @internal */
|
|
@@ -15,7 +15,7 @@ export declare class DefaultCollisionCoordinator implements ICollisionCoordinato
|
|
|
15
15
|
private _scaledPosition;
|
|
16
16
|
private _scaledVelocity;
|
|
17
17
|
private _finalPosition;
|
|
18
|
-
getNewPosition(position: Vector3, displacement: Vector3, collider: Collider, maximumRetry: number, excludedMesh: AbstractMesh, onNewPosition: (collisionIndex: number, newPosition: Vector3, collidedMesh: Nullable<AbstractMesh>) => void, collisionIndex: number, slideOnCollide?: boolean):
|
|
18
|
+
getNewPosition(position: Vector3, displacement: Vector3, collider: Collider, maximumRetry: number, excludedMesh: AbstractMesh, onNewPosition: (collisionIndex: number, newPosition: Vector3, collidedMesh: Nullable<AbstractMesh>) => void, collisionIndex: number, slideOnCollide?: boolean): Vector3;
|
|
19
19
|
createCollider(): Collider;
|
|
20
20
|
init(scene: Scene): void;
|
|
21
21
|
private _collideWithWorld;
|
|
@@ -20,6 +20,7 @@ export class DefaultCollisionCoordinator {
|
|
|
20
20
|
this._finalPosition.multiplyInPlace(collider._radius);
|
|
21
21
|
//run the callback
|
|
22
22
|
onNewPosition(collisionIndex, this._finalPosition, collider.collidedMesh);
|
|
23
|
+
return this._finalPosition;
|
|
23
24
|
}
|
|
24
25
|
createCollider() {
|
|
25
26
|
return new Collider();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collisionCoordinator.js","sourceRoot":"","sources":["../../../../dev/core/src/Collisions/collisionCoordinator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,EAAE,cAAc,EAAE,qCAAoC;AAkB7D,gBAAgB;AAChB,MAAM,OAAO,2BAA2B;IAAxC;QAGY,oBAAe,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QACjC,oBAAe,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QAEjC,mBAAc,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"collisionCoordinator.js","sourceRoot":"","sources":["../../../../dev/core/src/Collisions/collisionCoordinator.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Nullable } from \"../types\";\r\nimport { Scene } from \"../scene\";\r\nimport { Vector3 } from \"../Maths/math.vector\";\r\nimport { Collider } from \"./collider\";\r\nimport type { AbstractMesh } from \"../Meshes/abstractMesh\";\r\nimport { AbstractEngine } from \"core/Engines/abstractEngine\";\r\n\r\n/** @internal */\r\nexport interface ICollisionCoordinator {\r\n createCollider(): Collider;\r\n getNewPosition(\r\n position: Vector3,\r\n displacement: Vector3,\r\n collider: Collider,\r\n maximumRetry: number,\r\n excludedMesh: Nullable<AbstractMesh>,\r\n onNewPosition: (collisionIndex: number, newPosition: Vector3, collidedMesh: Nullable<AbstractMesh>) => void,\r\n collisionIndex: number,\r\n slideOnCollide?: boolean\r\n ): Vector3;\r\n init(scene: Scene): void;\r\n}\r\n\r\n/** @internal */\r\nexport class DefaultCollisionCoordinator implements ICollisionCoordinator {\r\n private _scene: Scene;\r\n\r\n private _scaledPosition = Vector3.Zero();\r\n private _scaledVelocity = Vector3.Zero();\r\n\r\n private _finalPosition = Vector3.Zero();\r\n\r\n public getNewPosition(\r\n position: Vector3,\r\n displacement: Vector3,\r\n collider: Collider,\r\n maximumRetry: number,\r\n excludedMesh: AbstractMesh,\r\n onNewPosition: (collisionIndex: number, newPosition: Vector3, collidedMesh: Nullable<AbstractMesh>) => void,\r\n collisionIndex: number,\r\n slideOnCollide: boolean = true\r\n ): Vector3 {\r\n position.divideToRef(collider._radius, this._scaledPosition);\r\n displacement.divideToRef(collider._radius, this._scaledVelocity);\r\n collider.collidedMesh = null;\r\n collider._retry = 0;\r\n collider._initialVelocity = this._scaledVelocity;\r\n collider._initialPosition = this._scaledPosition;\r\n this._collideWithWorld(this._scaledPosition, this._scaledVelocity, collider, maximumRetry, this._finalPosition, slideOnCollide, excludedMesh);\r\n\r\n this._finalPosition.multiplyInPlace(collider._radius);\r\n //run the callback\r\n onNewPosition(collisionIndex, this._finalPosition, collider.collidedMesh);\r\n\r\n return this._finalPosition;\r\n }\r\n\r\n public createCollider(): Collider {\r\n return new Collider();\r\n }\r\n\r\n public init(scene: Scene): void {\r\n this._scene = scene;\r\n }\r\n\r\n private _collideWithWorld(\r\n position: Vector3,\r\n velocity: Vector3,\r\n collider: Collider,\r\n maximumRetry: number,\r\n finalPosition: Vector3,\r\n slideOnCollide: boolean,\r\n excludedMesh: Nullable<AbstractMesh> = null\r\n ): void {\r\n const closeDistance = AbstractEngine.CollisionsEpsilon * 10.0;\r\n\r\n if (collider._retry >= maximumRetry) {\r\n finalPosition.copyFrom(position);\r\n return;\r\n }\r\n\r\n // Check if this is a mesh else camera or -1\r\n const collisionMask = excludedMesh ? excludedMesh.collisionMask : collider.collisionMask;\r\n\r\n collider._initialize(position, velocity, closeDistance);\r\n\r\n // Check if collision detection should happen against specified list of meshes or,\r\n // if not specified, against all meshes in the scene\r\n const meshes = (excludedMesh && excludedMesh.surroundingMeshes) || this._scene.meshes;\r\n\r\n for (let index = 0; index < meshes.length; index++) {\r\n const mesh = meshes[index];\r\n if (mesh.isEnabled() && mesh.checkCollisions && mesh.subMeshes && mesh !== excludedMesh && (collisionMask & mesh.collisionGroup) !== 0) {\r\n mesh._checkCollision(collider);\r\n }\r\n }\r\n\r\n if (!collider.collisionFound) {\r\n position.addToRef(velocity, finalPosition);\r\n return;\r\n }\r\n\r\n if (velocity.x !== 0 || velocity.y !== 0 || velocity.z !== 0) {\r\n collider._getResponse(position, velocity, slideOnCollide);\r\n // Halt all movement at the first collision, if not slideOnCollide\r\n if (!slideOnCollide) {\r\n velocity.setAll(0);\r\n }\r\n }\r\n\r\n if (velocity.length() <= closeDistance) {\r\n finalPosition.copyFrom(position);\r\n return;\r\n }\r\n\r\n collider._retry++;\r\n this._collideWithWorld(position, velocity, collider, maximumRetry, finalPosition, slideOnCollide, excludedMesh);\r\n }\r\n}\r\n\r\nScene.CollisionCoordinatorFactory = () => {\r\n return new DefaultCollisionCoordinator();\r\n};\r\n"]}
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
declare module "../../Engines/abstractEngine.js" {
|
|
2
2
|
interface AbstractEngine {
|
|
3
3
|
/** @internal */
|
|
4
|
-
_debugPushGroup(groupName: string
|
|
4
|
+
_debugPushGroup(groupName: string): void;
|
|
5
5
|
/** @internal */
|
|
6
|
-
_debugPopGroup(
|
|
6
|
+
_debugPopGroup(): void;
|
|
7
7
|
/** @internal */
|
|
8
|
-
_debugInsertMarker(text: string
|
|
9
|
-
/** @internal */
|
|
10
|
-
_debugFlushPendingCommands(): void;
|
|
8
|
+
_debugInsertMarker(text: string): void;
|
|
11
9
|
}
|
|
12
10
|
}
|
|
13
11
|
export {};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
2
|
import { AbstractEngine } from "../../Engines/abstractEngine.js";
|
|
3
|
-
AbstractEngine.prototype._debugPushGroup = function (groupName
|
|
4
|
-
AbstractEngine.prototype._debugPopGroup = function (
|
|
5
|
-
AbstractEngine.prototype._debugInsertMarker = function (text
|
|
6
|
-
AbstractEngine.prototype._debugFlushPendingCommands = function () { };
|
|
3
|
+
AbstractEngine.prototype._debugPushGroup = function (groupName) { };
|
|
4
|
+
AbstractEngine.prototype._debugPopGroup = function () { };
|
|
5
|
+
AbstractEngine.prototype._debugInsertMarker = function (text) { };
|
|
7
6
|
//# sourceMappingURL=engine.debugging.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.debugging.js","sourceRoot":"","sources":["../../../../../dev/core/src/Engines/Extensions/engine.debugging.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"engine.debugging.js","sourceRoot":"","sources":["../../../../../dev/core/src/Engines/Extensions/engine.debugging.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAgB9D,cAAc,CAAC,SAAS,CAAC,eAAe,GAAG,UAAU,SAAiB,IAAS,CAAC,CAAC;AAEjF,cAAc,CAAC,SAAS,CAAC,cAAc,GAAG,cAAmB,CAAC,CAAC;AAE/D,cAAc,CAAC,SAAS,CAAC,kBAAkB,GAAG,UAAU,IAAY,IAAS,CAAC,CAAC","sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\r\nimport { AbstractEngine } from \"../../Engines/abstractEngine\";\r\n\r\ndeclare module \"../../Engines/abstractEngine\" {\r\n // eslint-disable-next-line @typescript-eslint/naming-convention\r\n export interface AbstractEngine {\r\n /** @internal */\r\n _debugPushGroup(groupName: string): void;\r\n\r\n /** @internal */\r\n _debugPopGroup(): void;\r\n\r\n /** @internal */\r\n _debugInsertMarker(text: string): void;\r\n }\r\n}\r\n\r\nAbstractEngine.prototype._debugPushGroup = function (groupName: string): void {};\r\n\r\nAbstractEngine.prototype._debugPopGroup = function (): void {};\r\n\r\nAbstractEngine.prototype._debugInsertMarker = function (text: string): void {};\r\n"]}
|
|
@@ -1,94 +1,44 @@
|
|
|
1
1
|
import { WebGPUEngine } from "../../webgpuEngine.js";
|
|
2
|
-
WebGPUEngine.prototype._debugPushGroup = function (groupName
|
|
2
|
+
WebGPUEngine.prototype._debugPushGroup = function (groupName) {
|
|
3
3
|
if (!this._options.enableGPUDebugMarkers) {
|
|
4
4
|
return;
|
|
5
5
|
}
|
|
6
|
-
if (
|
|
7
|
-
|
|
8
|
-
if (this._currentRenderTarget) {
|
|
9
|
-
this.unBindFramebuffer(this._currentRenderTarget);
|
|
10
|
-
}
|
|
11
|
-
else {
|
|
12
|
-
this._endCurrentRenderPass();
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
this._renderEncoder.pushDebugGroup(groupName);
|
|
6
|
+
if (this._currentRenderTarget && !this._currentRenderPass) {
|
|
7
|
+
this._startRenderTargetRenderPass(this._currentRenderTarget, false, null, false, false);
|
|
16
8
|
}
|
|
17
|
-
|
|
9
|
+
if (this._currentRenderPass) {
|
|
18
10
|
this._currentRenderPass.pushDebugGroup(groupName);
|
|
19
|
-
this._debugStackRenderPass.push(groupName);
|
|
20
11
|
}
|
|
21
12
|
else {
|
|
22
|
-
this.
|
|
13
|
+
this._renderEncoder.pushDebugGroup(groupName);
|
|
23
14
|
}
|
|
24
15
|
};
|
|
25
|
-
WebGPUEngine.prototype._debugPopGroup = function (
|
|
16
|
+
WebGPUEngine.prototype._debugPopGroup = function () {
|
|
26
17
|
if (!this._options.enableGPUDebugMarkers) {
|
|
27
18
|
return;
|
|
28
19
|
}
|
|
29
|
-
if (
|
|
30
|
-
|
|
31
|
-
if (this._currentRenderTarget) {
|
|
32
|
-
this.unBindFramebuffer(this._currentRenderTarget);
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
this._endCurrentRenderPass();
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
this._renderEncoder.popDebugGroup();
|
|
20
|
+
if (this._currentRenderTarget && !this._currentRenderPass) {
|
|
21
|
+
this._startRenderTargetRenderPass(this._currentRenderTarget, false, null, false, false);
|
|
39
22
|
}
|
|
40
|
-
|
|
23
|
+
if (this._currentRenderPass) {
|
|
41
24
|
this._currentRenderPass.popDebugGroup();
|
|
42
|
-
this._debugStackRenderPass.pop();
|
|
43
25
|
}
|
|
44
26
|
else {
|
|
45
|
-
this.
|
|
27
|
+
this._renderEncoder.popDebugGroup();
|
|
46
28
|
}
|
|
47
29
|
};
|
|
48
|
-
WebGPUEngine.prototype._debugInsertMarker = function (text
|
|
30
|
+
WebGPUEngine.prototype._debugInsertMarker = function (text) {
|
|
49
31
|
if (!this._options.enableGPUDebugMarkers) {
|
|
50
32
|
return;
|
|
51
33
|
}
|
|
52
|
-
if (
|
|
53
|
-
|
|
54
|
-
if (this._currentRenderTarget) {
|
|
55
|
-
this.unBindFramebuffer(this._currentRenderTarget);
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
this._endCurrentRenderPass();
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
this._renderEncoder.insertDebugMarker(text);
|
|
34
|
+
if (this._currentRenderTarget && !this._currentRenderPass) {
|
|
35
|
+
this._startRenderTargetRenderPass(this._currentRenderTarget, false, null, false, false);
|
|
62
36
|
}
|
|
63
|
-
|
|
37
|
+
if (this._currentRenderPass) {
|
|
64
38
|
this._currentRenderPass.insertDebugMarker(text);
|
|
65
39
|
}
|
|
66
40
|
else {
|
|
67
|
-
this.
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
WebGPUEngine.prototype._debugFlushPendingCommands = function () {
|
|
71
|
-
if (this._debugStackRenderPass.length !== 0) {
|
|
72
|
-
const currentDebugStack = this._debugStackRenderPass.slice();
|
|
73
|
-
this._debugStackRenderPass.length = 0;
|
|
74
|
-
for (let i = 0; i < currentDebugStack.length; ++i) {
|
|
75
|
-
this._debugPushGroup(currentDebugStack[i], 2);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
for (let i = 0; i < this._pendingDebugCommands.length; ++i) {
|
|
79
|
-
const [name, param, targetObject] = this._pendingDebugCommands[i];
|
|
80
|
-
switch (name) {
|
|
81
|
-
case "push":
|
|
82
|
-
this._debugPushGroup(param, targetObject);
|
|
83
|
-
break;
|
|
84
|
-
case "pop":
|
|
85
|
-
this._debugPopGroup(targetObject);
|
|
86
|
-
break;
|
|
87
|
-
case "insert":
|
|
88
|
-
this._debugInsertMarker(param, targetObject);
|
|
89
|
-
break;
|
|
90
|
-
}
|
|
41
|
+
this._renderEncoder.insertDebugMarker(text);
|
|
91
42
|
}
|
|
92
|
-
this._pendingDebugCommands.length = 0;
|
|
93
43
|
};
|
|
94
44
|
//# sourceMappingURL=engine.debugging.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.debugging.js","sourceRoot":"","sources":["../../../../../../dev/core/src/Engines/WebGPU/Extensions/engine.debugging.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,YAAY,CAAC,SAAS,CAAC,eAAe,GAAG,UAAU,SAAiB
|
|
1
|
+
{"version":3,"file":"engine.debugging.js","sourceRoot":"","sources":["../../../../../../dev/core/src/Engines/WebGPU/Extensions/engine.debugging.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,YAAY,CAAC,SAAS,CAAC,eAAe,GAAG,UAAU,SAAiB;IAChE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,qBAAqB,EAAE,CAAC;QACvC,OAAO;IACX,CAAC;IAED,IAAI,IAAI,CAAC,oBAAoB,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACxD,IAAI,CAAC,4BAA4B,CAAC,IAAI,CAAC,oBAAoB,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAC5F,CAAC;IAED,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,kBAAkB,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;IACtD,CAAC;SAAM,CAAC;QACJ,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;IAClD,CAAC;AACL,CAAC,CAAC;AAEF,YAAY,CAAC,SAAS,CAAC,cAAc,GAAG;IACpC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,qBAAqB,EAAE,CAAC;QACvC,OAAO;IACX,CAAC;IAED,IAAI,IAAI,CAAC,oBAAoB,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACxD,IAAI,CAAC,4BAA4B,CAAC,IAAI,CAAC,oBAAoB,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAC5F,CAAC;IAED,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,kBAAkB,CAAC,aAAa,EAAE,CAAC;IAC5C,CAAC;SAAM,CAAC;QACJ,IAAI,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC;IACxC,CAAC;AACL,CAAC,CAAC;AAEF,YAAY,CAAC,SAAS,CAAC,kBAAkB,GAAG,UAAU,IAAY;IAC9D,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,qBAAqB,EAAE,CAAC;QACvC,OAAO;IACX,CAAC;IAED,IAAI,IAAI,CAAC,oBAAoB,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACxD,IAAI,CAAC,4BAA4B,CAAC,IAAI,CAAC,oBAAoB,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAC5F,CAAC;IAED,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,kBAAkB,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACpD,CAAC;SAAM,CAAC;QACJ,IAAI,CAAC,cAAc,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAChD,CAAC;AACL,CAAC,CAAC","sourcesContent":["import { WebGPUEngine } from \"../../webgpuEngine\";\r\n\r\nWebGPUEngine.prototype._debugPushGroup = function (groupName: string): void {\r\n if (!this._options.enableGPUDebugMarkers) {\r\n return;\r\n }\r\n\r\n if (this._currentRenderTarget && !this._currentRenderPass) {\r\n this._startRenderTargetRenderPass(this._currentRenderTarget, false, null, false, false);\r\n }\r\n\r\n if (this._currentRenderPass) {\r\n this._currentRenderPass.pushDebugGroup(groupName);\r\n } else {\r\n this._renderEncoder.pushDebugGroup(groupName);\r\n }\r\n};\r\n\r\nWebGPUEngine.prototype._debugPopGroup = function (): void {\r\n if (!this._options.enableGPUDebugMarkers) {\r\n return;\r\n }\r\n\r\n if (this._currentRenderTarget && !this._currentRenderPass) {\r\n this._startRenderTargetRenderPass(this._currentRenderTarget, false, null, false, false);\r\n }\r\n\r\n if (this._currentRenderPass) {\r\n this._currentRenderPass.popDebugGroup();\r\n } else {\r\n this._renderEncoder.popDebugGroup();\r\n }\r\n};\r\n\r\nWebGPUEngine.prototype._debugInsertMarker = function (text: string): void {\r\n if (!this._options.enableGPUDebugMarkers) {\r\n return;\r\n }\r\n\r\n if (this._currentRenderTarget && !this._currentRenderPass) {\r\n this._startRenderTargetRenderPass(this._currentRenderTarget, false, null, false, false);\r\n }\r\n\r\n if (this._currentRenderPass) {\r\n this._currentRenderPass.insertDebugMarker(text);\r\n } else {\r\n this._renderEncoder.insertDebugMarker(text);\r\n }\r\n};\r\n"]}
|
|
@@ -456,7 +456,7 @@ export class WebGPUTextureManager {
|
|
|
456
456
|
if (useOwnCommandEncoder) {
|
|
457
457
|
commandEncoder = this._device.createCommandEncoder({});
|
|
458
458
|
}
|
|
459
|
-
commandEncoder.pushDebugGroup
|
|
459
|
+
commandEncoder.pushDebugGroup(`copy video to texture (invertY=${invertY})`);
|
|
460
460
|
const webgpuHardwareTexture = texture._hardwareTexture;
|
|
461
461
|
const renderPassDescriptor = {
|
|
462
462
|
label: `BabylonWebGPUDevice${this._engine.uniqueId}_copyVideoToTexture_${format}_${invertY ? "InvertY" : "DontInvertY"}${texture.label ? "_" + texture.label : ""}`,
|
|
@@ -497,7 +497,7 @@ export class WebGPUTextureManager {
|
|
|
497
497
|
passEncoder.setBindGroup(0, bindGroup);
|
|
498
498
|
passEncoder.draw(4, 1, 0, 0);
|
|
499
499
|
passEncoder.end();
|
|
500
|
-
commandEncoder.popDebugGroup
|
|
500
|
+
commandEncoder.popDebugGroup();
|
|
501
501
|
if (useOwnCommandEncoder) {
|
|
502
502
|
this._device.queue.submit([commandEncoder.finish()]);
|
|
503
503
|
commandEncoder = null;
|
|
@@ -516,7 +516,6 @@ export class WebGPUTextureManager {
|
|
|
516
516
|
if (useOwnCommandEncoder) {
|
|
517
517
|
commandEncoder = this._device.createCommandEncoder({});
|
|
518
518
|
}
|
|
519
|
-
commandEncoder.pushDebugGroup?.(`internal process texture - invertY=${invertY} premultiplyAlpha=${premultiplyAlpha}`);
|
|
520
519
|
let gpuTexture;
|
|
521
520
|
if (WebGPUTextureHelper.IsHardwareTexture(gpuOrHdwTexture)) {
|
|
522
521
|
gpuTexture = gpuOrHdwTexture.underlyingResource;
|
|
@@ -532,6 +531,7 @@ export class WebGPUTextureManager {
|
|
|
532
531
|
if (!gpuTexture) {
|
|
533
532
|
return;
|
|
534
533
|
}
|
|
534
|
+
commandEncoder.pushDebugGroup(`internal process texture "${gpuTexture.label}" (invertY=${invertY} premultiplyAlpha=${premultiplyAlpha})`);
|
|
535
535
|
if (useRect) {
|
|
536
536
|
this._bufferManager.setRawData(this._ubCopyWithOfst, 0, new Float32Array([ofstX, ofstY, rectWidth, rectHeight]), 0, 4 * 4);
|
|
537
537
|
}
|
|
@@ -616,7 +616,7 @@ export class WebGPUTextureManager {
|
|
|
616
616
|
else {
|
|
617
617
|
this._deferredReleaseTextures.push([outputTexture, null]);
|
|
618
618
|
}
|
|
619
|
-
commandEncoder.popDebugGroup
|
|
619
|
+
commandEncoder.popDebugGroup();
|
|
620
620
|
if (useOwnCommandEncoder) {
|
|
621
621
|
this._device.queue.submit([commandEncoder.finish()]);
|
|
622
622
|
commandEncoder = null;
|
|
@@ -700,11 +700,11 @@ export class WebGPUTextureManager {
|
|
|
700
700
|
if (useOwnCommandEncoder) {
|
|
701
701
|
commandEncoder = this._device.createCommandEncoder({});
|
|
702
702
|
}
|
|
703
|
-
commandEncoder.pushDebugGroup
|
|
703
|
+
commandEncoder.pushDebugGroup(`create cube mipmaps for "${gpuTexture.label}" (${mipLevelCount} levels)`);
|
|
704
704
|
for (let f = 0; f < gpuTexture.depthOrArrayLayers; ++f) {
|
|
705
705
|
this.generateMipmaps(gpuOrHdwTexture, mipLevelCount, f, commandEncoder);
|
|
706
706
|
}
|
|
707
|
-
commandEncoder.popDebugGroup
|
|
707
|
+
commandEncoder.popDebugGroup();
|
|
708
708
|
if (useOwnCommandEncoder) {
|
|
709
709
|
this._device.queue.submit([commandEncoder.finish()]);
|
|
710
710
|
commandEncoder = null;
|
|
@@ -716,7 +716,6 @@ export class WebGPUTextureManager {
|
|
|
716
716
|
if (useOwnCommandEncoder) {
|
|
717
717
|
commandEncoder = this._device.createCommandEncoder({});
|
|
718
718
|
}
|
|
719
|
-
commandEncoder.pushDebugGroup?.(`create mipmaps for face #${faceIndex} - ${mipLevelCount} levels`);
|
|
720
719
|
let gpuTexture;
|
|
721
720
|
if (WebGPUTextureHelper.IsHardwareTexture(gpuOrHdwTexture)) {
|
|
722
721
|
gpuTexture = gpuOrHdwTexture.underlyingResource;
|
|
@@ -730,6 +729,7 @@ export class WebGPUTextureManager {
|
|
|
730
729
|
if (!gpuTexture) {
|
|
731
730
|
return;
|
|
732
731
|
}
|
|
732
|
+
commandEncoder.pushDebugGroup(`create mipmaps for "${gpuTexture.label}" (face #${faceIndex} - ${mipLevelCount} levels)`);
|
|
733
733
|
const format = gpuTexture.format;
|
|
734
734
|
const [pipeline, bindGroupLayout] = this._getPipeline(format);
|
|
735
735
|
const is3D = gpuTexture.dimension === "3d" /* WebGPUConstants.TextureDimension.E3d */;
|
|
@@ -787,7 +787,7 @@ export class WebGPUTextureManager {
|
|
|
787
787
|
passEncoder.draw(4, 1, 0, 0);
|
|
788
788
|
passEncoder.end();
|
|
789
789
|
}
|
|
790
|
-
commandEncoder.popDebugGroup
|
|
790
|
+
commandEncoder.popDebugGroup();
|
|
791
791
|
if (useOwnCommandEncoder) {
|
|
792
792
|
this._device.queue.submit([commandEncoder.finish()]);
|
|
793
793
|
commandEncoder = null;
|
|
@@ -893,7 +893,7 @@ export class WebGPUTextureManager {
|
|
|
893
893
|
if (useOwnCommandEncoder) {
|
|
894
894
|
commandEncoder = this._device.createCommandEncoder({});
|
|
895
895
|
}
|
|
896
|
-
commandEncoder.pushDebugGroup(`resolve MSAA Depth texture${msaaTexture.label
|
|
896
|
+
commandEncoder.pushDebugGroup(`resolve MSAA Depth texture "${msaaTexture.label}" to "${outputTexture.label}"`);
|
|
897
897
|
const renderPassDescriptor = {
|
|
898
898
|
label: `BabylonWebGPUDevice${this._engine.uniqueId}_resolveMSAADepthTexture${msaaTexture.label ? "_" + msaaTexture.label : ""}`,
|
|
899
899
|
colorAttachments: [
|