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 <Corrade/Containers/GrowableArray.h>
#include "Magnum/Math/Color.h"
#include "Magnum/Math/Functions.h"
#include "Magnum/Mesh.h"
#include "Magnum/Primitives/Implementation/Spheroid.h"
#include "Magnum/Primitives/Implementation/WireframeSpheroid.h"
#include "Magnum/Trade/ArrayAllocator.h"
#include "Magnum/Trade/MeshData.h"
namespace Magnum { namespace Primitives {
@ -42,12 +41,14 @@ Trade::MeshData capsule2DWireframe(const UnsignedInt hemisphereRings, const Unsi
(Trade::MeshData{MeshPrimitive::Triangles, 0}));
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 Float cylinderIncrement = 2.0f*halfLength/cylinderRings;
/* Bottom cap vertex */
arrayAppend(vertexData, {0.0f, -halfLength-1.0f});
Containers::arrayAppend<Trade::ArrayAllocator>(vertexData,
{0.0f, -halfLength-1.0f});
/* Bottom hemisphere */
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 Float x = sincos.first;
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) */
for(UnsignedInt i = 0; i != cylinderRings-1; ++i) {
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 */
@ -70,32 +73,37 @@ Trade::MeshData capsule2DWireframe(const UnsignedInt hemisphereRings, const Unsi
const std::pair<Float, Float> sincos = Math::sincos(angle);
const Float x = sincos.second;
const Float y = sincos.first+halfLength;
arrayAppend(vertexData, {{-x, y}, {x, y}});
Containers::arrayAppend<Trade::ArrayAllocator>(vertexData,
{{-x, y}, {x, y}});
}
/* Top cap vertex */
arrayAppend(vertexData, {0.0f, halfLength+1.0f});
Containers::arrayAppend<Trade::ArrayAllocator>(vertexData,
{0.0f, halfLength+1.0f});
Containers::Array<UnsignedInt> indexData;
arrayReserve(indexData, hemisphereRings*8+cylinderRings*4);
Containers::arrayReserve<Trade::ArrayAllocator>(indexData,
hemisphereRings*8+cylinderRings*4);
/* Bottom cap indices */
arrayAppend(indexData, {0u, 1u, 0u, 2u});
Containers::arrayAppend<Trade::ArrayAllocator>(indexData,
{0u, 1u, 0u, 2u});
/* Side indices */
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 */
arrayAppend(indexData,
Containers::arrayAppend<Trade::ArrayAllocator>(indexData,
{UnsignedInt(vertexData.size())-3, UnsignedInt(vertexData.size())-1,
UnsignedInt(vertexData.size())-2, UnsignedInt(vertexData.size())-1});
Trade::MeshIndexData indices{indexData};
Trade::MeshAttributeData positions{Trade::MeshAttribute::Position, Containers::arrayView(vertexData)};
return Trade::MeshData{MeshPrimitive::Lines,
Containers::arrayAllocatorCast<char>(std::move(indexData)), indices,
Containers::arrayAllocatorCast<char>(std::move(vertexData)), {positions}};
Containers::arrayAllocatorCast<char, Trade::ArrayAllocator>(std::move(indexData)), indices,
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) {

9
src/Magnum/Primitives/Icosphere.cpp

@ -25,12 +25,11 @@
#include "Icosphere.h"
#include <Corrade/Containers/GrowableArray.h>
#include "Magnum/Mesh.h"
#include "Magnum/Math/Vector3.h"
#include "Magnum/MeshTools/RemoveDuplicates.h"
#include "Magnum/MeshTools/Subdivide.h"
#include "Magnum/Trade/ArrayAllocator.h"
#include "Magnum/Trade/MeshData.h"
namespace Magnum { namespace Primitives {
@ -90,7 +89,8 @@ Trade::MeshData icosphereSolid(const UnsignedInt subdivisions) {
Vector3 normal;
};
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 */
{
@ -108,7 +108,8 @@ Trade::MeshData icosphereSolid(const UnsignedInt subdivisions) {
}
/** @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 */

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

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

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

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

Loading…
Cancel
Save