Skip to content

Commit fd12217

Browse files
Broadphase implementation (#77)
* Broadphase implementation * Bug fix and made template for priority queue in BVH * Addressed comments from PR review * Bug fix * Addressed review comments * Addressed PR comments
1 parent ed03290 commit fd12217

9 files changed

Lines changed: 4033 additions & 88 deletions

File tree

‎blast/blast‎

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
#include <cstdint>
66
#include <cstring>
77
#include <iostream>
8-
#include <vector>
8+
#include <queue>
99
#include <tuple>
10+
#include <vector>
1011

1112
namespace blast {
1213

@@ -22,11 +23,11 @@ constexpr int32_t MAX_CAPSULES = BLAST_MAX_CAPSULES;
2223
constexpr int32_t MAX_CAPSULES = 7;
2324
#endif
2425

25-
using u8 = uint8_t;
26+
using u8 = uint8_t;
2627
using u16 = uint16_t;
2728
using u32 = uint32_t;
2829
using u64 = uint64_t;
29-
using i8 = int8_t;
30+
using i8 = int8_t;
3031
using i16 = int16_t;
3132
using i32 = int32_t;
3233
using i64 = int64_t;
@@ -90,11 +91,12 @@ using i64 = int64_t;
9091
#include "blast_containers.hpp"
9192
#include "blast_utilities.hpp"
9293

93-
#include "blast_task.hpp"
94-
#include "blast_world.hpp"
9594
#include "blast_manipulator.hpp"
95+
#include "blast_task.hpp"
96+
9697
#include "blast_optimization.hpp"
9798
#include "blast_trajectory.hpp"
99+
#include "blast_world.hpp"
98100

99101
#include "utilities/file_io.hpp"
100102
#include "utilities/is_close.hpp"

‎blast/blast_optimization.hpp‎

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ enum class OptimizationMethod : u32 {
8383
baseline, // point-based constraints, finite-difference gradients
8484
with_analytical_pva, // point-based, analytical gradients for position/velocity/acceleration
8585
with_analytical_dynamics, // point-based, analytical gradients for PVA + torque dynamics
86+
broadphase,
87+
double_broadphase,
8688
};
8789

8890
struct ConstraintSelection {
@@ -117,11 +119,14 @@ struct Optimization {
117119
Objective objective;
118120
Matrix task;
119121
World world;
120-
real trajectory_start_time = 0.0;
121-
real success_tolerance = 0.01; // constraint violation after optimization that is still considered a success
122-
int max_tries = 1; // Maximum number of tries in the optimization loop.
123-
int max_eval = 1000; // Maximum number of function evaluations for a single NLopt call.
124-
real max_time = 30.0; // Maximum time (seconds) for a single NLopt call.
122+
123+
std::array<BoundingVolumeHierarchy<AABBPair>, MAX_CAPSULES> time_bounding_volume_hierarchies; // should be std::array<> ? Never changes size
124+
125+
real trajectory_start_time = 0.0;
126+
real success_tolerance = 0.01; // constraint violation after optimization that is still considered a success
127+
int max_tries = 1; // Maximum number of tries in the optimization loop.
128+
int max_eval = 1000; // Maximum number of function evaluations for a single NLopt call.
129+
real max_time = 30.0; // Maximum time (seconds) for a single NLopt call.
125130

126131
void* custom_data;
127132

@@ -147,9 +152,17 @@ struct Optimization {
147152

148153
inline void constraints_and_gradients_with_segments(const Array& x, Optimization& opt, Array& constraints,
149154
Matrix& grad);
155+
inline void constraints_and_gradients_with_broadphase(const Array& x, Optimization& opt, Array& constraints,
156+
Matrix& grad);
157+
inline void constraints_and_gradients_with_double_broadphase(const Array& x, Optimization& opt, Array& constraints,
158+
Matrix& grad);
150159
// inline void compute_constraints_with_segments(const Array& x, Optimization& opt, Array& constraints);
151160
inline void nlopt_constraints_with_segments(unsigned m, real* result, unsigned x_len, const real* x, real* grad,
152161
void* f_data);
162+
inline void nlopt_constraints_with_broadphase(unsigned m, real* result, unsigned x_len, const real* x, real* grad,
163+
void* f_data);
164+
inline void nlopt_constraints_with_double_broadphase(unsigned m, real* result, unsigned x_len, const real* x, real* grad,
165+
void* f_data);
153166

154167
inline void compute_constraints(real* result, const Array& x, Optimization* opt);
155168
inline void nlopt_constraints(unsigned m, real* result, unsigned x_len, const real* x, real* grad,

‎blast/blast_world.hpp‎

Lines changed: 145 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -13,51 +13,10 @@ struct DynamicBox;
1313
struct DynamicSphere;
1414
struct DynamicCapsule;
1515
struct DynamicDoor;
16+
struct AxisAlignedBoundingBox;
17+
template<typename T>
18+
struct BoundingVolumeHierarchy;
1619

17-
struct World {
18-
std::vector<Box> boxes;
19-
std::vector<Sphere> spheres;
20-
std::vector<Capsule> capsules;
21-
std::vector<DynamicBox> dynamic_boxes;
22-
std::vector<DynamicSphere> dynamic_spheres;
23-
std::vector<DynamicCapsule> dynamic_capsules;
24-
std::vector<DynamicDoor> dynamic_doors;
25-
u32 size = 0;
26-
27-
host_fn void add_box(const Box& box);
28-
host_fn void add_box(Vec3 center_point, Vec3 half_width, Mat3 rotation_matrix);
29-
30-
host_fn void add_sphere(const Sphere& sphere);
31-
host_fn void add_sphere(Vec3 center_point, real radius);
32-
33-
host_fn void add_capsule(const Capsule& capsule);
34-
host_fn void add_capsule(Vec3 point1, Vec3 point2, real radius);
35-
36-
host_fn void add_dynamic_box(const DynamicBox& box);
37-
host_fn void add_dynamic_box(const std::vector<Box>& new_boxes, u32 n_points, real start_time, real end_time);
38-
39-
host_fn void add_dynamic_sphere(const DynamicSphere& sphere);
40-
host_fn void add_dynamic_sphere(const std::vector<Sphere>& new_spheres, u32 n_points, real start_time, real end_time);
41-
42-
host_fn void add_dynamic_capsule(const DynamicCapsule& capsule);
43-
host_fn void add_dynamic_capsule(const std::vector<Capsule>& new_capsules, u32 n_points, real start_time, real end_time);
44-
};
45-
46-
struct CollisionModel {
47-
std::vector<Box> boxes;
48-
std::vector<Sphere> spheres;
49-
std::vector<Capsule> capsules;
50-
u32 size = 0;
51-
52-
host_fn void add_box(const Box& box);
53-
host_fn void add_box(Vec3 center_point, Vec3 half_width, Mat3 rotation_matrix);
54-
55-
host_fn void add_sphere(const Sphere& sphere);
56-
host_fn void add_sphere(Vec3 center_point, real radius);
57-
58-
host_fn void add_capsule(const Capsule& capsule);
59-
host_fn void add_capsule(Vec3 point1, Vec3 point2, real radius);
60-
};
6120

6221
struct PointCloud {
6322
Vec3 position;
@@ -122,6 +81,146 @@ struct DynamicDoor {
12281
inline blast_fn Box lookup(real t) const;
12382
};
12483

84+
enum class CollisionObjectType {
85+
box,
86+
sphere,
87+
capsule,
88+
aabb,
89+
door,
90+
};
91+
struct CollisionEntities {
92+
CollisionObjectType other_object_type = CollisionObjectType::box;
93+
union {
94+
Box box{};
95+
Sphere sphere;
96+
Capsule capsule;
97+
};
98+
99+
int point_in_segment = 0;
100+
};
101+
102+
struct AxisAlignedBoundingBox {
103+
104+
Vec3 center{};
105+
Vec3 extents{};
106+
size_t children[2];
107+
CollisionObjectType child_type = CollisionObjectType::aabb;
108+
const void* child_ptr = nullptr;
109+
int point_in_segment = -1;
110+
real dist = 0.0;
111+
};
112+
113+
struct AABBPair {
114+
int aabb_obj;
115+
int aabb_cap;
116+
real dist;
117+
};
118+
119+
struct Compare {
120+
const std::vector<AxisAlignedBoundingBox>* leaves = nullptr;
121+
122+
bool operator()(int id1, int id2) const {
123+
return (*leaves)[id1].dist > (*leaves)[id2].dist;
124+
}
125+
126+
bool operator()(const AABBPair& a, const AABBPair& b) const {
127+
return a.dist > b.dist;
128+
}
129+
};
130+
template<typename T = int>
131+
struct BoundingVolumeHierarchy {
132+
133+
std::vector<AxisAlignedBoundingBox> leaves{};
134+
135+
int root = -1;
136+
int num_objects = 0;
137+
real time = 0.0;
138+
139+
struct PriorityQueue : public std::priority_queue<T, std::vector<T>, Compare> {
140+
PriorityQueue(const std::vector<AxisAlignedBoundingBox>* leaves_ptr = nullptr) :
141+
std::priority_queue<T, std::vector<T>, Compare>(Compare{leaves_ptr}) {}
142+
143+
void clear_and_reserve(size_t capacity) {
144+
this->c.clear(); // Clears elements without deallocating vector capacity
145+
this->c.reserve(capacity); // Ensures internal buffer is pre-allocated
146+
}
147+
void rebind(const std::vector<AxisAlignedBoundingBox>* leaves_ptr) {
148+
this->c.clear();
149+
this->comp = Compare{leaves_ptr};
150+
}
151+
};
152+
PriorityQueue queue{&leaves};
153+
154+
BoundingVolumeHierarchy() :
155+
queue(&leaves) {}
156+
157+
// Ensure copy/move operations rebind the comparator's pointer to the local leaves vector
158+
BoundingVolumeHierarchy(const BoundingVolumeHierarchy& other) :
159+
leaves(other.leaves),
160+
root(other.root),
161+
num_objects(other.num_objects),
162+
time(other.time),
163+
queue(&leaves) {}
164+
165+
BoundingVolumeHierarchy& operator=(const BoundingVolumeHierarchy& other) {
166+
if (this != &other) {
167+
leaves = other.leaves;
168+
root = other.root;
169+
num_objects = other.num_objects;
170+
time = other.time;
171+
queue.rebind(&leaves);
172+
}
173+
return *this;
174+
}
175+
};
176+
177+
struct World {
178+
std::vector<Box> boxes;
179+
std::vector<Sphere> spheres;
180+
std::vector<Capsule> capsules;
181+
std::vector<DynamicBox> dynamic_boxes;
182+
std::vector<DynamicSphere> dynamic_spheres;
183+
std::vector<DynamicCapsule> dynamic_capsules;
184+
std::vector<DynamicDoor> dynamic_doors;
185+
BoundingVolumeHierarchy<int> static_bounding_volume_hierarchy;
186+
BoundingVolumeHierarchy<int> dynamic_bounding_volume_hierarchy;
187+
u32 size = 0;
188+
// ...
189+
host_fn void add_box(const Box& box);
190+
host_fn void add_box(Vec3 center_point, Vec3 half_width, Mat3 rotation_matrix);
191+
192+
host_fn void add_sphere(const Sphere& sphere);
193+
host_fn void add_sphere(Vec3 center_point, real radius);
194+
195+
host_fn void add_capsule(const Capsule& capsule);
196+
host_fn void add_capsule(Vec3 point1, Vec3 point2, real radius);
197+
198+
host_fn void add_dynamic_box(const DynamicBox& box);
199+
host_fn void add_dynamic_box(const std::vector<Box>& new_boxes, u32 n_points, real start_time, real end_time);
200+
201+
host_fn void add_dynamic_sphere(const DynamicSphere& sphere);
202+
host_fn void add_dynamic_sphere(const std::vector<Sphere>& new_spheres, u32 n_points, real start_time, real end_time);
203+
204+
host_fn void add_dynamic_capsule(const DynamicCapsule& capsule);
205+
host_fn void add_dynamic_capsule(const std::vector<Capsule>& new_capsules, u32 n_points, real start_time, real end_time);
206+
};
207+
208+
struct CollisionModel {
209+
std::vector<Box> boxes;
210+
std::vector<Sphere> spheres;
211+
std::vector<Capsule> capsules;
212+
u32 size = 0;
213+
214+
host_fn void add_box(const Box& box);
215+
host_fn void add_box(Vec3 center_point, Vec3 half_width, Mat3 rotation_matrix);
216+
217+
host_fn void add_sphere(const Sphere& sphere);
218+
host_fn void add_sphere(Vec3 center_point, real radius);
219+
220+
host_fn void add_capsule(const Capsule& capsule);
221+
host_fn void add_capsule(Vec3 point1, Vec3 point2, real radius);
222+
};
223+
125224
/**
126225
* @struct CollisionModelCapsule
127226
* @brief Simple capsule primitive for collision checking.
@@ -146,6 +245,7 @@ inline blast_fn real distance(const Capsule& capsule1, const Capsule& capsule2);
146245
inline blast_fn real distance(const Capsule& capsule, const Vec3& point);
147246
inline blast_fn real distance(const Box& box, const Vec3& point);
148247
inline blast_fn real distance(const Sphere& sphere, const Vec3& point);
248+
inline blast_fn real distance(const AxisAlignedBoundingBox& aabb1, const AxisAlignedBoundingBox& aabb2);
149249

150250
inline blast_fn Vec3 get_point(const Array& x, const Matrix& capsule_list);
151251

@@ -162,6 +262,7 @@ inline blast_fn Vec3 get_point(const Array& x, const Matrix& capsule_list);
162262
#include "world/dynamicsphere.hpp"
163263

164264
#include "world/CoDO.hpp"
265+
#include "world/broadphase.hpp"
165266

166267
#include "world/scenes.hpp"
167268

0 commit comments

Comments
 (0)