ADD: SphereFactory

This commit is contained in:
sebastian 2026-08-04 14:42:57 +02:00
parent 6ee58d4901
commit 023016c6a2
2 changed files with 84 additions and 0 deletions

View File

@ -0,0 +1,67 @@
//
// Created by sebastian on 04.08.26.
//
#include "SphereFactory.h"
#include <cmath>
#include <vector>
#include "utils/openglWrapper/openglObjects/Vao.h"
std::shared_ptr<engine::Model> engine::SphereFactory::createUVSphere(float radius, int sectorCount, int stackCount) {
constexpr float PI = 3.14159265358979323846f;
// Vertices: (stackCount + 1) Ringe entlang der Breitengrade, je (sectorCount + 1) Punkte
// entlang der Längengrade (der letzte Punkt dupliziert den ersten, damit das Index-Gitter
// pro Segment gleichförmig bleibt).
std::vector<float> vertices;
vertices.reserve(static_cast<std::size_t>(stackCount + 1) * (sectorCount + 1) * 3);
for (int i = 0; i <= stackCount; ++i) {
const float stackAngle = PI / 2.0f - static_cast<float>(i) * PI / static_cast<float>(stackCount); // +pi/2 .. -pi/2
const float xy = radius * std::cos(stackAngle);
const float z = radius * std::sin(stackAngle);
for (int j = 0; j <= sectorCount; ++j) {
const float sectorAngle = static_cast<float>(j) * 2.0f * PI / static_cast<float>(sectorCount); // 0 .. 2pi
vertices.push_back(xy * std::cos(sectorAngle)); // x
vertices.push_back(xy * std::sin(sectorAngle)); // y
vertices.push_back(z); // z
}
}
// Indices: zwei Dreiecke pro Gitterzelle; die Kappen am Pol lassen das jeweils
// entartete Dreieck aus.
std::vector<unsigned int> indices;
indices.reserve(static_cast<std::size_t>(stackCount) * sectorCount * 6);
for (int i = 0; i < stackCount; ++i) {
unsigned int k1 = static_cast<unsigned int>(i * (sectorCount + 1)); // Anfang des aktuellen Rings
unsigned int k2 = k1 + static_cast<unsigned int>(sectorCount + 1); // Anfang des nächsten Rings
for (int j = 0; j < sectorCount; ++j, ++k1, ++k2) {
if (i != 0) {
indices.push_back(k1);
indices.push_back(k2);
indices.push_back(k1 + 1);
}
if (i != stackCount - 1) {
indices.push_back(k1 + 1);
indices.push_back(k2);
indices.push_back(k2 + 1);
}
}
}
auto vao = Vao::create();
std::vector<std::unique_ptr<Attribute>> attribs;
attribs.push_back(std::make_unique<Vec3Attribute>(0));
vao->initDataFeed(vertices.data(), vertices.size() * sizeof(float), GL_STATIC_DRAW, std::move(attribs));
vao->createIndexBuffer(indices.data(), indices.size());
vao->unbind();
return std::make_shared<Model>(std::move(vao), static_cast<int>(indices.size()), true);
}

View File

@ -0,0 +1,17 @@
//
// Created by sebastian on 04.08.26.
//
#ifndef COLORRACE_SPHEREFACTORY_H
#define COLORRACE_SPHEREFACTORY_H
#include <memory>
#include "loader/models/Model.h"
namespace engine::SphereFactory {
// Erzeugt eine UV-Sphere mit gegebenem Radius (Radius ist in die Vertices eingebacken,
// die Transform braucht also nur eine Translation auf das Kugelzentrum).
std::shared_ptr<Model> createUVSphere(float radius, int sectorCount = 16, int stackCount = 12);
}
#endif //COLORRACE_SPHEREFACTORY_H