diff --git a/src/Physics/CMakeLists.txt b/src/Physics/CMakeLists.txt index fdfde2722..ec5533b98 100644 --- a/src/Physics/CMakeLists.txt +++ b/src/Physics/CMakeLists.txt @@ -6,6 +6,8 @@ set(MagnumPhysics_SRCS Line.cpp Plane.cpp Point.cpp + ObjectShape.cpp + ObjectShapeGroup.cpp ShapeGroup.cpp Sphere.cpp) set(MagnumPhysics_HEADERS @@ -17,6 +19,8 @@ set(MagnumPhysics_HEADERS LineSegment.h Plane.h Point.h + ObjectShape.h + ObjectShapeGroup.h ShapeGroup.h Sphere.h diff --git a/src/Physics/ObjectShape.cpp b/src/Physics/ObjectShape.cpp new file mode 100644 index 000000000..4ce8e4ce7 --- /dev/null +++ b/src/Physics/ObjectShape.cpp @@ -0,0 +1,46 @@ +/* + 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 "ObjectShape.h" + +#include + +#include "AbstractShape.h" +#include "ObjectShapeGroup.h" + +using namespace std; + +namespace Magnum { namespace Physics { + +template ObjectShape::ObjectShape(SceneGraph::AbstractObject* object, ObjectShapeGroup* group): SceneGraph::AbstractGroupedFeature>(object, group), _shape(nullptr) { + this->setCachedTransformations(SceneGraph::AbstractFeature::CachedTransformation::Absolute); +} + +template ObjectShape::~ObjectShape() { + delete _shape; +} + +template void ObjectShape::markDirty() { + group()->setDirty(); +} + +template void ObjectShape::clean(const typename DimensionTraits::MatrixType& absoluteTransformation) { + if(_shape) _shape->applyTransformation(absoluteTransformation); +} + +template class ObjectShape<2>; +template class ObjectShape<3>; + +}} diff --git a/src/Physics/ObjectShape.h b/src/Physics/ObjectShape.h new file mode 100644 index 000000000..1a651a8ee --- /dev/null +++ b/src/Physics/ObjectShape.h @@ -0,0 +1,98 @@ +#ifndef Magnum_Physics_ObjectShape_h +#define Magnum_Physics_ObjectShape_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::ObjectShape + */ + +#include "SceneGraph/AbstractGroupedFeature.h" +#include "ObjectShapeGroup.h" + +#include "magnumPhysicsVisibility.h" + +namespace Magnum { namespace Physics { + +template class ObjectShapeGroup; +template class AbstractShape; + +/** +@brief Object shape + +Adds shape for collision detection to object. +@see ObjectShape2D, ObjectShape3D +*/ +template class PHYSICS_EXPORT ObjectShape: public SceneGraph::AbstractGroupedFeature> { + public: + /** + * @brief Constructor + * @param object Object holding this feature + * @param group Group this shape belongs to + * + * Creates empty object shape. + * @see setShape() + */ + ObjectShape(SceneGraph::AbstractObject* object, ObjectShapeGroup* group = nullptr); + + /** + * @brief Destructor + * + * Deletes associated shape. + */ + ~ObjectShape(); + + /** @brief Shape */ + inline AbstractShape* shape() { return _shape; } + inline const AbstractShape* shape() const { return _shape; } /**< @overload */ + + /** + * @brief Set shape + * @return Pointer to self (for method chaining) + */ + inline ObjectShape* setShape(AbstractShape* shape) { + _shape = shape; + this->object()->setDirty(); + return this; + } + + inline ObjectShapeGroup* group() { + return static_cast*>(SceneGraph::AbstractGroupedFeature>::group()); + } + + inline const ObjectShapeGroup* group() const { + return static_cast*>(SceneGraph::AbstractGroupedFeature>::group()); + } + + protected: + /** Marks also the group as dirty */ + void markDirty() override; + + /** Applies transformation to associated shape. */ + void clean(const typename DimensionTraits::MatrixType& absoluteTransformation) override; + + private: + AbstractShape* _shape; +}; + +/** @brief Two-dimensional object shape */ +typedef ObjectShape<2> ObjectShape2D; + +/** @brief Three-dimensional object shape */ +typedef ObjectShape<3> ObjectShape3D; + +}} + +#endif diff --git a/src/Physics/ShapedObjectGroup.cpp b/src/Physics/ObjectShapeGroup.cpp similarity index 56% rename from src/Physics/ShapedObjectGroup.cpp rename to src/Physics/ObjectShapeGroup.cpp index ae02018f5..013bf4d78 100644 --- a/src/Physics/ShapedObjectGroup.cpp +++ b/src/Physics/ObjectShapeGroup.cpp @@ -13,20 +13,26 @@ GNU Lesser General Public License version 3 for more details. */ -#include "ShapedObjectGroup.h" +#include "ObjectShapeGroup.h" -#include "ShapedObject.h" +#include "ObjectShape.h" namespace Magnum { namespace Physics { -template void ShapedObjectGroup::setClean() { - for(ShapedObject* object: objects) - if(object->isDirty()) object->setClean(); +template void ObjectShapeGroup::setClean() { + /* Clean all objects */ + if(!this->isEmpty()) { + std::vector*> objects(this->size()); + for(std::size_t i = 0; i != this->size(); ++i) + objects[i] = (*this)[i]->object(); + + objects[0]->setClean(objects); + } dirty = false; } -template class ShapedObjectGroup<2>; -template class ShapedObjectGroup<3>; +template class ObjectShapeGroup<2>; +template class ObjectShapeGroup<3>; }} diff --git a/src/Physics/ShapedObjectGroup.h b/src/Physics/ObjectShapeGroup.h similarity index 64% rename from src/Physics/ShapedObjectGroup.h rename to src/Physics/ObjectShapeGroup.h index 1934ef19c..93eb61659 100644 --- a/src/Physics/ShapedObjectGroup.h +++ b/src/Physics/ObjectShapeGroup.h @@ -1,5 +1,5 @@ -#ifndef Magnum_Physics_ShapedObjectGroup_h -#define Magnum_Physics_ShapedObjectGroup_h +#ifndef Magnum_Physics_ObjectShapeGroup_h +#define Magnum_Physics_ObjectShapeGroup_h /* Copyright © 2010, 2011, 2012 Vladimír Vondruš @@ -16,28 +16,28 @@ */ /** @file - * @brief Class Magnum::Physics::ShapedObjectGroup + * @brief Class Magnum::Physics::ObjectShapeGroup */ #include #include +#include "SceneGraph/FeatureGroup.h" + #include "magnumPhysicsVisibility.h" namespace Magnum { namespace Physics { -template class ShapedObject; +template class ObjectShape; /** -@brief Group of shaped objects +@brief Group of object shapes + -@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 +@see ObjectShapeGroup2D, ObjectShapeGroup3D */ -template class PHYSICS_EXPORT ShapedObjectGroup { - friend class ShapedObject; +template class PHYSICS_EXPORT ObjectShapeGroup: public SceneGraph::FeatureGroup> { + friend class ObjectShape; public: /** @@ -45,16 +45,7 @@ template class PHYSICS_EXPORT ShapedObjectGroup { * * Marks the group as dirty. */ - inline ShapedObjectGroup(): dirty(true) {} - - /** - * @brief Destructor - * - * Deletes all objects belogning to the group. - */ - inline virtual ~ShapedObjectGroup() { - for(auto i: objects) delete i; - } + inline ObjectShapeGroup(): dirty(true) {} /** * @brief Whether the group is dirty @@ -82,15 +73,14 @@ template class PHYSICS_EXPORT ShapedObjectGroup { void setClean(); private: - std::vector*> objects; bool dirty; }; /** @brief Group of two-dimensional shaped objects */ -typedef ShapedObjectGroup<2> ShapedObjectGroup2D; +typedef ObjectShapeGroup<2> ObjectShapeGroup2D; /** @brief Group of three-dimensional shaped objects */ -typedef ShapedObjectGroup<3> ShapedObjectGroup3D; +typedef ObjectShapeGroup<3> ObjectShapeGroup3D; }} diff --git a/src/Physics/ShapedObject.cpp b/src/Physics/ShapedObject.cpp deleted file mode 100644 index fb92ede11..000000000 --- a/src/Physics/ShapedObject.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - 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 "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 DimensionTraits::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 deleted file mode 100644 index b9763270f..000000000 --- a/src/Physics/ShapedObject.h +++ /dev/null @@ -1,97 +0,0 @@ -#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 - * @return Pointer to self (for method chaining) - */ - inline ShapedObject* setShape(AbstractShape* shape) { - _shape = shape; - setDirty(); - return this; - } - - /** - * @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 DimensionTraits::MatrixType& absoluteTransformation); - - private: - ShapedObjectGroup* group; - AbstractShape* _shape; -}; - -/** @brief Two-dimensional shaped object */ -typedef ShapedObject<2> ShapedObject2D; - -/** @brief Three-dimensional shaped object */ -typedef ShapedObject<3> ShapedObject3D; - -}} - -#endif diff --git a/src/Physics/Test/CMakeLists.txt b/src/Physics/Test/CMakeLists.txt index 5bb96fb4a..5c6c5f2a5 100644 --- a/src/Physics/Test/CMakeLists.txt +++ b/src/Physics/Test/CMakeLists.txt @@ -7,3 +7,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(PhysicsObjectShapeTest ObjectShapeTest.cpp LIBRARIES MagnumPhysics) diff --git a/src/Physics/Test/ShapedObjectTest.cpp b/src/Physics/Test/ObjectShapeTest.cpp similarity index 58% rename from src/Physics/Test/ShapedObjectTest.cpp rename to src/Physics/Test/ObjectShapeTest.cpp index fec1e3c5a..dd5b438bd 100644 --- a/src/Physics/Test/ShapedObjectTest.cpp +++ b/src/Physics/Test/ObjectShapeTest.cpp @@ -13,23 +13,36 @@ GNU Lesser General Public License version 3 for more details. */ -#include "ShapedObjectTest.h" +#include "ObjectShapeTest.h" -#include "Physics/ShapedObjectGroup.h" -#include "Physics/ShapedObject.h" +#include "Physics/ObjectShapeGroup.h" +#include "Physics/ObjectShape.h" +#include "Physics/Point.h" +#include "SceneGraph/MatrixTransformation3D.h" +#include "SceneGraph/Scene.h" -CORRADE_TEST_MAIN(Magnum::Physics::Test::ShapedObjectTest) +CORRADE_TEST_MAIN(Magnum::Physics::Test::ObjectShapeTest) namespace Magnum { namespace Physics { namespace Test { -ShapedObjectTest::ShapedObjectTest() { - addTests(&ShapedObjectTest::clean); +typedef SceneGraph::Scene> Scene3D; +typedef SceneGraph::Object> Object3D; + +ObjectShapeTest::ObjectShapeTest() { + addTests(&ObjectShapeTest::clean); } -void ShapedObjectTest::clean() { - ShapedObjectGroup3D group; +void ObjectShapeTest::clean() { + Scene3D scene; + ObjectShapeGroup3D group; + + Object3D a(&scene); + ObjectShape3D* shape = new ObjectShape3D(&a, &group); + shape->setShape(new Physics::Point3D({1.0f, -2.0f, 3.0f})); + a.scale(Vector3(-2.0f)); - ShapedObject3D a(&group), b(&group); + Object3D b(&scene); + new ObjectShape3D(&b, &group); /* Everything is dirty at the beginning */ CORRADE_VERIFY(group.isDirty()); @@ -42,6 +55,10 @@ void ShapedObjectTest::clean() { CORRADE_VERIFY(!a.isDirty()); CORRADE_VERIFY(b.isDirty()); + /* Verify that the feature was actually cleaned */ + CORRADE_COMPARE(static_cast(shape->shape())->transformedPosition(), + Vector3(-2.0f, 4.0f, -6.0f)); + /* Setting group clean will clean whole group */ a.setDirty(); group.setClean(); diff --git a/src/Physics/Test/ShapedObjectTest.h b/src/Physics/Test/ObjectShapeTest.h similarity index 78% rename from src/Physics/Test/ShapedObjectTest.h rename to src/Physics/Test/ObjectShapeTest.h index 81f49e406..65d051da1 100644 --- a/src/Physics/Test/ShapedObjectTest.h +++ b/src/Physics/Test/ObjectShapeTest.h @@ -1,5 +1,5 @@ -#ifndef Magnum_Physics_Test_ShapedObjectTest_h -#define Magnum_Physics_Test_ShapedObjectTest_h +#ifndef Magnum_Physics_Test_ObjectShapeTest_h +#define Magnum_Physics_Test_ObjectShapeTest_h /* Copyright © 2010, 2011, 2012 Vladimír Vondruš @@ -19,9 +19,9 @@ namespace Magnum { namespace Physics { namespace Test { -class ShapedObjectTest: public Corrade::TestSuite::Tester { +class ObjectShapeTest: public Corrade::TestSuite::Tester { public: - ShapedObjectTest(); + ObjectShapeTest(); void clean(); };