DART  6.7.3
HeightmapShape-impl.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2019, The DART development contributors
3  * All rights reserved.
4  *
5  * The list of contributors can be found at:
6  * https://github.com/dartsim/dart/blob/master/LICENSE
7  *
8  * This file is provided under the following "BSD-style" License:
9  * Redistribution and use in source and binary forms, with or
10  * without modification, are permitted provided that the following
11  * conditions are met:
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/or other materials provided
17  * with the distribution.
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
34 
35 #include <algorithm>
36 #include <cmath>
37 #include <limits>
38 #include "dart/common/Console.hpp"
40 
41 namespace dart {
42 namespace dynamics {
43 
44 //==============================================================================
45 template <typename S>
46 HeightmapShape<S>::HeightmapShape() : Shape(HEIGHTMAP), mScale(1, 1, 1)
47 {
48  static_assert(
49  std::is_same<S, float>::value || std::is_same<S, double>::value,
50  "Height field needs to be double or float");
51 }
52 
53 //==============================================================================
54 template <typename S>
55 const std::string& HeightmapShape<S>::getType() const
56 {
57  return getStaticType();
58 }
59 
60 //==============================================================================
61 template <typename S>
63 {
64  static const std::string type
65  = "HeightmapShape (" + std::string(typeid(S).name()) + ")";
66  return type;
67 }
68 
69 //==============================================================================
70 template <typename S>
71 void HeightmapShape<S>::setScale(const Eigen::Vector3d& scale)
72 {
73  assert(scale[0] > 0.0);
74  assert(scale[1] > 0.0);
75  assert(scale[2] > 0.0);
76  mScale = scale;
77  mIsBoundingBoxDirty = true;
78  mIsVolumeDirty = true;
79 
80  incrementVersion();
81 }
82 
83 //==============================================================================
84 template <typename S>
85 const Eigen::Vector3d& HeightmapShape<S>::getScale() const
86 {
87  return mScale;
88 }
89 
90 //==============================================================================
91 template <typename S>
93  const std::size_t& width,
94  const std::size_t& depth,
95  const std::vector<S>& heights)
96 {
97  assert(heights.size() == width * depth);
98  if ((width * depth) != heights.size())
99  {
100  dterr << "Size of height field needs to be width*depth=" << width * depth
101  << std::endl;
102  return;
103  }
104  if (heights.empty())
105  {
106  dtwarn << "Empty height field makes no sense." << std::endl;
107  return;
108  }
109  mHeights = HeightField(depth, width);
110  for (size_t r = 0; r < depth; ++r)
111  {
112  for (size_t c = 0; c < width; ++c)
113  {
114  mHeights(r, c) = heights[r * width + c];
115  }
116  }
117 
118  // compute minimum and maximum height
119  mMinHeight = std::numeric_limits<S>::max();
120  mMaxHeight = -std::numeric_limits<S>::max();
121  for (auto it = heights.begin(); it != heights.end(); ++it)
122  {
123  if (*it < mMinHeight)
124  mMinHeight = *it;
125  if (*it > mMaxHeight)
126  mMaxHeight = *it;
127  }
128  mIsBoundingBoxDirty = true;
129  mIsVolumeDirty = true;
130 
131  incrementVersion();
132 }
133 
134 //==============================================================================
135 template <typename S>
137 {
138  return mHeights;
139 }
140 
141 //==============================================================================
142 template <typename S>
144 {
145  return mHeights;
146 }
147 
148 //==============================================================================
149 template <typename S>
151 {
152  mHeights = mHeights.colwise().reverse().eval();
153 }
154 
155 //==============================================================================
156 template <typename S>
158 {
159  return mMaxHeight;
160 }
161 
162 //==============================================================================
163 template <typename S>
165 {
166  return mMinHeight;
167 }
168 
169 //==============================================================================
170 template <typename S>
171 std::size_t HeightmapShape<S>::getWidth() const
172 {
173  return mHeights.cols();
174 }
175 
176 //==============================================================================
177 template <typename S>
178 std::size_t HeightmapShape<S>::getDepth() const
179 {
180  return mHeights.rows();
181 }
182 
183 //==============================================================================
184 template <typename S>
185 Eigen::Matrix3d HeightmapShape<S>::computeInertia(double mass) const
186 {
187  if (mIsBoundingBoxDirty)
188  {
189  updateBoundingBox();
190  }
191  return BoxShape::computeInertia(getBoundingBox().computeFullExtents(), mass);
192 }
193 
194 //==============================================================================
195 template <typename S>
197  Eigen::Vector3d& min, Eigen::Vector3d& max) const
198 {
199  const double dimX = getWidth() * mScale.x();
200  const double dimY = getDepth() * mScale.y();
201  const double dimZ = (mMaxHeight - mMinHeight) * mScale.z();
202  min = Eigen::Vector3d(-dimX * 0.5, -dimY * 0.5, mMinHeight * mScale.z());
203  max = min + Eigen::Vector3d(dimX, dimY, dimZ);
204 }
205 
206 //==============================================================================
207 template <typename S>
209 {
210  Eigen::Vector3d min;
211  Eigen::Vector3d max;
212  computeBoundingBox(min, max);
213  mBoundingBox.setMin(min);
214  mBoundingBox.setMax(max);
215  mIsBoundingBoxDirty = false;
216 }
217 
218 //==============================================================================
219 template <typename S>
221 {
222  updateBoundingBox();
223  const Eigen::Vector3d size = mBoundingBox.getMax() - mBoundingBox.getMin();
224  mVolume = size.x() * size.y() * size.z();
225  mIsVolumeDirty = false;
226 }
227 
228 } // namespace dynamics
229 } // namespace dart
#define dterr
Output an error message.
Definition: Console.hpp:49
#define dtwarn
Output a warning message.
Definition: Console.hpp:46
std::string type
Definition: SdfParser.cpp:82
std::string * name
Definition: SkelParser.cpp:1642
static Eigen::Matrix3d computeInertia(const Eigen::Vector3d &size, double mass)
Compute moments of inertia of a box.
Definition: BoxShape.cpp:75
const HeightField & getHeightField() const
Returns the height field.
Definition: HeightmapShape-impl.hpp:136
const Eigen::Vector3d & getScale() const
Returns scale of this heightmap.
Definition: HeightmapShape-impl.hpp:85
std::size_t getWidth() const
Returns the width dimension of the height field.
Definition: HeightmapShape-impl.hpp:171
void setScale(const Eigen::Vector3d &scale)
Sets scale of this heightmap.
Definition: HeightmapShape-impl.hpp:71
Eigen::Matrix3d computeInertia(double mass) const override
Computes the inertia.
Definition: HeightmapShape-impl.hpp:185
S_ S
Definition: HeightmapShape.hpp:49
void computeBoundingBox(Eigen::Vector3d &min, Eigen::Vector3d &max) const
Computes the bounding box of the height field.
Definition: HeightmapShape-impl.hpp:196
void updateVolume() const override
Updates volume.
Definition: HeightmapShape-impl.hpp:220
static const std::string & getStaticType()
Returns shape type for this class.
Definition: HeightmapShape-impl.hpp:62
HeightField & getHeightFieldModifiable() const
Returns the modified height field. See also setHeightField().
Definition: HeightmapShape-impl.hpp:143
void flipY() const
Flips the y values in the height field.
Definition: HeightmapShape-impl.hpp:150
void updateBoundingBox() const override
Updates bounding box.
Definition: HeightmapShape-impl.hpp:208
HeightmapShape()
Constructor.
Definition: HeightmapShape-impl.hpp:46
const std::string & getType() const override
Returns a string representing the shape type.
Definition: HeightmapShape-impl.hpp:55
Eigen::Matrix< S, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > HeightField
Definition: HeightmapShape.hpp:52
std::size_t getDepth() const
Returns the height dimension of the height field.
Definition: HeightmapShape-impl.hpp:178
S getMinHeight() const
Returns the minimum height set by setHeightField()
Definition: HeightmapShape-impl.hpp:164
S getMaxHeight() const
Returns the maximum height set by setHeightField()
Definition: HeightmapShape-impl.hpp:157
void setHeightField(const std::size_t &width, const std::size_t &depth, const std::vector< S > &heights)
Sets the height field.
Definition: HeightmapShape-impl.hpp:92
Definition: Shape.hpp:53
Definition: BulletCollisionDetector.cpp:63