Browse Source

Physics: ported debug draw to new SceneGraph.

Debug renderers are now subclasses of Drawable feature.
pull/7/head
Vladimír Vondruš 14 years ago
parent
commit
ee6d0ef438
  1. 8
      src/Physics/CMakeLists.txt
  2. 32
      src/Physics/DebugDrawResourceManager.cpp
  3. 47
      src/Physics/DebugDrawResourceManager.h
  4. 4
      src/Physics/Implementation/AbstractDebugRenderer.cpp
  5. 16
      src/Physics/Implementation/AbstractDebugRenderer.h
  6. 17
      src/Physics/Implementation/BoxRenderer.cpp
  7. 9
      src/Physics/Implementation/BoxRenderer.h
  8. 58
      src/Physics/Implementation/DebugRenderer.h

8
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

32
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<AbstractShaderProgram, Buffer, Mesh, Physics::Imp
namespace Physics {
SceneGraph::Object2D* DebugDrawResourceManager::createDebugRenderer(AbstractShape2D* shape, ResourceKey options) {
return createDebugMesh(nullptr, shape, options);
template<std::uint8_t dimensions> SceneGraph::Drawable<dimensions>* DebugDrawResourceManager::createDebugRenderer(ObjectShape<dimensions>* shape, ResourceKey options) {
Implementation::DebugRenderer<dimensions>* renderer = new Implementation::DebugRenderer<dimensions>(shape->object(), instance()->get<Options>(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<Box2D*>(shape), options, parent);
renderer->addRenderer(new Implementation::BoxRenderer<2>(*static_cast<Box2D*>(shape)));
break;
case AbstractShape2D::Type::ShapeGroup: {
if(!parent) parent = new SceneGraph::Object2D;
ShapeGroup2D* group = static_cast<ShapeGroup2D*>(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<Options>(new Options);
set<AbstractShaderProgram>("shader2d", new Shaders::FlatShader<2>, ResourceDataState::Final, ResourcePolicy::Resident);

47
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<GLfloat> color;
};
template<std::uint8_t> class AbstractDebugRenderer;
template<std::uint8_t> class DebugRenderer;
}}
#ifndef WIN32
extern template class PHYSICS_EXPORT ResourceManager<AbstractShaderProgram, Buffer, Mesh, Physics::Implementation::Options>;
#endif
#endif
/** @todo fix extern template multiple definition linker errors in mingw32-gcc */
namespace SceneGraph {
class Object2D;
class Object3D;
}
namespace Physics {
template<std::uint8_t> class AbstractShape;
typedef AbstractShape<2> AbstractShape2D;
typedef AbstractShape<3> AbstractShape3D;
template<std::uint8_t> 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<DebugDrawResourceManager::Options>("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<AbstractShaderProgram, Buffer, Mesh, Physics::Implementation::Options> {
@ -106,17 +103,17 @@ class PHYSICS_EXPORT DebugDrawResourceManager: public ResourceManager<AbstractSh
* @ref DebugDrawResourceManager-usage "class documentation" for
* more information.
*
* Returned object is not parented to anything, you have to add it to
* desired scene yourself.
* Returned drawable is not part of any group, you have to add it to
* one yourself.
*/
static SceneGraph::Object2D* createDebugRenderer(AbstractShape2D* shape, ResourceKey options = ResourceKey());
template<std::uint8_t dimensions> static SceneGraph::Drawable<dimensions>* createDebugRenderer(ObjectShape<dimensions>* 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);
};
}}

4
src/Physics/Implementation/AbstractDebugRenderer.cpp

@ -22,7 +22,9 @@
namespace Magnum { namespace Physics { namespace Implementation {
template<std::uint8_t dimensions> AbstractDebugRenderer<dimensions>::AbstractDebugRenderer(ResourceKey shader, ResourceKey mesh, ResourceKey options, typename SceneGraph::AbstractObject<dimensions>::ObjectType* parent): SceneGraph::AbstractObject<dimensions>::ObjectType(parent), shader(DebugDrawResourceManager::instance()->get<AbstractShaderProgram, Shaders::FlatShader<dimensions>>(shader)), mesh(DebugDrawResourceManager::instance()->get<Mesh>(mesh)), options(DebugDrawResourceManager::instance()->get<Options>(options)) {}
template<std::uint8_t dimensions> AbstractDebugRenderer<dimensions>::AbstractDebugRenderer(ResourceKey shader, ResourceKey mesh): shader(DebugDrawResourceManager::instance()->get<AbstractShaderProgram, Shaders::FlatShader<dimensions>>(shader)), mesh(DebugDrawResourceManager::instance()->get<Mesh>(mesh)) {}
template<std::uint8_t dimensions> AbstractDebugRenderer<dimensions>::~AbstractDebugRenderer() {}
template class AbstractDebugRenderer<2>;
template class AbstractDebugRenderer<3>;

16
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<std::uint8_t dimensions> class AbstractDebugRenderer: public SceneGraph::AbstractObject<dimensions>::ObjectType {
template<std::uint8_t dimensions> class AbstractDebugRenderer {
public:
AbstractDebugRenderer(ResourceKey shader, ResourceKey mesh, ResourceKey options, typename SceneGraph::AbstractObject<dimensions>::ObjectType* parent);
AbstractDebugRenderer(ResourceKey shader, ResourceKey mesh);
virtual ~AbstractDebugRenderer();
virtual void draw(Resource<Options>& options, const typename DimensionTraits<dimensions>::MatrixType& transformationMatrix, SceneGraph::AbstractCamera<dimensions, GLfloat>* camera) = 0;
protected:
Resource<AbstractShaderProgram, Shaders::FlatShader<dimensions>> shader;
Resource<Mesh> mesh;
Resource<Options> options;
};
extern template class AbstractDebugRenderer<2>;
extern template class AbstractDebugRenderer<3>;
}}}
#endif

17
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<std::uint8_t> 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<std::uint8_t dimensions> BoxRenderer<dimensions>::BoxRenderer(Box<dimensions>& box, ResourceKey options, typename SceneGraph::AbstractObject<dimensions>::ObjectType* parent): AbstractDebugRenderer<dimensions>(BoxMesh<dimensions>::shader(), BoxMesh<dimensions>::key(), options, parent), buffer(DebugDrawResourceManager::instance()->get<Buffer>(BoxMesh<dimensions>::key())), box(box) {
template<std::uint8_t dimensions> BoxRenderer<dimensions>::BoxRenderer(Box<dimensions>& box): AbstractDebugRenderer<dimensions>(BoxMesh<dimensions>::shader(), BoxMesh<dimensions>::key()), buffer(DebugDrawResourceManager::instance()->get<Buffer>(BoxMesh<dimensions>::key())), box(box) {
if(!this->mesh) {
DebugDrawResourceManager::instance()->set(this->buffer.key(), new Buffer, ResourceDataState::Final, ResourcePolicy::Manual);
DebugDrawResourceManager::instance()->set<Mesh>(this->mesh.key(), BoxMesh<dimensions>::mesh(buffer), ResourceDataState::Final, ResourcePolicy::Manual);
}
}
template<std::uint8_t dimensions> void BoxRenderer<dimensions>::draw(const typename DimensionTraits<dimensions, GLfloat>::MatrixType&, typename SceneGraph::AbstractObject<dimensions>::CameraType* camera) {
this->shader->setTransformationProjection(camera->projectionMatrix()*box.transformedTransformation())
->setColor(this->options->color)
template<std::uint8_t dimensions> void BoxRenderer<dimensions>::draw(Resource<Options>& options, const typename DimensionTraits<dimensions, GLfloat>::MatrixType&, typename SceneGraph::AbstractCamera<dimensions>* camera) {
this->shader->setTransformationProjection(camera->projectionMatrix()*camera->cameraMatrix()*box.transformedTransformation())
->setColor(options->color)
->use();
this->mesh->draw();
}

9
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<std::uint8_t dimensions> class BoxRenderer: public AbstractDebugRenderer<dimensions> {
public:
BoxRenderer(Box<dimensions>& box, ResourceKey options, typename SceneGraph::AbstractObject<dimensions>::ObjectType* parent);
BoxRenderer(Box<dimensions>& box);
void draw(const typename DimensionTraits<dimensions, GLfloat>::MatrixType& transformation, typename SceneGraph::AbstractObject<dimensions>::CameraType* camera);
void draw(Resource<Options>& options, const typename DimensionTraits<dimensions>::MatrixType& transformation, typename SceneGraph::AbstractCamera<dimensions, GLfloat>* camera) override;
private:
Resource<Buffer> buffer;
Box<dimensions>& box;
};
extern template class BoxRenderer<2>;
extern template class BoxRenderer<3>;
}}}
#endif

58
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š <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 "ResourceManager.h"
#include "SceneGraph/Drawable.h"
#include "AbstractDebugRenderer.h"
namespace Magnum {
class AbstractShaderProgram;
class Mesh;
namespace Shaders {
template<std::uint8_t> class FlatShader;
}
namespace Physics { namespace Implementation {
struct Options;
template<std::uint8_t dimensions> class DebugRenderer: public SceneGraph::Drawable<dimensions> {
public:
DebugRenderer(SceneGraph::AbstractObject<dimensions>* object, Resource<Options>&& options): SceneGraph::Drawable<dimensions>(object), options(options) {}
inline ~DebugRenderer() {
for(auto i: renderers) delete i;
}
inline void addRenderer(AbstractDebugRenderer<dimensions>* renderer) {
renderers.push_back(renderer);
}
inline void draw(const typename DimensionTraits<dimensions>::MatrixType& transformationMatrix, SceneGraph::AbstractCamera<dimensions, GLfloat>* camera) override {
for(auto i: renderers) i->draw(options, transformationMatrix, camera);
}
private:
Resource<Options> options;
std::vector<AbstractDebugRenderer<dimensions>*> renderers;
};
}}}
#endif
Loading…
Cancel
Save