Browse Source

Initial Physics classes, interfaces, documentation and unit tests.

vectorfields
Vladimír Vondruš 14 years ago
parent
commit
43301c170c
  1. 1
      CMakeLists.txt
  2. 111
      doc/CollisionDetection.dox
  3. 7
      doc/namespaces.dox
  4. 5
      modules/FindMagnum.cmake
  5. 1
      src/CMakeLists.txt
  6. 28
      src/Physics/AbstractShape.cpp
  7. 79
      src/Physics/AbstractShape.h
  8. 25
      src/Physics/AxisAlignedBox.cpp
  9. 70
      src/Physics/AxisAlignedBox.h
  10. 58
      src/Physics/Box.h
  11. 24
      src/Physics/CMakeLists.txt
  12. 27
      src/Physics/Capsule.cpp
  13. 73
      src/Physics/Capsule.h
  14. 25
      src/Physics/Line.cpp
  15. 56
      src/Physics/Line.h
  16. 38
      src/Physics/LineSegment.h
  17. 25
      src/Physics/Plane.cpp
  18. 70
      src/Physics/Plane.h
  19. 58
      src/Physics/Point.h
  20. 65
      src/Physics/ShapeGroup.cpp
  21. 177
      src/Physics/ShapeGroup.h
  22. 26
      src/Physics/Sphere.cpp
  23. 71
      src/Physics/Sphere.h
  24. 38
      src/Physics/Test/AxisAlignedBoxTest.cpp
  25. 31
      src/Physics/Test/AxisAlignedBoxTest.h
  26. 7
      src/Physics/Test/CMakeLists.txt
  27. 39
      src/Physics/Test/CapsuleTest.cpp
  28. 31
      src/Physics/Test/CapsuleTest.h
  29. 33
      src/Physics/Test/LineTest.cpp
  30. 31
      src/Physics/Test/LineTest.h
  31. 39
      src/Physics/Test/PlaneTest.cpp
  32. 31
      src/Physics/Test/PlaneTest.h
  33. 32
      src/Physics/Test/PointTest.cpp
  34. 31
      src/Physics/Test/PointTest.h
  35. 55
      src/Physics/Test/ShapeGroupTest.cpp
  36. 32
      src/Physics/Test/ShapeGroupTest.h
  37. 44
      src/Physics/Test/SphereTest.cpp
  38. 31
      src/Physics/Test/SphereTest.h
  39. 6
      src/utilities.h

1
CMakeLists.txt

@ -19,6 +19,7 @@ find_package(Corrade REQUIRED)
set_parent_scope(MAGNUM_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src")
set_parent_scope(MAGNUM_LIBRARY Magnum)
set_parent_scope(MAGNUM_PHYSICS_LIBRARY MagnumPhysics)
set_parent_scope(MAGNUM_PRIMITIVES_LIBRARY MagnumPrimitives)
set_parent_scope(MAGNUM_MESHTOOLS_LIBRARY MagnumMeshTools)
set_parent_scope(MAGNUM_SHADERS_LIBRARY MagnumShaders)

111
doc/CollisionDetection.dox

@ -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
*/
}}}

7
doc/namespaces.dox

@ -21,3 +21,10 @@ Basic primitives for testing purposes.
Collection of shaders for testing purposes.
*/
/** @namespace Magnum::Physics
@brief %Physics library
Collision detection system and rigid body objects. See @ref CollisionDetection
for introduction.
*/

5
modules/FindMagnum.cmake

@ -5,6 +5,7 @@
# MAGNUM_FOUND - True if Magnum library is found
# MAGNUM_INCLUDE_DIR - Include dir for Magnum
# MAGNUM_LIBRARY - Magnum library
# MAGNUM_PHYSICS_LIBRARY - Magnum physics library
# MAGNUM_PRIMITIVES_LIBRARY - Library with primitives
#
# MAGNUM_LIBRARY_INSTALL_DIR - Library installation directory
@ -16,7 +17,7 @@ find_package(Corrade REQUIRED)
find_package(OpenGL REQUIRED)
find_package(GLEW REQUIRED)
if (MAGNUM_INCLUDE_DIR AND MAGNUM_LIBRARY AND MAGNUM_PRIMITIVES_LIBRARY AND MAGNUM_MESHTOOLS_LIBRARY AND MAGNUM_SHADERS_LIBRARY)
if (MAGNUM_INCLUDE_DIR AND MAGNUM_LIBRARY AND MAGNUM_PHYSICS_LIBRARY AND MAGNUM_PRIMITIVES_LIBRARY AND MAGNUM_MESHTOOLS_LIBRARY AND MAGNUM_SHADERS_LIBRARY)
# Already in cache
set(MAGNUM_FOUND TRUE)
@ -24,6 +25,7 @@ if (MAGNUM_INCLUDE_DIR AND MAGNUM_LIBRARY AND MAGNUM_PRIMITIVES_LIBRARY AND MAGN
else()
# Libraries
find_library(MAGNUM_LIBRARY Magnum)
find_library(MAGNUM_PHYSICS_LIBRARY MagnumPhysics)
find_library(MAGNUM_PRIMITIVES_LIBRARY MagnumPrimitives)
find_library(MAGNUM_MESHTOOLS_LIBRARY MagnumMeshTools)
find_library(MAGNUM_SHADERS_LIBRARY MagnumShaders)
@ -38,6 +40,7 @@ else()
find_package_handle_standard_args("Magnum" DEFAULT_MSG
MAGNUM_INCLUDE_DIR
MAGNUM_LIBRARY
MAGNUM_PHYSICS_LIBRARY
MAGNUM_PRIMITIVES_LIBRARY
MAGNUM_MESHTOOLS_LIBRARY
MAGNUM_SHADERS_LIBRARY

1
src/CMakeLists.txt

@ -4,6 +4,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CORRADE_INCLUDE_DIR})
add_subdirectory(Math)
add_subdirectory(MeshTools)
add_subdirectory(Physics)
add_subdirectory(Primitives)
add_subdirectory(Shaders)

28
src/Physics/AbstractShape.cpp

@ -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;
}
}}

79
src/Physics/AbstractShape.h

@ -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

25
src/Physics/AxisAlignedBox.cpp

@ -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;
}
}}

70
src/Physics/AxisAlignedBox.h

@ -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

58
src/Physics/Box.h

@ -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

24
src/Physics/CMakeLists.txt

@ -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()

27
src/Physics/Capsule.cpp

@ -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;
}
}}

73
src/Physics/Capsule.h

@ -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

25
src/Physics/Line.cpp

@ -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();
}
}}

56
src/Physics/Line.h

@ -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

38
src/Physics/LineSegment.h

@ -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

25
src/Physics/Plane.cpp

@ -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;
}
}}

70
src/Physics/Plane.h

@ -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

58
src/Physics/Point.h

@ -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

65
src/Physics/ShapeGroup.cpp

@ -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;
}
}
}}

177
src/Physics/ShapeGroup.h

@ -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

26
src/Physics/Sphere.cpp

@ -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;
}
}}

71
src/Physics/Sphere.h

@ -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

38
src/Physics/Test/AxisAlignedBoxTest.cpp

@ -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)));
}
}}}

31
src/Physics/Test/AxisAlignedBoxTest.h

@ -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

7
src/Physics/Test/CMakeLists.txt

@ -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)

39
src/Physics/Test/CapsuleTest.cpp

@ -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);
}
}}}

31
src/Physics/Test/CapsuleTest.h

@ -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

33
src/Physics/Test/LineTest.cpp

@ -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)));
}
}}}

31
src/Physics/Test/LineTest.h

@ -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

39
src/Physics/Test/PlaneTest.cpp

@ -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));
}
}}}

31
src/Physics/Test/PlaneTest.h

@ -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

32
src/Physics/Test/PointTest.cpp

@ -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)));
}
}}}

31
src/Physics/Test/PointTest.h

@ -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

55
src/Physics/Test/ShapeGroupTest.cpp

@ -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)));
}
}}}

32
src/Physics/Test/ShapeGroupTest.h

@ -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

44
src/Physics/Test/SphereTest.cpp

@ -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);
}
}}}

31
src/Physics/Test/SphereTest.h

@ -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

6
src/utilities.h

@ -32,9 +32,15 @@ namespace Magnum {
#else
#define MESHTOOLS_EXPORT __declspec(dllimport)
#endif
#ifdef PHYSICS_EXPORTING
#define PHYSICS_EXPORT __declspec(dllexport)
#else
#define PHYSICS_EXPORT __declspec(dllimport)
#endif
#else
#define MAGNUM_EXPORT
#define MESHTOOLS_EXPORT
#define PHYSICS_EXPORT
#endif
}

Loading…
Cancel
Save