Fixed some crashes occurring when giving invalid arguments to functions
parent
149eb2a873
commit
52aa4963ea
|
@ -148,6 +148,28 @@ bool ProgramGraph::disconnect(PortLocation src, PortLocation dst) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ProgramGraph::is_input_port_valid(PortLocation loc) const {
|
||||
Node *node = try_get_node(loc.node_id);
|
||||
if (node == nullptr) {
|
||||
return false;
|
||||
}
|
||||
if (loc.port_index >= node->inputs.size()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ProgramGraph::is_output_port_valid(PortLocation loc) const {
|
||||
Node *node = try_get_node(loc.node_id);
|
||||
if (node == nullptr) {
|
||||
return false;
|
||||
}
|
||||
if (loc.port_index >= node->outputs.size()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ProgramGraph::Node *ProgramGraph::get_node(uint32_t id) const {
|
||||
auto it = _nodes.find(id);
|
||||
CRASH_COND(it == _nodes.end());
|
||||
|
|
|
@ -58,6 +58,8 @@ public:
|
|||
bool can_connect(PortLocation src, PortLocation dst) const;
|
||||
void connect(PortLocation src, PortLocation dst);
|
||||
bool disconnect(PortLocation src, PortLocation dst);
|
||||
bool is_input_port_valid(PortLocation loc) const;
|
||||
bool is_output_port_valid(PortLocation loc) const;
|
||||
|
||||
bool has_path(uint32_t p_src_node_id, uint32_t p_dst_node_id) const;
|
||||
void find_dependencies(std::vector<uint32_t> nodes_to_process, std::vector<uint32_t> &out_order) const;
|
||||
|
|
|
@ -47,36 +47,44 @@ static ProgramGraph::Node *create_node_internal(ProgramGraph &graph,
|
|||
}
|
||||
|
||||
uint32_t VoxelGeneratorGraph::create_node(NodeTypeID type_id, Vector2 position, uint32_t id) {
|
||||
ERR_FAIL_COND_V(!VoxelGraphNodeDB::get_singleton()->is_valid_type_id(type_id), ProgramGraph::NULL_ID);
|
||||
const ProgramGraph::Node *node = create_node_internal(_graph, type_id, position, id);
|
||||
ERR_FAIL_COND_V(node == nullptr, ProgramGraph::NULL_ID);
|
||||
return node->id;
|
||||
}
|
||||
|
||||
void VoxelGeneratorGraph::remove_node(uint32_t node_id) {
|
||||
ERR_FAIL_COND(_graph.try_get_node(node_id) == nullptr);
|
||||
_graph.remove_node(node_id);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
bool VoxelGeneratorGraph::can_connect(
|
||||
uint32_t src_node_id, uint32_t src_port_index, uint32_t dst_node_id, uint32_t dst_port_index) const {
|
||||
return _graph.can_connect(
|
||||
ProgramGraph::PortLocation{ src_node_id, src_port_index },
|
||||
ProgramGraph::PortLocation{ dst_node_id, dst_port_index });
|
||||
const ProgramGraph::PortLocation src_port{ src_node_id, src_port_index };
|
||||
const ProgramGraph::PortLocation dst_port{ dst_node_id, dst_port_index };
|
||||
ERR_FAIL_COND_V(!_graph.is_output_port_valid(src_port), false);
|
||||
ERR_FAIL_COND_V(!_graph.is_input_port_valid(dst_port), false);
|
||||
return _graph.can_connect(src_port, dst_port);
|
||||
}
|
||||
|
||||
void VoxelGeneratorGraph::add_connection(
|
||||
uint32_t src_node_id, uint32_t src_port_index, uint32_t dst_node_id, uint32_t dst_port_index) {
|
||||
_graph.connect(
|
||||
ProgramGraph::PortLocation{ src_node_id, src_port_index },
|
||||
ProgramGraph::PortLocation{ dst_node_id, dst_port_index });
|
||||
const ProgramGraph::PortLocation src_port{ src_node_id, src_port_index };
|
||||
const ProgramGraph::PortLocation dst_port{ dst_node_id, dst_port_index };
|
||||
ERR_FAIL_COND(!_graph.is_output_port_valid(src_port));
|
||||
ERR_FAIL_COND(!_graph.is_input_port_valid(dst_port));
|
||||
_graph.connect(src_port, dst_port);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
void VoxelGeneratorGraph::remove_connection(
|
||||
uint32_t src_node_id, uint32_t src_port_index, uint32_t dst_node_id, uint32_t dst_port_index) {
|
||||
_graph.disconnect(
|
||||
ProgramGraph::PortLocation{ src_node_id, src_port_index },
|
||||
ProgramGraph::PortLocation{ dst_node_id, dst_port_index });
|
||||
const ProgramGraph::PortLocation src_port{ src_node_id, src_port_index };
|
||||
const ProgramGraph::PortLocation dst_port{ dst_node_id, dst_port_index };
|
||||
ERR_FAIL_COND(!_graph.is_output_port_valid(src_port));
|
||||
ERR_FAIL_COND(!_graph.is_input_port_valid(dst_port));
|
||||
_graph.disconnect(src_port, dst_port);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
|
@ -1322,6 +1330,7 @@ int VoxelGeneratorGraph::_b_get_node_type_count() const {
|
|||
}
|
||||
|
||||
Dictionary VoxelGeneratorGraph::_b_get_node_type_info(int type_id) const {
|
||||
ERR_FAIL_COND_V(!VoxelGraphNodeDB::get_singleton()->is_valid_type_id(type_id), Dictionary());
|
||||
return VoxelGraphNodeDB::get_singleton()->get_type_info_dict(type_id);
|
||||
}
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@ public:
|
|||
static const char *get_category_name(Category category);
|
||||
|
||||
int get_type_count() const { return _types.size(); }
|
||||
bool is_valid_type_id(int type_id) const { return type_id >= 0 && type_id < _types.size(); }
|
||||
const NodeType &get_type(uint32_t id) const { return _types[id]; }
|
||||
Dictionary get_type_info_dict(uint32_t id) const;
|
||||
bool try_get_type_id_from_name(const String &name, VoxelGeneratorGraph::NodeTypeID &out_type_id) const;
|
||||
|
|
|
@ -26,6 +26,9 @@ void VoxelLibrary::set_voxel_count(unsigned int type_count) {
|
|||
int VoxelLibrary::get_voxel_index_from_name(StringName name) const {
|
||||
for (size_t i = 0; i < _voxel_types.size(); ++i) {
|
||||
const Ref<Voxel> &v = _voxel_types[i];
|
||||
if (v.is_null()) {
|
||||
continue;
|
||||
}
|
||||
if (v->get_voxel_name() == name) {
|
||||
return i;
|
||||
}
|
||||
|
|
|
@ -84,7 +84,9 @@ private:
|
|||
static void _bind_methods();
|
||||
|
||||
private:
|
||||
std::vector<Ref<Voxel> > _voxel_types;
|
||||
// There can be null entries. A vector is used because there should be no more than 65,536 items,
|
||||
// and in practice the intented use case rarely goes over a few hundreds
|
||||
std::vector<Ref<Voxel>> _voxel_types;
|
||||
int _atlas_size = 16;
|
||||
bool _needs_baking = true;
|
||||
bool _bake_tangents = true;
|
||||
|
|
|
@ -207,6 +207,11 @@ Ref<ArrayMesh> VoxelMesherTransvoxel::build_transition_mesh(Ref<VoxelBuffer> vox
|
|||
|
||||
ERR_FAIL_COND_V(voxels.is_null(), Ref<ArrayMesh>());
|
||||
|
||||
if (voxels->is_uniform(VoxelBuffer::CHANNEL_SDF)) {
|
||||
// Uniform SDF won't produce any surface
|
||||
return Ref<ArrayMesh>();
|
||||
}
|
||||
|
||||
// TODO We need to output transition meshes through the generic interface, they are part of the result
|
||||
// For now we can't support proper texture indices in this specific case
|
||||
Transvoxel::DefaultTextureIndicesData default_texture_indices_data;
|
||||
|
|
|
@ -54,7 +54,7 @@ bool VoxelInstanceLibraryItem::is_persistent() const {
|
|||
}
|
||||
|
||||
void VoxelInstanceLibraryItem::set_mesh(Ref<Mesh> mesh, int mesh_lod_index) {
|
||||
ERR_FAIL_INDEX(mesh_lod_index, VoxelInstancer::MAX_LOD);
|
||||
ERR_FAIL_INDEX(mesh_lod_index, _mesh_lods.size());
|
||||
if (_mesh_lods[mesh_lod_index] == mesh) {
|
||||
return;
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ int VoxelInstanceLibraryItem::get_mesh_lod_count() const {
|
|||
}
|
||||
|
||||
Ref<Mesh> VoxelInstanceLibraryItem::get_mesh(int mesh_lod_index) const {
|
||||
ERR_FAIL_INDEX_V(mesh_lod_index, VoxelInstancer::MAX_LOD, Ref<Mesh>());
|
||||
ERR_FAIL_INDEX_V(mesh_lod_index, _mesh_lods.size(), Ref<Mesh>());
|
||||
return _mesh_lods[mesh_lod_index];
|
||||
}
|
||||
|
||||
|
@ -143,6 +143,8 @@ static VisualServer::ShadowCastingSetting node_to_visual_server_enum(GeometryIns
|
|||
}
|
||||
|
||||
void VoxelInstanceLibraryItem::setup_from_template(Node *root) {
|
||||
ERR_FAIL_COND(root == nullptr);
|
||||
|
||||
_collision_shapes.clear();
|
||||
|
||||
PhysicsBody *physics_body = Object::cast_to<PhysicsBody>(root);
|
||||
|
|
Loading…
Reference in New Issue