@series-inc/rundot-syncplay 5.28.0-beta.0 → 5.28.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.d.ts +4 -4
- package/dist/browser.js +2 -2
- package/dist/creator.d.ts +6 -4
- package/dist/creator.js +3 -2
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -2
- package/dist/physics3d-destruction-cert.js +9 -2
- package/dist/physics3d-voxel.d.ts +51 -4
- package/dist/physics3d-voxel.js +282 -15
- package/dist/physics3d.d.ts +45 -2
- package/dist/physics3d.js +162 -1
- package/dist/schema-dsl-binary.d.ts +2 -2
- package/dist/schema-dsl-binary.js +25 -2
- package/package.json +2 -2
package/dist/browser.d.ts
CHANGED
|
@@ -24,8 +24,8 @@ export { createNetworkedSyncplayClient, prepareNetworkedSyncplayTransport } from
|
|
|
24
24
|
export { createSyncplayRunner } from './runner.js';
|
|
25
25
|
export { fbm2D, hash2, hashUint32, valueNoise1D, valueNoise2D } from './noise.js';
|
|
26
26
|
export { circleCastDeterministicPhysics2D, createDeterministicPhysicsWorld2D, nearestDeterministicPhysicsHit2D, queryDeterministicPhysicsAabb2D, queryDeterministicPhysicsShapeOverlap2D, raycastAllDeterministicPhysics2D, raycastDeterministicPhysics2D, stepDeterministicPhysicsWorld2D } from './physics2d.js';
|
|
27
|
-
export { applyDeterministicImpulse3D, applyDeterministicImpulses3D, applyDeterministicWorldEdit3D, contactDetailsDeterministicPhysics3D, createBoxShapeFromExtents, createBoxShapeFromMinMax, createCapsuleShapeFromBase, createDeterministicPhysicsWorld3D, createTrustedDeterministicPhysicsWorld3D, deriveInverseInertia, deterministicPhysicsBodyById3D, deterministicPhysicsCallback3D, overlapDeterministicPhysics3D, raycastDeterministicPhysics3D, raycastDeterministicPhysics3DDetailed, runDeterministicPhysics3DStress, setDeterministicBodyVelocity3D, setDeterministicKinematicPoses3D, setDeterministicKinematicTransforms3D, shapeCastDeterministicPhysics3D, shapeCastDeterministicPhysics3DDetailed, stepDeterministicPhysicsWorld3D } from './physics3d.js';
|
|
28
|
-
export { carveDeterministicVoxelChunk3D, cookDeterministicVoxelChunkCollider3D, cookDeterministicVoxelSubregion3D, raycastDeterministicVoxelChunk3D } from './physics3d-voxel.js';
|
|
27
|
+
export { applyDeterministicForces3D, applyDeterministicImpulse3D, applyDeterministicImpulses3D, applyDeterministicWorldEdit3D, contactDetailsDeterministicPhysics3D, createBoxShapeFromExtents, createBoxShapeFromMinMax, createCapsuleShapeFromBase, createDeterministicPhysicsWorld3D, createTrustedDeterministicPhysicsWorld3D, deriveInverseInertia, deterministicPhysicsBodyById3D, deterministicPhysicsCallback3D, overlapDeterministicPhysics3D, raycastDeterministicPhysics3D, raycastDeterministicPhysics3DDetailed, runDeterministicPhysics3DStress, setDeterministicBodyVelocity3D, setDeterministicKinematicPoses3D, setDeterministicKinematicTransforms3D, shapeCastDeterministicPhysics3D, shapeCastDeterministicPhysics3DDetailed, stepDeterministicPhysicsWorld3D } from './physics3d.js';
|
|
28
|
+
export { carveDeterministicVoxelChunk3D, cookDeterministicVoxelChunkCollider3D, cookDeterministicVoxelSubregion3D, recookDeterministicVoxelSubregion3D, raycastDeterministicVoxelChunk3D, splitDeterministicVoxelChunk3D } from './physics3d-voxel.js';
|
|
29
29
|
export { generatePhysicsWorldDebugMesh } from './debug-wireframe.js';
|
|
30
30
|
export { cylinderHullVertices } from './physics3d-hull.js';
|
|
31
31
|
export { createDeterministicCosmeticPhysicsWorld3D, setDeterministicCosmeticPhysicsAuthoritativeBodyProxies3D, stepDeterministicCosmeticPhysicsWorld3D } from './cosmetic-physics3d.js';
|
|
@@ -66,8 +66,8 @@ export type { CookedDeterministicNavmesh, DeterministicNavmeshAgent, Determinist
|
|
|
66
66
|
export type { ConfirmedSyncplayPresentationFrame, KinetixRuntimeFactory, NetworkedClientTransport, NetworkedSyncplayClient, NetworkedSyncplayClientInputDelayOptions, NetworkedSyncplayClientNetStats, NetworkedSyncplayClientOptions, NetworkedSyncplayClientPacingOptions, NetworkedSyncplayPreparationOptions, NetworkedSyncplaySessionDescriptor, NetworkedSyncplaySlotPresence, PreparedNetworkedSyncplayTransport, SyncplayPredictionMode, SyncplayRemoteInputPrediction } from './networked-client.js';
|
|
67
67
|
export type { SyncplayRunner, SyncplayRunnerConfig, SyncplayRunnerConnectionEvent, SyncplayRunnerOccupancy, SyncplayRunnerOfflineOptions, SyncplayRunnerPresentation, SyncplayRunnerSnapshot, SyncplayRunnerStatus, SyncplayRunnerTransport } from './runner.js';
|
|
68
68
|
export type { DeterministicBodyKind, DeterministicContactEvent2D, DeterministicContactEventType, DeterministicPhysicsAabbQuery2D, DeterministicPhysicsActivePair2D, DeterministicPhysicsBody2D, DeterministicPhysicsCircleCastQuery2D, DeterministicPhysicsConstraint2D, DeterministicPhysicsHit2D, DeterministicPhysicsQueryOptions2D, DeterministicPhysicsRaycastQuery2D, DeterministicPhysicsShape2D, DeterministicPhysicsShapeOverlapQuery2D, DeterministicPhysicsStepOptions2D, DeterministicPhysicsStepResult2D, DeterministicPhysicsWorld2D } from './physics2d.js';
|
|
69
|
-
export type { DeterministicContactCacheEntry3D, DeterministicJointCacheEntry3D, DeterministicKinematicPose3D, DeterministicKinematicTransformBuffer3D, DeterministicPhysicsActivePair3D, DeterministicPhysicsAxisLock3D, DeterministicPhysicsBody3D, DeterministicPhysicsCallbackMask3D, DeterministicPhysicsCompoundChild3D, DeterministicPhysicsCompoundChildShape3D, DeterministicPhysicsConstraint3D, DeterministicPhysicsContactDetail3D, DeterministicPhysicsContactEvent3D, DeterministicPhysicsDetailedHit3D, DeterministicPhysicsHit3D, DeterministicPhysicsHullShape3D, DeterministicPhysicsImpulseApplication3D, DeterministicPhysicsOverlapQuery3D, DeterministicPhysicsPrimitiveShape3D, DeterministicPhysicsQuaternion3D, DeterministicPhysicsQueryOptions3D, DeterministicPhysicsRaycastQuery3D, DeterministicPhysicsScheduledQuery3D, DeterministicPhysicsShape3D, DeterministicPhysicsShapeCastQuery3D, DeterministicPhysicsStepResult3D, DeterministicPhysicsVec3, DeterministicPhysicsWorld3D, DeterministicPhysicsWorldEdit3D } from './physics3d.js';
|
|
70
|
-
export type { DeterministicVoxelChunk3D, DeterministicVoxelCompoundShape3D, DeterministicVoxelRayHit3D, VoxelCarveRegion3D } from './physics3d-voxel.js';
|
|
69
|
+
export type { DeterministicContactCacheEntry3D, DeterministicJointCacheEntry3D, DeterministicKinematicPose3D, DeterministicKinematicTransformBuffer3D, DeterministicPhysicsActivePair3D, DeterministicPhysicsAxisLock3D, DeterministicPhysicsBody3D, DeterministicPhysicsCallbackMask3D, DeterministicPhysicsCompoundChild3D, DeterministicPhysicsCompoundChildShape3D, DeterministicPhysicsConstraint3D, DeterministicPhysicsContactDetail3D, DeterministicPhysicsContactEvent3D, DeterministicPhysicsDetailedHit3D, DeterministicPhysicsForceApplication3D, DeterministicPhysicsHit3D, DeterministicPhysicsHullShape3D, DeterministicPhysicsImpulseApplication3D, DeterministicPhysicsOverlapQuery3D, DeterministicPhysicsPrimitiveShape3D, DeterministicPhysicsQuaternion3D, DeterministicPhysicsQueryOptions3D, DeterministicPhysicsRaycastQuery3D, DeterministicPhysicsScheduledQuery3D, DeterministicPhysicsShape3D, DeterministicPhysicsShapeCastQuery3D, DeterministicPhysicsStepOptions3D, DeterministicPhysicsStepResult3D, DeterministicPhysicsVec3, DeterministicPhysicsWorld3D, DeterministicPhysicsWorldEdit3D } from './physics3d.js';
|
|
70
|
+
export type { DeterministicVoxelChunk3D, DeterministicVoxelCompoundShape3D, DeterministicVoxelRayHit3D, SplitDeterministicVoxelChunkOptions3D, VoxelAnchorFace, VoxelBoxCarveRegion3D, VoxelCapsuleCarveRegion3D, VoxelCarveRegion3D, VoxelOccupancy3D, VoxelSphereCarveRegion3D, VoxelSubChunk3D } from './physics3d-voxel.js';
|
|
71
71
|
export type { PhysicsWorldDebugMesh, PhysicsWorldDebugMeshOptions } from './debug-wireframe.js';
|
|
72
72
|
export type { DeterministicAuthoritativeBodyProxy3D, DeterministicCosmeticPhysicsBody3D, DeterministicCosmeticPhysicsStepOptions3D, DeterministicCosmeticPhysicsStepResult3D, DeterministicCosmeticPhysicsWorld3D } from './cosmetic-physics3d.js';
|
|
73
73
|
export type { DeterministicPhysicsJoint3D } from './physics3d-joints.js';
|
package/dist/browser.js
CHANGED
|
@@ -25,8 +25,8 @@ export { createNetworkedSyncplayClient, prepareNetworkedSyncplayTransport } from
|
|
|
25
25
|
export { createSyncplayRunner } from './runner.js';
|
|
26
26
|
export { fbm2D, hash2, hashUint32, valueNoise1D, valueNoise2D } from './noise.js';
|
|
27
27
|
export { circleCastDeterministicPhysics2D, createDeterministicPhysicsWorld2D, nearestDeterministicPhysicsHit2D, queryDeterministicPhysicsAabb2D, queryDeterministicPhysicsShapeOverlap2D, raycastAllDeterministicPhysics2D, raycastDeterministicPhysics2D, stepDeterministicPhysicsWorld2D } from './physics2d.js';
|
|
28
|
-
export { applyDeterministicImpulse3D, applyDeterministicImpulses3D, applyDeterministicWorldEdit3D, contactDetailsDeterministicPhysics3D, createBoxShapeFromExtents, createBoxShapeFromMinMax, createCapsuleShapeFromBase, createDeterministicPhysicsWorld3D, createTrustedDeterministicPhysicsWorld3D, deriveInverseInertia, deterministicPhysicsBodyById3D, deterministicPhysicsCallback3D, overlapDeterministicPhysics3D, raycastDeterministicPhysics3D, raycastDeterministicPhysics3DDetailed, runDeterministicPhysics3DStress, setDeterministicBodyVelocity3D, setDeterministicKinematicPoses3D, setDeterministicKinematicTransforms3D, shapeCastDeterministicPhysics3D, shapeCastDeterministicPhysics3DDetailed, stepDeterministicPhysicsWorld3D } from './physics3d.js';
|
|
29
|
-
export { carveDeterministicVoxelChunk3D, cookDeterministicVoxelChunkCollider3D, cookDeterministicVoxelSubregion3D, raycastDeterministicVoxelChunk3D } from './physics3d-voxel.js';
|
|
28
|
+
export { applyDeterministicForces3D, applyDeterministicImpulse3D, applyDeterministicImpulses3D, applyDeterministicWorldEdit3D, contactDetailsDeterministicPhysics3D, createBoxShapeFromExtents, createBoxShapeFromMinMax, createCapsuleShapeFromBase, createDeterministicPhysicsWorld3D, createTrustedDeterministicPhysicsWorld3D, deriveInverseInertia, deterministicPhysicsBodyById3D, deterministicPhysicsCallback3D, overlapDeterministicPhysics3D, raycastDeterministicPhysics3D, raycastDeterministicPhysics3DDetailed, runDeterministicPhysics3DStress, setDeterministicBodyVelocity3D, setDeterministicKinematicPoses3D, setDeterministicKinematicTransforms3D, shapeCastDeterministicPhysics3D, shapeCastDeterministicPhysics3DDetailed, stepDeterministicPhysicsWorld3D } from './physics3d.js';
|
|
29
|
+
export { carveDeterministicVoxelChunk3D, cookDeterministicVoxelChunkCollider3D, cookDeterministicVoxelSubregion3D, recookDeterministicVoxelSubregion3D, raycastDeterministicVoxelChunk3D, splitDeterministicVoxelChunk3D } from './physics3d-voxel.js';
|
|
30
30
|
export { generatePhysicsWorldDebugMesh } from './debug-wireframe.js';
|
|
31
31
|
export { cylinderHullVertices } from './physics3d-hull.js';
|
|
32
32
|
export { createDeterministicCosmeticPhysicsWorld3D, setDeterministicCosmeticPhysicsAuthoritativeBodyProxies3D, stepDeterministicCosmeticPhysicsWorld3D } from './cosmetic-physics3d.js';
|
package/dist/creator.d.ts
CHANGED
|
@@ -12,14 +12,16 @@ export type { RecordedChecksum, RecordedCommandFrame, RecordedDebugEvent, Record
|
|
|
12
12
|
export type { ReplayRuntimeFactory, ReplayVerificationConfig, ReplayVerificationExecution } from './replay.js';
|
|
13
13
|
export type { SyncplaySession, SyncplaySessionPolicy } from './sdk-session.js';
|
|
14
14
|
export type { InstantReplayInputFrame, InstantReplayResult, InstantReplayRunner, InstantReplayRunnerOptions, InstantReplayRunOptions, RunInstantReplayOptions, } from './instant-replay.js';
|
|
15
|
-
export { applyDeterministicImpulse3D, applyDeterministicImpulses3D, applyDeterministicWorldEdit3D, contactDetailsDeterministicPhysics3D, createBoxShapeFromExtents, createBoxShapeFromMinMax, createCapsuleShapeFromBase, createDeterministicPhysicsWorld3D, deriveInverseInertia, deterministicPhysicsBodyById3D, deterministicPhysicsCallback3D, overlapDeterministicPhysics3D, raycastDeterministicPhysics3D, raycastDeterministicPhysics3DDetailed, runDeterministicPhysics3DStress, setDeterministicBodyVelocity3D, setDeterministicKinematicPoses3D, setDeterministicKinematicTransforms3D, shapeCastDeterministicPhysics3D, shapeCastDeterministicPhysics3DDetailed, stepDeterministicPhysicsWorld3D, } from './physics3d.js';
|
|
16
|
-
export { carveDeterministicVoxelChunk3D, cookDeterministicVoxelChunkCollider3D, cookDeterministicVoxelSubregion3D, raycastDeterministicVoxelChunk3D, } from './physics3d-voxel.js';
|
|
15
|
+
export { applyDeterministicForces3D, applyDeterministicImpulse3D, applyDeterministicImpulses3D, applyDeterministicWorldEdit3D, contactDetailsDeterministicPhysics3D, createBoxShapeFromExtents, createBoxShapeFromMinMax, createCapsuleShapeFromBase, createDeterministicPhysicsWorld3D, deriveInverseInertia, deterministicPhysicsBodyById3D, deterministicPhysicsCallback3D, overlapDeterministicPhysics3D, raycastDeterministicPhysics3D, raycastDeterministicPhysics3DDetailed, runDeterministicPhysics3DStress, setDeterministicBodyVelocity3D, setDeterministicKinematicPoses3D, setDeterministicKinematicTransforms3D, shapeCastDeterministicPhysics3D, shapeCastDeterministicPhysics3DDetailed, stepDeterministicPhysicsWorld3D, } from './physics3d.js';
|
|
16
|
+
export { carveDeterministicVoxelChunk3D, cookDeterministicVoxelChunkCollider3D, cookDeterministicVoxelSubregion3D, recookDeterministicVoxelSubregion3D, raycastDeterministicVoxelChunk3D, splitDeterministicVoxelChunk3D, } from './physics3d-voxel.js';
|
|
17
17
|
export { generatePhysicsWorldDebugMesh } from './debug-wireframe.js';
|
|
18
18
|
export { cylinderHullVertices } from './physics3d-hull.js';
|
|
19
19
|
export { stepDeterministicVehicle3D } from './physics3d-vehicle.js';
|
|
20
|
-
export
|
|
21
|
-
export type {
|
|
20
|
+
export { createDeterministicBinarySerializer, deterministicDslMaxPlayers, parseDeterministicSchemaDsl, stableDeterministicDslSchemaJson, } from './schema-dsl-binary.js';
|
|
21
|
+
export type { DeterministicContactCacheEntry3D, DeterministicJointCacheEntry3D, DeterministicKinematicPose3D, DeterministicKinematicTransformBuffer3D, DeterministicPhysicsActivePair3D, DeterministicPhysicsAxisLock3D, DeterministicPhysicsBody3D, DeterministicPhysicsCallbackMask3D, DeterministicPhysicsCompoundChild3D, DeterministicPhysicsCompoundChildShape3D, DeterministicPhysicsConstraint3D, DeterministicPhysicsContactDetail3D, DeterministicPhysicsContactEvent3D, DeterministicPhysicsDetailedHit3D, DeterministicPhysicsForceApplication3D, DeterministicPhysicsHit3D, DeterministicPhysicsHullShape3D, DeterministicPhysicsImpulseApplication3D, DeterministicPhysicsOverlapQuery3D, DeterministicPhysicsPrimitiveShape3D, DeterministicPhysicsQuaternion3D, DeterministicPhysicsQueryOptions3D, DeterministicPhysicsRaycastQuery3D, DeterministicPhysicsScheduledQuery3D, DeterministicPhysicsShape3D, DeterministicPhysicsShapeCastQuery3D, DeterministicPhysicsStepOptions3D, DeterministicPhysicsStepResult3D, DeterministicPhysicsVec3, DeterministicPhysicsWorld3D, DeterministicPhysicsWorldEdit3D, } from './physics3d.js';
|
|
22
|
+
export type { DeterministicVoxelChunk3D, DeterministicVoxelCompoundShape3D, DeterministicVoxelRayHit3D, SplitDeterministicVoxelChunkOptions3D, VoxelAnchorFace, VoxelBoxCarveRegion3D, VoxelCapsuleCarveRegion3D, VoxelCarveRegion3D, VoxelOccupancy3D, VoxelSphereCarveRegion3D, VoxelSubChunk3D, } from './physics3d-voxel.js';
|
|
22
23
|
export type { PhysicsWorldDebugMesh, PhysicsWorldDebugMeshOptions } from './debug-wireframe.js';
|
|
23
24
|
export type { DeterministicPhysicsJoint3D } from './physics3d-joints.js';
|
|
24
25
|
export type { DeterministicVehicle3D, DeterministicVehicleImpulse3D, DeterministicVehicleInput3D, DeterministicVehicleStepOptions3D, DeterministicVehicleStepResult3D, DeterministicVehicleWheel3D, DeterministicVehicleWheelTelemetry3D, } from './physics3d-vehicle.js';
|
|
25
26
|
export type { DeterministicPhysicsMaterial } from './deterministic-primitives.js';
|
|
27
|
+
export type { DeterministicBinarySerializer, DeterministicDslDeclaration, DeterministicDslDeclarationKind, DeterministicDslDictionaryEntry, DeterministicDslDictionaryFieldKind, DeterministicDslField, DeterministicDslFieldKind, DeterministicDslFixedArrayFieldKind, DeterministicDslListFieldKind, DeterministicDslScalarFieldKind, DeterministicDslScalarValue, DeterministicDslSchema, DeterministicDslSetFieldKind, DeterministicDslValue, } from './schema-dsl-binary.js';
|
package/dist/creator.js
CHANGED
|
@@ -9,8 +9,9 @@ export { runSyncplaySynctest } from './synctest.js';
|
|
|
9
9
|
// create/step/edit, impulses, queries, vehicles, and voxel-chunk collider
|
|
10
10
|
// cooking. Cosmetic physics, KCC (movement3d), and the destruction-cert runner
|
|
11
11
|
// stay off it — the first two are not requested, the third reads wall clock.
|
|
12
|
-
export { applyDeterministicImpulse3D, applyDeterministicImpulses3D, applyDeterministicWorldEdit3D, contactDetailsDeterministicPhysics3D, createBoxShapeFromExtents, createBoxShapeFromMinMax, createCapsuleShapeFromBase, createDeterministicPhysicsWorld3D, deriveInverseInertia, deterministicPhysicsBodyById3D, deterministicPhysicsCallback3D, overlapDeterministicPhysics3D, raycastDeterministicPhysics3D, raycastDeterministicPhysics3DDetailed, runDeterministicPhysics3DStress, setDeterministicBodyVelocity3D, setDeterministicKinematicPoses3D, setDeterministicKinematicTransforms3D, shapeCastDeterministicPhysics3D, shapeCastDeterministicPhysics3DDetailed, stepDeterministicPhysicsWorld3D, } from './physics3d.js';
|
|
13
|
-
export { carveDeterministicVoxelChunk3D, cookDeterministicVoxelChunkCollider3D, cookDeterministicVoxelSubregion3D, raycastDeterministicVoxelChunk3D, } from './physics3d-voxel.js';
|
|
12
|
+
export { applyDeterministicForces3D, applyDeterministicImpulse3D, applyDeterministicImpulses3D, applyDeterministicWorldEdit3D, contactDetailsDeterministicPhysics3D, createBoxShapeFromExtents, createBoxShapeFromMinMax, createCapsuleShapeFromBase, createDeterministicPhysicsWorld3D, deriveInverseInertia, deterministicPhysicsBodyById3D, deterministicPhysicsCallback3D, overlapDeterministicPhysics3D, raycastDeterministicPhysics3D, raycastDeterministicPhysics3DDetailed, runDeterministicPhysics3DStress, setDeterministicBodyVelocity3D, setDeterministicKinematicPoses3D, setDeterministicKinematicTransforms3D, shapeCastDeterministicPhysics3D, shapeCastDeterministicPhysics3DDetailed, stepDeterministicPhysicsWorld3D, } from './physics3d.js';
|
|
13
|
+
export { carveDeterministicVoxelChunk3D, cookDeterministicVoxelChunkCollider3D, cookDeterministicVoxelSubregion3D, recookDeterministicVoxelSubregion3D, raycastDeterministicVoxelChunk3D, splitDeterministicVoxelChunk3D, } from './physics3d-voxel.js';
|
|
14
14
|
export { generatePhysicsWorldDebugMesh } from './debug-wireframe.js';
|
|
15
15
|
export { cylinderHullVertices } from './physics3d-hull.js';
|
|
16
16
|
export { stepDeterministicVehicle3D } from './physics3d-vehicle.js';
|
|
17
|
+
export { createDeterministicBinarySerializer, deterministicDslMaxPlayers, parseDeterministicSchemaDsl, stableDeterministicDslSchemaJson, } from './schema-dsl-binary.js';
|
package/dist/index.d.ts
CHANGED
|
@@ -27,8 +27,8 @@ export { createNetworkedSyncplayClient, prepareNetworkedSyncplayTransport } from
|
|
|
27
27
|
export { createSyncplayRunner } from './runner.js';
|
|
28
28
|
export { fbm2D, hash2, hashUint32, valueNoise1D, valueNoise2D } from './noise.js';
|
|
29
29
|
export { circleCastDeterministicPhysics2D, createDeterministicPhysicsWorld2D, nearestDeterministicPhysicsHit2D, queryDeterministicPhysicsAabb2D, queryDeterministicPhysicsShapeOverlap2D, raycastAllDeterministicPhysics2D, raycastDeterministicPhysics2D, stepDeterministicPhysicsWorld2D } from './physics2d.js';
|
|
30
|
-
export { applyDeterministicImpulse3D, applyDeterministicImpulses3D, applyDeterministicWorldEdit3D, contactDetailsDeterministicPhysics3D, createBoxShapeFromExtents, createBoxShapeFromMinMax, createCapsuleShapeFromBase, createDeterministicPhysicsWorld3D, createTrustedDeterministicPhysicsWorld3D, deriveInverseInertia, deterministicPhysicsBodyById3D, deterministicPhysicsCallback3D, overlapDeterministicPhysics3D, raycastDeterministicPhysics3D, raycastDeterministicPhysics3DDetailed, runDeterministicPhysics3DStress, setDeterministicBodyVelocity3D, setDeterministicKinematicPoses3D, setDeterministicKinematicTransforms3D, shapeCastDeterministicPhysics3D, shapeCastDeterministicPhysics3DDetailed, stepDeterministicPhysicsWorld3D } from './physics3d.js';
|
|
31
|
-
export { carveDeterministicVoxelChunk3D, cookDeterministicVoxelChunkCollider3D, cookDeterministicVoxelSubregion3D, raycastDeterministicVoxelChunk3D } from './physics3d-voxel.js';
|
|
30
|
+
export { applyDeterministicForces3D, applyDeterministicImpulse3D, applyDeterministicImpulses3D, applyDeterministicWorldEdit3D, contactDetailsDeterministicPhysics3D, createBoxShapeFromExtents, createBoxShapeFromMinMax, createCapsuleShapeFromBase, createDeterministicPhysicsWorld3D, createTrustedDeterministicPhysicsWorld3D, deriveInverseInertia, deterministicPhysicsBodyById3D, deterministicPhysicsCallback3D, overlapDeterministicPhysics3D, raycastDeterministicPhysics3D, raycastDeterministicPhysics3DDetailed, runDeterministicPhysics3DStress, setDeterministicBodyVelocity3D, setDeterministicKinematicPoses3D, setDeterministicKinematicTransforms3D, shapeCastDeterministicPhysics3D, shapeCastDeterministicPhysics3DDetailed, stepDeterministicPhysicsWorld3D } from './physics3d.js';
|
|
31
|
+
export { carveDeterministicVoxelChunk3D, cookDeterministicVoxelChunkCollider3D, cookDeterministicVoxelSubregion3D, recookDeterministicVoxelSubregion3D, raycastDeterministicVoxelChunk3D, splitDeterministicVoxelChunk3D } from './physics3d-voxel.js';
|
|
32
32
|
export { generatePhysicsWorldDebugMesh } from './debug-wireframe.js';
|
|
33
33
|
export { cylinderHullVertices } from './physics3d-hull.js';
|
|
34
34
|
export { runDeterministicPhysics3DDestructionCert } from './physics3d-destruction-cert.js';
|
|
@@ -78,8 +78,8 @@ export type { CookedDeterministicNavmesh, DeterministicNavmeshAgent, Determinist
|
|
|
78
78
|
export type { ConfirmedSyncplayPresentationFrame, KinetixRuntimeFactory, NetworkedClientTransport, NetworkedSyncplayClient, NetworkedSyncplayClientInputDelayOptions, NetworkedSyncplayClientNetStats, NetworkedSyncplayClientOptions, NetworkedSyncplayClientPacingOptions, NetworkedSyncplayPreparationOptions, NetworkedSyncplaySessionDescriptor, PreparedNetworkedSyncplayTransport, SyncplayPredictionMode, SyncplayRemoteInputPrediction } from './networked-client.js';
|
|
79
79
|
export type { SyncplayRunner, SyncplayRunnerConfig, SyncplayRunnerConnectionEvent, SyncplayRunnerOccupancy, SyncplayRunnerOfflineOptions, SyncplayRunnerPresentation, SyncplayRunnerSnapshot, SyncplayRunnerStatus, SyncplayRunnerTransport } from './runner.js';
|
|
80
80
|
export type { DeterministicBodyKind, DeterministicContactEvent2D, DeterministicContactEventType, DeterministicPhysicsAabbQuery2D, DeterministicPhysicsBody2D, DeterministicPhysicsCircleCastQuery2D, DeterministicPhysicsConstraint2D, DeterministicPhysicsHit2D, DeterministicPhysicsQueryOptions2D, DeterministicPhysicsRaycastQuery2D, DeterministicPhysicsShape2D, DeterministicPhysicsShapeOverlapQuery2D, DeterministicPhysicsStepOptions2D, DeterministicPhysicsStepResult2D, DeterministicPhysicsWorld2D } from './physics2d.js';
|
|
81
|
-
export type { DeterministicContactCacheEntry3D, DeterministicJointCacheEntry3D, DeterministicKinematicPose3D, DeterministicKinematicTransformBuffer3D, DeterministicPhysicsActivePair3D, DeterministicPhysicsAxisLock3D, DeterministicPhysicsBody3D, DeterministicPhysicsCallbackMask3D, DeterministicPhysicsCompoundChild3D, DeterministicPhysicsCompoundChildShape3D, DeterministicPhysicsConstraint3D, DeterministicPhysicsContactDetail3D, DeterministicPhysicsContactEvent3D, DeterministicPhysicsDetailedHit3D, DeterministicPhysicsHit3D, DeterministicPhysicsHullShape3D, DeterministicPhysicsImpulseApplication3D, DeterministicPhysicsOverlapQuery3D, DeterministicPhysicsPrimitiveShape3D, DeterministicPhysicsQuaternion3D, DeterministicPhysicsQueryOptions3D, DeterministicPhysicsRaycastQuery3D, DeterministicPhysicsScheduledQuery3D, DeterministicPhysicsShape3D, DeterministicPhysicsShapeCastQuery3D, DeterministicPhysicsStepResult3D, DeterministicPhysicsVec3, DeterministicPhysicsWorld3D, DeterministicPhysicsWorldEdit3D } from './physics3d.js';
|
|
82
|
-
export type { DeterministicVoxelChunk3D, DeterministicVoxelCompoundShape3D, DeterministicVoxelRayHit3D, VoxelCarveRegion3D } from './physics3d-voxel.js';
|
|
81
|
+
export type { DeterministicContactCacheEntry3D, DeterministicJointCacheEntry3D, DeterministicKinematicPose3D, DeterministicKinematicTransformBuffer3D, DeterministicPhysicsActivePair3D, DeterministicPhysicsAxisLock3D, DeterministicPhysicsBody3D, DeterministicPhysicsCallbackMask3D, DeterministicPhysicsCompoundChild3D, DeterministicPhysicsCompoundChildShape3D, DeterministicPhysicsConstraint3D, DeterministicPhysicsContactDetail3D, DeterministicPhysicsContactEvent3D, DeterministicPhysicsDetailedHit3D, DeterministicPhysicsForceApplication3D, DeterministicPhysicsHit3D, DeterministicPhysicsHullShape3D, DeterministicPhysicsImpulseApplication3D, DeterministicPhysicsOverlapQuery3D, DeterministicPhysicsPrimitiveShape3D, DeterministicPhysicsQuaternion3D, DeterministicPhysicsQueryOptions3D, DeterministicPhysicsRaycastQuery3D, DeterministicPhysicsScheduledQuery3D, DeterministicPhysicsShape3D, DeterministicPhysicsShapeCastQuery3D, DeterministicPhysicsStepOptions3D, DeterministicPhysicsStepResult3D, DeterministicPhysicsVec3, DeterministicPhysicsWorld3D, DeterministicPhysicsWorldEdit3D } from './physics3d.js';
|
|
82
|
+
export type { DeterministicVoxelChunk3D, DeterministicVoxelCompoundShape3D, DeterministicVoxelRayHit3D, SplitDeterministicVoxelChunkOptions3D, VoxelAnchorFace, VoxelBoxCarveRegion3D, VoxelCapsuleCarveRegion3D, VoxelCarveRegion3D, VoxelOccupancy3D, VoxelSphereCarveRegion3D, VoxelSubChunk3D } from './physics3d-voxel.js';
|
|
83
83
|
export type { PhysicsWorldDebugMesh, PhysicsWorldDebugMeshOptions } from './debug-wireframe.js';
|
|
84
84
|
export type { DeterministicDestructionCertOptions, DeterministicDestructionCertResult } from './physics3d-destruction-cert.js';
|
|
85
85
|
export type { DeterministicAuthoritativeBodyProxy3D, DeterministicCosmeticPhysicsBody3D, DeterministicCosmeticPhysicsStepOptions3D, DeterministicCosmeticPhysicsStepResult3D, DeterministicCosmeticPhysicsWorld3D } from './cosmetic-physics3d.js';
|
package/dist/index.js
CHANGED
|
@@ -28,8 +28,8 @@ export { createNetworkedSyncplayClient, prepareNetworkedSyncplayTransport } from
|
|
|
28
28
|
export { createSyncplayRunner } from './runner.js';
|
|
29
29
|
export { fbm2D, hash2, hashUint32, valueNoise1D, valueNoise2D } from './noise.js';
|
|
30
30
|
export { circleCastDeterministicPhysics2D, createDeterministicPhysicsWorld2D, nearestDeterministicPhysicsHit2D, queryDeterministicPhysicsAabb2D, queryDeterministicPhysicsShapeOverlap2D, raycastAllDeterministicPhysics2D, raycastDeterministicPhysics2D, stepDeterministicPhysicsWorld2D } from './physics2d.js';
|
|
31
|
-
export { applyDeterministicImpulse3D, applyDeterministicImpulses3D, applyDeterministicWorldEdit3D, contactDetailsDeterministicPhysics3D, createBoxShapeFromExtents, createBoxShapeFromMinMax, createCapsuleShapeFromBase, createDeterministicPhysicsWorld3D, createTrustedDeterministicPhysicsWorld3D, deriveInverseInertia, deterministicPhysicsBodyById3D, deterministicPhysicsCallback3D, overlapDeterministicPhysics3D, raycastDeterministicPhysics3D, raycastDeterministicPhysics3DDetailed, runDeterministicPhysics3DStress, setDeterministicBodyVelocity3D, setDeterministicKinematicPoses3D, setDeterministicKinematicTransforms3D, shapeCastDeterministicPhysics3D, shapeCastDeterministicPhysics3DDetailed, stepDeterministicPhysicsWorld3D } from './physics3d.js';
|
|
32
|
-
export { carveDeterministicVoxelChunk3D, cookDeterministicVoxelChunkCollider3D, cookDeterministicVoxelSubregion3D, raycastDeterministicVoxelChunk3D } from './physics3d-voxel.js';
|
|
31
|
+
export { applyDeterministicForces3D, applyDeterministicImpulse3D, applyDeterministicImpulses3D, applyDeterministicWorldEdit3D, contactDetailsDeterministicPhysics3D, createBoxShapeFromExtents, createBoxShapeFromMinMax, createCapsuleShapeFromBase, createDeterministicPhysicsWorld3D, createTrustedDeterministicPhysicsWorld3D, deriveInverseInertia, deterministicPhysicsBodyById3D, deterministicPhysicsCallback3D, overlapDeterministicPhysics3D, raycastDeterministicPhysics3D, raycastDeterministicPhysics3DDetailed, runDeterministicPhysics3DStress, setDeterministicBodyVelocity3D, setDeterministicKinematicPoses3D, setDeterministicKinematicTransforms3D, shapeCastDeterministicPhysics3D, shapeCastDeterministicPhysics3DDetailed, stepDeterministicPhysicsWorld3D } from './physics3d.js';
|
|
32
|
+
export { carveDeterministicVoxelChunk3D, cookDeterministicVoxelChunkCollider3D, cookDeterministicVoxelSubregion3D, recookDeterministicVoxelSubregion3D, raycastDeterministicVoxelChunk3D, splitDeterministicVoxelChunk3D } from './physics3d-voxel.js';
|
|
33
33
|
export { generatePhysicsWorldDebugMesh } from './debug-wireframe.js';
|
|
34
34
|
export { cylinderHullVertices } from './physics3d-hull.js';
|
|
35
35
|
export { runDeterministicPhysics3DDestructionCert } from './physics3d-destruction-cert.js';
|
|
@@ -87,7 +87,8 @@ function splitChunk(chunk) {
|
|
|
87
87
|
const sx = axis === 'x' ? x + from : x;
|
|
88
88
|
const sy = axis === 'y' ? y + from : y;
|
|
89
89
|
const sz = axis === 'z' ? z + from : z;
|
|
90
|
-
|
|
90
|
+
const val = chunk.occupancy[sx + chunk.dimX * (sy + chunk.dimY * sz)];
|
|
91
|
+
occupancy[x + dimX * (y + dimY * z)] = (val !== undefined && val !== 0) ? 1 : 0;
|
|
91
92
|
}
|
|
92
93
|
}
|
|
93
94
|
}
|
|
@@ -96,7 +97,13 @@ function splitChunk(chunk) {
|
|
|
96
97
|
return { lower: slice(0, cut), upper: slice(cut, dims[axis]), axis, offset: cut * chunk.cellSize };
|
|
97
98
|
}
|
|
98
99
|
function occupiedCount(chunk) {
|
|
99
|
-
|
|
100
|
+
let count = 0;
|
|
101
|
+
for (let i = 0; i < chunk.occupancy.length; i += 1) {
|
|
102
|
+
if (chunk.occupancy[i] !== 0) {
|
|
103
|
+
count += 1;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return count;
|
|
100
107
|
}
|
|
101
108
|
export function runDeterministicPhysics3DDestructionCert(options = {}) {
|
|
102
109
|
const chunks = options.chunks ?? 64;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { DeterministicPhysicsRaycastQuery3D, DeterministicPhysicsShape3D } from './physics3d.js';
|
|
2
|
+
export type VoxelOccupancy3D = readonly (0 | 1)[] | Uint8Array;
|
|
2
3
|
export interface DeterministicVoxelChunk3D {
|
|
3
4
|
readonly dimX: number;
|
|
4
5
|
readonly dimY: number;
|
|
@@ -6,7 +7,7 @@ export interface DeterministicVoxelChunk3D {
|
|
|
6
7
|
/** Edge length of one voxel in world units. Voxel (x,y,z) centers at (x·cellSize, y·cellSize, z·cellSize) in body-local space. */
|
|
7
8
|
readonly cellSize: number;
|
|
8
9
|
/** Row-major occupancy: occupancy[x + dimX * (y + dimY * z)]; non-zero = solid. */
|
|
9
|
-
readonly occupancy:
|
|
10
|
+
readonly occupancy: VoxelOccupancy3D;
|
|
10
11
|
}
|
|
11
12
|
export interface DeterministicVoxelRayHit3D {
|
|
12
13
|
readonly hit: boolean;
|
|
@@ -40,7 +41,8 @@ export declare function raycastDeterministicVoxelChunk3D(chunk: DeterministicVox
|
|
|
40
41
|
* of the occupancy grid.
|
|
41
42
|
*/
|
|
42
43
|
export declare function cookDeterministicVoxelChunkCollider3D(chunk: DeterministicVoxelChunk3D): DeterministicVoxelCompoundShape3D;
|
|
43
|
-
export interface
|
|
44
|
+
export interface VoxelBoxCarveRegion3D {
|
|
45
|
+
readonly type?: 'box';
|
|
44
46
|
readonly minX: number;
|
|
45
47
|
readonly minY: number;
|
|
46
48
|
readonly minZ: number;
|
|
@@ -49,9 +51,29 @@ export interface VoxelCarveRegion3D {
|
|
|
49
51
|
readonly maxZ: number;
|
|
50
52
|
readonly operation: 'carve' | 'fill';
|
|
51
53
|
}
|
|
54
|
+
export interface VoxelSphereCarveRegion3D {
|
|
55
|
+
readonly type: 'sphere';
|
|
56
|
+
readonly centerX: number;
|
|
57
|
+
readonly centerY: number;
|
|
58
|
+
readonly centerZ: number;
|
|
59
|
+
readonly radius: number;
|
|
60
|
+
readonly operation: 'carve' | 'fill';
|
|
61
|
+
}
|
|
62
|
+
export interface VoxelCapsuleCarveRegion3D {
|
|
63
|
+
readonly type: 'capsule';
|
|
64
|
+
readonly x0: number;
|
|
65
|
+
readonly y0: number;
|
|
66
|
+
readonly z0: number;
|
|
67
|
+
readonly x1: number;
|
|
68
|
+
readonly y1: number;
|
|
69
|
+
readonly z1: number;
|
|
70
|
+
readonly radius: number;
|
|
71
|
+
readonly operation: 'carve' | 'fill';
|
|
72
|
+
}
|
|
73
|
+
export type VoxelCarveRegion3D = VoxelBoxCarveRegion3D | VoxelSphereCarveRegion3D | VoxelCapsuleCarveRegion3D;
|
|
52
74
|
/**
|
|
53
|
-
* Carves or fills a 3D
|
|
54
|
-
* Computes
|
|
75
|
+
* Carves or fills a 3D region (box, sphere, or capsule) in a voxel chunk occupancy grid.
|
|
76
|
+
* Computes bounding box intersection with chunk dimensions, returning chunk unchanged
|
|
55
77
|
* if disjoint or no-op.
|
|
56
78
|
*/
|
|
57
79
|
export declare function carveDeterministicVoxelChunk3D(chunk: DeterministicVoxelChunk3D, region: VoxelCarveRegion3D): DeterministicVoxelChunk3D;
|
|
@@ -69,3 +91,28 @@ export declare function cookDeterministicVoxelSubregion3D(chunk: DeterministicVo
|
|
|
69
91
|
readonly maxY: number;
|
|
70
92
|
readonly maxZ: number;
|
|
71
93
|
}): DeterministicVoxelCompoundShape3D | undefined;
|
|
94
|
+
/**
|
|
95
|
+
* Alias for {@link cookDeterministicVoxelSubregion3D}.
|
|
96
|
+
* Re-cooks dirty subregions of a voxel chunk collider after carving or modifying voxels.
|
|
97
|
+
*/
|
|
98
|
+
export declare const recookDeterministicVoxelSubregion3D: typeof cookDeterministicVoxelSubregion3D;
|
|
99
|
+
export type VoxelAnchorFace = '+x' | '-x' | '+y' | '-y' | '+z' | '-z';
|
|
100
|
+
export interface VoxelSubChunk3D {
|
|
101
|
+
readonly chunk: DeterministicVoxelChunk3D;
|
|
102
|
+
readonly offsetCells: {
|
|
103
|
+
readonly x: number;
|
|
104
|
+
readonly y: number;
|
|
105
|
+
readonly z: number;
|
|
106
|
+
};
|
|
107
|
+
readonly occupiedCount: number;
|
|
108
|
+
readonly anchored: boolean;
|
|
109
|
+
}
|
|
110
|
+
export interface SplitDeterministicVoxelChunkOptions3D {
|
|
111
|
+
readonly anchorFaces?: readonly VoxelAnchorFace[];
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Partitions the non-zero voxels of a chunk into 6-connected components.
|
|
115
|
+
* Each component is tightly cropped into a sub-chunk with its origin offset in parent cells,
|
|
116
|
+
* occupied count, and whether any of its voxels touch the specified anchor faces.
|
|
117
|
+
*/
|
|
118
|
+
export declare function splitDeterministicVoxelChunk3D(chunk: DeterministicVoxelChunk3D, options?: SplitDeterministicVoxelChunkOptions3D): readonly VoxelSubChunk3D[];
|
package/dist/physics3d-voxel.js
CHANGED
|
@@ -82,7 +82,7 @@ export function raycastDeterministicVoxelChunk3D(chunk, query) {
|
|
|
82
82
|
let hitDistanceGrid = tMin;
|
|
83
83
|
while (currentX >= 0 && currentX < dimX && currentY >= 0 && currentY < dimY && currentZ >= 0 && currentZ < dimZ) {
|
|
84
84
|
const cellIndex = currentX + dimX * (currentY + dimY * currentZ);
|
|
85
|
-
if (occupancy[cellIndex]
|
|
85
|
+
if (occupancy[cellIndex] !== 0) {
|
|
86
86
|
const worldDistance = hitDistanceGrid * cellSize;
|
|
87
87
|
if (worldDistance > maxDistance) {
|
|
88
88
|
return undefined;
|
|
@@ -155,10 +155,12 @@ export function cookDeterministicVoxelChunkCollider3D(chunk) {
|
|
|
155
155
|
if (chunk.occupancy.length !== dimX * dimY * dimZ) {
|
|
156
156
|
throw new Error(`cookDeterministicVoxelChunkCollider3D: occupancy length ${chunk.occupancy.length} must equal dimX*dimY*dimZ (${dimX * dimY * dimZ})`);
|
|
157
157
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
158
|
+
if (Array.isArray(chunk.occupancy)) {
|
|
159
|
+
for (let index = 0; index < chunk.occupancy.length; index += 1) {
|
|
160
|
+
const cell = chunk.occupancy[index];
|
|
161
|
+
if (cell !== 0 && cell !== 1) {
|
|
162
|
+
throw new Error(`cookDeterministicVoxelChunkCollider3D: occupancy[${index}] must be 0 or 1, received ${cell}`);
|
|
163
|
+
}
|
|
162
164
|
}
|
|
163
165
|
}
|
|
164
166
|
const solid = (x, y, z) => chunk.occupancy[x + dimX * (y + dimY * z)] !== 0;
|
|
@@ -228,27 +230,100 @@ export function cookDeterministicVoxelChunkCollider3D(chunk) {
|
|
|
228
230
|
return { type: 'compound', children };
|
|
229
231
|
}
|
|
230
232
|
/**
|
|
231
|
-
* Carves or fills a 3D
|
|
232
|
-
* Computes
|
|
233
|
+
* Carves or fills a 3D region (box, sphere, or capsule) in a voxel chunk occupancy grid.
|
|
234
|
+
* Computes bounding box intersection with chunk dimensions, returning chunk unchanged
|
|
233
235
|
* if disjoint or no-op.
|
|
234
236
|
*/
|
|
235
237
|
export function carveDeterministicVoxelChunk3D(chunk, region) {
|
|
236
|
-
const { dimX, dimY, dimZ, cellSize
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
238
|
+
const { dimX, dimY, dimZ, cellSize } = chunk;
|
|
239
|
+
let startX = 0;
|
|
240
|
+
let endX = dimX - 1;
|
|
241
|
+
let startY = 0;
|
|
242
|
+
let endY = dimY - 1;
|
|
243
|
+
let startZ = 0;
|
|
244
|
+
let endZ = dimZ - 1;
|
|
245
|
+
let isInside;
|
|
246
|
+
if (region.type === 'sphere') {
|
|
247
|
+
const { centerX, centerY, centerZ, radius } = region;
|
|
248
|
+
if (radius <= 0) {
|
|
249
|
+
return chunk;
|
|
250
|
+
}
|
|
251
|
+
const rSq = radius * radius;
|
|
252
|
+
startX = Math.max(0, Math.floor(centerX - radius));
|
|
253
|
+
endX = Math.min(dimX - 1, Math.ceil(centerX + radius));
|
|
254
|
+
startY = Math.max(0, Math.floor(centerY - radius));
|
|
255
|
+
endY = Math.min(dimY - 1, Math.ceil(centerY + radius));
|
|
256
|
+
startZ = Math.max(0, Math.floor(centerZ - radius));
|
|
257
|
+
endZ = Math.min(dimZ - 1, Math.ceil(centerZ + radius));
|
|
258
|
+
isInside = (x, y, z) => {
|
|
259
|
+
const dx = x - centerX;
|
|
260
|
+
const dy = y - centerY;
|
|
261
|
+
const dz = z - centerZ;
|
|
262
|
+
return dx * dx + dy * dy + dz * dz <= rSq;
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
else if (region.type === 'capsule') {
|
|
266
|
+
const { x0, y0, z0, x1, y1, z1, radius } = region;
|
|
267
|
+
if (radius <= 0) {
|
|
268
|
+
return chunk;
|
|
269
|
+
}
|
|
270
|
+
const rSq = radius * radius;
|
|
271
|
+
startX = Math.max(0, Math.floor(Math.min(x0, x1) - radius));
|
|
272
|
+
endX = Math.min(dimX - 1, Math.ceil(Math.max(x0, x1) + radius));
|
|
273
|
+
startY = Math.max(0, Math.floor(Math.min(y0, y1) - radius));
|
|
274
|
+
endY = Math.min(dimY - 1, Math.ceil(Math.max(y0, y1) + radius));
|
|
275
|
+
startZ = Math.max(0, Math.floor(Math.min(z0, z1) - radius));
|
|
276
|
+
endZ = Math.min(dimZ - 1, Math.ceil(Math.max(z0, z1) + radius));
|
|
277
|
+
const segX = x1 - x0;
|
|
278
|
+
const segY = y1 - y0;
|
|
279
|
+
const segZ = z1 - z0;
|
|
280
|
+
const segLenSq = segX * segX + segY * segY + segZ * segZ;
|
|
281
|
+
if (segLenSq < 1e-9) {
|
|
282
|
+
isInside = (x, y, z) => {
|
|
283
|
+
const dx = x - x0;
|
|
284
|
+
const dy = y - y0;
|
|
285
|
+
const dz = z - z0;
|
|
286
|
+
return dx * dx + dy * dy + dz * dz <= rSq;
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
isInside = (x, y, z) => {
|
|
291
|
+
const px = x - x0;
|
|
292
|
+
const py = y - y0;
|
|
293
|
+
const pz = z - z0;
|
|
294
|
+
const dot = px * segX + py * segY + pz * segZ;
|
|
295
|
+
const t = Math.max(0, Math.min(1, dot / segLenSq));
|
|
296
|
+
const projX = x0 + t * segX;
|
|
297
|
+
const projY = y0 + t * segY;
|
|
298
|
+
const projZ = z0 + t * segZ;
|
|
299
|
+
const dx = x - projX;
|
|
300
|
+
const dy = y - projY;
|
|
301
|
+
const dz = z - projZ;
|
|
302
|
+
return dx * dx + dy * dy + dz * dz <= rSq;
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
else {
|
|
307
|
+
startX = Math.max(0, Math.min(region.minX, region.maxX));
|
|
308
|
+
endX = Math.min(dimX - 1, Math.max(region.minX, region.maxX));
|
|
309
|
+
startY = Math.max(0, Math.min(region.minY, region.maxY));
|
|
310
|
+
endY = Math.min(dimY - 1, Math.max(region.minY, region.maxY));
|
|
311
|
+
startZ = Math.max(0, Math.min(region.minZ, region.maxZ));
|
|
312
|
+
endZ = Math.min(dimZ - 1, Math.max(region.minZ, region.maxZ));
|
|
313
|
+
isInside = () => true;
|
|
314
|
+
}
|
|
243
315
|
if (startX > endX || startY > endY || startZ > endZ) {
|
|
244
316
|
return chunk;
|
|
245
317
|
}
|
|
246
318
|
const targetVal = region.operation === 'carve' ? 0 : 1;
|
|
247
319
|
let changed = false;
|
|
248
|
-
const nextOccupancy = [...occupancy];
|
|
320
|
+
const nextOccupancy = chunk.occupancy instanceof Uint8Array ? new Uint8Array(chunk.occupancy) : [...chunk.occupancy];
|
|
249
321
|
for (let z = startZ; z <= endZ; z += 1) {
|
|
250
322
|
for (let y = startY; y <= endY; y += 1) {
|
|
251
323
|
for (let x = startX; x <= endX; x += 1) {
|
|
324
|
+
if (!isInside(x, y, z)) {
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
252
327
|
const index = x + dimX * (y + dimY * z);
|
|
253
328
|
if (nextOccupancy[index] !== targetVal) {
|
|
254
329
|
nextOccupancy[index] = targetVal;
|
|
@@ -426,3 +501,195 @@ export function cookDeterministicVoxelSubregion3D(chunk, existingShape, dirtyReg
|
|
|
426
501
|
children: finalChildren,
|
|
427
502
|
};
|
|
428
503
|
}
|
|
504
|
+
/**
|
|
505
|
+
* Alias for {@link cookDeterministicVoxelSubregion3D}.
|
|
506
|
+
* Re-cooks dirty subregions of a voxel chunk collider after carving or modifying voxels.
|
|
507
|
+
*/
|
|
508
|
+
export const recookDeterministicVoxelSubregion3D = cookDeterministicVoxelSubregion3D;
|
|
509
|
+
/**
|
|
510
|
+
* Partitions the non-zero voxels of a chunk into 6-connected components.
|
|
511
|
+
* Each component is tightly cropped into a sub-chunk with its origin offset in parent cells,
|
|
512
|
+
* occupied count, and whether any of its voxels touch the specified anchor faces.
|
|
513
|
+
*/
|
|
514
|
+
export function splitDeterministicVoxelChunk3D(chunk, options) {
|
|
515
|
+
const { dimX, dimY, dimZ, cellSize, occupancy } = chunk;
|
|
516
|
+
const totalCells = dimX * dimY * dimZ;
|
|
517
|
+
if (totalCells === 0) {
|
|
518
|
+
return [];
|
|
519
|
+
}
|
|
520
|
+
const anchorFaces = new Set(options?.anchorFaces ?? []);
|
|
521
|
+
const checkAnchored = (x, y, z) => {
|
|
522
|
+
if (anchorFaces.has('-x') && x === 0)
|
|
523
|
+
return true;
|
|
524
|
+
if (anchorFaces.has('+x') && x === dimX - 1)
|
|
525
|
+
return true;
|
|
526
|
+
if (anchorFaces.has('-y') && y === 0)
|
|
527
|
+
return true;
|
|
528
|
+
if (anchorFaces.has('+y') && y === dimY - 1)
|
|
529
|
+
return true;
|
|
530
|
+
if (anchorFaces.has('-z') && z === 0)
|
|
531
|
+
return true;
|
|
532
|
+
if (anchorFaces.has('+z') && z === dimZ - 1)
|
|
533
|
+
return true;
|
|
534
|
+
return false;
|
|
535
|
+
};
|
|
536
|
+
const visited = new Uint8Array(totalCells);
|
|
537
|
+
const queueIdx = new Int32Array(totalCells);
|
|
538
|
+
const subChunks = [];
|
|
539
|
+
const sliceSize = dimX * dimY;
|
|
540
|
+
for (let z = 0; z < dimZ; z += 1) {
|
|
541
|
+
for (let y = 0; y < dimY; y += 1) {
|
|
542
|
+
for (let x = 0; x < dimX; x += 1) {
|
|
543
|
+
const seedIdx = x + dimX * y + sliceSize * z;
|
|
544
|
+
if (visited[seedIdx] !== 0 || occupancy[seedIdx] === 0) {
|
|
545
|
+
continue;
|
|
546
|
+
}
|
|
547
|
+
let head = 0;
|
|
548
|
+
let tail = 0;
|
|
549
|
+
queueIdx[tail++] = seedIdx;
|
|
550
|
+
visited[seedIdx] = 1;
|
|
551
|
+
let minX = x;
|
|
552
|
+
let maxX = x;
|
|
553
|
+
let minY = y;
|
|
554
|
+
let maxY = y;
|
|
555
|
+
let minZ = z;
|
|
556
|
+
let maxZ = z;
|
|
557
|
+
let isAnchored = checkAnchored(x, y, z);
|
|
558
|
+
while (head < tail) {
|
|
559
|
+
const currIdx = queueIdx[head++];
|
|
560
|
+
const cz = Math.floor(currIdx / sliceSize);
|
|
561
|
+
const rem = currIdx % sliceSize;
|
|
562
|
+
const cy = Math.floor(rem / dimX);
|
|
563
|
+
const cx = rem % dimX;
|
|
564
|
+
if (cx < minX)
|
|
565
|
+
minX = cx;
|
|
566
|
+
if (cx > maxX)
|
|
567
|
+
maxX = cx;
|
|
568
|
+
if (cy < minY)
|
|
569
|
+
minY = cy;
|
|
570
|
+
if (cy > maxY)
|
|
571
|
+
maxY = cy;
|
|
572
|
+
if (cz < minZ)
|
|
573
|
+
minZ = cz;
|
|
574
|
+
if (cz > maxZ)
|
|
575
|
+
maxZ = cz;
|
|
576
|
+
if (!isAnchored && checkAnchored(cx, cy, cz)) {
|
|
577
|
+
isAnchored = true;
|
|
578
|
+
}
|
|
579
|
+
if (cx > 0) {
|
|
580
|
+
const nIdx = currIdx - 1;
|
|
581
|
+
if (visited[nIdx] === 0 && occupancy[nIdx] !== 0) {
|
|
582
|
+
visited[nIdx] = 1;
|
|
583
|
+
queueIdx[tail++] = nIdx;
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
if (cx + 1 < dimX) {
|
|
587
|
+
const nIdx = currIdx + 1;
|
|
588
|
+
if (visited[nIdx] === 0 && occupancy[nIdx] !== 0) {
|
|
589
|
+
visited[nIdx] = 1;
|
|
590
|
+
queueIdx[tail++] = nIdx;
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
if (cy > 0) {
|
|
594
|
+
const nIdx = currIdx - dimX;
|
|
595
|
+
if (visited[nIdx] === 0 && occupancy[nIdx] !== 0) {
|
|
596
|
+
visited[nIdx] = 1;
|
|
597
|
+
queueIdx[tail++] = nIdx;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
if (cy + 1 < dimY) {
|
|
601
|
+
const nIdx = currIdx + dimX;
|
|
602
|
+
if (visited[nIdx] === 0 && occupancy[nIdx] !== 0) {
|
|
603
|
+
visited[nIdx] = 1;
|
|
604
|
+
queueIdx[tail++] = nIdx;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
if (cz > 0) {
|
|
608
|
+
const nIdx = currIdx - sliceSize;
|
|
609
|
+
if (visited[nIdx] === 0 && occupancy[nIdx] !== 0) {
|
|
610
|
+
visited[nIdx] = 1;
|
|
611
|
+
queueIdx[tail++] = nIdx;
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
if (cz + 1 < dimZ) {
|
|
615
|
+
const nIdx = currIdx + sliceSize;
|
|
616
|
+
if (visited[nIdx] === 0 && occupancy[nIdx] !== 0) {
|
|
617
|
+
visited[nIdx] = 1;
|
|
618
|
+
queueIdx[tail++] = nIdx;
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
const componentCount = tail;
|
|
623
|
+
const subDimX = maxX - minX + 1;
|
|
624
|
+
const subDimY = maxY - minY + 1;
|
|
625
|
+
const subDimZ = maxZ - minZ + 1;
|
|
626
|
+
const subTotal = subDimX * subDimY * subDimZ;
|
|
627
|
+
const subSlice = subDimX * subDimY;
|
|
628
|
+
let subOccupancy;
|
|
629
|
+
if (occupancy instanceof Uint8Array) {
|
|
630
|
+
const typed = new Uint8Array(subTotal);
|
|
631
|
+
for (let i = 0; i < tail; i += 1) {
|
|
632
|
+
const vIdx = queueIdx[i];
|
|
633
|
+
const vz = Math.floor(vIdx / sliceSize);
|
|
634
|
+
const vrem = vIdx % sliceSize;
|
|
635
|
+
const vy = Math.floor(vrem / dimX);
|
|
636
|
+
const vx = vrem % dimX;
|
|
637
|
+
const targetSubIdx = (vx - minX) + subDimX * (vy - minY) + subSlice * (vz - minZ);
|
|
638
|
+
typed[targetSubIdx] = occupancy[vIdx];
|
|
639
|
+
}
|
|
640
|
+
subOccupancy = typed;
|
|
641
|
+
}
|
|
642
|
+
else {
|
|
643
|
+
const arr = new Array(subTotal).fill(0);
|
|
644
|
+
for (let i = 0; i < tail; i += 1) {
|
|
645
|
+
const vIdx = queueIdx[i];
|
|
646
|
+
const vz = Math.floor(vIdx / sliceSize);
|
|
647
|
+
const vrem = vIdx % sliceSize;
|
|
648
|
+
const vy = Math.floor(vrem / dimX);
|
|
649
|
+
const vx = vrem % dimX;
|
|
650
|
+
const targetSubIdx = (vx - minX) + subDimX * (vy - minY) + subSlice * (vz - minZ);
|
|
651
|
+
arr[targetSubIdx] = occupancy[vIdx] !== 0 ? 1 : 0;
|
|
652
|
+
}
|
|
653
|
+
subOccupancy = arr;
|
|
654
|
+
}
|
|
655
|
+
subChunks.push({
|
|
656
|
+
chunk: {
|
|
657
|
+
dimX: subDimX,
|
|
658
|
+
dimY: subDimY,
|
|
659
|
+
dimZ: subDimZ,
|
|
660
|
+
cellSize,
|
|
661
|
+
occupancy: subOccupancy,
|
|
662
|
+
},
|
|
663
|
+
offsetCells: { x: minX, y: minY, z: minZ },
|
|
664
|
+
occupiedCount: componentCount,
|
|
665
|
+
anchored: isAnchored,
|
|
666
|
+
});
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
subChunks.sort((a, b) => {
|
|
671
|
+
if (a.anchored !== b.anchored) {
|
|
672
|
+
return a.anchored ? -1 : 1;
|
|
673
|
+
}
|
|
674
|
+
if (a.offsetCells.z !== b.offsetCells.z) {
|
|
675
|
+
return a.offsetCells.z - b.offsetCells.z;
|
|
676
|
+
}
|
|
677
|
+
if (a.offsetCells.y !== b.offsetCells.y) {
|
|
678
|
+
return a.offsetCells.y - b.offsetCells.y;
|
|
679
|
+
}
|
|
680
|
+
if (a.offsetCells.x !== b.offsetCells.x) {
|
|
681
|
+
return a.offsetCells.x - b.offsetCells.x;
|
|
682
|
+
}
|
|
683
|
+
if (a.chunk.dimZ !== b.chunk.dimZ) {
|
|
684
|
+
return a.chunk.dimZ - b.chunk.dimZ;
|
|
685
|
+
}
|
|
686
|
+
if (a.chunk.dimY !== b.chunk.dimY) {
|
|
687
|
+
return a.chunk.dimY - b.chunk.dimY;
|
|
688
|
+
}
|
|
689
|
+
if (a.chunk.dimX !== b.chunk.dimX) {
|
|
690
|
+
return a.chunk.dimX - b.chunk.dimX;
|
|
691
|
+
}
|
|
692
|
+
return a.occupiedCount - b.occupiedCount;
|
|
693
|
+
});
|
|
694
|
+
return subChunks;
|
|
695
|
+
}
|
package/dist/physics3d.d.ts
CHANGED
|
@@ -108,18 +108,28 @@ export interface DeterministicPhysicsBody3D {
|
|
|
108
108
|
readonly x: number;
|
|
109
109
|
readonly y: number;
|
|
110
110
|
readonly z: number;
|
|
111
|
+
/**
|
|
112
|
+
* Linear velocity along the X axis in units per tick (NOT per second).
|
|
113
|
+
* The solver integrates per tick (`dtTicks`), so positions advance as `x += vx * dtTicks`.
|
|
114
|
+
*/
|
|
111
115
|
readonly vx: number;
|
|
116
|
+
/** Linear velocity along the Y axis in units per tick (NOT per second). */
|
|
112
117
|
readonly vy: number;
|
|
118
|
+
/** Linear velocity along the Z axis in units per tick (NOT per second). */
|
|
113
119
|
readonly vz: number;
|
|
114
120
|
readonly rx?: number;
|
|
115
121
|
readonly ry?: number;
|
|
116
122
|
readonly rz?: number;
|
|
123
|
+
/** Angular velocity around the X axis in radians per tick (NOT per second). */
|
|
117
124
|
readonly avx?: number;
|
|
125
|
+
/** Angular velocity around the Y axis in radians per tick (NOT per second). */
|
|
118
126
|
readonly avy?: number;
|
|
127
|
+
/** Angular velocity around the Z axis in radians per tick (NOT per second). */
|
|
119
128
|
readonly avz?: number;
|
|
120
129
|
readonly inertia?: number;
|
|
121
130
|
/** Full 6-DOF orientation (opt-in); bodies without it are rotation-locked through the rigid solver. */
|
|
122
131
|
readonly orientation?: DeterministicPhysicsQuaternion3D;
|
|
132
|
+
/** Angular velocity vector in radians per tick (NOT per second). */
|
|
123
133
|
readonly angularVel?: DeterministicPhysicsVec3;
|
|
124
134
|
readonly mass?: number;
|
|
125
135
|
readonly linearDamping?: number;
|
|
@@ -272,6 +282,9 @@ export interface DeterministicPhysicsContactEvent3D {
|
|
|
272
282
|
readonly sensor: boolean;
|
|
273
283
|
/** Accumulated normal impulse (quantized) from the rigid solver; 0 for triggers/exits. */
|
|
274
284
|
readonly normalImpulse?: number;
|
|
285
|
+
readonly point?: Point3D;
|
|
286
|
+
readonly normal?: Point3D;
|
|
287
|
+
readonly closingSpeed?: number;
|
|
275
288
|
}
|
|
276
289
|
export interface DeterministicPhysicsContactDetail3D {
|
|
277
290
|
readonly pair: string;
|
|
@@ -384,6 +397,19 @@ export interface DeterministicPhysicsImpulseApplication3D {
|
|
|
384
397
|
* fast path for per-frame controller output (vehicles, KCC pushes).
|
|
385
398
|
*/
|
|
386
399
|
export declare function applyDeterministicImpulses3D(world: DeterministicPhysicsWorld3D, impulses: readonly DeterministicPhysicsImpulseApplication3D[]): DeterministicPhysicsWorld3D;
|
|
400
|
+
export interface DeterministicPhysicsForceApplication3D {
|
|
401
|
+
readonly bodyId: string;
|
|
402
|
+
readonly force?: Point3D;
|
|
403
|
+
readonly torque?: Point3D;
|
|
404
|
+
readonly worldPoint?: Point3D;
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Apply a batch of continuous deterministic forces and torques over a duration (defaulting to 1 dt tick),
|
|
408
|
+
* accumulating linear and angular delta-v and waking touched contact islands.
|
|
409
|
+
*/
|
|
410
|
+
export declare function applyDeterministicForces3D(world: DeterministicPhysicsWorld3D, forces: readonly DeterministicPhysicsForceApplication3D[], options?: {
|
|
411
|
+
readonly dtTicks?: number;
|
|
412
|
+
}): DeterministicPhysicsWorld3D;
|
|
387
413
|
export interface DeterministicPhysicsWorldEdit3D {
|
|
388
414
|
readonly add?: readonly DeterministicPhysicsBody3D[];
|
|
389
415
|
readonly remove?: readonly string[];
|
|
@@ -427,18 +453,35 @@ export declare function setDeterministicKinematicTransforms3D(world: Determinist
|
|
|
427
453
|
export declare function applyDeterministicImpulse3D(world: DeterministicPhysicsWorld3D, bodyId: string, impulse: Point3D, worldPoint?: Point3D): DeterministicPhysicsWorld3D;
|
|
428
454
|
/** Set a body's linear (and optional angular) velocity deterministically, waking its island. */
|
|
429
455
|
export declare function setDeterministicBodyVelocity3D(world: DeterministicPhysicsWorld3D, bodyId: string, velocity: Point3D, angularVelocity?: Point3D): DeterministicPhysicsWorld3D;
|
|
430
|
-
|
|
456
|
+
/**
|
|
457
|
+
* Options for advancing the deterministic 3D physics world snapshot-to-snapshot.
|
|
458
|
+
*/
|
|
459
|
+
export interface DeterministicPhysicsStepOptions3D {
|
|
460
|
+
/**
|
|
461
|
+
* Acceleration due to gravity along the Y axis, in units per tick squared (or dtTicks).
|
|
462
|
+
*
|
|
463
|
+
* NOTE ON TIME UNITS:
|
|
464
|
+
* `stepDeterministicPhysicsWorld3D` integrates per tick (with `dtTicks`, default 1 tick).
|
|
465
|
+
* Therefore, `gravityY` and rigid body velocities (`vx`, `vy`, `vz`, `angularVel`)
|
|
466
|
+
* are expressed per tick (units/tick, rad/tick), NOT per second.
|
|
467
|
+
* For example, at a 30 Hz tick rate with standard -9.8 m/s^2 gravity,
|
|
468
|
+
* `gravityY = -9.8 / (30 * 30)` ≈ `-0.0108889` units/tick^2.
|
|
469
|
+
*/
|
|
431
470
|
readonly gravityY?: number;
|
|
432
471
|
readonly scheduledQueries?: readonly DeterministicPhysicsScheduledQuery3D[];
|
|
433
472
|
readonly constraints?: readonly DeterministicPhysicsConstraint3D[];
|
|
434
473
|
readonly joints?: readonly DeterministicPhysicsJoint3D[];
|
|
474
|
+
/**
|
|
475
|
+
* Step duration measured in ticks (default: 1).
|
|
476
|
+
*/
|
|
435
477
|
readonly dtTicks?: number;
|
|
436
478
|
readonly velocityIterations?: number;
|
|
437
479
|
readonly substeps?: number;
|
|
438
480
|
readonly computeChecksum?: boolean;
|
|
439
481
|
readonly computeBroadphasePairs?: boolean;
|
|
440
482
|
readonly pairs?: readonly (readonly [number, number])[];
|
|
441
|
-
}
|
|
483
|
+
}
|
|
484
|
+
export declare function stepDeterministicPhysicsWorld3D(world: DeterministicPhysicsWorld3D, options?: DeterministicPhysicsStepOptions3D): DeterministicPhysicsStepResult3D;
|
|
442
485
|
/** O(1) body lookup backed by the per-world query-index cache. */
|
|
443
486
|
export declare function deterministicPhysicsBodyById3D(world: DeterministicPhysicsWorld3D, bodyId: string): DeterministicPhysicsBody3D | undefined;
|
|
444
487
|
export declare function __staticTreeBuildCount(): number;
|
package/dist/physics3d.js
CHANGED
|
@@ -257,6 +257,125 @@ export function applyDeterministicImpulses3D(world, impulses) {
|
|
|
257
257
|
});
|
|
258
258
|
return { ...world, bodies: normalizeBodies(bodies, 'trusted') };
|
|
259
259
|
}
|
|
260
|
+
/**
|
|
261
|
+
* Apply a batch of continuous deterministic forces and torques over a duration (defaulting to 1 dt tick),
|
|
262
|
+
* accumulating linear and angular delta-v and waking touched contact islands.
|
|
263
|
+
*/
|
|
264
|
+
export function applyDeterministicForces3D(world, forces, options) {
|
|
265
|
+
if (forces.length === 0) {
|
|
266
|
+
return world;
|
|
267
|
+
}
|
|
268
|
+
if (options?.dtTicks !== undefined && options.dtTicks <= 0) {
|
|
269
|
+
throw new Error(`applyDeterministicForces3D: dtTicks must be a positive finite number, received ${options.dtTicks}`);
|
|
270
|
+
}
|
|
271
|
+
const dt = options?.dtTicks ?? 1;
|
|
272
|
+
const bodyById = new Map(world.bodies.map((body) => [body.id, body]));
|
|
273
|
+
const linearDelta = new Map();
|
|
274
|
+
const angularDelta = new Map();
|
|
275
|
+
const invInertiaByBody = new Map();
|
|
276
|
+
for (const entry of forces) {
|
|
277
|
+
if (entry.force !== undefined) {
|
|
278
|
+
assertFinitePoint(entry.force, 'applyDeterministicForces3D: force');
|
|
279
|
+
}
|
|
280
|
+
if (entry.torque !== undefined) {
|
|
281
|
+
assertFinitePoint(entry.torque, 'applyDeterministicForces3D: torque');
|
|
282
|
+
}
|
|
283
|
+
if (entry.worldPoint !== undefined) {
|
|
284
|
+
assertFinitePoint(entry.worldPoint, 'applyDeterministicForces3D: worldPoint');
|
|
285
|
+
}
|
|
286
|
+
const target = bodyById.get(entry.bodyId);
|
|
287
|
+
if (target === undefined) {
|
|
288
|
+
throw new Error(`applyDeterministicForces3D: unknown body ${entry.bodyId}`);
|
|
289
|
+
}
|
|
290
|
+
if (entry.force !== undefined) {
|
|
291
|
+
const mass = target.mass ?? 1;
|
|
292
|
+
const baseInvMass = target.kind === 'dynamic' ? 1 / mass : 0;
|
|
293
|
+
const lockLinear = target.lockLinear ?? {};
|
|
294
|
+
const previousLinear = linearDelta.get(entry.bodyId) ?? { x: 0, y: 0, z: 0 };
|
|
295
|
+
linearDelta.set(entry.bodyId, {
|
|
296
|
+
x: previousLinear.x + entry.force.x * dt * (lockLinear.x === true ? 0 : baseInvMass),
|
|
297
|
+
y: previousLinear.y + entry.force.y * dt * (lockLinear.y === true ? 0 : baseInvMass),
|
|
298
|
+
z: previousLinear.z + entry.force.z * dt * (lockLinear.z === true ? 0 : baseInvMass),
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
let netTorque = undefined;
|
|
302
|
+
if (entry.torque !== undefined) {
|
|
303
|
+
netTorque = { x: entry.torque.x, y: entry.torque.y, z: entry.torque.z };
|
|
304
|
+
}
|
|
305
|
+
if (entry.force !== undefined && entry.worldPoint !== undefined && target.kind === 'dynamic') {
|
|
306
|
+
const center = worldCenterOfMassForBody(target);
|
|
307
|
+
const lever = { x: entry.worldPoint.x - center.x, y: entry.worldPoint.y - center.y, z: entry.worldPoint.z - center.z };
|
|
308
|
+
const torqueFromForce = cross(lever, entry.force);
|
|
309
|
+
netTorque = {
|
|
310
|
+
x: (netTorque?.x ?? 0) + torqueFromForce.x,
|
|
311
|
+
y: (netTorque?.y ?? 0) + torqueFromForce.y,
|
|
312
|
+
z: (netTorque?.z ?? 0) + torqueFromForce.z,
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
if (netTorque !== undefined && target.orientation !== undefined && target.kind === 'dynamic') {
|
|
316
|
+
let invInertia = invInertiaByBody.get(entry.bodyId);
|
|
317
|
+
if (invInertia === undefined) {
|
|
318
|
+
invInertia = worldInverseInertiaForBody(target);
|
|
319
|
+
invInertiaByBody.set(entry.bodyId, invInertia);
|
|
320
|
+
}
|
|
321
|
+
const angImpulse = { x: netTorque.x * dt, y: netTorque.y * dt, z: netTorque.z * dt };
|
|
322
|
+
const angularKick = mulMat3Vec(invInertia, angImpulse);
|
|
323
|
+
const previousAngular = angularDelta.get(entry.bodyId) ?? { x: 0, y: 0, z: 0 };
|
|
324
|
+
angularDelta.set(entry.bodyId, {
|
|
325
|
+
x: previousAngular.x + angularKick.x,
|
|
326
|
+
y: previousAngular.y + angularKick.y,
|
|
327
|
+
z: previousAngular.z + angularKick.z,
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
const touchedBodies = new Set();
|
|
332
|
+
for (const [bodyId, dv] of linearDelta.entries()) {
|
|
333
|
+
if (dv.x !== 0 || dv.y !== 0 || dv.z !== 0) {
|
|
334
|
+
touchedBodies.add(bodyId);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
for (const [bodyId, dw] of angularDelta.entries()) {
|
|
338
|
+
if (dw.x !== 0 || dw.y !== 0 || dw.z !== 0) {
|
|
339
|
+
touchedBodies.add(bodyId);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
const woken = new Set();
|
|
343
|
+
for (const bodyId of touchedBodies) {
|
|
344
|
+
for (const member of contactIslandFor(world, bodyId)) {
|
|
345
|
+
woken.add(member);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
const bodies = world.bodies.map((body) => {
|
|
349
|
+
const dv = linearDelta.get(body.id);
|
|
350
|
+
const dw = angularDelta.get(body.id);
|
|
351
|
+
const hasKick = (dv !== undefined && (dv.x !== 0 || dv.y !== 0 || dv.z !== 0))
|
|
352
|
+
|| (dw !== undefined && (dw.x !== 0 || dw.y !== 0 || dw.z !== 0));
|
|
353
|
+
const shouldWake = (hasKick || woken.has(body.id)) && body.kind === 'dynamic';
|
|
354
|
+
if (!hasKick && !shouldWake) {
|
|
355
|
+
return body;
|
|
356
|
+
}
|
|
357
|
+
const updated = {
|
|
358
|
+
...body,
|
|
359
|
+
vx: dv !== undefined ? quantizeDistance(body.vx + dv.x) : body.vx,
|
|
360
|
+
vy: dv !== undefined ? quantizeDistance(body.vy + dv.y) : body.vy,
|
|
361
|
+
vz: dv !== undefined ? quantizeDistance(body.vz + dv.z) : body.vz,
|
|
362
|
+
sleeping: shouldWake ? false : body.sleeping,
|
|
363
|
+
lowVelFrames: shouldWake ? 0 : body.lowVelFrames,
|
|
364
|
+
};
|
|
365
|
+
if (dw === undefined) {
|
|
366
|
+
return updated;
|
|
367
|
+
}
|
|
368
|
+
return {
|
|
369
|
+
...updated,
|
|
370
|
+
angularVel: {
|
|
371
|
+
x: quantizeDistance((body.angularVel?.x ?? 0) + dw.x),
|
|
372
|
+
y: quantizeDistance((body.angularVel?.y ?? 0) + dw.y),
|
|
373
|
+
z: quantizeDistance((body.angularVel?.z ?? 0) + dw.z),
|
|
374
|
+
},
|
|
375
|
+
};
|
|
376
|
+
});
|
|
377
|
+
return { ...world, bodies: normalizeBodies(bodies, 'trusted') };
|
|
378
|
+
}
|
|
260
379
|
/**
|
|
261
380
|
* Atomic deterministic topology edit: add/remove/replace bodies without
|
|
262
381
|
* recreating the world. Preserves `frame`, the object identity and sleep state
|
|
@@ -2255,14 +2374,56 @@ function runRigidSolver(world, dt, gravityY, velocityIterations, substeps, joint
|
|
|
2255
2374
|
.map((entry) => entry.jointId);
|
|
2256
2375
|
const impulseByPair = new Map();
|
|
2257
2376
|
const solidContacts = [];
|
|
2258
|
-
for (
|
|
2377
|
+
for (let i = 0; i < result.contactImpulses.length; i += 1) {
|
|
2378
|
+
const impulse = result.contactImpulses[i];
|
|
2379
|
+
const manifold = result.manifolds[i];
|
|
2259
2380
|
impulseByPair.set(impulse.pair, quantizeDistance(impulse.normalImpulse));
|
|
2381
|
+
let point = undefined;
|
|
2382
|
+
let normal = undefined;
|
|
2383
|
+
let closingSpeed = undefined;
|
|
2384
|
+
if (manifold !== undefined && manifold.points.length > 0) {
|
|
2385
|
+
let deepest = manifold.points[0];
|
|
2386
|
+
for (let p = 1; p < manifold.points.length; p += 1) {
|
|
2387
|
+
if (manifold.points[p].penetration > deepest.penetration) {
|
|
2388
|
+
deepest = manifold.points[p];
|
|
2389
|
+
}
|
|
2390
|
+
}
|
|
2391
|
+
const sbA = solverBodies[impulse.a];
|
|
2392
|
+
point = {
|
|
2393
|
+
x: quantizeDistance(sbA.p.x + deepest.rA.x),
|
|
2394
|
+
y: quantizeDistance(sbA.p.y + deepest.rA.y),
|
|
2395
|
+
z: quantizeDistance(sbA.p.z + deepest.rA.z),
|
|
2396
|
+
};
|
|
2397
|
+
normal = {
|
|
2398
|
+
x: quantizeDistance(manifold.normal.x),
|
|
2399
|
+
y: quantizeDistance(manifold.normal.y),
|
|
2400
|
+
z: quantizeDistance(manifold.normal.z),
|
|
2401
|
+
};
|
|
2402
|
+
const bodyA = source[impulse.a];
|
|
2403
|
+
const bodyB = source[impulse.b];
|
|
2404
|
+
const sbB = solverBodies[impulse.b];
|
|
2405
|
+
const applyGravityA = sbA.isDynamic && !sbA.sleeping && sbA.invMassVec.y !== 0;
|
|
2406
|
+
const applyGravityB = sbB.isDynamic && !sbB.sleeping && sbB.invMassVec.y !== 0;
|
|
2407
|
+
const wA = bodyA.angularVel ?? { x: 0, y: 0, z: 0 };
|
|
2408
|
+
const wB = bodyB.angularVel ?? { x: 0, y: 0, z: 0 };
|
|
2409
|
+
const vAx = (bodyA.vx ?? 0) + (wA.y * deepest.rA.z - wA.z * deepest.rA.y);
|
|
2410
|
+
const vAy = (bodyA.vy ?? 0) + (applyGravityA ? gravityY * dt * sbA.gravityScale : 0) + (wA.z * deepest.rA.x - wA.x * deepest.rA.z);
|
|
2411
|
+
const vAz = (bodyA.vz ?? 0) + (wA.x * deepest.rA.y - wA.y * deepest.rA.x);
|
|
2412
|
+
const vBx = (bodyB.vx ?? 0) + (wB.y * deepest.rB.z - wB.z * deepest.rB.y);
|
|
2413
|
+
const vBy = (bodyB.vy ?? 0) + (applyGravityB ? gravityY * dt * sbB.gravityScale : 0) + (wB.z * deepest.rB.x - wB.x * deepest.rB.z);
|
|
2414
|
+
const vBz = (bodyB.vz ?? 0) + (wB.x * deepest.rB.y - wB.y * deepest.rB.x);
|
|
2415
|
+
const relApproach = (vAx - vBx) * manifold.normal.x + (vAy - vBy) * manifold.normal.y + (vAz - vBz) * manifold.normal.z;
|
|
2416
|
+
closingSpeed = quantizeDistance(Math.max(0, relApproach));
|
|
2417
|
+
}
|
|
2260
2418
|
solidContacts.push({
|
|
2261
2419
|
pair: impulse.pair,
|
|
2262
2420
|
a: solverBodies[impulse.a].id,
|
|
2263
2421
|
b: solverBodies[impulse.b].id,
|
|
2264
2422
|
trigger: false,
|
|
2265
2423
|
sensor: false,
|
|
2424
|
+
...(point !== undefined ? { point } : {}),
|
|
2425
|
+
...(normal !== undefined ? { normal } : {}),
|
|
2426
|
+
...(closingSpeed !== undefined ? { closingSpeed } : {}),
|
|
2266
2427
|
});
|
|
2267
2428
|
}
|
|
2268
2429
|
return { bodies, contactCache, jointCache, impulseByPair, solidContacts, narrowphaseContacts: result.manifolds.length, brokenJointIds };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
export type DeterministicDslScalarFieldKind = 'int' | 'fixed' | 'bool' | 'button' | 'string' | 'asset-ref' | 'entity-ref' | 'player-ref' | `asset-ref:${string}` | `enum:${string}` | `flags:${string}` | `bitset:${string}`;
|
|
1
|
+
export type DeterministicDslScalarFieldKind = 'int' | 'fixed' | 'bool' | 'button' | 'string' | 'bytes' | 'asset-ref' | 'entity-ref' | 'player-ref' | `asset-ref:${string}` | `enum:${string}` | `flags:${string}` | `bitset:${string}`;
|
|
2
2
|
export type DeterministicDslFixedArrayFieldKind = `${DeterministicDslScalarFieldKind}[${number}]`;
|
|
3
3
|
export type DeterministicDslListFieldKind = `list<${DeterministicDslScalarFieldKind}>`;
|
|
4
4
|
export type DeterministicDslSetFieldKind = `set<${DeterministicDslScalarFieldKind}>`;
|
|
5
5
|
export type DeterministicDslDictionaryFieldKind = `dictionary<${DeterministicDslScalarFieldKind},${DeterministicDslScalarFieldKind}>`;
|
|
6
6
|
export type DeterministicDslFieldKind = DeterministicDslScalarFieldKind | `${DeterministicDslScalarFieldKind}[]` | DeterministicDslFixedArrayFieldKind | DeterministicDslListFieldKind | DeterministicDslSetFieldKind | DeterministicDslDictionaryFieldKind;
|
|
7
7
|
export type DeterministicDslDeclarationKind = 'component' | 'singleton' | 'global' | 'input' | 'command' | 'event' | 'signal' | 'struct' | 'enum' | 'flags' | 'union';
|
|
8
|
-
export type DeterministicDslScalarValue = boolean | number | string;
|
|
8
|
+
export type DeterministicDslScalarValue = boolean | number | string | Uint8Array;
|
|
9
9
|
export interface DeterministicDslDictionaryEntry {
|
|
10
10
|
readonly key: DeterministicDslScalarValue;
|
|
11
11
|
readonly value: DeterministicDslScalarValue;
|
|
@@ -352,12 +352,25 @@ function appendField(bytes, kind, value) {
|
|
|
352
352
|
if (Array.isArray(value)) {
|
|
353
353
|
throw new Error(`Unexpected array for ${kind} field`);
|
|
354
354
|
}
|
|
355
|
-
if (typeof value !== 'boolean' && typeof value !== 'number' && typeof value !== 'string') {
|
|
355
|
+
if (typeof value !== 'boolean' && typeof value !== 'number' && typeof value !== 'string' && !(value instanceof Uint8Array)) {
|
|
356
356
|
throw new Error(`Invalid ${kind} field value`);
|
|
357
357
|
}
|
|
358
358
|
appendScalarField(bytes, kind, value);
|
|
359
359
|
}
|
|
360
360
|
function appendScalarField(bytes, kind, value) {
|
|
361
|
+
if (kind === 'bytes') {
|
|
362
|
+
if (!(value instanceof Uint8Array)) {
|
|
363
|
+
throw new Error(`${kind} field requires Uint8Array value`);
|
|
364
|
+
}
|
|
365
|
+
if (value.byteLength > 65535) {
|
|
366
|
+
throw new Error('Bytes field too large');
|
|
367
|
+
}
|
|
368
|
+
appendUint16(bytes, value.byteLength);
|
|
369
|
+
for (let i = 0; i < value.byteLength; i += 1) {
|
|
370
|
+
bytes.push(value[i]);
|
|
371
|
+
}
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
361
374
|
if (kind === 'bool' || kind === 'button') {
|
|
362
375
|
if (typeof value !== 'boolean') {
|
|
363
376
|
throw new Error(`${kind} field requires boolean value`);
|
|
@@ -421,6 +434,16 @@ function readField(bytes, offset, kind) {
|
|
|
421
434
|
return readScalarField(bytes, offset, kind);
|
|
422
435
|
}
|
|
423
436
|
function readScalarField(bytes, offset, kind) {
|
|
437
|
+
if (kind === 'bytes') {
|
|
438
|
+
const length = readUint16(bytes, offset);
|
|
439
|
+
const start = offset + 2;
|
|
440
|
+
const end = start + length;
|
|
441
|
+
assertAvailable(bytes, start, length);
|
|
442
|
+
return {
|
|
443
|
+
value: bytes.slice(start, end),
|
|
444
|
+
offset: end,
|
|
445
|
+
};
|
|
446
|
+
}
|
|
424
447
|
if (kind === 'bool' || kind === 'button') {
|
|
425
448
|
assertAvailable(bytes, offset, 1);
|
|
426
449
|
if (bytes[offset] !== 0 && bytes[offset] !== 1) {
|
|
@@ -529,7 +552,7 @@ function normalizeDslFieldKind(rawKind) {
|
|
|
529
552
|
.replace(/\bbitset<([A-Za-z_][A-Za-z0-9_]*)>/g, 'bitset:$1');
|
|
530
553
|
}
|
|
531
554
|
function scalarKindPattern() {
|
|
532
|
-
return '(?:int|fixed|bool|button|string|asset-ref|entity-ref|player-ref|asset-ref:[A-Za-z_][A-Za-z0-9_]*|enum:[A-Za-z_][A-Za-z0-9_]*|flags:[A-Za-z_][A-Za-z0-9_]*|bitset:[A-Za-z_][A-Za-z0-9_]*)';
|
|
555
|
+
return '(?:int|fixed|bool|button|string|bytes|asset-ref|entity-ref|player-ref|asset-ref:[A-Za-z_][A-Za-z0-9_]*|enum:[A-Za-z_][A-Za-z0-9_]*|flags:[A-Za-z_][A-Za-z0-9_]*|bitset:[A-Za-z_][A-Za-z0-9_]*)';
|
|
533
556
|
}
|
|
534
557
|
function isTypedAssetRefKind(kind) {
|
|
535
558
|
return kind.startsWith('asset-ref:');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@series-inc/rundot-syncplay",
|
|
3
|
-
"version": "5.28.0-beta.
|
|
3
|
+
"version": "5.28.0-beta.2",
|
|
4
4
|
"description": "Kinetix orchestration, rollback, replay, late-join, and deterministic networking for RUN.game",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -168,7 +168,7 @@
|
|
|
168
168
|
"test:core": "node --expose-gc --import tsx --test --test-concurrency=1 tests/canonical.test.ts tests/canonical-portability.test.ts tests/runtime-session.test.ts tests/kinetix-runtime-session.test.ts tests/runtime-support.test.ts tests/runtime-guards.test.ts tests/r3f-render-adapter.test.ts tests/snapshot-cost.test.ts tests/sdkSession.test.ts tests/input-authority.test.ts tests/session-wire.test.ts tests/runtime-room-metadata.test.ts tests/session-snapshot.test.ts tests/authority-room.test.ts tests/networked-client-snapshot.test.ts tests/runner.test.ts tests/testing.test.ts tests/browser-session.test.ts tests/secret-config.test.ts tests/secret-protocol.test.ts tests/secret-authority.test.ts tests/secret-client.test.ts tests/late-join-checksum.test.ts tests/late-join-input-backfill.test.ts tests/replay-scoring.test.ts tests/bot-backfill.test.ts tests/latency-simulation.test.ts tests/production-input-budget.test.ts tests/time-sync.test.ts tests/match-log.test.ts tests/spectator.test.ts tests/synctest.test.ts tests/instant-replay.test.ts tests/session-promotion.test.ts tests/physics3d-broadphase-stats.test.ts tests/entrypoints.test.ts tests/export-surface.test.ts tests/module-seam.test.ts tests/module-contract-portability.test.ts tests/module-identity.test.ts tests/module-corpus.test.ts tests/component-model.test.ts tests/component-model-rollback.test.ts tests/component-model-integration.test.ts tests/actors-ai.test.ts tests/character-3d.test.ts tests/character-3d-certification.test.ts tests/combat-modules.test.ts tests/combat-modules-integration.test.ts tests/firearm.test.ts tests/gameplay-effects.test.ts tests/spatial-interaction.test.ts tests/stats-abilities.test.ts tests/inventory-equipment.test.ts tests/inventory-equipment-certification.test.ts tests/platformer-2d.test.ts tests/platformer-2d-certification.test.ts tests/module-promotion.test.ts tests/module-docs.test.ts tests/module-bundle-budget.test.ts tests/published-side-effects.test.ts tests/host-timing.test.ts tests/test-manifest.test.ts tests/coarse-region.test.ts tests/input-codec.test.ts tests/command-ingress.test.ts tests/session-reconfigure.test.ts tests/prediction-mode.test.ts tests/ephemeral-channel.test.ts tests/runner-surface.test.ts tests/runner-harness.test.ts tests/effects-adapter-bounds.test.ts tests/simulated-match-secrets.test.ts tests/run-glue-surface.test.mjs core/tests/core-boundary.test.mjs tests/math-core-parity.test.ts tests/math-profile.test.ts tests/movement3d-kcc-unit-contract.test.ts tests/movement3d-static-ground.test.ts",
|
|
169
169
|
"test:sdk-contract": "node --import tsx --test tests/sdk-runtime-contract.test.ts",
|
|
170
170
|
"test:soak": "tsx --test tests/runtime-soak.test.ts",
|
|
171
|
-
"test:extended": "tsx --test tests/kcc-vehicle-characterization.test.ts tests/animation.test.ts tests/asset-cooking.test.ts tests/backend-proof-checksum-vectors.test.ts tests/bot-documents.test.ts tests/bot-primitives.test.ts tests/collider-cooking.test.ts tests/collision.test.ts tests/command-timeline.test.ts tests/config-bundle.test.ts tests/cosmetic-physics3d.test.ts tests/deterministic-primitives.test.ts tests/ecs-lite.test.ts tests/effects-adapter.test.ts tests/engine-runtime.test.ts tests/errors.test.ts tests/events.test.ts tests/input-button.test.ts tests/load-128-players.test.ts tests/math.test.ts tests/movement.test.ts tests/movement3d.test.ts tests/multiclient-authority.test.ts tests/navigation.test.ts tests/noise.test.ts tests/physics-cert.test.ts tests/physics2d.test.ts tests/physics3d-ccd.test.ts tests/physics3d-coverage.test.ts tests/physics3d-debug-wireframe.test.ts tests/physics3d-destruction-cert.test.ts tests/physics3d-geometry-limits.test.ts tests/physics3d-heightfield.test.ts tests/physics3d-hull.test.ts tests/physics3d-joints.test.ts tests/physics3d-kinematic-mesh.test.ts tests/physics3d-kinematic-poses.test.ts tests/physics3d-kinematic-transforms.test.ts tests/physics3d-mass.test.ts tests/physics3d-materials.test.ts tests/physics3d-mesh-onesided.test.ts tests/physics3d-queries-capsule-childindex.test.ts tests/physics3d-query-index.test.ts tests/physics3d-recipes.test.ts tests/physics3d-rotation-convention.test.ts tests/physics3d-shape-builders.test.ts tests/physics3d-shared.test.ts tests/physics3d-sleeping-manifold-reuse.test.ts tests/physics3d-solver.test.ts tests/physics3d-static-memoization.test.ts tests/physics3d-static-overlap-memo.test.ts tests/physics3d-cylinder-hull.test.ts tests/physics3d-stacking.test.ts tests/physics3d-toi.test.ts tests/physics3d-vehicle.test.ts tests/physics3d-voxel-carving.test.ts tests/physics3d-voxel-dda.test.ts tests/physics3d-voxel.test.ts tests/physics3d-world-edit.test.ts tests/physics3d.test.ts tests/physics-vector-generator.test.ts tests/random.test.ts tests/rollback-history.test.ts tests/schema-artifacts.test.ts tests/schema-codegen.test.ts tests/schema-dsl-binary.test.ts tests/schema.test.ts tests/signals.test.ts tests/sparse-set.test.ts tests/static-checker.test.ts tests/system-lifecycle.test.ts tests/wire-canonical-sentinels.test.ts tests/ws-frame.test.ts",
|
|
171
|
+
"test:extended": "tsx --test tests/kcc-vehicle-characterization.test.ts tests/animation.test.ts tests/asset-cooking.test.ts tests/backend-proof-checksum-vectors.test.ts tests/bot-documents.test.ts tests/bot-primitives.test.ts tests/collider-cooking.test.ts tests/collision.test.ts tests/command-timeline.test.ts tests/config-bundle.test.ts tests/cosmetic-physics3d.test.ts tests/deterministic-primitives.test.ts tests/ecs-lite.test.ts tests/effects-adapter.test.ts tests/engine-runtime.test.ts tests/errors.test.ts tests/events.test.ts tests/input-button.test.ts tests/load-128-players.test.ts tests/math.test.ts tests/movement.test.ts tests/movement3d.test.ts tests/multiclient-authority.test.ts tests/navigation.test.ts tests/noise.test.ts tests/physics-cert.test.ts tests/physics2d.test.ts tests/physics3d-ccd.test.ts tests/physics3d-coverage.test.ts tests/physics3d-debug-wireframe.test.ts tests/physics3d-destruction-cert.test.ts tests/physics3d-forces-and-contacts.test.ts tests/physics3d-geometry-limits.test.ts tests/physics3d-heightfield.test.ts tests/physics3d-hull.test.ts tests/physics3d-joints.test.ts tests/physics3d-kinematic-mesh.test.ts tests/physics3d-kinematic-poses.test.ts tests/physics3d-kinematic-transforms.test.ts tests/physics3d-mass.test.ts tests/physics3d-materials.test.ts tests/physics3d-mesh-onesided.test.ts tests/physics3d-queries-capsule-childindex.test.ts tests/physics3d-query-index.test.ts tests/physics3d-recipes.test.ts tests/physics3d-rotation-convention.test.ts tests/physics3d-shape-builders.test.ts tests/physics3d-shared.test.ts tests/physics3d-sleeping-manifold-reuse.test.ts tests/physics3d-solver.test.ts tests/physics3d-static-memoization.test.ts tests/physics3d-static-overlap-memo.test.ts tests/physics3d-cylinder-hull.test.ts tests/physics3d-stacking.test.ts tests/physics3d-toi.test.ts tests/physics3d-vehicle.test.ts tests/physics3d-voxel-carving.test.ts tests/physics3d-voxel-dda.test.ts tests/physics3d-voxel-split.test.ts tests/physics3d-voxel.test.ts tests/physics3d-world-edit.test.ts tests/physics3d.test.ts tests/physics-vector-generator.test.ts tests/random.test.ts tests/rollback-history.test.ts tests/schema-artifacts.test.ts tests/schema-codegen.test.ts tests/schema-dsl-binary.test.ts tests/schema.test.ts tests/signals.test.ts tests/sparse-set.test.ts tests/static-checker.test.ts tests/system-lifecycle.test.ts tests/wire-canonical-sentinels.test.ts tests/ws-frame.test.ts",
|
|
172
172
|
"test:ci": "npm run build && npm run test",
|
|
173
173
|
"build:native": "node core/scripts/build-native.mjs",
|
|
174
174
|
"build:mobile-native": "node core/scripts/build-mobile-native.mjs",
|