mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-11-04 11:19:30 +01:00
Cull instances by compact records and draw them from a shader storage buffer
This commit is contained in:
@@ -381,7 +381,7 @@ basic_cell::insert( TAnimModel *Instance ) {
|
||||
}
|
||||
auto &bucket { m_instancebuckets_opaque[ key ] };
|
||||
bucket.instances.emplace_back( Instance );
|
||||
bucket.bounds.clear();
|
||||
bucket.records.clear();
|
||||
}
|
||||
}
|
||||
// re-calculate cell bounding area, in case model extends outside the cell's boundaries
|
||||
@@ -484,7 +484,7 @@ basic_cell::erase( TAnimModel *Instance ) {
|
||||
instances.erase(
|
||||
std::remove( std::begin( instances ), std::end( instances ), Instance ),
|
||||
std::end( instances ) );
|
||||
bucket->second.bounds.clear();
|
||||
bucket->second.records.clear();
|
||||
if( instances.empty() ) {
|
||||
bucket = m_instancebuckets_opaque.erase( bucket );
|
||||
}
|
||||
|
||||
@@ -237,19 +237,31 @@ public:
|
||||
}
|
||||
};
|
||||
using instance_bucket_map = std::unordered_map< instance_bucket_key, std::vector<TAnimModel *>, instance_bucket_key_hash >;
|
||||
// what it takes to tell that an instance is out of sight, copied from the instance.
|
||||
// what it takes to cull and place an instance, copied from the instance.
|
||||
// a cell can hold thousands of instances, each of them large and placed wherever the memory was free, and a render
|
||||
// pass rejects most of them. the renderer makes the copies and goes by them, to fetch only the instances it may draw
|
||||
struct instance_bounds {
|
||||
glm::vec3 center { 0.f }; // location of the instance, in the precision the frustum test takes it
|
||||
// pass rejects most of them. the renderer makes the copies and goes by them, and reads the instance itself only
|
||||
// for the first one of a batch drawn. the layout follows std430, for the copies to be handed to the gpu as they are
|
||||
struct instance_record {
|
||||
glm::vec3 position { 0.f }; // location of the instance, relative to the origin of the records of its bucket
|
||||
float radius { 0.f };
|
||||
float rangesquaredmax { 0.f }; // past it the instance isn't drawn: by its own range, or the lod stages of its model
|
||||
float rangesquaredmin { 0.f }; // visibility range of the instance
|
||||
float rangesquaredmax { 0.f };
|
||||
std::uint32_t flags { 0 }; // instance_record_flags
|
||||
std::uint32_t pad { 0 };
|
||||
glm::vec4 rotationscale[ 3 ] {}; // columns of rotation and scale of the instance, w unused
|
||||
};
|
||||
static_assert( sizeof( instance_record ) == 80, "instance_record has to keep its std430 layout" );
|
||||
enum instance_record_flags : std::uint32_t {
|
||||
instance_visible = 1 << 0,
|
||||
instance_instanceable = 1 << 1, // false once an event gave the instance animations or a skin of its own
|
||||
};
|
||||
struct instance_bucket {
|
||||
std::vector<TAnimModel *> instances;
|
||||
// caches owned by the renderer; emptied whenever the content of the bucket changes
|
||||
mutable std::vector<instance_bounds> bounds; // copies for the instances, in the same order
|
||||
mutable unsigned int boundsversion { 0 };
|
||||
mutable std::vector<instance_record> records; // copies for the instances, in the same order
|
||||
mutable glm::dvec3 recordorigin { 0.0 }; // the records hold locations relative to it
|
||||
mutable float lodrangesquared { 0.f }; // past it no submodel of the model of the bucket is drawn
|
||||
mutable unsigned int recordsversion { 0 };
|
||||
};
|
||||
using instance_bucketdata_map = std::unordered_map< instance_bucket_key, instance_bucket, instance_bucket_key_hash >;
|
||||
using sound_sequence = std::vector<sound_source *>;
|
||||
|
||||
@@ -345,6 +345,10 @@ private:
|
||||
|
||||
|
||||
|
||||
// changes whenever a node is shown or hidden, or a model instance stops being drawn along with other instances of its
|
||||
// model. copies of these states (instance records of the renderer) are made anew once it changes
|
||||
inline unsigned int node_state_version { 1 };
|
||||
|
||||
// base interface for nodes which can be actvated in scenario editor
|
||||
class basic_node {
|
||||
|
||||
@@ -460,6 +464,9 @@ basic_node::location() {
|
||||
inline
|
||||
void
|
||||
basic_node::visible( bool const Visible ) {
|
||||
if( Visible != m_visible ) {
|
||||
++node_state_version;
|
||||
}
|
||||
m_visible = Visible;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user