Browse Source

Primitives: 3D circle primitive.

pull/205/head
Vladimír Vondruš 8 years ago
parent
commit
ae8db0471f
  1. 5
      doc/changelog.dox
  2. 44
      src/Magnum/Primitives/Circle.cpp
  3. 26
      src/Magnum/Primitives/Circle.h
  4. 59
      src/Magnum/Primitives/Test/CircleTest.cpp

5
doc/changelog.dox

@ -51,6 +51,11 @@ See also:
@webgl_extension{WEBGL,color_buffer_float},
@webgl_extension{EXT,color_buffer_float}
@subsubsection changelog-latest-new-primitives Primitives library
- New @ref Primitives::circle3DSolid() and @ref Primitives::circle3DWireframe()
primitives
@subsection changelog-latest-deprecated Deprecated APIs
- Class @cpp Primitives::Capsule2D @ce and @cpp Primitives::Capsule3D @ce is

44
src/Magnum/Primitives/Circle.cpp

@ -29,6 +29,7 @@
#include "Magnum/Math/Color.h"
#include "Magnum/Mesh.h"
#include "Magnum/Trade/MeshData2D.h"
#include "Magnum/Trade/MeshData3D.h"
namespace Magnum { namespace Primitives {
@ -37,7 +38,7 @@ Trade::MeshData2D circle2DSolid(const UnsignedInt segments) {
(Trade::MeshData2D{MeshPrimitive::TriangleFan, {}, {}, {}, {}, nullptr}));
std::vector<Vector2> positions;
positions.reserve(segments+1);
positions.reserve(segments + 2);
/* Central point */
positions.emplace_back();
@ -70,6 +71,47 @@ Trade::MeshData2D circle2DWireframe(const UnsignedInt segments) {
return Trade::MeshData2D{MeshPrimitive::LineLoop, {}, {std::move(positions)}, {}, {}, nullptr};
}
Trade::MeshData3D circle3DSolid(const UnsignedInt segments) {
CORRADE_ASSERT(segments >= 3, "Primitives::circle3DSolid(): segments must be >= 3",
(Trade::MeshData3D{MeshPrimitive::TriangleFan, {}, {}, {}, {}, {}, nullptr}));
std::vector<Vector3> positions;
positions.reserve(segments + 2);
/* Central point */
positions.emplace_back();
/* Points on circle. The first/last point is here twice to close the circle
properly. */
const Rad angleIncrement(Constants::tau()/segments);
for(UnsignedInt i = 0; i != segments + 1; ++i) {
const Rad angle(Float(i)*angleIncrement);
positions.emplace_back(Math::cos(angle), Math::sin(angle), 0.0f);
}
/* Normals. All pointing in the same direction. */
std::vector<Vector3> normals{segments + 2, Vector3::zAxis(1.0f)};
return Trade::MeshData3D{MeshPrimitive::TriangleFan, {}, {std::move(positions)}, {std::move(normals)}, {}, {}, nullptr};
}
Trade::MeshData3D circle3DWireframe(const UnsignedInt segments) {
CORRADE_ASSERT(segments >= 3, "Primitives::circle3DWireframe(): segments must be >= 3",
(Trade::MeshData3D{MeshPrimitive::LineLoop, {}, {}, {}, {}, {}, nullptr}));
std::vector<Vector3> positions;
positions.reserve(segments);
/* Points on circle */
const Rad angleIncrement(Constants::tau()/segments);
for(UnsignedInt i = 0; i != segments; ++i) {
const Rad angle(Float(i)*angleIncrement);
positions.emplace_back(Math::cos(angle), Math::sin(angle), 0.0f);
}
return Trade::MeshData3D{MeshPrimitive::LineLoop, {}, {std::move(positions)}, {}, {}, {}, nullptr};
}
#ifdef MAGNUM_BUILD_DEPRECATED
Trade::MeshData2D Circle::solid(const UnsignedInt segments) {
return circle2DSolid(segments);

26
src/Magnum/Primitives/Circle.h

@ -26,7 +26,7 @@
*/
/** @file
* @brief Function @ref Magnum::Primitives::circle2DSolid(), @ref Magnum::Primitives::circle2DWireframe()
* @brief Function @ref Magnum::Primitives::circle2DSolid(), @ref Magnum::Primitives::circle2DWireframe(), @ref Magnum::Primitives::circle3DSolid(), @ref Magnum::Primitives::circle3DWireframe()
*/
#include "Magnum/Primitives/visibility.h"
@ -43,7 +43,7 @@ namespace Magnum { namespace Primitives {
@param segments Number of segments. Must be greater or equal to @cpp 3 @ce.
Circle with radius @cpp 1.0f @ce. Non-indexed @ref MeshPrimitive::TriangleFan.
@see @ref circle2DWireframe()
@see @ref circle2DWireframe(), @ref circle3DSolid()
*/
MAGNUM_PRIMITIVES_EXPORT Trade::MeshData2D circle2DSolid(UnsignedInt segments);
@ -52,7 +52,7 @@ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData2D circle2DSolid(UnsignedInt segments);
@param segments Number of segments. Must be greater or equal to @cpp 3 @ce.
Circle with radius @cpp 1.0f @ce. Non-indexed @ref MeshPrimitive::LineLoop.
@see @ref circle2DSolid()
@see @ref circle2DSolid(), @ref circle3DWireframe()
*/
MAGNUM_PRIMITIVES_EXPORT Trade::MeshData2D circle2DWireframe(UnsignedInt segments);
@ -74,6 +74,26 @@ struct MAGNUM_PRIMITIVES_EXPORT Circle {
};
#endif
/**
@brief Solid 3D circle
@param segments Number of segments. Must be greater or equal to @cpp 3 @ce.
Circle on the XY plane with radius @cpp 1.0f @ce. Non-indexed
@ref MeshPrimitive::TriangleFan with normals in positive Z direction.
@see @ref circle3DWireframe(), @ref circle2DSolid()
*/
MAGNUM_PRIMITIVES_EXPORT Trade::MeshData3D circle3DSolid(UnsignedInt segments);
/**
@brief Wireframe 3D circle
@param segments Number of segments. Must be greater or equal to @cpp 3 @ce.
Circle on the XY plane with radius @cpp 1.0f @ce. Non-indexed
@ref MeshPrimitive::LineLoop.
@see @ref circle2DSolid(), @ref circle3DWireframe()
*/
MAGNUM_PRIMITIVES_EXPORT Trade::MeshData3D circle3DWireframe(UnsignedInt segments);
}}
#endif

59
src/Magnum/Primitives/Test/CircleTest.cpp

@ -26,25 +26,30 @@
#include <Corrade/TestSuite/Tester.h>
#include "Magnum/Mesh.h"
#include "Magnum/Math/Vector2.h"
#include "Magnum/Math/Vector3.h"
#include "Magnum/Primitives/Circle.h"
#include "Magnum/Trade/MeshData2D.h"
#include "Magnum/Trade/MeshData3D.h"
namespace Magnum { namespace Primitives { namespace Test {
struct CircleTest: TestSuite::Tester {
explicit CircleTest();
void solid();
void wireframe();
void solid2D();
void solid3D();
void wireframe2D();
void wireframe3D();
};
CircleTest::CircleTest() {
addTests({&CircleTest::solid,
&CircleTest::wireframe});
addTests({&CircleTest::solid2D,
&CircleTest::solid3D,
&CircleTest::wireframe2D,
&CircleTest::wireframe3D});
}
void CircleTest::solid() {
void CircleTest::solid2D() {
Trade::MeshData2D circle = Primitives::circle2DSolid(8);
CORRADE_VERIFY(!circle.isIndexed());
@ -59,7 +64,34 @@ void CircleTest::solid() {
}));
}
void CircleTest::wireframe() {
void CircleTest::solid3D() {
Trade::MeshData3D circle = Primitives::circle3DSolid(8);
CORRADE_VERIFY(!circle.isIndexed());
CORRADE_COMPARE(circle.primitive(), MeshPrimitive::TriangleFan);
CORRADE_COMPARE(circle.positions(0), (std::vector<Vector3>{
{ 0.0f, 0.0f, 0.0f},
{ 1.0f, 0.0f, 0.0f}, { Constants::sqrt2()/2.0f, Constants::sqrt2()/2.0f, 0.0f},
{ 0.0f, 1.0f, 0.0f}, {-Constants::sqrt2()/2.0f, Constants::sqrt2()/2.0f, 0.0f},
{-1.0f, 0.0f, 0.0f}, {-Constants::sqrt2()/2.0f, -Constants::sqrt2()/2.0f, 0.0f},
{ 0.0f, -1.0f, 0.0f}, { Constants::sqrt2()/2.0f, -Constants::sqrt2()/2.0f, 0.0f},
{ 1.0f, 0.0f, 0.0f}
}));
CORRADE_COMPARE(circle.normals(0), (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},
{ 0.0f, 0.0f, 1.0f},
{ 0.0f, 0.0f, 1.0f},
{ 0.0f, 0.0f, 1.0f},
{ 0.0f, 0.0f, 1.0f}
}));
}
void CircleTest::wireframe2D() {
Trade::MeshData2D circle = Primitives::circle2DWireframe(8);
CORRADE_VERIFY(!circle.isIndexed());
@ -72,6 +104,19 @@ void CircleTest::wireframe() {
}));
}
void CircleTest::wireframe3D() {
Trade::MeshData3D circle = Primitives::circle3DWireframe(8);
CORRADE_VERIFY(!circle.isIndexed());
CORRADE_COMPARE(circle.primitive(), MeshPrimitive::LineLoop);
CORRADE_COMPARE(circle.positions(0), (std::vector<Vector3>{
{ 1.0f, 0.0f, 0.0f}, { Constants::sqrt2()/2.0f, Constants::sqrt2()/2.0f, 0.0f},
{ 0.0f, 1.0f, 0.0f}, {-Constants::sqrt2()/2.0f, Constants::sqrt2()/2.0f, 0.0f},
{-1.0f, 0.0f, 0.0f}, {-Constants::sqrt2()/2.0f, -Constants::sqrt2()/2.0f, 0.0f},
{ 0.0f, -1.0f, 0.0f}, { Constants::sqrt2()/2.0f, -Constants::sqrt2()/2.0f, 0.0f}
}));
}
}}}
CORRADE_TEST_MAIN(Magnum::Primitives::Test::CircleTest)

Loading…
Cancel
Save