@series-inc/rundot-syncplay 5.26.0-beta.9 → 5.27.0
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/core/native/physics/physics.cpp +129 -3
- package/core/native/physics/physics.hpp +1 -1
- package/core/physics.d.ts +1 -0
- package/core/scripts/build-wasm-physics.mjs +1 -1
- package/core/src/physics/index.mjs +20 -9
- package/core/src/physics/physics-wasm-module.generated.mjs +4 -4
- package/dist/authority-room.d.ts +10 -0
- package/dist/authority-room.js +11 -0
- package/dist/browser.d.ts +5 -5
- package/dist/browser.js +3 -3
- package/dist/creator.d.ts +4 -4
- package/dist/creator.js +2 -2
- package/dist/dev-authority-room.js +8 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +3 -3
- package/dist/input-authority.d.ts +8 -0
- package/dist/input-authority.js +13 -0
- package/dist/networked-client.d.ts +8 -0
- package/dist/networked-client.js +8 -0
- package/dist/node.d.ts +2 -0
- package/dist/node.js +1 -0
- package/dist/physics3d-voxel.d.ts +23 -1
- package/dist/physics3d-voxel.js +138 -0
- package/dist/physics3d.d.ts +26 -0
- package/dist/physics3d.js +187 -1
- package/dist/runtime-room-metadata.d.ts +47 -0
- package/dist/runtime-room-metadata.js +84 -0
- package/dist/session-snapshot.d.ts +24 -0
- package/dist/session-snapshot.js +24 -0
- package/package.json +4 -3
|
@@ -1890,6 +1890,7 @@ struct QueryHit {
|
|
|
1890
1890
|
double distance = 0.0;
|
|
1891
1891
|
Vec3 point{};
|
|
1892
1892
|
Vec3 normal{};
|
|
1893
|
+
std::int32_t childIndex = -1;
|
|
1893
1894
|
};
|
|
1894
1895
|
QueryHit gQueryHits[kQueryCapacity];
|
|
1895
1896
|
double gQueryResultData[kQueryCapacity * kQueryResultStride];
|
|
@@ -3764,6 +3765,7 @@ struct RayHit {
|
|
|
3764
3765
|
double distance = 0.0;
|
|
3765
3766
|
Vec3 point{};
|
|
3766
3767
|
Vec3 normal{};
|
|
3768
|
+
std::int32_t childIndex = -1;
|
|
3767
3769
|
};
|
|
3768
3770
|
|
|
3769
3771
|
RayHit rayAabb(
|
|
@@ -3859,6 +3861,125 @@ RayHit raySphere(const Body& body, const Vec3& origin, const Vec3& direction, do
|
|
|
3859
3861
|
};
|
|
3860
3862
|
}
|
|
3861
3863
|
|
|
3864
|
+
RayHit rayCapsule(const Body& body, const Vec3& origin, const Vec3& direction, double maxDistance) {
|
|
3865
|
+
const Vec3 center{body.x + body.shapeOffsetX, body.y + body.shapeOffsetY, body.z + body.shapeOffsetZ};
|
|
3866
|
+
const Vec3 localOrigin = inverseRotateByOrientation(body, subtractVec3(origin, center));
|
|
3867
|
+
const Vec3 localDirection = inverseRotateByOrientation(body, direction);
|
|
3868
|
+
const double radius = body.shape0;
|
|
3869
|
+
const double halfHeight = body.shape1;
|
|
3870
|
+
|
|
3871
|
+
const double clampedY = std::max(-halfHeight, std::min(halfHeight, localOrigin.y));
|
|
3872
|
+
const double deltaY = localOrigin.y - clampedY;
|
|
3873
|
+
const double distSq = localOrigin.x * localOrigin.x + deltaY * deltaY + localOrigin.z * localOrigin.z;
|
|
3874
|
+
if (distSq <= radius * radius) {
|
|
3875
|
+
return {
|
|
3876
|
+
true,
|
|
3877
|
+
0.0,
|
|
3878
|
+
origin,
|
|
3879
|
+
scaleVec3(direction, -1.0),
|
|
3880
|
+
-1,
|
|
3881
|
+
};
|
|
3882
|
+
}
|
|
3883
|
+
|
|
3884
|
+
double bestDistance = maxDistance + 1.0;
|
|
3885
|
+
Vec3 bestLocalNormal{};
|
|
3886
|
+
bool hitFound = false;
|
|
3887
|
+
|
|
3888
|
+
// 1. Test vertical cylinder along Y: x^2 + z^2 = radius^2, y in [-halfHeight, halfHeight]
|
|
3889
|
+
const double a = localDirection.x * localDirection.x + localDirection.z * localDirection.z;
|
|
3890
|
+
const double b = 2.0 * (localOrigin.x * localDirection.x + localOrigin.z * localDirection.z);
|
|
3891
|
+
const double c = localOrigin.x * localOrigin.x + localOrigin.z * localOrigin.z - radius * radius;
|
|
3892
|
+
|
|
3893
|
+
if (a > 1e-18) {
|
|
3894
|
+
const double discriminant = b * b - 4.0 * a * c;
|
|
3895
|
+
if (discriminant >= 0.0) {
|
|
3896
|
+
const double root = std::sqrt(discriminant);
|
|
3897
|
+
const double t0 = (-b - root) / (2.0 * a);
|
|
3898
|
+
const double t1 = (-b + root) / (2.0 * a);
|
|
3899
|
+
for (const double t : {t0, t1}) {
|
|
3900
|
+
if (t >= 0.0 && t <= maxDistance) {
|
|
3901
|
+
const double hitY = localOrigin.y + localDirection.y * t;
|
|
3902
|
+
if (hitY >= -halfHeight && hitY <= halfHeight) {
|
|
3903
|
+
if (t < bestDistance) {
|
|
3904
|
+
bestDistance = t;
|
|
3905
|
+
bestLocalNormal = scaleVec3({localOrigin.x + localDirection.x * t, 0.0, localOrigin.z + localDirection.z * t}, 1.0 / radius);
|
|
3906
|
+
hitFound = true;
|
|
3907
|
+
}
|
|
3908
|
+
}
|
|
3909
|
+
}
|
|
3910
|
+
}
|
|
3911
|
+
}
|
|
3912
|
+
}
|
|
3913
|
+
|
|
3914
|
+
// 2. Test bottom sphere: center (0, -halfHeight, 0), radius
|
|
3915
|
+
{
|
|
3916
|
+
const Vec3 capCenter{0.0, -halfHeight, 0.0};
|
|
3917
|
+
const Vec3 offset = subtractVec3(localOrigin, capCenter);
|
|
3918
|
+
const double sb = 2.0 * dotVec3(offset, localDirection);
|
|
3919
|
+
const double sc = dotVec3(offset, offset) - radius * radius;
|
|
3920
|
+
const double sdisc = sb * sb - 4.0 * sc;
|
|
3921
|
+
if (sdisc >= 0.0) {
|
|
3922
|
+
const double root = std::sqrt(sdisc);
|
|
3923
|
+
const double t0 = (-sb - root) / 2.0;
|
|
3924
|
+
const double t1 = (-sb + root) / 2.0;
|
|
3925
|
+
for (const double t : {t0, t1}) {
|
|
3926
|
+
if (t >= 0.0 && t <= maxDistance) {
|
|
3927
|
+
const double hitY = localOrigin.y + localDirection.y * t;
|
|
3928
|
+
if (hitY <= -halfHeight) {
|
|
3929
|
+
if (t < bestDistance) {
|
|
3930
|
+
bestDistance = t;
|
|
3931
|
+
const Vec3 hitPt = addVec3(localOrigin, scaleVec3(localDirection, t));
|
|
3932
|
+
const Vec3 nDelta = subtractVec3(hitPt, capCenter);
|
|
3933
|
+
const double nLen = solverSqrt(dotVec3(nDelta, nDelta));
|
|
3934
|
+
bestLocalNormal = nLen > 1e-18 ? scaleVec3(nDelta, 1.0 / nLen) : Vec3{0.0, -1.0, 0.0};
|
|
3935
|
+
hitFound = true;
|
|
3936
|
+
}
|
|
3937
|
+
}
|
|
3938
|
+
}
|
|
3939
|
+
}
|
|
3940
|
+
}
|
|
3941
|
+
}
|
|
3942
|
+
|
|
3943
|
+
// 3. Test top sphere: center (0, halfHeight, 0), radius
|
|
3944
|
+
{
|
|
3945
|
+
const Vec3 capCenter{0.0, halfHeight, 0.0};
|
|
3946
|
+
const Vec3 offset = subtractVec3(localOrigin, capCenter);
|
|
3947
|
+
const double sb = 2.0 * dotVec3(offset, localDirection);
|
|
3948
|
+
const double sc = dotVec3(offset, offset) - radius * radius;
|
|
3949
|
+
const double sdisc = sb * sb - 4.0 * sc;
|
|
3950
|
+
if (sdisc >= 0.0) {
|
|
3951
|
+
const double root = std::sqrt(sdisc);
|
|
3952
|
+
const double t0 = (-sb - root) / 2.0;
|
|
3953
|
+
const double t1 = (-sb + root) / 2.0;
|
|
3954
|
+
for (const double t : {t0, t1}) {
|
|
3955
|
+
if (t >= 0.0 && t <= maxDistance) {
|
|
3956
|
+
const double hitY = localOrigin.y + localDirection.y * t;
|
|
3957
|
+
if (hitY >= halfHeight) {
|
|
3958
|
+
if (t < bestDistance) {
|
|
3959
|
+
bestDistance = t;
|
|
3960
|
+
const Vec3 hitPt = addVec3(localOrigin, scaleVec3(localDirection, t));
|
|
3961
|
+
const Vec3 nDelta = subtractVec3(hitPt, capCenter);
|
|
3962
|
+
const double nLen = solverSqrt(dotVec3(nDelta, nDelta));
|
|
3963
|
+
bestLocalNormal = nLen > 1e-18 ? scaleVec3(nDelta, 1.0 / nLen) : Vec3{0.0, 1.0, 0.0};
|
|
3964
|
+
hitFound = true;
|
|
3965
|
+
}
|
|
3966
|
+
}
|
|
3967
|
+
}
|
|
3968
|
+
}
|
|
3969
|
+
}
|
|
3970
|
+
}
|
|
3971
|
+
|
|
3972
|
+
if (!hitFound) return {};
|
|
3973
|
+
|
|
3974
|
+
return {
|
|
3975
|
+
true,
|
|
3976
|
+
bestDistance,
|
|
3977
|
+
addVec3(origin, scaleVec3(direction, bestDistance)),
|
|
3978
|
+
rotateByOrientation(body, bestLocalNormal),
|
|
3979
|
+
-1,
|
|
3980
|
+
};
|
|
3981
|
+
}
|
|
3982
|
+
|
|
3862
3983
|
RayHit rayTriangle(
|
|
3863
3984
|
const Vec3& origin,
|
|
3864
3985
|
const Vec3& direction,
|
|
@@ -3990,6 +4111,7 @@ BroadphaseBounds queryProxyBounds(const Body& body);
|
|
|
3990
4111
|
RayHit rayBody(const Body& body, const Vec3& origin, const Vec3& direction, double maxDistance) {
|
|
3991
4112
|
if (body.shape == ShapeKind::Sphere) return raySphere(body, origin, direction, maxDistance);
|
|
3992
4113
|
if (body.shape == ShapeKind::Box) return rayBox(body, origin, direction, maxDistance);
|
|
4114
|
+
if (body.shape == ShapeKind::Capsule) return rayCapsule(body, origin, direction, maxDistance);
|
|
3993
4115
|
if (body.shape == ShapeKind::Mesh || body.shape == ShapeKind::Heightfield) {
|
|
3994
4116
|
if (body.shape == ShapeKind::Mesh && body.geometryCount % 3 != 0) {
|
|
3995
4117
|
return rayAabb(queryProxyBounds(body), origin, direction, maxDistance);
|
|
@@ -4000,8 +4122,11 @@ RayHit rayBody(const Body& body, const Vec3& origin, const Vec3& direction, doub
|
|
|
4000
4122
|
&& (body.geometryFormat == 4 || body.geometryFormat == 5)) {
|
|
4001
4123
|
RayHit best;
|
|
4002
4124
|
for (std::uint32_t child = 0; child < compoundChildCount(body); child += 1) {
|
|
4003
|
-
|
|
4004
|
-
if (candidate.hit && (!best.hit || candidate.distance < best.distance))
|
|
4125
|
+
RayHit candidate = rayBody(compoundChildBody(body, child), origin, direction, maxDistance);
|
|
4126
|
+
if (candidate.hit && (!best.hit || candidate.distance < best.distance)) {
|
|
4127
|
+
candidate.childIndex = static_cast<std::int32_t>(child);
|
|
4128
|
+
best = candidate;
|
|
4129
|
+
}
|
|
4005
4130
|
}
|
|
4006
4131
|
if (best.hit) return best;
|
|
4007
4132
|
}
|
|
@@ -4103,7 +4228,7 @@ bool validQueryInput(const double* queryData, std::uint32_t queryValues) {
|
|
|
4103
4228
|
|
|
4104
4229
|
void appendQueryHit(std::uint32_t bodyIndex, const RayHit& hit) {
|
|
4105
4230
|
if (!hit.hit || gQueryResultCount >= kQueryCapacity) return;
|
|
4106
|
-
gQueryHits[gQueryResultCount++] = {bodyIndex, hit.distance, hit.point, hit.normal};
|
|
4231
|
+
gQueryHits[gQueryResultCount++] = {bodyIndex, hit.distance, hit.point, hit.normal, hit.childIndex};
|
|
4107
4232
|
}
|
|
4108
4233
|
|
|
4109
4234
|
void finalizeQueryResults(bool quantizeQueryDistance) {
|
|
@@ -4124,6 +4249,7 @@ void finalizeQueryResults(bool quantizeQueryDistance) {
|
|
|
4124
4249
|
gQueryResultData[offset + 5] = hit.normal.x == 0.0 ? 0.0 : hit.normal.x;
|
|
4125
4250
|
gQueryResultData[offset + 6] = hit.normal.y == 0.0 ? 0.0 : hit.normal.y;
|
|
4126
4251
|
gQueryResultData[offset + 7] = hit.normal.z == 0.0 ? 0.0 : hit.normal.z;
|
|
4252
|
+
gQueryResultData[offset + 8] = static_cast<double>(hit.childIndex);
|
|
4127
4253
|
}
|
|
4128
4254
|
}
|
|
4129
4255
|
|
|
@@ -14,7 +14,7 @@ constexpr std::uint32_t kContactTelemetryStride = 9;
|
|
|
14
14
|
constexpr std::uint32_t kJointTelemetryStride = 5;
|
|
15
15
|
constexpr std::uint32_t kForceStride = 6;
|
|
16
16
|
constexpr std::uint32_t kQueryInputStride = 21;
|
|
17
|
-
constexpr std::uint32_t kQueryResultStride =
|
|
17
|
+
constexpr std::uint32_t kQueryResultStride = 9;
|
|
18
18
|
constexpr std::uint32_t kMotionKindMask = 0b11;
|
|
19
19
|
constexpr std::uint32_t kMotionTrigger = 0b100;
|
|
20
20
|
constexpr std::uint32_t kMotionSensor = 0b1000;
|
package/core/physics.d.ts
CHANGED
|
@@ -387,6 +387,7 @@ export function raycastPhysicsDetailed(world: KinetixPhysicsWorld, query: Kineti
|
|
|
387
387
|
readonly point: KinetixPhysicsVec3;
|
|
388
388
|
readonly normal: KinetixPhysicsVec3;
|
|
389
389
|
readonly penetration: number;
|
|
390
|
+
readonly childIndex?: number;
|
|
390
391
|
})[];
|
|
391
392
|
export function overlapPhysics(world: KinetixPhysicsWorld, query: KinetixPhysicsOverlapQuery): readonly string[];
|
|
392
393
|
export function shapeCastPhysics(world: KinetixPhysicsWorld, query: KinetixPhysicsShapeCastQuery): readonly KinetixPhysicsHit[];
|
|
@@ -124,7 +124,7 @@ export function buildWasmPhysics({ check = false } = {}) {
|
|
|
124
124
|
contactTelemetryStride: 9,
|
|
125
125
|
jointTelemetryStride: 5,
|
|
126
126
|
queryInputStride: 21,
|
|
127
|
-
queryResultStride:
|
|
127
|
+
queryResultStride: 9,
|
|
128
128
|
compiler: compiler.command,
|
|
129
129
|
emccVersion: compiler.version,
|
|
130
130
|
compilerVersion: compiler.version,
|
|
@@ -62,7 +62,7 @@ const PHYSICS_BODY_STRIDE = 44;
|
|
|
62
62
|
const PHYSICS_JOINT_STRIDE = 48;
|
|
63
63
|
const PHYSICS_JOINT_TELEMETRY_STRIDE = 5;
|
|
64
64
|
const PHYSICS_QUERY_INPUT_STRIDE = 21;
|
|
65
|
-
const PHYSICS_QUERY_RESULT_STRIDE =
|
|
65
|
+
const PHYSICS_QUERY_RESULT_STRIDE = 9;
|
|
66
66
|
const PHYSICS_ARENA_ALIGNMENT = 16;
|
|
67
67
|
const PHYSICS_ARENA_GUARD_BYTES = 64;
|
|
68
68
|
const PHYSICS_MIN_PROXY_HALF_EXTENT = 1e-9;
|
|
@@ -1848,7 +1848,8 @@ function nativeQuery(world, query, kind) {
|
|
|
1848
1848
|
const offset = index * PHYSICS_QUERY_RESULT_STRIDE;
|
|
1849
1849
|
const body = bodies[values[offset]];
|
|
1850
1850
|
if (body === undefined) fail('KINETIX_PHYSICS_QUERY_BODY_MISSING');
|
|
1851
|
-
|
|
1851
|
+
const childIndexRaw = values[offset + 8];
|
|
1852
|
+
const hitObj = {
|
|
1852
1853
|
bodyId: body.id,
|
|
1853
1854
|
distance: kind === 'shapeCast' ? quantizeDistance(values[offset + 1]) : values[offset + 1],
|
|
1854
1855
|
point: {
|
|
@@ -1862,6 +1863,10 @@ function nativeQuery(world, query, kind) {
|
|
|
1862
1863
|
z: values[offset + 7],
|
|
1863
1864
|
},
|
|
1864
1865
|
};
|
|
1866
|
+
if (Number.isFinite(childIndexRaw) && childIndexRaw >= 0) {
|
|
1867
|
+
hitObj.childIndex = childIndexRaw;
|
|
1868
|
+
}
|
|
1869
|
+
return hitObj;
|
|
1865
1870
|
});
|
|
1866
1871
|
}
|
|
1867
1872
|
|
|
@@ -2628,13 +2633,19 @@ export function raycastPhysics(world, query) {
|
|
|
2628
2633
|
export function raycastPhysicsDetailed(world, query) {
|
|
2629
2634
|
const normalized = normalizedRayQuery(query);
|
|
2630
2635
|
if (physicsInstance !== null) {
|
|
2631
|
-
return deepFreeze(nativeQuery(world, normalized, 'raycast').map((hit) =>
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2636
|
+
return deepFreeze(nativeQuery(world, normalized, 'raycast').map((hit) => {
|
|
2637
|
+
const detailed = {
|
|
2638
|
+
bodyId: hit.bodyId,
|
|
2639
|
+
distance: hit.distance,
|
|
2640
|
+
point: hit.point,
|
|
2641
|
+
normal: hit.normal,
|
|
2642
|
+
penetration: 0,
|
|
2643
|
+
};
|
|
2644
|
+
if (hit.childIndex !== undefined) {
|
|
2645
|
+
detailed.childIndex = hit.childIndex;
|
|
2646
|
+
}
|
|
2647
|
+
return detailed;
|
|
2648
|
+
}));
|
|
2638
2649
|
}
|
|
2639
2650
|
return deepFreeze(raycastPhysics(world, normalized).map((hit) => {
|
|
2640
2651
|
const body = world.bodies.find((candidate) => candidate.id === hit.bodyId);
|