Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.x] Use Bullet's convex hull computer in place of QuickHull when available. #47307

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions core/math/geometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

#include "geometry.h"

#include "core/math/quick_hull.h"
#include "core/print_string.h"

#include "thirdparty/misc/clipper.hpp"
Expand All @@ -39,6 +40,8 @@

#define SCALE_FACTOR 100000.0 // Based on CMP_EPSILON.

Geometry::ConvexHullFunc Geometry::convex_hull_function = NULL;
mortarroad marked this conversation as resolved.
Show resolved Hide resolved

// This implementation is very inefficient, commenting unless bugs happen. See the other one.
/*
bool Geometry::is_point_in_polygon(const Vector2 &p_point, const Vector<Vector2> &p_polygon) {
Expand Down Expand Up @@ -862,6 +865,13 @@ Geometry::MeshData Geometry::build_convex_mesh(const PoolVector<Plane> &p_planes
return mesh;
}

Error Geometry::build_convex_hull(const Vector<Vector3> &p_points, Geometry::MeshData &r_mesh) {
if (!convex_hull_function) {
return QuickHull::build(p_points, r_mesh);
}
return convex_hull_function(p_points, r_mesh);
}

PoolVector<Plane> Geometry::build_box_planes(const Vector3 &p_extents) {

PoolVector<Plane> planes;
Expand Down
4 changes: 4 additions & 0 deletions core/math/geometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -1037,6 +1037,7 @@ class Geometry {
static Vector<Vector<Vector2> > decompose_polygon_in_convex(Vector<Point2> polygon);

static MeshData build_convex_mesh(const PoolVector<Plane> &p_planes);
static Error build_convex_hull(const Vector<Vector3> &p_points, MeshData &r_mesh);
static PoolVector<Plane> build_sphere_planes(real_t p_radius, int p_lats, int p_lons, Vector3::Axis p_axis = Vector3::AXIS_Z);
static PoolVector<Plane> build_box_planes(const Vector3 &p_extents);
static PoolVector<Plane> build_cylinder_planes(real_t p_radius, real_t p_height, int p_sides, Vector3::Axis p_axis = Vector3::AXIS_Z);
Expand All @@ -1053,6 +1054,9 @@ class Geometry {

static Vector<Vector3> compute_convex_mesh_points(const Plane *p_planes, int p_plane_count);

typedef Error (*ConvexHullFunc)(const Vector<Vector3> &, MeshData &);
static ConvexHullFunc convex_hull_function;

private:
static Vector<Vector<Point2> > _polypaths_do_operation(PolyBooleanOperation p_op, const Vector<Point2> &p_polypath_a, const Vector<Point2> &p_polypath_b, bool is_a_open = false);
static Vector<Vector<Point2> > _polypath_offset(const Vector<Point2> &p_polypath, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type);
Expand Down
3 changes: 1 addition & 2 deletions editor/spatial_editor_gizmos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
#include "spatial_editor_gizmos.h"

#include "core/math/geometry.h"
#include "core/math/quick_hull.h"
#include "scene/3d/audio_stream_player_3d.h"
#include "scene/3d/baked_lightmap.h"
#include "scene/3d/collision_polygon.h"
Expand Down Expand Up @@ -3671,7 +3670,7 @@ void CollisionShapeSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {

Vector<Vector3> varr = Variant(points);
Geometry::MeshData md;
Error err = QuickHull::build(varr, md);
Error err = Geometry::build_convex_hull(varr, md);
if (err == OK) {
Vector<Vector3> points2;
points2.resize(md.edges.size() * 2);
Expand Down
3 changes: 1 addition & 2 deletions main/tests/test_physics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@

#include "core/map.h"
#include "core/math/math_funcs.h"
#include "core/math/quick_hull.h"
#include "core/os/main_loop.h"
#include "core/os/os.h"
#include "core/print_string.h"
Expand Down Expand Up @@ -176,7 +175,7 @@ class TestPhysicsMainLoop : public MainLoop {

RID convex_mesh = vs->mesh_create();
Geometry::MeshData convex_data = Geometry::build_convex_mesh(convex_planes);
QuickHull::build(convex_data.vertices, convex_data);
Geometry::build_convex_hull(convex_data.vertices, convex_data);
vs->mesh_add_surface_from_mesh_data(convex_mesh, convex_data);

type_mesh_map[PhysicsServer::SHAPE_CONVEX_POLYGON] = convex_mesh;
Expand Down
3 changes: 1 addition & 2 deletions main/tests/test_render.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
#include "test_render.h"

#include "core/math/math_funcs.h"
#include "core/math/quick_hull.h"
#include "core/os/keyboard.h"
#include "core/os/main_loop.h"
#include "core/os/os.h"
Expand Down Expand Up @@ -121,7 +120,7 @@ class TestMainLoop : public MainLoop {
vts.push_back(Vector3(-1, -1, -1));

Geometry::MeshData md;
Error err = QuickHull::build(vts, md);
Error err = Geometry::build_convex_hull(vts, md);
print_line("ERR: " + itos(err));
test_cube = vs->mesh_create();
vs->mesh_add_surface_from_mesh_data(test_cube, md);
Expand Down
3 changes: 1 addition & 2 deletions modules/recast/navigation_mesh_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
/*************************************************************************/

#include "navigation_mesh_generator.h"
#include "core/math/quick_hull.h"
#include "core/os/thread.h"
#include "editor/editor_settings.h"
#include "scene/3d/collision_shape.h"
Expand Down Expand Up @@ -217,7 +216,7 @@ void EditorNavigationMeshGenerator::_parse_geometry(Transform p_accumulated_tran
Vector<Vector3> varr = Variant(convex_polygon->get_points());
Geometry::MeshData md;

Error err = QuickHull::build(varr, md);
Error err = Geometry::build_convex_hull(varr, md);

if (err == OK) {
PoolVector3Array faces;
Expand Down
54 changes: 54 additions & 0 deletions modules/vhacd/register_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@
/*************************************************************************/

#include "register_types.h"
#include "core/math/geometry.h"
#include "scene/resources/mesh.h"
#include "thirdparty/vhacd/inc/btConvexHullComputer.h"
#include "thirdparty/vhacd/public/VHACD.h"

static Vector<Vector<Face3> > convex_decompose(const Vector<Face3> &p_faces) {
Expand Down Expand Up @@ -79,10 +81,62 @@ static Vector<Vector<Face3> > convex_decompose(const Vector<Face3> &p_faces) {
return ret;
}

static Error convex_hull(const Vector<Vector3> &p_points, Geometry::MeshData &r_mesh) {
// build the convex hull using the convex hull computer from bullet.
// simply copies the data over to Godot's types

r_mesh = Geometry::MeshData(); // clear

if (p_points.size() == 0) {
return FAILED; // matches QuickHull
}

VHACD::btConvexHullComputer ch;
ch.compute(&p_points.ptr()[0][0], sizeof(p_points.ptr()[0]), p_points.size(), -1.0, -1.0);

Geometry::MeshData ret;
r_mesh.vertices.resize(ch.vertices.size());
for (int i = 0; i < ch.vertices.size(); i++) {
r_mesh.vertices.write[i].x = ch.vertices[i].getX();
r_mesh.vertices.write[i].y = ch.vertices[i].getY();
r_mesh.vertices.write[i].z = ch.vertices[i].getZ();
}

r_mesh.edges.resize(ch.edges.size());
for (int i = 0; i < ch.edges.size(); i++) {
r_mesh.edges.write[i].a = (&ch.edges[i])->getSourceVertex();
r_mesh.edges.write[i].b = (&ch.edges[i])->getTargetVertex();
}

r_mesh.faces.resize(ch.faces.size());
for (int i = 0; i < ch.faces.size(); i++) {
const VHACD::btConvexHullComputer::Edge *e_start = &ch.edges[ch.faces[i]];
const VHACD::btConvexHullComputer::Edge *e = e_start;
Geometry::MeshData::Face &face = r_mesh.faces.write[i];

do {
face.indices.push_back(e->getTargetVertex());

e = e->getNextEdgeOfFace();
} while (e != e_start);

// compute normal
if (face.indices.size() >= 3) {
face.plane = Plane(r_mesh.vertices[face.indices[0]], r_mesh.vertices[face.indices[2]], r_mesh.vertices[face.indices[1]]);
} else {
WARN_PRINT("Too few vertices per face.");
}
}

return OK;
}

void register_vhacd_types() {
Mesh::convex_composition_function = convex_decompose;
Geometry::convex_hull_function = convex_hull;
}

void unregister_vhacd_types() {
Mesh::convex_composition_function = NULL;
Geometry::convex_hull_function = NULL;
}
4 changes: 2 additions & 2 deletions scene/resources/convex_polygon_shape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
/*************************************************************************/

#include "convex_polygon_shape.h"
#include "core/math/quick_hull.h"
#include "core/math/geometry.h"
#include "servers/physics_server.h"

Vector<Vector3> ConvexPolygonShape::get_debug_mesh_lines() {
Expand All @@ -40,7 +40,7 @@ Vector<Vector3> ConvexPolygonShape::get_debug_mesh_lines() {

Vector<Vector3> varr = Variant(points);
Geometry::MeshData md;
Error err = QuickHull::build(varr, md);
Error err = Geometry::build_convex_hull(varr, md);
if (err == OK) {
Vector<Vector3> lines;
lines.resize(md.edges.size() * 2);
Expand Down
5 changes: 2 additions & 3 deletions servers/physics/shape_sw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
#include "shape_sw.h"

#include "core/math/geometry.h"
#include "core/math/quick_hull.h"
#include "core/sort_array.h"

#define _EDGE_IS_VALID_SUPPORT_THRESHOLD 0.0002
Expand Down Expand Up @@ -1149,9 +1148,9 @@ Vector3 ConvexPolygonShapeSW::get_moment_of_inertia(real_t p_mass) const {

void ConvexPolygonShapeSW::_setup(const Vector<Vector3> &p_vertices) {

Error err = QuickHull::build(p_vertices, mesh);
Error err = Geometry::build_convex_hull(p_vertices, mesh);
if (err != OK)
ERR_PRINT("Failed to build QuickHull");
ERR_PRINT("Failed to build convex hull");

AABB _aabb;

Expand Down