dart
HeightmapShape-impl.hpp
1 /*
2  * Copyright (c) 2011-2021, 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 
33 #pragma once
34 
35 #include "dart/dynamics/HeightmapShape.hpp"
36 
37 #include <algorithm>
38 #include <cmath>
39 #include <limits>
40 #include "dart/common/Console.hpp"
41 #include "dart/dynamics/BoxShape.hpp"
42 
43 namespace dart {
44 namespace dynamics {
45 
46 //==============================================================================
47 template <typename S>
48 HeightmapShape<S>::HeightmapShape() : Shape(HEIGHTMAP), mScale(1, 1, 1)
49 {
50  static_assert(
51  std::is_same<S, float>::value || std::is_same<S, double>::value,
52  "Height field needs to be double or float");
53 }
54 
55 //==============================================================================
56 template <typename S>
57 const std::string& HeightmapShape<S>::getType() const
58 {
59  return getStaticType();
60 }
61 
62 //==============================================================================
63 template <typename S>
65 {
66  static const std::string type
67  = "HeightmapShape (" + std::string(typeid(S).name()) + ")";
68  return type;
69 }
70 
71 //==============================================================================
72 template <typename S>
73 void HeightmapShape<S>::setScale(const Vector3& scale)
74 {
75  assert(scale[0] > 0.0);
76  assert(scale[1] > 0.0);
77  assert(scale[2] > 0.0);
78  mScale = scale;
79  mIsBoundingBoxDirty = true;
80  mIsVolumeDirty = true;
81 
82  incrementVersion();
83 }
84 
85 //==============================================================================
86 template <typename S>
87 auto HeightmapShape<S>::getScale() const -> const Vector3&
88 {
89  return mScale;
90 }
91 
92 //==============================================================================
93 template <typename S>
95  const std::size_t& width,
96  const std::size_t& depth,
97  const std::vector<S>& heights)
98 {
99  assert(heights.size() == width * depth);
100  if ((width * depth) != heights.size())
101  {
102  dterr << "[HeightmapShape] Size of height field needs to be width*depth="
103  << width * depth << "\n";
104  return;
105  }
106  if (heights.empty())
107  {
108  dtwarn << "Empty height field makes no sense.\n";
109  return;
110  }
111 
112  // make heightmap data local copy
113  const Eigen::Map<const HeightField> data(heights.data(), depth, width);
114 
115  setHeightField(data);
116 }
117 
118 //==============================================================================
119 template <typename S>
120 void HeightmapShape<S>::setHeightField(const HeightField& heights)
121 {
122  mHeights = heights;
123 
124  mMinHeight = heights.minCoeff();
125  mMaxHeight = heights.maxCoeff();
126 
127  mIsBoundingBoxDirty = true;
128  mIsVolumeDirty = true;
129 
130  incrementVersion();
131 }
132 
133 //==============================================================================
134 template <typename S>
135 auto HeightmapShape<S>::getHeightField() const -> const HeightField&
136 {
137  return mHeights;
138 }
139 
140 //==============================================================================
141 template <typename S>
143 {
144  return mHeights;
145 }
146 
147 //==============================================================================
148 template <typename S>
150 {
151  mHeights = mHeights.colwise().reverse().eval();
152 }
153 
154 //==============================================================================
155 template <typename S>
157 {
158  return mMaxHeight;
159 }
160 
161 //==============================================================================
162 template <typename S>
164 {
165  return mMinHeight;
166 }
167 
168 //==============================================================================
169 template <typename S>
170 std::size_t HeightmapShape<S>::getWidth() const
171 {
172  return mHeights.cols();
173 }
174 
175 //==============================================================================
176 template <typename S>
177 std::size_t HeightmapShape<S>::getDepth() const
178 {
179  return mHeights.rows();
180 }
181 
182 //==============================================================================
183 template <typename S>
184 void HeightmapShape<S>::notifyColorUpdated(const Eigen::Vector4d& /*color*/)
185 {
186  incrementVersion();
187 }
188 
189 //==============================================================================
190 template <typename S>
191 Eigen::Matrix3d HeightmapShape<S>::computeInertia(double mass) const
192 {
193  if (mIsBoundingBoxDirty)
194  {
195  updateBoundingBox();
196  }
197  return BoxShape::computeInertia(getBoundingBox().computeFullExtents(), mass);
198 }
199 
200 //==============================================================================
201 template <typename S>
203  Eigen::Vector3d& min, Eigen::Vector3d& max) const
204 {
205  const double dimX = getWidth() * mScale.x();
206  const double dimY = getDepth() * mScale.y();
207  const double dimZ = (mMaxHeight - mMinHeight) * mScale.z();
208  min = Eigen::Vector3d(-dimX * 0.5, -dimY * 0.5, mMinHeight * mScale.z());
209  max = min + Eigen::Vector3d(dimX, dimY, dimZ);
210 }
211 
212 //==============================================================================
213 template <typename S>
215 {
216  Eigen::Vector3d min;
217  Eigen::Vector3d max;
218  computeBoundingBox(min, max);
219  mBoundingBox.setMin(min);
220  mBoundingBox.setMax(max);
221  mIsBoundingBoxDirty = false;
222 }
223 
224 //==============================================================================
225 template <typename S>
227 {
228  updateBoundingBox();
229  const Eigen::Vector3d size = mBoundingBox.getMax() - mBoundingBox.getMin();
230  mVolume = size.x() * size.y() * size.z();
231  mIsVolumeDirty = false;
232 }
233 
234 } // namespace dynamics
235 } // namespace dart
Shape for a height map.
Definition: HeightmapShape.hpp:46
Definition: Aspect.cpp:40
HeightmapShape()
Constructor.
Definition: HeightmapShape-impl.hpp:48
Definition: Shape.hpp:52