Browse Source

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.
pull/278/head
Vladimír Vondruš 13 years ago
parent
commit
aacb6b7041
  1. 16
      src/DebugTools/Implementation/AbstractShapeRenderer.cpp
  2. 7
      src/Primitives/Capsule.cpp
  3. 22
      src/Primitives/Circle.cpp
  4. 4
      src/Primitives/Crosshair.cpp
  5. 10
      src/Primitives/Cube.cpp
  6. 5
      src/Primitives/Cylinder.cpp
  7. 6
      src/Primitives/Icosphere.cpp
  8. 76
      src/Primitives/Implementation/Spheroid.cpp
  9. 15
      src/Primitives/Implementation/Spheroid.h
  10. 4
      src/Primitives/Line.cpp
  11. 6
      src/Primitives/Plane.cpp
  12. 4
      src/Primitives/Square.cpp
  13. 12
      src/Primitives/Test/CapsuleTest.cpp
  14. 4
      src/Primitives/Test/CircleTest.cpp
  15. 14
      src/Primitives/Test/CylinderTest.cpp
  16. 12
      src/Primitives/Test/UVSphereTest.cpp
  17. 9
      src/Primitives/UVSphere.cpp
  18. 46
      src/Trade/MeshData2D.cpp
  19. 66
      src/Trade/MeshData2D.h
  20. 58
      src/Trade/MeshData3D.cpp
  21. 76
      src/Trade/MeshData3D.h

16
src/DebugTools/Implementation/AbstractShapeRenderer.cpp

@ -46,21 +46,21 @@ template<UnsignedInt dimensions> void create(typename MeshData<dimensions>::Type
template<> void create<2>(Trade::MeshData2D& data, Resource<Mesh>& meshResource, Resource<Buffer>& vertexBufferResource, Resource<Buffer>& indexBufferResource) { template<> void create<2>(Trade::MeshData2D& data, Resource<Mesh>& meshResource, Resource<Buffer>& vertexBufferResource, Resource<Buffer>& indexBufferResource) {
/* Vertex buffer */ /* Vertex buffer */
Buffer* buffer = new Buffer(Buffer::Target::Array); 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); ResourceManager::instance()->set(vertexBufferResource.key(), buffer, ResourceDataState::Final, ResourcePolicy::Manual);
/* Mesh configuration */ /* Mesh configuration */
Mesh* mesh = new Mesh; Mesh* mesh = new Mesh;
mesh->setPrimitive(data.primitive()) mesh->setPrimitive(data.primitive())
->setVertexCount(data.positions(0)->size()) ->setVertexCount(data.positions(0).size())
->addVertexBuffer(buffer, 0, Shaders::Flat2D::Position()); ->addVertexBuffer(buffer, 0, Shaders::Flat2D::Position());
ResourceManager::instance()->set(meshResource.key(), mesh, ResourceDataState::Final, ResourcePolicy::Manual); ResourceManager::instance()->set(meshResource.key(), mesh, ResourceDataState::Final, ResourcePolicy::Manual);
/* Index buffer, if needed, if not, resource key doesn't have to be set */ /* 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()); CORRADE_INTERNAL_ASSERT(indexBufferResource.key() != ResourceKey());
Buffer* indexBuffer = new Buffer(Buffer::Target::ElementArray); 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); ResourceManager::instance()->set(indexBufferResource.key(), indexBuffer, ResourceDataState::Final, ResourcePolicy::Manual);
} }
} }
@ -68,21 +68,21 @@ template<> void create<2>(Trade::MeshData2D& data, Resource<Mesh>& meshResource,
template<> void create<3>(Trade::MeshData3D& data, Resource<Mesh>& meshResource, Resource<Buffer>& vertexBufferResource, Resource<Buffer>& indexBufferResource) { template<> void create<3>(Trade::MeshData3D& data, Resource<Mesh>& meshResource, Resource<Buffer>& vertexBufferResource, Resource<Buffer>& indexBufferResource) {
/* Vertex buffer */ /* Vertex buffer */
Buffer* vertexBuffer = new Buffer(Buffer::Target::Array); 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); ResourceManager::instance()->set(vertexBufferResource.key(), vertexBuffer, ResourceDataState::Final, ResourcePolicy::Manual);
/* Mesh configuration */ /* Mesh configuration */
Mesh* mesh = new Mesh; Mesh* mesh = new Mesh;
mesh->setPrimitive(data.primitive()) mesh->setPrimitive(data.primitive())
->setVertexCount(data.positions(0)->size()) ->setVertexCount(data.positions(0).size())
->addVertexBuffer(vertexBuffer, 0, Shaders::Flat3D::Position()); ->addVertexBuffer(vertexBuffer, 0, Shaders::Flat3D::Position());
ResourceManager::instance()->set(meshResource.key(), mesh, ResourceDataState::Final, ResourcePolicy::Manual); ResourceManager::instance()->set(meshResource.key(), mesh, ResourceDataState::Final, ResourcePolicy::Manual);
/* Index buffer, if needed, if not, resource key doesn't have to be set */ /* 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()); CORRADE_INTERNAL_ASSERT(indexBufferResource.key() != ResourceKey());
Buffer* indexBuffer = new Buffer(Buffer::Target::ElementArray); 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); ResourceManager::instance()->set(indexBufferResource.key(), indexBuffer, ResourceDataState::Final, ResourcePolicy::Manual);
} }
} }

7
src/Primitives/Capsule.cpp

@ -24,13 +24,14 @@
#include "Capsule.h" #include "Capsule.h"
#include "Math/Angle.h" #include "Math/Vector3.h"
#include "Primitives/Implementation/Spheroid.h" #include "Primitives/Implementation/Spheroid.h"
#include "Trade/MeshData3D.h"
namespace Magnum { namespace Primitives { namespace Magnum { namespace Primitives {
Trade::MeshData3D Capsule::solid(UnsignedInt hemisphereRings, UnsignedInt cylinderRings, UnsignedInt segments, Float length, TextureCoords textureCoords) { 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 capsule(segments, textureCoords == TextureCoords::Generate ?
Implementation::Spheroid::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.faceRings(hemisphereRings*2-2+cylinderRings);
capsule.topFaceRing(); capsule.topFaceRing();
return std::move(capsule); return capsule.finalize();
} }
}} }}

22
src/Primitives/Circle.cpp

@ -32,39 +32,39 @@ namespace Magnum { namespace Primitives {
Trade::MeshData2D Circle::solid(UnsignedInt segments) { Trade::MeshData2D Circle::solid(UnsignedInt segments) {
CORRADE_ASSERT(segments >= 3, "Primitives::Circle::solid(): segments must be >= 3", 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<Vector2>; std::vector<Vector2> positions;
positions->reserve(segments+1); positions.reserve(segments+1);
/* Central point */ /* Central point */
positions->emplace_back(); positions.emplace_back();
/* Points on circle */ /* Points on circle */
const Rad angleIncrement(2*Constants::pi()/segments); const Rad angleIncrement(2*Constants::pi()/segments);
for(UnsignedInt i = 0; i != segments; ++i) { for(UnsignedInt i = 0; i != segments; ++i) {
const Rad angle(i*angleIncrement); 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) { Trade::MeshData2D Circle::wireframe(UnsignedInt segments) {
CORRADE_ASSERT(segments >= 3, "Primitives::Circle::wireframe(): segments must be >= 3", 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<Vector2>; std::vector<Vector2> positions;
positions->reserve(segments); positions.reserve(segments);
/* Points on circle */ /* Points on circle */
const Rad angleIncrement(2*Constants::pi()/segments); const Rad angleIncrement(2*Constants::pi()/segments);
for(UnsignedInt i = 0; i != segments; ++i) { for(UnsignedInt i = 0; i != segments; ++i) {
const Rad angle(i*angleIncrement); 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)}, {});
} }
}} }}

4
src/Primitives/Crosshair.cpp

@ -31,14 +31,14 @@
namespace Magnum { namespace Primitives { namespace Magnum { namespace Primitives {
Trade::MeshData2D Crosshair2D::wireframe() { Trade::MeshData2D Crosshair2D::wireframe() {
return Trade::MeshData2D(Mesh::Primitive::Lines, nullptr, {new std::vector<Vector2>{ return Trade::MeshData2D(Mesh::Primitive::Lines, {}, {{
{-1.0f, 0.0f}, {1.0f, 0.0f}, {-1.0f, 0.0f}, {1.0f, 0.0f},
{ 0.0f, -1.0f}, {0.0f, 1.0f} { 0.0f, -1.0f}, {0.0f, 1.0f}
}}, {}); }}, {});
} }
Trade::MeshData3D Crosshair3D::wireframe() { Trade::MeshData3D Crosshair3D::wireframe() {
return Trade::MeshData3D(Mesh::Primitive::Lines, nullptr, {new std::vector<Vector3>{ return Trade::MeshData3D(Mesh::Primitive::Lines, {}, {{
{-1.0f, 0.0f, 0.0f}, {1.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, 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} { 0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, 1.0f}

10
src/Primitives/Cube.cpp

@ -30,14 +30,14 @@
namespace Magnum { namespace Primitives { namespace Magnum { namespace Primitives {
Trade::MeshData3D Cube::solid() { Trade::MeshData3D Cube::solid() {
return Trade::MeshData3D(Mesh::Primitive::Triangles, new std::vector<UnsignedInt>{ return Trade::MeshData3D(Mesh::Primitive::Triangles, {
0, 1, 2, 0, 2, 3, /* +Z */ 0, 1, 2, 0, 2, 3, /* +Z */
4, 5, 6, 4, 6, 7, /* +X */ 4, 5, 6, 4, 6, 7, /* +X */
8, 9, 10, 8, 10, 11, /* +Y */ 8, 9, 10, 8, 10, 11, /* +Y */
12, 13, 14, 12, 14, 15, /* -Z */ 12, 13, 14, 12, 14, 15, /* -Z */
16, 17, 18, 16, 18, 19, /* -Y */ 16, 17, 18, 16, 18, 19, /* -Y */
20, 21, 22, 20, 22, 23 /* -X */ 20, 21, 22, 20, 22, 23 /* -X */
}, {new std::vector<Vector3>{ }, {{
{-1.0f, -1.0f, 1.0f}, {-1.0f, -1.0f, 1.0f},
{ 1.0f, -1.0f, 1.0f}, { 1.0f, -1.0f, 1.0f},
{ 1.0f, 1.0f, 1.0f}, /* +Z */ { 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},
{-1.0f, 1.0f, 1.0f}, /* -X */ {-1.0f, 1.0f, 1.0f}, /* -X */
{-1.0f, 1.0f, -1.0f} {-1.0f, 1.0f, -1.0f}
}}, {new std::vector<Vector3>{ }}, {{
{ 0.0f, 0.0f, 1.0f}, { 0.0f, 0.0f, 1.0f},
{ 0.0f, 0.0f, 1.0f}, { 0.0f, 0.0f, 1.0f},
{ 0.0f, 0.0f, 1.0f}, /* +Z */ { 0.0f, 0.0f, 1.0f}, /* +Z */
@ -101,12 +101,12 @@ Trade::MeshData3D Cube::solid() {
} }
Trade::MeshData3D Cube::wireframe() { Trade::MeshData3D Cube::wireframe() {
return Trade::MeshData3D(Mesh::Primitive::Lines, new std::vector<UnsignedInt>{ return Trade::MeshData3D(Mesh::Primitive::Lines, {
0, 1, 1, 2, 2, 3, 3, 0, /* +Z */ 0, 1, 1, 2, 2, 3, 3, 0, /* +Z */
4, 5, 5, 6, 6, 7, 7, 4, /* -Z */ 4, 5, 5, 6, 6, 7, 7, 4, /* -Z */
1, 5, 2, 6, /* +X */ 1, 5, 2, 6, /* +X */
0, 4, 3, 7 /* -X */ 0, 4, 3, 7 /* -X */
}, {new std::vector<Vector3>{ }, {{
{-1.0f, -1.0f, 1.0f}, {-1.0f, -1.0f, 1.0f},
{ 1.0f, -1.0f, 1.0f}, { 1.0f, -1.0f, 1.0f},
{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 1.0f},

5
src/Primitives/Cylinder.cpp

@ -26,11 +26,12 @@
#include "Math/Vector3.h" #include "Math/Vector3.h"
#include "Primitives/Implementation/Spheroid.h" #include "Primitives/Implementation/Spheroid.h"
#include "Trade/MeshData3D.h"
namespace Magnum { namespace Primitives { namespace Magnum { namespace Primitives {
Trade::MeshData3D Cylinder::solid(UnsignedInt rings, UnsignedInt segments, Float length, Cylinder::Flags flags) { 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); 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); cylinder.faceRings(rings, flags & Flag::CapEnds ? 1 : 0);
if(flags & Flag::CapEnds) cylinder.topFaceRing(); if(flags & Flag::CapEnds) cylinder.topFaceRing();
return std::move(cylinder); return cylinder.finalize();
} }
}} }}

6
src/Primitives/Icosphere.cpp

@ -28,7 +28,7 @@
namespace Magnum { namespace Primitives { namespace Magnum { namespace Primitives {
Icosphere<0>::Icosphere(): MeshData3D(Mesh::Primitive::Triangles, new std::vector<UnsignedInt>{ Icosphere<0>::Icosphere(): MeshData3D(Mesh::Primitive::Triangles, {
1, 2, 6, 1, 2, 6,
1, 7, 2, 1, 7, 2,
3, 4, 5, 3, 4, 5,
@ -49,7 +49,7 @@ Icosphere<0>::Icosphere(): MeshData3D(Mesh::Primitive::Triangles, new std::vecto
7, 1, 0, 7, 1, 0,
3, 9, 8, 3, 9, 8,
4, 8, 0 4, 8, 0
}, {new std::vector<Vector3>}, {new std::vector<Vector3>{ }, {}, {{
{0.0f, -0.525731f, 0.850651f}, {0.0f, -0.525731f, 0.850651f},
{0.850651f, 0.0f, 0.525731f}, {0.850651f, 0.0f, 0.525731f},
{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},
{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());
} }
}} }}

76
src/Primitives/Implementation/Spheroid.cpp

@ -26,17 +26,18 @@
#include "Math/Functions.h" #include "Math/Functions.h"
#include "Math/Vector3.h" #include "Math/Vector3.h"
#include "Trade/MeshData3D.h"
namespace Magnum { namespace Primitives { namespace Implementation { namespace Magnum { namespace Primitives { namespace Implementation {
Spheroid::Spheroid(UnsignedInt segments, TextureCoords textureCoords): MeshData3D(Mesh::Primitive::Triangles, new std::vector<UnsignedInt>, {new std::vector<Vector3>()}, {new std::vector<Vector3>()}, textureCoords == TextureCoords::Generate ? std::vector<std::vector<Vector2>*>{new std::vector<Vector2>()} : std::vector<std::vector<Vector2>*>()), segments(segments), textureCoords(textureCoords) {} Spheroid::Spheroid(UnsignedInt segments, TextureCoords textureCoords): segments(segments), textureCoords(textureCoords) {}
void Spheroid::capVertex(Float y, Float normalY, Float textureCoordsV) { void Spheroid::capVertex(Float y, Float normalY, Float textureCoordsV) {
positions(0)->push_back({0.0f, y, 0.0f}); positions.push_back({0.0f, y, 0.0f});
normals(0)->push_back({0.0f, normalY, 0.0f}); normals.push_back({0.0f, normalY, 0.0f});
if(textureCoords == TextureCoords::Generate) 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) { 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) { for(UnsignedInt j = 0; j != segments; ++j) {
Rad segmentAngle = j*segmentAngleIncrement; Rad segmentAngle = j*segmentAngleIncrement;
positions(0)->push_back({x*Math::sin(segmentAngle), centerY+y, z*Math::cos(segmentAngle)}); positions.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)}); normals.push_back({x*Math::sin(segmentAngle), y, z*Math::cos(segmentAngle)});
if(textureCoords == TextureCoords::Generate) 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 */ /* Duplicate first segment in the ring for additional vertex for texture coordinate */
if(textureCoords == TextureCoords::Generate) { if(textureCoords == TextureCoords::Generate) {
positions(0)->push_back((*positions(0))[positions(0)->size()-segments]); positions.push_back(positions[positions.size()-segments]);
normals(0)->push_back((*normals(0))[normals(0)->size()-segments]); normals.push_back(normals[normals.size()-segments]);
textureCoords2D(0)->push_back({1.0f, startTextureCoordsV + i*textureCoordsVIncrement}); 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 i = 0; i != count; ++i) {
for(UnsignedInt j = 0; j != segments; ++j) { for(UnsignedInt j = 0; j != segments; ++j) {
Rad segmentAngle = j*segmentAngleIncrement; Rad segmentAngle = j*segmentAngleIncrement;
positions(0)->push_back({Math::sin(segmentAngle), startY, Math::cos(segmentAngle)}); positions.push_back({Math::sin(segmentAngle), startY, Math::cos(segmentAngle)});
normals(0)->push_back({Math::sin(segmentAngle), 0.0f, Math::cos(segmentAngle)}); normals.push_back({Math::sin(segmentAngle), 0.0f, Math::cos(segmentAngle)});
if(textureCoords == TextureCoords::Generate) 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 */ /* Duplicate first segment in the ring for additional vertex for texture coordinate */
if(textureCoords == TextureCoords::Generate) { if(textureCoords == TextureCoords::Generate) {
positions(0)->push_back((*positions(0))[positions(0)->size()-segments]); positions.push_back(positions[positions.size()-segments]);
normals(0)->push_back((*normals(0))[normals(0)->size()-segments]); normals.push_back(normals[normals.size()-segments]);
textureCoords2D(0)->push_back({1.0f, startTextureCoordsV + i*textureCoordsVIncrement}); textureCoords2D.push_back({1.0f, startTextureCoordsV + i*textureCoordsVIncrement});
} }
startY += yIncrement; startY += yIncrement;
@ -91,14 +92,14 @@ void Spheroid::cylinderVertexRings(UnsignedInt count, Float startY, Float yIncre
void Spheroid::bottomFaceRing() { void Spheroid::bottomFaceRing() {
for(UnsignedInt j = 0; j != segments; ++j) { for(UnsignedInt j = 0; j != segments; ++j) {
/* Bottom vertex */ /* Bottom vertex */
indices()->push_back(0); indices.push_back(0);
/* Top right vertex */ /* Top right vertex */
indices()->push_back((j != segments-1 || textureCoords == TextureCoords::Generate) ? indices.push_back((j != segments-1 || textureCoords == TextureCoords::Generate) ?
j+2 : 1); j+2 : 1);
/* Top left vertex */ /* 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 topLeft = bottomLeft+vertexSegments;
UnsignedInt topRight = bottomRight+vertexSegments; UnsignedInt topRight = bottomRight+vertexSegments;
indices()->push_back(bottomLeft); indices.push_back(bottomLeft);
indices()->push_back(bottomRight); indices.push_back(bottomRight);
indices()->push_back(topRight); indices.push_back(topRight);
indices()->push_back(bottomLeft); indices.push_back(bottomLeft);
indices()->push_back(topRight); indices.push_back(topRight);
indices()->push_back(topLeft); indices.push_back(topLeft);
} }
} }
} }
@ -128,14 +129,14 @@ void Spheroid::topFaceRing() {
for(UnsignedInt j = 0; j != segments; ++j) { for(UnsignedInt j = 0; j != segments; ++j) {
/* Bottom left vertex */ /* Bottom left vertex */
indices()->push_back(normals(0)->size()-vertexSegments+j-1); indices.push_back(normals.size()-vertexSegments+j-1);
/* Bottom right vertex */ /* Bottom right vertex */
indices()->push_back((j != segments-1 || textureCoords == TextureCoords::Generate) ? indices.push_back((j != segments-1 || textureCoords == TextureCoords::Generate) ?
normals(0)->size()-vertexSegments+j : normals(0)->size()-segments-1); normals.size()-vertexSegments+j : normals.size()-segments-1);
/* Top vertex */ /* 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) { for(UnsignedInt i = 0; i != segments; ++i) {
Rad segmentAngle = i*segmentAngleIncrement; Rad segmentAngle = i*segmentAngleIncrement;
positions(0)->push_back({Math::sin(segmentAngle), y, Math::cos(segmentAngle)}); positions.push_back({Math::sin(segmentAngle), y, Math::cos(segmentAngle)});
normals(0)->push_back(normal); normals.push_back(normal);
if(textureCoords == TextureCoords::Generate) 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 */ /* Duplicate first segment in the ring for additional vertex for texture coordinate */
if(textureCoords == TextureCoords::Generate) { if(textureCoords == TextureCoords::Generate) {
positions(0)->push_back((*positions(0))[positions(0)->size()-segments]); positions.push_back(positions[positions.size()-segments]);
normals(0)->push_back(normal); normals.push_back(normal);
textureCoords2D(0)->push_back({1.0f, textureCoordsV}); 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::vector<Vector2>>{std::move(textureCoords2D)} : std::vector<std::vector<Vector2>>());
}
}}} }}}

15
src/Primitives/Implementation/Spheroid.h

@ -24,11 +24,14 @@
DEALINGS IN THE SOFTWARE. DEALINGS IN THE SOFTWARE.
*/ */
#include "Trade/MeshData3D.h" #include <vector>
#include "Magnum.h"
#include "Trade/Trade.h"
namespace Magnum { namespace Primitives { namespace Implementation { namespace Magnum { namespace Primitives { namespace Implementation {
class Spheroid: public Trade::MeshData3D { class Spheroid {
public: public:
enum class TextureCoords: UnsignedByte { enum class TextureCoords: UnsignedByte {
DontGenerate, DontGenerate,
@ -45,8 +48,16 @@ class Spheroid: public Trade::MeshData3D {
void topFaceRing(); void topFaceRing();
void capVertexRing(Float y, Float textureCoordsV, const Vector3& normal); void capVertexRing(Float y, Float textureCoordsV, const Vector3& normal);
Trade::MeshData3D finalize();
UnsignedInt segments; UnsignedInt segments;
TextureCoords textureCoords; TextureCoords textureCoords;
private:
std::vector<UnsignedInt> indices;
std::vector<Vector3> positions;
std::vector<Vector3> normals;
std::vector<Vector2> textureCoords2D;
}; };
}}} }}}

4
src/Primitives/Line.cpp

@ -31,13 +31,13 @@
namespace Magnum { namespace Primitives { namespace Magnum { namespace Primitives {
Trade::MeshData2D Line2D::wireframe() { Trade::MeshData2D Line2D::wireframe() {
return Trade::MeshData2D(Mesh::Primitive::Lines, nullptr, {new std::vector<Vector2>{ return Trade::MeshData2D(Mesh::Primitive::Lines, {}, {{
{0.0f, 0.0f}, {1.0f, 0.0f} {0.0f, 0.0f}, {1.0f, 0.0f}
}}, {}); }}, {});
} }
Trade::MeshData3D Line3D::wireframe() { Trade::MeshData3D Line3D::wireframe() {
return Trade::MeshData3D(Mesh::Primitive::Lines, nullptr, {new std::vector<Vector3>{ return Trade::MeshData3D(Mesh::Primitive::Lines, {}, {{
{0.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f},
}}, {}, {}); }}, {}, {});
} }

6
src/Primitives/Plane.cpp

@ -30,12 +30,12 @@
namespace Magnum { namespace Primitives { namespace Magnum { namespace Primitives {
Trade::MeshData3D Plane::solid() { Trade::MeshData3D Plane::solid() {
return Trade::MeshData3D(Mesh::Primitive::TriangleStrip, nullptr, {new std::vector<Vector3>{ 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},
{-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<Vector3>{ }}, {{
{0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 1.0f},
{0.0f, 0.0f, 1.0f}, {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() { Trade::MeshData3D Plane::wireframe() {
return Trade::MeshData3D(Mesh::Primitive::LineLoop, nullptr, {new std::vector<Vector3>{ return Trade::MeshData3D(Mesh::Primitive::LineLoop, {}, {{
{-1.0f, -1.0f, 0.0f}, {-1.0f, -1.0f, 0.0f},
{1.0f, -1.0f, 0.0f}, {1.0f, -1.0f, 0.0f},
{1.0f, 1.0f, 0.0f}, {1.0f, 1.0f, 0.0f},

4
src/Primitives/Square.cpp

@ -30,7 +30,7 @@
namespace Magnum { namespace Primitives { namespace Magnum { namespace Primitives {
Trade::MeshData2D Square::solid() { Trade::MeshData2D Square::solid() {
return Trade::MeshData2D(Mesh::Primitive::TriangleStrip, nullptr, {new std::vector<Vector2>{ return Trade::MeshData2D(Mesh::Primitive::TriangleStrip, {}, {{
{1.0f, -1.0f}, {1.0f, -1.0f},
{1.0f, 1.0f}, {1.0f, 1.0f},
{-1.0f, -1.0f}, {-1.0f, -1.0f},
@ -39,7 +39,7 @@ Trade::MeshData2D Square::solid() {
} }
Trade::MeshData2D Square::wireframe() { Trade::MeshData2D Square::wireframe() {
return Trade::MeshData2D(Mesh::Primitive::LineLoop, nullptr, {new std::vector<Vector2>{ return Trade::MeshData2D(Mesh::Primitive::LineLoop, {}, {{
{-1.0f, -1.0f}, {-1.0f, -1.0f},
{1.0f, -1.0f}, {1.0f, -1.0f},
{1.0f, 1.0f}, {1.0f, 1.0f},

12
src/Primitives/Test/CapsuleTest.cpp

@ -50,7 +50,7 @@ CapsuleTest::CapsuleTest() {
void CapsuleTest::withoutTextureCoords() { void CapsuleTest::withoutTextureCoords() {
Trade::MeshData3D capsule = Capsule::solid(2, 2, 3, 1.0f); Trade::MeshData3D capsule = Capsule::solid(2, 2, 3, 1.0f);
CORRADE_COMPARE_AS(*capsule.positions(0), (std::vector<Vector3>{ CORRADE_COMPARE_AS(capsule.positions(0), (std::vector<Vector3>{
{0.0f, -1.5f, 0.0f}, {0.0f, -1.5f, 0.0f},
{0.0f, -1.20711f, 0.707107f}, {0.0f, -1.20711f, 0.707107f},
@ -76,7 +76,7 @@ void CapsuleTest::withoutTextureCoords() {
{0.0f, 1.5f, 0.0f} {0.0f, 1.5f, 0.0f}
}), TestSuite::Compare::Container); }), TestSuite::Compare::Container);
CORRADE_COMPARE_AS(*capsule.normals(0), (std::vector<Vector3>{ CORRADE_COMPARE_AS(capsule.normals(0), (std::vector<Vector3>{
{0.0f, -1.0f, 0.0f}, {0.0f, -1.0f, 0.0f},
{0.0f, -0.707107f, 0.707107f}, {0.0f, -0.707107f, 0.707107f},
@ -102,7 +102,7 @@ void CapsuleTest::withoutTextureCoords() {
{0.0f, 1.0f, 0.0f} {0.0f, 1.0f, 0.0f}
}), TestSuite::Compare::Container); }), TestSuite::Compare::Container);
CORRADE_COMPARE_AS(*capsule.indices(), (std::vector<UnsignedInt>{ CORRADE_COMPARE_AS(capsule.indices(), (std::vector<UnsignedInt>{
0, 2, 1, 0, 3, 2, 0, 1, 3, 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, 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, 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() { void CapsuleTest::withTextureCoords() {
Trade::MeshData3D capsule = Capsule::solid(2, 2, 3, 1.0f, Capsule::TextureCoords::Generate); Trade::MeshData3D capsule = Capsule::solid(2, 2, 3, 1.0f, Capsule::TextureCoords::Generate);
CORRADE_COMPARE_AS(*capsule.positions(0), (std::vector<Vector3>{ CORRADE_COMPARE_AS(capsule.positions(0), (std::vector<Vector3>{
{0.0f, -1.5f, 0.0f}, {0.0f, -1.5f, 0.0f},
{0.0f, -1.20711f, 0.707107f}, {0.0f, -1.20711f, 0.707107f},
@ -146,7 +146,7 @@ void CapsuleTest::withTextureCoords() {
{0.0f, 1.5f, 0.0f} {0.0f, 1.5f, 0.0f}
}), TestSuite::Compare::Container); }), TestSuite::Compare::Container);
CORRADE_COMPARE_AS(*capsule.textureCoords2D(0), (std::vector<Vector2>{ CORRADE_COMPARE_AS(capsule.textureCoords2D(0), (std::vector<Vector2>{
{0.5f, 0.0f}, {0.5f, 0.0f},
{0.0f, 0.166667f}, {0.0f, 0.166667f},
@ -177,7 +177,7 @@ void CapsuleTest::withTextureCoords() {
{0.5f, 1.0f} {0.5f, 1.0f}
}), TestSuite::Compare::Container); }), TestSuite::Compare::Container);
CORRADE_COMPARE_AS(*capsule.indices(), (std::vector<UnsignedInt>{ CORRADE_COMPARE_AS(capsule.indices(), (std::vector<UnsignedInt>{
0, 2, 1, 0, 3, 2, 0, 4, 3, 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, 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, 5, 6, 10, 5, 10, 9, 6, 7, 11, 6, 11, 10, 7, 8, 12, 7, 12, 11,

4
src/Primitives/Test/CircleTest.cpp

@ -46,7 +46,7 @@ CircleTest::CircleTest() {
void CircleTest::solid() { void CircleTest::solid() {
Trade::MeshData2D circle = Primitives::Circle::solid(8); Trade::MeshData2D circle = Primitives::Circle::solid(8);
CORRADE_COMPARE(*circle.positions(0), (std::vector<Vector2>{ CORRADE_COMPARE(circle.positions(0), (std::vector<Vector2>{
{ 0.0f, 0.0f}, { 0.0f, 0.0f},
{ 1.0f, 0.0f}, { Constants::sqrt2()/2.0f, Constants::sqrt2()/2.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}, { 0.0f, 1.0f}, {-Constants::sqrt2()/2.0f, Constants::sqrt2()/2.0f},
@ -58,7 +58,7 @@ void CircleTest::solid() {
void CircleTest::wireframe() { void CircleTest::wireframe() {
Trade::MeshData2D circle = Primitives::Circle::wireframe(8); Trade::MeshData2D circle = Primitives::Circle::wireframe(8);
CORRADE_COMPARE(*circle.positions(0), (std::vector<Vector2>{ CORRADE_COMPARE(circle.positions(0), (std::vector<Vector2>{
{ 1.0f, 0.0f}, { Constants::sqrt2()/2.0f, Constants::sqrt2()/2.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}, { 0.0f, 1.0f}, {-Constants::sqrt2()/2.0f, Constants::sqrt2()/2.0f},
{-1.0f, 0.0f}, {-Constants::sqrt2()/2.0f, -Constants::sqrt2()/2.0f}, {-1.0f, 0.0f}, {-Constants::sqrt2()/2.0f, -Constants::sqrt2()/2.0f},

14
src/Primitives/Test/CylinderTest.cpp

@ -47,7 +47,7 @@ CylinderTest::CylinderTest() {
void CylinderTest::withoutAnything() { void CylinderTest::withoutAnything() {
Trade::MeshData3D cylinder = Cylinder::solid(2, 3, 3.0f); Trade::MeshData3D cylinder = Cylinder::solid(2, 3, 3.0f);
CORRADE_COMPARE_AS(*cylinder.positions(0), (std::vector<Vector3>{ CORRADE_COMPARE_AS(cylinder.positions(0), (std::vector<Vector3>{
{0.0f, -1.5f, 1.0f}, {0.0f, -1.5f, 1.0f},
{0.866025f, -1.5f, -0.5f}, {0.866025f, -1.5f, -0.5f},
{-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} {-0.866025f, 1.5f, -0.5f}
}), TestSuite::Compare::Container); }), TestSuite::Compare::Container);
CORRADE_COMPARE_AS(*cylinder.normals(0), (std::vector<Vector3>{ CORRADE_COMPARE_AS(cylinder.normals(0), (std::vector<Vector3>{
{0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 1.0f},
{0.866025f, 0.0f, -0.5f}, {0.866025f, 0.0f, -0.5f},
{-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} {-0.866025f, 0.0f, -0.5f}
}), TestSuite::Compare::Container); }), TestSuite::Compare::Container);
CORRADE_COMPARE_AS(*cylinder.indices(), (std::vector<UnsignedInt>{ CORRADE_COMPARE_AS(cylinder.indices(), (std::vector<UnsignedInt>{
0, 1, 4, 0, 4, 3, 1, 2, 5, 1, 5, 4, 2, 0, 3, 2, 3, 5, 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 3, 4, 7, 3, 7, 6, 4, 5, 8, 4, 8, 7, 5, 3, 6, 5, 6, 8
}), TestSuite::Compare::Container); }), TestSuite::Compare::Container);
@ -84,7 +84,7 @@ void CylinderTest::withoutAnything() {
void CylinderTest::withTextureCoordsAndCaps() { void CylinderTest::withTextureCoordsAndCaps() {
Trade::MeshData3D cylinder = Cylinder::solid(2, 3, 3.0f, Cylinder::Flag::GenerateTextureCoords|Cylinder::Flag::CapEnds); Trade::MeshData3D cylinder = Cylinder::solid(2, 3, 3.0f, Cylinder::Flag::GenerateTextureCoords|Cylinder::Flag::CapEnds);
CORRADE_COMPARE_AS(*cylinder.positions(0), (std::vector<Vector3>{ CORRADE_COMPARE_AS(cylinder.positions(0), (std::vector<Vector3>{
{0.0f, -1.5f, 0.0f}, {0.0f, -1.5f, 0.0f},
{0.0f, -1.5f, 1.0f}, {0.0f, -1.5f, 1.0f},
@ -115,7 +115,7 @@ void CylinderTest::withTextureCoordsAndCaps() {
{0.0f, 1.5f, 0.0f} {0.0f, 1.5f, 0.0f}
}), TestSuite::Compare::Container); }), TestSuite::Compare::Container);
CORRADE_COMPARE_AS(*cylinder.normals(0), (std::vector<Vector3>{ CORRADE_COMPARE_AS(cylinder.normals(0), (std::vector<Vector3>{
{0.0f, -1.0f, 0.0f}, {0.0f, -1.0f, 0.0f},
{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}, {0.0f, 1.0f, 0.0f},
}), TestSuite::Compare::Container); }), TestSuite::Compare::Container);
CORRADE_COMPARE_AS(*cylinder.textureCoords2D(0), (std::vector<Vector2>{ CORRADE_COMPARE_AS(cylinder.textureCoords2D(0), (std::vector<Vector2>{
{0.5f, 0.0f}, {0.5f, 0.0f},
{0.0f, 0.2f}, {0.0f, 0.2f},
@ -177,7 +177,7 @@ void CylinderTest::withTextureCoordsAndCaps() {
{0.5f, 1.0f} {0.5f, 1.0f}
}), TestSuite::Compare::Container); }), TestSuite::Compare::Container);
CORRADE_COMPARE_AS(*cylinder.indices(), (std::vector<UnsignedInt>{ CORRADE_COMPARE_AS(cylinder.indices(), (std::vector<UnsignedInt>{
0, 2, 1, 0, 3, 2, 0, 4, 3, 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, 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, 5, 6, 10, 5, 10, 9, 6, 7, 11, 6, 11, 10, 7, 8, 12, 7,

12
src/Primitives/Test/UVSphereTest.cpp

@ -47,7 +47,7 @@ UVSphereTest::UVSphereTest() {
void UVSphereTest::withoutTextureCoords() { void UVSphereTest::withoutTextureCoords() {
Trade::MeshData3D sphere = UVSphere::solid(3, 3); Trade::MeshData3D sphere = UVSphere::solid(3, 3);
CORRADE_COMPARE_AS(*sphere.positions(0), (std::vector<Vector3>{ CORRADE_COMPARE_AS(sphere.positions(0), (std::vector<Vector3>{
{0.0f, -1.0f, 0.0f}, {0.0f, -1.0f, 0.0f},
{0.0f, -0.5f, 0.866025f}, {0.0f, -0.5f, 0.866025f},
@ -61,7 +61,7 @@ void UVSphereTest::withoutTextureCoords() {
{0.0f, 1.0f, 0.0f} {0.0f, 1.0f, 0.0f}
}), TestSuite::Compare::Container); }), TestSuite::Compare::Container);
CORRADE_COMPARE_AS(*sphere.normals(0), (std::vector<Vector3>{ CORRADE_COMPARE_AS(sphere.normals(0), (std::vector<Vector3>{
{0.0f, -1.0f, 0.0f}, {0.0f, -1.0f, 0.0f},
{0.0f, -0.5f, 0.866025f}, {0.0f, -0.5f, 0.866025f},
@ -75,7 +75,7 @@ void UVSphereTest::withoutTextureCoords() {
{0.0f, 1.0f, 0.0f} {0.0f, 1.0f, 0.0f}
}), TestSuite::Compare::Container); }), TestSuite::Compare::Container);
CORRADE_COMPARE_AS(*sphere.indices(), (std::vector<UnsignedInt>{ CORRADE_COMPARE_AS(sphere.indices(), (std::vector<UnsignedInt>{
0, 2, 1, 0, 3, 2, 0, 1, 3, 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, 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 4, 5, 7, 5, 6, 7, 6, 4, 7
@ -85,7 +85,7 @@ void UVSphereTest::withoutTextureCoords() {
void UVSphereTest::withTextureCoords() { void UVSphereTest::withTextureCoords() {
Trade::MeshData3D sphere = UVSphere::solid(3, 3, UVSphere::TextureCoords::Generate); Trade::MeshData3D sphere = UVSphere::solid(3, 3, UVSphere::TextureCoords::Generate);
CORRADE_COMPARE_AS(*sphere.positions(0), (std::vector<Vector3>{ CORRADE_COMPARE_AS(sphere.positions(0), (std::vector<Vector3>{
{0.0f, -1.0f, 0.0f}, {0.0f, -1.0f, 0.0f},
{0.0f, -0.5f, 0.866025f}, {0.0f, -0.5f, 0.866025f},
@ -101,7 +101,7 @@ void UVSphereTest::withTextureCoords() {
{0.0f, 1.0f, 0.0f} {0.0f, 1.0f, 0.0f}
}), TestSuite::Compare::Container); }), TestSuite::Compare::Container);
CORRADE_COMPARE_AS(*sphere.textureCoords2D(0), (std::vector<Vector2>{ CORRADE_COMPARE_AS(sphere.textureCoords2D(0), (std::vector<Vector2>{
{0.5f, 0.0f}, {0.5f, 0.0f},
{0.0f, 0.333333f}, {0.0f, 0.333333f},
@ -117,7 +117,7 @@ void UVSphereTest::withTextureCoords() {
{0.5f, 1.0f} {0.5f, 1.0f}
}), TestSuite::Compare::Container); }), TestSuite::Compare::Container);
CORRADE_COMPARE_AS(*sphere.indices(), (std::vector<UnsignedInt>{ CORRADE_COMPARE_AS(sphere.indices(), (std::vector<UnsignedInt>{
0, 2, 1, 0, 3, 2, 0, 4, 3, 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, 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 5, 6, 9, 6, 7, 9, 7, 8, 9

9
src/Primitives/UVSphere.cpp

@ -24,13 +24,14 @@
#include "UVSphere.h" #include "UVSphere.h"
#include "Math/Angle.h" #include "Math/Vector3.h"
#include "Implementation/Spheroid.h" #include "Primitives/Implementation/Spheroid.h"
#include "Trade/MeshData3D.h"
namespace Magnum { namespace Primitives { namespace Magnum { namespace Primitives {
Trade::MeshData3D UVSphere::solid(UnsignedInt rings, UnsignedInt segments, TextureCoords textureCoords) { 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 sphere(segments, textureCoords == TextureCoords::Generate ?
Implementation::Spheroid::TextureCoords::Generate : Implementation::Spheroid::TextureCoords::Generate :
@ -53,7 +54,7 @@ Trade::MeshData3D UVSphere::solid(UnsignedInt rings, UnsignedInt segments, Textu
sphere.faceRings(rings-2); sphere.faceRings(rings-2);
sphere.topFaceRing(); sphere.topFaceRing();
return std::move(sphere); return sphere.finalize();
} }
}} }}

46
src/Trade/MeshData2D.cpp

@ -28,24 +28,44 @@
namespace Magnum { namespace Trade { namespace Magnum { namespace Trade {
MeshData2D::MeshData2D(Mesh::Primitive primitive, std::vector<UnsignedInt>* indices, std::vector<std::vector<Vector2>*> positions, std::vector<std::vector<Vector2>*> textureCoords2D): _primitive(primitive), _indices(indices), _positions(std::move(positions)), _textureCoords2D(std::move(textureCoords2D)) {} MeshData2D::MeshData2D(Mesh::Primitive primitive, std::vector<UnsignedInt> indices, std::vector<std::vector<Vector2>> positions, std::vector<std::vector<Vector2>> 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<UnsignedInt>& MeshData2D::indices() {
CORRADE_ASSERT(isIndexed(), "Trade::MeshData2D::indices(): the mesh is not indexed", _indices);
return _indices;
}
const std::vector<UnsignedInt>& MeshData2D::indices() const {
CORRADE_ASSERT(isIndexed(), "Trade::MeshData2D::indices(): the mesh is not indexed", _indices);
return _indices;
}
std::vector<Vector2>& 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)) { const std::vector<Vector2>& MeshData2D::positions(const UnsignedInt id) const {
other._indices = nullptr; CORRADE_ASSERT(id < positionArrayCount(), "Trade::MeshData2D::positions(): index out of range", _positions[id]);
return _positions[id];
} }
MeshData2D& MeshData2D::operator=(MeshData2D&& other) { std::vector<Vector2>& MeshData2D::textureCoords2D(const UnsignedInt id) {
_primitive = other._primitive; CORRADE_ASSERT(id < textureCoords2DArrayCount(), "Trade::MeshData2D::textureCoords2D(): index out of range", _textureCoords2D[id]);
std::swap(_indices, other._indices); return _textureCoords2D[id];
std::swap(_positions, other._positions);
std::swap(_textureCoords2D, other._textureCoords2D);
return *this;
} }
MeshData2D::~MeshData2D() { const std::vector<Vector2>& MeshData2D::textureCoords2D(const UnsignedInt id) const {
delete _indices; CORRADE_ASSERT(id < textureCoords2DArrayCount(), "Trade::MeshData2D::textureCoords2D(): index out of range", _textureCoords2D[id]);
for(auto i: _positions) delete i; return _textureCoords2D[id];
for(auto i: _textureCoords2D) delete i;
} }
}} }}

66
src/Trade/MeshData2D.h

@ -42,70 +42,76 @@ type.
@see MeshData3D @see MeshData3D
*/ */
class MAGNUM_EXPORT MeshData2D { class MAGNUM_EXPORT MeshData2D {
MeshData2D(const MeshData2D&) = delete;
MeshData2D& operator=(const MeshData2D&) = delete;
public: public:
/** /**
* @brief Constructor * @brief Constructor
* @param primitive Primitive * @param primitive Primitive
* @param indices Array with indices or 0, if this is not * @param indices Index array or empty array, if the mesh is
* indexed mesh * not indexed
* @param positions Array with vertex positions. At least one * @param positions Position arrays. At least one position
* position array should be present. * array should be present.
* @param textureCoords2D Array with two-dimensional texture * @param textureCoords2D Two-dimensional texture coordinate arrays,
* coordinate arrays or empty array * if present
*/ */
explicit MeshData2D(Mesh::Primitive primitive, std::vector<UnsignedInt>* indices, std::vector<std::vector<Vector2>*> positions, std::vector<std::vector<Vector2>*> textureCoords2D); explicit MeshData2D(Mesh::Primitive primitive, std::vector<UnsignedInt> indices, std::vector<std::vector<Vector2>> positions, std::vector<std::vector<Vector2>> textureCoords2D);
/** @brief Copying is not allowed */
MeshData2D(const MeshData2D&) = delete;
/** @brief Move constructor */ /** @brief Move constructor */
MeshData2D(MeshData2D&&); MeshData2D(MeshData2D&& other);
/** @brief Destructor */
~MeshData2D(); ~MeshData2D();
/** @brief Copying is not allowed */
MeshData2D& operator=(const MeshData2D&) = delete;
/** @brief Move assignment */ /** @brief Move assignment */
MeshData2D& operator=(MeshData2D&&); MeshData2D& operator=(MeshData2D&& other);
/** @brief Primitive */ /** @brief Primitive */
Mesh::Primitive primitive() const { return _primitive; } Mesh::Primitive primitive() const { return _primitive; }
/** @brief Whether the mesh is indexed */
bool isIndexed() const { return !_indices.empty(); }
/** /**
* @brief Indices * @brief Indices
* @return Indices or nullptr if the mesh is not indexed. *
* @see isIndexed()
*/ */
std::vector<UnsignedInt>* indices() { return _indices; } std::vector<UnsignedInt>& indices();
const std::vector<UnsignedInt>* indices() const { return _indices; } /**< @overload */ const std::vector<UnsignedInt>& indices() const; /**< @overload */
/** @brief Count of vertex position arrays */ /** @brief Count of position arrays */
UnsignedInt positionArrayCount() const { return _positions.size(); } UnsignedInt positionArrayCount() const { return _positions.size(); }
/** /**
* @brief Positions * @brief Positions
* @param id ID of position data array * @param id Position array ID
* @return Positions or nullptr if there is no vertex array with given *
* ID. * @see positionArrayCount()
*/ */
std::vector<Vector2>* positions(UnsignedInt id) { return _positions[id]; } std::vector<Vector2>& positions(UnsignedInt id);
const std::vector<Vector2>* positions(UnsignedInt id) const { return _positions[id]; } /**< @overload */ const std::vector<Vector2>& positions(UnsignedInt id) const; /**< @overload */
/** @brief Count of 2D texture coordinate arrays */ /** @brief Count of 2D texture coordinate arrays */
UnsignedInt textureCoords2DArrayCount() const { return _textureCoords2D.size(); } UnsignedInt textureCoords2DArrayCount() const { return _textureCoords2D.size(); }
/** /**
* @brief 2D texture coordinates * @brief 2D texture coordinates
* @param id ID of texture coordinates array * @param id Texture coordinate array ID
* @return %Texture coordinates or nullptr if there is no texture *
* coordinates array with given ID. * @see textureCoords2DArrayCount()
*/ */
std::vector<Vector2>* textureCoords2D(UnsignedInt id) { return _textureCoords2D[id]; } std::vector<Vector2>& textureCoords2D(UnsignedInt id);
const std::vector<Vector2>* textureCoords2D(UnsignedInt id) const { return _textureCoords2D[id]; } /**< @overload */ const std::vector<Vector2>& textureCoords2D(UnsignedInt id) const; /**< @overload */
private: private:
Mesh::Primitive _primitive; Mesh::Primitive _primitive;
std::vector<UnsignedInt>* _indices; std::vector<UnsignedInt> _indices;
std::vector<std::vector<Vector2>*> _positions; std::vector<std::vector<Vector2>> _positions;
std::vector<std::vector<Vector2>*> _textureCoords2D; std::vector<std::vector<Vector2>> _textureCoords2D;
}; };
}} }}

58
src/Trade/MeshData3D.cpp

@ -28,26 +28,54 @@
namespace Magnum { namespace Trade { namespace Magnum { namespace Trade {
MeshData3D::MeshData3D(Mesh::Primitive primitive, std::vector<UnsignedInt>* indices, std::vector<std::vector<Vector3>*> positions, std::vector<std::vector<Vector3>*> normals, std::vector<std::vector<Vector2>*> textureCoords2D): _primitive(primitive), _indices(indices), _positions(std::move(positions)), _normals(std::move(normals)), _textureCoords2D(std::move(textureCoords2D)) {} MeshData3D::MeshData3D(Mesh::Primitive primitive, std::vector<UnsignedInt> indices, std::vector<std::vector<Vector3>> positions, std::vector<std::vector<Vector3>> normals, std::vector<std::vector<Vector2>> 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<UnsignedInt>& MeshData3D::indices() {
CORRADE_ASSERT(isIndexed(), "Trade::MeshData3D::indices(): the mesh is not indexed", _indices);
return _indices;
}
const std::vector<UnsignedInt>& MeshData3D::indices() const {
CORRADE_ASSERT(isIndexed(), "Trade::MeshData3D::indices(): the mesh is not indexed", _indices);
return _indices;
}
std::vector<Vector3>& MeshData3D::positions(const UnsignedInt id) {
CORRADE_ASSERT(id < positionArrayCount(), "Trade::MeshData3D::positions(): index out of range", _positions[id]);
return _positions[id];
}
const std::vector<Vector3>& MeshData3D::positions(const UnsignedInt id) const {
CORRADE_ASSERT(id < positionArrayCount(), "Trade::MeshData3D::positions(): index out of range", _positions[id]);
return _positions[id];
}
std::vector<Vector3>& 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)) { const std::vector<Vector3>& MeshData3D::normals(const UnsignedInt id) const {
other._indices = nullptr; CORRADE_ASSERT(id < normalArrayCount(), "Trade::MeshData3D::normals(): index out of range", _normals[id]);
return _normals[id];
} }
MeshData3D& MeshData3D::operator=(MeshData3D&& other) { std::vector<Vector2>& MeshData3D::textureCoords2D(const UnsignedInt id) {
_primitive = other._primitive; CORRADE_ASSERT(id < textureCoords2DArrayCount(), "Trade::MeshData3D::textureCoords2D(): index out of range", _textureCoords2D[id]);
std::swap(_indices, other._indices); return _textureCoords2D[id];
std::swap(_positions, other._positions);
std::swap(_normals, other._normals);
std::swap(_textureCoords2D, other._textureCoords2D);
return *this;
} }
MeshData3D::~MeshData3D() { const std::vector<Vector2>& MeshData3D::textureCoords2D(const UnsignedInt id) const {
delete _indices; CORRADE_ASSERT(id < textureCoords2DArrayCount(), "Trade::MeshData3D::textureCoords2D(): index out of range", _textureCoords2D[id]);
for(auto i: _positions) delete i; return _textureCoords2D[id];
for(auto i: _normals) delete i;
for(auto i: _textureCoords2D) delete i;
} }
}} }}

76
src/Trade/MeshData3D.h

@ -42,84 +42,90 @@ type.
@see MeshData2D @see MeshData2D
*/ */
class MAGNUM_EXPORT MeshData3D { class MAGNUM_EXPORT MeshData3D {
MeshData3D(const MeshData3D&) = delete;
MeshData3D& operator=(const MeshData3D&) = delete;
public: public:
/** /**
* @brief Constructor * @brief Constructor
* @param primitive Primitive * @param primitive Primitive
* @param indices Array with indices or 0, if this is not * @param indices Index array or empty array, if the mesh is
* indexed mesh * not indexed
* @param positions Array with vertex positions. At least one * @param positions Position arrays. At least one position
* position array should be present. * array should be present.
* @param normals Array with normal arrays or empty array * @param normals Normal arrays, if present
* @param textureCoords2D Array with two-dimensional texture * @param textureCoords2D Two-dimensional texture coordinate arrays,
* coordinate arrays or empty array * if present
*/ */
explicit MeshData3D(Mesh::Primitive primitive, std::vector<UnsignedInt>* indices, std::vector<std::vector<Vector3>*> positions, std::vector<std::vector<Vector3>*> normals, std::vector<std::vector<Vector2>*> textureCoords2D); explicit MeshData3D(Mesh::Primitive primitive, std::vector<UnsignedInt> indices, std::vector<std::vector<Vector3>> positions, std::vector<std::vector<Vector3>> normals, std::vector<std::vector<Vector2>> textureCoords2D);
/** @brief Copying is not allowed */
MeshData3D(const MeshData3D&) = delete;
/** @brief Move constructor */ /** @brief Move constructor */
MeshData3D(MeshData3D&&); MeshData3D(MeshData3D&&);
/** @brief Destructor */
~MeshData3D(); ~MeshData3D();
/** @brief Copying is not allowed */
MeshData3D& operator=(const MeshData3D&) = delete;
/** @brief Move assignment */ /** @brief Move assignment */
MeshData3D& operator=(MeshData3D&&); MeshData3D& operator=(MeshData3D&&);
/** @brief Primitive */ /** @brief Primitive */
Mesh::Primitive primitive() const { return _primitive; } Mesh::Primitive primitive() const { return _primitive; }
/** @brief Whether the mesh is indexed */
bool isIndexed() const { return !_indices.empty(); }
/** /**
* @brief Indices * @brief Indices
* @return Indices or nullptr if the mesh is not indexed. *
* @see isIndexed()
*/ */
std::vector<UnsignedInt>* indices() { return _indices; } std::vector<UnsignedInt>& indices();
const std::vector<UnsignedInt>* indices() const { return _indices; } /**< @overload */ const std::vector<UnsignedInt>& indices() const; /**< @overload */
/** @brief Count of vertex position arrays */ /** @brief Count of position arrays */
UnsignedInt positionArrayCount() const { return _positions.size(); } UnsignedInt positionArrayCount() const { return _positions.size(); }
/** /**
* @brief Positions * @brief Positions
* @param id ID of position data array * @param id Position array ID
* @return Positions or nullptr if there is no vertex array with given *
* ID. * @see positionArrayCount()
*/ */
std::vector<Vector3>* positions(UnsignedInt id) { return _positions[id]; } std::vector<Vector3>& positions(UnsignedInt id);
const std::vector<Vector3>* positions(UnsignedInt id) const { return _positions[id]; } /**< @overload */ const std::vector<Vector3>& positions(UnsignedInt id) const; /**< @overload */
/** @brief Count of normal arrays */ /** @brief Count of normal arrays */
UnsignedInt normalArrayCount() const { return _normals.size(); } UnsignedInt normalArrayCount() const { return _normals.size(); }
/** /**
* @brief Normals * @brief Normals
* @param id ID of normal data array * @param id Normal array ID
* @return Normals or nullptr if there is no normal array with given *
* ID. * @see normalArrayCount()
*/ */
std::vector<Vector3>* normals(UnsignedInt id) { return _normals[id]; } std::vector<Vector3>& normals(UnsignedInt id);
const std::vector<Vector3>* normals(UnsignedInt id) const { return _normals[id]; } /**< @overload */ const std::vector<Vector3>& normals(UnsignedInt id) const; /**< @overload */
/** @brief Count of 2D texture coordinate arrays */ /** @brief Count of 2D texture coordinate arrays */
UnsignedInt textureCoords2DArrayCount() const { return _textureCoords2D.size(); } UnsignedInt textureCoords2DArrayCount() const { return _textureCoords2D.size(); }
/** /**
* @brief 2D texture coordinates * @brief 2D texture coordinates
* @param id ID of texture coordinates array * @param id Texture coordinate array ID
* @return %Texture coordinates or nullptr if there is no texture *
* coordinates array with given ID. * @see textureCoords2DArrayCount()
*/ */
std::vector<Vector2>* textureCoords2D(UnsignedInt id) { return _textureCoords2D[id]; } std::vector<Vector2>& textureCoords2D(UnsignedInt id);
const std::vector<Vector2>* textureCoords2D(UnsignedInt id) const { return _textureCoords2D[id]; } /**< @overload */ const std::vector<Vector2>& textureCoords2D(UnsignedInt id) const; /**< @overload */
private: private:
Mesh::Primitive _primitive; Mesh::Primitive _primitive;
std::vector<UnsignedInt>* _indices; std::vector<UnsignedInt> _indices;
std::vector<std::vector<Vector3>*> _positions; std::vector<std::vector<Vector3>> _positions;
std::vector<std::vector<Vector3>*> _normals; std::vector<std::vector<Vector3>> _normals;
std::vector<std::vector<Vector2>*> _textureCoords2D; std::vector<std::vector<Vector2>> _textureCoords2D;
}; };
}} }}

Loading…
Cancel
Save