Consider gridmap collisions in navigation bake
This commit is contained in:
parent
8958e1b352
commit
cc46abd73d
@ -67,7 +67,7 @@
|
|||||||
Returns whether or not the specified layer of the [member collision_mask] is enabled, given a [code]layer_number[/code] between 1 and 32.
|
Returns whether or not the specified layer of the [member collision_mask] is enabled, given a [code]layer_number[/code] between 1 and 32.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="get_meshes">
|
<method name="get_meshes" qualifiers="const">
|
||||||
<return type="Array" />
|
<return type="Array" />
|
||||||
<description>
|
<description>
|
||||||
Returns an array of [Transform3D] and [Mesh] references corresponding to the non-empty cells in the grid. The transforms are specified in world space.
|
Returns an array of [Transform3D] and [Mesh] references corresponding to the non-empty cells in the grid. The transforms are specified in world space.
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include "scene/3d/light_3d.h"
|
#include "scene/3d/light_3d.h"
|
||||||
#include "scene/resources/mesh_library.h"
|
#include "scene/resources/mesh_library.h"
|
||||||
#include "scene/resources/physics_material.h"
|
#include "scene/resources/physics_material.h"
|
||||||
|
#include "scene/resources/primitive_meshes.h"
|
||||||
#include "scene/resources/surface_tool.h"
|
#include "scene/resources/surface_tool.h"
|
||||||
#include "scene/scene_string_names.h"
|
#include "scene/scene_string_names.h"
|
||||||
#include "servers/navigation_server_3d.h"
|
#include "servers/navigation_server_3d.h"
|
||||||
@ -197,6 +198,24 @@ bool GridMap::get_collision_mask_value(int p_layer_number) const {
|
|||||||
return get_collision_mask() & (1 << (p_layer_number - 1));
|
return get_collision_mask() & (1 << (p_layer_number - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Array GridMap::get_collision_shapes() const {
|
||||||
|
Array shapes;
|
||||||
|
for (const KeyValue<OctantKey, Octant *> &E : octant_map) {
|
||||||
|
Octant *g = E.value;
|
||||||
|
RID body = g->static_body;
|
||||||
|
Transform3D body_xform = PhysicsServer3D::get_singleton()->body_get_state(body, PhysicsServer3D::BODY_STATE_TRANSFORM);
|
||||||
|
int nshapes = PhysicsServer3D::get_singleton()->body_get_shape_count(body);
|
||||||
|
for (int i = 0; i < nshapes; i++) {
|
||||||
|
RID shape = PhysicsServer3D::get_singleton()->body_get_shape(body, i);
|
||||||
|
Transform3D xform = PhysicsServer3D::get_singleton()->body_get_shape_transform(body, i);
|
||||||
|
shapes.push_back(body_xform * xform);
|
||||||
|
shapes.push_back(shape);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return shapes;
|
||||||
|
}
|
||||||
|
|
||||||
void GridMap::set_bake_navigation(bool p_bake_navigation) {
|
void GridMap::set_bake_navigation(bool p_bake_navigation) {
|
||||||
bake_navigation = p_bake_navigation;
|
bake_navigation = p_bake_navigation;
|
||||||
_recreate_octant_data();
|
_recreate_octant_data();
|
||||||
@ -930,7 +949,7 @@ Array GridMap::get_used_cells() const {
|
|||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
Array GridMap::get_meshes() {
|
Array GridMap::get_meshes() const {
|
||||||
if (mesh_library.is_null()) {
|
if (mesh_library.is_null()) {
|
||||||
return Array();
|
return Array();
|
||||||
}
|
}
|
||||||
@ -938,7 +957,7 @@ Array GridMap::get_meshes() {
|
|||||||
Vector3 ofs = _get_offset();
|
Vector3 ofs = _get_offset();
|
||||||
Array meshes;
|
Array meshes;
|
||||||
|
|
||||||
for (KeyValue<IndexKey, Cell> &E : cell_map) {
|
for (const KeyValue<IndexKey, Cell> &E : cell_map) {
|
||||||
int id = E.value.item;
|
int id = E.value.item;
|
||||||
if (!mesh_library->has_item(id)) {
|
if (!mesh_library->has_item(id)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -229,6 +229,8 @@ public:
|
|||||||
void set_physics_material(Ref<PhysicsMaterial> p_material);
|
void set_physics_material(Ref<PhysicsMaterial> p_material);
|
||||||
Ref<PhysicsMaterial> get_physics_material() const;
|
Ref<PhysicsMaterial> get_physics_material() const;
|
||||||
|
|
||||||
|
Array get_collision_shapes() const;
|
||||||
|
|
||||||
void set_bake_navigation(bool p_bake_navigation);
|
void set_bake_navigation(bool p_bake_navigation);
|
||||||
bool is_baking_navigation();
|
bool is_baking_navigation();
|
||||||
|
|
||||||
@ -265,7 +267,7 @@ public:
|
|||||||
|
|
||||||
Array get_used_cells() const;
|
Array get_used_cells() const;
|
||||||
|
|
||||||
Array get_meshes();
|
Array get_meshes() const;
|
||||||
|
|
||||||
void clear_baked_meshes();
|
void clear_baked_meshes();
|
||||||
void make_baked_meshes(bool p_gen_lightmap_uv = false, float p_lightmap_uv_texel_size = 0.1);
|
void make_baked_meshes(bool p_gen_lightmap_uv = false, float p_lightmap_uv_texel_size = 0.1);
|
||||||
|
@ -265,14 +265,100 @@ void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transfor
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MODULE_GRIDMAP_ENABLED
|
#ifdef MODULE_GRIDMAP_ENABLED
|
||||||
if (Object::cast_to<GridMap>(p_node) && p_generate_from != NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS) {
|
GridMap *gridmap = Object::cast_to<GridMap>(p_node);
|
||||||
GridMap *gridmap_instance = Object::cast_to<GridMap>(p_node);
|
|
||||||
Array meshes = gridmap_instance->get_meshes();
|
if (gridmap) {
|
||||||
Transform3D xform = gridmap_instance->get_transform();
|
if (p_generate_from != NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS) {
|
||||||
for (int i = 0; i < meshes.size(); i += 2) {
|
Array meshes = gridmap->get_meshes();
|
||||||
Ref<Mesh> mesh = meshes[i + 1];
|
Transform3D xform = gridmap->get_transform();
|
||||||
if (mesh.is_valid()) {
|
for (int i = 0; i < meshes.size(); i += 2) {
|
||||||
_add_mesh(mesh, p_accumulated_transform * xform * (Transform3D)meshes[i], p_vertices, p_indices);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user