From aacb6b7041967b83f881627dd78d368801757833 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 6 Jul 2013 20:09:11 +0200 Subject: [PATCH] Trade: return references, not pointers from MeshData. The access methods assert that the user is querying only available data. Also updated Primitives implementation to create MeshData when everything is done, not creating empty MeshData and then shooting the data through interface intended for end users. --- .../Implementation/AbstractShapeRenderer.cpp | 16 ++-- src/Primitives/Capsule.cpp | 7 +- src/Primitives/Circle.cpp | 22 +++--- src/Primitives/Crosshair.cpp | 4 +- src/Primitives/Cube.cpp | 10 +-- src/Primitives/Cylinder.cpp | 5 +- src/Primitives/Icosphere.cpp | 6 +- src/Primitives/Implementation/Spheroid.cpp | 76 ++++++++++--------- src/Primitives/Implementation/Spheroid.h | 15 +++- src/Primitives/Line.cpp | 4 +- src/Primitives/Plane.cpp | 6 +- src/Primitives/Square.cpp | 4 +- src/Primitives/Test/CapsuleTest.cpp | 12 +-- src/Primitives/Test/CircleTest.cpp | 4 +- src/Primitives/Test/CylinderTest.cpp | 14 ++-- src/Primitives/Test/UVSphereTest.cpp | 12 +-- src/Primitives/UVSphere.cpp | 9 ++- src/Trade/MeshData2D.cpp | 46 +++++++---- src/Trade/MeshData2D.h | 66 ++++++++-------- src/Trade/MeshData3D.cpp | 58 ++++++++++---- src/Trade/MeshData3D.h | 76 ++++++++++--------- 21 files changed, 276 insertions(+), 196 deletions(-) diff --git a/src/DebugTools/Implementation/AbstractShapeRenderer.cpp b/src/DebugTools/Implementation/AbstractShapeRenderer.cpp index c11985bd5..6ee4d5f4c 100644 --- a/src/DebugTools/Implementation/AbstractShapeRenderer.cpp +++ b/src/DebugTools/Implementation/AbstractShapeRenderer.cpp @@ -46,21 +46,21 @@ template void create(typename MeshData::Type template<> void create<2>(Trade::MeshData2D& data, Resource& meshResource, Resource& vertexBufferResource, Resource& indexBufferResource) { /* Vertex buffer */ Buffer* buffer = new Buffer(Buffer::Target::Array); - buffer->setData(*data.positions(0), Buffer::Usage::StaticDraw); + buffer->setData(data.positions(0), Buffer::Usage::StaticDraw); ResourceManager::instance()->set(vertexBufferResource.key(), buffer, ResourceDataState::Final, ResourcePolicy::Manual); /* Mesh configuration */ Mesh* mesh = new Mesh; mesh->setPrimitive(data.primitive()) - ->setVertexCount(data.positions(0)->size()) + ->setVertexCount(data.positions(0).size()) ->addVertexBuffer(buffer, 0, Shaders::Flat2D::Position()); ResourceManager::instance()->set(meshResource.key(), mesh, ResourceDataState::Final, ResourcePolicy::Manual); /* Index buffer, if needed, if not, resource key doesn't have to be set */ - if(data.indices()) { + if(data.isIndexed()) { CORRADE_INTERNAL_ASSERT(indexBufferResource.key() != ResourceKey()); Buffer* indexBuffer = new Buffer(Buffer::Target::ElementArray); - MeshTools::compressIndices(mesh, indexBuffer, Buffer::Usage::StaticDraw, *data.indices()); + MeshTools::compressIndices(mesh, indexBuffer, Buffer::Usage::StaticDraw, data.indices()); ResourceManager::instance()->set(indexBufferResource.key(), indexBuffer, ResourceDataState::Final, ResourcePolicy::Manual); } } @@ -68,21 +68,21 @@ template<> void create<2>(Trade::MeshData2D& data, Resource& meshResource, template<> void create<3>(Trade::MeshData3D& data, Resource& meshResource, Resource& vertexBufferResource, Resource& indexBufferResource) { /* Vertex buffer */ Buffer* vertexBuffer = new Buffer(Buffer::Target::Array); - vertexBuffer->setData(*data.positions(0), Buffer::Usage::StaticDraw); + vertexBuffer->setData(data.positions(0), Buffer::Usage::StaticDraw); ResourceManager::instance()->set(vertexBufferResource.key(), vertexBuffer, ResourceDataState::Final, ResourcePolicy::Manual); /* Mesh configuration */ Mesh* mesh = new Mesh; mesh->setPrimitive(data.primitive()) - ->setVertexCount(data.positions(0)->size()) + ->setVertexCount(data.positions(0).size()) ->addVertexBuffer(vertexBuffer, 0, Shaders::Flat3D::Position()); ResourceManager::instance()->set(meshResource.key(), mesh, ResourceDataState::Final, ResourcePolicy::Manual); /* Index buffer, if needed, if not, resource key doesn't have to be set */ - if(data.indices()) { + if(data.isIndexed()) { CORRADE_INTERNAL_ASSERT(indexBufferResource.key() != ResourceKey()); Buffer* indexBuffer = new Buffer(Buffer::Target::ElementArray); - MeshTools::compressIndices(mesh, indexBuffer, Buffer::Usage::StaticDraw, *data.indices()); + MeshTools::compressIndices(mesh, indexBuffer, Buffer::Usage::StaticDraw, data.indices()); ResourceManager::instance()->set(indexBufferResource.key(), indexBuffer, ResourceDataState::Final, ResourcePolicy::Manual); } } diff --git a/src/Primitives/Capsule.cpp b/src/Primitives/Capsule.cpp index 1447e2e16..d0128ba53 100644 --- a/src/Primitives/Capsule.cpp +++ b/src/Primitives/Capsule.cpp @@ -24,13 +24,14 @@ #include "Capsule.h" -#include "Math/Angle.h" +#include "Math/Vector3.h" #include "Primitives/Implementation/Spheroid.h" +#include "Trade/MeshData3D.h" namespace Magnum { namespace Primitives { Trade::MeshData3D Capsule::solid(UnsignedInt hemisphereRings, UnsignedInt cylinderRings, UnsignedInt segments, Float length, TextureCoords textureCoords) { - CORRADE_ASSERT(hemisphereRings >= 1 && cylinderRings >= 1 && segments >= 3, "Capsule must have at least one hemisphere ring, one cylinder ring and three segments", Trade::MeshData3D(Mesh::Primitive::Triangles, nullptr, {}, {}, {})); + CORRADE_ASSERT(hemisphereRings >= 1 && cylinderRings >= 1 && segments >= 3, "Capsule must have at least one hemisphere ring, one cylinder ring and three segments", Trade::MeshData3D(Mesh::Primitive::Triangles, {}, {}, {}, {})); Implementation::Spheroid capsule(segments, textureCoords == TextureCoords::Generate ? Implementation::Spheroid::TextureCoords::Generate : @@ -60,7 +61,7 @@ Trade::MeshData3D Capsule::solid(UnsignedInt hemisphereRings, UnsignedInt cylind capsule.faceRings(hemisphereRings*2-2+cylinderRings); capsule.topFaceRing(); - return std::move(capsule); + return capsule.finalize(); } }} diff --git a/src/Primitives/Circle.cpp b/src/Primitives/Circle.cpp index 3ad904ca4..e6b019410 100644 --- a/src/Primitives/Circle.cpp +++ b/src/Primitives/Circle.cpp @@ -32,39 +32,39 @@ namespace Magnum { namespace Primitives { Trade::MeshData2D Circle::solid(UnsignedInt segments) { CORRADE_ASSERT(segments >= 3, "Primitives::Circle::solid(): segments must be >= 3", - Trade::MeshData2D(Mesh::Primitive::TriangleFan, nullptr, {}, {})); + Trade::MeshData2D(Mesh::Primitive::TriangleFan, {}, {}, {})); - auto positions = new std::vector; - positions->reserve(segments+1); + std::vector positions; + positions.reserve(segments+1); /* Central point */ - positions->emplace_back(); + positions.emplace_back(); /* Points on circle */ const Rad angleIncrement(2*Constants::pi()/segments); for(UnsignedInt i = 0; i != segments; ++i) { const Rad angle(i*angleIncrement); - positions->emplace_back(Math::cos(angle), Math::sin(angle)); + positions.emplace_back(Math::cos(angle), Math::sin(angle)); } - return Trade::MeshData2D(Mesh::Primitive::TriangleFan, nullptr, {positions}, {}); + return Trade::MeshData2D(Mesh::Primitive::TriangleFan, {}, {std::move(positions)}, {}); } Trade::MeshData2D Circle::wireframe(UnsignedInt segments) { CORRADE_ASSERT(segments >= 3, "Primitives::Circle::wireframe(): segments must be >= 3", - Trade::MeshData2D(Mesh::Primitive::LineLoop, nullptr, {}, {})); + Trade::MeshData2D(Mesh::Primitive::LineLoop, {}, {}, {})); - auto positions = new std::vector; - positions->reserve(segments); + std::vector positions; + positions.reserve(segments); /* Points on circle */ const Rad angleIncrement(2*Constants::pi()/segments); for(UnsignedInt i = 0; i != segments; ++i) { const Rad angle(i*angleIncrement); - positions->emplace_back(Math::cos(angle), Math::sin(angle)); + positions.emplace_back(Math::cos(angle), Math::sin(angle)); } - return Trade::MeshData2D(Mesh::Primitive::LineLoop, nullptr, {positions}, {}); + return Trade::MeshData2D(Mesh::Primitive::LineLoop, {}, {std::move(positions)}, {}); } }} diff --git a/src/Primitives/Crosshair.cpp b/src/Primitives/Crosshair.cpp index c20fe61fe..a03aa2292 100644 --- a/src/Primitives/Crosshair.cpp +++ b/src/Primitives/Crosshair.cpp @@ -31,14 +31,14 @@ namespace Magnum { namespace Primitives { Trade::MeshData2D Crosshair2D::wireframe() { - return Trade::MeshData2D(Mesh::Primitive::Lines, nullptr, {new std::vector{ + return Trade::MeshData2D(Mesh::Primitive::Lines, {}, {{ {-1.0f, 0.0f}, {1.0f, 0.0f}, { 0.0f, -1.0f}, {0.0f, 1.0f} }}, {}); } Trade::MeshData3D Crosshair3D::wireframe() { - return Trade::MeshData3D(Mesh::Primitive::Lines, nullptr, {new std::vector{ + return Trade::MeshData3D(Mesh::Primitive::Lines, {}, {{ {-1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, { 0.0f, -1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, { 0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, 1.0f} diff --git a/src/Primitives/Cube.cpp b/src/Primitives/Cube.cpp index eb369ce23..084a2e9b2 100644 --- a/src/Primitives/Cube.cpp +++ b/src/Primitives/Cube.cpp @@ -30,14 +30,14 @@ namespace Magnum { namespace Primitives { Trade::MeshData3D Cube::solid() { - return Trade::MeshData3D(Mesh::Primitive::Triangles, new std::vector{ + return Trade::MeshData3D(Mesh::Primitive::Triangles, { 0, 1, 2, 0, 2, 3, /* +Z */ 4, 5, 6, 4, 6, 7, /* +X */ 8, 9, 10, 8, 10, 11, /* +Y */ 12, 13, 14, 12, 14, 15, /* -Z */ 16, 17, 18, 16, 18, 19, /* -Y */ 20, 21, 22, 20, 22, 23 /* -X */ - }, {new std::vector{ + }, {{ {-1.0f, -1.0f, 1.0f}, { 1.0f, -1.0f, 1.0f}, { 1.0f, 1.0f, 1.0f}, /* +Z */ @@ -67,7 +67,7 @@ Trade::MeshData3D Cube::solid() { {-1.0f, -1.0f, 1.0f}, {-1.0f, 1.0f, 1.0f}, /* -X */ {-1.0f, 1.0f, -1.0f} - }}, {new std::vector{ + }}, {{ { 0.0f, 0.0f, 1.0f}, { 0.0f, 0.0f, 1.0f}, { 0.0f, 0.0f, 1.0f}, /* +Z */ @@ -101,12 +101,12 @@ Trade::MeshData3D Cube::solid() { } Trade::MeshData3D Cube::wireframe() { - return Trade::MeshData3D(Mesh::Primitive::Lines, new std::vector{ + return Trade::MeshData3D(Mesh::Primitive::Lines, { 0, 1, 1, 2, 2, 3, 3, 0, /* +Z */ 4, 5, 5, 6, 6, 7, 7, 4, /* -Z */ 1, 5, 2, 6, /* +X */ 0, 4, 3, 7 /* -X */ - }, {new std::vector{ + }, {{ {-1.0f, -1.0f, 1.0f}, { 1.0f, -1.0f, 1.0f}, { 1.0f, 1.0f, 1.0f}, diff --git a/src/Primitives/Cylinder.cpp b/src/Primitives/Cylinder.cpp index 13c043b3a..a750715ae 100644 --- a/src/Primitives/Cylinder.cpp +++ b/src/Primitives/Cylinder.cpp @@ -26,11 +26,12 @@ #include "Math/Vector3.h" #include "Primitives/Implementation/Spheroid.h" +#include "Trade/MeshData3D.h" namespace Magnum { namespace Primitives { Trade::MeshData3D Cylinder::solid(UnsignedInt rings, UnsignedInt segments, Float length, Cylinder::Flags flags) { - CORRADE_ASSERT(rings >= 1 && segments >= 3, "Primitives::Cylinder::solid(): cylinder must have at least one ring and three segments", Trade::MeshData3D(Mesh::Primitive::Triangles, nullptr, {}, {}, {})); + CORRADE_ASSERT(rings >= 1 && segments >= 3, "Primitives::Cylinder::solid(): cylinder must have at least one ring and three segments", Trade::MeshData3D(Mesh::Primitive::Triangles, {}, {}, {}, {})); Implementation::Spheroid cylinder(segments, flags & Flag::GenerateTextureCoords ? Implementation::Spheroid::TextureCoords::Generate : Implementation::Spheroid::TextureCoords::DontGenerate); @@ -57,7 +58,7 @@ Trade::MeshData3D Cylinder::solid(UnsignedInt rings, UnsignedInt segments, Float cylinder.faceRings(rings, flags & Flag::CapEnds ? 1 : 0); if(flags & Flag::CapEnds) cylinder.topFaceRing(); - return std::move(cylinder); + return cylinder.finalize(); } }} diff --git a/src/Primitives/Icosphere.cpp b/src/Primitives/Icosphere.cpp index b5ddc86ea..56a10f776 100644 --- a/src/Primitives/Icosphere.cpp +++ b/src/Primitives/Icosphere.cpp @@ -28,7 +28,7 @@ namespace Magnum { namespace Primitives { -Icosphere<0>::Icosphere(): MeshData3D(Mesh::Primitive::Triangles, new std::vector{ +Icosphere<0>::Icosphere(): MeshData3D(Mesh::Primitive::Triangles, { 1, 2, 6, 1, 7, 2, 3, 4, 5, @@ -49,7 +49,7 @@ Icosphere<0>::Icosphere(): MeshData3D(Mesh::Primitive::Triangles, new std::vecto 7, 1, 0, 3, 9, 8, 4, 8, 0 -}, {new std::vector}, {new std::vector{ +}, {}, {{ {0.0f, -0.525731f, 0.850651f}, {0.850651f, 0.0f, 0.525731f}, {0.850651f, 0.0f, -0.525731f}, @@ -63,7 +63,7 @@ Icosphere<0>::Icosphere(): MeshData3D(Mesh::Primitive::Triangles, new std::vecto {0.0f, 0.525731f, -0.850651f}, {0.0f, 0.525731f, 0.850651f} }}, {}) { - positions(0)->assign(normals(0)->begin(), normals(0)->end()); + positions(0).assign(normals(0).begin(), normals(0).end()); } }} diff --git a/src/Primitives/Implementation/Spheroid.cpp b/src/Primitives/Implementation/Spheroid.cpp index 288279160..506221c73 100644 --- a/src/Primitives/Implementation/Spheroid.cpp +++ b/src/Primitives/Implementation/Spheroid.cpp @@ -26,17 +26,18 @@ #include "Math/Functions.h" #include "Math/Vector3.h" +#include "Trade/MeshData3D.h" namespace Magnum { namespace Primitives { namespace Implementation { -Spheroid::Spheroid(UnsignedInt segments, TextureCoords textureCoords): MeshData3D(Mesh::Primitive::Triangles, new std::vector, {new std::vector()}, {new std::vector()}, textureCoords == TextureCoords::Generate ? std::vector*>{new std::vector()} : std::vector*>()), segments(segments), textureCoords(textureCoords) {} +Spheroid::Spheroid(UnsignedInt segments, TextureCoords textureCoords): segments(segments), textureCoords(textureCoords) {} void Spheroid::capVertex(Float y, Float normalY, Float textureCoordsV) { - positions(0)->push_back({0.0f, y, 0.0f}); - normals(0)->push_back({0.0f, normalY, 0.0f}); + positions.push_back({0.0f, y, 0.0f}); + normals.push_back({0.0f, normalY, 0.0f}); if(textureCoords == TextureCoords::Generate) - textureCoords2D(0)->push_back({0.5, textureCoordsV}); + textureCoords2D.push_back({0.5, textureCoordsV}); } void Spheroid::hemisphereVertexRings(UnsignedInt count, Float centerY, Rad startRingAngle, Rad ringAngleIncrement, Float startTextureCoordsV, Float textureCoordsVIncrement) { @@ -49,18 +50,18 @@ void Spheroid::hemisphereVertexRings(UnsignedInt count, Float centerY, Rad start for(UnsignedInt j = 0; j != segments; ++j) { Rad segmentAngle = j*segmentAngleIncrement; - positions(0)->push_back({x*Math::sin(segmentAngle), centerY+y, z*Math::cos(segmentAngle)}); - normals(0)->push_back({x*Math::sin(segmentAngle), y, z*Math::cos(segmentAngle)}); + positions.push_back({x*Math::sin(segmentAngle), centerY+y, z*Math::cos(segmentAngle)}); + normals.push_back({x*Math::sin(segmentAngle), y, z*Math::cos(segmentAngle)}); if(textureCoords == TextureCoords::Generate) - textureCoords2D(0)->push_back({j*1.0f/segments, startTextureCoordsV + i*textureCoordsVIncrement}); + textureCoords2D.push_back({j*1.0f/segments, startTextureCoordsV + i*textureCoordsVIncrement}); } /* Duplicate first segment in the ring for additional vertex for texture coordinate */ if(textureCoords == TextureCoords::Generate) { - positions(0)->push_back((*positions(0))[positions(0)->size()-segments]); - normals(0)->push_back((*normals(0))[normals(0)->size()-segments]); - textureCoords2D(0)->push_back({1.0f, startTextureCoordsV + i*textureCoordsVIncrement}); + positions.push_back(positions[positions.size()-segments]); + normals.push_back(normals[normals.size()-segments]); + textureCoords2D.push_back({1.0f, startTextureCoordsV + i*textureCoordsVIncrement}); } } } @@ -70,18 +71,18 @@ void Spheroid::cylinderVertexRings(UnsignedInt count, Float startY, Float yIncre for(UnsignedInt i = 0; i != count; ++i) { for(UnsignedInt j = 0; j != segments; ++j) { Rad segmentAngle = j*segmentAngleIncrement; - positions(0)->push_back({Math::sin(segmentAngle), startY, Math::cos(segmentAngle)}); - normals(0)->push_back({Math::sin(segmentAngle), 0.0f, Math::cos(segmentAngle)}); + positions.push_back({Math::sin(segmentAngle), startY, Math::cos(segmentAngle)}); + normals.push_back({Math::sin(segmentAngle), 0.0f, Math::cos(segmentAngle)}); if(textureCoords == TextureCoords::Generate) - textureCoords2D(0)->push_back({j*1.0f/segments, startTextureCoordsV + i*textureCoordsVIncrement}); + textureCoords2D.push_back({j*1.0f/segments, startTextureCoordsV + i*textureCoordsVIncrement}); } /* Duplicate first segment in the ring for additional vertex for texture coordinate */ if(textureCoords == TextureCoords::Generate) { - positions(0)->push_back((*positions(0))[positions(0)->size()-segments]); - normals(0)->push_back((*normals(0))[normals(0)->size()-segments]); - textureCoords2D(0)->push_back({1.0f, startTextureCoordsV + i*textureCoordsVIncrement}); + positions.push_back(positions[positions.size()-segments]); + normals.push_back(normals[normals.size()-segments]); + textureCoords2D.push_back({1.0f, startTextureCoordsV + i*textureCoordsVIncrement}); } startY += yIncrement; @@ -91,14 +92,14 @@ void Spheroid::cylinderVertexRings(UnsignedInt count, Float startY, Float yIncre void Spheroid::bottomFaceRing() { for(UnsignedInt j = 0; j != segments; ++j) { /* Bottom vertex */ - indices()->push_back(0); + indices.push_back(0); /* Top right vertex */ - indices()->push_back((j != segments-1 || textureCoords == TextureCoords::Generate) ? + indices.push_back((j != segments-1 || textureCoords == TextureCoords::Generate) ? j+2 : 1); /* Top left vertex */ - indices()->push_back(j+1); + indices.push_back(j+1); } } @@ -113,12 +114,12 @@ void Spheroid::faceRings(UnsignedInt count, UnsignedInt offset) { UnsignedInt topLeft = bottomLeft+vertexSegments; UnsignedInt topRight = bottomRight+vertexSegments; - indices()->push_back(bottomLeft); - indices()->push_back(bottomRight); - indices()->push_back(topRight); - indices()->push_back(bottomLeft); - indices()->push_back(topRight); - indices()->push_back(topLeft); + indices.push_back(bottomLeft); + indices.push_back(bottomRight); + indices.push_back(topRight); + indices.push_back(bottomLeft); + indices.push_back(topRight); + indices.push_back(topLeft); } } } @@ -128,14 +129,14 @@ void Spheroid::topFaceRing() { for(UnsignedInt j = 0; j != segments; ++j) { /* Bottom left vertex */ - indices()->push_back(normals(0)->size()-vertexSegments+j-1); + indices.push_back(normals.size()-vertexSegments+j-1); /* Bottom right vertex */ - indices()->push_back((j != segments-1 || textureCoords == TextureCoords::Generate) ? - normals(0)->size()-vertexSegments+j : normals(0)->size()-segments-1); + indices.push_back((j != segments-1 || textureCoords == TextureCoords::Generate) ? + normals.size()-vertexSegments+j : normals.size()-segments-1); /* Top vertex */ - indices()->push_back(normals(0)->size()-1); + indices.push_back(normals.size()-1); } } @@ -144,19 +145,24 @@ void Spheroid::capVertexRing(Float y, Float textureCoordsV, const Vector3& norma for(UnsignedInt i = 0; i != segments; ++i) { Rad segmentAngle = i*segmentAngleIncrement; - positions(0)->push_back({Math::sin(segmentAngle), y, Math::cos(segmentAngle)}); - normals(0)->push_back(normal); + positions.push_back({Math::sin(segmentAngle), y, Math::cos(segmentAngle)}); + normals.push_back(normal); if(textureCoords == TextureCoords::Generate) - textureCoords2D(0)->push_back({i*1.0f/segments, textureCoordsV}); + textureCoords2D.push_back({i*1.0f/segments, textureCoordsV}); } /* Duplicate first segment in the ring for additional vertex for texture coordinate */ if(textureCoords == TextureCoords::Generate) { - positions(0)->push_back((*positions(0))[positions(0)->size()-segments]); - normals(0)->push_back(normal); - textureCoords2D(0)->push_back({1.0f, textureCoordsV}); + positions.push_back(positions[positions.size()-segments]); + normals.push_back(normal); + textureCoords2D.push_back({1.0f, textureCoordsV}); } } +Trade::MeshData3D Spheroid::finalize() { + return Trade::MeshData3D(Mesh::Primitive::Triangles, std::move(indices), {std::move(positions)}, {std::move(normals)}, + textureCoords == TextureCoords::Generate ? std::vector>{std::move(textureCoords2D)} : std::vector>()); +} + }}} diff --git a/src/Primitives/Implementation/Spheroid.h b/src/Primitives/Implementation/Spheroid.h index 9a3f89203..b493ee42e 100644 --- a/src/Primitives/Implementation/Spheroid.h +++ b/src/Primitives/Implementation/Spheroid.h @@ -24,11 +24,14 @@ DEALINGS IN THE SOFTWARE. */ -#include "Trade/MeshData3D.h" +#include + +#include "Magnum.h" +#include "Trade/Trade.h" namespace Magnum { namespace Primitives { namespace Implementation { -class Spheroid: public Trade::MeshData3D { +class Spheroid { public: enum class TextureCoords: UnsignedByte { DontGenerate, @@ -45,8 +48,16 @@ class Spheroid: public Trade::MeshData3D { void topFaceRing(); void capVertexRing(Float y, Float textureCoordsV, const Vector3& normal); + Trade::MeshData3D finalize(); + UnsignedInt segments; TextureCoords textureCoords; + + private: + std::vector indices; + std::vector positions; + std::vector normals; + std::vector textureCoords2D; }; }}} diff --git a/src/Primitives/Line.cpp b/src/Primitives/Line.cpp index 53926a9f6..fc0da8207 100644 --- a/src/Primitives/Line.cpp +++ b/src/Primitives/Line.cpp @@ -31,13 +31,13 @@ namespace Magnum { namespace Primitives { Trade::MeshData2D Line2D::wireframe() { - return Trade::MeshData2D(Mesh::Primitive::Lines, nullptr, {new std::vector{ + return Trade::MeshData2D(Mesh::Primitive::Lines, {}, {{ {0.0f, 0.0f}, {1.0f, 0.0f} }}, {}); } Trade::MeshData3D Line3D::wireframe() { - return Trade::MeshData3D(Mesh::Primitive::Lines, nullptr, {new std::vector{ + return Trade::MeshData3D(Mesh::Primitive::Lines, {}, {{ {0.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, }}, {}, {}); } diff --git a/src/Primitives/Plane.cpp b/src/Primitives/Plane.cpp index 3ff7488a5..d3fe3787e 100644 --- a/src/Primitives/Plane.cpp +++ b/src/Primitives/Plane.cpp @@ -30,12 +30,12 @@ namespace Magnum { namespace Primitives { Trade::MeshData3D Plane::solid() { - return Trade::MeshData3D(Mesh::Primitive::TriangleStrip, nullptr, {new std::vector{ + return Trade::MeshData3D(Mesh::Primitive::TriangleStrip, {}, {{ {1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}, {-1.0f, -1.0f, 0.0f}, {-1.0f, 1.0f, 0.0f} - }}, {new std::vector{ + }}, {{ {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 1.0f}, @@ -44,7 +44,7 @@ Trade::MeshData3D Plane::solid() { } Trade::MeshData3D Plane::wireframe() { - return Trade::MeshData3D(Mesh::Primitive::LineLoop, nullptr, {new std::vector{ + return Trade::MeshData3D(Mesh::Primitive::LineLoop, {}, {{ {-1.0f, -1.0f, 0.0f}, {1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}, diff --git a/src/Primitives/Square.cpp b/src/Primitives/Square.cpp index f17646966..e5bfda106 100644 --- a/src/Primitives/Square.cpp +++ b/src/Primitives/Square.cpp @@ -30,7 +30,7 @@ namespace Magnum { namespace Primitives { Trade::MeshData2D Square::solid() { - return Trade::MeshData2D(Mesh::Primitive::TriangleStrip, nullptr, {new std::vector{ + return Trade::MeshData2D(Mesh::Primitive::TriangleStrip, {}, {{ {1.0f, -1.0f}, {1.0f, 1.0f}, {-1.0f, -1.0f}, @@ -39,7 +39,7 @@ Trade::MeshData2D Square::solid() { } Trade::MeshData2D Square::wireframe() { - return Trade::MeshData2D(Mesh::Primitive::LineLoop, nullptr, {new std::vector{ + return Trade::MeshData2D(Mesh::Primitive::LineLoop, {}, {{ {-1.0f, -1.0f}, {1.0f, -1.0f}, {1.0f, 1.0f}, diff --git a/src/Primitives/Test/CapsuleTest.cpp b/src/Primitives/Test/CapsuleTest.cpp index 33b3da9f2..4e41eae02 100644 --- a/src/Primitives/Test/CapsuleTest.cpp +++ b/src/Primitives/Test/CapsuleTest.cpp @@ -50,7 +50,7 @@ CapsuleTest::CapsuleTest() { void CapsuleTest::withoutTextureCoords() { Trade::MeshData3D capsule = Capsule::solid(2, 2, 3, 1.0f); - CORRADE_COMPARE_AS(*capsule.positions(0), (std::vector{ + CORRADE_COMPARE_AS(capsule.positions(0), (std::vector{ {0.0f, -1.5f, 0.0f}, {0.0f, -1.20711f, 0.707107f}, @@ -76,7 +76,7 @@ void CapsuleTest::withoutTextureCoords() { {0.0f, 1.5f, 0.0f} }), TestSuite::Compare::Container); - CORRADE_COMPARE_AS(*capsule.normals(0), (std::vector{ + CORRADE_COMPARE_AS(capsule.normals(0), (std::vector{ {0.0f, -1.0f, 0.0f}, {0.0f, -0.707107f, 0.707107f}, @@ -102,7 +102,7 @@ void CapsuleTest::withoutTextureCoords() { {0.0f, 1.0f, 0.0f} }), TestSuite::Compare::Container); - CORRADE_COMPARE_AS(*capsule.indices(), (std::vector{ + CORRADE_COMPARE_AS(capsule.indices(), (std::vector{ 0, 2, 1, 0, 3, 2, 0, 1, 3, 1, 2, 5, 1, 5, 4, 2, 3, 6, 2, 6, 5, 3, 1, 4, 3, 4, 6, 4, 5, 8, 4, 8, 7, 5, 6, 9, 5, 9, 8, 6, 4, 7, 6, 7, 9, @@ -115,7 +115,7 @@ void CapsuleTest::withoutTextureCoords() { void CapsuleTest::withTextureCoords() { Trade::MeshData3D capsule = Capsule::solid(2, 2, 3, 1.0f, Capsule::TextureCoords::Generate); - CORRADE_COMPARE_AS(*capsule.positions(0), (std::vector{ + CORRADE_COMPARE_AS(capsule.positions(0), (std::vector{ {0.0f, -1.5f, 0.0f}, {0.0f, -1.20711f, 0.707107f}, @@ -146,7 +146,7 @@ void CapsuleTest::withTextureCoords() { {0.0f, 1.5f, 0.0f} }), TestSuite::Compare::Container); - CORRADE_COMPARE_AS(*capsule.textureCoords2D(0), (std::vector{ + CORRADE_COMPARE_AS(capsule.textureCoords2D(0), (std::vector{ {0.5f, 0.0f}, {0.0f, 0.166667f}, @@ -177,7 +177,7 @@ void CapsuleTest::withTextureCoords() { {0.5f, 1.0f} }), TestSuite::Compare::Container); - CORRADE_COMPARE_AS(*capsule.indices(), (std::vector{ + CORRADE_COMPARE_AS(capsule.indices(), (std::vector{ 0, 2, 1, 0, 3, 2, 0, 4, 3, 1, 2, 6, 1, 6, 5, 2, 3, 7, 2, 7, 6, 3, 4, 8, 3, 8, 7, 5, 6, 10, 5, 10, 9, 6, 7, 11, 6, 11, 10, 7, 8, 12, 7, 12, 11, diff --git a/src/Primitives/Test/CircleTest.cpp b/src/Primitives/Test/CircleTest.cpp index 58c763af2..4395086f3 100644 --- a/src/Primitives/Test/CircleTest.cpp +++ b/src/Primitives/Test/CircleTest.cpp @@ -46,7 +46,7 @@ CircleTest::CircleTest() { void CircleTest::solid() { Trade::MeshData2D circle = Primitives::Circle::solid(8); - CORRADE_COMPARE(*circle.positions(0), (std::vector{ + CORRADE_COMPARE(circle.positions(0), (std::vector{ { 0.0f, 0.0f}, { 1.0f, 0.0f}, { Constants::sqrt2()/2.0f, Constants::sqrt2()/2.0f}, { 0.0f, 1.0f}, {-Constants::sqrt2()/2.0f, Constants::sqrt2()/2.0f}, @@ -58,7 +58,7 @@ void CircleTest::solid() { void CircleTest::wireframe() { Trade::MeshData2D circle = Primitives::Circle::wireframe(8); - CORRADE_COMPARE(*circle.positions(0), (std::vector{ + CORRADE_COMPARE(circle.positions(0), (std::vector{ { 1.0f, 0.0f}, { Constants::sqrt2()/2.0f, Constants::sqrt2()/2.0f}, { 0.0f, 1.0f}, {-Constants::sqrt2()/2.0f, Constants::sqrt2()/2.0f}, {-1.0f, 0.0f}, {-Constants::sqrt2()/2.0f, -Constants::sqrt2()/2.0f}, diff --git a/src/Primitives/Test/CylinderTest.cpp b/src/Primitives/Test/CylinderTest.cpp index f999cde89..33e8a7d43 100644 --- a/src/Primitives/Test/CylinderTest.cpp +++ b/src/Primitives/Test/CylinderTest.cpp @@ -47,7 +47,7 @@ CylinderTest::CylinderTest() { void CylinderTest::withoutAnything() { Trade::MeshData3D cylinder = Cylinder::solid(2, 3, 3.0f); - CORRADE_COMPARE_AS(*cylinder.positions(0), (std::vector{ + CORRADE_COMPARE_AS(cylinder.positions(0), (std::vector{ {0.0f, -1.5f, 1.0f}, {0.866025f, -1.5f, -0.5f}, {-0.866025f, -1.5f, -0.5f}, @@ -61,7 +61,7 @@ void CylinderTest::withoutAnything() { {-0.866025f, 1.5f, -0.5f} }), TestSuite::Compare::Container); - CORRADE_COMPARE_AS(*cylinder.normals(0), (std::vector{ + CORRADE_COMPARE_AS(cylinder.normals(0), (std::vector{ {0.0f, 0.0f, 1.0f}, {0.866025f, 0.0f, -0.5f}, {-0.866025f, 0.0f, -0.5f}, @@ -75,7 +75,7 @@ void CylinderTest::withoutAnything() { {-0.866025f, 0.0f, -0.5f} }), TestSuite::Compare::Container); - CORRADE_COMPARE_AS(*cylinder.indices(), (std::vector{ + CORRADE_COMPARE_AS(cylinder.indices(), (std::vector{ 0, 1, 4, 0, 4, 3, 1, 2, 5, 1, 5, 4, 2, 0, 3, 2, 3, 5, 3, 4, 7, 3, 7, 6, 4, 5, 8, 4, 8, 7, 5, 3, 6, 5, 6, 8 }), TestSuite::Compare::Container); @@ -84,7 +84,7 @@ void CylinderTest::withoutAnything() { void CylinderTest::withTextureCoordsAndCaps() { Trade::MeshData3D cylinder = Cylinder::solid(2, 3, 3.0f, Cylinder::Flag::GenerateTextureCoords|Cylinder::Flag::CapEnds); - CORRADE_COMPARE_AS(*cylinder.positions(0), (std::vector{ + CORRADE_COMPARE_AS(cylinder.positions(0), (std::vector{ {0.0f, -1.5f, 0.0f}, {0.0f, -1.5f, 1.0f}, @@ -115,7 +115,7 @@ void CylinderTest::withTextureCoordsAndCaps() { {0.0f, 1.5f, 0.0f} }), TestSuite::Compare::Container); - CORRADE_COMPARE_AS(*cylinder.normals(0), (std::vector{ + CORRADE_COMPARE_AS(cylinder.normals(0), (std::vector{ {0.0f, -1.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, @@ -146,7 +146,7 @@ void CylinderTest::withTextureCoordsAndCaps() { {0.0f, 1.0f, 0.0f}, }), TestSuite::Compare::Container); - CORRADE_COMPARE_AS(*cylinder.textureCoords2D(0), (std::vector{ + CORRADE_COMPARE_AS(cylinder.textureCoords2D(0), (std::vector{ {0.5f, 0.0f}, {0.0f, 0.2f}, @@ -177,7 +177,7 @@ void CylinderTest::withTextureCoordsAndCaps() { {0.5f, 1.0f} }), TestSuite::Compare::Container); - CORRADE_COMPARE_AS(*cylinder.indices(), (std::vector{ + CORRADE_COMPARE_AS(cylinder.indices(), (std::vector{ 0, 2, 1, 0, 3, 2, 0, 4, 3, 1, 2, 6, 1, 6, 5, 2, 3, 7, 2, 7, 6, 3, 4, 8, 3, 8, 7, 5, 6, 10, 5, 10, 9, 6, 7, 11, 6, 11, 10, 7, 8, 12, 7, diff --git a/src/Primitives/Test/UVSphereTest.cpp b/src/Primitives/Test/UVSphereTest.cpp index 9403d79ff..46f25bbf0 100644 --- a/src/Primitives/Test/UVSphereTest.cpp +++ b/src/Primitives/Test/UVSphereTest.cpp @@ -47,7 +47,7 @@ UVSphereTest::UVSphereTest() { void UVSphereTest::withoutTextureCoords() { Trade::MeshData3D sphere = UVSphere::solid(3, 3); - CORRADE_COMPARE_AS(*sphere.positions(0), (std::vector{ + CORRADE_COMPARE_AS(sphere.positions(0), (std::vector{ {0.0f, -1.0f, 0.0f}, {0.0f, -0.5f, 0.866025f}, @@ -61,7 +61,7 @@ void UVSphereTest::withoutTextureCoords() { {0.0f, 1.0f, 0.0f} }), TestSuite::Compare::Container); - CORRADE_COMPARE_AS(*sphere.normals(0), (std::vector{ + CORRADE_COMPARE_AS(sphere.normals(0), (std::vector{ {0.0f, -1.0f, 0.0f}, {0.0f, -0.5f, 0.866025f}, @@ -75,7 +75,7 @@ void UVSphereTest::withoutTextureCoords() { {0.0f, 1.0f, 0.0f} }), TestSuite::Compare::Container); - CORRADE_COMPARE_AS(*sphere.indices(), (std::vector{ + CORRADE_COMPARE_AS(sphere.indices(), (std::vector{ 0, 2, 1, 0, 3, 2, 0, 1, 3, 1, 2, 5, 1, 5, 4, 2, 3, 6, 2, 6, 5, 3, 1, 4, 3, 4, 6, 4, 5, 7, 5, 6, 7, 6, 4, 7 @@ -85,7 +85,7 @@ void UVSphereTest::withoutTextureCoords() { void UVSphereTest::withTextureCoords() { Trade::MeshData3D sphere = UVSphere::solid(3, 3, UVSphere::TextureCoords::Generate); - CORRADE_COMPARE_AS(*sphere.positions(0), (std::vector{ + CORRADE_COMPARE_AS(sphere.positions(0), (std::vector{ {0.0f, -1.0f, 0.0f}, {0.0f, -0.5f, 0.866025f}, @@ -101,7 +101,7 @@ void UVSphereTest::withTextureCoords() { {0.0f, 1.0f, 0.0f} }), TestSuite::Compare::Container); - CORRADE_COMPARE_AS(*sphere.textureCoords2D(0), (std::vector{ + CORRADE_COMPARE_AS(sphere.textureCoords2D(0), (std::vector{ {0.5f, 0.0f}, {0.0f, 0.333333f}, @@ -117,7 +117,7 @@ void UVSphereTest::withTextureCoords() { {0.5f, 1.0f} }), TestSuite::Compare::Container); - CORRADE_COMPARE_AS(*sphere.indices(), (std::vector{ + CORRADE_COMPARE_AS(sphere.indices(), (std::vector{ 0, 2, 1, 0, 3, 2, 0, 4, 3, 1, 2, 6, 1, 6, 5, 2, 3, 7, 2, 7, 6, 3, 4, 8, 3, 8, 7, 5, 6, 9, 6, 7, 9, 7, 8, 9 diff --git a/src/Primitives/UVSphere.cpp b/src/Primitives/UVSphere.cpp index 5ec1d72c5..b4003300f 100644 --- a/src/Primitives/UVSphere.cpp +++ b/src/Primitives/UVSphere.cpp @@ -24,13 +24,14 @@ #include "UVSphere.h" -#include "Math/Angle.h" -#include "Implementation/Spheroid.h" +#include "Math/Vector3.h" +#include "Primitives/Implementation/Spheroid.h" +#include "Trade/MeshData3D.h" namespace Magnum { namespace Primitives { Trade::MeshData3D UVSphere::solid(UnsignedInt rings, UnsignedInt segments, TextureCoords textureCoords) { - CORRADE_ASSERT(rings >= 2 && segments >= 3, "UVSphere must have at least two rings and three segments", Trade::MeshData3D(Mesh::Primitive::Triangles, nullptr, {}, {}, {})); + CORRADE_ASSERT(rings >= 2 && segments >= 3, "UVSphere must have at least two rings and three segments", Trade::MeshData3D(Mesh::Primitive::Triangles, {}, {}, {}, {})); Implementation::Spheroid sphere(segments, textureCoords == TextureCoords::Generate ? Implementation::Spheroid::TextureCoords::Generate : @@ -53,7 +54,7 @@ Trade::MeshData3D UVSphere::solid(UnsignedInt rings, UnsignedInt segments, Textu sphere.faceRings(rings-2); sphere.topFaceRing(); - return std::move(sphere); + return sphere.finalize(); } }} diff --git a/src/Trade/MeshData2D.cpp b/src/Trade/MeshData2D.cpp index 44ea06609..4e06a1b00 100644 --- a/src/Trade/MeshData2D.cpp +++ b/src/Trade/MeshData2D.cpp @@ -28,24 +28,44 @@ namespace Magnum { namespace Trade { -MeshData2D::MeshData2D(Mesh::Primitive primitive, std::vector* indices, std::vector*> positions, std::vector*> textureCoords2D): _primitive(primitive), _indices(indices), _positions(std::move(positions)), _textureCoords2D(std::move(textureCoords2D)) {} +MeshData2D::MeshData2D(Mesh::Primitive primitive, std::vector indices, std::vector> positions, std::vector> textureCoords2D): _primitive(primitive), _indices(std::move(indices)), _positions(std::move(positions)), _textureCoords2D(std::move(textureCoords2D)) { + CORRADE_ASSERT(!_positions.empty(), "Trade::MeshData2D: no position array specified", ); +} + +MeshData2D::MeshData2D(MeshData2D&&) = default; + +MeshData2D::~MeshData2D() = default; + +MeshData2D& MeshData2D::operator=(MeshData2D&&) = default; + +std::vector& MeshData2D::indices() { + CORRADE_ASSERT(isIndexed(), "Trade::MeshData2D::indices(): the mesh is not indexed", _indices); + return _indices; +} + +const std::vector& MeshData2D::indices() const { + CORRADE_ASSERT(isIndexed(), "Trade::MeshData2D::indices(): the mesh is not indexed", _indices); + return _indices; +} + +std::vector& MeshData2D::positions(const UnsignedInt id) { + CORRADE_ASSERT(id < positionArrayCount(), "Trade::MeshData2D::positions(): index out of range", _positions[id]); + return _positions[id]; +} -MeshData2D::MeshData2D(MeshData2D&& other): _primitive(other._primitive), _indices(other._indices), _positions(std::move(other._positions)), _textureCoords2D(std::move(other._textureCoords2D)) { - other._indices = nullptr; +const std::vector& MeshData2D::positions(const UnsignedInt id) const { + CORRADE_ASSERT(id < positionArrayCount(), "Trade::MeshData2D::positions(): index out of range", _positions[id]); + return _positions[id]; } -MeshData2D& MeshData2D::operator=(MeshData2D&& other) { - _primitive = other._primitive; - std::swap(_indices, other._indices); - std::swap(_positions, other._positions); - std::swap(_textureCoords2D, other._textureCoords2D); - return *this; +std::vector& MeshData2D::textureCoords2D(const UnsignedInt id) { + CORRADE_ASSERT(id < textureCoords2DArrayCount(), "Trade::MeshData2D::textureCoords2D(): index out of range", _textureCoords2D[id]); + return _textureCoords2D[id]; } -MeshData2D::~MeshData2D() { - delete _indices; - for(auto i: _positions) delete i; - for(auto i: _textureCoords2D) delete i; +const std::vector& MeshData2D::textureCoords2D(const UnsignedInt id) const { + CORRADE_ASSERT(id < textureCoords2DArrayCount(), "Trade::MeshData2D::textureCoords2D(): index out of range", _textureCoords2D[id]); + return _textureCoords2D[id]; } }} diff --git a/src/Trade/MeshData2D.h b/src/Trade/MeshData2D.h index d8a910460..7f50ce820 100644 --- a/src/Trade/MeshData2D.h +++ b/src/Trade/MeshData2D.h @@ -42,70 +42,76 @@ type. @see MeshData3D */ class MAGNUM_EXPORT MeshData2D { - MeshData2D(const MeshData2D&) = delete; - MeshData2D& operator=(const MeshData2D&) = delete; - public: /** * @brief Constructor * @param primitive Primitive - * @param indices Array with indices or 0, if this is not - * indexed mesh - * @param positions Array with vertex positions. At least one - * position array should be present. - * @param textureCoords2D Array with two-dimensional texture - * coordinate arrays or empty array + * @param indices Index array or empty array, if the mesh is + * not indexed + * @param positions Position arrays. At least one position + * array should be present. + * @param textureCoords2D Two-dimensional texture coordinate arrays, + * if present */ - explicit MeshData2D(Mesh::Primitive primitive, std::vector* indices, std::vector*> positions, std::vector*> textureCoords2D); + explicit MeshData2D(Mesh::Primitive primitive, std::vector indices, std::vector> positions, std::vector> textureCoords2D); + + /** @brief Copying is not allowed */ + MeshData2D(const MeshData2D&) = delete; /** @brief Move constructor */ - MeshData2D(MeshData2D&&); + MeshData2D(MeshData2D&& other); - /** @brief Destructor */ ~MeshData2D(); + /** @brief Copying is not allowed */ + MeshData2D& operator=(const MeshData2D&) = delete; + /** @brief Move assignment */ - MeshData2D& operator=(MeshData2D&&); + MeshData2D& operator=(MeshData2D&& other); /** @brief Primitive */ Mesh::Primitive primitive() const { return _primitive; } + /** @brief Whether the mesh is indexed */ + bool isIndexed() const { return !_indices.empty(); } + /** * @brief Indices - * @return Indices or nullptr if the mesh is not indexed. + * + * @see isIndexed() */ - std::vector* indices() { return _indices; } - const std::vector* indices() const { return _indices; } /**< @overload */ + std::vector& indices(); + const std::vector& indices() const; /**< @overload */ - /** @brief Count of vertex position arrays */ + /** @brief Count of position arrays */ UnsignedInt positionArrayCount() const { return _positions.size(); } /** * @brief Positions - * @param id ID of position data array - * @return Positions or nullptr if there is no vertex array with given - * ID. + * @param id Position array ID + * + * @see positionArrayCount() */ - std::vector* positions(UnsignedInt id) { return _positions[id]; } - const std::vector* positions(UnsignedInt id) const { return _positions[id]; } /**< @overload */ + std::vector& positions(UnsignedInt id); + const std::vector& positions(UnsignedInt id) const; /**< @overload */ /** @brief Count of 2D texture coordinate arrays */ UnsignedInt textureCoords2DArrayCount() const { return _textureCoords2D.size(); } /** * @brief 2D texture coordinates - * @param id ID of texture coordinates array - * @return %Texture coordinates or nullptr if there is no texture - * coordinates array with given ID. + * @param id Texture coordinate array ID + * + * @see textureCoords2DArrayCount() */ - std::vector* textureCoords2D(UnsignedInt id) { return _textureCoords2D[id]; } - const std::vector* textureCoords2D(UnsignedInt id) const { return _textureCoords2D[id]; } /**< @overload */ + std::vector& textureCoords2D(UnsignedInt id); + const std::vector& textureCoords2D(UnsignedInt id) const; /**< @overload */ private: Mesh::Primitive _primitive; - std::vector* _indices; - std::vector*> _positions; - std::vector*> _textureCoords2D; + std::vector _indices; + std::vector> _positions; + std::vector> _textureCoords2D; }; }} diff --git a/src/Trade/MeshData3D.cpp b/src/Trade/MeshData3D.cpp index 5ad47c640..a483521ec 100644 --- a/src/Trade/MeshData3D.cpp +++ b/src/Trade/MeshData3D.cpp @@ -28,26 +28,54 @@ namespace Magnum { namespace Trade { -MeshData3D::MeshData3D(Mesh::Primitive primitive, std::vector* indices, std::vector*> positions, std::vector*> normals, std::vector*> textureCoords2D): _primitive(primitive), _indices(indices), _positions(std::move(positions)), _normals(std::move(normals)), _textureCoords2D(std::move(textureCoords2D)) {} +MeshData3D::MeshData3D(Mesh::Primitive primitive, std::vector indices, std::vector> positions, std::vector> normals, std::vector> textureCoords2D): _primitive(primitive), _indices(std::move(indices)), _positions(std::move(positions)), _normals(std::move(normals)), _textureCoords2D(std::move(textureCoords2D)) { + CORRADE_ASSERT(!_positions.empty(), "Trade::MeshData3D: no position array specified", ); +} + +MeshData3D::MeshData3D(MeshData3D&&) = default; + +MeshData3D::~MeshData3D() = default; + +MeshData3D& MeshData3D::operator=(MeshData3D&&) = default; + +std::vector& MeshData3D::indices() { + CORRADE_ASSERT(isIndexed(), "Trade::MeshData3D::indices(): the mesh is not indexed", _indices); + return _indices; +} + +const std::vector& MeshData3D::indices() const { + CORRADE_ASSERT(isIndexed(), "Trade::MeshData3D::indices(): the mesh is not indexed", _indices); + return _indices; +} + +std::vector& MeshData3D::positions(const UnsignedInt id) { + CORRADE_ASSERT(id < positionArrayCount(), "Trade::MeshData3D::positions(): index out of range", _positions[id]); + return _positions[id]; +} + +const std::vector& MeshData3D::positions(const UnsignedInt id) const { + CORRADE_ASSERT(id < positionArrayCount(), "Trade::MeshData3D::positions(): index out of range", _positions[id]); + return _positions[id]; +} + +std::vector& MeshData3D::normals(const UnsignedInt id) { + CORRADE_ASSERT(id < normalArrayCount(), "Trade::MeshData3D::normals(): index out of range", _normals[id]); + return _normals[id]; +} -MeshData3D::MeshData3D(MeshData3D&& other): _primitive(other._primitive), _indices(other._indices), _positions(std::move(other._positions)), _normals(std::move(other._normals)), _textureCoords2D(std::move(other._textureCoords2D)) { - other._indices = nullptr; +const std::vector& MeshData3D::normals(const UnsignedInt id) const { + CORRADE_ASSERT(id < normalArrayCount(), "Trade::MeshData3D::normals(): index out of range", _normals[id]); + return _normals[id]; } -MeshData3D& MeshData3D::operator=(MeshData3D&& other) { - _primitive = other._primitive; - std::swap(_indices, other._indices); - std::swap(_positions, other._positions); - std::swap(_normals, other._normals); - std::swap(_textureCoords2D, other._textureCoords2D); - return *this; +std::vector& MeshData3D::textureCoords2D(const UnsignedInt id) { + CORRADE_ASSERT(id < textureCoords2DArrayCount(), "Trade::MeshData3D::textureCoords2D(): index out of range", _textureCoords2D[id]); + return _textureCoords2D[id]; } -MeshData3D::~MeshData3D() { - delete _indices; - for(auto i: _positions) delete i; - for(auto i: _normals) delete i; - for(auto i: _textureCoords2D) delete i; +const std::vector& MeshData3D::textureCoords2D(const UnsignedInt id) const { + CORRADE_ASSERT(id < textureCoords2DArrayCount(), "Trade::MeshData3D::textureCoords2D(): index out of range", _textureCoords2D[id]); + return _textureCoords2D[id]; } }} diff --git a/src/Trade/MeshData3D.h b/src/Trade/MeshData3D.h index 64271f2a0..c1cffca6f 100644 --- a/src/Trade/MeshData3D.h +++ b/src/Trade/MeshData3D.h @@ -42,84 +42,90 @@ type. @see MeshData2D */ class MAGNUM_EXPORT MeshData3D { - MeshData3D(const MeshData3D&) = delete; - MeshData3D& operator=(const MeshData3D&) = delete; - public: /** * @brief Constructor * @param primitive Primitive - * @param indices Array with indices or 0, if this is not - * indexed mesh - * @param positions Array with vertex positions. At least one - * position array should be present. - * @param normals Array with normal arrays or empty array - * @param textureCoords2D Array with two-dimensional texture - * coordinate arrays or empty array + * @param indices Index array or empty array, if the mesh is + * not indexed + * @param positions Position arrays. At least one position + * array should be present. + * @param normals Normal arrays, if present + * @param textureCoords2D Two-dimensional texture coordinate arrays, + * if present */ - explicit MeshData3D(Mesh::Primitive primitive, std::vector* indices, std::vector*> positions, std::vector*> normals, std::vector*> textureCoords2D); + explicit MeshData3D(Mesh::Primitive primitive, std::vector indices, std::vector> positions, std::vector> normals, std::vector> textureCoords2D); + + /** @brief Copying is not allowed */ + MeshData3D(const MeshData3D&) = delete; /** @brief Move constructor */ MeshData3D(MeshData3D&&); - /** @brief Destructor */ ~MeshData3D(); + /** @brief Copying is not allowed */ + MeshData3D& operator=(const MeshData3D&) = delete; + /** @brief Move assignment */ MeshData3D& operator=(MeshData3D&&); /** @brief Primitive */ Mesh::Primitive primitive() const { return _primitive; } + /** @brief Whether the mesh is indexed */ + bool isIndexed() const { return !_indices.empty(); } + /** * @brief Indices - * @return Indices or nullptr if the mesh is not indexed. + * + * @see isIndexed() */ - std::vector* indices() { return _indices; } - const std::vector* indices() const { return _indices; } /**< @overload */ + std::vector& indices(); + const std::vector& indices() const; /**< @overload */ - /** @brief Count of vertex position arrays */ + /** @brief Count of position arrays */ UnsignedInt positionArrayCount() const { return _positions.size(); } /** * @brief Positions - * @param id ID of position data array - * @return Positions or nullptr if there is no vertex array with given - * ID. + * @param id Position array ID + * + * @see positionArrayCount() */ - std::vector* positions(UnsignedInt id) { return _positions[id]; } - const std::vector* positions(UnsignedInt id) const { return _positions[id]; } /**< @overload */ + std::vector& positions(UnsignedInt id); + const std::vector& positions(UnsignedInt id) const; /**< @overload */ /** @brief Count of normal arrays */ UnsignedInt normalArrayCount() const { return _normals.size(); } /** * @brief Normals - * @param id ID of normal data array - * @return Normals or nullptr if there is no normal array with given - * ID. + * @param id Normal array ID + * + * @see normalArrayCount() */ - std::vector* normals(UnsignedInt id) { return _normals[id]; } - const std::vector* normals(UnsignedInt id) const { return _normals[id]; } /**< @overload */ + std::vector& normals(UnsignedInt id); + const std::vector& normals(UnsignedInt id) const; /**< @overload */ /** @brief Count of 2D texture coordinate arrays */ UnsignedInt textureCoords2DArrayCount() const { return _textureCoords2D.size(); } /** * @brief 2D texture coordinates - * @param id ID of texture coordinates array - * @return %Texture coordinates or nullptr if there is no texture - * coordinates array with given ID. + * @param id Texture coordinate array ID + * + * @see textureCoords2DArrayCount() */ - std::vector* textureCoords2D(UnsignedInt id) { return _textureCoords2D[id]; } - const std::vector* textureCoords2D(UnsignedInt id) const { return _textureCoords2D[id]; } /**< @overload */ + std::vector& textureCoords2D(UnsignedInt id); + const std::vector& textureCoords2D(UnsignedInt id) const; /**< @overload */ private: Mesh::Primitive _primitive; - std::vector* _indices; - std::vector*> _positions; - std::vector*> _normals; - std::vector*> _textureCoords2D; + std::vector _indices; + std::vector> _positions; + std::vector> _normals; + std::vector> _textureCoords2D; }; }}