22 #ifndef PLAYRHO_COLLISION_SHAPES_SHAPE_HPP
23 #define PLAYRHO_COLLISION_SHAPES_SHAPE_HPP
70 NonNegative<AreaDensity>
GetDensity(
const Shape& shape) noexcept;
104 bool Visit(
const Shape& shape,
void* userData);
110 const void*
GetData(
const Shape& shape) noexcept;
118 using TypeInfoVisitor = std::function<void(
const std::type_info& ti,
const void* data)>;
181 template <
typename T>
182 explicit Shape(T arg): m_self{std::make_shared<Model<T>>(std::move(arg))}
201 return shape.m_self->GetChildCount_();
206 return shape.m_self->GetChild_(index);
211 return shape.m_self->GetMassData_();
216 return shape.m_self->GetVertexRadius_(idx);
221 return shape.m_self->GetFriction_();
226 return shape.m_self->GetRestitution_();
231 return shape.m_self->GetDensity_();
236 auto copy = shape.m_self->Clone();
238 shape.m_self = std::unique_ptr<const Shape::Concept>{std::move(copy)};
243 return shape.m_self->Visit_(userData);
248 return shape.m_self->GetData_();
253 return shape.m_self->GetUseTypeInfo_();
258 const auto self = shape.m_self;
259 visitor(self->GetUseTypeInfo_(), self->GetData_());
264 return lhs.m_self == rhs.m_self || *lhs.m_self == *rhs.m_self;
269 return !(lhs == rhs);
278 virtual ~Concept() =
default;
284 virtual std::unique_ptr<Concept> Clone()
const = 0;
287 virtual ChildCounter GetChildCount_() const noexcept = 0;
290 virtual DistanceProxy GetChild_(
ChildCounter index) const = 0;
293 virtual
MassData GetMassData_() const noexcept = 0;
303 virtual
Real GetFriction_() const noexcept = 0;
306 virtual
Real GetRestitution_() const noexcept = 0;
310 virtual
void Transform_(const
Mat22& m) = 0;
313 virtual
bool Visit_(
void* userData) const = 0;
316 virtual
bool IsEqual_(const Concept& other) const noexcept = 0;
320 virtual const std::type_info& GetUseTypeInfo_() const = 0;
323 virtual const
void* GetData_() const noexcept = 0;
326 friend
bool operator== (const Concept& lhs, const Concept &rhs) noexcept
328 return &lhs == &rhs || lhs.IsEqual_(rhs);
332 friend bool operator!= (
const Concept& lhs,
const Concept &rhs) noexcept
334 return !(lhs == rhs);
340 template <
typename T>
341 struct Model final: Concept
347 Model(T arg): data{std::move(arg)} {}
349 std::unique_ptr<Concept> Clone()
const override
351 return std::make_unique<Model>(data);
359 DistanceProxy GetChild_(
ChildCounter index)
const override
364 MassData GetMassData_() const noexcept
override
369 NonNegative<Length> GetVertexRadius_(
ChildCounter idx)
const override
374 NonNegative<AreaDensity> GetDensity_() const noexcept
override
379 Real GetFriction_() const noexcept
override
384 Real GetRestitution_() const noexcept
override
389 void Transform_(
const Mat22& m)
override
394 bool Visit_(
void* userData)
const override
399 bool IsEqual_(
const Concept& other)
const noexcept
override
403 return (GetUseTypeInfo_() == other.GetUseTypeInfo_()) &&
404 (data == *
static_cast<const T*
>(other.GetData_()));
407 const std::type_info& GetUseTypeInfo_()
const override
409 return typeid(data_type);
412 const void* GetData_() const noexcept
override
422 std::shared_ptr<const Concept> m_self;
443 inline bool Visit<d2::Shape>(
const d2::Shape& shape,
void* userData)
450 #endif // PLAYRHO_COLLISION_SHAPES_SHAPE_HPP