Browse Source

*Tools: deinlined heavy functions, removed redundant `inline`.

pull/278/head
Vladimír Vondruš 13 years ago
parent
commit
5bf61ceb74
  1. 10
      src/DebugTools/ForceRenderer.h
  2. 2
      src/DebugTools/Implementation/ForceRendererTransformation.h
  3. 16
      src/DebugTools/ObjectRenderer.cpp
  4. 6
      src/DebugTools/ObjectRenderer.h
  5. 2
      src/DebugTools/Profiler.h
  6. 14
      src/DebugTools/ShapeRenderer.h
  7. 136
      src/MeshTools/Clean.h
  8. 8
      src/MeshTools/CombineIndexedArrays.h
  9. 6
      src/MeshTools/CompressIndices.cpp
  10. 20
      src/MeshTools/Interleave.h
  11. 76
      src/MeshTools/Subdivide.h
  12. 2
      src/MeshTools/Test/SubdivideCleanBenchmark.h
  13. 2
      src/MeshTools/Test/SubdivideTest.cpp
  14. 2
      src/MeshTools/Tipsify.h
  15. 4
      src/TextureTools/DistanceField.cpp

10
src/DebugTools/ForceRenderer.h

@ -44,10 +44,10 @@ See ForceRenderer documentation for more information.
*/
class ForceRendererOptions {
public:
inline constexpr ForceRendererOptions(): _color(1.0f), _size(1.0f) {}
constexpr ForceRendererOptions(): _color(1.0f), _size(1.0f) {}
/** @brief Color of rendered arrow */
inline constexpr Color4<> color() const { return _color; }
constexpr Color4<> color() const { return _color; }
/**
* @brief Set color of rendered arrow
@ -55,13 +55,13 @@ class ForceRendererOptions {
*
* Default is 100% opaque white.
*/
inline ForceRendererOptions* setColor(const Color4<>& color) {
ForceRendererOptions* setColor(const Color4<>& color) {
_color = color;
return this;
}
/** @brief Scale of rendered arrow */
inline constexpr Float scale() const { return _size; }
constexpr Float scale() const { return _size; }
/**
* @brief Set scale of rendered arrow
@ -69,7 +69,7 @@ class ForceRendererOptions {
*
* Default is `1.0f`.
*/
inline ForceRendererOptions* setSize(Float size) {
ForceRendererOptions* setSize(Float size) {
_size = size;
return this;
}

2
src/DebugTools/Implementation/ForceRendererTransformation.h

@ -37,7 +37,7 @@ template<> inline Matrix3 forceRendererTransformation<2>(const Vector2& forcePos
return Matrix3::from({force, Vector2(-force.y(), force.x())}, forcePosition);
}
template<> inline Matrix4 forceRendererTransformation<3>(const Vector3& forcePosition, const Vector3& force) {
template<> Matrix4 forceRendererTransformation<3>(const Vector3& forcePosition, const Vector3& force) {
const Matrix4 translation = Matrix4::translation(forcePosition);
const Float forceLength = force.length();

16
src/DebugTools/ObjectRenderer.cpp

@ -37,10 +37,10 @@ namespace {
template<UnsignedInt> struct Renderer;
template<> struct Renderer<2> {
inline static ResourceKey shader() { return {"VertexColorShader2D"}; }
inline static ResourceKey vertexBuffer() { return {"object2d-vertices"}; }
inline static ResourceKey indexBuffer() { return {"object2d-indices"}; }
inline static ResourceKey mesh() { return {"object2d"}; }
static ResourceKey shader() { return {"VertexColorShader2D"}; }
static ResourceKey vertexBuffer() { return {"object2d-vertices"}; }
static ResourceKey indexBuffer() { return {"object2d-indices"}; }
static ResourceKey mesh() { return {"object2d"}; }
static const std::array<Vector2, 8> positions;
static const std::array<Color3<>, 8> colors;
@ -82,10 +82,10 @@ const std::array<UnsignedByte, 12> Renderer<2>::indices{{
}};
template<> struct Renderer<3> {
inline static ResourceKey shader() { return {"VertexColorShader3D"}; }
inline static ResourceKey vertexBuffer() { return {"object3d-vertices"}; }
inline static ResourceKey indexBuffer() { return {"object3d-indices"}; }
inline static ResourceKey mesh() { return {"object3d"}; }
static ResourceKey shader() { return {"VertexColorShader3D"}; }
static ResourceKey vertexBuffer() { return {"object3d-vertices"}; }
static ResourceKey indexBuffer() { return {"object3d-indices"}; }
static ResourceKey mesh() { return {"object3d"}; }
static const std::array<Vector3, 12> positions;
static const std::array<Color3<>, 12> colors;

6
src/DebugTools/ObjectRenderer.h

@ -43,10 +43,10 @@ See ObjectRenderer documentation for more information.
*/
class ObjectRendererOptions {
public:
inline constexpr ObjectRendererOptions(): _size(1.0f) {}
constexpr ObjectRendererOptions(): _size(1.0f) {}
/** @brief Size of the rendered axes */
inline constexpr Float size() const { return _size; }
constexpr Float size() const { return _size; }
/**
* @brief Set size of the rendered axes
@ -54,7 +54,7 @@ class ObjectRendererOptions {
*
* Default is `1.0f`.
*/
inline ObjectRendererOptions* setSize(Float size) {
ObjectRendererOptions* setSize(Float size) {
_size = size;
return this;
}

2
src/DebugTools/Profiler.h

@ -171,7 +171,7 @@ class MAGNUM_DEBUGTOOLS_EXPORT Profiler {
* Same as calling `start(Profiler::otherSection)`.
* @note Does nothing if profiling is disabled.
*/
inline void start() { start(otherSection); }
void start() { start(otherSection); }
/**
* @brief Stop profiling

14
src/DebugTools/ShapeRenderer.h

@ -66,10 +66,10 @@ class ShapeRendererOptions {
Solid
};
inline constexpr ShapeRendererOptions(): _color(1.0f), _pointSize(0.25f), _renderMode(RenderMode::Wireframe) {}
constexpr ShapeRendererOptions(): _color(1.0f), _pointSize(0.25f), _renderMode(RenderMode::Wireframe) {}
/** @brief Shape rendering mode */
inline constexpr RenderMode renderMode() const { return _renderMode; }
constexpr RenderMode renderMode() const { return _renderMode; }
/**
* @brief Set shape rendering mode
@ -77,13 +77,13 @@ class ShapeRendererOptions {
*
* Default is @ref RenderMode "RenderMode::Wireframe".
*/
inline ShapeRendererOptions* setRenderMode(RenderMode mode) {
ShapeRendererOptions* setRenderMode(RenderMode mode) {
_renderMode = mode;
return this;
}
/** @brief Color of rendered shape */
inline constexpr Color4<> color() const { return _color; }
constexpr Color4<> color() const { return _color; }
/**
* @brief Set color of rendered shape
@ -91,13 +91,13 @@ class ShapeRendererOptions {
*
* Default is 100% opaque white.
*/
inline ShapeRendererOptions* setColor(const Color4<>& color) {
ShapeRendererOptions* setColor(const Color4<>& color) {
_color = color;
return this;
}
/** @brief Point size */
inline constexpr Float pointSize() const { return _pointSize; }
constexpr Float pointSize() const { return _pointSize; }
/**
* @brief Set point size
@ -106,7 +106,7 @@ class ShapeRendererOptions {
* Size of rendered crosshairs, representing Shapes::Point shapes.
* Default is `0.25f`.
*/
inline ShapeRendererOptions* setPointSize(Float size) {
ShapeRendererOptions* setPointSize(Float size) {
_pointSize = size;
return this;
}

136
src/MeshTools/Clean.h

@ -41,76 +41,14 @@ namespace Implementation {
template<class Vertex, std::size_t vertexSize = Vertex::Size> class Clean {
public:
inline Clean(std::vector<UnsignedInt>& indices, std::vector<Vertex>& vertices): indices(indices), vertices(vertices) {}
void operator()(typename Vertex::Type epsilon = Math::TypeTraits<typename Vertex::Type>::epsilon()) {
if(indices.empty()) return;
/* Get mesh bounds */
Vertex min, max;
for(std::size_t i = 0; i != Vertex::Size; ++i) {
min[i] = std::numeric_limits<typename Vertex::Type>::max();
max[i] = std::numeric_limits<typename Vertex::Type>::min();
}
for(auto it = vertices.cbegin(); it != vertices.cend(); ++it)
for(std::size_t i = 0; i != vertexSize; ++i)
if((*it)[i] < min[i])
min[i] = (*it)[i];
else if((*it)[i] > max[i])
max[i] = (*it)[i];
/* Make epsilon so large that std::size_t can index all vertices
inside mesh bounds. */
Vertex size = max-min;
for(std::size_t i = 0; i != Vertex::Size; ++i)
if(static_cast<typename Vertex::Type>(size[i]/std::numeric_limits<std::size_t>::max()) > epsilon)
epsilon = static_cast<typename Vertex::Type>(size[i]/std::numeric_limits<std::size_t>::max());
/* First go with original vertex coordinates, then move them by
epsilon/2 in each direction. */
Vertex moved;
for(std::size_t moving = 0; moving <= vertexSize; ++moving) {
/* Under each index is pointer to face which contains given vertex
and index of vertex in the face. */
std::unordered_map<Math::Vector<vertexSize, std::size_t>, HashedVertex, IndexHash> table;
/* Reserve space for all vertices */
table.reserve(vertices.size());
/* Go through all faces' vertices */
for(auto it = indices.begin(); it != indices.end(); ++it) {
/* Index of a vertex in vertexSize-dimensional table */
std::size_t index[vertexSize];
for(std::size_t ii = 0; ii != vertexSize; ++ii)
index[ii] = (vertices[*it][ii]+moved[ii]-min[ii])/epsilon;
/* Try inserting the vertex into table, if it already
exists, change vertex pointer of the face to already
existing vertex */
HashedVertex v(*it, table.size());
auto result = table.insert(std::pair<Math::Vector<vertexSize, std::size_t>, HashedVertex>(Math::Vector<vertexSize, std::size_t>::from(index), v));
*it = result.first->second.newIndex;
}
/* Shrink vertices array */
std::vector<Vertex> newVertices(table.size());
for(auto it = table.cbegin(); it != table.cend(); ++it)
newVertices[it->second.newIndex] = vertices[it->second.oldIndex];
std::swap(newVertices, vertices);
Clean(std::vector<UnsignedInt>& indices, std::vector<Vertex>& vertices): indices(indices), vertices(vertices) {}
/* Move vertex coordinates by epsilon/2 in next direction */
if(moving != Vertex::Size) {
moved = Vertex();
moved[moving] = epsilon/2;
}
}
}
void operator()(typename Vertex::Type epsilon = Math::TypeTraits<typename Vertex::Type>::epsilon());
private:
class IndexHash {
public:
inline std::size_t operator()(const Math::Vector<vertexSize, std::size_t>& data) const {
std::size_t operator()(const Math::Vector<vertexSize, std::size_t>& data) const {
return *reinterpret_cast<const std::size_t*>(Utility::MurmurHash2()(reinterpret_cast<const char*>(&data), sizeof(data)).byteArray());
}
};
@ -148,6 +86,74 @@ template<class Vertex, std::size_t vertexSize = Vertex::Size> inline void clean(
Implementation::Clean<Vertex, vertexSize>(indices, vertices)(epsilon);
}
namespace Implementation {
template<class Vertex, std::size_t vertexSize> void Clean<Vertex, vertexSize>::operator()(typename Vertex::Type epsilon) {
if(indices.empty()) return;
/* Get mesh bounds */
Vertex min, max;
for(std::size_t i = 0; i != Vertex::Size; ++i) {
min[i] = std::numeric_limits<typename Vertex::Type>::max();
max[i] = std::numeric_limits<typename Vertex::Type>::min();
}
for(auto it = vertices.cbegin(); it != vertices.cend(); ++it)
for(std::size_t i = 0; i != vertexSize; ++i)
if((*it)[i] < min[i])
min[i] = (*it)[i];
else if((*it)[i] > max[i])
max[i] = (*it)[i];
/* Make epsilon so large that std::size_t can index all vertices
inside mesh bounds. */
Vertex size = max-min;
for(std::size_t i = 0; i != Vertex::Size; ++i)
if(static_cast<typename Vertex::Type>(size[i]/std::numeric_limits<std::size_t>::max()) > epsilon)
epsilon = static_cast<typename Vertex::Type>(size[i]/std::numeric_limits<std::size_t>::max());
/* First go with original vertex coordinates, then move them by
epsilon/2 in each direction. */
Vertex moved;
for(std::size_t moving = 0; moving <= vertexSize; ++moving) {
/* Under each index is pointer to face which contains given vertex
and index of vertex in the face. */
std::unordered_map<Math::Vector<vertexSize, std::size_t>, HashedVertex, IndexHash> table;
/* Reserve space for all vertices */
table.reserve(vertices.size());
/* Go through all faces' vertices */
for(auto it = indices.begin(); it != indices.end(); ++it) {
/* Index of a vertex in vertexSize-dimensional table */
std::size_t index[vertexSize];
for(std::size_t ii = 0; ii != vertexSize; ++ii)
index[ii] = (vertices[*it][ii]+moved[ii]-min[ii])/epsilon;
/* Try inserting the vertex into table, if it already
exists, change vertex pointer of the face to already
existing vertex */
HashedVertex v(*it, table.size());
auto result = table.insert(std::pair<Math::Vector<vertexSize, std::size_t>, HashedVertex>(Math::Vector<vertexSize, std::size_t>::from(index), v));
*it = result.first->second.newIndex;
}
/* Shrink vertices array */
std::vector<Vertex> newVertices(table.size());
for(auto it = table.cbegin(); it != table.cend(); ++it)
newVertices[it->second.newIndex] = vertices[it->second.oldIndex];
std::swap(newVertices, vertices);
/* Move vertex coordinates by epsilon/2 in next direction */
if(moving != Vertex::Size) {
moved = Vertex();
moved[moving] = epsilon/2;
}
}
}
}
}}
#endif

8
src/MeshTools/CombineIndexedArrays.h

@ -64,7 +64,7 @@ class CombineIndexedArrays {
}
private:
template<class ...T> inline static std::size_t indexCount(const std::vector<UnsignedInt>& first, const std::vector<T>&... next) {
template<class ...T> static std::size_t indexCount(const std::vector<UnsignedInt>& first, const std::vector<T>&... next) {
CORRADE_ASSERT(sizeof...(next) == 0 || indexCount(next...) == first.size(), "MeshTools::combineIndexedArrays(): index arrays don't have the same length, nothing done.", 0);
return first.size();
@ -89,9 +89,9 @@ class CombineIndexedArrays {
}
/* Terminator functions for recursive calls */
inline static std::size_t indexCount() { return 0; }
template<std::size_t size> inline static void writeCombinedIndices(std::vector<Math::Vector<size, UnsignedInt>>&) {}
template<std::size_t size> inline static void writeCombinedArrays(const std::vector<Math::Vector<size, UnsignedInt>>&) {}
static std::size_t indexCount() { return 0; }
template<std::size_t size> static void writeCombinedIndices(std::vector<Math::Vector<size, UnsignedInt>>&) {}
template<std::size_t size> static void writeCombinedArrays(const std::vector<Math::Vector<size, UnsignedInt>>&) {}
};
}

6
src/MeshTools/CompressIndices.cpp

@ -34,9 +34,9 @@ namespace Magnum { namespace MeshTools {
namespace {
template<class> constexpr Mesh::IndexType indexType();
template<> inline constexpr Mesh::IndexType indexType<UnsignedByte>() { return Mesh::IndexType::UnsignedByte; }
template<> inline constexpr Mesh::IndexType indexType<UnsignedShort>() { return Mesh::IndexType::UnsignedShort; }
template<> inline constexpr Mesh::IndexType indexType<UnsignedInt>() { return Mesh::IndexType::UnsignedInt; }
template<> constexpr Mesh::IndexType indexType<UnsignedByte>() { return Mesh::IndexType::UnsignedByte; }
template<> constexpr Mesh::IndexType indexType<UnsignedShort>() { return Mesh::IndexType::UnsignedShort; }
template<> constexpr Mesh::IndexType indexType<UnsignedInt>() { return Mesh::IndexType::UnsignedInt; }
template<class T> inline std::tuple<std::size_t, Mesh::IndexType, char*> compress(const std::vector<UnsignedInt>& indices) {
char* buffer = new char[indices.size()*sizeof(T)];

20
src/MeshTools/Interleave.h

@ -42,7 +42,7 @@ namespace Implementation {
class Interleave {
public:
inline Interleave(): _attributeCount(0), _stride(0), _data(nullptr) {}
Interleave(): _attributeCount(0), _stride(0), _data(nullptr) {}
template<class ...T> std::tuple<std::size_t, std::size_t, char*> operator()(const T&... attributes) {
/* Compute buffer size and stride */
@ -75,30 +75,30 @@ class Interleave {
buffer->setData(attribute, usage);
}
template<class T, class ...U> inline static typename std::enable_if<!std::is_convertible<T, std::size_t>::value, std::size_t>::type attributeCount(const T& first, const U&... next) {
template<class T, class ...U> static typename std::enable_if<!std::is_convertible<T, std::size_t>::value, std::size_t>::type attributeCount(const T& first, const U&... next) {
CORRADE_ASSERT(sizeof...(next) == 0 || attributeCount(next...) == first.size() || attributeCount(next...) == ~std::size_t(0), "MeshTools::interleave(): attribute arrays don't have the same length, nothing done.", 0);
return first.size();
}
template<class... T> inline static std::size_t attributeCount(std::size_t, const T&... next) {
template<class... T> static std::size_t attributeCount(std::size_t, const T&... next) {
return attributeCount(next...);
}
template<class ...T> inline static std::size_t attributeCount(std::size_t) {
template<class ...T> static std::size_t attributeCount(std::size_t) {
return ~std::size_t(0);
}
template<class T, class ...U> inline static typename std::enable_if<!std::is_convertible<T, std::size_t>::value, std::size_t>::type stride(const T&, const U&... next) {
template<class T, class ...U> static typename std::enable_if<!std::is_convertible<T, std::size_t>::value, std::size_t>::type stride(const T&, const U&... next) {
return sizeof(typename T::value_type) + stride(next...);
}
template<class... T> inline static std::size_t stride(std::size_t gap, const T&... next) {
template<class... T> static std::size_t stride(std::size_t gap, const T&... next) {
return gap + stride(next...);
}
private:
template<class T, class ...U> inline void write(char* startingOffset, const T& first, const U&... next) {
template<class T, class ...U> void write(char* startingOffset, const T& first, const U&... next) {
write(startingOffset+writeOne(startingOffset, first), next...);
}
@ -122,9 +122,9 @@ class Interleave {
}
/* Terminator functions for recursive calls */
inline static std::size_t attributeCount() { return 0; }
inline static std::size_t stride() { return 0; }
inline void write(char*) {}
static std::size_t attributeCount() { return 0; }
static std::size_t stride() { return 0; }
void write(char*) {}
std::size_t _attributeCount;
std::size_t _stride;

76
src/MeshTools/Subdivide.h

@ -37,41 +37,9 @@ namespace Implementation {
template<class Vertex, class Interpolator> class Subdivide {
public:
inline Subdivide(std::vector<UnsignedInt>& indices, std::vector<Vertex>& vertices): indices(indices), vertices(vertices) {}
void operator()(Interpolator interpolator) {
CORRADE_ASSERT(!(indices.size()%3), "MeshTools::subdivide(): index count is not divisible by 3!", );
std::size_t indexCount = indices.size();
indices.reserve(indices.size()*4);
/* Subdivide each face to four new */
for(std::size_t i = 0; i != indexCount; i += 3) {
/* Interpolate each side */
UnsignedInt newVertices[3];
for(int j = 0; j != 3; ++j)
newVertices[j] = addVertex(interpolator(vertices[indices[i+j]], vertices[indices[i+(j+1)%3]]));
/*
* Add three new faces (0, 1, 3) and update original (2)
*
* orig 0
* / \
* / 0 \
* / \
* new 0 ----- new 2
* / \ / \
* / 1 \ 2 / 3 \
* / \ / \
* orig 1 ----- new 1 ---- orig 2
*/
addFace(indices[i], newVertices[0], newVertices[2]);
addFace(newVertices[0], indices[i+1], newVertices[1]);
addFace(newVertices[2], newVertices[1], indices[i+2]);
for(std::size_t j = 0; j != 3; ++j)
indices[i+j] = newVertices[j];
}
}
Subdivide(std::vector<UnsignedInt>& indices, std::vector<Vertex>& vertices): indices(indices), vertices(vertices) {}
void operator()(Interpolator interpolator);
private:
std::vector<UnsignedInt>& indices;
@ -107,6 +75,44 @@ template<class Vertex, class Interpolator> inline void subdivide(std::vector<Uns
Implementation::Subdivide<Vertex, Interpolator>(indices, vertices)(interpolator);
}
namespace Implementation {
template<class Vertex, class Interpolator> void Subdivide<Vertex, Interpolator>::operator()(Interpolator interpolator) {
CORRADE_ASSERT(!(indices.size()%3), "MeshTools::subdivide(): index count is not divisible by 3!", );
std::size_t indexCount = indices.size();
indices.reserve(indices.size()*4);
/* Subdivide each face to four new */
for(std::size_t i = 0; i != indexCount; i += 3) {
/* Interpolate each side */
UnsignedInt newVertices[3];
for(int j = 0; j != 3; ++j)
newVertices[j] = addVertex(interpolator(vertices[indices[i+j]], vertices[indices[i+(j+1)%3]]));
/*
* Add three new faces (0, 1, 3) and update original (2)
*
* orig 0
* / \
* / 0 \
* / \
* new 0 ----- new 2
* / \ / \
* / 1 \ 2 / 3 \
* / \ / \
* orig 1 ----- new 1 ---- orig 2
*/
addFace(indices[i], newVertices[0], newVertices[2]);
addFace(newVertices[0], indices[i+1], newVertices[1]);
addFace(newVertices[2], newVertices[1], indices[i+2]);
for(std::size_t j = 0; j != 3; ++j)
indices[i+j] = newVertices[j];
}
}
}
}}
#endif

2
src/MeshTools/Test/SubdivideCleanBenchmark.h

@ -39,7 +39,7 @@ class SubdivideCleanBenchmark: public QObject {
void subdivideAndCleanMeshBetween();
private:
static inline Magnum::Vector4 interpolator(const Magnum::Vector4& a, const Magnum::Vector4& b) {
static Magnum::Vector4 interpolator(const Magnum::Vector4& a, const Magnum::Vector4& b) {
return (a+b).xyz().normalized();
}
};

2
src/MeshTools/Test/SubdivideTest.cpp

@ -54,7 +54,7 @@ class SubdivideTest: public TestSuite::Tester {
Type data;
};
inline static Vector1 interpolator(Vector1 a, Vector1 b) { return (a[0]+b[0])/2; }
static Vector1 interpolator(Vector1 a, Vector1 b) { return (a[0]+b[0])/2; }
};
SubdivideTest::SubdivideTest() {

2
src/MeshTools/Tipsify.h

@ -39,7 +39,7 @@ namespace Implementation {
class MAGNUM_MESHTOOLS_EXPORT Tipsify {
public:
inline Tipsify(std::vector<UnsignedInt>& indices, UnsignedInt vertexCount): indices(indices), vertexCount(vertexCount) {}
Tipsify(std::vector<UnsignedInt>& indices, UnsignedInt vertexCount): indices(indices), vertexCount(vertexCount) {}
void operator()(std::size_t cacheSize);

4
src/TextureTools/DistanceField.cpp

@ -45,12 +45,12 @@ class DistanceFieldShader: public AbstractShaderProgram {
explicit DistanceFieldShader();
inline DistanceFieldShader* setRadius(Int radius) {
DistanceFieldShader* setRadius(Int radius) {
setUniform(radiusUniform, radius);
return this;
}
inline DistanceFieldShader* setScaling(Vector2 scaling) {
DistanceFieldShader* setScaling(Vector2 scaling) {
setUniform(scalingUniform, scaling);
return this;
}

Loading…
Cancel
Save