mirror of https://github.com/mosra/magnum.git
39 changed files with 1630 additions and 1 deletions
@ -0,0 +1,111 @@
|
||||
namespace Magnum { namespace Physics { |
||||
/** @page CollisionDetection Collision detection system |
||||
|
||||
The collision detection system consists of a low-level part, consisting of |
||||
shape collection providing collision detection and high-level part, |
||||
consisting of rigid bodies and their groups. |
||||
|
||||
@subpage CollisionDetectionShapes |
||||
|
||||
@page CollisionDetectionShapes Shapes providing collision detection features |
||||
|
||||
The essential thing in collision detection is to define a complex object with |
||||
collection of simple shapes, for which it is easy to detect collisions. These |
||||
shapes can be either one-, two- or three-dimensional and they can be grouped |
||||
together using five different set operations. |
||||
|
||||
@tableofcontents |
||||
|
||||
@section CollisionDetectionShapeCollection Available shapes |
||||
|
||||
@subsection CollisionDetectionShapes1D One-dimensional shapes |
||||
|
||||
- Physics::Point - @copybrief Physics::Point |
||||
- Physics::Line - @copybrief Physics::Line |
||||
- Physics::LineSegment - @copybrief Physics::LineSegment |
||||
|
||||
One-dimensional shapes don't provide collision detection with each other |
||||
because of numerical instability. |
||||
|
||||
@subsection CollisionDetectionShapes2D Two-dimensional shapes |
||||
|
||||
- Physics::Plane - @copybrief Physics::Plane |
||||
|
||||
@subsection CollisionDetectionShapes3D Three-dimensional shapes |
||||
|
||||
- Physics::Sphere - @copybrief Physics::Sphere |
||||
- Physics::Capsule - @copybrief Physics::Capsule |
||||
- Physics::AxisAlignedBox - @copybrief Physics::AxisAlignedBox |
||||
- Physics::Box - @copybrief Physics::Box |
||||
|
||||
The easiest (and most efficient) shape combination for detecting collisions |
||||
is point and sphere, followed by two spheres. Computing collision of two boxes |
||||
is least efficient. |
||||
|
||||
@section CollisionDetectionShapeGroups Creating hierarchic groups of shapes |
||||
|
||||
Shapes can be grouped together using one of five set operations: complement, |
||||
union, intersection, difference and XOR. These operations are mapped to |
||||
operator~(), operator|(), operator&(), operator-() and operator^(), so for |
||||
example creating complement of union of sphere and box is simple as this: |
||||
@code |
||||
Physics::Sphere sphere; |
||||
Physics::Box box; |
||||
|
||||
Physics::ShapeGroup group = ~(sphere|box); |
||||
@endcode |
||||
|
||||
The resulting object internally stores copies of both shapes, so the original |
||||
instances can be destroyed. For simple combinations appropriate resulting |
||||
shape is generated (e.g. intersection of line and three-dimensional object |
||||
can be a line segment) and stored inside ShapeGroup instead of two original |
||||
objects. |
||||
|
||||
@subsection CollisionDetectionShapeReference Referencing the shapes for later changes |
||||
|
||||
Sometimes you may want to modify the shape based on changes of the object |
||||
itself. In previous example all the shapes were copied into ShapeGroup, so it |
||||
was not possible to change their properties such as sphere radius without |
||||
recreating the group again. You can, however, explicitly pass a reference to |
||||
original object, so you can change it later: |
||||
@code |
||||
Physics::Sphere sphere; |
||||
Physics::Box box; |
||||
|
||||
Physics::ShapeGroup group = ~(std::ref(sphere)|box); |
||||
|
||||
sphere.setRadius(2.0f); |
||||
@endcode |
||||
|
||||
Note that passing a reference implies that you must not destroy the original |
||||
instance (in this case the sphere). Also because the referenced instance could |
||||
change, there are no shape optimizations done, unlike above. |
||||
|
||||
@subsection CollisionDetectionShapeSimplification Providing simplified version of shape for better performance |
||||
|
||||
If there are many shapes grouped together, it might hurt performance of |
||||
collision detection, because it might be testing collision with more shapes |
||||
than necessary. It's then good to specify simplified version of such shape, |
||||
so the collision detection is done on the original if and only if collision |
||||
was detected with the simplified shape. It is in fact intersection group - |
||||
the collision is initially detected on first (simplified) shape and then on |
||||
the other: |
||||
@code |
||||
Physics::AxisAlignedBox simplified; |
||||
|
||||
Physics::ShapeGroup object = simplified & (sphere|box); |
||||
@endcode |
||||
|
||||
@section CollisionDetectionShapeCollisions Detecting shape collisions |
||||
|
||||
Shape pairs which have collision detection implemented can be tested for |
||||
collision using operator%(), for example: |
||||
@code |
||||
Physics::Point point; |
||||
Physics::Sphere sphere; |
||||
|
||||
bool collide = point % sphere; |
||||
@endcode |
||||
|
||||
*/ |
||||
}}} |
||||
@ -0,0 +1,28 @@
|
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
#include "AbstractShape.h" |
||||
|
||||
namespace Magnum { namespace Physics { |
||||
|
||||
bool AbstractShape::collides(const AbstractShape* other) const { |
||||
/* Operate only with simpler types than this */ |
||||
if(static_cast<int>(other->type()) > static_cast<int>(type())) |
||||
return other->collides(this); |
||||
|
||||
return false; |
||||
} |
||||
|
||||
}} |
||||
@ -0,0 +1,79 @@
|
||||
#ifndef Magnum_Physics_AbstractShape_h |
||||
#define Magnum_Physics_AbstractShape_h |
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
/** @file
|
||||
* @brief Class Magnum::Physics::AbstractShape |
||||
*/ |
||||
|
||||
#include "Magnum.h" |
||||
|
||||
namespace Magnum { namespace Physics { |
||||
|
||||
/**
|
||||
@brief Base class for shapes |
||||
|
||||
See @ref CollisionDetection for brief introduction. |
||||
*/ |
||||
class PHYSICS_EXPORT AbstractShape { |
||||
public: |
||||
/**
|
||||
* @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. |
||||
*/ |
||||
enum class Type { |
||||
Point, |
||||
Line, |
||||
LineSegment, |
||||
Plane, |
||||
Sphere, |
||||
Capsule, |
||||
AxisAlignedBox, |
||||
Box, |
||||
ShapeGroup |
||||
}; |
||||
|
||||
/** @brief Destructor */ |
||||
virtual inline ~AbstractShape() {} |
||||
|
||||
/** @brief Shape type */ |
||||
virtual Type type() const = 0; |
||||
|
||||
/**
|
||||
* @brief Apply transformation |
||||
* |
||||
* Applies transformation to user-defined shape properties and caches |
||||
* them for later usage in collision detection. |
||||
*/ |
||||
virtual void applyTransformation(const Matrix4& transformation) = 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; |
||||
}; |
||||
|
||||
}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,25 @@
|
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
#include "AxisAlignedBox.h" |
||||
|
||||
namespace Magnum { namespace Physics { |
||||
|
||||
void AxisAlignedBox::applyTransformation(const Matrix4& transformation) { |
||||
_transformedPosition = (transformation*Vector4(_position)).xyz(); |
||||
_transformedSize = transformation.rotationScaling()*_size; |
||||
} |
||||
|
||||
}} |
||||
@ -0,0 +1,70 @@
|
||||
#ifndef Magnum_Physics_AxisAlignedBox_h |
||||
#define Magnum_Physics_AxisAlignedBox_h |
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
/** @file
|
||||
* @brief Class Magnum::Physics::AxisAlignedBox |
||||
*/ |
||||
|
||||
#include "AbstractShape.h" |
||||
|
||||
namespace Magnum { namespace Physics { |
||||
|
||||
/** @brief Axis aligned box */ |
||||
class PHYSICS_EXPORT AxisAlignedBox: public AbstractShape { |
||||
public: |
||||
/** @brief Constructor */ |
||||
inline constexpr AxisAlignedBox(const Vector3& position, const Vector3& size): _position(position), _transformedPosition(position), _size(size), _transformedSize(size) {} |
||||
|
||||
void applyTransformation(const Matrix4& transformation); |
||||
|
||||
/** @brief Position */ |
||||
inline Vector3 position() const { return _position; } |
||||
|
||||
/** @brief Set position */ |
||||
inline void setPosition(const Vector3& position) { |
||||
_position = position; |
||||
} |
||||
|
||||
/** @brief Size */ |
||||
inline Vector3 size() const { return _size; } |
||||
|
||||
/** @brief Set size */ |
||||
inline void setSize(const Vector3& size) { |
||||
_size = size; |
||||
} |
||||
|
||||
/** @brief Transformed position */ |
||||
inline Vector3 transformedPosition() const { |
||||
return _transformedPosition; |
||||
} |
||||
|
||||
/** @brief Transformed size */ |
||||
inline Vector3 transformedSize() const { |
||||
return _transformedSize; |
||||
} |
||||
|
||||
protected: |
||||
inline Type type() const { return Type::AxisAlignedBox; } |
||||
|
||||
private: |
||||
Vector3 _position, _transformedPosition, |
||||
_size, _transformedSize; |
||||
}; |
||||
|
||||
}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,58 @@
|
||||
#ifndef Magnum_Physics_Box_h |
||||
#define Magnum_Physics_Box_h |
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
/** @file
|
||||
* @brief Class Magnum::Physics::Box |
||||
*/ |
||||
|
||||
#include "AbstractShape.h" |
||||
|
||||
namespace Magnum { namespace Physics { |
||||
|
||||
/** @brief Unit size box with assigned transformation matrix */ |
||||
class Box: public AbstractShape { |
||||
public: |
||||
/** @brief Constructor */ |
||||
inline constexpr Box(const Matrix4& transformation): _transformation(transformation), _transformedTransformation(transformation) {} |
||||
|
||||
inline void applyTransformation(const Matrix4& transformation) { |
||||
_transformedTransformation = transformation*_transformation; |
||||
} |
||||
|
||||
/** @brief Transformation */ |
||||
inline constexpr Matrix4 transformation() const { return _transformation; } |
||||
|
||||
/** @brief Set transformation */ |
||||
inline Vector3 setTransformation(const Matrix4& transformation) { |
||||
_transformation = transformation; |
||||
} |
||||
|
||||
/** @brief Transformed transformation */ |
||||
inline constexpr Vector3 transformedTransformation() const { |
||||
return _transformedTransformation; |
||||
} |
||||
|
||||
protected: |
||||
inline Type type() const { return Type::Box; } |
||||
|
||||
private: |
||||
Vector3 _transformation, _transformedTransformation; |
||||
}; |
||||
|
||||
}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,24 @@
|
||||
set(MagnumPhysics_SRCS |
||||
AbstractShape.cpp |
||||
AxisAlignedBox.cpp |
||||
Capsule.cpp |
||||
Line.cpp |
||||
Plane.cpp |
||||
ShapeGroup.cpp |
||||
Sphere.cpp |
||||
) |
||||
|
||||
add_library(MagnumPhysics SHARED ${MagnumPhysics_SRCS}) |
||||
|
||||
if(WIN32) |
||||
set_target_properties(MagnumPhysics PROPERTIES COMPILE_FLAGS -DPHYSICS_EXPORTING) |
||||
endif() |
||||
|
||||
target_link_libraries(MagnumPhysics Magnum) |
||||
|
||||
install(TARGETS MagnumPhysics DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) |
||||
|
||||
if(BUILD_TESTS) |
||||
enable_testing() |
||||
add_subdirectory(Test) |
||||
endif() |
||||
@ -0,0 +1,27 @@
|
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
#include "Capsule.h" |
||||
|
||||
namespace Magnum { namespace Physics { |
||||
|
||||
void Capsule::applyTransformation(const Matrix4& transformation) { |
||||
_transformedA = (transformation*Vector4(_a)).xyz(); |
||||
_transformedB = (transformation*Vector4(_b)).xyz(); |
||||
float scaling = (transformation.rotationScaling()*Vector3(1/Math::Constants<float>::Sqrt3)).length(); |
||||
_transformedRadius = scaling*_radius; |
||||
} |
||||
|
||||
}} |
||||
@ -0,0 +1,73 @@
|
||||
#ifndef Magnum_Physics_Capsule_h |
||||
#define Magnum_Physics_Capsule_h |
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
/** @file
|
||||
* @brief Class Magnum::Physics::Capsule |
||||
*/ |
||||
|
||||
#include "AbstractShape.h" |
||||
|
||||
namespace Magnum { namespace Physics { |
||||
|
||||
/**
|
||||
@brief %Capsule defined by cylinder start and end point and radius |
||||
|
||||
Unlike other elements the capsule doesn't support asymmetric scaling. When |
||||
applying transformation, the scale factor is averaged from all axes. |
||||
*/ |
||||
class PHYSICS_EXPORT Capsule: public AbstractShape { |
||||
public: |
||||
/** @brief Constructor */ |
||||
inline constexpr Capsule(const Vector3& a, const Vector3& b, float radius): _a(a), _transformedA(a), _b(b), _transformedB(b), _radius(radius), _transformedRadius(radius) {} |
||||
|
||||
void applyTransformation(const Matrix4& transformation); |
||||
|
||||
inline Vector3 a() const { return _a; } /**< @brief Start point */ |
||||
inline Vector3 b() const { return _a; } /**< @brief End point */ |
||||
|
||||
inline void setA(const Vector3& a) { _a = a; } /**< @brief Set start point */ |
||||
inline void setB(const Vector3& b) { _b = b; } /**< @brief Set end point */ |
||||
|
||||
/** @brief Radius */ |
||||
inline float radius() const { return _radius; } |
||||
|
||||
/** @brief Set radius */ |
||||
inline void setRadius(float radius) { _radius = radius; } |
||||
|
||||
/** @brief Transformed first point */ |
||||
inline Vector3 transformedA() const { return _transformedA; } |
||||
|
||||
/** @brief Transformed second point */ |
||||
inline Vector3 transformedB() const { return _transformedB; } |
||||
|
||||
/** @brief Transformed radius */ |
||||
inline float transformedRadius() const { |
||||
return _transformedRadius; |
||||
} |
||||
|
||||
protected: |
||||
inline Type type() const { return Type::Capsule; } |
||||
|
||||
private: |
||||
Vector3 _a, _transformedA, |
||||
_b, _transformedB; |
||||
float _radius, _transformedRadius; |
||||
}; |
||||
|
||||
}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,25 @@
|
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
#include "Line.h" |
||||
|
||||
namespace Magnum { namespace Physics { |
||||
|
||||
void Line::applyTransformation(const Matrix4& transformation) { |
||||
_transformedA = (transformation*Vector4(_a)).xyz(); |
||||
_transformedB = (transformation*Vector4(_b)).xyz(); |
||||
} |
||||
|
||||
}} |
||||
@ -0,0 +1,56 @@
|
||||
#ifndef Magnum_Physics_Line_h |
||||
#define Magnum_Physics_Line_h |
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
/** @file
|
||||
* @brief Class Magnum::Physics::Line |
||||
*/ |
||||
|
||||
#include "AbstractShape.h" |
||||
|
||||
namespace Magnum { namespace Physics { |
||||
|
||||
/** @brief Infinite line, defined by two points */ |
||||
class PHYSICS_EXPORT Line: public AbstractShape { |
||||
public: |
||||
/** @brief Constructor */ |
||||
inline Line(const Vector3& a, const Vector3& b): _a(a), _transformedA(a), _b(b), _transformedB(b) {} |
||||
|
||||
void applyTransformation(const Matrix4& transformation); |
||||
|
||||
inline Vector3 a() const { return _a; } /**< @brief First point */ |
||||
inline Vector3 b() const { return _a; } /**< @brief Second point */ |
||||
|
||||
inline void setA(const Vector3& a) { _a = a; } /**< @brief Set first point */ |
||||
inline void setB(const Vector3& b) { _b = b; } /**< @brief Set second point */ |
||||
|
||||
/** @brief Transformed first point */ |
||||
inline Vector3 transformedA() const { return _transformedA; } |
||||
|
||||
/** @brief Transformed second point */ |
||||
inline Vector3 transformedB() const { return _transformedB; } |
||||
|
||||
protected: |
||||
inline Type type() const { return Type::Line; } |
||||
|
||||
private: |
||||
Vector3 _a, _transformedA, |
||||
_b, _transformedB; |
||||
}; |
||||
|
||||
}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,38 @@
|
||||
#ifndef Magnum_Physics_LineSegment_h |
||||
#define Magnum_Physics_LineSegment_h |
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
/** @file
|
||||
* @brief Class Magnum::Physics::LineSegment |
||||
*/ |
||||
|
||||
#include "Line.h" |
||||
|
||||
namespace Magnum { namespace Physics { |
||||
|
||||
/** @brief %Line segment, defined by starting and ending point */ |
||||
class LineSegment: public Line { |
||||
public: |
||||
/** @brief Constructor */ |
||||
LineSegment(const Vector3& a, const Vector3& b): Line(a, b) {} |
||||
|
||||
protected: |
||||
inline Type type() const { return Type::LineSegment; } |
||||
}; |
||||
|
||||
}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,25 @@
|
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
#include "Plane.h" |
||||
|
||||
namespace Magnum { namespace Physics { |
||||
|
||||
void Plane::applyTransformation(const Matrix4& transformation) { |
||||
_transformedPosition = (transformation*Vector4(_position)).xyz(); |
||||
_transformedNormal = transformation.rotation()*_normal; |
||||
} |
||||
|
||||
}} |
||||
@ -0,0 +1,70 @@
|
||||
#ifndef Magnum_Physics_Plane_h |
||||
#define Magnum_Physics_Plane_h |
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
/** @file
|
||||
* @brief Class Magnum::Physics::Plane |
||||
*/ |
||||
|
||||
#include "AbstractShape.h" |
||||
|
||||
namespace Magnum { namespace Physics { |
||||
|
||||
/** @brief Infinite plane, defined by position and normal */ |
||||
class PHYSICS_EXPORT Plane: public AbstractShape { |
||||
public: |
||||
/** @brief Constructor */ |
||||
inline constexpr Plane(const Vector3& position, const Vector3& normal): _position(position), _transformedPosition(position), _normal(normal), _transformedNormal(normal) {} |
||||
|
||||
void applyTransformation(const Matrix4& transformation); |
||||
|
||||
/** @brief Position */ |
||||
inline Vector3 position() const { return _position; } |
||||
|
||||
/** @brief Set position */ |
||||
inline void setPosition(const Vector3& position) { |
||||
_position = position; |
||||
} |
||||
|
||||
/** @brief Normal */ |
||||
inline 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; |
||||
} |
||||
|
||||
protected: |
||||
inline Type type() const { return Type::Plane; } |
||||
|
||||
private: |
||||
Vector3 _position, _transformedPosition, |
||||
_normal, _transformedNormal; |
||||
}; |
||||
|
||||
}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,58 @@
|
||||
#ifndef Magnum_Physics_Point_h |
||||
#define Magnum_Physics_Point_h |
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
/** @file
|
||||
* @brief Class Magnum::Physics::Point |
||||
*/ |
||||
|
||||
#include "AbstractShape.h" |
||||
|
||||
namespace Magnum { namespace Physics { |
||||
|
||||
/** @brief %Point */ |
||||
class Point: public AbstractShape { |
||||
public: |
||||
/** @brief Constructor */ |
||||
inline constexpr Point(const Vector3& position): _position(position), _transformedPosition(position) {} |
||||
|
||||
inline void applyTransformation(const Matrix4& transformation) { |
||||
_transformedPosition = (transformation*Vector4(_position)).xyz(); |
||||
} |
||||
|
||||
/** @brief Position */ |
||||
inline Vector3 position() const { return _position; } |
||||
|
||||
/** @brief Set position */ |
||||
inline void setPosition(const Vector3& position) { |
||||
_position = position; |
||||
} |
||||
|
||||
/** @brief Transformed position */ |
||||
inline Vector3 transformedPosition() const { |
||||
return _transformedPosition; |
||||
} |
||||
|
||||
protected: |
||||
inline Type type() const { return Type::Point; } |
||||
|
||||
private: |
||||
Vector3 _position, _transformedPosition; |
||||
}; |
||||
|
||||
}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,65 @@
|
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
#include "ShapeGroup.h" |
||||
|
||||
namespace Magnum { namespace Physics { |
||||
|
||||
ShapeGroup::ShapeGroup(ShapeGroup&& other): operation(other.operation), a(other.a), b(other.b) { |
||||
other.operation = AlwaysFalse; |
||||
other.a = nullptr; |
||||
other.b = nullptr; |
||||
} |
||||
|
||||
ShapeGroup::~ShapeGroup() { |
||||
if(!(operation & RefA)) delete a; |
||||
if(!(operation & RefB)) delete b; |
||||
} |
||||
|
||||
ShapeGroup& ShapeGroup::operator=(ShapeGroup&& other) { |
||||
if(!(operation & RefA)) delete a; |
||||
if(!(operation & RefB)) delete b; |
||||
|
||||
operation = other.operation; |
||||
a = other.a; |
||||
b = other.b; |
||||
|
||||
other.operation = AlwaysFalse; |
||||
other.a = nullptr; |
||||
other.b = nullptr; |
||||
|
||||
return *this; |
||||
} |
||||
|
||||
void ShapeGroup::applyTransformation(const Matrix4& transformation) { |
||||
if(a) a->applyTransformation(transformation); |
||||
if(b) b->applyTransformation(transformation); |
||||
} |
||||
|
||||
bool ShapeGroup::collides(const AbstractShape* other) const { |
||||
switch(operation & ~RefAB) { |
||||
case Complement: return !a->collides(other); |
||||
case Union: return a->collides(other) || b->collides(other); |
||||
case Intersection: return a->collides(other) && b->collides(other); |
||||
case Difference: return a->collides(other) && !b->collides(other); |
||||
case Xor: return a->collides(other) != b->collides(other); |
||||
case FirstObjectOnly: return a->collides(other); |
||||
|
||||
default: |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
}} |
||||
@ -0,0 +1,177 @@
|
||||
#ifndef Magnum_Physics_ShapeGroup_h |
||||
#define Magnum_Physics_ShapeGroup_h |
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
/** @file
|
||||
* @brief Class Magnum::Physics::ShapeGroup |
||||
*/ |
||||
|
||||
#include "AbstractShape.h" |
||||
|
||||
namespace Magnum { namespace Physics { |
||||
|
||||
#ifndef DOXYGEN_GENERATING_OUTPUT |
||||
#define enableIfIsBaseType typename std::enable_if<std::is_base_of<AbstractShape, T>::value, ShapeGroup>::type |
||||
#define enableIfAreBaseType typename std::enable_if<std::is_base_of<AbstractShape, T>::value && std::is_base_of<AbstractShape, U>::value, ShapeGroup>::type |
||||
#endif |
||||
|
||||
/**
|
||||
@brief Collider group with defined set operation |
||||
|
||||
Result of union, intersection, substraction or XOR of two collider objects. |
||||
See @ref CollisionDetection for brief introduction. |
||||
*/ |
||||
class PHYSICS_EXPORT ShapeGroup: public AbstractShape { |
||||
#ifndef DOXYGEN_GENERATING_OUTPUT |
||||
template<class T> friend constexpr enableIfIsBaseType operator~(const T& a); |
||||
template<class T> friend constexpr enableIfIsBaseType operator~(T&& a); |
||||
template<class T> friend constexpr enableIfIsBaseType operator~(T& a); |
||||
|
||||
#define friendOp(char) \ |
||||
template<class T, class U> friend constexpr enableIfAreBaseType operator char(const T& a, const U& b); \
|
||||
template<class T, class U> friend constexpr enableIfAreBaseType operator char(const T& a, U&& b); \
|
||||
template<class T, class U> friend constexpr enableIfAreBaseType operator char(T&& a, const U& b); \
|
||||
template<class T, class U> friend constexpr enableIfAreBaseType operator char(T&& a, U&& b); \
|
||||
template<class T, class U> friend constexpr enableIfAreBaseType operator char(const T& a, std::reference_wrapper<U> b); \
|
||||
template<class T, class U> friend constexpr enableIfAreBaseType operator char(T&& a, std::reference_wrapper<U> b); \
|
||||
template<class T, class U> friend constexpr enableIfAreBaseType operator char(std::reference_wrapper<T> a, const U& b); \
|
||||
template<class T, class U> friend constexpr enableIfAreBaseType operator char(std::reference_wrapper<T> a, U&& b); \
|
||||
template<class T, class U> friend constexpr enableIfAreBaseType operator char(std::reference_wrapper<T> a, std::reference_wrapper<U> b); |
||||
friendOp(|) |
||||
friendOp(&) |
||||
friendOp(-) |
||||
friendOp(^) |
||||
#undef friendOp |
||||
#endif |
||||
|
||||
ShapeGroup(const ShapeGroup& other) = delete; |
||||
ShapeGroup& operator=(const ShapeGroup& other) = delete; |
||||
|
||||
private: |
||||
enum Operation { |
||||
RefA = 0x01, |
||||
RefB = 0x02, |
||||
RefAB = 0x03, |
||||
Complement = 1 << 2, |
||||
Union = 2 << 2, |
||||
Intersection = 3 << 2, |
||||
Difference = 4 << 2, |
||||
Xor = 5 << 2, |
||||
FirstObjectOnly = 6 << 2, |
||||
AlwaysFalse = 7 << 2 |
||||
}; |
||||
|
||||
public: |
||||
/** @brief Default constructor */ |
||||
inline ShapeGroup(): operation(AlwaysFalse), a(nullptr), b(nullptr) {} |
||||
|
||||
/** @brief Move constructor */ |
||||
ShapeGroup(ShapeGroup&& other); |
||||
|
||||
/** @brief Destructor */ |
||||
~ShapeGroup(); |
||||
|
||||
/** @brief Move assignment */ |
||||
ShapeGroup& operator=(ShapeGroup&& other); |
||||
|
||||
void applyTransformation(const Matrix4& transformation); |
||||
|
||||
bool collides(const AbstractShape* other) const; |
||||
|
||||
protected: |
||||
virtual Type type() const { return Type::ShapeGroup; } |
||||
|
||||
private: |
||||
inline constexpr ShapeGroup(int operation, AbstractShape* a, AbstractShape* b): operation(operation), a(a), b(b) {} |
||||
|
||||
int operation; |
||||
AbstractShape* a; |
||||
AbstractShape* b; |
||||
}; |
||||
|
||||
/** @brief Complement of shape */ |
||||
template<class T> inline constexpr enableIfIsBaseType operator~(const T& a) { |
||||
return ShapeGroup(ShapeGroup::Complement, new T(a), nullptr); |
||||
} |
||||
#ifndef DOXYGEN_GENERATING_OUTPUT |
||||
template<class T> inline constexpr enableIfIsBaseType operator~(T&& a) { |
||||
return ShapeGroup(ShapeGroup::Complement, new T(std::forward<T>(a)), nullptr); |
||||
} |
||||
template<class T> inline constexpr enableIfIsBaseType operator~(T& a) { |
||||
return ShapeGroup(ShapeGroup::Complement|ShapeGroup::RefA, &a.get(), nullptr); |
||||
} |
||||
#endif |
||||
|
||||
#ifdef DOXYGEN_GENERATING_OUTPUT |
||||
/** @brief Union of two shapes */ |
||||
template<class T, class U> inline constexpr ShapeGroup operator&(T a, U b); |
||||
|
||||
/**
|
||||
@brief Intersection of two shapes |
||||
|
||||
Collision with @p a is computed first, so this operation can be also used for |
||||
providing simplified version for shape @p b. See @ref CollisionDetectionShapeGroups |
||||
for an example. |
||||
*/ |
||||
template<class T, class U> inline constexpr ShapeGroup operator&(T a, U b); |
||||
|
||||
/** @brief Difference of two shapes */ |
||||
template<class T, class U> inline constexpr ShapeGroup operator-(T a, U b); |
||||
|
||||
/** @brief XOR of two shapes */ |
||||
template<class T, class U> inline constexpr ShapeGroup operator^(T a, U b); |
||||
#else |
||||
#define op(type, char) \ |
||||
template<class T, class U> inline constexpr enableIfAreBaseType operator char(const T& a, const U& b) { \
|
||||
return ShapeGroup(ShapeGroup::type, new T(a), new U(b)); \
|
||||
} \
|
||||
template<class T, class U> inline constexpr enableIfAreBaseType operator char(const T& a, U&& b) { \
|
||||
return ShapeGroup(ShapeGroup::type, new T(a), new U(std::forward<U>(b))); \
|
||||
} \
|
||||
template<class T, class U> inline constexpr enableIfAreBaseType operator char(T&& a, const U& b) { \
|
||||
return ShapeGroup(ShapeGroup::type, new T(std::forward<T>(a)), new U(b)); \
|
||||
} \
|
||||
template<class T, class U> inline constexpr enableIfAreBaseType operator char(T&& a, U&& b) { \
|
||||
return ShapeGroup(ShapeGroup::type, new T(std::forward<T>(a)), new U(std::forward<U>(b))); \
|
||||
} \
|
||||
template<class T, class U> inline constexpr enableIfAreBaseType operator char(const T& a, std::reference_wrapper<U> b) { \
|
||||
return ShapeGroup(ShapeGroup::type|ShapeGroup::RefB, new T(a), &b.get()); \
|
||||
} \
|
||||
template<class T, class U> inline constexpr enableIfAreBaseType operator char(T&& a, std::reference_wrapper<U> b) { \
|
||||
return ShapeGroup(ShapeGroup::type|ShapeGroup::RefB, new T(std::forward<T>(a)), &b.get()); \
|
||||
} \
|
||||
template<class T, class U> inline constexpr enableIfAreBaseType operator char(std::reference_wrapper<T> a, const U& b) { \
|
||||
return ShapeGroup(ShapeGroup::type|ShapeGroup::RefA, &a.get(), new U(b)); \
|
||||
} \
|
||||
template<class T, class U> inline constexpr enableIfAreBaseType operator char(std::reference_wrapper<T> a, U&& b) { \
|
||||
return ShapeGroup(ShapeGroup::type|ShapeGroup::RefA, &a.get(), new U(std::forward<U>(b))); \
|
||||
} \
|
||||
template<class T, class U> inline constexpr enableIfAreBaseType operator char(std::reference_wrapper<T> a, std::reference_wrapper<U> b) { \
|
||||
return ShapeGroup(ShapeGroup::type|ShapeGroup::RefAB, &a.get(), &b.get()); \
|
||||
} |
||||
op(Union, |) |
||||
op(Intersection, &) |
||||
op(Difference, -) |
||||
op(Xor, ^) |
||||
#undef op |
||||
#endif |
||||
|
||||
#undef enableIfIsBaseType |
||||
#undef enableIfAreBaseType |
||||
|
||||
}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,26 @@
|
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
#include "Sphere.h" |
||||
|
||||
namespace Magnum { namespace Physics { |
||||
|
||||
void Sphere::applyTransformation(const Matrix4& transformation) { |
||||
_transformedPosition = (transformation*Vector4(_position)).xyz(); |
||||
float scaling = (transformation.rotationScaling()*Vector3(1/Math::Constants<float>::Sqrt3)).length(); |
||||
_transformedRadius = scaling*_radius; |
||||
} |
||||
|
||||
}} |
||||
@ -0,0 +1,71 @@
|
||||
#ifndef Magnum_Physics_Sphere_h |
||||
#define Magnum_Physics_Sphere_h |
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
/** @file
|
||||
* @brief Class Magnum::Physics::Sphere |
||||
*/ |
||||
|
||||
#include "AbstractShape.h" |
||||
|
||||
namespace Magnum { namespace Physics { |
||||
|
||||
/**
|
||||
@brief %Sphere defined by position and radius |
||||
|
||||
Unlike other elements the sphere doesn't support asymmetric scaling. When |
||||
applying transformation, the scale factor is averaged from all axes. |
||||
*/ |
||||
class PHYSICS_EXPORT Sphere: public AbstractShape { |
||||
public: |
||||
/** @brief Constructor */ |
||||
inline constexpr Sphere(const Vector3& position, float radius): _position(position), _transformedPosition(position), _radius(radius), _transformedRadius(radius) {} |
||||
|
||||
void applyTransformation(const Matrix4& transformation); |
||||
|
||||
/** @brief Position */ |
||||
inline Vector3 position() const { return _position; } |
||||
|
||||
/** @brief Set position */ |
||||
inline void setPosition(const Vector3& position) { _position = position; } |
||||
|
||||
/** @brief Radius */ |
||||
inline float radius() const { return _radius; } |
||||
|
||||
/** @brief Set radius */ |
||||
inline void setRadius(float radius) { _radius = radius; } |
||||
|
||||
/** @brief Transformed position */ |
||||
inline Vector3 transformedPosition() const { |
||||
return _transformedPosition; |
||||
} |
||||
|
||||
/** @brief Transformed radius */ |
||||
inline float transformedRadius() const { |
||||
return _transformedRadius; |
||||
} |
||||
|
||||
protected: |
||||
inline Type type() const { return Type::Sphere; } |
||||
|
||||
private: |
||||
Vector3 _position, _transformedPosition; |
||||
float _radius, _transformedRadius; |
||||
}; |
||||
|
||||
}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,38 @@
|
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
#include "AxisAlignedBoxTest.h" |
||||
|
||||
#include <QtTest/QTest> |
||||
|
||||
#include "Physics/AxisAlignedBox.h" |
||||
|
||||
QTEST_APPLESS_MAIN(Magnum::Physics::Test::AxisAlignedBoxTest) |
||||
|
||||
namespace Magnum { namespace Physics { namespace Test { |
||||
|
||||
void AxisAlignedBoxTest::applyTransformation() { |
||||
Physics::AxisAlignedBox box({-1.0f, -2.0f, -3.0f}, {1.0f, 2.0f, 3.0f}); |
||||
|
||||
box.applyTransformation(Matrix4::scaling({2.0f, -1.0f, 1.5f})); |
||||
QVERIFY((box.transformedPosition() == Vector3(-2.0f, 2.0f, -4.5f))); |
||||
QVERIFY((box.transformedSize() == Vector3(2.0f, -2.0f, 4.5f))); |
||||
|
||||
box.applyTransformation(Matrix4::translation(Vector3(1.0f))*Matrix4::rotation(deg(90.0f), Vector3::xAxis())); |
||||
QVERIFY((box.transformedPosition() == Vector3(0.0f, 4.0f, -1.0f))); |
||||
QVERIFY((box.transformedSize() == Vector3(1.0f, -3.0f, 2.0f))); |
||||
} |
||||
|
||||
}}} |
||||
@ -0,0 +1,31 @@
|
||||
#ifndef Magnum_Physics_Test_AxisAlignedBoxTest_h |
||||
#define Magnum_Physics_Test_AxisAlignedBoxTest_h |
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
#include <QtCore/QObject> |
||||
|
||||
namespace Magnum { namespace Physics { namespace Test { |
||||
|
||||
class AxisAlignedBoxTest: public QObject { |
||||
Q_OBJECT |
||||
|
||||
private slots: |
||||
void applyTransformation(); |
||||
}; |
||||
|
||||
}}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,7 @@
|
||||
corrade_add_test(PhysicsAxisAlignedBoxTest AxisAlignedBoxTest.h AxisAlignedBoxTest.cpp MagnumPhysics) |
||||
corrade_add_test(PhysicsCapsuleTest CapsuleTest.h CapsuleTest.cpp MagnumPhysics) |
||||
corrade_add_test(PhysicsLineTest LineTest.h LineTest.cpp MagnumPhysics) |
||||
corrade_add_test(PhysicsPlaneTest PlaneTest.h PlaneTest.cpp MagnumPhysics) |
||||
corrade_add_test(PhysicsPointTest PointTest.h PointTest.cpp MagnumPhysics) |
||||
corrade_add_test(PhysicsShapeGroupTest ShapeGroupTest.h ShapeGroupTest.cpp MagnumPhysics) |
||||
corrade_add_test(PhysicsSphereTest SphereTest.h SphereTest.cpp MagnumPhysics) |
||||
@ -0,0 +1,39 @@
|
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
#include "CapsuleTest.h" |
||||
|
||||
#include <QtTest/QTest> |
||||
|
||||
#include "Physics/Capsule.h" |
||||
|
||||
QTEST_APPLESS_MAIN(Magnum::Physics::Test::CapsuleTest) |
||||
|
||||
namespace Magnum { namespace Physics { namespace Test { |
||||
|
||||
void CapsuleTest::applyTransformation() { |
||||
Physics::Capsule capsule({1.0f, 2.0f, 3.0f}, {-1.0f, -2.0f, -3.0f}, 7.0f); |
||||
|
||||
capsule.applyTransformation(Matrix4::rotation(deg(90.0f), Vector3::zAxis())); |
||||
QVERIFY((capsule.transformedA() == Vector3(-2.0f, 1.0f, 3.0f))); |
||||
QVERIFY((capsule.transformedB() == Vector3(2.0f, -1.0f, -3.0f))); |
||||
QCOMPARE(capsule.radius(), 7.0f); |
||||
|
||||
/* Apply average scaling to radius */ |
||||
capsule.applyTransformation(Matrix4::scaling({Math::Constants<GLfloat>::Sqrt3, -Math::Constants<GLfloat>::Sqrt2, 2.0f})); |
||||
QCOMPARE(capsule.transformedRadius(), Math::Constants<GLfloat>::Sqrt3*7.0f); |
||||
} |
||||
|
||||
}}} |
||||
@ -0,0 +1,31 @@
|
||||
#ifndef Magnum_Physics_Test_CapsuleTest_h |
||||
#define Magnum_Physics_Test_CapsuleTest_h |
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
#include <QtCore/QObject> |
||||
|
||||
namespace Magnum { namespace Physics { namespace Test { |
||||
|
||||
class CapsuleTest: public QObject { |
||||
Q_OBJECT |
||||
|
||||
private slots: |
||||
void applyTransformation(); |
||||
}; |
||||
|
||||
}}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,33 @@
|
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
#include "LineTest.h" |
||||
|
||||
#include <QtTest/QTest> |
||||
|
||||
#include "Physics/Line.h" |
||||
|
||||
QTEST_APPLESS_MAIN(Magnum::Physics::Test::LineTest) |
||||
|
||||
namespace Magnum { namespace Physics { namespace Test { |
||||
|
||||
void LineTest::applyTransformation() { |
||||
Physics::Line line({1.0f, 2.0f, 3.0f}, {-1.0f, -2.0f, -3.0f}); |
||||
line.applyTransformation(Matrix4::rotation(deg(90.0f), Vector3::zAxis())); |
||||
QVERIFY((line.transformedA() == Vector3(-2.0f, 1.0f, 3.0f))); |
||||
QVERIFY((line.transformedB() == Vector3(2.0f, -1.0f, -3.0f))); |
||||
} |
||||
|
||||
}}} |
||||
@ -0,0 +1,31 @@
|
||||
#ifndef Magnum_Physics_Test_LineTest_h |
||||
#define Magnum_Physics_Test_LineTest_h |
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
#include <QtCore/QObject> |
||||
|
||||
namespace Magnum { namespace Physics { namespace Test { |
||||
|
||||
class LineTest: public QObject { |
||||
Q_OBJECT |
||||
|
||||
private slots: |
||||
void applyTransformation(); |
||||
}; |
||||
|
||||
}}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,39 @@
|
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
#include "PlaneTest.h" |
||||
|
||||
#include <QtTest/QTest> |
||||
|
||||
#include "Physics/Plane.h" |
||||
|
||||
QTEST_APPLESS_MAIN(Magnum::Physics::Test::PlaneTest) |
||||
|
||||
namespace Magnum { namespace Physics { namespace Test { |
||||
|
||||
void PlaneTest::applyTransformation() { |
||||
Physics::Plane plane({1.0f, 2.0f, 3.0f}, {Math::Constants<float>::Sqrt2, -Math::Constants<float>::Sqrt2, 0}); |
||||
|
||||
plane.applyTransformation(Matrix4::rotation(deg(90.0f), Vector3::xAxis())); |
||||
QVERIFY(plane.transformedPosition() == Vector3(1.0f, -3.0f, 2.0f)); |
||||
QVERIFY(plane.transformedNormal() == Vector3(Math::Constants<float>::Sqrt2, 0, -Math::Constants<float>::Sqrt2)); |
||||
|
||||
/* The normal should stay normalized */ |
||||
plane.applyTransformation(Matrix4::scaling({1.5f, 2.0f, 3.0f})); |
||||
QVERIFY(plane.transformedPosition() == Vector3(1.5f, 4.0f, 9.0f)); |
||||
QVERIFY(plane.transformedNormal() == Vector3(Math::Constants<float>::Sqrt2, -Math::Constants<float>::Sqrt2, 0)); |
||||
} |
||||
|
||||
}}} |
||||
@ -0,0 +1,31 @@
|
||||
#ifndef Magnum_Physics_Test_PlaneTest_h |
||||
#define Magnum_Physics_Test_PlaneTest_h |
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
#include <QtCore/QObject> |
||||
|
||||
namespace Magnum { namespace Physics { namespace Test { |
||||
|
||||
class PlaneTest: public QObject { |
||||
Q_OBJECT |
||||
|
||||
private slots: |
||||
void applyTransformation(); |
||||
}; |
||||
|
||||
}}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,32 @@
|
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
#include "PointTest.h" |
||||
|
||||
#include <QtTest/QTest> |
||||
|
||||
#include "Physics/Point.h" |
||||
|
||||
QTEST_APPLESS_MAIN(Magnum::Physics::Test::PointTest) |
||||
|
||||
namespace Magnum { namespace Physics { namespace Test { |
||||
|
||||
void PointTest::applyTransformation() { |
||||
Physics::Point point({1.0f, 2.0f, 3.0f}); |
||||
point.applyTransformation(Matrix4::translation({5.0f, 6.0f, 7.0f})); |
||||
QVERIFY((point.transformedPosition() == Vector3(6.0f, 8.0f, 10.0f))); |
||||
} |
||||
|
||||
}}} |
||||
@ -0,0 +1,31 @@
|
||||
#ifndef Magnum_Physics_Test_PointTest_h |
||||
#define Magnum_Physics_Test_PointTest_h |
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
#include <QtCore/QObject> |
||||
|
||||
namespace Magnum { namespace Physics { namespace Test { |
||||
|
||||
class PointTest: public QObject { |
||||
Q_OBJECT |
||||
|
||||
private slots: |
||||
void applyTransformation(); |
||||
}; |
||||
|
||||
}}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,55 @@
|
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
#include "ShapeGroupTest.h" |
||||
|
||||
#include <QtTest/QTest> |
||||
|
||||
#include "Physics/Point.h" |
||||
#include "Physics/Sphere.h" |
||||
#include "Physics/ShapeGroup.h" |
||||
|
||||
QTEST_APPLESS_MAIN(Magnum::Physics::Test::ShapeGroupTest) |
||||
|
||||
using namespace std; |
||||
|
||||
namespace Magnum { namespace Physics { namespace Test { |
||||
|
||||
void ShapeGroupTest::copy() { |
||||
ShapeGroup group; |
||||
{ |
||||
Physics::Point point({1.0f, 2.0f, 3.0f}); |
||||
Physics::Sphere sphere({2.0f, 1.0f, 30.0f}, 1.0f); |
||||
|
||||
group = ~(point|sphere); |
||||
} |
||||
|
||||
/* Just to test that it doesn't crash */ |
||||
group.applyTransformation(Matrix4::translation(Vector3::xAxis(1.0f))); |
||||
} |
||||
|
||||
void ShapeGroupTest::reference() { |
||||
Physics::Point point({1.0f, 2.0f, 3.0f}); |
||||
Physics::Sphere sphere({2.0f, 1.0f, 30.0f}, 1.0f); |
||||
|
||||
ShapeGroup group = ~(ref(point)|ref(sphere)); |
||||
|
||||
group.applyTransformation(Matrix4::translation(Vector3(1.0f))); |
||||
|
||||
QVERIFY((point.transformedPosition() == Vector3(2.0f, 3.0f, 4.0f))); |
||||
QVERIFY((sphere.transformedPosition() == Vector3(3.0f, 2.0f, 31.0f))); |
||||
} |
||||
|
||||
}}} |
||||
@ -0,0 +1,32 @@
|
||||
#ifndef Magnum_Physics_Test_ShapeGroupTest_h |
||||
#define Magnum_Physics_Test_ShapeGroupTest_h |
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
#include <QtCore/QObject> |
||||
|
||||
namespace Magnum { namespace Physics { namespace Test { |
||||
|
||||
class ShapeGroupTest: public QObject { |
||||
Q_OBJECT |
||||
|
||||
private slots: |
||||
void copy(); |
||||
void reference(); |
||||
}; |
||||
|
||||
}}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,44 @@
|
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
#include "SphereTest.h" |
||||
|
||||
#include <QtTest/QTest> |
||||
#include "Utility/Debug.h" |
||||
|
||||
#include "Physics/Sphere.h" |
||||
|
||||
QTEST_APPLESS_MAIN(Magnum::Physics::Test::SphereTest) |
||||
|
||||
namespace Magnum { namespace Physics { namespace Test { |
||||
|
||||
void SphereTest::applyTransformation() { |
||||
Physics::Sphere sphere({1.0f, 2.0f, 3.0f}, 7.0f); |
||||
|
||||
sphere.applyTransformation(Matrix4::rotation(deg(90.0f), Vector3::yAxis())); |
||||
QVERIFY((sphere.transformedPosition() == Vector3(3.0f, 2.0f, -1.0f))); |
||||
QCOMPARE(sphere.transformedRadius(), 7.0f); |
||||
|
||||
/* Symmetric scaling */ |
||||
sphere.applyTransformation(Matrix4::scaling(Vector3(2.0f))); |
||||
QVERIFY((sphere.transformedPosition() == Vector3(2.0f, 4.0f, 6.0f))); |
||||
QCOMPARE(sphere.transformedRadius(), 14.0f); |
||||
|
||||
/* Apply average scaling to radius */ |
||||
sphere.applyTransformation(Matrix4::scaling({Math::Constants<GLfloat>::Sqrt3, -Math::Constants<GLfloat>::Sqrt2, 2.0f})); |
||||
QCOMPARE(sphere.transformedRadius(), Math::Constants<GLfloat>::Sqrt3*7.0f); |
||||
} |
||||
|
||||
}}} |
||||
@ -0,0 +1,31 @@
|
||||
#ifndef Magnum_Physics_Test_SphereTest_h |
||||
#define Magnum_Physics_Test_SphereTest_h |
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
#include <QtCore/QObject> |
||||
|
||||
namespace Magnum { namespace Physics { namespace Test { |
||||
|
||||
class SphereTest: public QObject { |
||||
Q_OBJECT |
||||
|
||||
private slots: |
||||
void applyTransformation(); |
||||
}; |
||||
|
||||
}}} |
||||
|
||||
#endif |
||||
Loading…
Reference in new issue