diff --git a/CMakeLists.txt b/CMakeLists.txt index 76eed8cbe..c33a6f7ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ option(WITH_EVERYTHING "Build everything (doesn't include contexts)" ON) cmake_dependent_option(WITH_MESHTOOLS "Build MeshTools library" OFF "NOT WITH_EVERYTHING" ON) cmake_dependent_option(WITH_PHYSICS "Build Physics library" OFF "NOT WITH_EVERYTHING" ON) cmake_dependent_option(WITH_PRIMITIVES "Builf Primitives library" OFF "NOT WITH_EVERYTHING" ON) -cmake_dependent_option(WITH_SCENEGRAPH "Build SceneGraph library" OFF "NOT WITH_EVERYTHING" ON) +cmake_dependent_option(WITH_SCENEGRAPH "Build SceneGraph library" OFF "NOT WITH_EVERYTHING;NOT WITH_PHYSICS" ON) cmake_dependent_option(WITH_SHADERS "Build Shaders library" OFF "NOT WITH_EVERYTHING" ON) option(WITH_GLXWINDOWCONTEXT "Build GlxWindowContext library" OFF) diff --git a/modules/FindMagnum.cmake b/modules/FindMagnum.cmake index 70b874ff9..a4544ed74 100644 --- a/modules/FindMagnum.cmake +++ b/modules/FindMagnum.cmake @@ -16,7 +16,7 @@ # libraries. Additional dependencies are specified by the components. The # optional components are: # MeshTools - MeshTools library -# Physics - Physics library +# Physics - Physics library (depends on SceneGraph component) # Primitives - Library with stock geometric primitives (static) # SceneGraph - Scene graph library # Shaders - Library with stock shaders diff --git a/src/Physics/CMakeLists.txt b/src/Physics/CMakeLists.txt index 430587b7d..799da9a00 100644 --- a/src/Physics/CMakeLists.txt +++ b/src/Physics/CMakeLists.txt @@ -6,6 +6,8 @@ set(MagnumPhysics_SRCS Line.cpp Plane.cpp Point.cpp + ShapedObject.cpp + ShapedObjectGroup.cpp ShapeGroup.cpp Sphere.cpp) set(MagnumPhysics_HEADERS @@ -17,6 +19,8 @@ set(MagnumPhysics_HEADERS LineSegment.h Plane.h Point.h + ShapedObject.h + ShapedObjectGroup.h ShapeGroup.h Sphere.h @@ -24,7 +28,7 @@ set(MagnumPhysics_HEADERS add_library(MagnumPhysics SHARED ${MagnumPhysics_SRCS}) -target_link_libraries(MagnumPhysics Magnum) +target_link_libraries(MagnumPhysics Magnum MagnumSceneGraph) install(TARGETS MagnumPhysics DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) install(FILES ${MagnumPhysics_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Physics) diff --git a/src/Physics/ShapedObject.cpp b/src/Physics/ShapedObject.cpp new file mode 100644 index 000000000..f7f31deb9 --- /dev/null +++ b/src/Physics/ShapedObject.cpp @@ -0,0 +1,54 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "ShapedObject.h" + +#include + +#include "AbstractShaderProgram.h" +#include "Mesh.h" +#include "ResourceManager.h" +#include "AbstractShape.h" +#include "ShapedObjectGroup.h" + +using namespace std; + +namespace Magnum { namespace Physics { + +template ShapedObject::ShapedObject(ShapedObjectGroup* group, typename SceneGraph::AbstractObject::ObjectType* parent): SceneGraph::AbstractObject::ObjectType(parent), group(group), _shape(nullptr) { + group->objects.push_back(this); +} + +template ShapedObject::~ShapedObject() { + group->objects.erase(find(group->objects.begin(), group->objects.end(), this)); + delete _shape; +} + +template void ShapedObject::setDirty() { + SceneGraph::AbstractObject::ObjectType::setDirty(); + + group->setDirty(); +} + +template void ShapedObject::clean(const typename SceneGraph::AbstractObject::MatrixType& absoluteTransformation) { + SceneGraph::AbstractObject::ObjectType::clean(absoluteTransformation); + + if(_shape) _shape->applyTransformation(absoluteTransformation); +} + +template class ShapedObject<2>; +template class ShapedObject<3>; + +}} diff --git a/src/Physics/ShapedObject.h b/src/Physics/ShapedObject.h new file mode 100644 index 000000000..4ceeb238e --- /dev/null +++ b/src/Physics/ShapedObject.h @@ -0,0 +1,95 @@ +#ifndef Magnum_Physics_ShapedObject_h +#define Magnum_Physics_ShapedObject_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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::ShapedObject + */ + +#include "SceneGraph/Object.h" + +#include "magnumPhysicsVisibility.h" + +namespace Magnum { namespace Physics { + +template class ShapedObjectGroup; +template class AbstractShape; + +/** +@brief Object with assigned shape + +@see ShapedObject2D, ShapedObject3D +*/ +template class PHYSICS_EXPORT ShapedObject: public SceneGraph::AbstractObject::ObjectType { + public: + /** + * @brief Constructor + * @param group Group this shaped object belongs to + * @param parent Parent object + * + * Creates object with no shape. + * @see setShape() + */ + ShapedObject(ShapedObjectGroup* group, typename SceneGraph::AbstractObject::ObjectType* parent = nullptr); + + /** + * @brief Destructor + * + * Deletes associated shape. + */ + ~ShapedObject(); + + /** @brief Object shape */ + inline AbstractShape* shape() { return _shape; } + inline const AbstractShape* shape() const { return _shape; } /**< @overload */ + + /** @brief Set object shape */ + void setShape(AbstractShape* shape) { _shape = shape; } + + /** + * @copybrief SceneGraph::AbstractObject::setDirty() + * + * Marks shaped object group as dirty. + */ + void setDirty(); + + protected: + /** + * @copybrief SceneGraph::AbstractObject::clean() + * + * Applies transformation to associated shape. + */ + void clean(const typename SceneGraph::AbstractObject::MatrixType& absoluteTransformation); + + private: + ShapedObjectGroup* group; + AbstractShape* _shape; +}; + +#ifndef DOXYGEN_GENERATING_OUTPUT +extern template class PHYSICS_EXPORT ShapedObject<2>; +extern template class PHYSICS_EXPORT ShapedObject<3>; +#endif + +/** @brief Two-dimensional shaped object */ +typedef ShapedObject<2> ShapedObject2D; + +/** @brief Three-dimensional shaped object */ +typedef ShapedObject<3> ShapedObject3D; + +}} + +#endif diff --git a/src/Physics/ShapedObjectGroup.cpp b/src/Physics/ShapedObjectGroup.cpp new file mode 100644 index 000000000..89a901449 --- /dev/null +++ b/src/Physics/ShapedObjectGroup.cpp @@ -0,0 +1,32 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "ShapedObjectGroup.h" + +#include "ShapedObject.h" + +namespace Magnum { namespace Physics { + +template void ShapedObjectGroup::setClean() { + for(ShapedObject* object: objects) + if(object->isDirty()) object->setClean(); + + dirty = false; +} + +template class ShapedObjectGroup<2>; +template class ShapedObjectGroup<3>; + +}} diff --git a/src/Physics/ShapedObjectGroup.h b/src/Physics/ShapedObjectGroup.h new file mode 100644 index 000000000..74d38c816 --- /dev/null +++ b/src/Physics/ShapedObjectGroup.h @@ -0,0 +1,134 @@ +#ifndef Magnum_Physics_ShapedObjectGroup_h +#define Magnum_Physics_ShapedObjectGroup_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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::ShapedObjectGroup + */ + +#include +#include + +#include "magnumPhysicsVisibility.h" + +namespace Magnum { + +class AbstractShaderProgram; +template class Resource; + +namespace Physics { + +template class ShapedObject; + +#ifndef DOXYGEN_GENERATING_OUTPUT +namespace Implementation { + enum class DebugMode { + None, + Wireframe, + SolidWireframe + }; +} +#endif + +/** +@brief Group of shaped objects + +@ref ShapedObject "ShapedObject*D" instances are added to the group by +specifying it in the constructor. When the group is deleted, all objects +belogning to it are deleted too. +@see ShapedObjectGroup2D, ShapedObjectGroup3D +*/ +template class PHYSICS_EXPORT ShapedObjectGroup { + friend class ShapedObject; + + public: + #ifdef DOXYGEN_GENERATING_OUTPUT + /** + * @brief Debug mode + * + * @see setDebugMode() + */ + enum class DebugMode { + None, /**< @brief Nothing is rendered */ + Wireframe, /**< @brief Wireframe of the shape is rendered */ + SolidWireframe /**< @brief Solid with wireframe is rendered */ + }; + #else + typedef Implementation::DebugMode DebugMode; + #endif + + /** + * @brief Destructor + * + * Deletes all objects belogning to the group. + */ + inline virtual ~ShapedObjectGroup() { + for(auto i: objects) delete i; + } + + /** @brief Debug mode */ + inline DebugMode debugMode() const { return _debugMode; } + + /** @brief Set debug mode */ + inline void setDebugMode(DebugMode mode) { _debugMode = mode; } + + /** + * @brief Whether the group is dirty + * @return True if any object in the group is dirty, false otherwise. + */ + inline bool isDirty() const { return dirty; } + + /** + * @brief Set the group as dirty + * + * If some body in the group changes its transformation, it sets dirty + * status also on the group to indicate that the body and maybe also + * group state needs to be cleaned before computing collisions. + * + * @see setClean() + */ + inline void setDirty() { dirty = true; } + + /** + * @brief Set the group and all bodies as clean + * + * This function is called before computing any collisions to ensure + * all objects are cleaned. + */ + void setClean(); + + private: + Resource& shader(); + + DebugMode _debugMode; + std::vector*> objects; + bool dirty; +}; + +#ifndef DOXYGEN_GENERATING_OUTPUT +extern template class PHYSICS_EXPORT ShapedObjectGroup<2>; +extern template class PHYSICS_EXPORT ShapedObjectGroup<3>; +#endif + +/** @brief Group of two-dimensional shaped objects */ +typedef ShapedObjectGroup<2> ShapedObjectGroup2D; + +/** @brief Group of three-dimensional shaped objects */ +typedef ShapedObjectGroup<3> ShapedObjectGroup3D; + +}} + +#endif diff --git a/src/Physics/Test/CMakeLists.txt b/src/Physics/Test/CMakeLists.txt index 4f8130a83..dd56a0631 100644 --- a/src/Physics/Test/CMakeLists.txt +++ b/src/Physics/Test/CMakeLists.txt @@ -6,3 +6,5 @@ corrade_add_test2(PhysicsPlaneTest PlaneTest.cpp LIBRARIES MagnumPhysics) corrade_add_test2(PhysicsPointTest PointTest.cpp LIBRARIES MagnumPhysics) corrade_add_test2(PhysicsShapeGroupTest ShapeGroupTest.cpp LIBRARIES MagnumPhysics) corrade_add_test2(PhysicsSphereTest SphereTest.cpp LIBRARIES MagnumPhysics) + +corrade_add_test2(PhysicsShapedObjectTest ShapedObjectTest.cpp LIBRARIES MagnumPhysics) diff --git a/src/Physics/Test/ShapedObjectTest.cpp b/src/Physics/Test/ShapedObjectTest.cpp new file mode 100644 index 000000000..fec1e3c5a --- /dev/null +++ b/src/Physics/Test/ShapedObjectTest.cpp @@ -0,0 +1,59 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 "ShapedObjectTest.h" + +#include "Physics/ShapedObjectGroup.h" +#include "Physics/ShapedObject.h" + +CORRADE_TEST_MAIN(Magnum::Physics::Test::ShapedObjectTest) + +namespace Magnum { namespace Physics { namespace Test { + +ShapedObjectTest::ShapedObjectTest() { + addTests(&ShapedObjectTest::clean); +} + +void ShapedObjectTest::clean() { + ShapedObjectGroup3D group; + + ShapedObject3D a(&group), b(&group); + + /* Everything is dirty at the beginning */ + CORRADE_VERIFY(group.isDirty()); + CORRADE_VERIFY(a.isDirty()); + CORRADE_VERIFY(b.isDirty()); + + /* Cleaning object will not clean anything other */ + a.setClean(); + CORRADE_VERIFY(group.isDirty()); + CORRADE_VERIFY(!a.isDirty()); + CORRADE_VERIFY(b.isDirty()); + + /* Setting group clean will clean whole group */ + a.setDirty(); + group.setClean(); + CORRADE_VERIFY(!group.isDirty()); + CORRADE_VERIFY(!a.isDirty()); + CORRADE_VERIFY(!b.isDirty()); + + /* Setting object dirty will set also the group, but not other objects */ + b.setDirty(); + CORRADE_VERIFY(group.isDirty()); + CORRADE_VERIFY(!a.isDirty()); + CORRADE_VERIFY(b.isDirty()); +} + +}}} diff --git a/src/Physics/Test/ShapedObjectTest.h b/src/Physics/Test/ShapedObjectTest.h new file mode 100644 index 000000000..81f49e406 --- /dev/null +++ b/src/Physics/Test/ShapedObjectTest.h @@ -0,0 +1,31 @@ +#ifndef Magnum_Physics_Test_ShapedObjectTest_h +#define Magnum_Physics_Test_ShapedObjectTest_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + 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 + +namespace Magnum { namespace Physics { namespace Test { + +class ShapedObjectTest: public Corrade::TestSuite::Tester { + public: + ShapedObjectTest(); + + void clean(); +}; + +}}} + +#endif