37 #ifndef HPP_FCL_HEIGHT_FIELD_H 38 #define HPP_FCL_HEIGHT_FIELD_H 72 max_height(std::numeric_limits<
FCL_REAL>::lowest()) {}
77 x_size == other.
x_size && y_id == other.
y_id &&
86 inline bool isLeaf()
const {
return x_size == 1 && y_size == 1; }
90 inline size_t leftChild()
const {
return first_child; }
94 inline size_t rightChild()
const {
return first_child + 1; }
97 return Eigen::Vector2i(x_id, y_id);
100 return Eigen::Vector2i(x_id + x_size / 2, y_id + y_size / 2);
104 template <
typename BV>
113 return Base::operator==(other) && bv == other.
bv;
123 FCL_REAL& sqrDistLowerBound)
const {
124 return bv.overlap(other.
bv, request, sqrDistLowerBound);
131 return bv.distance(other.
bv,
P1,
P2);
139 static const Matrix3f id3 = Matrix3f::Identity();
146 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
152 template <
typename BV>
155 AABB bv_aabb(pointA, pointB);
165 AABB bv_aabb(pointA, pointB);
181 template <
typename BV>
187 typedef std::vector<Node>
BVS;
192 min_height((std::numeric_limits<
FCL_REAL>::min)()),
193 max_height((std::numeric_limits<
FCL_REAL>::max)()) {}
209 init(x_dim, y_dim, heights, min_height);
220 heights(other.heights),
221 min_height(other.min_height),
222 max_height(other.max_height),
223 x_grid(other.x_grid),
224 y_grid(other.y_grid),
226 num_bvs(other.num_bvs) {}
254 const Vec3f A(x_grid[0], y_grid[0], min_height);
255 const Vec3f B(x_grid[x_grid.size() - 1], y_grid[y_grid.size() - 1],
257 const AABB aabb_(A,
B);
259 aabb_radius = (A -
B).norm() / 2.;
261 aabb_center = aabb_.center();
266 if (new_heights.rows() != heights.rows() ||
267 new_heights.cols() != heights.cols())
269 "The matrix containing the new heights values does not have the same " 270 "matrix size as the original one.\n" 271 "\tinput values - rows: " 272 << new_heights.rows() <<
" - cols: " << new_heights.cols() <<
"\n" 273 <<
"\texpected values - rows: " << heights.rows()
274 <<
" - cols: " << heights.cols() <<
"\n",
275 std::invalid_argument);
277 heights = new_heights.cwiseMax(min_height);
278 this->max_height = recursiveUpdateHeight(0);
279 assert(this->max_height == heights.maxCoeff());
287 this->heights = heights.cwiseMax(min_height);
288 this->min_height = min_height;
289 this->max_height = heights.maxCoeff();
291 const Eigen::DenseIndex NX = heights.cols(), NY = heights.rows();
292 assert(NX >= 2 &&
"The number of columns is too small.");
293 assert(NY >= 2 &&
"The number of rows is too small.");
295 x_grid = VecXf::LinSpaced(NX, -0.5 * x_dim, 0.5 * x_dim);
296 y_grid = VecXf::LinSpaced(NY, 0.5 * y_dim, -0.5 * y_dim);
299 const size_t num_tot_bvs =
300 (size_t)(NX * NY) - 1 + (size_t)((NX - 1) * (NY - 1));
301 bvs.resize(num_tot_bvs);
339 const FCL_REAL max_recursive_height =
340 recursiveBuildTree(0, 0, heights.cols() - 1, 0, heights.rows() - 1);
341 assert(max_recursive_height == max_height &&
342 "the maximal height is not correct");
354 max_height = heights.block<2, 2>(bv_node.
y_id, bv_node.
x_id).maxCoeff();
357 max_left_height = recursiveUpdateHeight(bv_node.
leftChild()),
358 max_right_height = recursiveUpdateHeight(bv_node.
rightChild());
360 max_height = (std::max)(max_left_height, max_right_height);
365 const Vec3f pointA(x_grid[bv_node.
x_id], y_grid[bv_node.
y_id], min_height);
367 y_grid[bv_node.
y_id + bv_node.
y_size], max_height);
375 const Eigen::DenseIndex x_size,
376 const Eigen::DenseIndex y_id,
377 const Eigen::DenseIndex y_size) {
378 assert(x_id < heights.cols() &&
"x_id is out of bounds");
379 assert(y_id < heights.rows() &&
"y_id is out of bounds");
380 assert(x_size >= 0 && y_size >= 0 &&
381 "x_size or y_size are not of correct value");
382 assert(bv_id < bvs.size() &&
"bv_id exceeds the vector dimension");
389 max_height = heights.block<2, 2>(y_id, x_id).maxCoeff();
394 FCL_REAL max_left_height = min_height, max_right_height = min_height;
395 if (x_size >= y_size)
397 Eigen::DenseIndex x_size_half = x_size / 2;
398 if (x_size == 1) x_size_half = 1;
399 max_left_height = recursiveBuildTree(bv_node.leftChild(), x_id,
400 x_size_half, y_id, y_size);
403 recursiveBuildTree(bv_node.rightChild(), x_id + x_size_half,
404 x_size - x_size_half, y_id, y_size);
407 Eigen::DenseIndex y_size_half = y_size / 2;
408 if (y_size == 1) y_size_half = 1;
409 max_left_height = recursiveBuildTree(bv_node.leftChild(), x_id, x_size,
413 recursiveBuildTree(bv_node.rightChild(), x_id, x_size,
414 y_id + y_size_half, y_size - y_size_half);
417 max_height = (std::max)(max_left_height, max_right_height);
420 bv_node.max_height = max_height;
423 const Vec3f pointA(x_grid[x_id], y_grid[y_id], min_height);
424 assert(x_id + x_size < x_grid.size());
425 assert(y_id + y_size < y_grid.size());
426 const Vec3f pointB(x_grid[x_id + x_size], y_grid[y_id + y_size],
432 bv_node.x_size = x_size;
433 bv_node.y_size = y_size;
459 if (other_ptr ==
nullptr)
return false;
462 return x_dim == other.
x_dim && y_dim == other.
y_dim &&
465 y_grid == other.
y_grid && bvs == other.
bvs &&
470 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
bool overlap(const HFNode &other) const
Check whether two BVNode collide.
FCL_REAL getYDim() const
Returns the dimension of the Height Field along the Y direction.
Eigen::Matrix< FCL_REAL, Eigen::Dynamic, Eigen::Dynamic > MatrixXf
Matrix3f computeMomentofInertia() const
compute the inertia matrix, related to the origin
bool operator!=(const HFNodeBase &other) const
Difference operator.
HeightField(const FCL_REAL x_dim, const FCL_REAL y_dim, const MatrixXf &heights, const FCL_REAL min_height=(FCL_REAL) 0)
Constructing an HeightField from its base dimensions and the set of heights points. The granularity of the height field along X and Y direction is extraded from the Z grid.
OBJECT_TYPE
object type: BVH (mesh, points), basic geometry, octree
OBJECT_TYPE getObjectType() const
Get the object type: it is a HFIELD.
virtual bool isEqual(const CollisionGeometry &_other) const
equal operator with another object of derived type.
virtual HeightField< BV > * clone() const
Clone *this into a new CollisionGeometry.
FCL_REAL min_height
Minimal height of the Height Field: all values bellow min_height will be discarded.
bool operator==(const HFNode &other) const
Equality operator.
Eigen::Matrix< FCL_REAL, Eigen::Dynamic, 1 > VecXf
bool operator!=(const HFNode &other) const
Difference operator.
FCL_REAL distance(const HFNode &other, Vec3f *P1=NULL, Vec3f *P2=NULL) const
Compute the distance between two BVNode. P1 and P2, if not NULL and the underlying BV supports distan...
Eigen::Matrix< FCL_REAL, 3, 3 > Matrix3f
FCL_REAL getXDim() const
Returns the dimension of the Height Field along the X direction.
FCL_REAL computeVolume() const
compute the volume
bool operator==(const HFNodeBase &other) const
Comparison operator.
void computeLocalAABB()
Compute the AABB for the HeightField, used for broad-phase collision.
BV bv
bounding volume storing the geometry
const VecXf & getXGrid() const
Returns a const reference of the grid along the X direction.
static void run(const Vec3f &pointA, const Vec3f &pointB, AABB &bv)
virtual ~HeightField()
deconstruction, delete mesh data related.
Data structure depicting a height field given by the base grid dimensions and the elevation along the...
Vec3f computeCOM() const
compute center of mass
FCL_REAL getMaxHeight() const
Returns the maximal height value of the Height Field.
BVS bvs
Bounding volume hierarchy.
Eigen::Vector2i rightChildIndexes() const
request to the collision algorithm
const VecXf & getYGrid() const
Returns a const reference of the grid along the Y direction.
#define HPP_FCL_UNUSED_VARIABLE(var)
size_t first_child
An index for first child node or primitive If the value is positive, it is the index of the first chi...
void init(const FCL_REAL x_dim, const FCL_REAL y_dim, const MatrixXf &heights, const FCL_REAL min_height)
size_t leftChild() const
Return the index of the first child. The index is referred to the bounding volume array (i...
A class describing the AABB collision structure, which is a box in 3D space determined by two diagona...
NODE_TYPE getNodeType() const
Get the BV type: default is unknown.
const MatrixXf & getHeights() const
Returns a const reference of the heights.
const HFNode< BV > & getBV(unsigned int i) const
Access the bv giving the its index.
HFNodeBase()
Default constructor.
Vec3f getCenter() const
Access to the center of the BV.
NODE_TYPE
traversal node type: bounding volume (AABB, OBB, RSS, kIOS, OBBRSS, KDOP16, KDOP18, kDOP24), basic shape (box, sphere, ellipsoid, capsule, cone, cylinder, convex, plane, triangle), and octree
VecXf x_grid
Grids along the X and Y directions. Useful for plotting or other related things.
void updateHeights(const MatrixXf &new_heights)
Update Height Field height.
FCL_REAL getMinHeight() const
Returns the minimal height value of the Height Field.
FCL_REAL recursiveBuildTree(const size_t bv_id, const Eigen::DenseIndex x_id, const Eigen::DenseIndex x_size, const Eigen::DenseIndex y_id, const Eigen::DenseIndex y_size)
Eigen::Vector2i leftChildIndexes() const
MatrixXf heights
Elevation values in meters of the Height Field.
size_t rightChild() const
Return the index of the second child. The index is referred to the bounding volume array (i...
HeightField(const HeightField &other)
Copy contructor from another HeightField.
int buildTree()
Build the bounding volume hierarchy.
static void run(const Vec3f &pointA, const Vec3f &pointB, BV &bv)
const Matrix3f & getOrientation() const
Access to the orientation of the BV.
FCL_REAL x_dim
Dimensions in meters along X and Y directions.
Eigen::Matrix< FCL_REAL, 3, 1 > Vec3f
static void convertBV(const BV1 &bv1, const Transform3f &tf1, BV2 &bv2)
Convert a bounding volume of type BV1 in configuration tf1 to bounding volume of type BV2 in identity...
HFNode< BV > & getBV(unsigned int i)
Access the bv giving the its index.
The geometry for the object for collision or distance computation.
bool isLeaf() const
Whether current node is a leaf node (i.e. contains a primitive index)
HeightField()
Constructing an empty HeightField.
FCL_REAL recursiveUpdateHeight(const size_t bv_id)
#define HPP_FCL_THROW_PRETTY(message, exception)
bool overlap(const HFNode &other, const CollisionRequest &request, FCL_REAL &sqrDistLowerBound) const
Check whether two BVNode collide.