From ee6d0ef438f7aad77916eb9225273ac5d72fe5b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Tue, 13 Nov 2012 14:02:55 +0100 Subject: [PATCH] Physics: ported debug draw to new SceneGraph. Debug renderers are now subclasses of Drawable feature. --- src/Physics/CMakeLists.txt | 8 ++- src/Physics/DebugDrawResourceManager.cpp | 32 ++++++---- src/Physics/DebugDrawResourceManager.h | 47 +++++++-------- .../Implementation/AbstractDebugRenderer.cpp | 4 +- .../Implementation/AbstractDebugRenderer.h | 16 ++--- src/Physics/Implementation/BoxRenderer.cpp | 17 +++--- src/Physics/Implementation/BoxRenderer.h | 9 ++- src/Physics/Implementation/DebugRenderer.h | 58 +++++++++++++++++++ 8 files changed, 132 insertions(+), 59 deletions(-) create mode 100644 src/Physics/Implementation/DebugRenderer.h diff --git a/src/Physics/CMakeLists.txt b/src/Physics/CMakeLists.txt index ec5533b98..e3eec9146 100644 --- a/src/Physics/CMakeLists.txt +++ b/src/Physics/CMakeLists.txt @@ -3,18 +3,24 @@ set(MagnumPhysics_SRCS AxisAlignedBox.cpp Box.cpp Capsule.cpp + DebugDrawResourceManager.cpp Line.cpp Plane.cpp Point.cpp ObjectShape.cpp ObjectShapeGroup.cpp ShapeGroup.cpp - Sphere.cpp) + Sphere.cpp + + Implementation/AbstractDebugRenderer.cpp + Implementation/BoxRenderer.cpp) + set(MagnumPhysics_HEADERS AbstractShape.h AxisAlignedBox.h Box.h Capsule.h + DebugDrawResourceManager.h Line.h LineSegment.h Plane.h diff --git a/src/Physics/DebugDrawResourceManager.cpp b/src/Physics/DebugDrawResourceManager.cpp index f048a5816..c2f35c2f3 100644 --- a/src/Physics/DebugDrawResourceManager.cpp +++ b/src/Physics/DebugDrawResourceManager.cpp @@ -18,13 +18,14 @@ #include "AbstractShaderProgram.h" #include "Buffer.h" #include "Mesh.h" +#include "ResourceManager.h" #include "Shaders/FlatShader.h" #include "AbstractShape.h" #include "Box.h" -#include "ShapedObject.h" +#include "ObjectShape.h" #include "ShapeGroup.h" -#include "Implementation/AbstractDebugRenderer.h" #include "Implementation/BoxRenderer.h" +#include "Implementation/DebugRenderer.h" namespace Magnum { @@ -32,24 +33,33 @@ template class ResourceManager SceneGraph::Drawable* DebugDrawResourceManager::createDebugRenderer(ObjectShape* shape, ResourceKey options) { + Implementation::DebugRenderer* renderer = new Implementation::DebugRenderer(shape->object(), instance()->get(options)); + createDebugMesh(renderer, shape->shape()); + return renderer; } -SceneGraph::Object2D* DebugDrawResourceManager::createDebugMesh(SceneGraph::Object2D* parent, AbstractShape2D* shape, ResourceKey options) { +template SceneGraph::Drawable<2>* DebugDrawResourceManager::createDebugRenderer(ObjectShape<2>* shape, ResourceKey options); +template SceneGraph::Drawable<3>* DebugDrawResourceManager::createDebugRenderer(ObjectShape<3>* shape, ResourceKey options); + +void DebugDrawResourceManager::createDebugMesh(Implementation::DebugRenderer<2>* renderer, AbstractShape2D* shape) { switch(shape->type()) { case AbstractShape2D::Type::Box: - return new Implementation::BoxRenderer<2>(*static_cast(shape), options, parent); + renderer->addRenderer(new Implementation::BoxRenderer<2>(*static_cast(shape))); + break; case AbstractShape2D::Type::ShapeGroup: { - if(!parent) parent = new SceneGraph::Object2D; ShapeGroup2D* group = static_cast(shape); - if(group->first()) createDebugMesh(parent, group->first(), options); - if(group->second()) createDebugMesh(parent, group->second(), options); - return parent; - } default: return nullptr; + if(group->first()) createDebugMesh(renderer, group->first()); + if(group->second()) createDebugMesh(renderer, group->second()); + break; + } + default: + Warning() << "Physics::DebugDrawResourceManager::createDebugRenderer(): type" << shape->type() << "not implemented"; } } +void DebugDrawResourceManager::createDebugMesh(Implementation::DebugRenderer<3>*, AbstractShape3D*) {} + DebugDrawResourceManager::DebugDrawResourceManager() { setFallback(new Options); set("shader2d", new Shaders::FlatShader<2>, ResourceDataState::Final, ResourcePolicy::Resident); diff --git a/src/Physics/DebugDrawResourceManager.h b/src/Physics/DebugDrawResourceManager.h index db22e4221..618b594eb 100644 --- a/src/Physics/DebugDrawResourceManager.h +++ b/src/Physics/DebugDrawResourceManager.h @@ -22,6 +22,7 @@ #include "Magnum.h" #include "Color.h" #include "ResourceManager.h" +#include "SceneGraph/SceneGraph.h" #include "magnumPhysicsVisibility.h" @@ -36,27 +37,20 @@ namespace Physics { namespace Implementation { struct Options { Color3 color; }; - template class AbstractDebugRenderer; + template class DebugRenderer; }} - -#ifndef WIN32 -extern template class PHYSICS_EXPORT ResourceManager; -#endif #endif -/** @todo fix extern template multiple definition linker errors in mingw32-gcc */ - -namespace SceneGraph { - class Object2D; - class Object3D; -} - namespace Physics { template class AbstractShape; typedef AbstractShape<2> AbstractShape2D; typedef AbstractShape<3> AbstractShape3D; +template class ObjectShape; +typedef ObjectShape<2> ObjectShape2D; +typedef ObjectShape<3> ObjectShape3D; + /** @brief %Resource manager for physics debug draw @@ -64,14 +58,18 @@ Can create objects which draw object collision shape for debugging purposes. @section DebugDrawResourceManager-usage Basic usage The manager must be instanced for the whole lifetime of debug draw objects. -To create debug draw objects, call createDebugRenderer() and add the resulting -object to the scene. You can specify options via Options struct - add it to +To create debug renderers, call createDebugRenderer() and add the resulting +drawable to some group. You can specify options via Options struct - add it to the manager and then create debug renderer with the same options key. This way -you can easily share the same options with more objects. If no options for +you can easily share the same options with more renderers. If no options for given key exist, default is used. Example code: @code +// Group of drawables,preferrably dedicated for debug renderers, so you can +// easily enable or disable debug draw +DrawableGroup2D group; + // Instance the manager at first DebugDrawResourceManager manager; @@ -81,11 +79,10 @@ auto o = new DebugDrawResourceManager::Options { }; manager->set("red", o, ResourceDataState::Final, ResourcePolicy::Persistent); -// Add debug draw object for given shape, use "red" options for it, don't -// forget to add it to the scene -ShapedObject2D* object; -DebugDrawResourceManager::createDebugRenderer(object->shape(), "red") - ->setParent(object); +// Create debug renderer for given shape, use "red" options for it. Don't +// forget to add it to some drawable group. +ObjectShape2D* shape; +group.add(DebugDrawResourceManager::createDebugRenderer(shape, "red")); @endcode */ class PHYSICS_EXPORT DebugDrawResourceManager: public ResourceManager { @@ -106,17 +103,17 @@ class PHYSICS_EXPORT DebugDrawResourceManager: public ResourceManager static SceneGraph::Drawable* createDebugRenderer(ObjectShape* shape, ResourceKey options = ResourceKey()); DebugDrawResourceManager(); - ~DebugDrawResourceManager(); private: - static SceneGraph::Object2D* createDebugMesh(SceneGraph::Object2D* parent, AbstractShape2D* shape, ResourceKey options); + static void createDebugMesh(Implementation::DebugRenderer<2>* renderer, AbstractShape2D* shape); + static void createDebugMesh(Implementation::DebugRenderer<3>* renderer, AbstractShape3D* shape); }; }} diff --git a/src/Physics/Implementation/AbstractDebugRenderer.cpp b/src/Physics/Implementation/AbstractDebugRenderer.cpp index 63235f8bb..dbd41dcd7 100644 --- a/src/Physics/Implementation/AbstractDebugRenderer.cpp +++ b/src/Physics/Implementation/AbstractDebugRenderer.cpp @@ -22,7 +22,9 @@ namespace Magnum { namespace Physics { namespace Implementation { -template AbstractDebugRenderer::AbstractDebugRenderer(ResourceKey shader, ResourceKey mesh, ResourceKey options, typename SceneGraph::AbstractObject::ObjectType* parent): SceneGraph::AbstractObject::ObjectType(parent), shader(DebugDrawResourceManager::instance()->get>(shader)), mesh(DebugDrawResourceManager::instance()->get(mesh)), options(DebugDrawResourceManager::instance()->get(options)) {} +template AbstractDebugRenderer::AbstractDebugRenderer(ResourceKey shader, ResourceKey mesh): shader(DebugDrawResourceManager::instance()->get>(shader)), mesh(DebugDrawResourceManager::instance()->get(mesh)) {} + +template AbstractDebugRenderer::~AbstractDebugRenderer() {} template class AbstractDebugRenderer<2>; template class AbstractDebugRenderer<3>; diff --git a/src/Physics/Implementation/AbstractDebugRenderer.h b/src/Physics/Implementation/AbstractDebugRenderer.h index ed236b60d..0b3af89c2 100644 --- a/src/Physics/Implementation/AbstractDebugRenderer.h +++ b/src/Physics/Implementation/AbstractDebugRenderer.h @@ -15,9 +15,9 @@ GNU Lesser General Public License version 3 for more details. */ -#include "Color.h" +#include "DimensionTraits.h" #include "ResourceManager.h" -#include "SceneGraph/Camera.h" +#include "SceneGraph/SceneGraph.h" namespace Magnum { @@ -32,19 +32,19 @@ namespace Physics { namespace Implementation { struct Options; -template class AbstractDebugRenderer: public SceneGraph::AbstractObject::ObjectType { +template class AbstractDebugRenderer { public: - AbstractDebugRenderer(ResourceKey shader, ResourceKey mesh, ResourceKey options, typename SceneGraph::AbstractObject::ObjectType* parent); + AbstractDebugRenderer(ResourceKey shader, ResourceKey mesh); + + virtual ~AbstractDebugRenderer(); + + virtual void draw(Resource& options, const typename DimensionTraits::MatrixType& transformationMatrix, SceneGraph::AbstractCamera* camera) = 0; protected: Resource> shader; Resource mesh; - Resource options; }; -extern template class AbstractDebugRenderer<2>; -extern template class AbstractDebugRenderer<3>; - }}} #endif diff --git a/src/Physics/Implementation/BoxRenderer.cpp b/src/Physics/Implementation/BoxRenderer.cpp index 31b609e73..a6cc9d4ca 100644 --- a/src/Physics/Implementation/BoxRenderer.cpp +++ b/src/Physics/Implementation/BoxRenderer.cpp @@ -20,6 +20,7 @@ #include "Physics/DebugDrawResourceManager.h" #include "Primitives/Cube.h" #include "Primitives/Square.h" +#include "SceneGraph/AbstractCamera.h" #include "Shaders/FlatShader.h" namespace Magnum { namespace Physics { namespace Implementation { @@ -28,8 +29,8 @@ namespace { template struct BoxMesh {}; template<> struct BoxMesh<2> { - constexpr static ResourceKey shader() { return {"shader2d"}; } - constexpr static ResourceKey key() { return {"box2d"}; } + static ResourceKey shader() { return {"shader2d"}; } + static ResourceKey key() { return {"box2d"}; } static Mesh* mesh(Buffer* buffer) { Primitives::Square square; @@ -42,8 +43,8 @@ namespace { }; template<> struct BoxMesh<3> { - constexpr static ResourceKey shader() { return {"shader3d"}; } - constexpr static ResourceKey key() { return {"box3d"}; } + static ResourceKey shader() { return {"shader3d"}; } + static ResourceKey key() { return {"box3d"}; } static Mesh* mesh(Buffer* buffer) { Primitives::Cube cube; @@ -56,16 +57,16 @@ namespace { }; } -template BoxRenderer::BoxRenderer(Box& box, ResourceKey options, typename SceneGraph::AbstractObject::ObjectType* parent): AbstractDebugRenderer(BoxMesh::shader(), BoxMesh::key(), options, parent), buffer(DebugDrawResourceManager::instance()->get(BoxMesh::key())), box(box) { +template BoxRenderer::BoxRenderer(Box& box): AbstractDebugRenderer(BoxMesh::shader(), BoxMesh::key()), buffer(DebugDrawResourceManager::instance()->get(BoxMesh::key())), box(box) { if(!this->mesh) { DebugDrawResourceManager::instance()->set(this->buffer.key(), new Buffer, ResourceDataState::Final, ResourcePolicy::Manual); DebugDrawResourceManager::instance()->set(this->mesh.key(), BoxMesh::mesh(buffer), ResourceDataState::Final, ResourcePolicy::Manual); } } -template void BoxRenderer::draw(const typename DimensionTraits::MatrixType&, typename SceneGraph::AbstractObject::CameraType* camera) { - this->shader->setTransformationProjection(camera->projectionMatrix()*box.transformedTransformation()) - ->setColor(this->options->color) +template void BoxRenderer::draw(Resource& options, const typename DimensionTraits::MatrixType&, typename SceneGraph::AbstractCamera* camera) { + this->shader->setTransformationProjection(camera->projectionMatrix()*camera->cameraMatrix()*box.transformedTransformation()) + ->setColor(options->color) ->use(); this->mesh->draw(); } diff --git a/src/Physics/Implementation/BoxRenderer.h b/src/Physics/Implementation/BoxRenderer.h index a04683ee4..d563c7c63 100644 --- a/src/Physics/Implementation/BoxRenderer.h +++ b/src/Physics/Implementation/BoxRenderer.h @@ -17,6 +17,8 @@ #include "AbstractDebugRenderer.h" +#include "magnumCompatibility.h" + namespace Magnum { class Buffer; @@ -29,18 +31,15 @@ namespace Implementation { template class BoxRenderer: public AbstractDebugRenderer { public: - BoxRenderer(Box& box, ResourceKey options, typename SceneGraph::AbstractObject::ObjectType* parent); + BoxRenderer(Box& box); - void draw(const typename DimensionTraits::MatrixType& transformation, typename SceneGraph::AbstractObject::CameraType* camera); + void draw(Resource& options, const typename DimensionTraits::MatrixType& transformation, typename SceneGraph::AbstractCamera* camera) override; private: Resource buffer; Box& box; }; -extern template class BoxRenderer<2>; -extern template class BoxRenderer<3>; - }}} #endif diff --git a/src/Physics/Implementation/DebugRenderer.h b/src/Physics/Implementation/DebugRenderer.h new file mode 100644 index 000000000..fdb19e268 --- /dev/null +++ b/src/Physics/Implementation/DebugRenderer.h @@ -0,0 +1,58 @@ +#ifndef Magnum_Physics_Implementation_DebugRenderer_h +#define Magnum_Physics_Implementation_DebugRenderer_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 "ResourceManager.h" +#include "SceneGraph/Drawable.h" +#include "AbstractDebugRenderer.h" + +namespace Magnum { + +class AbstractShaderProgram; +class Mesh; + +namespace Shaders { + template class FlatShader; +} + +namespace Physics { namespace Implementation { + +struct Options; + +template class DebugRenderer: public SceneGraph::Drawable { + public: + DebugRenderer(SceneGraph::AbstractObject* object, Resource&& options): SceneGraph::Drawable(object), options(options) {} + + inline ~DebugRenderer() { + for(auto i: renderers) delete i; + } + + inline void addRenderer(AbstractDebugRenderer* renderer) { + renderers.push_back(renderer); + } + + inline void draw(const typename DimensionTraits::MatrixType& transformationMatrix, SceneGraph::AbstractCamera* camera) override { + for(auto i: renderers) i->draw(options, transformationMatrix, camera); + } + + private: + Resource options; + std::vector*> renderers; +}; + +}}} + +#endif