1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-07 12:30:27 +00:00

Consider gridmap collisions in navigation bake

This commit is contained in:
rafallus
2022-01-14 09:36:59 -06:00
parent 8958e1b352
commit cc46abd73d
4 changed files with 119 additions and 12 deletions

View File

@@ -265,14 +265,100 @@ void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transfor
}
#ifdef MODULE_GRIDMAP_ENABLED
if (Object::cast_to<GridMap>(p_node) && p_generate_from != NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS) {
GridMap *gridmap_instance = Object::cast_to<GridMap>(p_node);
Array meshes = gridmap_instance->get_meshes();
Transform3D xform = gridmap_instance->get_transform();
for (int i = 0; i < meshes.size(); i += 2) {
Ref<Mesh> mesh = meshes[i + 1];
if (mesh.is_valid()) {
_add_mesh(mesh, p_accumulated_transform * xform * (Transform3D)meshes[i], p_vertices, p_indices);
GridMap *gridmap = Object::cast_to<GridMap>(p_node);
if (gridmap) {
if (p_generate_from != NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS) {
Array meshes = gridmap->get_meshes();
Transform3D xform = gridmap->get_transform();
for (int i = 0; i < meshes.size(); i += 2) {
Ref<Mesh> mesh = meshes[i + 1];
if (mesh.is_valid()) {
_add_mesh(mesh, p_accumulated_transform * xform * (Transform3D)meshes[i], p_vertices, p_indices);
}
}
}
if (p_generate_from != NavigationMesh::PARSED_GEOMETRY_MESH_INSTANCES && (gridmap->get_collision_layer() & p_collision_mask)) {
Array shapes = gridmap->get_collision_shapes();
for (int i = 0; i < shapes.size(); i += 2) {
RID shape = shapes[i + 1];
PhysicsServer3D::ShapeType type = PhysicsServer3D::get_singleton()->shape_get_type(shape);
Variant data = PhysicsServer3D::get_singleton()->shape_get_data(shape);
Ref<Mesh> mesh;
switch (type) {
case PhysicsServer3D::SHAPE_SPHERE: {
real_t radius = data;
Ref<SphereMesh> sphere_mesh;
sphere_mesh.instantiate();
sphere_mesh->set_radius(radius);
sphere_mesh->set_height(radius * 2.0);
mesh = sphere_mesh;
} break;
case PhysicsServer3D::SHAPE_BOX: {
Vector3 extents = data;
Ref<BoxMesh> box_mesh;
box_mesh.instantiate();
box_mesh->set_size(2.0 * extents);
mesh = box_mesh;
} break;
case PhysicsServer3D::SHAPE_CAPSULE: {
Dictionary dict = data;
real_t radius = dict["radius"];
real_t height = dict["height"];
Ref<CapsuleMesh> capsule_mesh;
capsule_mesh.instantiate();
capsule_mesh->set_radius(radius);
capsule_mesh->set_height(height);
mesh = capsule_mesh;
} break;
case PhysicsServer3D::SHAPE_CYLINDER: {
Dictionary dict = data;
real_t radius = dict["radius"];
real_t height = dict["height"];
Ref<CylinderMesh> cylinder_mesh;
cylinder_mesh.instantiate();
cylinder_mesh->set_height(height);
cylinder_mesh->set_bottom_radius(radius);
cylinder_mesh->set_top_radius(radius);
mesh = cylinder_mesh;
} break;
case PhysicsServer3D::SHAPE_CONVEX_POLYGON: {
PackedVector3Array vertices = data;
Geometry3D::MeshData md;
Error err = ConvexHullComputer::convex_hull(vertices, md);
if (err == OK) {
PackedVector3Array faces;
for (int j = 0; j < md.faces.size(); ++j) {
Geometry3D::MeshData::Face face = md.faces[j];
for (int k = 2; k < face.indices.size(); ++k) {
faces.push_back(md.vertices[face.indices[0]]);
faces.push_back(md.vertices[face.indices[k - 1]]);
faces.push_back(md.vertices[face.indices[k]]);
}
}
_add_faces(faces, shapes[i], p_vertices, p_indices);
}
} break;
case PhysicsServer3D::SHAPE_CONCAVE_POLYGON: {
Dictionary dict = data;
PackedVector3Array faces = Variant(dict["faces"]);
_add_faces(faces, shapes[i], p_vertices, p_indices);
} break;
default: {
WARN_PRINT("Unsupported collision shape type.");
} break;
}
if (mesh.is_valid()) {
_add_mesh(mesh, shapes[i], p_vertices, p_indices);
}
}
}
}