Skip to content

Commit

Permalink
Use Bullet's convex hull computer in place of QuickHull when available.
Browse files Browse the repository at this point in the history
  • Loading branch information
mortarroad committed Mar 25, 2021
1 parent ed1f5c2 commit 7f0a8c6
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 13 deletions.
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;

// 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

0 comments on commit 7f0a8c6

Please sign in to comment.