@onerjs/core 8.41.4 → 8.41.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/Cameras/Inputs/geospatialCameraPointersInput.d.ts +16 -0
- package/Cameras/Inputs/geospatialCameraPointersInput.js +19 -3
- package/Cameras/Inputs/geospatialCameraPointersInput.js.map +1 -1
- package/Cameras/Limits/geospatialLimits.d.ts +0 -6
- package/Cameras/Limits/geospatialLimits.js +0 -6
- package/Cameras/Limits/geospatialLimits.js.map +1 -1
- package/Cameras/geospatialCamera.d.ts +5 -0
- package/Cameras/geospatialCamera.js +38 -10
- package/Cameras/geospatialCamera.js.map +1 -1
- package/Engines/abstractEngine.d.ts +2 -2
- package/Engines/abstractEngine.js +2 -2
- package/Engines/abstractEngine.js.map +1 -1
- package/Engines/webgpuEngine.d.ts +1 -4
- package/Engines/webgpuEngine.js +8 -6
- package/Engines/webgpuEngine.js.map +1 -1
- package/FrameGraph/frameGraphContext.js +1 -1
- package/FrameGraph/frameGraphContext.js.map +1 -1
- package/FrameGraph/frameGraphRenderContext.js +2 -2
- package/FrameGraph/frameGraphRenderContext.js.map +1 -1
- package/Lights/Shadows/cascadedShadowGenerator.js +1 -1
- package/Lights/Shadows/cascadedShadowGenerator.js.map +1 -1
- package/Lights/Shadows/shadowGenerator.js +1 -1
- package/Lights/Shadows/shadowGenerator.js.map +1 -1
- package/Lights/lightingVolume.js +1 -1
- package/Lights/lightingVolume.js.map +1 -1
- package/Materials/Textures/Procedurals/proceduralTexture.js +1 -1
- package/Materials/Textures/Procedurals/proceduralTexture.js.map +1 -1
- package/Maths/math.path.js +3 -3
- package/Maths/math.path.js.map +1 -1
- package/Meshes/Builders/capsuleBuilder.js +0 -3
- package/Meshes/Builders/capsuleBuilder.js.map +1 -1
- package/Meshes/Builders/cylinderBuilder.d.ts +1 -1
- package/Meshes/Builders/cylinderBuilder.js +1 -2
- package/Meshes/Builders/cylinderBuilder.js.map +1 -1
- package/Meshes/Builders/decalBuilder.js +2 -0
- package/Meshes/Builders/decalBuilder.js.map +1 -1
- package/Meshes/Builders/discBuilder.js +0 -1
- package/Meshes/Builders/discBuilder.js.map +1 -1
- package/Meshes/Builders/groundBuilder.d.ts +50 -54
- package/Meshes/Builders/groundBuilder.js +50 -54
- package/Meshes/Builders/groundBuilder.js.map +1 -1
- package/Meshes/Builders/tiledBoxBuilder.d.ts +0 -26
- package/Meshes/Builders/tiledBoxBuilder.js +0 -26
- package/Meshes/Builders/tiledBoxBuilder.js.map +1 -1
- package/Meshes/Builders/tiledPlaneBuilder.d.ts +0 -25
- package/Meshes/Builders/tiledPlaneBuilder.js +0 -25
- package/Meshes/Builders/tiledPlaneBuilder.js.map +1 -1
- package/Meshes/Builders/torusBuilder.d.ts +0 -13
- package/Meshes/Builders/torusBuilder.js +0 -13
- package/Meshes/Builders/torusBuilder.js.map +1 -1
- package/Meshes/Builders/torusKnotBuilder.d.ts +0 -19
- package/Meshes/Builders/torusKnotBuilder.js +0 -19
- package/Meshes/Builders/torusKnotBuilder.js.map +1 -1
- package/Meshes/Compression/dracoCompressionWorker.js.map +1 -1
- package/Meshes/Compression/dracoDecoder.js.map +1 -1
- package/Meshes/Compression/dracoDecoder.types.d.ts +11 -0
- package/Meshes/Compression/dracoDecoder.types.js.map +1 -1
- package/Meshes/Compression/dracoEncoder.js.map +1 -1
- package/Meshes/Compression/meshoptCompression.js +0 -2
- package/Meshes/Compression/meshoptCompression.js.map +1 -1
- package/Meshes/GreasedLine/greasedLineRibbonMesh.js +0 -8
- package/Meshes/GreasedLine/greasedLineRibbonMesh.js.map +1 -1
- package/Meshes/Node/Blocks/Instances/instantiateBaseBlock.d.ts +1 -0
- package/Meshes/Node/Blocks/Instances/instantiateBaseBlock.js +1 -0
- package/Meshes/Node/Blocks/Instances/instantiateBaseBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Instances/instantiateOnFacesBlock.d.ts +1 -0
- package/Meshes/Node/Blocks/Instances/instantiateOnFacesBlock.js +1 -0
- package/Meshes/Node/Blocks/Instances/instantiateOnFacesBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Instances/instantiateOnVerticesBlock.d.ts +1 -0
- package/Meshes/Node/Blocks/Instances/instantiateOnVerticesBlock.js +1 -0
- package/Meshes/Node/Blocks/Instances/instantiateOnVerticesBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Instances/instantiateOnVolumeBlock.d.ts +1 -0
- package/Meshes/Node/Blocks/Instances/instantiateOnVolumeBlock.js +1 -0
- package/Meshes/Node/Blocks/Instances/instantiateOnVolumeBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Matrices/scalingBlock.d.ts +1 -0
- package/Meshes/Node/Blocks/Matrices/scalingBlock.js +1 -0
- package/Meshes/Node/Blocks/Matrices/scalingBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Matrices/translationBlock.d.ts +1 -0
- package/Meshes/Node/Blocks/Matrices/translationBlock.js +1 -0
- package/Meshes/Node/Blocks/Matrices/translationBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Set/aggregatorBlock.d.ts +1 -0
- package/Meshes/Node/Blocks/Set/aggregatorBlock.js +1 -0
- package/Meshes/Node/Blocks/Set/aggregatorBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Set/latticeBlock.d.ts +1 -0
- package/Meshes/Node/Blocks/Set/latticeBlock.js +1 -0
- package/Meshes/Node/Blocks/Set/latticeBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Set/setColorsBlock.d.ts +1 -0
- package/Meshes/Node/Blocks/Set/setColorsBlock.js +1 -0
- package/Meshes/Node/Blocks/Set/setColorsBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Set/setMaterialIDBlock.d.ts +1 -0
- package/Meshes/Node/Blocks/Set/setMaterialIDBlock.js +1 -0
- package/Meshes/Node/Blocks/Set/setMaterialIDBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Set/setNormalsBlock.d.ts +1 -0
- package/Meshes/Node/Blocks/Set/setNormalsBlock.js +1 -0
- package/Meshes/Node/Blocks/Set/setNormalsBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Set/setPositionsBlock.d.ts +1 -0
- package/Meshes/Node/Blocks/Set/setPositionsBlock.js +1 -0
- package/Meshes/Node/Blocks/Set/setPositionsBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Set/setTangentsBlock.d.ts +1 -0
- package/Meshes/Node/Blocks/Set/setTangentsBlock.js +1 -0
- package/Meshes/Node/Blocks/Set/setTangentsBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Set/setUVsBlock.d.ts +1 -0
- package/Meshes/Node/Blocks/Set/setUVsBlock.js +1 -0
- package/Meshes/Node/Blocks/Set/setUVsBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Sources/boxBlock.d.ts +2 -0
- package/Meshes/Node/Blocks/Sources/boxBlock.js +2 -0
- package/Meshes/Node/Blocks/Sources/boxBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Sources/capsuleBlock.d.ts +2 -0
- package/Meshes/Node/Blocks/Sources/capsuleBlock.js +2 -0
- package/Meshes/Node/Blocks/Sources/capsuleBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Sources/cylinderBlock.d.ts +2 -0
- package/Meshes/Node/Blocks/Sources/cylinderBlock.js +2 -0
- package/Meshes/Node/Blocks/Sources/cylinderBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Sources/discBlock.d.ts +2 -0
- package/Meshes/Node/Blocks/Sources/discBlock.js +2 -0
- package/Meshes/Node/Blocks/Sources/discBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Sources/gridBlock.d.ts +2 -0
- package/Meshes/Node/Blocks/Sources/gridBlock.js +2 -0
- package/Meshes/Node/Blocks/Sources/gridBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Sources/icoSphereBlock.d.ts +2 -0
- package/Meshes/Node/Blocks/Sources/icoSphereBlock.js +2 -0
- package/Meshes/Node/Blocks/Sources/icoSphereBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Sources/meshBlock.d.ts +1 -0
- package/Meshes/Node/Blocks/Sources/meshBlock.js +1 -0
- package/Meshes/Node/Blocks/Sources/meshBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Sources/planeBlock.d.ts +2 -0
- package/Meshes/Node/Blocks/Sources/planeBlock.js +2 -0
- package/Meshes/Node/Blocks/Sources/planeBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Sources/pointListBlock.d.ts +2 -1
- package/Meshes/Node/Blocks/Sources/pointListBlock.js +2 -1
- package/Meshes/Node/Blocks/Sources/pointListBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Sources/sphereBlock.d.ts +2 -0
- package/Meshes/Node/Blocks/Sources/sphereBlock.js +2 -0
- package/Meshes/Node/Blocks/Sources/sphereBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Sources/torusBlock.d.ts +2 -0
- package/Meshes/Node/Blocks/Sources/torusBlock.js +2 -0
- package/Meshes/Node/Blocks/Sources/torusBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Teleport/teleportInBlock.d.ts +1 -0
- package/Meshes/Node/Blocks/Teleport/teleportInBlock.js +1 -0
- package/Meshes/Node/Blocks/Teleport/teleportInBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Teleport/teleportOutBlock.d.ts +3 -0
- package/Meshes/Node/Blocks/Teleport/teleportOutBlock.js +3 -0
- package/Meshes/Node/Blocks/Teleport/teleportOutBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Textures/geometryTextureBlock.d.ts +1 -0
- package/Meshes/Node/Blocks/Textures/geometryTextureBlock.js +1 -1
- package/Meshes/Node/Blocks/Textures/geometryTextureBlock.js.map +1 -1
- package/Meshes/Node/Blocks/Textures/geometryTextureFetchBlock.d.ts +1 -0
- package/Meshes/Node/Blocks/Textures/geometryTextureFetchBlock.js +1 -0
- package/Meshes/Node/Blocks/Textures/geometryTextureFetchBlock.js.map +1 -1
- package/Meshes/Node/Blocks/booleanGeometryBlock.d.ts +1 -0
- package/Meshes/Node/Blocks/booleanGeometryBlock.js +1 -1
- package/Meshes/Node/Blocks/booleanGeometryBlock.js.map +1 -1
- package/Meshes/Node/Blocks/cleanGeometryBlock.d.ts +1 -0
- package/Meshes/Node/Blocks/cleanGeometryBlock.js +1 -0
- package/Meshes/Node/Blocks/cleanGeometryBlock.js.map +1 -1
- package/Meshes/Node/Blocks/conditionBlock.d.ts +2 -0
- package/Meshes/Node/Blocks/conditionBlock.js +2 -0
- package/Meshes/Node/Blocks/conditionBlock.js.map +1 -1
- package/Meshes/Node/Blocks/geometryClampBlock.d.ts +1 -0
- package/Meshes/Node/Blocks/geometryClampBlock.js +1 -0
- package/Meshes/Node/Blocks/geometryClampBlock.js.map +1 -1
- package/Meshes/Node/Blocks/geometryCollectionBlock.d.ts +1 -0
- package/Meshes/Node/Blocks/geometryCollectionBlock.js +1 -0
- package/Meshes/Node/Blocks/geometryCollectionBlock.js.map +1 -1
- package/Meshes/Node/Blocks/geometryCurveBlock.d.ts +2 -0
- package/Meshes/Node/Blocks/geometryCurveBlock.js +2 -0
- package/Meshes/Node/Blocks/geometryCurveBlock.js.map +1 -1
- package/Meshes/Node/Blocks/geometryEaseBlock.d.ts +2 -0
- package/Meshes/Node/Blocks/geometryEaseBlock.js +2 -0
- package/Meshes/Node/Blocks/geometryEaseBlock.js.map +1 -1
- package/Meshes/Node/Blocks/geometryInputBlock.d.ts +3 -0
- package/Meshes/Node/Blocks/geometryInputBlock.js +3 -0
- package/Meshes/Node/Blocks/geometryInputBlock.js.map +1 -1
- package/Meshes/Node/Blocks/geometryOptimizeBlock.d.ts +1 -0
- package/Meshes/Node/Blocks/geometryOptimizeBlock.js +1 -0
- package/Meshes/Node/Blocks/geometryOptimizeBlock.js.map +1 -1
- package/Meshes/Node/Blocks/geometryTransformBlock.d.ts +1 -0
- package/Meshes/Node/Blocks/geometryTransformBlock.js +1 -0
- package/Meshes/Node/Blocks/geometryTransformBlock.js.map +1 -1
- package/Meshes/Node/Blocks/geometryTrigonometryBlock.d.ts +2 -0
- package/Meshes/Node/Blocks/geometryTrigonometryBlock.js +2 -0
- package/Meshes/Node/Blocks/geometryTrigonometryBlock.js.map +1 -1
- package/Meshes/Node/Blocks/mappingBlock.d.ts +1 -0
- package/Meshes/Node/Blocks/mappingBlock.js +1 -0
- package/Meshes/Node/Blocks/mappingBlock.js.map +1 -1
- package/Meshes/Node/Blocks/mathBlock.d.ts +1 -0
- package/Meshes/Node/Blocks/mathBlock.js +1 -0
- package/Meshes/Node/Blocks/mathBlock.js.map +1 -1
- package/Meshes/Node/Blocks/mergeGeometryBlock.d.ts +1 -0
- package/Meshes/Node/Blocks/mergeGeometryBlock.js +1 -0
- package/Meshes/Node/Blocks/mergeGeometryBlock.js.map +1 -1
- package/Meshes/Node/Blocks/randomBlock.d.ts +2 -0
- package/Meshes/Node/Blocks/randomBlock.js +2 -0
- package/Meshes/Node/Blocks/randomBlock.js.map +1 -1
- package/Meshes/Node/Blocks/subdivideBlock.d.ts +1 -0
- package/Meshes/Node/Blocks/subdivideBlock.js +1 -0
- package/Meshes/Node/Blocks/subdivideBlock.js.map +1 -1
- package/Meshes/Node/Interfaces/nodeGeometryTextureData.d.ts +3 -0
- package/Meshes/Node/Interfaces/nodeGeometryTextureData.js.map +1 -1
- package/Meshes/Node/nodeGeometry.js +0 -2
- package/Meshes/Node/nodeGeometry.js.map +1 -1
- package/Meshes/Node/nodeGeometryBlockConnectionPoint.js +0 -1
- package/Meshes/Node/nodeGeometryBlockConnectionPoint.js.map +1 -1
- package/Meshes/Node/nodeGeometryBuildState.js +0 -1
- package/Meshes/Node/nodeGeometryBuildState.js.map +1 -1
- package/Meshes/WebGL/webGLDataBuffer.d.ts +2 -0
- package/Meshes/WebGL/webGLDataBuffer.js +2 -0
- package/Meshes/WebGL/webGLDataBuffer.js.map +1 -1
- package/Meshes/WebGPU/webgpuDataBuffer.d.ts +4 -0
- package/Meshes/WebGPU/webgpuDataBuffer.js +4 -0
- package/Meshes/WebGPU/webgpuDataBuffer.js.map +1 -1
- package/Meshes/abstractMesh.d.ts +1 -0
- package/Meshes/abstractMesh.decalMap.d.ts +1 -0
- package/Meshes/abstractMesh.decalMap.js.map +1 -1
- package/Meshes/abstractMesh.js +1 -6
- package/Meshes/abstractMesh.js.map +1 -1
- package/Meshes/csg.js +0 -6
- package/Meshes/csg.js.map +1 -1
- package/Meshes/csg2.js +1 -2
- package/Meshes/csg2.js.map +1 -1
- package/Meshes/geodesicMesh.d.ts +26 -0
- package/Meshes/geodesicMesh.js +18 -3
- package/Meshes/geodesicMesh.js.map +1 -1
- package/Meshes/groundMesh.d.ts +1 -0
- package/Meshes/groundMesh.js +1 -0
- package/Meshes/groundMesh.js.map +1 -1
- package/Meshes/index.js +0 -2
- package/Meshes/index.js.map +1 -1
- package/Meshes/instancedMesh.d.ts +18 -3
- package/Meshes/instancedMesh.js +10 -3
- package/Meshes/instancedMesh.js.map +1 -1
- package/Meshes/mesh.d.ts +286 -204
- package/Meshes/mesh.js +251 -197
- package/Meshes/mesh.js.map +1 -1
- package/Meshes/mesh.vertexData.d.ts +15 -19
- package/Meshes/mesh.vertexData.js +15 -19
- package/Meshes/mesh.vertexData.js.map +1 -1
- package/Meshes/meshSimplification.d.ts +0 -1
- package/Meshes/meshSimplification.js +6 -1
- package/Meshes/meshSimplification.js.map +1 -1
- package/Meshes/meshSimplificationSceneComponent.d.ts +2 -0
- package/Meshes/meshSimplificationSceneComponent.js.map +1 -1
- package/Meshes/meshUVSpaceRenderer.d.ts +1 -0
- package/Meshes/meshUVSpaceRenderer.js.map +1 -1
- package/Meshes/polygonMesh.js +4 -0
- package/Meshes/polygonMesh.js.map +1 -1
- package/Meshes/subMesh.project.d.ts +1 -0
- package/Meshes/subMesh.project.js.map +1 -1
- package/Meshes/thinInstanceMesh.d.ts +5 -0
- package/Meshes/thinInstanceMesh.js.map +1 -1
- package/Meshes/transformNode.d.ts +1 -1
- package/Meshes/transformNode.js +1 -1
- package/Meshes/transformNode.js.map +1 -1
- package/Physics/v2/Plugins/havokPlugin.d.ts +75 -2
- package/Physics/v2/Plugins/havokPlugin.js +243 -52
- package/Physics/v2/Plugins/havokPlugin.js.map +1 -1
- package/Probes/reflectionProbe.js +1 -1
- package/Probes/reflectionProbe.js.map +1 -1
- package/Rendering/depthRenderer.js +1 -1
- package/Rendering/depthRenderer.js.map +1 -1
- package/package.json +1 -1
- package/scene.d.ts +0 -3
- package/scene.js +18 -5
- package/scene.js.map +1 -1
|
@@ -11,6 +11,7 @@ import { InstancedMesh } from "../../../Meshes/instancedMesh.js";
|
|
|
11
11
|
import { VertexBuffer } from "../../../Buffers/buffer.js";
|
|
12
12
|
import { BuildArray } from "../../../Misc/arrayTools.js";
|
|
13
13
|
import { Observable } from "../../../Misc/observable.js";
|
|
14
|
+
import { FloatingOriginCurrentScene } from "../../../Materials/floatingOriginMatrixOverrides.js";
|
|
14
15
|
class MeshAccumulator {
|
|
15
16
|
/**
|
|
16
17
|
* Constructor of the mesh accumulator
|
|
@@ -210,6 +211,45 @@ class TriggerEvent {
|
|
|
210
211
|
* The Havok Physics plugin
|
|
211
212
|
*/
|
|
212
213
|
export class HavokPlugin {
|
|
214
|
+
/**
|
|
215
|
+
* Finds an existing world region that contains the given world position,
|
|
216
|
+
* or creates a new world region centered at that position.
|
|
217
|
+
*
|
|
218
|
+
* When floatingOriginMode is enabled, we use multiple Havok worlds to maintain
|
|
219
|
+
* float32 precision across a large world. Each world region has its own fixed
|
|
220
|
+
* floating origin, and bodies within that region are simulated relative to it.
|
|
221
|
+
*
|
|
222
|
+
* @param worldPosition - The world position of the body being created
|
|
223
|
+
* @returns The world region to use for this body
|
|
224
|
+
*/
|
|
225
|
+
_getOrCreateWorldRegion(worldPosition) {
|
|
226
|
+
// Check if floating origin mode is enabled
|
|
227
|
+
const scene = FloatingOriginCurrentScene.getScene();
|
|
228
|
+
if (!scene?.floatingOriginMode) {
|
|
229
|
+
// When floating origin mode is disabled, use the default world region
|
|
230
|
+
return this._worldRegions[0];
|
|
231
|
+
}
|
|
232
|
+
// Find an existing region that contains this position
|
|
233
|
+
for (const region of this._worldRegions) {
|
|
234
|
+
const distance = Vector3.Distance(worldPosition, region.floatingOrigin);
|
|
235
|
+
if (distance <= this._floatingOriginWorldRadius) {
|
|
236
|
+
return region;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// No existing region found - create a new one centered at this position
|
|
240
|
+
const newWorld = this._hknp.HP_World_Create()[1];
|
|
241
|
+
// Apply stored gravity to new world
|
|
242
|
+
this._hknp.HP_World_SetGravity(newWorld, this._currentGravity);
|
|
243
|
+
// Copy velocity limits from main world
|
|
244
|
+
this._hknp.HP_World_SetSpeedLimit(newWorld, this.getMaxLinearVelocity(), this.getMaxAngularVelocity());
|
|
245
|
+
const newRegion = {
|
|
246
|
+
world: newWorld,
|
|
247
|
+
floatingOrigin: worldPosition.clone(),
|
|
248
|
+
gravity: [...this._currentGravity],
|
|
249
|
+
};
|
|
250
|
+
this._worldRegions.push(newRegion);
|
|
251
|
+
return newRegion;
|
|
252
|
+
}
|
|
213
253
|
constructor(_useDeltaForWorldStep = true, hpInjection = HK, parameters = {}) {
|
|
214
254
|
this._useDeltaForWorldStep = _useDeltaForWorldStep;
|
|
215
255
|
/**
|
|
@@ -230,6 +270,20 @@ export class HavokPlugin {
|
|
|
230
270
|
// Map from constraint id to the pair of bodies, where the first is the parent and the second is the child
|
|
231
271
|
this._constraintToBodyIdPair = new Map();
|
|
232
272
|
this._bodyCollisionEndedObservable = new Map();
|
|
273
|
+
/**
|
|
274
|
+
* Array of world regions. The first region is always the default world with origin at Vector3.Zero.
|
|
275
|
+
* Additional regions are created as needed for floating origin mode.
|
|
276
|
+
*/
|
|
277
|
+
this._worldRegions = [];
|
|
278
|
+
/**
|
|
279
|
+
* Stored gravity value to apply to new world regions.
|
|
280
|
+
*/
|
|
281
|
+
this._currentGravity = [0, -9.81, 0];
|
|
282
|
+
/**
|
|
283
|
+
* Radius of each floating origin world region.
|
|
284
|
+
* Bodies within this radius of a world region's origin will use that world.
|
|
285
|
+
*/
|
|
286
|
+
this._floatingOriginWorldRadius = 100000;
|
|
233
287
|
/**
|
|
234
288
|
* Observable for collision started and collision continued events
|
|
235
289
|
*/
|
|
@@ -254,8 +308,15 @@ export class HavokPlugin {
|
|
|
254
308
|
return;
|
|
255
309
|
}
|
|
256
310
|
this.world = this._hknp.HP_World_Create()[1];
|
|
311
|
+
// Add the default world as the first region with origin at zero
|
|
312
|
+
this._worldRegions.push({
|
|
313
|
+
world: this.world,
|
|
314
|
+
floatingOrigin: Vector3.Zero(),
|
|
315
|
+
gravity: [...this._currentGravity],
|
|
316
|
+
});
|
|
257
317
|
this._queryCollector = this._hknp.HP_QueryCollector_Create(1)[1];
|
|
258
318
|
this.setMaxQueryCollectorHits(parameters.maxQueryCollectorHits ?? 1);
|
|
319
|
+
this._floatingOriginWorldRadius = parameters.floatingOriginWorldRadius ?? 100000;
|
|
259
320
|
}
|
|
260
321
|
/**
|
|
261
322
|
* If this plugin is supported
|
|
@@ -268,10 +329,41 @@ export class HavokPlugin {
|
|
|
268
329
|
* Sets the gravity of the physics world.
|
|
269
330
|
*
|
|
270
331
|
* @param gravity - The gravity vector to set.
|
|
332
|
+
* @param worldPosition - Optional world position to specify which region's gravity to set.
|
|
333
|
+
* If provided, only the region containing this position will be updated.
|
|
334
|
+
* If not provided, all regions will be updated (default behavior).
|
|
335
|
+
* This is useful for planetary scenarios where gravity direction varies by location.
|
|
336
|
+
*/
|
|
337
|
+
setGravity(gravity, worldPosition) {
|
|
338
|
+
const gravityArray = this._bVecToV3(gravity);
|
|
339
|
+
if (worldPosition) {
|
|
340
|
+
// Set gravity for a specific region based on world position
|
|
341
|
+
const region = this._getOrCreateWorldRegion(worldPosition);
|
|
342
|
+
region.gravity = gravityArray;
|
|
343
|
+
this._hknp.HP_World_SetGravity(region.world, gravityArray);
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
// Set gravity for all regions (default behavior)
|
|
347
|
+
this._currentGravity = gravityArray;
|
|
348
|
+
for (const region of this._worldRegions) {
|
|
349
|
+
region.gravity = gravityArray;
|
|
350
|
+
this._hknp.HP_World_SetGravity(region.world, gravityArray);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Gets the gravity of the physics world or a specific region.
|
|
271
356
|
*
|
|
357
|
+
* @param worldPosition - Optional world position to get the gravity for that region.
|
|
358
|
+
* If not provided, returns the default gravity.
|
|
359
|
+
* @returns The gravity vector.
|
|
272
360
|
*/
|
|
273
|
-
|
|
274
|
-
|
|
361
|
+
getGravity(worldPosition) {
|
|
362
|
+
if (worldPosition) {
|
|
363
|
+
const region = this._getOrCreateWorldRegion(worldPosition);
|
|
364
|
+
return new Vector3(region.gravity[0], region.gravity[1], region.gravity[2]);
|
|
365
|
+
}
|
|
366
|
+
return new Vector3(this._currentGravity[0], this._currentGravity[1], this._currentGravity[2]);
|
|
275
367
|
}
|
|
276
368
|
/**
|
|
277
369
|
* Sets the fixed time step for the physics engine.
|
|
@@ -334,16 +426,23 @@ export class HavokPlugin {
|
|
|
334
426
|
this.setPhysicsBodyTransformation(physicsBody, physicsBody.transformNode);
|
|
335
427
|
}
|
|
336
428
|
const deltaTime = this._useDeltaForWorldStep ? delta : this._fixedTimeStep;
|
|
337
|
-
|
|
338
|
-
|
|
429
|
+
// Step all world regions
|
|
430
|
+
for (const region of this._worldRegions) {
|
|
431
|
+
this._hknp.HP_World_SetIdealStepTime(region.world, deltaTime);
|
|
432
|
+
this._hknp.HP_World_Step(region.world, deltaTime);
|
|
433
|
+
}
|
|
434
|
+
// Get body buffer from the default world (first region)
|
|
339
435
|
this._bodyBuffer = this._hknp.HP_World_GetBodyBuffer(this.world)[1];
|
|
340
436
|
for (const physicsBody of physicsBodies) {
|
|
341
437
|
if (!physicsBody.disableSync) {
|
|
342
438
|
this.sync(physicsBody);
|
|
343
439
|
}
|
|
344
440
|
}
|
|
345
|
-
|
|
346
|
-
this.
|
|
441
|
+
// Notify collisions and triggers for all world regions
|
|
442
|
+
for (const region of this._worldRegions) {
|
|
443
|
+
this._notifyCollisions(region.world);
|
|
444
|
+
this._notifyTriggers(region.world);
|
|
445
|
+
}
|
|
347
446
|
}
|
|
348
447
|
/**
|
|
349
448
|
* Returns the version of the physics engine plugin.
|
|
@@ -361,7 +460,9 @@ export class HavokPlugin {
|
|
|
361
460
|
* @param maxAngularVelocity maximum allowed angular velocity
|
|
362
461
|
*/
|
|
363
462
|
setVelocityLimits(maxLinearVelocity, maxAngularVelocity) {
|
|
364
|
-
|
|
463
|
+
for (const region of this._worldRegions) {
|
|
464
|
+
this._hknp.HP_World_SetSpeedLimit(region.world, maxLinearVelocity, maxAngularVelocity);
|
|
465
|
+
}
|
|
365
466
|
}
|
|
366
467
|
/**
|
|
367
468
|
* @returns maximum allowed linear velocity
|
|
@@ -391,9 +492,13 @@ export class HavokPlugin {
|
|
|
391
492
|
initBody(body, motionType, position, orientation) {
|
|
392
493
|
body._pluginData = new BodyPluginData(this._hknp.HP_Body_Create()[1]);
|
|
393
494
|
this._internalSetMotionType(body._pluginData, motionType);
|
|
394
|
-
|
|
495
|
+
// Get the world region for this body's position
|
|
496
|
+
const worldRegion = this._getOrCreateWorldRegion(position);
|
|
497
|
+
body._pluginData.worldRegion = worldRegion;
|
|
498
|
+
const offset = worldRegion.floatingOrigin;
|
|
499
|
+
const transform = [[position._x - offset._x, position._y - offset._y, position._z - offset._z], this._bQuatToV4(orientation)];
|
|
395
500
|
this._hknp.HP_Body_SetQTransform(body._pluginData.hpBodyId, transform);
|
|
396
|
-
this._hknp.HP_World_AddBody(
|
|
501
|
+
this._hknp.HP_World_AddBody(worldRegion.world, body._pluginData.hpBodyId, body.startAsleep);
|
|
397
502
|
this._bodies.set(body._pluginData.hpBodyId[0], { body: body, index: 0 });
|
|
398
503
|
}
|
|
399
504
|
/**
|
|
@@ -405,13 +510,13 @@ export class HavokPlugin {
|
|
|
405
510
|
if (body._pluginDataInstances && body._pluginDataInstances.length > 0) {
|
|
406
511
|
for (const instance of body._pluginDataInstances) {
|
|
407
512
|
this._bodyCollisionObservable.delete(instance.hpBodyId[0]);
|
|
408
|
-
this._hknp.HP_World_RemoveBody(
|
|
513
|
+
this._hknp.HP_World_RemoveBody(instance.worldRegion.world, instance.hpBodyId);
|
|
409
514
|
this._bodies.delete(instance.hpBodyId[0]);
|
|
410
515
|
}
|
|
411
516
|
}
|
|
412
517
|
if (body._pluginData) {
|
|
413
518
|
this._bodyCollisionObservable.delete(body._pluginData.hpBodyId[0]);
|
|
414
|
-
this._hknp.HP_World_RemoveBody(
|
|
519
|
+
this._hknp.HP_World_RemoveBody(body._pluginData.worldRegion.world, body._pluginData.hpBodyId);
|
|
415
520
|
this._bodies.delete(body._pluginData.hpBodyId[0]);
|
|
416
521
|
}
|
|
417
522
|
}
|
|
@@ -443,15 +548,29 @@ export class HavokPlugin {
|
|
|
443
548
|
_createOrUpdateBodyInstances(body, motionType, matrixData, startIndex, endIndex, update) {
|
|
444
549
|
const rotation = TmpVectors.Quaternion[0];
|
|
445
550
|
const rotationMatrix = Matrix.Identity();
|
|
551
|
+
const worldPos = TmpVectors.Vector3[0];
|
|
446
552
|
for (let i = startIndex; i < endIndex; i++) {
|
|
447
|
-
|
|
553
|
+
// Get world position for this instance
|
|
554
|
+
worldPos.set(matrixData[i * 16 + 12], matrixData[i * 16 + 13], matrixData[i * 16 + 14]);
|
|
448
555
|
let hkbody;
|
|
556
|
+
let pluginData;
|
|
449
557
|
if (!update) {
|
|
450
558
|
hkbody = this._hknp.HP_Body_Create()[1];
|
|
559
|
+
pluginData = new BodyPluginData(hkbody);
|
|
560
|
+
if (body._pluginDataInstances.length) {
|
|
561
|
+
// If an instance already exists, copy any user-provided mass properties
|
|
562
|
+
pluginData.userMassProps = body._pluginDataInstances[0].userMassProps;
|
|
563
|
+
}
|
|
451
564
|
}
|
|
452
565
|
else {
|
|
453
|
-
|
|
566
|
+
pluginData = body._pluginDataInstances[i];
|
|
567
|
+
hkbody = pluginData.hpBodyId;
|
|
454
568
|
}
|
|
569
|
+
// Get the world region for this instance's position
|
|
570
|
+
const worldRegion = this._getOrCreateWorldRegion(worldPos);
|
|
571
|
+
const offset = worldRegion.floatingOrigin;
|
|
572
|
+
// Subtract floating origin offset to get small coordinates for Havok (float32 precision)
|
|
573
|
+
const position = [worldPos._x - offset._x, worldPos._y - offset._y, worldPos._z - offset._z];
|
|
455
574
|
rotationMatrix.setRowFromFloats(0, matrixData[i * 16 + 0], matrixData[i * 16 + 1], matrixData[i * 16 + 2], 0);
|
|
456
575
|
rotationMatrix.setRowFromFloats(1, matrixData[i * 16 + 4], matrixData[i * 16 + 5], matrixData[i * 16 + 6], 0);
|
|
457
576
|
rotationMatrix.setRowFromFloats(2, matrixData[i * 16 + 8], matrixData[i * 16 + 9], matrixData[i * 16 + 10], 0);
|
|
@@ -459,15 +578,12 @@ export class HavokPlugin {
|
|
|
459
578
|
const transform = [position, [rotation.x, rotation.y, rotation.z, rotation.w]];
|
|
460
579
|
this._hknp.HP_Body_SetQTransform(hkbody, transform);
|
|
461
580
|
if (!update) {
|
|
462
|
-
const pluginData = new BodyPluginData(hkbody);
|
|
463
|
-
if (body._pluginDataInstances.length) {
|
|
464
|
-
// If an instance already exists, copy any user-provided mass properties
|
|
465
|
-
pluginData.userMassProps = body._pluginDataInstances[0].userMassProps;
|
|
466
|
-
}
|
|
467
581
|
this._internalSetMotionType(pluginData, motionType);
|
|
468
582
|
this._internalUpdateMassProperties(pluginData);
|
|
469
583
|
body._pluginDataInstances.push(pluginData);
|
|
470
|
-
|
|
584
|
+
// Add to the appropriate world
|
|
585
|
+
pluginData.worldRegion = worldRegion;
|
|
586
|
+
this._hknp.HP_World_AddBody(worldRegion.world, hkbody, body.startAsleep);
|
|
471
587
|
pluginData.worldTransformOffset = this._hknp.HP_Body_GetWorldTransformOffset(hkbody)[1];
|
|
472
588
|
}
|
|
473
589
|
}
|
|
@@ -504,7 +620,7 @@ export class HavokPlugin {
|
|
|
504
620
|
for (let i = 0; i < instancesToRemove; i++) {
|
|
505
621
|
const hkbody = body._pluginDataInstances.pop();
|
|
506
622
|
this._bodies.delete(hkbody.hpBodyId[0]);
|
|
507
|
-
this._hknp.HP_World_RemoveBody(
|
|
623
|
+
this._hknp.HP_World_RemoveBody(hkbody.worldRegion.world, hkbody.hpBodyId);
|
|
508
624
|
this._hknp.HP_Body_Release(hkbody.hpBodyId);
|
|
509
625
|
}
|
|
510
626
|
this._createOrUpdateBodyInstances(body, motionType, matrixData, 0, instancesCount, true);
|
|
@@ -535,6 +651,8 @@ export class HavokPlugin {
|
|
|
535
651
|
* physical behavior of the body.
|
|
536
652
|
*/
|
|
537
653
|
syncTransform(body, transformNode) {
|
|
654
|
+
// Get the floating origin offset - this was subtracted when positions were sent to Havok
|
|
655
|
+
// We need to add it back to get the correct world position
|
|
538
656
|
if (body._pluginDataInstances.length) {
|
|
539
657
|
// instances
|
|
540
658
|
const m = transformNode;
|
|
@@ -544,26 +662,40 @@ export class HavokPlugin {
|
|
|
544
662
|
}
|
|
545
663
|
const instancesCount = body._pluginDataInstances.length;
|
|
546
664
|
for (let i = 0; i < instancesCount; i++) {
|
|
547
|
-
const
|
|
548
|
-
|
|
665
|
+
const pluginData = body._pluginDataInstances[i];
|
|
666
|
+
// Use instance's world region offset
|
|
667
|
+
const instanceOffset = pluginData.worldRegion.floatingOrigin;
|
|
668
|
+
const bodyBuffer = this._bodyBuffer;
|
|
669
|
+
const bufOffset = pluginData.worldTransformOffset;
|
|
670
|
+
const transformBuffer = new Float32Array(this._hknp.HEAPU8.buffer, bodyBuffer + bufOffset, 16);
|
|
549
671
|
const index = i * 16;
|
|
550
672
|
for (let mi = 0; mi < 15; mi++) {
|
|
551
673
|
if ((mi & 3) != 3) {
|
|
552
674
|
matrixData[index + mi] = transformBuffer[mi];
|
|
553
675
|
}
|
|
554
676
|
}
|
|
677
|
+
// Add back the floating origin offset to get world position
|
|
678
|
+
// (Havok stores position - offset, so we add offset back)
|
|
679
|
+
matrixData[index + 12] += instanceOffset._x;
|
|
680
|
+
matrixData[index + 13] += instanceOffset._y;
|
|
681
|
+
matrixData[index + 14] += instanceOffset._z;
|
|
555
682
|
matrixData[index + 15] = 1;
|
|
556
683
|
}
|
|
557
684
|
m.thinInstanceBufferUpdated("matrix");
|
|
558
685
|
}
|
|
559
686
|
else {
|
|
560
687
|
try {
|
|
561
|
-
// regular
|
|
562
688
|
const bodyTransform = this._hknp.HP_Body_GetQTransform(body._pluginData.hpBodyId)[1];
|
|
563
689
|
const bodyTranslation = bodyTransform[0];
|
|
564
690
|
const bodyOrientation = bodyTransform[1];
|
|
565
691
|
const quat = TmpVectors.Quaternion[0];
|
|
692
|
+
// Use body's world region offset
|
|
693
|
+
const offset = body._pluginData.worldRegion.floatingOrigin;
|
|
566
694
|
quat.set(bodyOrientation[0], bodyOrientation[1], bodyOrientation[2], bodyOrientation[3]);
|
|
695
|
+
// Add back the floating origin offset to get world position
|
|
696
|
+
const worldX = bodyTranslation[0] + offset._x;
|
|
697
|
+
const worldY = bodyTranslation[1] + offset._y;
|
|
698
|
+
const worldZ = bodyTranslation[2] + offset._z;
|
|
567
699
|
const parent = transformNode.parent;
|
|
568
700
|
// transform position/orientation in parent space
|
|
569
701
|
if (parent && !parent.getWorldMatrix().isIdentity()) {
|
|
@@ -573,7 +705,7 @@ export class HavokPlugin {
|
|
|
573
705
|
quat.normalize();
|
|
574
706
|
const finalTransform = TmpVectors.Matrix[0];
|
|
575
707
|
const finalTranslation = TmpVectors.Vector3[0];
|
|
576
|
-
finalTranslation.copyFromFloats(
|
|
708
|
+
finalTranslation.copyFromFloats(worldX, worldY, worldZ);
|
|
577
709
|
Matrix.ComposeToRef(transformNode.absoluteScaling, quat, finalTranslation, finalTransform);
|
|
578
710
|
const parentInverseTransform = TmpVectors.Matrix[1];
|
|
579
711
|
parent.getWorldMatrix().invertToRef(parentInverseTransform);
|
|
@@ -585,7 +717,7 @@ export class HavokPlugin {
|
|
|
585
717
|
transformNode.scaling.copyFrom(TmpVectors.Vector3[1]);
|
|
586
718
|
}
|
|
587
719
|
else {
|
|
588
|
-
transformNode.position.set(
|
|
720
|
+
transformNode.position.set(worldX, worldY, worldZ);
|
|
589
721
|
if (transformNode.rotationQuaternion) {
|
|
590
722
|
transformNode.rotationQuaternion.copyFrom(quat);
|
|
591
723
|
}
|
|
@@ -938,7 +1070,8 @@ export class HavokPlugin {
|
|
|
938
1070
|
*/
|
|
939
1071
|
applyImpulse(body, impulse, location, instanceIndex) {
|
|
940
1072
|
this._applyToBodyOrInstances(body, (pluginRef) => {
|
|
941
|
-
|
|
1073
|
+
const offset = pluginRef.worldRegion.floatingOrigin;
|
|
1074
|
+
this._hknp.HP_Body_ApplyImpulse(pluginRef.hpBodyId, this._bVecToV3WithOffset(location, offset), this._bVecToV3(impulse));
|
|
942
1075
|
}, instanceIndex);
|
|
943
1076
|
}
|
|
944
1077
|
/**
|
|
@@ -1036,8 +1169,9 @@ export class HavokPlugin {
|
|
|
1036
1169
|
this._createOrUpdateBodyInstances(body, body.getMotionType(), matrixData, 0, instancesCount, true);
|
|
1037
1170
|
}
|
|
1038
1171
|
else {
|
|
1039
|
-
// regular
|
|
1040
|
-
|
|
1172
|
+
// regular - use body's world region offset
|
|
1173
|
+
const offset = body._pluginData.worldRegion.floatingOrigin;
|
|
1174
|
+
this._hknp.HP_Body_SetQTransform(body._pluginData.hpBodyId, this._getTransformInfos(node, offset));
|
|
1041
1175
|
}
|
|
1042
1176
|
}
|
|
1043
1177
|
else if (body.getPrestepType() == PhysicsPrestepType.ACTION) {
|
|
@@ -1059,7 +1193,8 @@ export class HavokPlugin {
|
|
|
1059
1193
|
*/
|
|
1060
1194
|
setTargetTransform(body, position, rotation, instanceIndex) {
|
|
1061
1195
|
this._applyToBodyOrInstances(body, (pluginRef) => {
|
|
1062
|
-
|
|
1196
|
+
const offset = pluginRef.worldRegion.floatingOrigin;
|
|
1197
|
+
this._hknp.HP_Body_SetTargetQTransform(pluginRef.hpBodyId, [this._bVecToV3WithOffset(position, offset), this._bQuatToV4(rotation)]);
|
|
1063
1198
|
}, instanceIndex);
|
|
1064
1199
|
}
|
|
1065
1200
|
/**
|
|
@@ -1341,12 +1476,13 @@ export class HavokPlugin {
|
|
|
1341
1476
|
* It first checks if the node has a rotation quaternion, and if not, it creates one from the node's rotation.
|
|
1342
1477
|
* It then creates an array containing the position and orientation of the node and returns it.
|
|
1343
1478
|
* @param node - The transform node.
|
|
1479
|
+
* @param offset - The floating origin offset to apply.
|
|
1344
1480
|
* @returns An array containing the position and orientation of the node.
|
|
1345
1481
|
*/
|
|
1346
|
-
_getTransformInfos(node) {
|
|
1482
|
+
_getTransformInfos(node, offset) {
|
|
1347
1483
|
if (node.parent) {
|
|
1348
1484
|
node.computeWorldMatrix(true);
|
|
1349
|
-
return [this.
|
|
1485
|
+
return [this._bVecToV3WithOffset(node.absolutePosition, offset), this._bQuatToV4(node.absoluteRotationQuaternion)];
|
|
1350
1486
|
}
|
|
1351
1487
|
let orientation = TmpVectors.Quaternion[0];
|
|
1352
1488
|
if (node.rotationQuaternion) {
|
|
@@ -1356,7 +1492,7 @@ export class HavokPlugin {
|
|
|
1356
1492
|
const r = node.rotation;
|
|
1357
1493
|
Quaternion.FromEulerAnglesToRef(r.x, r.y, r.z, orientation);
|
|
1358
1494
|
}
|
|
1359
|
-
const transform = [this.
|
|
1495
|
+
const transform = [this._bVecToV3WithOffset(node.position, offset), this._bQuatToV4(orientation)];
|
|
1360
1496
|
return transform;
|
|
1361
1497
|
}
|
|
1362
1498
|
/**
|
|
@@ -1905,7 +2041,10 @@ export class HavokPlugin {
|
|
|
1905
2041
|
const hitPos = hitData[3];
|
|
1906
2042
|
const hitNormal = hitData[4];
|
|
1907
2043
|
const hitTriangle = hitData[5];
|
|
1908
|
-
|
|
2044
|
+
// Add floating origin offset back to hit position using the hit body's world region offset
|
|
2045
|
+
// If no hit body (shouldn't happen), use zero offset from default region
|
|
2046
|
+
const offset = hitBody?.body?._pluginData?.worldRegion?.floatingOrigin ?? this._worldRegions[0].floatingOrigin;
|
|
2047
|
+
result.setHitData({ x: hitNormal[0], y: hitNormal[1], z: hitNormal[2] }, { x: hitPos[0] + offset._x, y: hitPos[1] + offset._y, z: hitPos[2] + offset._z }, hitTriangle);
|
|
1909
2048
|
}
|
|
1910
2049
|
/**
|
|
1911
2050
|
* Performs a raycast from a given start point to a given end point and stores the result in a given PhysicsRaycastResult object.
|
|
@@ -1929,9 +2068,15 @@ export class HavokPlugin {
|
|
|
1929
2068
|
for (const raycastResult of results) {
|
|
1930
2069
|
raycastResult.reset(from, to);
|
|
1931
2070
|
}
|
|
1932
|
-
|
|
2071
|
+
// Use the ignored body's world region if available, otherwise use default region
|
|
2072
|
+
const worldRegion = query?.ignoreBody?._pluginData?.worldRegion ?? this._worldRegions[0];
|
|
2073
|
+
const offset = worldRegion.floatingOrigin;
|
|
2074
|
+
const world = worldRegion.world;
|
|
2075
|
+
const offsetFrom = this._bVecToV3WithOffset(from, offset);
|
|
2076
|
+
const offsetTo = this._bVecToV3WithOffset(to, offset);
|
|
2077
|
+
const hkQuery = [offsetFrom, offsetTo, [queryMembership, queryCollideWith], shouldHitTriggers, bodyToIgnore];
|
|
1933
2078
|
const queryCollector = results.length === 1 || !this._multiQueryCollector ? this._queryCollector : this._multiQueryCollector;
|
|
1934
|
-
this._hknp.HP_World_CastRayWithCollector(
|
|
2079
|
+
this._hknp.HP_World_CastRayWithCollector(world, queryCollector, hkQuery);
|
|
1935
2080
|
const numHits = this._hknp.HP_QueryCollector_GetNumHits(queryCollector)[1];
|
|
1936
2081
|
if (numHits <= 0) {
|
|
1937
2082
|
return;
|
|
@@ -1948,7 +2093,8 @@ export class HavokPlugin {
|
|
|
1948
2093
|
for (let i = 0; i < numHits; i++) {
|
|
1949
2094
|
const [, hitData] = this._hknp.HP_QueryCollector_GetCastRayResult(queryCollector, i)[1];
|
|
1950
2095
|
const hitPos = hitData[3];
|
|
1951
|
-
|
|
2096
|
+
// Use offsetFrom for distance calculation since hitPos is in Havok's offset space
|
|
2097
|
+
this._tmpVec3[0].set(offsetFrom[0] - hitPos[0], offsetFrom[1] - hitPos[1], offsetFrom[2] - hitPos[2]);
|
|
1952
2098
|
const distance = this._tmpVec3[0].lengthSquared();
|
|
1953
2099
|
hitDatas[i] = {
|
|
1954
2100
|
hitData,
|
|
@@ -1974,8 +2120,12 @@ export class HavokPlugin {
|
|
|
1974
2120
|
const queryCollideWith = query?.collisionFilter?.collideWith ?? ~0;
|
|
1975
2121
|
result.reset();
|
|
1976
2122
|
const bodyToIgnore = query.ignoreBody ? [BigInt(query.ignoreBody._pluginData.hpBodyId[0])] : [BigInt(0)];
|
|
1977
|
-
|
|
1978
|
-
|
|
2123
|
+
// Use the ignored body's world region if available, otherwise use default region
|
|
2124
|
+
const worldRegion = query.ignoreBody?._pluginData?.worldRegion ?? this._worldRegions[0];
|
|
2125
|
+
const offset = worldRegion.floatingOrigin;
|
|
2126
|
+
const world = worldRegion.world;
|
|
2127
|
+
const hkQuery = [this._bVecToV3WithOffset(query.position, offset), query.maxDistance, [queryMembership, queryCollideWith], query.shouldHitTriggers, bodyToIgnore];
|
|
2128
|
+
this._hknp.HP_World_PointProximityWithCollector(world, this._queryCollector, hkQuery);
|
|
1979
2129
|
if (this._hknp.HP_QueryCollector_GetNumHits(this._queryCollector)[1] > 0) {
|
|
1980
2130
|
const [distance, hitData] = this._hknp.HP_QueryCollector_GetPointProximityResult(this._queryCollector, 0)[1];
|
|
1981
2131
|
this._populateHitData(hitData, result);
|
|
@@ -1993,8 +2143,12 @@ export class HavokPlugin {
|
|
|
1993
2143
|
hitShapeResult.reset();
|
|
1994
2144
|
const shapeId = query.shape._pluginData;
|
|
1995
2145
|
const bodyToIgnore = query.ignoreBody ? [BigInt(query.ignoreBody._pluginData.hpBodyId[0])] : [BigInt(0)];
|
|
1996
|
-
|
|
1997
|
-
|
|
2146
|
+
// Use the ignored body's world region if available, otherwise use default region
|
|
2147
|
+
const worldRegion = query.ignoreBody?._pluginData?.worldRegion ?? this._worldRegions[0];
|
|
2148
|
+
const offset = worldRegion.floatingOrigin;
|
|
2149
|
+
const world = worldRegion.world;
|
|
2150
|
+
const hkQuery = [shapeId, this._bVecToV3WithOffset(query.position, offset), this._bQuatToV4(query.rotation), query.maxDistance, query.shouldHitTriggers, bodyToIgnore];
|
|
2151
|
+
this._hknp.HP_World_ShapeProximityWithCollector(world, this._queryCollector, hkQuery);
|
|
1998
2152
|
if (this._hknp.HP_QueryCollector_GetNumHits(this._queryCollector)[1] > 0) {
|
|
1999
2153
|
const [distance, hitInputData, hitShapeData] = this._hknp.HP_QueryCollector_GetShapeProximityResult(this._queryCollector, 0)[1];
|
|
2000
2154
|
this._populateHitData(hitInputData, inputShapeResult);
|
|
@@ -2014,8 +2168,19 @@ export class HavokPlugin {
|
|
|
2014
2168
|
hitShapeResult.reset();
|
|
2015
2169
|
const shapeId = query.shape._pluginData;
|
|
2016
2170
|
const bodyToIgnore = query.ignoreBody ? [BigInt(query.ignoreBody._pluginData.hpBodyId[0])] : [BigInt(0)];
|
|
2017
|
-
|
|
2018
|
-
|
|
2171
|
+
// Use the ignored body's world region if available, otherwise use default region
|
|
2172
|
+
const worldRegion = query.ignoreBody?._pluginData?.worldRegion ?? this._worldRegions[0];
|
|
2173
|
+
const offset = worldRegion.floatingOrigin;
|
|
2174
|
+
const world = worldRegion.world;
|
|
2175
|
+
const hkQuery = [
|
|
2176
|
+
shapeId,
|
|
2177
|
+
this._bQuatToV4(query.rotation),
|
|
2178
|
+
this._bVecToV3WithOffset(query.startPosition, offset),
|
|
2179
|
+
this._bVecToV3WithOffset(query.endPosition, offset),
|
|
2180
|
+
query.shouldHitTriggers,
|
|
2181
|
+
bodyToIgnore,
|
|
2182
|
+
];
|
|
2183
|
+
this._hknp.HP_World_ShapeCastWithCollector(world, this._queryCollector, hkQuery);
|
|
2019
2184
|
if (this._hknp.HP_QueryCollector_GetNumHits(this._queryCollector)[1] > 0) {
|
|
2020
2185
|
const [fractionAlongRay, hitInputData, hitShapeData] = this._hknp.HP_QueryCollector_GetShapeCastResult(this._queryCollector, 0)[1];
|
|
2021
2186
|
this._populateHitData(hitInputData, inputShapeResult);
|
|
@@ -2093,8 +2258,9 @@ export class HavokPlugin {
|
|
|
2093
2258
|
this._hknp.HP_Body_SetEventMask(body._pluginData.hpBodyId, currentCollideEvents);
|
|
2094
2259
|
}
|
|
2095
2260
|
}
|
|
2096
|
-
_notifyTriggers() {
|
|
2097
|
-
|
|
2261
|
+
_notifyTriggers(world) {
|
|
2262
|
+
const targetWorld = world ?? this.world;
|
|
2263
|
+
let eventAddress = this._hknp.HP_World_GetTriggerEvents(targetWorld)[1];
|
|
2098
2264
|
const event = new TriggerEvent();
|
|
2099
2265
|
while (eventAddress) {
|
|
2100
2266
|
TriggerEvent.readToRef(this._hknp.HEAPU8.buffer, eventAddress, event);
|
|
@@ -2111,20 +2277,28 @@ export class HavokPlugin {
|
|
|
2111
2277
|
};
|
|
2112
2278
|
this.onTriggerCollisionObservable.notifyObservers(triggerCollisionInfo);
|
|
2113
2279
|
}
|
|
2114
|
-
eventAddress = this._hknp.HP_World_GetNextTriggerEvent(
|
|
2280
|
+
eventAddress = this._hknp.HP_World_GetNextTriggerEvent(targetWorld, eventAddress);
|
|
2115
2281
|
}
|
|
2116
2282
|
}
|
|
2117
2283
|
/**
|
|
2118
2284
|
* Runs thru all detected collisions and filter by body
|
|
2285
|
+
* @param world optional world to check collisions for (defaults to main world)
|
|
2119
2286
|
*/
|
|
2120
|
-
_notifyCollisions() {
|
|
2121
|
-
|
|
2287
|
+
_notifyCollisions(world) {
|
|
2288
|
+
const targetWorld = world ?? this.world;
|
|
2289
|
+
let eventAddress = this._hknp.HP_World_GetCollisionEvents(targetWorld)[1];
|
|
2122
2290
|
const event = new CollisionEvent();
|
|
2123
|
-
const worldAddr = Number(
|
|
2291
|
+
const worldAddr = Number(targetWorld);
|
|
2124
2292
|
while (eventAddress) {
|
|
2125
2293
|
CollisionEvent.readToRef(this._hknp.HEAPU8.buffer, eventAddress, event);
|
|
2126
2294
|
const bodyInfoA = this._bodies.get(event.contactOnA.bodyId);
|
|
2127
2295
|
const bodyInfoB = this._bodies.get(event.contactOnB.bodyId);
|
|
2296
|
+
// Add floating origin offset back to collision contact positions using the body's world region offset
|
|
2297
|
+
// If body doesn't exist, use default region's offset (zero)
|
|
2298
|
+
const offsetA = bodyInfoA?.body?._pluginData?.worldRegion?.floatingOrigin ?? this._worldRegions[0].floatingOrigin;
|
|
2299
|
+
event.contactOnA.position.addInPlace(offsetA);
|
|
2300
|
+
const offsetB = bodyInfoB?.body?._pluginData?.worldRegion?.floatingOrigin ?? this._worldRegions[0].floatingOrigin;
|
|
2301
|
+
event.contactOnB.position.addInPlace(offsetB);
|
|
2128
2302
|
// Bodies may have been disposed between events. Check both still exist.
|
|
2129
2303
|
if (bodyInfoA && bodyInfoB) {
|
|
2130
2304
|
const collisionInfo = {
|
|
@@ -2212,12 +2386,16 @@ export class HavokPlugin {
|
|
|
2212
2386
|
}
|
|
2213
2387
|
if (this._multiQueryCollector) {
|
|
2214
2388
|
this._hknp.HP_QueryCollector_Release(this._multiQueryCollector);
|
|
2215
|
-
this._multiQueryCollector;
|
|
2389
|
+
this._multiQueryCollector = undefined;
|
|
2216
2390
|
}
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2391
|
+
// Dispose all world regions (includes the default world)
|
|
2392
|
+
for (const region of this._worldRegions) {
|
|
2393
|
+
if (region.world) {
|
|
2394
|
+
this._hknp.HP_World_Release(region.world);
|
|
2395
|
+
}
|
|
2220
2396
|
}
|
|
2397
|
+
this._worldRegions.length = 0;
|
|
2398
|
+
this.world = undefined;
|
|
2221
2399
|
}
|
|
2222
2400
|
_v3ToBvecRef(v, vec3) {
|
|
2223
2401
|
vec3.set(v[0], v[1], v[2]);
|
|
@@ -2225,6 +2403,19 @@ export class HavokPlugin {
|
|
|
2225
2403
|
_bVecToV3(v) {
|
|
2226
2404
|
return [v._x, v._y, v._z];
|
|
2227
2405
|
}
|
|
2406
|
+
/**
|
|
2407
|
+
* Converts a Vector3 to Havok format with floating origin offset subtracted.
|
|
2408
|
+
* Use this for world-space positions being sent to Havok.
|
|
2409
|
+
* @param v - The vector to convert
|
|
2410
|
+
* @param offset - Optional offset to use. If not provided, no offset is applied.
|
|
2411
|
+
* @returns The converted vector
|
|
2412
|
+
*/
|
|
2413
|
+
_bVecToV3WithOffset(v, offset) {
|
|
2414
|
+
if (offset) {
|
|
2415
|
+
return [v._x - offset._x, v._y - offset._y, v._z - offset._z];
|
|
2416
|
+
}
|
|
2417
|
+
return [v._x, v._y, v._z];
|
|
2418
|
+
}
|
|
2228
2419
|
_bQuatToV4(q) {
|
|
2229
2420
|
return [q._x, q._y, q._z, q._w];
|
|
2230
2421
|
}
|