mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-17 08:39:19 +02:00
feat(instancing): batch models animated only by time, wind or sky
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user