17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-17 06:19:19 +02:00

feat(instancing): batch models animated only by time, wind or sky

This commit is contained in:
2026-10-01 12:07:54 +02:00
parent 20f536f05e
commit 4eabf3c3b5

View File

@@ -403,8 +403,8 @@ namespace {
// TSubModel tree, which would make batched rendering unsafe. Most animations
// loaded from .t3d files are global functions of time (clocks, wind, sky) and
// only transform the local modelview matrix — those are safe to share. Camera-
// relative billboards also operate purely on the local matrix using whatever
// modelview the caller pushed, which is exactly per-instance behaviour.
// relative billboards are not: they're computed on the cpu from the modelview of
// the drawn instance, which in a batch is only the submodel-local chain.
// The runtime SetRotate/SetTranslate animations (at_Rotate / at_RotateXYZ /
// at_Translate) are tied to per-instance iAnimOwner and are unsafe to share.
// at_Undefined is the type assigned to .t3d submodels declared with `anim: true`
@@ -425,17 +425,40 @@ bool anim_type_unsafe_for_instancing( TAnimType a ) {
}
}
// returns true if this animation type depends only on global state (simulation
// time, wind, sky) and so gives every instance of the model the same local
// transform. The batch evaluates it once and the per-instance placement comes
// from the instance matrix, the result is the same as with per-instance drawing.
bool anim_type_shared_by_instances( TAnimType a ) {
switch( a ) {
case TAnimType::at_SecondsJump:
case TAnimType::at_MinutesJump:
case TAnimType::at_HoursJump:
case TAnimType::at_Hours24Jump:
case TAnimType::at_Seconds:
case TAnimType::at_Minutes:
case TAnimType::at_Hours:
case TAnimType::at_Hours24:
case TAnimType::at_Wind:
case TAnimType::at_Sky:
return true;
default:
return false;
}
}
// recursively walks a submodel tree and returns true if any submodel declares
// an animation type that's unsafe to batch, OR carries the runtime "needs
// animation matrix" flag (iFlags bit 0x4000), which is set whenever the
// submodel was tagged as animatable in the .t3d file or had WillBeAnimated()
// called on it during model load. Either signal means the submodel may receive
// animation matrix" flag (iFlags bit 0x4000) for anything else than an animation
// shared by all instances. The flag is set whenever the submodel was tagged as
// animatable in the .t3d file (any `anim:` other than `false`) or had
// WillBeAnimated() called on it during model load. Such a submodel may receive
// per-instance event-driven animation commands at runtime, which the GPU-
// instanced path (one shared submodel tree across all instances) cannot serve.
bool submodel_tree_blocks_instancing( TSubModel const *Sub ) {
if( Sub == nullptr ) { return false; }
if( anim_type_unsafe_for_instancing( Sub->b_Anim ) ) { return true; }
if( ( Sub->iFlags & 0x4000 ) != 0 ) { return true; }
if( ( ( Sub->iFlags & 0x4000 ) != 0 ) && ( false == anim_type_shared_by_instances( Sub->b_Anim ) ) ) { return true; }
if( submodel_tree_blocks_instancing( Sub->Child ) ) { return true; }
if( submodel_tree_blocks_instancing( Sub->Next ) ) { return true; }
return false;