mirror of https://github.com/mosra/magnum.git
15 changed files with 407 additions and 12 deletions
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
@ -0,0 +1,73 @@
|
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 |
||||
Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#include "Cone.h" |
||||
|
||||
#include "Magnum/Mesh.h" |
||||
#include "Magnum/Math/Color.h" |
||||
#include "Magnum/Primitives/Implementation/Spheroid.h" |
||||
#include "Magnum/Primitives/Implementation/WireframeSpheroid.h" |
||||
#include "Magnum/Trade/MeshData3D.h" |
||||
|
||||
namespace Magnum { namespace Primitives { |
||||
|
||||
Trade::MeshData3D coneSolid(const UnsignedInt rings, const UnsignedInt segments, const Float halfLength, const ConeFlags flags) { |
||||
CORRADE_ASSERT(rings >= 1 && segments >= 3, |
||||
"Primitives::coneSolid(): at least one ring and three segments expected", |
||||
(Trade::MeshData3D{MeshPrimitive::Triangles, {}, {}, {}, {}, {}, nullptr})); |
||||
|
||||
Implementation::Spheroid cone{segments, flags & ConeFlag::GenerateTextureCoords ? Implementation::Spheroid::TextureCoords::Generate : Implementation::Spheroid::TextureCoords::DontGenerate}; |
||||
|
||||
const Float length = 2.0f*halfLength; |
||||
const Float textureCoordsV = flags & ConeFlag::CapEnd ? 1.0f/(length + 1.0f) : 0.0f; |
||||
|
||||
/* Bottom cap */ |
||||
if(flags & ConeFlag::CapEnd) { |
||||
cone.capVertex(-halfLength, -1.0f, 0.0f); |
||||
cone.capVertexRing(-halfLength, textureCoordsV, Vector3::yAxis(-1.0f)); |
||||
} |
||||
|
||||
/* Vertex rings */ |
||||
cone.cylinderVertexRings(rings+1, -halfLength, {-1.0f/rings, length/rings}, textureCoordsV, length/(rings*(flags & ConeFlag::CapEnd ? length + 1.0f : length))); |
||||
|
||||
/* Faces */ |
||||
if(flags & ConeFlag::CapEnd) cone.bottomFaceRing(); |
||||
cone.faceRings(rings, flags & ConeFlag::CapEnd ? (1 + segments) : 0); |
||||
|
||||
return cone.finalize(); |
||||
} |
||||
|
||||
Trade::MeshData3D coneWireframe(const UnsignedInt segments, const Float halfLength) { |
||||
CORRADE_ASSERT(segments >= 4 && segments%4 == 0, |
||||
"Primitives::cylinderWireframe(): multiples of 4 segments expected", |
||||
(Trade::MeshData3D{MeshPrimitive::Lines, {}, {}, {}, {}, {}, nullptr})); |
||||
|
||||
Implementation::WireframeSpheroid cone{segments/4}; |
||||
cone.ring(-halfLength); |
||||
cone.topHemisphere(halfLength - 1.0f, 1); |
||||
return cone.finalize(); |
||||
} |
||||
|
||||
}} |
||||
@ -0,0 +1,100 @@
|
||||
#ifndef Magnum_Primitives_Cone_h |
||||
#define Magnum_Primitives_Cone_h |
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 |
||||
Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
/** @file
|
||||
* @brief Function @ref Magnum::Primitives::coneSolid(), @ref Magnum::Primitives::coneWireframe() |
||||
*/ |
||||
|
||||
#include <Corrade/Containers/EnumSet.h> |
||||
|
||||
#include "Magnum/Magnum.h" |
||||
#include "Magnum/Primitives/visibility.h" |
||||
#include "Magnum/Trade/Trade.h" |
||||
|
||||
namespace Magnum { namespace Primitives { |
||||
|
||||
/**
|
||||
@brief Cone flag |
||||
|
||||
@see @ref ConeFlags, @ref coneSolid() |
||||
*/ |
||||
enum class ConeFlag { |
||||
GenerateTextureCoords = 1 << 0, /**< Generate texture coordinates */ |
||||
CapEnd = 1 << 1 /**< Cap end */ |
||||
}; |
||||
|
||||
/**
|
||||
@brief Cone flags |
||||
|
||||
@see @ref coneSolid() |
||||
*/ |
||||
typedef Containers::EnumSet<ConeFlag> ConeFlags; |
||||
|
||||
CORRADE_ENUMSET_OPERATORS(ConeFlags) |
||||
|
||||
/**
|
||||
@brief Solid 3D cone |
||||
@param rings Number of (face) rings. Must be larger or equal to |
||||
@cpp 1 @ce. |
||||
@param segments Number of (face) segments. Must be larger or equal to |
||||
@cpp 3 @ce. |
||||
@param halfLength Half the cone length |
||||
@param flags Flags |
||||
|
||||
Cone along Y axis of radius @cpp 1.0f @ce. Indexed |
||||
@ref MeshPrimitive::Triangles. Note that in order to have properly smooth |
||||
normals over the whole area, the tip consists of @cpp segments*2 @ce vertices |
||||
instead of just one. |
||||
|
||||
@image html primitives-conesolid.png |
||||
|
||||
The cone is by default created with radius set to @f$ 1.0 @f$. In order to get |
||||
radius @f$ r @f$, length @f$ l @f$ and preserve correct normals, set |
||||
@p halfLength to @f$ 0.5 \frac{l}{r} @f$ and then scale all |
||||
@ref Trade::MeshData3D::positions() by @f$ r @f$, for example using |
||||
@ref MeshTools::transformPointsInPlace(). |
||||
@see @ref coneWireframe(), @ref cylinderSolid() |
||||
*/ |
||||
MAGNUM_PRIMITIVES_EXPORT Trade::MeshData3D coneSolid(UnsignedInt rings, UnsignedInt segments, Float halfLength, ConeFlags flags = {}); |
||||
|
||||
/**
|
||||
@brief Wireframe 3D cone |
||||
@param segments Number of (line) segments. Must be larger or equal to |
||||
@cpp 4 @ce and multiple of @cpp 4 @ce. |
||||
@param halfLength Half the cone length |
||||
|
||||
Cone along Y axis of radius @cpp 1.0f @ce. Indexed @ref MeshPrimitive::Lines. |
||||
|
||||
@image html primitives-conewireframe.png |
||||
|
||||
@see @ref coneSolid(), @ref cylinderWireframe() |
||||
*/ |
||||
MAGNUM_PRIMITIVES_EXPORT Trade::MeshData3D coneWireframe(UnsignedInt segments, Float halfLength); |
||||
|
||||
}} |
||||
|
||||
#endif |
||||
@ -0,0 +1,200 @@
|
||||
/*
|
||||
This file is part of Magnum. |
||||
|
||||
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 |
||||
Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a |
||||
copy of this software and associated documentation files (the "Software"), |
||||
to deal in the Software without restriction, including without limitation |
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||||
and/or sell copies of the Software, and to permit persons to whom the |
||||
Software is furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included |
||||
in all copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||
DEALINGS IN THE SOFTWARE. |
||||
*/ |
||||
|
||||
#include <Corrade/TestSuite/Tester.h> |
||||
#include <Corrade/TestSuite/Compare/Container.h> |
||||
|
||||
#include "Magnum/Math/Vector3.h" |
||||
#include "Magnum/Primitives/Cone.h" |
||||
#include "Magnum/Trade/MeshData3D.h" |
||||
|
||||
namespace Magnum { namespace Primitives { namespace Test { |
||||
|
||||
struct ConeTest: TestSuite::Tester { |
||||
explicit ConeTest(); |
||||
|
||||
void solidWithoutAnything(); |
||||
void solidWithTextureCoordsAndCaps(); |
||||
void wireframe(); |
||||
}; |
||||
|
||||
ConeTest::ConeTest() { |
||||
addTests({&ConeTest::solidWithoutAnything, |
||||
&ConeTest::solidWithTextureCoordsAndCaps, |
||||
&ConeTest::wireframe}); |
||||
} |
||||
|
||||
void ConeTest::solidWithoutAnything() { |
||||
Trade::MeshData3D cone = coneSolid(2, 3, 1.0f); |
||||
|
||||
CORRADE_COMPARE_AS(cone.positions(0), (std::vector<Vector3>{ |
||||
{0.0f, -1.0f, 1.0f}, |
||||
{0.866025f, -1.0f, -0.5f}, |
||||
{-0.866025f, -1.0f, -0.5f}, |
||||
|
||||
{0.0f, 0.0f, 0.5f}, |
||||
{0.433013f, 0.0f, -0.25f}, |
||||
{-0.433013f, 0.0f, -0.25f}, |
||||
|
||||
{0.0f, 1.0f, 0.0f}, |
||||
{0.0f, 1.0f, 0.0f}, |
||||
{0.0f, 1.0f, 0.0f} |
||||
}), TestSuite::Compare::Container); |
||||
|
||||
CORRADE_COMPARE_AS(cone.normals(0), (std::vector<Vector3>{ |
||||
{0.0f, 0.447214f, 0.894427f}, |
||||
{0.774597f, 0.447214f, -0.447214f}, |
||||
{-0.774597f, 0.447214f, -0.447214f}, |
||||
|
||||
{0.0f, 0.447214f, 0.894427f}, |
||||
{0.774597f, 0.447214f, -0.447214f}, |
||||
{-0.774597f, 0.447214f, -0.447214f}, |
||||
|
||||
{0.0f, 0.447214f, 0.894427f}, |
||||
{0.774597f, 0.447214f, -0.447214f}, |
||||
{-0.774597f, 0.447214f, -0.447214f} |
||||
}), TestSuite::Compare::Container); |
||||
|
||||
CORRADE_COMPARE_AS(cone.indices(), (std::vector<UnsignedInt>{ |
||||
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); |
||||
} |
||||
|
||||
void ConeTest::solidWithTextureCoordsAndCaps() { |
||||
Trade::MeshData3D cone = coneSolid(2, 3, 1.0f, ConeFlag::GenerateTextureCoords|ConeFlag::CapEnd); |
||||
|
||||
/* Bottom ring duplicated because it has different normals, first vertex of
|
||||
each ring duplicated because it has different texture coordinates */ |
||||
CORRADE_COMPARE_AS(cone.positions(0), (std::vector<Vector3>{ |
||||
{0.0f, -1.0f, 0.0f}, |
||||
|
||||
{0.0f, -1.0f, 1.0f}, |
||||
{0.866025f, -1.0f, -0.5f}, |
||||
{-0.866025f, -1.0f, -0.5f}, |
||||
{0.0f, -1.0f, 1.0f}, |
||||
|
||||
{0.0f, -1.0f, 1.0f}, |
||||
{0.866025f, -1.0f, -0.5f}, |
||||
{-0.866025f, -1.0f, -0.5f}, |
||||
{0.0f, -1.0f, 1.0f}, |
||||
|
||||
{0.0f, 0.0f, 0.5f}, |
||||
{0.433013f, 0.0f, -0.25f}, |
||||
{-0.433013f, 0.0f, -0.25f}, |
||||
{0.0f, 0.0f, 0.5f}, |
||||
|
||||
{0.0f, 1.0f, 0.0f}, |
||||
{0.0f, 1.0f, 0.0f}, |
||||
{0.0f, 1.0f, 0.0f}, |
||||
{0.0f, 1.0f, 0.0f} |
||||
}), TestSuite::Compare::Container); |
||||
|
||||
CORRADE_COMPARE_AS(cone.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}, |
||||
{0.0f, -1.0f, 0.0f}, |
||||
|
||||
{0.0f, 0.447214f, 0.894427f}, |
||||
{0.774597f, 0.447214f, -0.447214f}, |
||||
{-0.774597f, 0.447214f, -0.447214f}, |
||||
{0.0f, 0.447214f, 0.894427f}, |
||||
|
||||
{0.0f, 0.447214f, 0.894427f}, |
||||
{0.774597f, 0.447214f, -0.447214f}, |
||||
{-0.774597f, 0.447214f, -0.447214f}, |
||||
{0.0f, 0.447214f, 0.894427f}, |
||||
|
||||
{0.0f, 0.447214f, 0.894427f}, |
||||
{0.774597f, 0.447214f, -0.447214f}, |
||||
{-0.774597f, 0.447214f, -0.447214f}, |
||||
{0.0f, 0.447214f, 0.894427f} |
||||
}), TestSuite::Compare::Container); |
||||
|
||||
CORRADE_COMPARE_AS(cone.textureCoords2D(0), (std::vector<Vector2>{ |
||||
{0.5f, 0.0f}, |
||||
|
||||
{0.0f, 0.333333f}, |
||||
{0.333333f, 0.333333f}, |
||||
{0.666667f, 0.333333f}, |
||||
{1.0f, 0.333333f}, |
||||
|
||||
{0.0f, 0.333333f}, |
||||
{0.333333f, 0.333333f}, |
||||
{0.666667f, 0.333333f}, |
||||
{1.0f, 0.333333f}, |
||||
|
||||
{0.0f, 0.666667f}, |
||||
{0.333333f, 0.666667f}, |
||||
{0.666667f, 0.666667f}, |
||||
{1.0f, 0.666667f}, |
||||
|
||||
{0.0f, 1.0f}, |
||||
{0.333333f, 1.0f}, |
||||
{0.666667f, 1.0f}, |
||||
{1.0f, 1.0f}, |
||||
}), TestSuite::Compare::Container); |
||||
|
||||
/* Faces of the caps and sides do not share any vertices due to different
|
||||
normals */ |
||||
CORRADE_COMPARE_AS(cone.indices(), (std::vector<UnsignedInt>{ |
||||
0, 2, 1, 0, 3, 2, 0, 4, 3, |
||||
4, 5, 9, 4, 9, 8, 5, 6, 10, 5, 10, 9, 6, 7, 11, 6, 11, 10, |
||||
8, 9, 13, 8, 13, 12, 9, 10, 14, 9, 14, 13, 10, 11, 15, 10, 15, 14 |
||||
}), TestSuite::Compare::Container); |
||||
} |
||||
|
||||
void ConeTest::wireframe() { |
||||
Trade::MeshData3D cone = coneWireframe(8, 1.5f); |
||||
|
||||
CORRADE_COMPARE_AS(cone.positions(0), (std::vector<Vector3>{ |
||||
{0.0f, -1.5f, 1.0f}, |
||||
{1.0f, -1.5f, 0.0f}, |
||||
{0.0f, -1.5f, -1.0f}, |
||||
{-1.0f, -1.5f, 0.0f}, |
||||
{0.707107f, -1.5f, 0.707107f}, |
||||
{0.707107f, -1.5f, -0.707107f}, |
||||
{-0.707107f, -1.5f, -0.707107f}, |
||||
{-0.707107f, -1.5f, 0.707107f}, |
||||
|
||||
{0.0f, 1.5f, 0.0f} |
||||
}), TestSuite::Compare::Container); |
||||
|
||||
CORRADE_COMPARE(cone.normalArrayCount(), 0); |
||||
|
||||
CORRADE_COMPARE_AS(cone.indices(), (std::vector<UnsignedInt>{ |
||||
0, 4, 1, 5, 2, 6, 3, 7, |
||||
4, 1, 5, 2, 6, 3, 7, 0, |
||||
|
||||
0, 8, 1, 8, 2, 8, 3, 8 |
||||
}), TestSuite::Compare::Container); |
||||
} |
||||
|
||||
}}} |
||||
|
||||
CORRADE_TEST_MAIN(Magnum::Primitives::Test::ConeTest) |
||||
Loading…
Reference in new issue