Files
j3ml/include/J3ML/Geometry/Icosahedron.hpp
josh bf794ce092
All checks were successful
Run ReCI Build Test / Explore-Gitea-Actions (push) Successful in 1m37s
Build Docs With Doxygen / Explore-Gitea-Actions (push) Successful in 29s
Sending up work
2024-10-23 14:16:41 -04:00

109 lines
4.0 KiB
C++

/// Josh's 3D Math Library
/// A C++20 Library for 3D Math, Computer Graphics, and Scientific Computing.
/// Developed and Maintained by Josh O'Leary @ Redacted Software.
/// Special Thanks to William Tomasine II and Maxine Hayes.
/// (c) 2024 Redacted Software
/// This work is dedicated to the public domain.
/// @file Icosahedron.hpp
/// @desc Icosahedron class implementation, borrowed from http://www.songho.ca/opengl/gl_sphere.html#icosphere
/// @edit 2024-10-22
/** Polyhedron with 12 vertices, 30 edges, and 20 faces (triangles) for OpenGL
If the radius is r, then the length of the edge is (r / sin(2pi/5))
Vertices of icosahedron are constructed with spherical coords by aligning
the north pole to (0,0,r) and the south pole to (0,0,-r). Other 10 vertices
are computed by rotating 72 degrees along y-axis at the elevation angle
+/- 26.565 (=arctan(1/2)).
The unwrapped (paper model) of icosahedron and texture map look like this:
// (S,0) 3S 5S 7S 9S
// /\ /\ /\ /\ /\ : 1st row (5 triangles) //
// /__\/__\/__\/__\/__\ //
// T \ /\ /\ /\ /\ /\ : 2nd row (10 triangles) //
// \/__\/__\/__\/__\/__\ //
// 2T \ /\ /\ /\ /\ / : 3rd row (5 triangles) //
// \/ \/ \/ \/ \/ //
// 2S 4S 6S 8S (10S,3T)
// where S = 186/2048 = 0.0908203
// T = 322/1024 = 0.3144531
// If a texture size is 2048x1024, S=186, T=322
AUTHOR: Song Ho Ahn (song.ahn@gmail.com)
*/
#include <vector>
#include "Color4.hpp"
#pragma once
namespace J3ML
{
class Icosahedron
{
public:
float radius;
float edgeLength;
Icosahedron(float radius = 1.0f);
float Radius() const { return radius; }
void Radius(float new_radius) {radius = new_radius;}
float EdgeLength() const { return edgeLength;}
void EdgeLength(float new_edge_length) { edgeLength = new_edge_length;}
// for vertex data
unsigned int VertexCount() const;
unsigned int NormalCount() const;
unsigned int TexCoordCount() const;
unsigned int IndexCount() const;
unsigned int LineIndexCount() const;
unsigned int TriangleCount() const;
unsigned int VertexSize() const;
unsigned int NormalSize() const;
unsigned int TexCoordSize() const;
unsigned int IndexSize() const;
unsigned int LineIndexSize() const;
const float* Vertices() const;
const float* Normals() const;
const float* TexCoords() const;
const unsigned int* Indices() const;
const unsigned int* LineIndices() const;
// for interleaved vertices: V/N/T
unsigned int InterleavedVertexCount() const;
unsigned int InterleavedVertexSize() const;
int InterleavedStride() const;
const float* InterleavedVertices() const;
// draw in VertexArray mode
void draw() const;
void drawLines(const Color4& lineColor) const;
void drawWithLines(const Color4& lineColor) const;
protected:
private:
// static functions
static void computeFaceNormal(float v1[3], float v2[3], float v3[3], float n[3]);
// member functions
void updateRadius();
std::vector<float> computeVertices();
void buildVertices();
void buildInterleavedVertices();
void addVertices(float v1[3], float v2[3], float v3[3]);
void addNormals(float n1[3], float n2[3], float n3[3]);
void addTexCoords(float t1[2], float t2[2], float t3[2]);
void addIndices(unsigned int i1, unsigned int i2, unsigned int i3);
void addLineIndices(unsigned int indexFrom);
// member vars
//float radius;
//float edgeLength;
std::vector<float> vertices;
std::vector<float> normals;
std::vector<float> texCoords;
std::vector<unsigned int> indices;
std::vector<unsigned int> lineIndices;
};
}