diff --git a/godot-cpp b/godot-cpp index 21d526e..a62f633 160000 --- a/godot-cpp +++ b/godot-cpp @@ -1 +1 @@ -Subproject commit 21d526e5e5b1e5d8b6be4db05a704c2c2e7837a9 +Subproject commit a62f633cebee4b36356dc903d00670733cd28fb1 diff --git a/src/RecastNavMesh.cpp b/src/RecastNavMesh.cpp index 0bb2cf0..a97070d 100644 --- a/src/RecastNavMesh.cpp +++ b/src/RecastNavMesh.cpp @@ -1,4 +1,5 @@ #include "RecastNavMesh.hpp" +#include godot::RecastNavMesh::RecastNavMesh() { } @@ -44,6 +45,18 @@ void godot::RecastNavMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("get_walkable_height"), &RecastNavMesh::get_walkable_height); ADD_PROPERTY(PropertyInfo(Variant::INT, "walkable_height"), "set_walkable_height", "get_walkable_height"); + ClassDB::bind_method(D_METHOD("set_filter_low_hanging_obstacles", "filter_low_hanging_obstacles"), &RecastNavMesh::set_filter_low_hanging_obstacles); + ClassDB::bind_method(D_METHOD("get_filter_low_hanging_obstacles"), &RecastNavMesh::get_filter_low_hanging_obstacles); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter_low_hanging_obstacles"), "set_filter_low_hanging_obstacles", "get_filter_low_hanging_obstacles"); + + ClassDB::bind_method(D_METHOD("set_filter_ledge_spans", "filter_ledge_spans"), &RecastNavMesh::set_filter_ledge_spans); + ClassDB::bind_method(D_METHOD("get_filter_ledge_spans"), &RecastNavMesh::get_filter_ledge_spans); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter_ledge_spans"), "set_filter_ledge_spans", "get_filter_ledge_spans"); + + ClassDB::bind_method(D_METHOD("set_filter_walkable_low_height_spans", "filter_walkable_low_height_spans"), &RecastNavMesh::set_filter_walkable_low_height_spans); + ClassDB::bind_method(D_METHOD("get_filter_walkable_low_height_spans"), &RecastNavMesh::get_filter_walkable_low_height_spans); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter_walkable_low_height_spans"), "set_filter_walkable_low_height_spans", "get_filter_walkable_low_height_spans"); + ClassDB::bind_method(D_METHOD("set_walkable_climb", "walkable_climb"), &RecastNavMesh::set_walkable_climb); ClassDB::bind_method(D_METHOD("get_walkable_climb"), &RecastNavMesh::get_walkable_climb); ADD_PROPERTY(PropertyInfo(Variant::INT, "walkable_climb"), "set_walkable_climb", "get_walkable_climb"); diff --git a/src/RecastNavMesh.hpp b/src/RecastNavMesh.hpp index 9ee04a3..9db28e6 100644 --- a/src/RecastNavMesh.hpp +++ b/src/RecastNavMesh.hpp @@ -7,134 +7,148 @@ namespace godot { - enum RecastPartitionType { - WATERSHED = 0, - MONOTONE, - LAYERS, - PARTITION_TYPE_COUNT - }; +enum RecastPartitionType { + WATERSHED = 0, + MONOTONE, + LAYERS, + PARTITION_TYPE_COUNT +}; - class RecastNavMesh : public Node3D { - GDCLASS(RecastNavMesh, Node3D) - private: - bool m_calculated = false; - rcConfig config; - RecastPartitionType partition_type = WATERSHED; - rcHeightfield* m_heightfield = NULL; - protected: - static void _bind_methods(); - public: - RecastNavMesh(); - ~RecastNavMesh(); - // config +class RecastNavMesh : public Node3D { + GDCLASS(RecastNavMesh, Node3D) +private: + bool m_calculated = false; + bool filter_low_hanging_obstacles = false; + bool filter_ledge_spans = false; + bool filter_walkable_low_height_spans = false; - /// The width of the field along the x-axis. [Limit: >= 0] [Units: vx] - int get_width() { return config.width; } - /// The height of the field along the z-axis. [Limit: >= 0] [Units: vx] - int get_height() { return config.height; } - /// The width/height size of tile's on the xz-plane. [Limit: >= 0] [Units: vx] - void set_tile_size(float tile_size) { config.tileSize = tile_size; } - float get_tile_size() { return config.tileSize; } - /// The size of the non-navigable border around the heightfield. [Limit: >=0] [Units: vx] - void set_border_size(int border_size) { config.borderSize = border_size; } - int get_border_size() { return config.borderSize; } - /// The xz-plane cell size to use for fields. [Limit: > 0] [Units: wu] - void set_cs(float cs) { - config.cs = cs; - // update width & height of the grid - rcCalcGridSize(config.bmin, config.bmax, config.cs, &config.width, &config.height); - } - float get_cs() { return config.cs; } - /// The y-axis cell size to use for fields. [Limit: > 0] [Units: wu] - void set_ch(float ch) { config.ch = ch; } - float get_ch() { return config.ch; } - /// The minimum bounds of the field's AABB. [(x, y, z)] [Units: wu] - void set_bmin(const Vector3& bmin) { - // Vector3 can be float or double precision, but Recast expects float - config.bmin[0] = bmin.x; - config.bmin[1] = bmin.y; - config.bmin[2] = bmin.z; - // update width & height of the grid - rcCalcGridSize(config.bmin, config.bmax, config.cs, &config.width, &config.height); - } - Vector3 get_bmin() { - return Vector3(config.bmin[0], config.bmin[1], config.bmin[2]); - } - /// The maximum bounds of the field's AABB. [(x, y, z)] [Units: wu] - void set_bmax(const Vector3& bmax) { - config.bmax[0] = bmax.x; - config.bmax[1] = bmax.y; - config.bmax[2] = bmax.z; - // update width & height of the grid - rcCalcGridSize(config.bmin, config.bmax, config.cs, &config.width, &config.height); - } - Vector3 get_bmax() { - return Vector3(config.bmax[0], config.bmax[1], config.bmax[2]); - } - /// The maximum slope that is considered walkable. [Limits: 0 <= value < 90] [Units: Degrees] - void set_walkable_slope_angle(float walkable_slope_angle) { config.walkableSlopeAngle = walkable_slope_angle; } - float get_walkable_slope_angle() { return config.walkableSlopeAngle; } - /// Minimum floor to 'ceiling' height that will still allow the floor area to - /// be considered walkable. [Limit: >= 3] [Units: vx] - void set_walkable_height(float walkable_height) { config.walkableHeight = walkable_height; } - float get_walkable_height() { return config.walkableHeight; } - /// Maximum ledge height that is considered to still be traversable. [Limit: >=0] [Units: vx] - void set_walkable_climb(float walkable_climb) { config.walkableClimb = walkable_climb; } - float get_walkable_climb() { return config.walkableClimb; } - /// The distance to erode/shrink the walkable area of the heightfield away from - /// obstructions. [Limit: >=0] [Units: vx] - void set_walkable_radius(float walkable_radius) { config.walkableRadius = walkable_radius; } - float get_walkable_radius() { return config.walkableRadius; } - /// The maximum allowed length for contour edges along the border of the mesh. [Limit: >=0] [Units: vx] - void set_max_edge_len(int max_edge_len) { config.maxEdgeLen = max_edge_len; } - int get_max_edge_len() { return config.maxEdgeLen; } - /// The maximum distance a simplified contour's border edges should deviate - /// the original raw contour. [Limit: >=0] [Units: vx] - void set_max_simplification_error(float max_simplification_error) { config.maxSimplificationError = max_simplification_error; } - float get_max_simplification_error() { return config.maxSimplificationError; } - /// The minimum number of cells allowed to form isolated island areas. [Limit: >=0] [Units: vx] - void set_min_region_area(int min_region_area) { config.minRegionArea = min_region_area; } - int get_min_region_area() { return config.minRegionArea; } - /// Any regions with a span count smaller than this value will, if possible, - /// be merged with larger regions. [Limit: >=0] [Units: vx] - void set_merge_region_area(int merge_region_area) { config.mergeRegionArea = merge_region_area; } - int get_merge_region_area() { return config.mergeRegionArea; } - /// The maximum number of vertices allowed for polygons generated during the - /// contour to polygon conversion process. [Limit: >= 3] - void set_max_verts_per_poly(int max_verts_per_poly) { config.maxVertsPerPoly = max_verts_per_poly; } - int get_max_verts_per_poly() { return config.maxVertsPerPoly; } - /// Sets the sampling distance to use when generating the detail mesh. - /// (For height detail only.) [Limits: 0 or >= 0.9] [Units: wu] - void set_detail_sample_dist(float detail_sample_dist) { config.detailSampleDist = detail_sample_dist; } - float get_detail_sample_dist() { return config.detailSampleDist; } - /// The maximum distance the detail mesh surface should deviate from heightfield - /// data. (For height detail only.) [Limit: >=0] [Units: wu] - void set_detail_sample_max_error(float detail_sample_max_error) { config.detailSampleMaxError = detail_sample_max_error; } - float get_detail_sample_max_error() { return config.detailSampleMaxError; } - /// The partition type to use for the heightfield. - /// - /// Allowed values are: - /// - WATERSHED - /// - MONOTONE - /// - LAYERS - /// - /// Any other value will lead to no change in the partition type. - void set_partition_type(int partition_type) { - if((partition_type >= 0) && (partition_type < PARTITION_TYPE_COUNT)) { - this->partition_type = (RecastPartitionType)partition_type; - } - } - int get_partition_type() { - return (int)partition_type; - } - - // Recast - bool init(); - void cleanup(); - void clear_vertices(); - void add_vertices(PackedByteArray vertices, unsigned char area_id); - bool recalculate_navmesh(); - bool is_calculated() { return m_calculated; } - }; + rcConfig config; + RecastPartitionType partition_type = WATERSHED; + + rcHeightfield* m_heightfield = NULL; + rcCompactHeightfield* m_compact_heightfield = NULL; +protected: + static void _bind_methods(); +public: + RecastNavMesh(); + ~RecastNavMesh(); + // config + + /// The width of the field along the x-axis. [Limit: >= 0] [Units: vx] + int get_width() { return config.width; } + /// The height of the field along the z-axis. [Limit: >= 0] [Units: vx] + int get_height() { return config.height; } + /// The width/height size of tile's on the xz-plane. [Limit: >= 0] [Units: vx] + void set_tile_size(float tile_size) { config.tileSize = tile_size; } + float get_tile_size() { return config.tileSize; } + /// The size of the non-navigable border around the heightfield. [Limit: >=0] [Units: vx] + void set_border_size(int border_size) { config.borderSize = border_size; } + int get_border_size() { return config.borderSize; } + /// The xz-plane cell size to use for fields. [Limit: > 0] [Units: wu] + void set_cs(float cs) { + config.cs = cs; + // update width & height of the grid + rcCalcGridSize(config.bmin, config.bmax, config.cs, &config.width, &config.height); + } + float get_cs() { return config.cs; } + /// The y-axis cell size to use for fields. [Limit: > 0] [Units: wu] + void set_ch(float ch) { config.ch = ch; } + float get_ch() { return config.ch; } + /// The minimum bounds of the field's AABB. [(x, y, z)] [Units: wu] + void set_bmin(const Vector3& bmin) { + // Vector3 can be float or double precision, but Recast expects float + config.bmin[0] = bmin.x; + config.bmin[1] = bmin.y; + config.bmin[2] = bmin.z; + // update width & height of the grid + rcCalcGridSize(config.bmin, config.bmax, config.cs, &config.width, &config.height); + } + Vector3 get_bmin() { + return Vector3(config.bmin[0], config.bmin[1], config.bmin[2]); + } + /// The maximum bounds of the field's AABB. [(x, y, z)] [Units: wu] + void set_bmax(const Vector3& bmax) { + config.bmax[0] = bmax.x; + config.bmax[1] = bmax.y; + config.bmax[2] = bmax.z; + // update width & height of the grid + rcCalcGridSize(config.bmin, config.bmax, config.cs, &config.width, &config.height); + } + Vector3 get_bmax() { + return Vector3(config.bmax[0], config.bmax[1], config.bmax[2]); + } + + void set_filter_low_hanging_obstacles(bool filter_low_hanging_obstacles) { this->filter_low_hanging_obstacles = filter_low_hanging_obstacles; } + bool get_filter_low_hanging_obstacles() { return filter_low_hanging_obstacles; } + void set_filter_ledge_spans(bool filter_ledge_spans) { this->filter_ledge_spans = filter_ledge_spans; } + bool get_filter_ledge_spans() { return filter_ledge_spans; } + void set_filter_walkable_low_height_spans(bool filter_walkable_low_height_spans) { this->filter_walkable_low_height_spans = filter_walkable_low_height_spans; } + bool get_filter_walkable_low_height_spans() { return filter_walkable_low_height_spans; } + + /// The maximum slope that is considered walkable. [Limits: 0 <= value < 90] [Units: Degrees] + void set_walkable_slope_angle(float walkable_slope_angle) { config.walkableSlopeAngle = walkable_slope_angle; } + float get_walkable_slope_angle() { return config.walkableSlopeAngle; } + /// Minimum floor to 'ceiling' height that will still allow the floor area to + /// be considered walkable. [Limit: >= 3] [Units: vx] + void set_walkable_height(float walkable_height) { config.walkableHeight = walkable_height; } + float get_walkable_height() { return config.walkableHeight; } + /// Maximum ledge height that is considered to still be traversable. [Limit: >=0] [Units: vx] + void set_walkable_climb(float walkable_climb) { config.walkableClimb = walkable_climb; } + float get_walkable_climb() { return config.walkableClimb; } + /// The distance to erode/shrink the walkable area of the heightfield away from + /// obstructions. [Limit: >=0] [Units: vx] + void set_walkable_radius(float walkable_radius) { config.walkableRadius = walkable_radius; } + float get_walkable_radius() { return config.walkableRadius; } + /// The maximum allowed length for contour edges along the border of the mesh. [Limit: >=0] [Units: vx] + void set_max_edge_len(int max_edge_len) { config.maxEdgeLen = max_edge_len; } + int get_max_edge_len() { return config.maxEdgeLen; } + /// The maximum distance a simplified contour's border edges should deviate + /// the original raw contour. [Limit: >=0] [Units: vx] + void set_max_simplification_error(float max_simplification_error) { config.maxSimplificationError = max_simplification_error; } + float get_max_simplification_error() { return config.maxSimplificationError; } + /// The minimum number of cells allowed to form isolated island areas. [Limit: >=0] [Units: vx] + void set_min_region_area(int min_region_area) { config.minRegionArea = min_region_area; } + int get_min_region_area() { return config.minRegionArea; } + /// Any regions with a span count smaller than this value will, if possible, + /// be merged with larger regions. [Limit: >=0] [Units: vx] + void set_merge_region_area(int merge_region_area) { config.mergeRegionArea = merge_region_area; } + int get_merge_region_area() { return config.mergeRegionArea; } + /// The maximum number of vertices allowed for polygons generated during the + /// contour to polygon conversion process. [Limit: >= 3] + void set_max_verts_per_poly(int max_verts_per_poly) { config.maxVertsPerPoly = max_verts_per_poly; } + int get_max_verts_per_poly() { return config.maxVertsPerPoly; } + /// Sets the sampling distance to use when generating the detail mesh. + /// (For height detail only.) [Limits: 0 or >= 0.9] [Units: wu] + void set_detail_sample_dist(float detail_sample_dist) { config.detailSampleDist = detail_sample_dist; } + float get_detail_sample_dist() { return config.detailSampleDist; } + /// The maximum distance the detail mesh surface should deviate from heightfield + /// data. (For height detail only.) [Limit: >=0] [Units: wu] + void set_detail_sample_max_error(float detail_sample_max_error) { config.detailSampleMaxError = detail_sample_max_error; } + float get_detail_sample_max_error() { return config.detailSampleMaxError; } + /// The partition type to use for the heightfield. + /// + /// Allowed values are: + /// - WATERSHED + /// - MONOTONE + /// - LAYERS + /// + /// Any other value will lead to no change in the partition type. + void set_partition_type(int partition_type) { + if((partition_type >= 0) && (partition_type < PARTITION_TYPE_COUNT)) { + this->partition_type = (RecastPartitionType)partition_type; + } + } + int get_partition_type() { + return (int)partition_type; + } +public: + // Recast + bool init(); + void cleanup(); + void clear_vertices(); + void add_vertices(PackedByteArray vertices, unsigned char area_id); + bool recalculate_navmesh(); + bool is_calculated() { return m_calculated; } +}; }