diff --git a/modules/FindMagnum.cmake b/modules/FindMagnum.cmake index a4544ed74..a242f3310 100644 --- a/modules/FindMagnum.cmake +++ b/modules/FindMagnum.cmake @@ -16,7 +16,8 @@ # libraries. Additional dependencies are specified by the components. The # optional components are: # MeshTools - MeshTools library -# Physics - Physics library (depends on SceneGraph component) +# Physics - Physics library (depends on Primitives and SceneGraph +# components) # 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 799da9a00..a9709f340 100644 --- a/src/Physics/CMakeLists.txt +++ b/src/Physics/CMakeLists.txt @@ -1,20 +1,30 @@ +corrade_add_resource(MagnumPhysics_RCS MagnumPhysics + Implementation/ShapeShader2D.vert ALIAS ShapeShader2D.vert + Implementation/ShapeShader2D.frag ALIAS ShapeShader2D.frag) + set(MagnumPhysics_SRCS AbstractShape.cpp AxisAlignedBox.cpp Box.cpp Capsule.cpp + DebugDrawResourceManager.cpp Line.cpp Plane.cpp Point.cpp ShapedObject.cpp ShapedObjectGroup.cpp ShapeGroup.cpp - Sphere.cpp) + Sphere.cpp + + Implementation/AbstractDebugRenderer.cpp + Implementation/ShapeShader.cpp + ${MagnumPhysics_RCS}) set(MagnumPhysics_HEADERS AbstractShape.h AxisAlignedBox.h Box.h Capsule.h + DebugDrawResourceManager.h Line.h LineSegment.h Plane.h @@ -28,7 +38,7 @@ set(MagnumPhysics_HEADERS add_library(MagnumPhysics SHARED ${MagnumPhysics_SRCS}) -target_link_libraries(MagnumPhysics Magnum MagnumSceneGraph) +target_link_libraries(MagnumPhysics Magnum MagnumPrimitives MagnumSceneGraph) install(TARGETS MagnumPhysics DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) install(FILES ${MagnumPhysics_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Physics) diff --git a/src/Physics/DebugDrawResourceManager.cpp b/src/Physics/DebugDrawResourceManager.cpp new file mode 100644 index 000000000..a19cb3152 --- /dev/null +++ b/src/Physics/DebugDrawResourceManager.cpp @@ -0,0 +1,56 @@ +/* + 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 "DebugDrawResourceManager.h" + +#include "AbstractShaderProgram.h" +#include "Mesh.h" +#include "AbstractShape.h" +#include "Box.h" +#include "ShapedObject.h" +#include "ShapeGroup.h" +#include "Implementation/AbstractDebugRenderer.h" +#include "Implementation/ShapeShader.h" + +namespace Magnum { + +template class ResourceManager; + +namespace Physics { + +SceneGraph::Object2D* DebugDrawResourceManager::createDebugRenderer(AbstractShape2D* shape, ResourceKey options) { + return createDebugMesh(nullptr, shape, options); +} + +SceneGraph::Object2D* DebugDrawResourceManager::createDebugMesh(SceneGraph::Object2D* parent, AbstractShape2D* shape, ResourceKey options) { + switch(shape->type()) { + 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; + } +} + +DebugDrawResourceManager::DebugDrawResourceManager() { + setFallback(new Options); + set("shader2d", new Implementation::ShapeShader<2>, ResourceDataState::Final, ResourcePolicy::Resident); +} + +DebugDrawResourceManager::~DebugDrawResourceManager() {} + +}} diff --git a/src/Physics/DebugDrawResourceManager.h b/src/Physics/DebugDrawResourceManager.h new file mode 100644 index 000000000..92f292b70 --- /dev/null +++ b/src/Physics/DebugDrawResourceManager.h @@ -0,0 +1,119 @@ +#ifndef Magnum_Physics_DebugDrawResourceManager_h +#define Magnum_Physics_DebugDrawResourceManager_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::DebugDrawResourceManager + */ + +#include "Magnum.h" +#include "Color.h" +#include "ResourceManager.h" + +#include "magnumPhysicsVisibility.h" + +namespace Magnum { + +class AbstractShaderProgram; +class Mesh; + +#ifndef DOXYGEN_GENERATING_OUTPUT +namespace Physics { namespace Implementation { + struct Options { + Color3 color; + }; + template class AbstractDebugRenderer; +}} + +extern template class PHYSICS_EXPORT ResourceManager; +#endif + +namespace SceneGraph { + class Object2D; + class Object3D; +} + +namespace Physics { + +template class AbstractShape; +typedef AbstractShape<2> AbstractShape2D; +typedef AbstractShape<3> AbstractShape3D; + +/** +@brief %Resource manager for physics debug draw + +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 +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 +given key exist, default is used. + +Example code: +@code +// Instance the manager at first +DebugDrawResourceManager manager; + +// Create some options +auto o = new DebugDrawResourceManager::Options { + {1.0f, 0.0f, 0.0f} // Red color +}; +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); +@endcode +*/ +class PHYSICS_EXPORT DebugDrawResourceManager: public ResourceManager { + public: + #ifdef DOXYGEN_GENERATING_OUTPUT + /** @brief %Options */ + struct Options { + Color3 color; /**< @brief Color */ + }; + #else + typedef Implementation::Options Options; + #endif + + /** + * @brief Create debug renderer for given shape + * @param shape Shape for which to create debug renderer + * @param options Options resource key. See + * @ref DebugDrawResourceManager-usage "class documentation" for + * more information. + * + * Returned object is not parented to anything, you have to add it to + * desired scene yourself. + */ + static SceneGraph::Object2D* createDebugRenderer(AbstractShape2D* shape, ResourceKey options = ResourceKey()); + + DebugDrawResourceManager(); + + ~DebugDrawResourceManager(); + + private: + static SceneGraph::Object2D* createDebugMesh(SceneGraph::Object2D* parent, AbstractShape2D* shape, ResourceKey options); +}; + +}} + +#endif diff --git a/src/Physics/Implementation/AbstractDebugRenderer.cpp b/src/Physics/Implementation/AbstractDebugRenderer.cpp new file mode 100644 index 000000000..76bcfcf22 --- /dev/null +++ b/src/Physics/Implementation/AbstractDebugRenderer.cpp @@ -0,0 +1,30 @@ +/* + 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 "AbstractDebugRenderer.h" + +#include "AbstractShaderProgram.h" +#include "Mesh.h" +#include "Physics/DebugDrawResourceManager.h" +#include "ShapeShader.h" + +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 class AbstractDebugRenderer<2>; +template class AbstractDebugRenderer<3>; + +}}} diff --git a/src/Physics/Implementation/AbstractDebugRenderer.h b/src/Physics/Implementation/AbstractDebugRenderer.h new file mode 100644 index 000000000..63400b22b --- /dev/null +++ b/src/Physics/Implementation/AbstractDebugRenderer.h @@ -0,0 +1,48 @@ +#ifndef Magnum_Physics_Implementation_AbstractDebugRenderer_h +#define Magnum_Physics_Implementation_AbstractDebugRenderer_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 "Color.h" +#include "ResourceManager.h" +#include "SceneGraph/Camera.h" + +namespace Magnum { + +class AbstractShaderProgram; +class Mesh; + +namespace Physics { namespace Implementation { + +struct Options; + +template class ShapeShader; + +template class AbstractDebugRenderer: public SceneGraph::AbstractObject::ObjectType { + public: + AbstractDebugRenderer(ResourceKey shader, ResourceKey mesh, ResourceKey options, typename SceneGraph::AbstractObject::ObjectType* parent); + + protected: + Resource> shader; + Resource mesh; + Resource options; +}; + +extern template class AbstractDebugRenderer<2>; +extern template class AbstractDebugRenderer<3>; + +}}} + +#endif diff --git a/src/Physics/Implementation/ShapeShader.cpp b/src/Physics/Implementation/ShapeShader.cpp new file mode 100644 index 000000000..c7cf1096f --- /dev/null +++ b/src/Physics/Implementation/ShapeShader.cpp @@ -0,0 +1,52 @@ +/* + 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 "ShapeShader.h" + +#include + +#include "Shader.h" + +namespace Magnum { namespace Physics { namespace Implementation { + +namespace { + template struct ShaderName {}; + + template<> struct ShaderName<2> { + constexpr static const char* Vertex = "ShapeShader2D.vert"; + constexpr static const char* Fragment = "ShapeShader2D.frag"; + }; + + template<> struct ShaderName<3> { + constexpr static const char* Vertex = "ShapeShader3D.vert"; + constexpr static const char* Fragment = "ShapeShader3D.frag"; + }; +} + +template ShapeShader::ShapeShader() { + Corrade::Utility::Resource resource("MagnumPhysics"); + attachShader(Shader::fromData(Version::GL330, Shader::Type::Vertex, resource.get(ShaderName::Vertex))); + attachShader(Shader::fromData(Version::GL330, Shader::Type::Fragment, resource.get(ShaderName::Fragment))); + + link(); + + transformationProjectionUniform = uniformLocation("transformationProjection"); + colorUniform = uniformLocation("color"); +} + +template class ShapeShader<2>; +template class ShapeShader<3>; + +}}} diff --git a/src/Physics/Implementation/ShapeShader.h b/src/Physics/Implementation/ShapeShader.h new file mode 100644 index 000000000..b1d1eac98 --- /dev/null +++ b/src/Physics/Implementation/ShapeShader.h @@ -0,0 +1,52 @@ +#ifndef Magnum_Physics_Implementation_ShapeShader_h +#define Magnum_Physics_Implementation_ShapeShader_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 "Math/Matrix3.h" +#include "Math/Matrix4.h" +#include "AbstractShaderProgram.h" +#include "Color.h" +#include "DimensionTraits.h" + +namespace Magnum { namespace Physics { namespace Implementation { + +template class ShapeShader: public AbstractShaderProgram { + public: + typedef Attribute<0, typename DimensionTraits::PointType> Position; + + ShapeShader(); + + ShapeShader* setTransformationProjection(const typename DimensionTraits::MatrixType& matrix) { + setUniform(transformationProjectionUniform, matrix); + return this; + } + + ShapeShader* setColor(const Color3& color) { + setUniform(colorUniform, color); + return this; + } + + private: + GLint transformationProjectionUniform, + colorUniform; +}; + +extern template class ShapeShader<2>; +extern template class ShapeShader<3>; + +}}} + +#endif diff --git a/src/Physics/Implementation/ShapeShader2D.frag b/src/Physics/Implementation/ShapeShader2D.frag new file mode 100644 index 000000000..200b2f88c --- /dev/null +++ b/src/Physics/Implementation/ShapeShader2D.frag @@ -0,0 +1,7 @@ +uniform vec3 color; + +out vec4 fragmentColor; + +void main() { + fragmentColor = vec4(color, 1.0); +} diff --git a/src/Physics/Implementation/ShapeShader2D.vert b/src/Physics/Implementation/ShapeShader2D.vert new file mode 100644 index 000000000..0ab2076cf --- /dev/null +++ b/src/Physics/Implementation/ShapeShader2D.vert @@ -0,0 +1,7 @@ +uniform mat3 transformationProjection; + +layout(location = 0) in vec3 position; + +void main() { + gl_Position.xywz = vec4(transformationProjection*position, 0.0); +}