diff --git a/src/Physics/AbstractShape.cpp b/src/Physics/AbstractShape.cpp deleted file mode 100644 index 2321bd481..000000000 --- a/src/Physics/AbstractShape.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/* - This file is part of Magnum. - - Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -#include "AbstractShape.h" - -#include - -namespace Magnum { namespace Physics { - -template bool AbstractShape::collides(const AbstractShape* other) const { - /* Operate only with simpler types than this */ - if(static_cast(other->type()) > static_cast(type())) - return other->collides(this); - - return false; -} - -template class AbstractShape<2>; -template class AbstractShape<3>; - -#ifndef DOXYGEN_GENERATING_OUTPUT -namespace Implementation { - -Debug operator<<(Debug debug, ShapeDimensionTraits<2>::Type value) { - switch(value) { - #define _val(value) case AbstractShape2D::Type::value: return debug << "AbstractShape2D::Type::" #value; - _val(Point) - _val(Line) - _val(LineSegment) - _val(Sphere) - _val(Capsule) - _val(AxisAlignedBox) - _val(Box) - _val(ShapeGroup) - #undef _val - } - - return debug << "AbstractShape2D::Type::(unknown)"; -} - -Debug operator<<(Debug debug, ShapeDimensionTraits<3>::Type value) { - switch(value) { - #define _val(value) case AbstractShape3D::Type::value: return debug << "AbstractShape3D::Type::" #value; - _val(Point) - _val(Line) - _val(LineSegment) - _val(Sphere) - _val(Capsule) - _val(AxisAlignedBox) - _val(Box) - _val(ShapeGroup) - _val(Plane) - #undef _val - } - - return debug << "AbstractShape2D::Type::(unknown)"; -} - -} -#endif - -}} diff --git a/src/Physics/AbstractShape.h b/src/Physics/AbstractShape.h deleted file mode 100644 index aaa541663..000000000 --- a/src/Physics/AbstractShape.h +++ /dev/null @@ -1,146 +0,0 @@ -#ifndef Magnum_Physics_AbstractShape_h -#define Magnum_Physics_AbstractShape_h -/* - This file is part of Magnum. - - Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -*/ - -/** @file - * @brief Class Magnum::Physics::AbstractShape, typedef Magnum::Physics::AbstractShape2D, Magnum::Physics::AbstractShape3D - */ - -#include "Magnum.h" -#include "DimensionTraits.h" - -#include "magnumPhysicsVisibility.h" - -namespace Magnum { namespace Physics { - -#ifndef DOXYGEN_GENERATING_OUTPUT -namespace Implementation { - template struct ShapeDimensionTraits {}; - - template<> struct ShapeDimensionTraits<2> { - enum class Type { - Point, - Line, - LineSegment, - Sphere, - Capsule, - AxisAlignedBox, - Box, - ShapeGroup - }; - }; - - template<> struct ShapeDimensionTraits<3> { - enum class Type { - Point, - Line, - LineSegment, - Sphere, - Capsule, - AxisAlignedBox, - Box, - ShapeGroup, - Plane - }; - }; - - Debug MAGNUM_PHYSICS_EXPORT operator<<(Debug debug, ShapeDimensionTraits<2>::Type value); - Debug MAGNUM_PHYSICS_EXPORT operator<<(Debug debug, ShapeDimensionTraits<3>::Type value); -} -#endif - -/** -@brief Base class for shapes - -See @ref collision-detection for brief introduction. -@see AbstractShape2D, AbstractShape3D -*/ -template class MAGNUM_PHYSICS_EXPORT AbstractShape { - public: - /** @brief Dimension count */ - static const UnsignedInt Dimensions = dimensions; - - /** - * @brief Shape type - * - * @internal Sorted by complexity, so the shape which is later in - * the list provides collision detection for previous shapes, not - * the other way around. - */ - #ifdef DOXYGEN_GENERATING_OUTPUT - enum class Type { - Point, /**< Point */ - Line, /**< Line */ - LineSegment, /**< @ref LineSegment "Line segment" */ - Sphere, /**< Sphere */ - Capsule, /**< Capsule */ - AxisAlignedBox, /**< @ref AxisAlignedBox "Axis aligned box" */ - Box, /**< Box */ - ShapeGroup, /**< @ref ShapeGroup "Shape group" */ - Plane /**< Plane (3D only) */ - }; - #else - typedef typename Implementation::ShapeDimensionTraits::Type Type; - #endif - - explicit AbstractShape() = default; - virtual inline ~AbstractShape() {} - - /** @brief Shape type */ - virtual Type type() const = 0; - - /** - * @brief Apply transformation matrix - * - * Applies transformation matrix to user-defined shape properties and - * caches them for later usage in collision detection. - */ - virtual void applyTransformationMatrix(const typename DimensionTraits::MatrixType& matrix) = 0; - - /** - * @brief Detect collision with other shape - * - * Default implementation returns false. - * - * @internal If other shape is more complex than this, returns - * `other->collides(this)`. - */ - virtual bool collides(const AbstractShape* other) const; -}; - -/** @brief Abstract two-dimensional shape */ -typedef AbstractShape<2> AbstractShape2D; - -/** @brief Abstract three-dimensional shape */ -typedef AbstractShape<3> AbstractShape3D; - -#ifdef DOXYGEN_GENERATING_OUTPUT -/** @debugoperator{Magnum::Physics::AbstractShape} */ -template Debug operator<<(Debug debug, typename AbstractShape::Type value); -#endif - -}} - -#endif diff --git a/src/Physics/AxisAlignedBox.cpp b/src/Physics/AxisAlignedBox.cpp index 5b7a5d7bb..c4ea7e9bb 100644 --- a/src/Physics/AxisAlignedBox.cpp +++ b/src/Physics/AxisAlignedBox.cpp @@ -30,21 +30,14 @@ namespace Magnum { namespace Physics { -template void AxisAlignedBox::applyTransformationMatrix(const typename DimensionTraits::MatrixType& matrix) { - _transformedMin = matrix.transformPoint(_min); - _transformedMax = matrix.transformPoint(_max); -} - -template bool AxisAlignedBox::collides(const AbstractShape* other) const { - if(other->type() == AbstractShape::Type::Point) - return *this % *static_cast*>(other); - - return AbstractShape::collides(other); +template AxisAlignedBox AxisAlignedBox::transformed(const typename DimensionTraits::MatrixType& matrix) const { + return AxisAlignedBox(matrix.transformPoint(_min), + matrix.transformPoint(_max)); } template bool AxisAlignedBox::operator%(const Point& other) const { - return (other.transformedPosition() >= _transformedMin).all() && - (other.transformedPosition() < _transformedMax).all(); + return (other.position() >= _min).all() && + (other.position() < _max).all(); } #ifndef DOXYGEN_GENERATING_OUTPUT diff --git a/src/Physics/AxisAlignedBox.h b/src/Physics/AxisAlignedBox.h index 1a0a1e6d7..361e8ca36 100644 --- a/src/Physics/AxisAlignedBox.h +++ b/src/Physics/AxisAlignedBox.h @@ -29,10 +29,9 @@ */ #include "Math/Vector3.h" -#include "Physics/AbstractShape.h" +#include "DimensionTraits.h" #include "Physics/Physics.h" - -#include "corradeCompatibility.h" +#include "Physics/magnumPhysicsVisibility.h" namespace Magnum { namespace Physics { @@ -44,28 +43,27 @@ radius. @see AxisAlignedBox2D, AxisAlignedBox3D @todo Assert for rotation */ -template class MAGNUM_PHYSICS_EXPORT AxisAlignedBox: public AbstractShape { +template class MAGNUM_PHYSICS_EXPORT AxisAlignedBox { public: + enum: UnsignedInt { + Dimensions = dimensions /**< Dimension count */ + }; + /** * @brief Default constructor * * Creates zero sized box positioned at origin. */ - inline explicit AxisAlignedBox() {} + inline constexpr explicit AxisAlignedBox() {} /** @brief Constructor */ - inline explicit AxisAlignedBox(const typename DimensionTraits::VectorType& min, const typename DimensionTraits::VectorType& max): _min(min), _max(max), _transformedMin(min), _transformedMax(max) {} - - inline typename AbstractShape::Type type() const override { - return AbstractShape::Type::AxisAlignedBox; - } - - void applyTransformationMatrix(const typename DimensionTraits::MatrixType& matrix) override; + inline constexpr explicit AxisAlignedBox(const typename DimensionTraits::VectorType& min, const typename DimensionTraits::VectorType& max): _min(min), _max(max) {} - bool collides(const AbstractShape* other) const override; + /** @brief Transformed shape */ + AxisAlignedBox transformed(const typename DimensionTraits::MatrixType& matrix) const; /** @brief Minimal coordinates */ - inline typename DimensionTraits::VectorType min() const { + inline constexpr typename DimensionTraits::VectorType min() const { return _min; } @@ -75,29 +73,20 @@ template class MAGNUM_PHYSICS_EXPORT AxisAlignedBox: pub } /** @brief Maximal coordinates */ - inline typename DimensionTraits::VectorType max() const { return _max; } + inline constexpr typename DimensionTraits::VectorType max() const { + return _max; + } /** @brief Set maximal coordinates */ inline void setMax(const typename DimensionTraits::VectorType& max) { _max = max; } - /** @brief Transformed minimal coordinates */ - inline typename DimensionTraits::VectorType transformedMin() const { - return _transformedMin; - } - - /** @brief Transformed maximal coordinates */ - inline typename DimensionTraits::VectorType transformedMax() const { - return _transformedMax; - } - /** @brief Collision with point */ bool operator%(const Point& other) const; private: - typename DimensionTraits::VectorType _min, _max, - _transformedMin, _transformedMax; + typename DimensionTraits::VectorType _min, _max; }; /** @brief Two-dimensional axis-aligned box */ diff --git a/src/Physics/Box.cpp b/src/Physics/Box.cpp index 3f724793e..cf410ac91 100644 --- a/src/Physics/Box.cpp +++ b/src/Physics/Box.cpp @@ -24,12 +24,10 @@ #include "Box.h" -#include "Math/Matrix4.h" - namespace Magnum { namespace Physics { -template void Box::applyTransformationMatrix(const typename DimensionTraits::MatrixType& matrix) { - _transformedTransformation = matrix*_transformation; +template Box Box::transformed(const typename DimensionTraits::MatrixType& matrix) const { + return Box(matrix*_transformation); } template class Box<2>; diff --git a/src/Physics/Box.h b/src/Physics/Box.h index cf7276187..8180dc225 100644 --- a/src/Physics/Box.h +++ b/src/Physics/Box.h @@ -30,9 +30,8 @@ #include "Math/Matrix3.h" #include "Math/Matrix4.h" -#include "AbstractShape.h" - -#include "corradeCompatibility.h" +#include "DimensionTraits.h" +#include "Physics/magnumPhysicsVisibility.h" namespace Magnum { namespace Physics { @@ -45,26 +44,27 @@ radius. @see Box2D, Box3D @todo Assert for skew */ -template class MAGNUM_PHYSICS_EXPORT Box: public AbstractShape { +template class MAGNUM_PHYSICS_EXPORT Box { public: + enum: UnsignedInt { + Dimensions = dimensions /**< Dimension count */ + }; + /** * @brief Default constructor * * Creates zero-sized box positioned at origin. */ - inline explicit Box(): _transformation(DimensionTraits::MatrixType::Zero), _transformedTransformation(DimensionTraits::MatrixType::Zero) {} + inline constexpr explicit Box(): _transformation(DimensionTraits::MatrixType::Zero) {} /** @brief Constructor */ - inline explicit Box(const typename DimensionTraits::MatrixType& transformation): _transformation(transformation), _transformedTransformation(transformation) {} - - inline typename AbstractShape::Type type() const override { - return AbstractShape::Type::Box; - } + inline constexpr explicit Box(const typename DimensionTraits::MatrixType& transformation): _transformation(transformation) {} - void applyTransformationMatrix(const typename DimensionTraits::MatrixType& matrix) override; + /** @brief Transformed shape */ + Box transformed(const typename DimensionTraits::MatrixType& matrix) const; /** @brief Transformation */ - inline typename DimensionTraits::MatrixType transformation() const { + inline constexpr typename DimensionTraits::MatrixType transformation() const { return _transformation; } @@ -73,14 +73,8 @@ template class MAGNUM_PHYSICS_EXPORT Box: public Abstrac _transformation = transformation; } - /** @brief Transformed transformation */ - inline typename DimensionTraits::MatrixType transformedTransformation() const { - return _transformedTransformation; - } - private: - typename DimensionTraits::MatrixType _transformation, - _transformedTransformation; + typename DimensionTraits::MatrixType _transformation; }; /** @brief Two-dimensional box */ diff --git a/src/Physics/Capsule.cpp b/src/Physics/Capsule.cpp index 09823df5d..08fd06ec4 100644 --- a/src/Physics/Capsule.cpp +++ b/src/Physics/Capsule.cpp @@ -28,37 +28,27 @@ #include "Math/Matrix3.h" #include "Math/Matrix4.h" #include "Math/Geometry/Distance.h" -#include "Point.h" -#include "Sphere.h" +#include "Magnum.h" +#include "Physics/Point.h" +#include "Physics/Sphere.h" using namespace Magnum::Math::Geometry; namespace Magnum { namespace Physics { -template void Capsule::applyTransformationMatrix(const typename DimensionTraits::MatrixType& matrix) { - _transformedA = matrix.transformPoint(_a); - _transformedB = matrix.transformPoint(_b); - Float scaling = (matrix.rotationScaling()*typename DimensionTraits::VectorType(1/Constants::sqrt3())).length(); - _transformedRadius = scaling*_radius; -} - -template bool Capsule::collides(const AbstractShape* other) const { - if(other->type() == AbstractShape::Type::Point) - return *this % *static_cast*>(other); - if(other->type() == AbstractShape::Type::Sphere) - return *this % *static_cast*>(other); - - return AbstractShape::collides(other); +template Capsule Capsule::transformed(const typename DimensionTraits::MatrixType& matrix) const { + return Capsule(matrix.transformPoint(_a), matrix.transformPoint(_b), + (matrix.rotationScaling()*typename DimensionTraits::VectorType(1/Constants::sqrt3())).length()*_radius); } template bool Capsule::operator%(const Point& other) const { - return Distance::lineSegmentPointSquared(transformedA(), transformedB(), other.transformedPosition()) < - Math::pow<2>(transformedRadius()); + return Distance::lineSegmentPointSquared(_a, _b, other.position()) < + Math::pow<2>(_radius); } template bool Capsule::operator%(const Sphere& other) const { - return Distance::lineSegmentPointSquared(transformedA(), transformedB(), other.transformedPosition()) < - Math::pow<2>(transformedRadius()+other.transformedRadius()); + return Distance::lineSegmentPointSquared(_a, _b, other.position()) < + Math::pow<2>(_radius+other.radius()); } #ifndef DOXYGEN_GENERATING_OUTPUT diff --git a/src/Physics/Capsule.h b/src/Physics/Capsule.h index b40a33b4f..5c133594b 100644 --- a/src/Physics/Capsule.h +++ b/src/Physics/Capsule.h @@ -29,10 +29,9 @@ */ #include "Math/Vector3.h" -#include "AbstractShape.h" -#include "Physics.h" - -#include "corradeCompatibility.h" +#include "DimensionTraits.h" +#include "Physics/Physics.h" +#include "Physics/magnumPhysicsVisibility.h" namespace Magnum { namespace Physics { @@ -44,67 +43,51 @@ applying transformation, the scale factor is averaged from all axes. @see Capsule2D, Capsule3D @todo Assert for asymmetric scaling */ -template class MAGNUM_PHYSICS_EXPORT Capsule: public AbstractShape { +template class MAGNUM_PHYSICS_EXPORT Capsule { public: + enum: UnsignedInt { + Dimensions = dimensions /**< Dimension count */ + }; + /** * @brief Constructor * * Creates zero-sized capsule at origin. */ - inline explicit Capsule(): _radius(0.0f), _transformedRadius(0.0f) {} + inline constexpr explicit Capsule(): _radius(0.0f) {} /** @brief Constructor */ - inline explicit Capsule(const typename DimensionTraits::VectorType& a, const typename DimensionTraits::VectorType& b, Float radius): _a(a), _transformedA(a), _b(b), _transformedB(b), _radius(radius), _transformedRadius(radius) {} - - inline typename AbstractShape::Type type() const override { - return AbstractShape::Type::Capsule; - } - - void applyTransformationMatrix(const typename DimensionTraits::MatrixType& matrix) override; + inline constexpr explicit Capsule(const typename DimensionTraits::VectorType& a, const typename DimensionTraits::VectorType& b, Float radius): _a(a), _b(b), _radius(radius) {} - bool collides(const AbstractShape* other) const override; + /** @brief Transformed shape */ + Capsule transformed(const typename DimensionTraits::MatrixType& matrix) const; /** @brief Start point */ - inline typename DimensionTraits::VectorType a() const { + inline constexpr typename DimensionTraits::VectorType a() const { return _a; } - /** @brief End point */ - inline typename DimensionTraits::VectorType b() const { - return _b; - } - /** @brief Set start point */ inline void setA(const typename DimensionTraits::VectorType& a) { _a = a; } + /** @brief End point */ + inline constexpr typename DimensionTraits::VectorType b() const { + return _b; + } + /** @brief Set end point */ inline void setB(const typename DimensionTraits::VectorType& b) { _b = b; } /** @brief Radius */ - inline Float radius() const { return _radius; } + inline constexpr Float radius() const { return _radius; } /** @brief Set radius */ inline void setRadius(Float radius) { _radius = radius; } - /** @brief Transformed first point */ - inline typename DimensionTraits::VectorType transformedA() const { - return _transformedA; - } - - /** @brief Transformed second point */ - inline typename DimensionTraits::VectorType transformedB() const { - return _transformedB; - } - - /** @brief Transformed radius */ - inline Float transformedRadius() const { - return _transformedRadius; - } - /** @brief Collision with point */ bool operator%(const Point& other) const; @@ -112,9 +95,8 @@ template class MAGNUM_PHYSICS_EXPORT Capsule: public Abs bool operator%(const Sphere& other) const; private: - typename DimensionTraits::VectorType _a, _transformedA, - _b, _transformedB; - Float _radius, _transformedRadius; + typename DimensionTraits::VectorType _a, _b; + Float _radius; }; /** @brief Two-dimensional capsule */ diff --git a/src/Physics/Line.cpp b/src/Physics/Line.cpp index bcb5f9a15..50d265cae 100644 --- a/src/Physics/Line.cpp +++ b/src/Physics/Line.cpp @@ -29,9 +29,9 @@ namespace Magnum { namespace Physics { -template void Line::applyTransformationMatrix(const typename DimensionTraits::MatrixType& matrix) { - _transformedA = matrix.transformPoint(_a); - _transformedB = matrix.transformPoint(_b); +template Line Line::transformed(const typename DimensionTraits::MatrixType& matrix) const { + return Line(matrix.transformPoint(_a), + matrix.transformPoint(_b)); } /* Explicitly instantiate the templates */ diff --git a/src/Physics/Line.h b/src/Physics/Line.h index 49e835c3c..63279d9fc 100644 --- a/src/Physics/Line.h +++ b/src/Physics/Line.h @@ -29,9 +29,8 @@ */ #include "Math/Vector3.h" -#include "AbstractShape.h" - -#include "corradeCompatibility.h" +#include "DimensionTraits.h" +#include "Physics/magnumPhysicsVisibility.h" namespace Magnum { namespace Physics { @@ -41,57 +40,47 @@ namespace Magnum { namespace Physics { @see Line2D, Line3D @todo collision detection of two Line2D */ -template class MAGNUM_PHYSICS_EXPORT Line: public AbstractShape { +template class MAGNUM_PHYSICS_EXPORT Line { public: + enum: UnsignedInt { + Dimensions = dimensions /**< Dimension count */ + }; + /** * @brief Default constructor * * Creates line with both points at origin. */ - inline explicit Line() {} + inline constexpr explicit Line() {} /** @brief Constructor */ - inline explicit Line(const typename DimensionTraits::VectorType& a, const typename DimensionTraits::VectorType& b): _a(a), _transformedA(a), _b(b), _transformedB(b) {} - - inline typename AbstractShape::Type type() const override { - return AbstractShape::Type::Line; - } + inline constexpr explicit Line(const typename DimensionTraits::VectorType& a, const typename DimensionTraits::VectorType& b): _a(a), _b(b) {} - void applyTransformationMatrix(const typename DimensionTraits::MatrixType& matrix) override; + /** @brief Transformed shape */ + Line transformed(const typename DimensionTraits::MatrixType& matrix) const; /** @brief First point */ - inline typename DimensionTraits::VectorType a() const { + inline constexpr typename DimensionTraits::VectorType a() const { return _a; } - /** @brief Second point */ - inline typename DimensionTraits::VectorType b() const { - return _b; - } - /** @brief Set first point */ inline void setA(const typename DimensionTraits::VectorType& a) { _a = a; } + /** @brief Second point */ + inline constexpr typename DimensionTraits::VectorType b() const { + return _b; + } + /** @brief Set second point */ inline void setB(const typename DimensionTraits::VectorType& b) { _b = b; } - /** @brief Transformed first point */ - inline typename DimensionTraits::VectorType transformedA() const { - return _transformedA; - } - - /** @brief Transformed second point */ - inline typename DimensionTraits::VectorType transformedB() const { - return _transformedB; - } - private: - typename DimensionTraits::VectorType _a, _transformedA, - _b, _transformedB; + typename DimensionTraits::VectorType _a, _b; }; /** @brief Infinite two-dimensional line */ diff --git a/src/Physics/LineSegment.h b/src/Physics/LineSegment.h index 666764734..a114586d1 100644 --- a/src/Physics/LineSegment.h +++ b/src/Physics/LineSegment.h @@ -44,14 +44,18 @@ template class LineSegment: public Line { * * Creates line segment with both points at origin. */ - inline explicit LineSegment() {} + inline constexpr explicit LineSegment() {} /** @brief Constructor */ - inline explicit LineSegment(const typename DimensionTraits::VectorType& a, const typename DimensionTraits::VectorType& b): Line(a, b) {} + inline constexpr explicit LineSegment(const typename DimensionTraits::VectorType& a, const typename DimensionTraits::VectorType& b): Line(a, b) {} - inline typename AbstractShape::Type type() const override { - return AbstractShape::Type::LineSegment; + /** @brief Transformed shape */ + inline LineSegment transformed(const typename DimensionTraits::MatrixType& matrix) const { + return Line::transformed(matrix); } + + private: + inline constexpr LineSegment(const Line& line): Line(line) {} }; /** @brief Two-dimensional line segment */ diff --git a/src/Physics/Plane.cpp b/src/Physics/Plane.cpp index 047e22773..c0211bb34 100644 --- a/src/Physics/Plane.cpp +++ b/src/Physics/Plane.cpp @@ -28,33 +28,24 @@ #include "Math/Matrix4.h" #include "Math/Geometry/Intersection.h" -#include "LineSegment.h" +#include "Physics/LineSegment.h" using namespace Magnum::Math::Geometry; namespace Magnum { namespace Physics { -void Plane::applyTransformationMatrix(const Matrix4& matrix) { - _transformedPosition = matrix.transformPoint(_position); - _transformedNormal = matrix.rotation()*_normal; -} - -bool Plane::collides(const AbstractShape<3>* other) const { - if(other->type() == Type::Line) - return *this % *static_cast(other); - if(other->type() == Type::LineSegment) - return *this % *static_cast(other); - - return AbstractShape<3>::collides(other); +Plane Plane::transformed(const Matrix4& matrix) const { + return Plane(matrix.transformPoint(_position), + matrix.rotation()*_normal); } bool Plane::operator%(const Line3D& other) const { - Float t = Intersection::planeLine(transformedPosition(), transformedNormal(), other.transformedA(), other.transformedB()-other.transformedA()); + Float t = Intersection::planeLine(_position, _normal, other.a(), other.b()-other.a()); return t != t || (t != std::numeric_limits::infinity() && t != -std::numeric_limits::infinity()); } bool Plane::operator%(const LineSegment3D& other) const { - Float t = Intersection::planeLine(transformedPosition(), transformedNormal(), other.transformedA(), other.transformedB()-other.transformedA()); + Float t = Intersection::planeLine(_position, _normal, other.a(), other.b()-other.a()); return t > 0.0f && t < 1.0f; } diff --git a/src/Physics/Plane.h b/src/Physics/Plane.h index fbb576eb6..580d7924f 100644 --- a/src/Physics/Plane.h +++ b/src/Physics/Plane.h @@ -29,38 +29,34 @@ */ #include "Math/Vector3.h" -#include "AbstractShape.h" -#include "Physics.h" - -#include "corradeCompatibility.h" +#include "Magnum.h" +#include "Physics/Physics.h" +#include "Physics/magnumPhysicsVisibility.h" namespace Magnum { namespace Physics { /** @brief Infinite plane, defined by position and normal (3D only) */ -class MAGNUM_PHYSICS_EXPORT Plane: public AbstractShape<3> { +class MAGNUM_PHYSICS_EXPORT Plane { public: + enum: UnsignedInt { + Dimensions = 3 /**< Dimension count */ + }; + /** * @brief Default constructor * * Creates plane with zero-sized normal at origin. */ - inline explicit Plane() {} + inline constexpr explicit Plane() {} /** @brief Constructor */ - inline explicit Plane(const Vector3& position, const Vector3& normal): _position(position), _transformedPosition(position), _normal(normal), _transformedNormal(normal) {} + inline constexpr explicit Plane(const Vector3& position, const Vector3& normal): _position(position), _normal(normal) {} - inline Type type() const override { return Type::Plane; } - - #ifndef DOXYGEN_GENERATING_OUTPUT - void applyTransformationMatrix(const Matrix4& matrix) override; - bool collides(const AbstractShape<3>* other) const override; - #else - void applyTransformationMatrix(const typename DimensionTraits::MatrixType& matrix) override; - bool collides(const AbstractShape* other) const override; - #endif + /** @brief Transformed shape */ + Plane transformed(const Matrix4& matrix) const; /** @brief Position */ - inline Vector3 position() const { return _position; } + inline constexpr Vector3 position() const { return _position; } /** @brief Set position */ inline void setPosition(const Vector3& position) { @@ -68,23 +64,13 @@ class MAGNUM_PHYSICS_EXPORT Plane: public AbstractShape<3> { } /** @brief Normal */ - inline Vector3 normal() const { return _normal; } + inline constexpr Vector3 normal() const { return _normal; } /** @brief Set normal */ inline void setNormal(const Vector3& normal) { _normal = normal; } - /** @brief Transformed position */ - inline Vector3 transformedPosition() const { - return _transformedPosition; - } - - /** @brief Transformed normal */ - inline Vector3 transformedNormal() const { - return _transformedNormal; - } - /** @brief Collision with line */ bool operator%(const Line3D& other) const; @@ -92,8 +78,7 @@ class MAGNUM_PHYSICS_EXPORT Plane: public AbstractShape<3> { bool operator%(const LineSegment3D& other) const; private: - Vector3 _position, _transformedPosition, - _normal, _transformedNormal; + Vector3 _position, _normal; }; /** @collisionoperator{Line,Plane} */ diff --git a/src/Physics/Point.cpp b/src/Physics/Point.cpp index fb52d3b7e..a215ae973 100644 --- a/src/Physics/Point.cpp +++ b/src/Physics/Point.cpp @@ -29,8 +29,8 @@ namespace Magnum { namespace Physics { -template void Point::applyTransformationMatrix(const typename DimensionTraits::MatrixType& matrix) { - _transformedPosition = matrix.transformPoint(_position); +template Point Point::transformed(const typename DimensionTraits::MatrixType& matrix) const { + return Point(matrix.transformPoint(_position)); } template class Point<2>; diff --git a/src/Physics/Point.h b/src/Physics/Point.h index 606ad0b51..af6f5a4e1 100644 --- a/src/Physics/Point.h +++ b/src/Physics/Point.h @@ -29,9 +29,8 @@ */ #include "Math/Vector3.h" -#include "AbstractShape.h" - -#include "corradeCompatibility.h" +#include "DimensionTraits.h" +#include "Physics/magnumPhysicsVisibility.h" namespace Magnum { namespace Physics { @@ -40,26 +39,27 @@ namespace Magnum { namespace Physics { @see Point2D, Point3D */ -template class MAGNUM_PHYSICS_EXPORT Point: public AbstractShape { +template class MAGNUM_PHYSICS_EXPORT Point { public: + enum: UnsignedInt { + Dimensions = dimensions /**< Dimension count */ + }; + /** * @brief Default constructor * * Creates point at origin. */ - inline explicit Point() {} + inline constexpr explicit Point() {} /** @brief Constructor */ - inline explicit Point(const typename DimensionTraits::VectorType& position): _position(position), _transformedPosition(position) {} - - inline typename AbstractShape::Type type() const override { - return AbstractShape::Type::Point; - } + inline constexpr explicit Point(const typename DimensionTraits::VectorType& position): _position(position) {} - void applyTransformationMatrix(const typename DimensionTraits::MatrixType& matrix) override; + /** @brief Transformed shape */ + Point transformed(const typename DimensionTraits::MatrixType& matrix) const; /** @brief Position */ - inline typename DimensionTraits::VectorType position() const { + inline constexpr typename DimensionTraits::VectorType position() const { return _position; } @@ -68,13 +68,8 @@ template class MAGNUM_PHYSICS_EXPORT Point: public Abstr _position = position; } - /** @brief Transformed position */ - inline typename DimensionTraits::VectorType transformedPosition() const { - return _transformedPosition; - } - private: - typename DimensionTraits::VectorType _position, _transformedPosition; + typename DimensionTraits::VectorType _position; }; /** @brief Two-dimensional point */ diff --git a/src/Physics/Sphere.cpp b/src/Physics/Sphere.cpp index 4eebd8c49..fe3602c0e 100644 --- a/src/Physics/Sphere.cpp +++ b/src/Physics/Sphere.cpp @@ -28,8 +28,9 @@ #include "Math/Matrix3.h" #include "Math/Matrix4.h" #include "Math/Geometry/Distance.h" -#include "LineSegment.h" -#include "Point.h" +#include "Magnum.h" +#include "Physics/LineSegment.h" +#include "Physics/Point.h" using namespace Magnum::Math::Geometry; @@ -47,43 +48,25 @@ namespace { } } -template void Sphere::applyTransformationMatrix(const typename DimensionTraits::MatrixType& matrix) { - _transformedPosition = matrix.transformPoint(_position); - Float scaling = (matrix.rotationScaling()*unitVector()).length(); - _transformedRadius = scaling*_radius; -} - -template bool Sphere::collides(const AbstractShape* other) const { - if(other->type() == AbstractShape::Type::Point) - return *this % *static_cast*>(other); - if(other->type() == AbstractShape::Type::Line) - return *this % *static_cast*>(other); - if(other->type() == AbstractShape::Type::LineSegment) - return *this % *static_cast*>(other); - if(other->type() == AbstractShape::Type::Sphere) - return *this % *static_cast*>(other); - - return AbstractShape::collides(other); +template Sphere Sphere::transformed(const typename DimensionTraits::MatrixType& matrix) const { + return Sphere(matrix.transformPoint(_position), + (matrix.rotationScaling()*unitVector()).length()*_radius); } template bool Sphere::operator%(const Point& other) const { - return (other.transformedPosition()-transformedPosition()).dot() < - Math::pow<2>(transformedRadius()); + return (other.position()-_position).dot() < Math::pow<2>(_radius); } template bool Sphere::operator%(const Line& other) const { - return Distance::linePointSquared(other.transformedA(), other.transformedB(), transformedPosition()) < - Math::pow<2>(transformedRadius()); + return Distance::linePointSquared(other.a(), other.b(), _position) < Math::pow<2>(_radius); } template bool Sphere::operator%(const LineSegment& other) const { - return Distance::lineSegmentPointSquared(other.transformedA(), other.transformedB(), transformedPosition()) < - Math::pow<2>(transformedRadius()); + return Distance::lineSegmentPointSquared(other.a(), other.b(), _position) < Math::pow<2>(_radius); } template bool Sphere::operator%(const Sphere& other) const { - return (other.transformedPosition()-transformedPosition()).dot() < - Math::pow<2>(transformedRadius()+other.transformedRadius()); + return (other._position-_position).dot() < Math::pow<2>(_radius+other._radius); } #ifndef DOXYGEN_GENERATING_OUTPUT diff --git a/src/Physics/Sphere.h b/src/Physics/Sphere.h index 6f83d2ddb..f9c7160d3 100644 --- a/src/Physics/Sphere.h +++ b/src/Physics/Sphere.h @@ -29,10 +29,9 @@ */ #include "Math/Vector3.h" -#include "AbstractShape.h" -#include "Physics.h" - -#include "corradeCompatibility.h" +#include "DimensionTraits.h" +#include "Physics/Physics.h" +#include "Physics/magnumPhysicsVisibility.h" namespace Magnum { namespace Physics { @@ -44,28 +43,27 @@ applying transformation, the scale factor is averaged from all axes. @see Sphere2D, Sphere3D @todo Assert for asymmetric scaling */ -template class MAGNUM_PHYSICS_EXPORT Sphere: public AbstractShape { +template class MAGNUM_PHYSICS_EXPORT Sphere { public: + enum: UnsignedInt { + Dimensions = dimensions /**< Dimension count */ + }; + /** * @brief Default constructor * * Creates zero-sized sphere at origin. */ - inline explicit Sphere(): _radius(0.0f), _transformedRadius(0.0f) {} + inline constexpr explicit Sphere(): _radius(0.0f) {} /** @brief Constructor */ - inline explicit Sphere(const typename DimensionTraits::VectorType& position, Float radius): _position(position), _transformedPosition(position), _radius(radius), _transformedRadius(radius) {} - - inline typename AbstractShape::Type type() const override { - return AbstractShape::Type::Sphere; - } - - void applyTransformationMatrix(const typename DimensionTraits::MatrixType& matrix) override; + inline constexpr explicit Sphere(const typename DimensionTraits::VectorType& position, Float radius): _position(position), _radius(radius) {} - bool collides(const AbstractShape* other) const override; + /** @brief Transformed shape */ + Sphere transformed(const typename DimensionTraits::MatrixType& matrix) const; /** @brief Position */ - inline typename DimensionTraits::VectorType position() const { + inline constexpr typename DimensionTraits::VectorType position() const { return _position; } @@ -75,21 +73,11 @@ template class MAGNUM_PHYSICS_EXPORT Sphere: public Abst } /** @brief Radius */ - inline Float radius() const { return _radius; } + inline constexpr Float radius() const { return _radius; } /** @brief Set radius */ inline void setRadius(Float radius) { _radius = radius; } - /** @brief Transformed position */ - inline typename DimensionTraits::VectorType transformedPosition() const { - return _transformedPosition; - } - - /** @brief Transformed radius */ - inline Float transformedRadius() const { - return _transformedRadius; - } - /** @brief Collision with point */ bool operator%(const Point& other) const; @@ -103,9 +91,8 @@ template class MAGNUM_PHYSICS_EXPORT Sphere: public Abst bool operator%(const Sphere& other) const; private: - typename DimensionTraits::VectorType _position, - _transformedPosition; - Float _radius, _transformedRadius; + typename DimensionTraits::VectorType _position; + Float _radius; }; /** @brief Two-dimensional sphere */ diff --git a/src/Physics/Test/AxisAlignedBoxTest.cpp b/src/Physics/Test/AxisAlignedBoxTest.cpp index cf45bf009..08db66ccb 100644 --- a/src/Physics/Test/AxisAlignedBoxTest.cpp +++ b/src/Physics/Test/AxisAlignedBoxTest.cpp @@ -22,9 +22,8 @@ DEALINGS IN THE SOFTWARE. */ -#include - #include "Math/Matrix4.h" +#include "Magnum.h" #include "Physics/AxisAlignedBox.h" #include "Physics/Point.h" @@ -32,25 +31,24 @@ namespace Magnum { namespace Physics { namespace Test { -class AxisAlignedBoxTest: public Corrade::TestSuite::Tester, ShapeTestBase { +class AxisAlignedBoxTest: public Corrade::TestSuite::Tester { public: AxisAlignedBoxTest(); - void applyTransformation(); + void transformed(); void collisionPoint(); }; AxisAlignedBoxTest::AxisAlignedBoxTest() { - addTests({&AxisAlignedBoxTest::applyTransformation, + addTests({&AxisAlignedBoxTest::transformed, &AxisAlignedBoxTest::collisionPoint}); } -void AxisAlignedBoxTest::applyTransformation() { - Physics::AxisAlignedBox3D box({-1.0f, -2.0f, -3.0f}, {1.0f, 2.0f, 3.0f}); - - box.applyTransformationMatrix(Matrix4::translation(Vector3(1.0f))*Matrix4::scaling({2.0f, -1.0f, 1.5f})); - CORRADE_COMPARE(box.transformedMin(), Vector3(-1.0f, 3.0f, -3.5f)); - CORRADE_COMPARE(box.transformedMax(), Vector3(3.0f, -1.0f, 5.5f)); +void AxisAlignedBoxTest::transformed() { + const auto box = Physics::AxisAlignedBox3D({-1.0f, -2.0f, -3.0f}, {1.0f, 2.0f, 3.0f}) + .transformed(Matrix4::translation(Vector3(1.0f))*Matrix4::scaling({2.0f, -1.0f, 1.5f})); + CORRADE_COMPARE(box.min(), Vector3(-1.0f, 3.0f, -3.5f)); + CORRADE_COMPARE(box.max(), Vector3(3.0f, -1.0f, 5.5f)); } void AxisAlignedBoxTest::collisionPoint() { @@ -58,10 +56,6 @@ void AxisAlignedBoxTest::collisionPoint() { Physics::Point3D point1({-1.5f, -1.0f, 2.0f}); Physics::Point3D point2({0.5f, 1.0f, -2.5f}); - randomTransformation(box); - randomTransformation(point1); - randomTransformation(point2); - VERIFY_NOT_COLLIDES(box, point1); VERIFY_COLLIDES(box, point2); } diff --git a/src/Physics/Test/BoxTest.cpp b/src/Physics/Test/BoxTest.cpp index 33bc2781b..006273ab5 100644 --- a/src/Physics/Test/BoxTest.cpp +++ b/src/Physics/Test/BoxTest.cpp @@ -25,6 +25,7 @@ #include #include "Math/Matrix4.h" +#include "Magnum.h" #include "Physics/Box.h" namespace Magnum { namespace Physics { namespace Test { @@ -33,18 +34,17 @@ class BoxTest: public Corrade::TestSuite::Tester { public: BoxTest(); - void applyTransformation(); + void transformed(); }; BoxTest::BoxTest() { - addTests({&BoxTest::applyTransformation}); + addTests({&BoxTest::transformed}); } -void BoxTest::applyTransformation() { - Physics::Box3D box(Matrix4::translation({1.0f, 2.0f, -3.0f})); - - box.applyTransformationMatrix(Matrix4::scaling({2.0f, -1.0f, 1.5f})); - CORRADE_COMPARE(box.transformedTransformation(), Matrix4::scaling({2.0f, -1.0f, 1.5f})*Matrix4::translation({1.0f, 2.0f, -3.0f})); +void BoxTest::transformed() { + const auto box = Physics::Box3D(Matrix4::translation({1.0f, 2.0f, -3.0f})) + .transformed(Matrix4::scaling({2.0f, -1.0f, 1.5f})); + CORRADE_COMPARE(box.transformation(), Matrix4::scaling({2.0f, -1.0f, 1.5f})*Matrix4::translation({1.0f, 2.0f, -3.0f})); } }}} diff --git a/src/Physics/Test/CapsuleTest.cpp b/src/Physics/Test/CapsuleTest.cpp index 9c829f7e8..02c305038 100644 --- a/src/Physics/Test/CapsuleTest.cpp +++ b/src/Physics/Test/CapsuleTest.cpp @@ -22,6 +22,8 @@ DEALINGS IN THE SOFTWARE. */ +#include "Math/Matrix4.h" +#include "Magnum.h" #include "Physics/Capsule.h" #include "Physics/Point.h" #include "Physics/Sphere.h" @@ -30,32 +32,33 @@ namespace Magnum { namespace Physics { namespace Test { -class CapsuleTest: public Corrade::TestSuite::Tester, ShapeTestBase { +class CapsuleTest: public Corrade::TestSuite::Tester { public: CapsuleTest(); - void applyTransformation(); + void transformed(); + void transformedAverageScaling(); void collisionPoint(); void collisionSphere(); }; CapsuleTest::CapsuleTest() { - addTests({&CapsuleTest::applyTransformation, + addTests({&CapsuleTest::transformed, &CapsuleTest::collisionPoint, &CapsuleTest::collisionSphere}); } -void CapsuleTest::applyTransformation() { - Physics::Capsule3D capsule({1.0f, 2.0f, 3.0f}, {-1.0f, -2.0f, -3.0f}, 7.0f); +void CapsuleTest::transformed() { + const Physics::Capsule3D capsule({1.0f, 2.0f, 3.0f}, {-1.0f, -2.0f, -3.0f}, 7.0f); - capsule.applyTransformationMatrix(Matrix4::rotation(Deg(90.0f), Vector3::zAxis())); - CORRADE_COMPARE(capsule.transformedA(), Vector3(-2.0f, 1.0f, 3.0f)); - CORRADE_COMPARE(capsule.transformedB(), Vector3(2.0f, -1.0f, -3.0f)); - CORRADE_COMPARE(capsule.transformedRadius(), 7.0f); + const auto transformed = capsule.transformed(Matrix4::rotation(Deg(90.0f), Vector3::zAxis())); + CORRADE_COMPARE(transformed.a(), Vector3(-2.0f, 1.0f, 3.0f)); + CORRADE_COMPARE(transformed.b(), Vector3(2.0f, -1.0f, -3.0f)); + CORRADE_COMPARE(transformed.radius(), 7.0f); /* Apply average scaling to radius */ - capsule.applyTransformationMatrix(Matrix4::scaling({Constants::sqrt3(), -Constants::sqrt2(), 2.0f})); - CORRADE_COMPARE(capsule.transformedRadius(), Constants::sqrt3()*7.0f); + const auto scaled = capsule.transformed(Matrix4::scaling({Constants::sqrt3(), -Constants::sqrt2(), 2.0f})); + CORRADE_COMPARE(scaled.radius(), Constants::sqrt3()*7.0f); } void CapsuleTest::collisionPoint() { @@ -64,11 +67,6 @@ void CapsuleTest::collisionPoint() { Physics::Point3D point1({2.9f, 1.0f, 0.0f}); Physics::Point3D point2({1.0f, 3.1f, 0.0f}); - randomTransformation(capsule); - randomTransformation(point); - randomTransformation(point1); - randomTransformation(point2); - VERIFY_COLLIDES(capsule, point); VERIFY_COLLIDES(capsule, point1); VERIFY_NOT_COLLIDES(capsule, point2); @@ -80,11 +78,6 @@ void CapsuleTest::collisionSphere() { Physics::Sphere3D sphere1({3.5f, 1.0f, 0.0f}, 0.6f); Physics::Sphere3D sphere2({1.0f, 4.1f, 0.0f}, 1.0f); - randomTransformation(capsule); - randomTransformation(sphere); - randomTransformation(sphere1); - randomTransformation(sphere2); - VERIFY_COLLIDES(capsule, sphere); VERIFY_COLLIDES(capsule, sphere1); VERIFY_NOT_COLLIDES(capsule, sphere2); diff --git a/src/Physics/Test/LineTest.cpp b/src/Physics/Test/LineTest.cpp index 6f0f2cd9d..e398ed013 100644 --- a/src/Physics/Test/LineTest.cpp +++ b/src/Physics/Test/LineTest.cpp @@ -25,6 +25,7 @@ #include #include "Math/Matrix4.h" +#include "Magnum.h" #include "Physics/Line.h" namespace Magnum { namespace Physics { namespace Test { @@ -33,18 +34,18 @@ class LineTest: public Corrade::TestSuite::Tester { public: LineTest(); - void applyTransformation(); + void transformed(); }; LineTest::LineTest() { - addTests({&LineTest::applyTransformation}); + addTests({&LineTest::transformed}); } -void LineTest::applyTransformation() { - Physics::Line3D line({1.0f, 2.0f, 3.0f}, {-1.0f, -2.0f, -3.0f}); - line.applyTransformationMatrix(Matrix4::rotation(Deg(90.0f), Vector3::zAxis())); - CORRADE_COMPARE(line.transformedA(), Vector3(-2.0f, 1.0f, 3.0f)); - CORRADE_COMPARE(line.transformedB(), Vector3(2.0f, -1.0f, -3.0f)); +void LineTest::transformed() { + const auto line = Physics::Line3D({1.0f, 2.0f, 3.0f}, {-1.0f, -2.0f, -3.0f}) + .transformed(Matrix4::rotation(Deg(90.0f), Vector3::zAxis())); + CORRADE_COMPARE(line.a(), Vector3(-2.0f, 1.0f, 3.0f)); + CORRADE_COMPARE(line.b(), Vector3(2.0f, -1.0f, -3.0f)); } }}} diff --git a/src/Physics/Test/PlaneTest.cpp b/src/Physics/Test/PlaneTest.cpp index 028ccb770..c857229df 100644 --- a/src/Physics/Test/PlaneTest.cpp +++ b/src/Physics/Test/PlaneTest.cpp @@ -22,6 +22,7 @@ DEALINGS IN THE SOFTWARE. */ +#include "Math/Matrix4.h" #include "Physics/LineSegment.h" #include "Physics/Point.h" #include "Physics/Plane.h" @@ -30,32 +31,32 @@ namespace Magnum { namespace Physics { namespace Test { -class PlaneTest: public Corrade::TestSuite::Tester, ShapeTestBase { +class PlaneTest: public Corrade::TestSuite::Tester { public: PlaneTest(); - void applyTransformation(); + void transformed(); void collisionLine(); void collisionLineSegment(); }; PlaneTest::PlaneTest() { - addTests({&PlaneTest::applyTransformation, + addTests({&PlaneTest::transformed, &PlaneTest::collisionLine, &PlaneTest::collisionLineSegment}); } -void PlaneTest::applyTransformation() { - Physics::Plane plane({1.0f, 2.0f, 3.0f}, {Constants::sqrt2(), -Constants::sqrt2(), 0}); +void PlaneTest::transformed() { + const Physics::Plane plane({1.0f, 2.0f, 3.0f}, {Constants::sqrt2(), -Constants::sqrt2(), 0}); - plane.applyTransformationMatrix(Matrix4::rotation(Deg(90.0f), Vector3::xAxis())); - CORRADE_COMPARE(plane.transformedPosition(), Vector3(1.0f, -3.0f, 2.0f)); - CORRADE_COMPARE(plane.transformedNormal(), Vector3(Constants::sqrt2(), 0, -Constants::sqrt2())); + const auto transformed = plane.transformed(Matrix4::rotation(Deg(90.0f), Vector3::xAxis())); + CORRADE_COMPARE(transformed.position(), Vector3(1.0f, -3.0f, 2.0f)); + CORRADE_COMPARE(transformed.normal(), Vector3(Constants::sqrt2(), 0, -Constants::sqrt2())); /* The normal should stay normalized */ - plane.applyTransformationMatrix(Matrix4::scaling({1.5f, 2.0f, 3.0f})); - CORRADE_COMPARE(plane.transformedPosition(), Vector3(1.5f, 4.0f, 9.0f)); - CORRADE_COMPARE(plane.transformedNormal(), Vector3(Constants::sqrt2(), -Constants::sqrt2(), 0)); + const auto scaled = plane.transformed(Matrix4::scaling({1.5f, 2.0f, 3.0f})); + CORRADE_COMPARE(scaled.position(), Vector3(1.5f, 4.0f, 9.0f)); + CORRADE_COMPARE(scaled.normal(), Vector3(Constants::sqrt2(), -Constants::sqrt2(), 0)); } void PlaneTest::collisionLine() { @@ -64,11 +65,6 @@ void PlaneTest::collisionLine() { Physics::Line3D line2({0.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}); Physics::Line3D line3({0.0f, 1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}); - randomTransformation(plane); - randomTransformation(line); - randomTransformation(line2); - randomTransformation(line3); - VERIFY_COLLIDES(plane, line); VERIFY_COLLIDES(plane, line2); VERIFY_NOT_COLLIDES(plane, line3); @@ -80,11 +76,6 @@ void PlaneTest::collisionLineSegment() { Physics::LineSegment3D line2({0.0f, 0.1f, 0.0f}, {0.0f, 7.0f, 0.0f}); Physics::LineSegment3D line3({0.0f, -7.0f, 0.0f}, {0.0f, -0.1f, 0.0f}); - randomTransformation(plane); - randomTransformation(line); - randomTransformation(line2); - randomTransformation(line3); - VERIFY_COLLIDES(plane, line); VERIFY_NOT_COLLIDES(plane, line2); VERIFY_NOT_COLLIDES(plane, line3); diff --git a/src/Physics/Test/PointTest.cpp b/src/Physics/Test/PointTest.cpp index f2e10188c..741484a26 100644 --- a/src/Physics/Test/PointTest.cpp +++ b/src/Physics/Test/PointTest.cpp @@ -25,6 +25,7 @@ #include #include "Math/Matrix4.h" +#include "Magnum.h" #include "Physics/Point.h" namespace Magnum { namespace Physics { namespace Test { @@ -33,17 +34,17 @@ class PointTest: public Corrade::TestSuite::Tester { public: PointTest(); - void applyTransformation(); + void transformed(); }; PointTest::PointTest() { - addTests({&PointTest::applyTransformation}); + addTests({&PointTest::transformed}); } -void PointTest::applyTransformation() { - Physics::Point3D point({1.0f, 2.0f, 3.0f}); - point.applyTransformationMatrix(Matrix4::translation({5.0f, 6.0f, 7.0f})); - CORRADE_COMPARE(point.transformedPosition(), Vector3(6.0f, 8.0f, 10.0f)); +void PointTest::transformed() { + const auto point = Physics::Point3D({1.0f, 2.0f, 3.0f}) + .transformed(Matrix4::translation({5.0f, 6.0f, 7.0f})); + CORRADE_COMPARE(point.position(), Vector3(6.0f, 8.0f, 10.0f)); } }}} diff --git a/src/Physics/Test/ShapeTestBase.h b/src/Physics/Test/ShapeTestBase.h index 9e9f52304..52ff4a130 100644 --- a/src/Physics/Test/ShapeTestBase.h +++ b/src/Physics/Test/ShapeTestBase.h @@ -26,29 +26,15 @@ #include -#include "Math/Matrix4.h" -#include "Magnum.h" - namespace Magnum { namespace Physics { namespace Test { -class ShapeTestBase { - protected: - template void randomTransformation(T& shape) { - shape.applyTransformationMatrix(Matrix4::translation({7.0f, 8.0f, -9.0f})); - } -}; - #define VERIFY_COLLIDES(a, b) \ CORRADE_VERIFY(a % b); \ - CORRADE_VERIFY(b % a); \ - CORRADE_VERIFY(a.collides(&b)); \ - CORRADE_VERIFY(b.collides(&a)); + CORRADE_VERIFY(b % a); #define VERIFY_NOT_COLLIDES(a, b) \ CORRADE_VERIFY(!(a % b)); \ - CORRADE_VERIFY(!(b % a)); \ - CORRADE_VERIFY(!(a.collides(&b))); \ - CORRADE_VERIFY(!(b.collides(&a))); + CORRADE_VERIFY(!(b % a)); }}} diff --git a/src/Physics/Test/SphereTest.cpp b/src/Physics/Test/SphereTest.cpp index ba50a5b15..30167fd5e 100644 --- a/src/Physics/Test/SphereTest.cpp +++ b/src/Physics/Test/SphereTest.cpp @@ -22,6 +22,8 @@ DEALINGS IN THE SOFTWARE. */ +#include "Math/Matrix4.h" +#include "Magnum.h" #include "Physics/LineSegment.h" #include "Physics/Point.h" #include "Physics/Sphere.h" @@ -30,11 +32,11 @@ namespace Magnum { namespace Physics { namespace Test { -class SphereTest: public Corrade::TestSuite::Tester, ShapeTestBase { +class SphereTest: public Corrade::TestSuite::Tester { public: SphereTest(); - void applyTransformation(); + void transformed(); void collisionPoint(); void collisionLine(); void collisionLineSegment(); @@ -42,28 +44,28 @@ class SphereTest: public Corrade::TestSuite::Tester, ShapeTestBase { }; SphereTest::SphereTest() { - addTests({&SphereTest::applyTransformation, + addTests({&SphereTest::transformed, &SphereTest::collisionPoint, &SphereTest::collisionLine, &SphereTest::collisionLineSegment, &SphereTest::collisionSphere}); } -void SphereTest::applyTransformation() { - Physics::Sphere3D sphere({1.0f, 2.0f, 3.0f}, 7.0f); +void SphereTest::transformed() { + const Physics::Sphere3D sphere({1.0f, 2.0f, 3.0f}, 7.0f); - sphere.applyTransformationMatrix(Matrix4::rotation(Deg(90.0f), Vector3::yAxis())); - CORRADE_COMPARE(sphere.transformedPosition(), Vector3(3.0f, 2.0f, -1.0f)); - CORRADE_COMPARE(sphere.transformedRadius(), 7.0f); + const auto transformed = sphere.transformed(Matrix4::rotation(Deg(90.0f), Vector3::yAxis())); + CORRADE_COMPARE(transformed.position(), Vector3(3.0f, 2.0f, -1.0f)); + CORRADE_COMPARE(transformed.radius(), 7.0f); /* Symmetric scaling */ - sphere.applyTransformationMatrix(Matrix4::scaling(Vector3(2.0f))); - CORRADE_COMPARE(sphere.transformedPosition(), Vector3(2.0f, 4.0f, 6.0f)); - CORRADE_COMPARE(sphere.transformedRadius(), 14.0f); + const auto scaled = sphere.transformed(Matrix4::scaling(Vector3(2.0f))); + CORRADE_COMPARE(scaled.position(), Vector3(2.0f, 4.0f, 6.0f)); + CORRADE_COMPARE(scaled.radius(), 14.0f); /* Apply average scaling to radius */ - sphere.applyTransformationMatrix(Matrix4::scaling({Constants::sqrt3(), -Constants::sqrt2(), 2.0f})); - CORRADE_COMPARE(sphere.transformedRadius(), Constants::sqrt3()*7.0f); + const auto nonEven = sphere.transformed(Matrix4::scaling({Constants::sqrt3(), -Constants::sqrt2(), 2.0f})); + CORRADE_COMPARE(nonEven.radius(), Constants::sqrt3()*7.0f); } void SphereTest::collisionPoint() { @@ -71,10 +73,6 @@ void SphereTest::collisionPoint() { Physics::Point3D point({1.0f, 3.0f, 3.0f}); Physics::Point3D point2({1.0f, 3.0f, 1.0f}); - randomTransformation(sphere); - randomTransformation(point); - randomTransformation(point2); - VERIFY_COLLIDES(sphere, point); VERIFY_NOT_COLLIDES(sphere, point2); } @@ -84,10 +82,6 @@ void SphereTest::collisionLine() { Physics::Line3D line({1.0f, 1.5f, 3.5f}, {1.0f, 2.5f, 2.5f}); Physics::Line3D line2({1.0f, 2.0f, 5.1f}, {1.0f, 3.0f, 5.1f}); - randomTransformation(sphere); - randomTransformation(line); - randomTransformation(line2); - VERIFY_COLLIDES(sphere, line); VERIFY_NOT_COLLIDES(sphere, line2); } @@ -97,10 +91,6 @@ void SphereTest::collisionLineSegment() { Physics::LineSegment3D line({1.0f, 2.0f, 4.9f}, {1.0f, 2.0f, 7.0f}); Physics::LineSegment3D line2({1.0f, 2.0f, 5.1f}, {1.0f, 2.0f, 7.0f}); - randomTransformation(sphere); - randomTransformation(line); - randomTransformation(line2); - VERIFY_COLLIDES(sphere, line); VERIFY_NOT_COLLIDES(sphere, line2); } @@ -110,10 +100,6 @@ void SphereTest::collisionSphere() { Physics::Sphere3D sphere1({1.0f, 3.0f, 5.0f}, 1.0f); Physics::Sphere3D sphere2({1.0f, 3.0f, 0.0f}, 1.0f); - randomTransformation(sphere); - randomTransformation(sphere1); - randomTransformation(sphere2); - VERIFY_COLLIDES(sphere, sphere1); VERIFY_NOT_COLLIDES(sphere, sphere2); }