Add instancer_mode
This commit is contained in:
parent
25d581d79a
commit
0503cb1b27
|
|
@ -1118,7 +1118,7 @@ void Terrain3D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_physics_material", "material"), &Terrain3D::set_physics_material);
|
||||
ClassDB::bind_method(D_METHOD("get_physics_material"), &Terrain3D::get_physics_material);
|
||||
|
||||
// Meshes
|
||||
// Mesh
|
||||
ClassDB::bind_method(D_METHOD("set_mesh_lods", "count"), &Terrain3D::set_mesh_lods);
|
||||
ClassDB::bind_method(D_METHOD("get_mesh_lods"), &Terrain3D::get_mesh_lods);
|
||||
ClassDB::bind_method(D_METHOD("set_mesh_size", "size"), &Terrain3D::set_mesh_size);
|
||||
|
|
@ -1139,8 +1139,8 @@ void Terrain3D::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_cull_margin"), &Terrain3D::get_cull_margin);
|
||||
ClassDB::bind_method(D_METHOD("set_free_editor_textures"), &Terrain3D::set_free_editor_textures);
|
||||
ClassDB::bind_method(D_METHOD("get_free_editor_textures"), &Terrain3D::get_free_editor_textures);
|
||||
ClassDB::bind_method(D_METHOD("set_show_instances", "visible"), &Terrain3D::set_show_instances);
|
||||
ClassDB::bind_method(D_METHOD("get_show_instances"), &Terrain3D::get_show_instances);
|
||||
ClassDB::bind_method(D_METHOD("set_instancer_mode", "mode"), &Terrain3D::set_instancer_mode);
|
||||
ClassDB::bind_method(D_METHOD("get_instancer_mode"), &Terrain3D::get_instancer_mode);
|
||||
|
||||
// Overlays
|
||||
ClassDB::bind_method(D_METHOD("set_show_region_grid", "enabled"), &Terrain3D::set_show_region_grid);
|
||||
|
|
@ -1219,7 +1219,7 @@ void Terrain3D::_bind_methods() {
|
|||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physics_material", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsMaterial"), "set_physics_material", "get_physics_material");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "collision_target", PROPERTY_HINT_NODE_TYPE, "Node3D", PROPERTY_USAGE_DEFAULT, "Node3D"), "set_collision_target", "get_collision_target");
|
||||
|
||||
ADD_GROUP("Mesh", "");
|
||||
ADD_GROUP("Clipmap Mesh", "");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "mesh_lods", PROPERTY_HINT_RANGE, "1,10,1"), "set_mesh_lods", "get_mesh_lods");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "mesh_size", PROPERTY_HINT_RANGE, "8,256,2"), "set_mesh_size", "get_mesh_size");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "vertex_spacing", PROPERTY_HINT_RANGE, "0.25,10.0,0.05,or_greater"), "set_vertex_spacing", "get_vertex_spacing");
|
||||
|
|
@ -1232,7 +1232,7 @@ void Terrain3D::_bind_methods() {
|
|||
ADD_PROPERTY(PropertyInfo(Variant::INT, "gi_mode", PROPERTY_HINT_ENUM, "Disabled,Static,Dynamic"), "set_gi_mode", "get_gi_mode");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "cull_margin", PROPERTY_HINT_RANGE, "0.0,10000.0,.5,or_greater"), "set_cull_margin", "get_cull_margin");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "free_editor_textures"), "set_free_editor_textures", "get_free_editor_textures");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_instances"), "set_show_instances", "get_show_instances");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "instancer_mode", PROPERTY_HINT_ENUM, "Disabled,Normal"), "set_instancer_mode", "get_instancer_mode");
|
||||
|
||||
ADD_GROUP("Overlays", "show_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_region_grid"), "set_show_region_grid", "get_show_region_grid");
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ public:
|
|||
int get_label_size() const { return _label_size; }
|
||||
void update_region_labels();
|
||||
|
||||
// Meshes
|
||||
// Mesh
|
||||
void set_mesh_lods(const int p_count);
|
||||
int get_mesh_lods() const { return _mesh_lods; }
|
||||
void set_mesh_size(const int p_size);
|
||||
|
|
@ -186,8 +186,6 @@ public:
|
|||
real_t get_cull_margin() const { return _cull_margin; };
|
||||
void set_free_editor_textures(const bool p_free_textures) { _free_editor_textures = p_free_textures; }
|
||||
bool get_free_editor_textures() const { return _free_editor_textures; };
|
||||
void set_show_instances(const bool p_visible) { _instancer ? _instancer->set_show_instances(p_visible) : void(); }
|
||||
bool get_show_instances() const { return _instancer ? _instancer->get_show_instances() : true; }
|
||||
|
||||
// Utility
|
||||
Vector3 get_intersection(const Vector3 &p_src_pos, const Vector3 &p_direction, const bool p_gpu_mode = false);
|
||||
|
|
@ -216,6 +214,10 @@ public:
|
|||
void set_physics_material(const Ref<PhysicsMaterial> &p_mat) { _collision ? _collision->set_physics_material(p_mat) : void(); }
|
||||
Ref<PhysicsMaterial> get_physics_material() const { return _collision ? _collision->get_physics_material() : Ref<PhysicsMaterial>(); }
|
||||
|
||||
// Instancer Aliases
|
||||
void set_instancer_mode(const InstancerMode p_mode) { _instancer ? _instancer->set_mode(p_mode) : void(); }
|
||||
InstancerMode get_instancer_mode() const { return _instancer ? _instancer->get_mode() : InstancerMode::NORMAL; }
|
||||
|
||||
// Overlay Aliases
|
||||
void set_show_region_grid(const bool p_enabled) { _material.is_valid() ? _material->set_show_region_grid(p_enabled) : void(); }
|
||||
bool get_show_region_grid() const { return _material.is_valid() ? _material->get_show_region_grid() : false; }
|
||||
|
|
|
|||
|
|
@ -34,9 +34,9 @@ void Terrain3DInstancer::_process_updates() {
|
|||
bool update_all = false;
|
||||
if (_queued_updates.find({ V2I_MAX, -2 }) != _queued_updates.end()) {
|
||||
destroy();
|
||||
update_all = _show_instances;
|
||||
update_all = true;
|
||||
} else if (_queued_updates.find({ V2I_MAX, -1 }) != _queued_updates.end()) {
|
||||
update_all = _show_instances;
|
||||
update_all = true;
|
||||
}
|
||||
|
||||
if (update_all) {
|
||||
|
|
@ -437,7 +437,6 @@ void Terrain3DInstancer::_destroy_mmi_by_cell(const Vector2i &p_region_loc, cons
|
|||
ma->update_instance_count(-RS->multimesh_get_instance_count(mm));
|
||||
}
|
||||
}
|
||||
|
||||
LOG(EXTREME, "Freeing mmi:", mmi, ", mm:", mm, " and erasing mmi cell ", p_cell);
|
||||
if (mmi.is_valid()) {
|
||||
RS->free_rid(mmi);
|
||||
|
|
@ -479,6 +478,9 @@ void Terrain3DInstancer::_backup_region(const Ref<Terrain3DRegion> &p_region) {
|
|||
RID Terrain3DInstancer::_create_multimesh(const int p_mesh_id, const int p_lod, const TypedArray<Transform3D> &p_xforms, const PackedColorArray &p_colors) const {
|
||||
RID mm;
|
||||
IS_INIT(mm);
|
||||
if (p_xforms.size() == 0) {
|
||||
return mm;
|
||||
}
|
||||
Ref<Terrain3DMeshAsset> mesh_asset = _terrain->get_assets()->get_mesh_asset(p_mesh_id);
|
||||
if (mesh_asset.is_null()) {
|
||||
LOG(ERROR, "No mesh id ", p_mesh_id, " found");
|
||||
|
|
@ -606,6 +608,23 @@ void Terrain3DInstancer::clear_by_region(const Ref<Terrain3DRegion> &p_region, c
|
|||
_destroy_mmi_by_location(region_loc, p_mesh_id);
|
||||
}
|
||||
|
||||
void Terrain3DInstancer::set_mode(const InstancerMode p_mode) {
|
||||
LOG(INFO, "Setting instancer mode: ", p_mode);
|
||||
if (p_mode != _mode) {
|
||||
_mode = p_mode;
|
||||
switch (_mode) {
|
||||
case NORMAL:
|
||||
update_mmis(-1, V2I_MAX, true);
|
||||
break;
|
||||
//case PLACEHOLDER:
|
||||
// break;
|
||||
default:
|
||||
destroy();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Terrain3DInstancer::add_instances(const Vector3 &p_global_position, const Dictionary &p_params) {
|
||||
IS_DATA_INIT_MESG("Instancer isn't initialized.", VOID);
|
||||
int mesh_id = p_params.get("asset_id", 0);
|
||||
|
|
@ -1276,6 +1295,10 @@ void Terrain3DInstancer::swap_ids(const int p_src_id, const int p_dst_id) {
|
|||
// If mesh_id < 0, will do all meshes in the specified region
|
||||
// You safely can call multiple times per frame, and select any combo of options without fillling up the queue.
|
||||
void Terrain3DInstancer::update_mmis(const int p_mesh_id, const Vector2i &p_region_loc, const bool p_rebuild) {
|
||||
if (_mode == DISABLED) {
|
||||
LOG(INFO, "Instancer is disabled");
|
||||
return;
|
||||
}
|
||||
LOG(INFO, "Queueing MMI update for mesh id: ", p_mesh_id < 0 ? "all" : String::num_int64(p_mesh_id),
|
||||
", region: ", p_region_loc == V2I_MAX ? "all" : String(p_region_loc),
|
||||
p_rebuild ? ", destroying first" : "");
|
||||
|
|
@ -1314,20 +1337,21 @@ void Terrain3DInstancer::update_mmis(const int p_mesh_id, const Vector2i &p_regi
|
|||
}
|
||||
}
|
||||
|
||||
void Terrain3DInstancer::set_show_instances(const bool p_visible) {
|
||||
SET_IF_DIFF(_show_instances, p_visible);
|
||||
LOG(INFO, "Setting instancer visibility to: ", p_visible);
|
||||
update_mmis(-1, V2I_MAX, true);
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
// Protected Functions
|
||||
///////////////////////////
|
||||
|
||||
void Terrain3DInstancer::_bind_methods() {
|
||||
BIND_ENUM_CONSTANT(NORMAL);
|
||||
//BIND_ENUM_CONSTANT(PLACEHOLDER);
|
||||
BIND_ENUM_CONSTANT(DISABLED);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("clear_by_mesh", "mesh_id"), &Terrain3DInstancer::clear_by_mesh);
|
||||
ClassDB::bind_method(D_METHOD("clear_by_location", "region_location", "mesh_id"), &Terrain3DInstancer::clear_by_location);
|
||||
ClassDB::bind_method(D_METHOD("clear_by_region", "region", "mesh_id"), &Terrain3DInstancer::clear_by_region);
|
||||
ClassDB::bind_method(D_METHOD("set_mode", "mode"), &Terrain3DInstancer::set_mode);
|
||||
ClassDB::bind_method(D_METHOD("get_mode"), &Terrain3DInstancer::get_mode);
|
||||
ClassDB::bind_method(D_METHOD("is_enabled"), &Terrain3DInstancer::is_enabled);
|
||||
ClassDB::bind_method(D_METHOD("add_instances", "global_position", "params"), &Terrain3DInstancer::add_instances);
|
||||
ClassDB::bind_method(D_METHOD("remove_instances", "global_position", "params"), &Terrain3DInstancer::remove_instances);
|
||||
ClassDB::bind_method(D_METHOD("add_multimesh", "mesh_id", "multimesh", "transform", "update"), &Terrain3DInstancer::add_multimesh, DEFVAL(Transform3D()), DEFVAL(true));
|
||||
|
|
@ -1338,6 +1362,6 @@ void Terrain3DInstancer::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_closest_mesh_id", "global_position"), &Terrain3DInstancer::get_closest_mesh_id);
|
||||
ClassDB::bind_method(D_METHOD("update_mmis", "mesh_id", "region_location", "rebuild_all"), &Terrain3DInstancer::update_mmis, DEFVAL(-1), DEFVAL(V2I_MAX), DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("swap_ids", "src_id", "dest_id"), &Terrain3DInstancer::swap_ids);
|
||||
ClassDB::bind_method(D_METHOD("set_show_instances", "p_visible"), &Terrain3DInstancer::set_show_instances);
|
||||
ClassDB::bind_method(D_METHOD("get_show_instances"), &Terrain3DInstancer::get_show_instances);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Disabled,Normal"), "set_mode", "get_mode");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,12 @@ class Terrain3DInstancer : public Object {
|
|||
public: // Constants
|
||||
static inline const int CELL_SIZE = 32;
|
||||
|
||||
enum InstancerMode {
|
||||
DISABLED,
|
||||
//PLACEHOLDER,
|
||||
NORMAL,
|
||||
};
|
||||
|
||||
private:
|
||||
Terrain3D *_terrain = nullptr;
|
||||
|
||||
|
|
@ -43,8 +49,8 @@ private:
|
|||
using V2IIntPair = std::unordered_set<std::pair<Vector2i, int>, PairVector2iIntHash>;
|
||||
V2IIntPair _queued_updates;
|
||||
|
||||
InstancerMode _mode = NORMAL;
|
||||
uint32_t _density_counter = 0;
|
||||
bool _show_instances = true;
|
||||
|
||||
uint32_t _get_density_count(const real_t p_density);
|
||||
int _get_master_lod(const Ref<Terrain3DMeshAsset> &p_ma);
|
||||
|
|
@ -71,6 +77,10 @@ public:
|
|||
void clear_by_location(const Vector2i &p_region_loc, const int p_mesh_id);
|
||||
void clear_by_region(const Ref<Terrain3DRegion> &p_region, const int p_mesh_id);
|
||||
|
||||
void set_mode(const InstancerMode p_mode);
|
||||
InstancerMode get_mode() const { return _mode; }
|
||||
bool is_enabled() const { return _mode != DISABLED; }
|
||||
|
||||
void add_instances(const Vector3 &p_global_position, const Dictionary &p_params);
|
||||
void remove_instances(const Vector3 &p_global_position, const Dictionary &p_params);
|
||||
void add_multimesh(const int p_mesh_id, const Ref<MultiMesh> &p_multimesh, const Transform3D &p_xform = Transform3D(), const bool p_update = true);
|
||||
|
|
@ -87,13 +97,14 @@ public:
|
|||
void update_mmis(const int p_mesh_id = -1, const Vector2i &p_region_loc = V2I_MAX, const bool p_rebuild = false);
|
||||
|
||||
void reset_density_counter() { _density_counter = 0; }
|
||||
void set_show_instances(const bool p_visible);
|
||||
bool get_show_instances() const { return _show_instances; }
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
};
|
||||
|
||||
using InstancerMode = Terrain3DInstancer::InstancerMode;
|
||||
VARIANT_ENUM_CAST(Terrain3DInstancer::InstancerMode);
|
||||
|
||||
// Allows us to instance every X function calls for sparse placement
|
||||
// Modifies _density_counter, not const!
|
||||
inline uint32_t Terrain3DInstancer::_get_density_count(const real_t p_density) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue