mirror of
https://github.com/godotengine/godot.git
synced 2025-01-18 16:01:31 +00:00
Merge pull request #32863 from JFonS/navmesh_from_group
Add option to create navmesh from objects in group
This commit is contained in:
commit
f5dd4d574f
@ -107,6 +107,10 @@
|
||||
</member>
|
||||
<member name="geometry/parsed_geometry_type" type="int" setter="set_parsed_geometry_type" getter="get_parsed_geometry_type" default="0">
|
||||
</member>
|
||||
<member name="geometry/source_geometry_mode" type="int" setter="set_source_geometry_mode" getter="get_source_geometry_mode" default="0">
|
||||
</member>
|
||||
<member name="geometry/source_group_name" type="String" setter="set_source_group_name" getter="get_source_group_name">
|
||||
</member>
|
||||
<member name="polygon/verts_per_poly" type="float" setter="set_verts_per_poly" getter="get_verts_per_poly" default="6.0">
|
||||
</member>
|
||||
<member name="region/merge_size" type="float" setter="set_region_merge_size" getter="get_region_merge_size" default="20.0">
|
||||
|
@ -131,7 +131,7 @@ void EditorNavigationMeshGenerator::_add_faces(const PoolVector3Array &p_faces,
|
||||
}
|
||||
}
|
||||
|
||||
void EditorNavigationMeshGenerator::_parse_geometry(Transform p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, int p_generate_from, uint32_t p_collision_mask) {
|
||||
void EditorNavigationMeshGenerator::_parse_geometry(Transform p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, int p_generate_from, uint32_t p_collision_mask, bool p_recurse_children) {
|
||||
|
||||
if (Object::cast_to<MeshInstance>(p_node) && p_generate_from != NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS) {
|
||||
|
||||
@ -263,8 +263,10 @@ void EditorNavigationMeshGenerator::_parse_geometry(Transform p_accumulated_tran
|
||||
p_accumulated_transform = p_accumulated_transform * spatial->get_transform();
|
||||
}
|
||||
|
||||
for (int i = 0; i < p_node->get_child_count(); i++) {
|
||||
_parse_geometry(p_accumulated_transform, p_node->get_child(i), p_verticies, p_indices, p_generate_from, p_collision_mask);
|
||||
if (p_recurse_children) {
|
||||
for (int i = 0; i < p_node->get_child_count(); i++) {
|
||||
_parse_geometry(p_accumulated_transform, p_node->get_child(i), p_verticies, p_indices, p_generate_from, p_collision_mask, p_recurse_children);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -439,7 +441,21 @@ void EditorNavigationMeshGenerator::bake(Ref<NavigationMesh> p_nav_mesh, Node *p
|
||||
Vector<float> vertices;
|
||||
Vector<int> indices;
|
||||
|
||||
_parse_geometry(Object::cast_to<Spatial>(p_node)->get_transform().affine_inverse(), p_node, vertices, indices, p_nav_mesh->get_parsed_geometry_type(), p_nav_mesh->get_collision_mask());
|
||||
List<Node *> parse_nodes;
|
||||
|
||||
if (p_nav_mesh->get_source_geometry_mode() == NavigationMesh::SOURCE_GEOMETRY_NAVMESH_CHILDREN) {
|
||||
parse_nodes.push_back(p_node);
|
||||
} else {
|
||||
p_node->get_tree()->get_nodes_in_group(p_nav_mesh->get_source_group_name(), &parse_nodes);
|
||||
}
|
||||
|
||||
Transform navmesh_xform = Object::cast_to<Spatial>(p_node)->get_transform().affine_inverse();
|
||||
for (const List<Node *>::Element *E = parse_nodes.front(); E; E = E->next()) {
|
||||
int geometry_type = p_nav_mesh->get_parsed_geometry_type();
|
||||
uint32_t collision_mask = p_nav_mesh->get_collision_mask();
|
||||
bool recurse_children = p_nav_mesh->get_source_geometry_mode() != NavigationMesh::SOURCE_GEOMETRY_GROUPS_EXPLICIT;
|
||||
_parse_geometry(navmesh_xform, E->get(), vertices, indices, geometry_type, collision_mask, recurse_children);
|
||||
}
|
||||
|
||||
if (vertices.size() > 0 && indices.size() > 0) {
|
||||
|
||||
|
@ -47,7 +47,7 @@ protected:
|
||||
static void _add_vertex(const Vector3 &p_vec3, Vector<float> &p_verticies);
|
||||
static void _add_mesh(const Ref<Mesh> &p_mesh, const Transform &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices);
|
||||
static void _add_faces(const PoolVector3Array &p_faces, const Transform &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices);
|
||||
static void _parse_geometry(Transform p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, int p_generate_from, uint32_t p_collision_mask);
|
||||
static void _parse_geometry(Transform p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, int p_generate_from, uint32_t p_collision_mask, bool p_recurse_children);
|
||||
|
||||
static void _convert_detail_mesh_to_native_navigation_mesh(const rcPolyMeshDetail *p_detail_mesh, Ref<NavigationMesh> p_nav_mesh);
|
||||
static void _build_recast_navigation_mesh(Ref<NavigationMesh> p_nav_mesh, EditorProgress *ep,
|
||||
|
@ -108,6 +108,24 @@ bool NavigationMesh::get_collision_mask_bit(int p_bit) const {
|
||||
return get_collision_mask() & (1 << p_bit);
|
||||
}
|
||||
|
||||
void NavigationMesh::set_source_geometry_mode(int p_geometry_mode) {
|
||||
ERR_FAIL_INDEX(p_geometry_mode, SOURCE_GEOMETRY_MAX);
|
||||
source_geometry_mode = static_cast<SourceGeometryMode>(p_geometry_mode);
|
||||
_change_notify();
|
||||
}
|
||||
|
||||
int NavigationMesh::get_source_geometry_mode() const {
|
||||
return source_geometry_mode;
|
||||
}
|
||||
|
||||
void NavigationMesh::set_source_group_name(StringName p_group_name) {
|
||||
source_group_name = p_group_name;
|
||||
}
|
||||
|
||||
StringName NavigationMesh::get_source_group_name() const {
|
||||
return source_group_name;
|
||||
}
|
||||
|
||||
void NavigationMesh::set_cell_size(float p_value) {
|
||||
cell_size = p_value;
|
||||
}
|
||||
@ -387,6 +405,12 @@ void NavigationMesh::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_collision_mask_bit", "bit", "value"), &NavigationMesh::set_collision_mask_bit);
|
||||
ClassDB::bind_method(D_METHOD("get_collision_mask_bit", "bit"), &NavigationMesh::get_collision_mask_bit);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_source_geometry_mode", "mask"), &NavigationMesh::set_source_geometry_mode);
|
||||
ClassDB::bind_method(D_METHOD("get_source_geometry_mode"), &NavigationMesh::get_source_geometry_mode);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_source_group_name", "mask"), &NavigationMesh::set_source_group_name);
|
||||
ClassDB::bind_method(D_METHOD("get_source_group_name"), &NavigationMesh::get_source_group_name);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_cell_size", "cell_size"), &NavigationMesh::set_cell_size);
|
||||
ClassDB::bind_method(D_METHOD("get_cell_size"), &NavigationMesh::get_cell_size);
|
||||
|
||||
@ -462,6 +486,8 @@ void NavigationMesh::_bind_methods() {
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "sample_partition_type/sample_partition_type", PROPERTY_HINT_ENUM, "Watershed,Monotone,Layers"), "set_sample_partition_type", "get_sample_partition_type");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "geometry/parsed_geometry_type", PROPERTY_HINT_ENUM, "Mesh Instances,Static Colliders,Both"), "set_parsed_geometry_type", "get_parsed_geometry_type");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "geometry/collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "geometry/source_geometry_mode", PROPERTY_HINT_ENUM, "Navmesh Children, Group With Children, Group Explicit"), "set_source_geometry_mode", "get_source_geometry_mode");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "geometry/source_group_name"), "set_source_group_name", "get_source_group_name");
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "cell/size", PROPERTY_HINT_RANGE, "0.1,1.0,0.01,or_greater"), "set_cell_size", "get_cell_size");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "cell/height", PROPERTY_HINT_RANGE, "0.1,1.0,0.01,or_greater"), "set_cell_height", "get_cell_height");
|
||||
@ -489,6 +515,13 @@ void NavigationMesh::_validate_property(PropertyInfo &property) const {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (property.name == "geometry/source_group_name") {
|
||||
if (source_geometry_mode == SOURCE_GEOMETRY_NAVMESH_CHILDREN) {
|
||||
property.usage = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NavigationMesh::NavigationMesh() {
|
||||
@ -509,6 +542,8 @@ NavigationMesh::NavigationMesh() {
|
||||
partition_type = SAMPLE_PARTITION_WATERSHED;
|
||||
parsed_geometry_type = PARSED_GEOMETRY_MESH_INSTANCES;
|
||||
collision_mask = 0xFFFFFFFF;
|
||||
source_geometry_mode = SOURCE_GEOMETRY_NAVMESH_CHILDREN;
|
||||
source_group_name = "navmesh";
|
||||
filter_low_hanging_obstacles = false;
|
||||
filter_ledge_spans = false;
|
||||
filter_walkable_low_height_spans = false;
|
||||
|
@ -77,6 +77,13 @@ public:
|
||||
PARSED_GEOMETRY_MAX
|
||||
};
|
||||
|
||||
enum SourceGeometryMode {
|
||||
SOURCE_GEOMETRY_NAVMESH_CHILDREN = 0,
|
||||
SOURCE_GEOMETRY_GROUPS_WITH_CHILDREN,
|
||||
SOURCE_GEOMETRY_GROUPS_EXPLICIT,
|
||||
SOURCE_GEOMETRY_MAX
|
||||
};
|
||||
|
||||
protected:
|
||||
float cell_size;
|
||||
float cell_height;
|
||||
@ -96,6 +103,9 @@ protected:
|
||||
ParsedGeometryType parsed_geometry_type;
|
||||
uint32_t collision_mask;
|
||||
|
||||
SourceGeometryMode source_geometry_mode;
|
||||
StringName source_group_name;
|
||||
|
||||
bool filter_low_hanging_obstacles;
|
||||
bool filter_ledge_spans;
|
||||
bool filter_walkable_low_height_spans;
|
||||
@ -114,6 +124,12 @@ public:
|
||||
void set_collision_mask_bit(int p_bit, bool p_value);
|
||||
bool get_collision_mask_bit(int p_bit) const;
|
||||
|
||||
void set_source_geometry_mode(int p_source_mode);
|
||||
int get_source_geometry_mode() const;
|
||||
|
||||
void set_source_group_name(StringName p_group_name);
|
||||
StringName get_source_group_name() const;
|
||||
|
||||
void set_cell_size(float p_value);
|
||||
float get_cell_size() const;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user