mirror of https://github.com/mosra/magnum.git
8 changed files with 349 additions and 4 deletions
@ -0,0 +1,69 @@
|
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
#include "Cylinder.h" |
||||
|
||||
using namespace std; |
||||
|
||||
namespace Magnum { namespace Primitives { |
||||
|
||||
Cylinder::Cylinder(unsigned int rings, unsigned int segments, GLfloat length, Flags flags): Capsule(segments, flags & Flag::GenerateTextureCoords ? TextureCoords::Generate : TextureCoords::DontGenerate) { |
||||
CORRADE_ASSERT(rings >= 1 && segments >= 3, "Cylinder must have at least one ring and three segments", ); |
||||
|
||||
GLfloat y = length*0.5f; |
||||
GLfloat textureCoordsV = flags & Flag::CapEnds ? 1.0f/(length+2.0f) : 0.0f; |
||||
|
||||
/* Bottom cap */ |
||||
if(flags & Flag::CapEnds) { |
||||
capVertex(-y, -1.0f, 0.0f); |
||||
capVertexRing(-y, textureCoordsV, Vector3::yAxis(-1.0f)); |
||||
} |
||||
|
||||
/* Vertex rings */ |
||||
cylinderVertexRings(rings+1, -y, length/rings, textureCoordsV, length/(rings*(flags & Flag::CapEnds ? length + 2.0f : length))); |
||||
|
||||
/* Top cap */ |
||||
if(flags & Flag::CapEnds) { |
||||
capVertexRing(y, 1.0f - textureCoordsV, Vector3::yAxis(1.0f)); |
||||
capVertex(y, 1.0f, 1.0f); |
||||
} |
||||
|
||||
/* Faces */ |
||||
if(flags & Flag::CapEnds) bottomFaceRing(); |
||||
faceRings(rings, flags & Flag::CapEnds ? 1 : 0); |
||||
if(flags & Flag::CapEnds) topFaceRing(); |
||||
} |
||||
|
||||
void Cylinder::capVertexRing(GLfloat y, GLfloat textureCoordsV, const Vector3& normal) { |
||||
GLfloat segmentAngleIncrement = 2*Math::Constants<GLfloat>::pi()/segments; |
||||
|
||||
for(unsigned int i = 0; i != segments; ++i) { |
||||
GLfloat segmentAngle = i*segmentAngleIncrement; |
||||
positions(0)->push_back({sin(segmentAngle), y, cos(segmentAngle)}); |
||||
normals(0)->push_back(normal); |
||||
|
||||
if(textureCoords == TextureCoords::Generate) |
||||
textureCoords2D(0)->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}); |
||||
} |
||||
} |
||||
|
||||
}} |
||||
@ -0,0 +1,65 @@
|
||||
#ifndef Magnum_Primitives_Cylinder_h |
||||
#define Magnum_Primitives_Cylinder_h |
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
/** @file
|
||||
* @brief Class Magnum::Primitives::UVSphere |
||||
*/ |
||||
|
||||
#include "Primitives/Capsule.h" |
||||
#include <Containers/EnumSet.h> |
||||
|
||||
namespace Magnum { namespace Primitives { |
||||
|
||||
/** @brief Cylinder primitive */ |
||||
class Cylinder: public Capsule { |
||||
public: |
||||
/**
|
||||
* @brief %Flags |
||||
* |
||||
* @see Flags, Cylinder() |
||||
*/ |
||||
enum class Flag { |
||||
GenerateTextureCoords = 1, /**< @brief Generate texture coordinates */ |
||||
CapEnds /**< @brief Cap ends */ |
||||
}; |
||||
|
||||
/** @brief %Flags */ |
||||
typedef Corrade::Containers::EnumSet<Flag, int> Flags; |
||||
|
||||
/**
|
||||
* @brief Constructor |
||||
* @param rings Number of (face) rings. Must be larger or |
||||
* equal to 1. |
||||
* @param segments Number of (face) segments. Must be larger or |
||||
* equal to 3. |
||||
* @param length Cylinder length |
||||
* @param flags Flags |
||||
* |
||||
* If texture coordinates are generated, vertices of one segment are |
||||
* duplicated for texture wrapping. |
||||
*/ |
||||
Cylinder(unsigned int rings, unsigned int segments, GLfloat length, Flags flags = Flags()); |
||||
|
||||
private: |
||||
void capVertexRing(GLfloat y, GLfloat textureCoordsV, const Vector3& normal); |
||||
}; |
||||
|
||||
CORRADE_ENUMSET_OPERATORS(Cylinder::Flags) |
||||
|
||||
}} |
||||
|
||||
#endif |
||||
@ -1,2 +1,3 @@
|
||||
corrade_add_test2(PrimitivesCapsuleTest CapsuleTest.cpp LIBRARIES MagnumPrimitives) |
||||
corrade_add_test2(PrimitivesUVSphereTest UVSphereTest.cpp LIBRARIES MagnumPrimitives) |
||||
corrade_add_test2(PrimitivesCylinderTest CylinderTest.cpp LIBRARIES MagnumPrimitives) |
||||
|
||||
@ -0,0 +1,175 @@
|
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
#include "CylinderTest.h" |
||||
|
||||
#include <TestSuite/Compare/Container.h> |
||||
|
||||
#include "Primitives/Cylinder.h" |
||||
|
||||
using namespace std; |
||||
using Corrade::TestSuite::Compare::Container; |
||||
|
||||
CORRADE_TEST_MAIN(Magnum::Primitives::Test::CylinderTest) |
||||
|
||||
namespace Magnum { namespace Primitives { namespace Test { |
||||
|
||||
CylinderTest::CylinderTest() { |
||||
addTests(&CylinderTest::withoutAnything, |
||||
&CylinderTest::withTextureCoordsAndCaps); |
||||
} |
||||
|
||||
void CylinderTest::withoutAnything() { |
||||
Cylinder cylinder(2, 3, 3.0f); |
||||
|
||||
CORRADE_COMPARE_AS(*cylinder.positions(0), (vector<Vector4>{ |
||||
{0.0f, -1.5f, 1.0f}, |
||||
{0.866025f, -1.5f, -0.5f}, |
||||
{-0.866025f, -1.5f, -0.5f}, |
||||
|
||||
{0.0f, 0.0f, 1.0f}, |
||||
{0.866025f, 0.0f, -0.5f}, |
||||
{-0.866025f, 0.0f, -0.5f}, |
||||
|
||||
{0.0f, 1.5f, 1.0f}, |
||||
{0.866025f, 1.5f, -0.5f}, |
||||
{-0.866025f, 1.5f, -0.5f} |
||||
}), Container); |
||||
|
||||
CORRADE_COMPARE_AS(*cylinder.normals(0), (vector<Vector3>{ |
||||
{0.0f, 0.0f, 1.0f}, |
||||
{0.866025f, 0.0f, -0.5f}, |
||||
{-0.866025f, 0.0f, -0.5f}, |
||||
|
||||
{0.0f, 0.0f, 1.0f}, |
||||
{0.866025f, 0.0f, -0.5f}, |
||||
{-0.866025f, 0.0f, -0.5f}, |
||||
|
||||
{0.0f, 0.0f, 1.0f}, |
||||
{0.866025f, 0.0f, -0.5f}, |
||||
{-0.866025f, 0.0f, -0.5f} |
||||
}), Container); |
||||
|
||||
CORRADE_COMPARE_AS(*cylinder.indices(), (vector<unsigned int>{ |
||||
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 |
||||
}), Container); |
||||
} |
||||
|
||||
void CylinderTest::withTextureCoordsAndCaps() { |
||||
Cylinder cylinder(2, 3, 3.0f, Cylinder::Flag::GenerateTextureCoords|Cylinder::Flag::CapEnds); |
||||
|
||||
CORRADE_COMPARE_AS(*cylinder.positions(0), (vector<Vector4>{ |
||||
{0.0f, -1.5f, 0.0f}, |
||||
|
||||
{0.0f, -1.5f, 1.0f}, |
||||
{0.866025f, -1.5f, -0.5f}, |
||||
{-0.866025f, -1.5f, -0.5f}, |
||||
{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.0f, -1.5f, 1.0f}, |
||||
|
||||
{0.0f, 0.0f, 1.0f}, |
||||
{0.866025f, 0.0f, -0.5f}, |
||||
{-0.866025f, 0.0f, -0.5f}, |
||||
{0.0f, 0.0f, 1.0f}, |
||||
|
||||
{0.0f, 1.5f, 1.0f}, |
||||
{0.866025f, 1.5f, -0.5f}, |
||||
{-0.866025f, 1.5f, -0.5f}, |
||||
{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.0f, 1.5f, 1.0f}, |
||||
|
||||
{0.0f, 1.5f, 0.0f} |
||||
}), Container); |
||||
|
||||
CORRADE_COMPARE_AS(*cylinder.normals(0), (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.0f, 1.0f}, |
||||
{0.866025f, 0.0f, -0.5f}, |
||||
{-0.866025f, 0.0f, -0.5f}, |
||||
{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.0f, 0.0f, 1.0f}, |
||||
|
||||
{0.0f, 0.0f, 1.0f}, |
||||
{0.866025f, 0.0f, -0.5f}, |
||||
{-0.866025f, 0.0f, -0.5f}, |
||||
{0.0f, 0.0f, 1.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}, |
||||
}), Container); |
||||
|
||||
CORRADE_COMPARE_AS(*cylinder.textureCoords2D(0), (vector<Vector2>{ |
||||
{0.5f, 0.0f}, |
||||
|
||||
{0.0f, 0.2f}, |
||||
{0.333333f, 0.2f}, |
||||
{0.666667f, 0.2f}, |
||||
{1.0f, 0.2f}, |
||||
|
||||
{0.0f, 0.2f}, |
||||
{0.333333f, 0.2f}, |
||||
{0.666667f, 0.2f}, |
||||
{1.0f, 0.2f}, |
||||
|
||||
{0.0f, 0.5f}, |
||||
{0.333333f, 0.5f}, |
||||
{0.666667f, 0.5f}, |
||||
{1.0f, 0.5f}, |
||||
|
||||
{0.0f, 0.8f}, |
||||
{0.333333f, 0.8f}, |
||||
{0.666667f, 0.8f}, |
||||
{1.0f, 0.8f}, |
||||
|
||||
{0.0f, 0.8f}, |
||||
{0.333333f, 0.8f}, |
||||
{0.666667f, 0.8f}, |
||||
{1.0f, 0.8f}, |
||||
|
||||
{0.5f, 1.0f} |
||||
}), Container); |
||||
|
||||
CORRADE_COMPARE_AS(*cylinder.indices(), (vector<unsigned int>{ |
||||
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, 17, 18, 21, 18, 19, 21, 19, 20, 21 |
||||
}), Container); |
||||
} |
||||
|
||||
}}} |
||||
@ -0,0 +1,32 @@
|
||||
#ifndef Magnum_Primitives_Test_CylinderTest_h |
||||
#define Magnum_Primitives_Test_CylinderTest_h |
||||
/*
|
||||
Copyright © 2010, 2011, 2012 Vladimír Vondruš <mosra@centrum.cz> |
||||
|
||||
This file is part of Magnum. |
||||
|
||||
Magnum is free software: you can redistribute it and/or modify |
||||
it under the terms of the GNU Lesser General Public License version 3 |
||||
only, as published by the Free Software Foundation. |
||||
|
||||
Magnum is distributed in the hope that it will be useful, |
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
GNU Lesser General Public License version 3 for more details. |
||||
*/ |
||||
|
||||
#include <TestSuite/Tester.h> |
||||
|
||||
namespace Magnum { namespace Primitives { namespace Test { |
||||
|
||||
class CylinderTest: public Corrade::TestSuite::Tester<CylinderTest> { |
||||
public: |
||||
CylinderTest(); |
||||
|
||||
void withoutAnything(); |
||||
void withTextureCoordsAndCaps(); |
||||
}; |
||||
|
||||
}}} |
||||
|
||||
#endif |
||||
Loading…
Reference in new issue