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 #ifndef DART_DYNAMICS_SHAPEFRAME_HPP_
34 #define DART_DYNAMICS_SHAPEFRAME_HPP_
35 
36 #include <Eigen/Dense>
37 
38 #include "dart/common/AspectWithVersion.hpp"
39 #include "dart/common/Signal.hpp"
40 #include "dart/common/SpecializedForAspect.hpp"
41 #include "dart/dynamics/EllipsoidShape.hpp"
42 #include "dart/dynamics/FixedFrame.hpp"
43 #include "dart/dynamics/TemplatedJacobianNode.hpp"
44 #include "dart/dynamics/detail/ShapeFrameAspect.hpp"
45 
46 namespace dart {
47 namespace dynamics {
48 
49 //==============================================================================
50 class VisualAspect final : public common::AspectWithVersionedProperties<
51                                VisualAspect,
52                                detail::VisualAspectProperties,
53                                ShapeFrame>
54 {
55 public:
56   using Base = common::AspectWithVersionedProperties<
57       VisualAspect,
58       detail::VisualAspectProperties,
59       ShapeFrame>;
60 
61   /// Constructor
62   VisualAspect(const PropertiesData& properties = PropertiesData());
63 
64   VisualAspect(const VisualAspect&) = delete;
65 
66   /// Set RGBA color
67   void setRGBA(const Eigen::Vector4d& color);
68 
69   DART_COMMON_GET_ASPECT_PROPERTY(Eigen::Vector4d, RGBA)
70   // const Eigen::Vector4d& getRGBA() const;
71 
72   DART_COMMON_SET_GET_ASPECT_PROPERTY(bool, Hidden)
73   // void setHidden(const bool& value);
74   // const bool& getHidden() const;
75 
76   DART_COMMON_SET_GET_ASPECT_PROPERTY(bool, Shadowed)
77   // void setShadowed(const bool& value);
78   // const bool& getShadowed() const;
79 
80   /// Identical to setRGB(const Eigen::Vector3d&)
81   void setColor(const Eigen::Vector3d& color);
82 
83   /// Identical to setRGBA(const Eigen::Vector4d&)
84   void setColor(const Eigen::Vector4d& color);
85 
86   /// Set RGB color components (leave alpha alone)
87   void setRGB(const Eigen::Vector3d& rgb);
88 
89   /// Set the transparency of the Shape
90   void setAlpha(const double alpha);
91 
92   /// Get color
93   Eigen::Vector3d getColor() const;
94 
95   /// Get RGB color components
96   Eigen::Vector3d getRGB() const;
97 
98   /// Get the transparency of the Shape
99   double getAlpha() const;
100 
101   /// Hide the ShapeNode
102   void hide();
103 
104   /// Show the ShapeNode
105   void show();
106 
107   /// True iff the ShapeNode is set to be hidden. Use hide(bool) to change this
108   /// setting
109   bool isHidden() const;
110 };
111 
112 //==============================================================================
113 class CollisionAspect final : public common::AspectWithVersionedProperties<
114                                   CollisionAspect,
115                                   detail::CollisionAspectProperties,
116                                   ShapeFrame>
117 {
118 public:
119   CollisionAspect(const CollisionAspect&) = delete;
120   CollisionAspect(const PropertiesData& properties = PropertiesData());
121 
122   DART_COMMON_SET_GET_ASPECT_PROPERTY(bool, Collidable)
123   // void setCollidable(const bool& value);
124   // const bool& getCollidable() const;
125 
126   /// Return true if this body can collide with others bodies
127   bool isCollidable() const;
128 };
129 
130 //==============================================================================
131 class DynamicsAspect final : public common::AspectWithVersionedProperties<
132                                  DynamicsAspect,
133                                  detail::DynamicsAspectProperties,
134                                  ShapeFrame>
135 {
136 public:
137   using Base = common::AspectWithVersionedProperties<
138       DynamicsAspect,
139       detail::DynamicsAspectProperties,
140       ShapeFrame>;
141 
142   DynamicsAspect(const DynamicsAspect&) = delete;
143 
144   DynamicsAspect(const PropertiesData& properties = PropertiesData());
145 
146   /// Set both primary and secondary friction coefficients to the same value.
147   void setFrictionCoeff(const double& value);
148   /// Get average of primary and secondary friction coefficients.
149   double getFrictionCoeff() const;
150 
151   // DART_COMMON_SET_GET_ASPECT_PROPERTY(double, PrimaryFrictionCoeff)
152   void setPrimaryFrictionCoeff(const double& value);
153   const double& getPrimaryFrictionCoeff() const;
154 
155   DART_COMMON_SET_GET_ASPECT_PROPERTY(double, SecondaryFrictionCoeff)
156   // void setSecondaryFrictionCoeff(const double& value);
157   // const double& getSecondaryFrictionCoeff() const;
158   DART_COMMON_SET_GET_ASPECT_PROPERTY(double, RestitutionCoeff)
159   // void setRestitutionCoeff(const double& value);
160   // const double& getRestitutionCoeff() const;
161 
162   /// Slip compliance parameters act as constraint force mixing (cfm)
163   /// for the friction constraints.
164   /// They start with a default value of -1.0 and will be ignored
165   /// in favor of the global default value unless explicitly
166   /// set to a positive value.
167   DART_COMMON_SET_GET_ASPECT_PROPERTY(double, PrimarySlipCompliance)
168   // void sePrimarytSlipCompliance(const double& value);
169   // const double& getPrimarySlipCompliance() const;
170   DART_COMMON_SET_GET_ASPECT_PROPERTY(double, SecondarySlipCompliance)
171   // void setSecondarySlipCompliance(const double& value);
172   // const double& getSecondarySlipCompliance() const;
173 
174   /// Set the frame for interpreting the first friction direction vector.
175   /// The frame pointer defaults to nullptr, which is interpreted as this
176   /// ShapeFrame.
177   void setFirstFrictionDirectionFrame(const Frame* value);
178 
179   /// Get the frame for the first friction direction vector.
180   const Frame* getFirstFrictionDirectionFrame() const;
181 
182   DART_COMMON_SET_GET_ASPECT_PROPERTY(Eigen::Vector3d, FirstFrictionDirection)
183   // void setFirstFrictionDirection(const Eigen::Vector3d& value);
184   // const Eigen::Vector3d& getFirstFrictionDirection() const;
185 };
186 
187 //==============================================================================
188 DART_DECLARE_CLASS_WITH_VIRTUAL_BASE_BEGIN
189 class ShapeFrame : public virtual common::VersionCounter,
190                    public detail::ShapeFrameCompositeBase,
191                    public virtual Frame
192 {
193 public:
194   friend class BodyNode;
195 
196   using ShapeUpdatedSignal = common::Signal<void(
197       const ShapeFrame* thisShapeFrame,
198       const ShapePtr& oldShape,
199       const ShapePtr& newShape)>;
200 
201   using RelativeTransformUpdatedSignal = common::Signal<void(
202       const ShapeFrame* thisShapeFrame,
203       const Eigen::Isometry3d& oldTransform,
204       const Eigen::Isometry3d& newTransform)>;
205 
206   using UniqueProperties = AspectProperties;
207   using Properties = UniqueProperties;
208 
209   /// Destructor
210   virtual ~ShapeFrame() override;
211 
212   /// Set the UniqueProperties of this ShapeFrame
213   void setProperties(const UniqueProperties& properties);
214 
215   /// Set the AspectProperties of this ShapeFrame
216   void setAspectProperties(const AspectProperties& properties);
217 
218   const AspectProperties& getAspectProperties() const;
219 
220   /// Set shape
221   void setShape(const ShapePtr& shape);
222 
223   /// Return shape
224   ShapePtr getShape();
225 
226   /// Return (const) shape
227   ConstShapePtr getShape() const;
228 
229   DART_BAKE_SPECIALIZED_ASPECT(VisualAspect)
230 
231   DART_BAKE_SPECIALIZED_ASPECT(CollisionAspect)
232 
233   DART_BAKE_SPECIALIZED_ASPECT(DynamicsAspect)
234 
235   // Documentation inherited
236   ShapeFrame* asShapeFrame() override;
237 
238   // Documentation inherited
239   const ShapeFrame* asShapeFrame() const override;
240 
241   /// Returns true if this Frame is a ShapeNode
242   bool isShapeNode() const;
243 
244   /// Convert 'this' into a ShapeNode pointer if ShapeFrame is a ShapeNode,
245   /// otherwise return nullptr
246   virtual ShapeNode* asShapeNode();
247 
248   /// Convert 'const this' into a ShapeNode pointer if ShapeFrame is a
249   /// ShapeNode, otherwise return nullptr.
250   ///
251   /// This should be preferred over performing a dynamic_cast when you want to
252   /// cast a ShapeFrame into a ShapeNode, because this method costs less.
253   virtual const ShapeNode* asShapeNode() const;
254 
255 protected:
256   /// Constructor
257   ShapeFrame(Frame* parent, const Properties& properties);
258 
259   /// Constructor
260   ShapeFrame(Frame* parent, const ShapePtr& shape = nullptr);
261 
262   /// Delegating constructor
263   ShapeFrame(const std::tuple<Frame*, Properties>& args);
264 
265   /// Contains whether or not this is a ShapeNode
266   bool mAmShapeNode;
267 
268   /// Shape updated signal
269   ShapeUpdatedSignal mShapeUpdatedSignal;
270 
271   /// Relative transformation updated signal
272   RelativeTransformUpdatedSignal mRelativeTransformUpdatedSignal;
273 
274   /// Connect to changes in the Shape version
275   common::Connection mConnectionForShapeVersionChange;
276 
277 public:
278   /// Slot register for shape updated signal
279   common::SlotRegister<ShapeUpdatedSignal> onShapeUpdated;
280 
281   /// Slot register for relative transformation updated signal
282   common::SlotRegister<RelativeTransformUpdatedSignal>
283       onRelativeTransformUpdated;
284 };
285 DART_DECLARE_CLASS_WITH_VIRTUAL_BASE_END
286 
287 } // namespace dynamics
288 } // namespace dart
289 
290 #endif // DART_DYNAMICS_SHAPEFRAME_HPP_
291