Browse Source

Primitives: use the exported growable allocator from Trade.

So the primitives can be used inside plugins without the risk of
dangling deleter pointers.
pull/430/head
Vladimír Vondruš 6 years ago
parent
commit
ff3e771231
  1. 36
      src/Magnum/Primitives/Capsule.cpp
  2. 9
      src/Magnum/Primitives/Icosphere.cpp
  3. 17
      src/Magnum/Primitives/Implementation/Spheroid.cpp
  4. 46
      src/Magnum/Primitives/Implementation/WireframeSpheroid.cpp

36
src/Magnum/Primitives/Capsule.cpp

@ -25,13 +25,12 @@
#include "Capsule.h" #include "Capsule.h"
#include <Corrade/Containers/GrowableArray.h>
#include "Magnum/Math/Color.h" #include "Magnum/Math/Color.h"
#include "Magnum/Math/Functions.h" #include "Magnum/Math/Functions.h"
#include "Magnum/Mesh.h" #include "Magnum/Mesh.h"
#include "Magnum/Primitives/Implementation/Spheroid.h" #include "Magnum/Primitives/Implementation/Spheroid.h"
#include "Magnum/Primitives/Implementation/WireframeSpheroid.h" #include "Magnum/Primitives/Implementation/WireframeSpheroid.h"
#include "Magnum/Trade/ArrayAllocator.h"
#include "Magnum/Trade/MeshData.h" #include "Magnum/Trade/MeshData.h"
namespace Magnum { namespace Primitives { namespace Magnum { namespace Primitives {
@ -42,12 +41,14 @@ Trade::MeshData capsule2DWireframe(const UnsignedInt hemisphereRings, const Unsi
(Trade::MeshData{MeshPrimitive::Triangles, 0})); (Trade::MeshData{MeshPrimitive::Triangles, 0}));
Containers::Array<Vector2> vertexData; Containers::Array<Vector2> vertexData;
arrayReserve(vertexData, hemisphereRings*4+2+(cylinderRings-1)*2); Containers::arrayReserve<Trade::ArrayAllocator>(vertexData,
hemisphereRings*4+2+(cylinderRings-1)*2);
const Rad angleIncrement(Constants::piHalf()/hemisphereRings); const Rad angleIncrement(Constants::piHalf()/hemisphereRings);
const Float cylinderIncrement = 2.0f*halfLength/cylinderRings; const Float cylinderIncrement = 2.0f*halfLength/cylinderRings;
/* Bottom cap vertex */ /* Bottom cap vertex */
arrayAppend(vertexData, {0.0f, -halfLength-1.0f}); Containers::arrayAppend<Trade::ArrayAllocator>(vertexData,
{0.0f, -halfLength-1.0f});
/* Bottom hemisphere */ /* Bottom hemisphere */
for(UnsignedInt i = 0; i != hemisphereRings; ++i) { for(UnsignedInt i = 0; i != hemisphereRings; ++i) {
@ -55,13 +56,15 @@ Trade::MeshData capsule2DWireframe(const UnsignedInt hemisphereRings, const Unsi
const std::pair<Float, Float> sincos = Math::sincos(angle); const std::pair<Float, Float> sincos = Math::sincos(angle);
const Float x = sincos.first; const Float x = sincos.first;
const Float y = -sincos.second-halfLength; const Float y = -sincos.second-halfLength;
arrayAppend(vertexData, {{-x, y}, {x, y}}); Containers::arrayAppend<Trade::ArrayAllocator>(vertexData,
{{-x, y}, {x, y}});
} }
/* Cylinder (bottom and top vertices are done within caps) */ /* Cylinder (bottom and top vertices are done within caps) */
for(UnsignedInt i = 0; i != cylinderRings-1; ++i) { for(UnsignedInt i = 0; i != cylinderRings-1; ++i) {
const Float y = (i+1)*cylinderIncrement-halfLength; const Float y = (i+1)*cylinderIncrement-halfLength;
arrayAppend(vertexData, {{-1.0f, y}, {1.0f, y}}); Containers::arrayAppend<Trade::ArrayAllocator>(vertexData,
{{-1.0f, y}, {1.0f, y}});
} }
/* Top hemisphere */ /* Top hemisphere */
@ -70,32 +73,37 @@ Trade::MeshData capsule2DWireframe(const UnsignedInt hemisphereRings, const Unsi
const std::pair<Float, Float> sincos = Math::sincos(angle); const std::pair<Float, Float> sincos = Math::sincos(angle);
const Float x = sincos.second; const Float x = sincos.second;
const Float y = sincos.first+halfLength; const Float y = sincos.first+halfLength;
arrayAppend(vertexData, {{-x, y}, {x, y}}); Containers::arrayAppend<Trade::ArrayAllocator>(vertexData,
{{-x, y}, {x, y}});
} }
/* Top cap vertex */ /* Top cap vertex */
arrayAppend(vertexData, {0.0f, halfLength+1.0f}); Containers::arrayAppend<Trade::ArrayAllocator>(vertexData,
{0.0f, halfLength+1.0f});
Containers::Array<UnsignedInt> indexData; Containers::Array<UnsignedInt> indexData;
arrayReserve(indexData, hemisphereRings*8+cylinderRings*4); Containers::arrayReserve<Trade::ArrayAllocator>(indexData,
hemisphereRings*8+cylinderRings*4);
/* Bottom cap indices */ /* Bottom cap indices */
arrayAppend(indexData, {0u, 1u, 0u, 2u}); Containers::arrayAppend<Trade::ArrayAllocator>(indexData,
{0u, 1u, 0u, 2u});
/* Side indices */ /* Side indices */
for(UnsignedInt i = 0; i != cylinderRings+hemisphereRings*2-2; ++i) for(UnsignedInt i = 0; i != cylinderRings+hemisphereRings*2-2; ++i)
arrayAppend(indexData, {i*2+1, i*2+3, i*2+2, i*2+4}); Containers::arrayAppend<Trade::ArrayAllocator>(indexData,
{i*2+1, i*2+3, i*2+2, i*2+4});
/* Top cap indices */ /* Top cap indices */
arrayAppend(indexData, Containers::arrayAppend<Trade::ArrayAllocator>(indexData,
{UnsignedInt(vertexData.size())-3, UnsignedInt(vertexData.size())-1, {UnsignedInt(vertexData.size())-3, UnsignedInt(vertexData.size())-1,
UnsignedInt(vertexData.size())-2, UnsignedInt(vertexData.size())-1}); UnsignedInt(vertexData.size())-2, UnsignedInt(vertexData.size())-1});
Trade::MeshIndexData indices{indexData}; Trade::MeshIndexData indices{indexData};
Trade::MeshAttributeData positions{Trade::MeshAttribute::Position, Containers::arrayView(vertexData)}; Trade::MeshAttributeData positions{Trade::MeshAttribute::Position, Containers::arrayView(vertexData)};
return Trade::MeshData{MeshPrimitive::Lines, return Trade::MeshData{MeshPrimitive::Lines,
Containers::arrayAllocatorCast<char>(std::move(indexData)), indices, Containers::arrayAllocatorCast<char, Trade::ArrayAllocator>(std::move(indexData)), indices,
Containers::arrayAllocatorCast<char>(std::move(vertexData)), {positions}}; Containers::arrayAllocatorCast<char, Trade::ArrayAllocator>(std::move(vertexData)), {positions}};
} }
Trade::MeshData capsule3DSolid(const UnsignedInt hemisphereRings, const UnsignedInt cylinderRings, const UnsignedInt segments, const Float halfLength, const CapsuleFlags flags) { Trade::MeshData capsule3DSolid(const UnsignedInt hemisphereRings, const UnsignedInt cylinderRings, const UnsignedInt segments, const Float halfLength, const CapsuleFlags flags) {

9
src/Magnum/Primitives/Icosphere.cpp

@ -25,12 +25,11 @@
#include "Icosphere.h" #include "Icosphere.h"
#include <Corrade/Containers/GrowableArray.h>
#include "Magnum/Mesh.h" #include "Magnum/Mesh.h"
#include "Magnum/Math/Vector3.h" #include "Magnum/Math/Vector3.h"
#include "Magnum/MeshTools/RemoveDuplicates.h" #include "Magnum/MeshTools/RemoveDuplicates.h"
#include "Magnum/MeshTools/Subdivide.h" #include "Magnum/MeshTools/Subdivide.h"
#include "Magnum/Trade/ArrayAllocator.h"
#include "Magnum/Trade/MeshData.h" #include "Magnum/Trade/MeshData.h"
namespace Magnum { namespace Primitives { namespace Magnum { namespace Primitives {
@ -90,7 +89,8 @@ Trade::MeshData icosphereSolid(const UnsignedInt subdivisions) {
Vector3 normal; Vector3 normal;
}; };
Containers::Array<char> vertexData; Containers::Array<char> vertexData;
arrayResize(vertexData, Containers::NoInit, sizeof(Vertex)*vertexCount); Containers::arrayResize<Trade::ArrayAllocator>(vertexData,
Containers::NoInit, sizeof(Vertex)*vertexCount);
/* Build up the subdivided positions */ /* Build up the subdivided positions */
{ {
@ -108,7 +108,8 @@ Trade::MeshData icosphereSolid(const UnsignedInt subdivisions) {
} }
/** @todo i need arrayShrinkAndGiveUpMemoryIfItDoesntCauseRealloc() */ /** @todo i need arrayShrinkAndGiveUpMemoryIfItDoesntCauseRealloc() */
arrayResize(vertexData, MeshTools::removeDuplicatesIndexedInPlace(Containers::stridedArrayView(indices), Containers::stridedArrayView(positions))*sizeof(Vertex)); Containers::arrayResize<Trade::ArrayAllocator>(vertexData,
MeshTools::removeDuplicatesIndexedInPlace(Containers::stridedArrayView(indices), Containers::stridedArrayView(positions))*sizeof(Vertex));
} }
/* Build up the views again with correct size, fill the normals */ /* Build up the views again with correct size, fill the normals */

17
src/Magnum/Primitives/Implementation/Spheroid.cpp

@ -31,6 +31,7 @@
#include "Magnum/Math/Color.h" #include "Magnum/Math/Color.h"
#include "Magnum/Mesh.h" #include "Magnum/Mesh.h"
#include "Magnum/Trade/MeshData.h" #include "Magnum/Trade/MeshData.h"
#include "Magnum/Trade/ArrayAllocator.h"
namespace Magnum { namespace Primitives { namespace Implementation { namespace Magnum { namespace Primitives { namespace Implementation {
@ -58,10 +59,12 @@ struct VertexTextureCoords {
void Spheroid::append(const Vector3& position, const Vector3& normal, const Vector2& textureCoords) { void Spheroid::append(const Vector3& position, const Vector3& normal, const Vector2& textureCoords) {
if(_flags & Flag::TextureCoordinates) { if(_flags & Flag::TextureCoordinates) {
const VertexTextureCoords v[]{{position, normal, textureCoords}}; const VertexTextureCoords v[]{{position, normal, textureCoords}};
arrayAppend(_vertexData, Containers::arrayCast<const char>(Containers::arrayView(v))); Containers::arrayAppend<Trade::ArrayAllocator>(_vertexData,
Containers::arrayCast<const char>(Containers::arrayView(v)));
} else { } else {
const Vertex v[]{{position, normal}}; const Vertex v[]{{position, normal}};
arrayAppend(_vertexData, Containers::arrayCast<const char>(Containers::arrayView(v))); Containers::arrayAppend<Trade::ArrayAllocator>(_vertexData,
Containers::arrayCast<const char>(Containers::arrayView(v)));
} }
} }
@ -137,7 +140,7 @@ void Spheroid::cylinderVertexRings(const UnsignedInt count, const Float startY,
void Spheroid::bottomFaceRing() { void Spheroid::bottomFaceRing() {
for(UnsignedInt j = 0; j != _segments; ++j) { for(UnsignedInt j = 0; j != _segments; ++j) {
arrayAppend(_indexData, { Containers::arrayAppend<Trade::ArrayAllocator>(_indexData, {
/* Bottom vertex */ /* Bottom vertex */
0u, 0u,
@ -162,7 +165,7 @@ void Spheroid::faceRings(UnsignedInt count, UnsignedInt offset) {
const UnsignedInt topLeft = bottomLeft+vertexSegments; const UnsignedInt topLeft = bottomLeft+vertexSegments;
const UnsignedInt topRight = bottomRight+vertexSegments; const UnsignedInt topRight = bottomRight+vertexSegments;
arrayAppend(_indexData, { Containers::arrayAppend<Trade::ArrayAllocator>(_indexData, {
bottomLeft, bottomLeft,
bottomRight, bottomRight,
topRight, topRight,
@ -184,7 +187,7 @@ void Spheroid::topFaceRing() {
vertexCount = _vertexData.size()/sizeof(Vertex); vertexCount = _vertexData.size()/sizeof(Vertex);
for(UnsignedInt j = 0; j != _segments; ++j) { for(UnsignedInt j = 0; j != _segments; ++j) {
arrayAppend(_indexData, { Containers::arrayAppend<Trade::ArrayAllocator>(_indexData, {
/* Bottom left vertex */ /* Bottom left vertex */
vertexCount - vertexSegments + j - 1, vertexCount - vertexSegments + j - 1,
@ -251,8 +254,8 @@ Trade::MeshData Spheroid::finalize() {
const UnsignedInt vertexCount = _vertexData.size()/attributes[0].stride(); const UnsignedInt vertexCount = _vertexData.size()/attributes[0].stride();
return Trade::MeshData{MeshPrimitive::Triangles, return Trade::MeshData{MeshPrimitive::Triangles,
Containers::arrayAllocatorCast<char>(std::move(_indexData)), indices, Containers::arrayAllocatorCast<char, Trade::ArrayAllocator>(std::move(_indexData)),
std::move(_vertexData), std::move(attributes), vertexCount}; indices, std::move(_vertexData), std::move(attributes), vertexCount};
} }
}}} }}}

46
src/Magnum/Primitives/Implementation/WireframeSpheroid.cpp

@ -25,11 +25,10 @@
#include "WireframeSpheroid.h" #include "WireframeSpheroid.h"
#include <Corrade/Containers/GrowableArray.h>
#include "Magnum/Math/Functions.h" #include "Magnum/Math/Functions.h"
#include "Magnum/Math/Color.h" #include "Magnum/Math/Color.h"
#include "Magnum/Mesh.h" #include "Magnum/Mesh.h"
#include "Magnum/Trade/ArrayAllocator.h"
#include "Magnum/Trade/MeshData.h" #include "Magnum/Trade/MeshData.h"
namespace Magnum { namespace Primitives { namespace Implementation { namespace Magnum { namespace Primitives { namespace Implementation {
@ -40,11 +39,12 @@ void WireframeSpheroid::bottomHemisphere(const Float endY, const UnsignedInt rin
CORRADE_INTERNAL_ASSERT(_vertexData.empty()); CORRADE_INTERNAL_ASSERT(_vertexData.empty());
/* Initial vertex */ /* Initial vertex */
arrayAppend(_vertexData, Vector3::yAxis(endY - 1.0f)); Containers::arrayAppend<Trade::ArrayAllocator>(_vertexData,
Vector3::yAxis(endY - 1.0f));
/* Connect initial vertex to first ring */ /* Connect initial vertex to first ring */
for(UnsignedInt i = 0; i != 4; ++i) for(UnsignedInt i = 0; i != 4; ++i)
arrayAppend(_indexData, {0u, i+1}); Containers::arrayAppend<Trade::ArrayAllocator>(_indexData, {0u, i+1});
/* Hemisphere vertices and indices */ /* Hemisphere vertices and indices */
const Rad ringAngleIncrement(Constants::piHalf()/rings); const Rad ringAngleIncrement(Constants::piHalf()/rings);
@ -52,7 +52,7 @@ void WireframeSpheroid::bottomHemisphere(const Float endY, const UnsignedInt rin
const Rad angle = Float(j+1)*ringAngleIncrement; const Rad angle = Float(j+1)*ringAngleIncrement;
const std::pair<Float, Float> sincos = Math::sincos(angle); const std::pair<Float, Float> sincos = Math::sincos(angle);
arrayAppend(_vertexData, { Containers::arrayAppend<Trade::ArrayAllocator>(_vertexData, {
{0.0f, endY - sincos.second, sincos.first}, {0.0f, endY - sincos.second, sincos.first},
{sincos.first, endY - sincos.second, 0.0f}, {sincos.first, endY - sincos.second, 0.0f},
{0.0f, endY - sincos.second, -sincos.first}, {0.0f, endY - sincos.second, -sincos.first},
@ -61,7 +61,8 @@ void WireframeSpheroid::bottomHemisphere(const Float endY, const UnsignedInt rin
/* Connect vertices to next ring */ /* Connect vertices to next ring */
for(UnsignedInt i = 0; i != 4; ++i) { for(UnsignedInt i = 0; i != 4; ++i) {
arrayAppend(_indexData, {UnsignedInt(_vertexData.size()) - 4 + i, UnsignedInt(_vertexData.size()) + i}); Containers::arrayAppend<Trade::ArrayAllocator>(_indexData,
{UnsignedInt(_vertexData.size()) - 4 + i, UnsignedInt(_vertexData.size()) + i});
} }
} }
} }
@ -69,7 +70,8 @@ void WireframeSpheroid::bottomHemisphere(const Float endY, const UnsignedInt rin
void WireframeSpheroid::topHemisphere(const Float startY, const UnsignedInt rings) { void WireframeSpheroid::topHemisphere(const Float startY, const UnsignedInt rings) {
/* Connect previous ring to following vertices (if any) */ /* Connect previous ring to following vertices (if any) */
if(rings > 1) for(UnsignedInt i = 0; i != 4; ++i) { if(rings > 1) for(UnsignedInt i = 0; i != 4; ++i) {
arrayAppend(_indexData, {UnsignedInt(_vertexData.size()) - 4*_segments + i, UnsignedInt(_vertexData.size()) + i}); Containers::arrayAppend<Trade::ArrayAllocator>(_indexData,
{UnsignedInt(_vertexData.size()) - 4*_segments + i, UnsignedInt(_vertexData.size()) + i});
} }
/* Hemisphere vertices and indices */ /* Hemisphere vertices and indices */
@ -80,10 +82,11 @@ void WireframeSpheroid::topHemisphere(const Float startY, const UnsignedInt ring
/* Connect previous hemisphere ring to current vertices */ /* Connect previous hemisphere ring to current vertices */
if(j != 0) for(UnsignedInt i = 0; i != 4; ++i) { if(j != 0) for(UnsignedInt i = 0; i != 4; ++i) {
arrayAppend(_indexData, {UnsignedInt(_vertexData.size()) - 4 + i, UnsignedInt(_vertexData.size()) + i}); Containers::arrayAppend<Trade::ArrayAllocator>(_indexData,
{UnsignedInt(_vertexData.size()) - 4 + i, UnsignedInt(_vertexData.size()) + i});
} }
arrayAppend(_vertexData, { Containers::arrayAppend<Trade::ArrayAllocator>(_vertexData, {
{0.0f, startY + sincos.first, sincos.second}, {0.0f, startY + sincos.first, sincos.second},
{sincos.second, startY + sincos.first, 0.0f}, {sincos.second, startY + sincos.first, 0.0f},
{0.0f, startY + sincos.first, -sincos.second}, {0.0f, startY + sincos.first, -sincos.second},
@ -92,13 +95,16 @@ void WireframeSpheroid::topHemisphere(const Float startY, const UnsignedInt ring
} }
/* Final vertex */ /* Final vertex */
arrayAppend(_vertexData, Vector3::yAxis(startY + 1.0f)); Containers::arrayAppend<Trade::ArrayAllocator>(_vertexData,
Vector3::yAxis(startY + 1.0f));
/* Connect last ring to final vertex */ /* Connect last ring to final vertex */
if(rings > 1) for(UnsignedInt i = 0; i != 4; ++i) if(rings > 1) for(UnsignedInt i = 0; i != 4; ++i)
arrayAppend(_indexData, {UnsignedInt(_vertexData.size()) - 5 + i, UnsignedInt(_vertexData.size()) - 1}); Containers::arrayAppend<Trade::ArrayAllocator>(_indexData,
{UnsignedInt(_vertexData.size()) - 5 + i, UnsignedInt(_vertexData.size()) - 1});
else for(UnsignedInt i = 0; i != 4; ++i) else for(UnsignedInt i = 0; i != 4; ++i)
arrayAppend(_indexData, {UnsignedInt(_vertexData.size()) - 4*_segments + i - 1, UnsignedInt(_vertexData.size()) - 1}); Containers::arrayAppend<Trade::ArrayAllocator>(_indexData,
{UnsignedInt(_vertexData.size()) - 4*_segments + i - 1, UnsignedInt(_vertexData.size()) - 1});
} }
void WireframeSpheroid::ring(const Float y) { void WireframeSpheroid::ring(const Float y) {
@ -108,20 +114,24 @@ void WireframeSpheroid::ring(const Float y) {
for(UnsignedInt i = 0; i != 4; ++i) { for(UnsignedInt i = 0; i != 4; ++i) {
const Rad segmentAngle = Rad(Float(i)*Constants::piHalf()) + Float(j)*segmentAngleIncrement; const Rad segmentAngle = Rad(Float(i)*Constants::piHalf()) + Float(j)*segmentAngleIncrement;
const std::pair<Float, Float> sincos = Math::sincos(segmentAngle); const std::pair<Float, Float> sincos = Math::sincos(segmentAngle);
if(j != 0) arrayAppend(_indexData, {UnsignedInt(_vertexData.size() - 4), UnsignedInt(_vertexData.size())}); if(j != 0) Containers::arrayAppend<Trade::ArrayAllocator>(_indexData,
arrayAppend(_vertexData, {sincos.first, y, sincos.second}); {UnsignedInt(_vertexData.size() - 4), UnsignedInt(_vertexData.size())});
Containers::arrayAppend<Trade::ArrayAllocator>(_vertexData,
{sincos.first, y, sincos.second});
} }
} }
/* Close the ring */ /* Close the ring */
for(UnsignedInt i = 0; i != 4; ++i) for(UnsignedInt i = 0; i != 4; ++i)
arrayAppend(_indexData, {UnsignedInt(_vertexData.size()) - 4 + i, UnsignedInt(_vertexData.size()) - 4*_segments + (i + 1)%4}); Containers::arrayAppend<Trade::ArrayAllocator>(_indexData,
{UnsignedInt(_vertexData.size()) - 4 + i, UnsignedInt(_vertexData.size()) - 4*_segments + (i + 1)%4});
} }
void WireframeSpheroid::cylinder() { void WireframeSpheroid::cylinder() {
/* Connect four vertex pairs of previous and next ring */ /* Connect four vertex pairs of previous and next ring */
for(UnsignedInt i = 0; i != 4; ++i) for(UnsignedInt i = 0; i != 4; ++i)
arrayAppend(_indexData, {UnsignedInt(_vertexData.size()) - 4*_segments + i, UnsignedInt(_vertexData.size()) + i}); Containers::arrayAppend<Trade::ArrayAllocator>(_indexData,
{UnsignedInt(_vertexData.size()) - 4*_segments + i, UnsignedInt(_vertexData.size()) + i});
} }
namespace { namespace {
@ -138,8 +148,8 @@ Trade::MeshData WireframeSpheroid::finalize() {
Trade::MeshAttributeData positions{Trade::MeshAttribute::Position, Containers::arrayView(_vertexData)}; Trade::MeshAttributeData positions{Trade::MeshAttribute::Position, Containers::arrayView(_vertexData)};
const UnsignedInt vertexCount = _vertexData.size(); const UnsignedInt vertexCount = _vertexData.size();
return Trade::MeshData{MeshPrimitive::Lines, return Trade::MeshData{MeshPrimitive::Lines,
Containers::arrayAllocatorCast<char>(std::move(_indexData)), indices, Containers::arrayAllocatorCast<char, Trade::ArrayAllocator>(std::move(_indexData)), indices,
Containers::arrayAllocatorCast<char>(std::move(_vertexData)), Containers::arrayAllocatorCast<char, Trade::ArrayAllocator>(std::move(_vertexData)),
Trade::meshAttributeDataNonOwningArray(AttributeData), vertexCount}; Trade::meshAttributeDataNonOwningArray(AttributeData), vertexCount};
} }

Loading…
Cancel
Save