@series-inc/rundot-syncplay 6.0.0-rc.48 → 6.0.0-rc.49
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/MIGRATING-RC47-TO-RC48.md +22 -0
- package/MIGRATING-RC48-TO-RC49.md +11 -0
- package/core/native/physics/checkpoint_schema.hpp +33 -5
- package/core/native/physics/contact_material_store.cpp +791 -0
- package/core/native/physics/contact_material_store.hpp +281 -0
- package/core/native/physics/extended_abi.cpp +48 -0
- package/core/native/physics/extended_abi.hpp +31 -0
- package/core/native/physics/physics.cpp +345 -51
- package/core/native/physics/physics.hpp +28 -1
- package/core/native/physics/surface_velocity.cpp +817 -13
- package/core/native/physics/surface_velocity.hpp +283 -67
- package/core/native/physics/surface_velocity_math.hpp +91 -0
- package/core/native/physics/topology.cpp +68 -0
- package/core/native/physics/topology.hpp +31 -1
- package/core/native/physics/world.cpp +1367 -91
- package/core/native/physics/world.hpp +125 -1
- package/core/native/physics/world_abi.cpp +458 -11
- package/core/native/physics/world_abi.hpp +65 -0
- package/core/native/physics/world_digest_visitor.hpp +54 -0
- package/core/native/physics/world_strong_digest.hpp +66 -1
- package/core/scripts/build-native.mjs +5 -0
- package/core/scripts/build-wasm-physics.mjs +6 -1
- package/core/scripts/extended-physics-profile.mjs +11 -0
- package/core/src/physics/abi-constants.mjs +1 -1
- package/core/src/physics/physics-profile-wasm-module.generated.mjs +10 -9
- package/core/src/physics/physics-wasm-module.generated.mjs +10 -9
- package/core/src/physics/surface-velocity.d.mts +47 -5
- package/core/src/physics/surface-velocity.mjs +916 -118
- package/core/src/physics/world.d.mts +124 -0
- package/core/src/physics/world.mjs +352 -19
- package/core/src/physics2d/physics2d-wasm-module.generated.mjs +1 -1
- package/core/world.d.ts +14 -1
- package/dist/physics/3d.d.ts +98 -4
- package/dist/physics/3d.js +816 -88
- package/dist/physics/contact-materials3d.d.ts +435 -0
- package/dist/physics/contact-materials3d.js +776 -0
- package/dist/physics/voxel-body-state.d.ts +2 -2
- package/package.json +4 -2
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Syncplay rc.48
|
|
2
|
+
|
|
3
|
+
This release contains verified performance optimizations for the lag-compensation history and the engine free lists. No public API, wire format, or checksum changes.
|
|
4
|
+
|
|
5
|
+
## Lag-Compensation History Record
|
|
6
|
+
|
|
7
|
+
- `createDeterministicLagCompensation3DHistory.recordTargets` merges the normalized batch into the retained window and trims the front, instead of rebuilding and re-sorting the whole window on every record.
|
|
8
|
+
- Measured 54.8x faster on a 128-target / 128-frame window. The win grows with the retained window size.
|
|
9
|
+
- Observable behavior is unchanged: window content, `checksum()`, `snapshot()`, `rewind()`, `validateShot()`, `restore()`, and every error message and throw point are identical.
|
|
10
|
+
|
|
11
|
+
## Engine Free-List Insert
|
|
12
|
+
|
|
13
|
+
- The four free lists (slot map, entity ids in both runtimes, frame-heap handles) insert a freed id by binary search instead of push-then-sort.
|
|
14
|
+
- Measured 7.7x faster at 16 free ids and 81.1x faster at 5000.
|
|
15
|
+
- Reuse order stays smallest-id-first, and snapshot free lists stay ascending.
|
|
16
|
+
- A forged ref with a non-numeric id keeps the exact pre-change push-then-sort path, because a NaN comparator has no specified placement.
|
|
17
|
+
|
|
18
|
+
## Verification
|
|
19
|
+
|
|
20
|
+
- A frozen checksum record (`tests/golden/js-hotpath-regression.json`) was captured from the pre-change implementation and reproduces byte for byte.
|
|
21
|
+
- Differential tests compare against frozen pre-change oracles on random operation sequences.
|
|
22
|
+
- Mutation checks inject 8 defects into the changed functions and require every test lane to reject them with failing assertions.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Syncplay rc.49
|
|
2
|
+
|
|
3
|
+
This release adds first-class contact materials and contact pair overrides to 3D physics:
|
|
4
|
+
|
|
5
|
+
## First-Class Contact Materials
|
|
6
|
+
- Define material dictionaries with explicit friction, restitution, and rolling resistance.
|
|
7
|
+
- Define pair contact rules with priority and combine overrides.
|
|
8
|
+
- Provide zero-allocation solver input view during contact solve steps.
|
|
9
|
+
- Support moving conveyor surfaces with frame-relative velocity inheritance and portal crossing support.
|
|
10
|
+
- Sensor and trigger contacts evaluate winning pair rules while keeping collision response disabled.
|
|
11
|
+
- Checkpoint wire format version advances to 17 to serialize custom materials and rules.
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
namespace rundot::kinetix::physics {
|
|
9
9
|
|
|
10
|
-
inline constexpr std::uint32_t kWorldStrongDigestAlgorithmRevision =
|
|
10
|
+
inline constexpr std::uint32_t kWorldStrongDigestAlgorithmRevision = 2;
|
|
11
11
|
inline constexpr char kStrongCheckpointDomain[] = "kinetix.world-checkpoint/1";
|
|
12
12
|
inline constexpr char kStrongRecordDomain[] = "kinetix.geometry-record/1";
|
|
13
13
|
inline constexpr char kStrongRootDomain[] = "kinetix.geometry-root/1";
|
|
@@ -43,7 +43,9 @@ static_assert(sizeof(kStrongTileDomain) - 1 == 19);
|
|
|
43
43
|
X(JointBreaks) \
|
|
44
44
|
X(FluidInteractions) \
|
|
45
45
|
X(DefinitionSignatures) \
|
|
46
|
-
X(Pose)
|
|
46
|
+
X(Pose) \
|
|
47
|
+
X(BodyMaterials) \
|
|
48
|
+
X(BodyMaterialFrames)
|
|
47
49
|
|
|
48
50
|
enum class CheckpointField : std::uint8_t {
|
|
49
51
|
#define RUNDOT_CHECKPOINT_FIELD_ENUM(name) name,
|
|
@@ -67,6 +69,8 @@ enum class StrongSection : std::uint32_t {
|
|
|
67
69
|
JointBreaks = 12,
|
|
68
70
|
FluidInteractions = 13,
|
|
69
71
|
DefinitionSignatures = 14,
|
|
72
|
+
BodyMaterials = 15,
|
|
73
|
+
BodyMaterialFrames = 16,
|
|
70
74
|
};
|
|
71
75
|
|
|
72
76
|
// FNV revision 2 order. Supports stays in the list. The visitor omits an empty channel.
|
|
@@ -91,6 +95,8 @@ inline constexpr CheckpointField kFnvFieldOrder[] = {
|
|
|
91
95
|
CheckpointField::JointWarm,
|
|
92
96
|
CheckpointField::DefinitionSignatures,
|
|
93
97
|
CheckpointField::Pose,
|
|
98
|
+
CheckpointField::BodyMaterials,
|
|
99
|
+
CheckpointField::BodyMaterialFrames,
|
|
94
100
|
};
|
|
95
101
|
|
|
96
102
|
// Strong order. Warm state is before the output records.
|
|
@@ -117,6 +123,8 @@ inline constexpr CheckpointField kStrongFieldOrder[] = {
|
|
|
117
123
|
CheckpointField::FluidInteractions,
|
|
118
124
|
CheckpointField::DefinitionSignatures,
|
|
119
125
|
CheckpointField::Pose,
|
|
126
|
+
CheckpointField::BodyMaterials,
|
|
127
|
+
CheckpointField::BodyMaterialFrames,
|
|
120
128
|
};
|
|
121
129
|
|
|
122
130
|
consteval bool checkpointOrderHas(const CheckpointField* order, std::size_t count, CheckpointField field) {
|
|
@@ -162,9 +170,19 @@ inline void checkpointRecordSchemaGuard(const WorldSupportForce& value) noexcept
|
|
|
162
170
|
[[maybe_unused]] const auto& [body, support, force, bodyLocalPoint,
|
|
163
171
|
supportLocalPoint, supportReceivesReaction] = value;
|
|
164
172
|
}
|
|
173
|
+
inline void checkpointRecordSchemaGuard(const WorldContactMaterialSnapshot& value) noexcept {
|
|
174
|
+
[[maybe_unused]] const auto& [kind, materialId, friction, restitution,
|
|
175
|
+
rollingResistance, frictionCombine, restitutionCombine, rollingResistanceCombine] = value;
|
|
176
|
+
}
|
|
177
|
+
inline void checkpointRecordSchemaGuard(const WorldContactMaterialResult& value) noexcept {
|
|
178
|
+
[[maybe_unused]] const auto& [materialA, materialB, friction, restitution,
|
|
179
|
+
rollingResistance, relativeSurfaceVelocity, matchedRuleIndex, ruleMatched,
|
|
180
|
+
ruleEnabled, responseEnabled, suppressionReason, resolvedRestitution,
|
|
181
|
+
effectiveRestitution, normalTarget, closingSpeed] = value;
|
|
182
|
+
}
|
|
165
183
|
inline void checkpointRecordSchemaGuard(const WorldContactEvent& value) noexcept {
|
|
166
184
|
[[maybe_unused]] const auto& [type, bodyA, bodyB, trigger, sensor, normalImpulse,
|
|
167
|
-
tangentImpulse1, tangentImpulse2, point, normal, penetration, closingSpeed] = value;
|
|
185
|
+
tangentImpulse1, tangentImpulse2, point, normal, penetration, closingSpeed, material] = value;
|
|
168
186
|
}
|
|
169
187
|
inline void checkpointRecordSchemaGuard(const WorldJointReaction& value) noexcept {
|
|
170
188
|
[[maybe_unused]] const auto& [joint, bodyA, bodyB, force, torque] = value;
|
|
@@ -181,7 +199,7 @@ inline void checkpointRecordSchemaGuard(const WorldTickSupports& value) noexcept
|
|
|
181
199
|
}
|
|
182
200
|
inline void checkpointRecordSchemaGuard(const WorldStatePayload& value) noexcept {
|
|
183
201
|
[[maybe_unused]] const auto& [joints, geometry, contactCache, forces, tickForces,
|
|
184
|
-
tickSupports, fluids, jointWarmState, topology, frame, surfaceVelocities,
|
|
202
|
+
tickSupports, fluids, jointWarmState, topology, bodyMaterials, bodyMaterialFrames, frame, surfaceVelocities,
|
|
185
203
|
contactEvents, jointReactions, jointBreakEvents, fluidInteractions, pose] = value;
|
|
186
204
|
}
|
|
187
205
|
inline void checkpointRecordSchemaGuard(const WorldOwnerToken& value) noexcept {
|
|
@@ -251,6 +269,10 @@ inline void checkpointDataSchemaGuard(const CheckpointData& data) noexcept {
|
|
|
251
269
|
fluidsCount,
|
|
252
270
|
surfaceVelocitiesOffset,
|
|
253
271
|
surfaceVelocitiesCount,
|
|
272
|
+
bodyMaterialsOffset,
|
|
273
|
+
bodyMaterialsCount,
|
|
274
|
+
bodyMaterialFramesOffset,
|
|
275
|
+
bodyMaterialFramesCount,
|
|
254
276
|
jointWarmStateOffset,
|
|
255
277
|
jointWarmStateCount,
|
|
256
278
|
contactEventsOffset,
|
|
@@ -304,6 +326,10 @@ inline void checkpointDataSchemaGuard(const CheckpointData& data) noexcept {
|
|
|
304
326
|
static_cast<void>(fluidsCount);
|
|
305
327
|
static_cast<void>(surfaceVelocitiesOffset);
|
|
306
328
|
static_cast<void>(surfaceVelocitiesCount);
|
|
329
|
+
static_cast<void>(bodyMaterialsOffset);
|
|
330
|
+
static_cast<void>(bodyMaterialsCount);
|
|
331
|
+
static_cast<void>(bodyMaterialFramesOffset);
|
|
332
|
+
static_cast<void>(bodyMaterialFramesCount);
|
|
307
333
|
static_cast<void>(jointWarmStateOffset);
|
|
308
334
|
static_cast<void>(jointWarmStateCount);
|
|
309
335
|
static_cast<void>(contactEventsOffset);
|
|
@@ -365,7 +391,9 @@ static_assert(offsetof(WorldLimits, maxGeometryValues) == 16);
|
|
|
365
391
|
static_assert(offsetof(WorldLimits, maxSupportRecords) == 40);
|
|
366
392
|
static_assert(sizeof(WorldSupportSpring) == 120);
|
|
367
393
|
static_assert(sizeof(WorldSupportForce) == 96);
|
|
368
|
-
static_assert(sizeof(
|
|
394
|
+
static_assert(sizeof(WorldContactMaterialSnapshot) == 48);
|
|
395
|
+
static_assert(sizeof(WorldContactMaterialResult) == 184);
|
|
396
|
+
static_assert(sizeof(WorldContactEvent) == 304);
|
|
369
397
|
static_assert(sizeof(WorldJointReaction) == 72);
|
|
370
398
|
static_assert(sizeof(WorldJointBreakEvent) == 16);
|
|
371
399
|
static_assert(sizeof(WorldFluidInteraction) == 128);
|