DART  6.6.2
HeightmapShape-impl.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2018, 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 
81 //==============================================================================
82 template <typename S>
83 const Eigen::Vector3d& HeightmapShape<S>::getScale() const
84 {
85  return mScale;
86 }
87 
88 //==============================================================================
89 template <typename S>
91  const std::size_t& width,
92  const std::size_t& depth,
93  const std::vector<S>& heights)
94 {
95  assert(heights.size() == width * depth);
96  if ((width * depth) != heights.size())
97  {
98  dterr << "Size of height field needs to be width*depth=" << width * depth
99  << std::endl;
100  return;
101  }
102  if (heights.empty())
103  {
104  dtwarn << "Empty height field makes no sense." << std::endl;
105  return;
106  }
107  mHeights = HeightField(depth, width);
108  for (size_t r = 0; r < depth; ++r)
109  {
110  for (size_t c = 0; c < width; ++c)
111  {
112  mHeights(r, c) = heights[r * width + c];
113  }
114  }
115 
116  // compute minimum and maximum height
117  mMinHeight = std::numeric_limits<S>::max();
118  mMaxHeight = -std::numeric_limits<S>::max();
119  for (auto it = heights.begin(); it != heights.end(); ++it)
120  {
121  if (*it < mMinHeight)
122  mMinHeight = *it;
123  if (*it > mMaxHeight)
124  mMaxHeight = *it;
125  }
126  mIsBoundingBoxDirty = true;
127  mIsVolumeDirty = true;
128 }
129 
130 //==============================================================================
131 template <typename S>
133 {
134  return mHeights;
135 }
136 
137 //==============================================================================
138 template <typename S>
140 {
141  return mHeights;
142 }
143 
144 //==============================================================================
145 template <typename S>
147 {
148  mHeights = mHeights.colwise().reverse().eval();
149 }
150 
151 //==============================================================================
152 template <typename S>
154 {
155  return mMaxHeight;
156 }
157 
158 //==============================================================================
159 template <typename S>
161 {
162  return mMinHeight;
163 }
164 
165 //==============================================================================
166 template <typename S>
167 std::size_t HeightmapShape<S>::getWidth() const
168 {
169  return mHeights.cols();
170 }
171 
172 //==============================================================================
173 template <typename S>
174 std::size_t HeightmapShape<S>::getDepth() const
175 {
176  return mHeights.rows();
177 }
178 
179 //==============================================================================
180 template <typename S>
181 Eigen::Matrix3d HeightmapShape<S>::computeInertia(double mass) const
182 {
183  if (mIsBoundingBoxDirty)
184  {
185  updateBoundingBox();
186  }
187  return BoxShape::computeInertia(getBoundingBox().computeFullExtents(), mass);
188 }
189 
190 //==============================================================================
191 template <typename S>
193  Eigen::Vector3d& min, Eigen::Vector3d& max) const
194 {
195  const double dimX = getWidth() * mScale.x();
196  const double dimY = getDepth() * mScale.y();
197  const double dimZ = (mMaxHeight - mMinHeight) * mScale.z();
198  min = Eigen::Vector3d(-dimX * 0.5, -dimY * 0.5, mMinHeight * mScale.z());
199  max = min + Eigen::Vector3d(dimX, dimY, dimZ);
200 }
201 
202 //==============================================================================
203 template <typename S>
205 {
206  Eigen::Vector3d min;
207  Eigen::Vector3d max;
208  computeBoundingBox(min, max);
209  mBoundingBox.setMin(min);
210  mBoundingBox.setMax(max);
211  mIsBoundingBoxDirty = false;
212 }
213 
214 //==============================================================================
215 template <typename S>
217 {
218  updateBoundingBox();
219  const Eigen::Vector3d size = mBoundingBox.getMax() - mBoundingBox.getMin();
220  mVolume = size.x() * size.y() * size.z();
221  mIsVolumeDirty = false;
222 }
223 
224 } // namespace dynamics
225 } // 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:132
const Eigen::Vector3d & getScale() const
Returns scale of this heightmap.
Definition: HeightmapShape-impl.hpp:83
std::size_t getWidth() const
Returns the width dimension of the height field.
Definition: HeightmapShape-impl.hpp:167
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:181
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:192
void updateVolume() const override
Updates volume.
Definition: HeightmapShape-impl.hpp:216
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:139
void flipY() const
Flips the y values in the height field.
Definition: HeightmapShape-impl.hpp:146
void updateBoundingBox() const override
Updates bounding box.
Definition: HeightmapShape-impl.hpp:204
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:174
S getMinHeight() const
Returns the minimum height set by setHeightField()
Definition: HeightmapShape-impl.hpp:160
S getMaxHeight() const
Returns the maximum height set by setHeightField()
Definition: HeightmapShape-impl.hpp:153
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:90
Definition: Shape.hpp:49
Definition: BulletCollisionDetector.cpp:63