render: key rigid pose rings by instance identity and make their mispair gates rotation-aware
This commit is contained in:
parent
020af8ae90
commit
14acde031b
1 changed files with 37 additions and 5 deletions
|
|
@ -6801,7 +6801,21 @@ void InterpolateDynamicItems(uint8_t* base, FrameScene& scene, double now) {
|
||||||
const float dx = item.world[12] - lp.w[12];
|
const float dx = item.world[12] - lp.w[12];
|
||||||
const float dy = item.world[13] - lp.w[13];
|
const float dy = item.world[13] - lp.w[13];
|
||||||
const float dz = item.world[14] - lp.w[14];
|
const float dz = item.world[14] - lp.w[14];
|
||||||
return dx * dx + dy * dy + dz * dz;
|
const float d2 = dx * dx + dy * dy + dz * dz;
|
||||||
|
// Rotation-aware for rigid: mirrored clone twins can sit at the SAME
|
||||||
|
// translation (railing pairs), and a translation-only metric pairs
|
||||||
|
// their rings freely - the interpolator then lerps across the flip.
|
||||||
|
// Fold the rotation delta in as an equivalent distance; a mispair
|
||||||
|
// (elementwise delta up to 2.0) lands far outside every claim cap,
|
||||||
|
// while a physics prop's one-tick rotation stays well inside.
|
||||||
|
float rd = 0.0f;
|
||||||
|
for (int r = 0; r < 3; ++r) {
|
||||||
|
for (int c2 = 0; c2 < 3; ++c2) {
|
||||||
|
rd = std::max(rd, std::fabs(item.world[r * 4 + c2] -
|
||||||
|
lp.w[r * 4 + c2]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::max(d2, rd * rd * 4.0f);
|
||||||
};
|
};
|
||||||
// One-time bind-space vertex-centroid table for this entity (see the
|
// One-time bind-space vertex-centroid table for this entity (see the
|
||||||
// pivot-boxcar comment at the collapse guard). Also computed EAGERLY on
|
// pivot-boxcar comment at the collapse guard). Also computed EAGERLY on
|
||||||
|
|
@ -6859,10 +6873,18 @@ void InterpolateDynamicItems(uint8_t* base, FrameScene& scene, double now) {
|
||||||
// list clone reshuffles cannot mispair an identity key, so the whole
|
// list clone reshuffles cannot mispair an identity key, so the whole
|
||||||
// positional claim search below is skipped for them. Mesh stays in the
|
// positional claim search below is skipped for them. Mesh stays in the
|
||||||
// key so a model/LOD swap on the same instance starts a fresh ring
|
// key so a model/LOD swap on the same instance starts a fresh ring
|
||||||
// (pose sizes differ). Legacy (mesh, occurrence) pairing continues to
|
// (pose sizes differ). RIGID items with a ctx take the identity key
|
||||||
// serve everything without a store entry (player, CAC, non-LW).
|
// too: park-editor venues submit dozens of same-mesh piece clones,
|
||||||
bool lw_keyed = item.lw_entity != 0 && item.ctx != 0 &&
|
// including mirrored twins at the SAME translation, and any camera pan
|
||||||
REXCVAR_GET(skate3_native_render_scene_lw_identity);
|
// reshuffles the occurrence ordinals - the positional claim below then
|
||||||
|
// swaps the twins' rings every frame (translation distance 0) and the
|
||||||
|
// interpolator lerps their 180-degree-apart rotations, the visible
|
||||||
|
// piece spin. Legacy (mesh, occurrence) pairing continues to serve
|
||||||
|
// everything without a usable ctx (player, CAC, ctx-less captures).
|
||||||
|
bool lw_keyed = item.ctx != 0 &&
|
||||||
|
((item.lw_entity != 0 &&
|
||||||
|
REXCVAR_GET(skate3_native_render_scene_lw_identity)) ||
|
||||||
|
!skinned);
|
||||||
uint64_t key = lw_keyed ? ((1ull << 63) | (uint64_t(item.ctx) << 32) |
|
uint64_t key = lw_keyed ? ((1ull << 63) | (uint64_t(item.ctx) << 32) |
|
||||||
uint64_t(item.mesh))
|
uint64_t(item.mesh))
|
||||||
: ((uint64_t(item.mesh) << 8) | (k & 0xFF));
|
: ((uint64_t(item.mesh) << 8) | (k & 0xFF));
|
||||||
|
|
@ -7108,6 +7130,16 @@ void InterpolateDynamicItems(uint8_t* base, FrameScene& scene, double now) {
|
||||||
const float dy = item.world[13] - latest.w[13];
|
const float dy = item.world[13] - latest.w[13];
|
||||||
const float dz = item.world[14] - latest.w[14];
|
const float dz = item.world[14] - latest.w[14];
|
||||||
d2 = dx * dx + dy * dy + dz * dz;
|
d2 = dx * dx + dy * dy + dz * dz;
|
||||||
|
// Same rotation fold as hist_dist2: a same-spot mirrored-twin
|
||||||
|
// mispair must reset the ring, not lerp across the flip.
|
||||||
|
float rd = 0.0f;
|
||||||
|
for (int r = 0; r < 3; ++r) {
|
||||||
|
for (int c2 = 0; c2 < 3; ++c2) {
|
||||||
|
rd = std::max(rd, std::fabs(item.world[r * 4 + c2] -
|
||||||
|
latest.w[r * 4 + c2]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
d2 = std::max(d2, rd * rd * 4.0f);
|
||||||
}
|
}
|
||||||
// Rigid uses the same tight one-tick bound as the claim cap
|
// Rigid uses the same tight one-tick bound as the claim cap
|
||||||
// above: 0.78 m clone placements sit inside the vehicles' 1.5 m
|
// above: 0.78 m clone placements sit inside the vehicles' 1.5 m
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue