Browse Source

Added Icosphere primitive.

Templated on subdivision count, so it is for given subdivision computed
only once.
vectorfields
Vladimír Vondruš 15 years ago
parent
commit
e9a16b1824
  1. 1
      src/Primitives/CMakeLists.txt
  2. 64
      src/Primitives/Icosphere.cpp
  3. 79
      src/Primitives/Icosphere.h

1
src/Primitives/CMakeLists.txt

@ -1,5 +1,6 @@
set(MagnumPrimitives_SRCS set(MagnumPrimitives_SRCS
Cube.cpp Cube.cpp
Icosphere.cpp
) )
add_library(MagnumPrimitives STATIC ${MagnumPrimitives_SRCS}) add_library(MagnumPrimitives STATIC ${MagnumPrimitives_SRCS})

64
src/Primitives/Icosphere.cpp

@ -0,0 +1,64 @@
/*
Copyright © 2010, 2011 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 "Icosphere.h"
namespace Magnum { namespace Primitives {
/**
* @todo Use own computed (and more precise) icosahedron data, not these stolen
* from Blender.
*/
#ifndef DOXYGEN_GENERATING_OUTPUT
const Vector4 _AbstractIcosphere::initialVertices[] = {
Vector4(0, -0.525731f, 0.850651f),
Vector4(0.850651f, 0, 0.525731f),
Vector4(0.850651f, 0, -0.525731f),
Vector4(-0.850651f, 0, -0.525731f),
Vector4(-0.850651f, 0, 0.525731f),
Vector4(-0.525731f, 0.850651f, 0),
Vector4(0.525731f, 0.850651f, 0),
Vector4(0.525731f, -0.850651f, 0),
Vector4(-0.525731f, -0.850651f, 0),
Vector4(0, -0.525731f, -0.850651f),
Vector4(0, 0.525731f, -0.850651f),
Vector4(0, 0.525731f, 0.850651f),
};
const GLubyte _AbstractIcosphere::initialIndices[] = {
1, 2, 6,
1, 7, 2,
3, 4, 5,
4, 3, 8,
6, 5, 11,
5, 6, 10,
9, 10, 2,
10, 9, 3,
7, 8, 9,
8, 7, 0,
11, 0, 1,
0, 11, 4,
6, 2, 10,
1, 6, 11,
3, 5, 10,
5, 4, 11,
2, 7, 9,
7, 1, 0,
3, 9, 8,
4, 8, 0
};
#endif
}}

79
src/Primitives/Icosphere.h

@ -0,0 +1,79 @@
#ifndef Magnum_Primitives_Icosphere_h
#define Magnum_Primitives_Icosphere_h
/*
Copyright © 2010, 2011 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::Icosphere
*/
#include "AbstractPrimitive.h"
#include "MeshBuilder.h"
#include "SizeTraits.h"
namespace Magnum { namespace Primitives {
#ifndef DOXYGEN_GENERATING_OUTPUT
class _AbstractIcosphere {
public:
~_AbstractIcosphere() {}
protected:
static const Vector4 initialVertices[];
static const GLubyte initialIndices[];
};
#endif
/**
* @brief Icosphere primitive
* @tparam subdivisions Number of subdivisions
*/
template<size_t subdivisions> class Icosphere: public AbstractPrimitive<typename SizeTraits<Log<256, Pow<4, subdivisions>::value*20*3>::value>::SizeType>, _AbstractIcosphere {
public:
Icosphere() {
if(vertexCount() == 0) subdivide();
}
inline Mesh::Primitive primitive() const { return Mesh::Triangles; }
inline size_t vertexCount() const { return builder()->vertexCount(); }
inline size_t indexCount() const { return builder()->faceCount()*3; }
inline void build(IndexedMesh* mesh, Buffer* vertexBuffer) {
/* mesh is prepared by the builder, no need to call prepareMesh */
builder()->build(mesh, vertexBuffer, Buffer::DrawStatic, Buffer::DrawStatic);
}
private:
static MeshBuilder<Vector4>* builder() {
static MeshBuilder<Vector4>* _builder = nullptr;
if(!_builder) _builder = new MeshBuilder<Vector4>();
return _builder;
}
static void subdivide() {
builder()->setData(initialVertices, initialIndices, 12, 60);
for(size_t i = 0; i != subdivisions; ++i)
builder()->subdivide([](const Vector4& a, const Vector4& b) {
return (a+b).xyz().normalized();
});
if(subdivisions) builder()->cleanMesh();
}
};
}}
#endif
Loading…
Cancel
Save