-
Notifications
You must be signed in to change notification settings - Fork 23
Expand file tree
/
Copy pathbounding_box.h
More file actions
274 lines (236 loc) · 10 KB
/
bounding_box.h
File metadata and controls
274 lines (236 loc) · 10 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
/* -----------------------------------------------------------------------------
* Copyright 2022 Massachusetts Institute of Technology.
* All Rights Reserved
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Research was sponsored by the United States Air Force Research Laboratory and
* the United States Air Force Artificial Intelligence Accelerator and was
* accomplished under Cooperative Agreement Number FA8750-19-2-1000. The views
* and conclusions contained in this document are those of the authors and should
* not be interpreted as representing the official policies, either expressed or
* implied, of the United States Air Force or the U.S. Government. The U.S.
* Government is authorized to reproduce and distribute reprints for Government
* purposes notwithstanding any copyright notation herein.
* -------------------------------------------------------------------------- */
#pragma once
#include <Eigen/Geometry>
#include "spark_dsg/spark_dsg_fwd.h"
namespace spark_dsg {
/**
* @brief Union of AABB, RAABB, and OBB bounding box formats. Can directly be extracted
* from point-cloud data if needed.
*/
struct BoundingBox {
// Types.
/**
* @brief type of bounding box (defaults to AABB)
*/
enum class Type : int32_t {
INVALID = 0, /**< an invalid bounding box */
AABB = 1, /**< an axis-aligned bounding box */
OBB = 2, /**< an oriented bounding box */
RAABB = 3 /**< a (yaw-adjusted) axis-aligned bounding box */
};
/**
* Interface to lookup points to allow fitting a bounding box to a set of points.
*/
struct PointAdaptor {
virtual size_t size() const = 0;
virtual Eigen::Vector3f get(size_t index) const = 0;
Eigen::Vector3f operator[](size_t index) const { return get(index); }
};
// Constructors.
/**
* @brief Construct an INVALID (unitialized) bounding box.
*/
BoundingBox() = default;
/**
* @brief Construct an AABB bounding box from only an extent.
* @param dimensions The dimensions of the bounding box along each axis.
*/
explicit BoundingBox(const Eigen::Vector3f& dimensions);
/**
* @brief Construct an AABB bounding box in world coordinate frame.
* @param dimensions The dimensions of the bounding box along each axis.
* @param world_P_center The center of the bounding box in world coordinates.
*/
BoundingBox(const Eigen::Vector3f& dimensions, const Eigen::Vector3f& world_P_center);
/**
* @brief Construct an RAABB bounding box from min and max points in world coordinate.
* frame.
* @param dimensions The dimensions of the bounding box along each axis.
* @param world_P_center The center of the bounding box in world coordinates.
* @param yaw The yaw angle of the bounding box in radians.
*/
BoundingBox(const Eigen::Vector3f& dimensions,
const Eigen::Vector3f& world_P_center,
float yaw);
/**
* @brief Construct an OBB bounding box.
* @param dimensions The dimensions of the bounding box along each axis.
* @param world_P_center The center of the bounding box in world coordinates.
* @param world_R_center The orientation of the bounding box in world coordinates.
*/
BoundingBox(const Eigen::Vector3f& dimensions,
const Eigen::Vector3f& world_P_center,
const Eigen::Quaternionf& world_R_center);
/**
* @brief Construct an arbitrary bounding box.
* @param type The type of the bounding box.
* @param dimensions The dimensions of the bounding box along each axis.
* @param world_P_center The center of the bounding box in world coordinates.
* @param world_R_center The orientation of the bounding box in world coordinates.
*/
BoundingBox(BoundingBox::Type type,
const Eigen::Vector3f& dimensions,
const Eigen::Vector3f& world_P_center,
const Eigen::Matrix3f& world_R_center);
/**
* @brief Fit a bounding box of a given type to a set of points in world coordinates.
* @param points Adaptor to lookup the points to fit the bounding box to.
* @param type The type of bounding box to fit. Defaults to AABB.
*/
explicit BoundingBox(const PointAdaptor& points,
BoundingBox::Type type = BoundingBox::Type::AABB);
/**
* @brief Fit a bounding box of a given type to a set of points in world coordinates.
* @param points Points to fit the bounding box to.
* @param type The type of bounding box to fit. Defaults to AABB.
*/
explicit BoundingBox(const std::vector<Eigen::Vector3f>& points,
BoundingBox::Type type = BoundingBox::Type::AABB);
/**
* @brief Fit a bounding box of a given type to a mesh in world coordinates.
* @param mesh Adaptor to lookup the points to fit the bounding box to.
* @param type The type of bounding box to fit. Defaults to AABB.
*/
explicit BoundingBox(const Mesh& mesh,
BoundingBox::Type type = BoundingBox::Type::AABB);
virtual ~BoundingBox() = default;
// Operators.
bool operator==(const BoundingBox& other) const;
bool operator!=(const BoundingBox& other) const { return !(*this == other); }
operator bool() const { return isValid(); }
// Bounding box properties.
/**
* @brief Check if a bounding box is setup properly (i.e., it must have positive
* volume).
*/
bool isValid() const;
/**
* @brief Get the volume of the bounding box in m3.
*/
float volume() const;
/**
* @brief Returns true if the bounding box has a non-identity rotation.
*/
bool hasRotation() const;
/**
* @brief Get all corners of the bounding box in world frame.
*/
std::array<Eigen::Vector3f, 8> corners() const;
// Bounding box operations.
/**
* @brief Merge this bounding box with another bounding box, computing a bounding box
* that contains both.
*/
void merge(const BoundingBox& other);
// Bounding box inference.
/**
* @brief Transform a point from world frame to bounding box frame.
* @param point_W The point to transform in world coordinates.
* @returns The point in bounding box coordinates.
*/
Eigen::Vector3f pointToWorldFrame(const Eigen::Vector3f& point_B) const;
/**
* @brief Transform a point from bounding box frame to world frame.
* @param point_B The point to transform in bounding box coordinates.
* @returns The point in world coordinates.
*/
Eigen::Vector3f pointToBoxFrame(const Eigen::Vector3f& point_W) const;
/**
* @brief Check whether this bounding box contains the given point in world
* coordinates.
*/
bool contains(const Eigen::Vector3f& point) const;
bool contains(const Eigen::Vector3d& point) const;
// Bounding box comparisons.
/**
* @brief Check whether this bounding box intersects with another bounding box.
* @note Currently only supports AABB-AABB intersection.
*/
bool intersects(const BoundingBox& other) const;
/**
* @brief Compute the intersection over union (IoU) of this bounding box with another.
* @note Currently only supports AABB-AABB intersection.
*/
float computeIoU(const BoundingBox& other) const;
/**
* @brief Transform the bounding box.
* @param transform The transform to apply.
*/
void transform(const Eigen::Isometry3d& transform);
/**
* @brief output bounding box information
* @param out output stream
* @param bounding_box bounding box to print
* @returns original output stream
*/
friend std::ostream& operator<<(std::ostream& out, const BoundingBox& bounding_box);
// Properties.
// Type of the current bounding box.
Type type = Type::INVALID;
//! Dimensions along each axis.
Eigen::Vector3f dimensions = Eigen::Vector3f::Zero();
//! Position of the bounding box center in world frame.
Eigen::Vector3f world_P_center = Eigen::Vector3f::Zero();
//! World orientation (only for OBB)
Eigen::Matrix3f world_R_center = Eigen::Matrix3f::Identity();
protected:
/**
* @brief Check whether a point is inside the bounding box.
* @param point_B The point to check in bounding box coordinates.
*/
bool isInside(const Eigen::Vector3f& point_B) const;
void mergeAABB(const BoundingBox& other);
void mergeGeneral(const BoundingBox& other);
// Min and max corners of an AABB in world frame.
Eigen::Vector3f minCorner() const;
Eigen::Vector3f maxCorner() const;
public:
// Specialized point adaptors.
struct MeshAdaptor : PointAdaptor {
MeshAdaptor(const Mesh& mesh, const std::vector<size_t>* indices = nullptr);
size_t size() const override;
Eigen::Vector3f get(size_t index) const override;
const Mesh& mesh;
const std::vector<size_t>* indices;
};
struct PointVectorAdaptor : PointAdaptor {
PointVectorAdaptor(const std::vector<Eigen::Vector3f>& points);
size_t size() const override;
Eigen::Vector3f get(size_t index) const override;
const std::vector<Eigen::Vector3f>& points;
};
};
} // namespace spark_dsg