From 023016c6a27f02c53f7597584a879c4480dc5708 Mon Sep 17 00:00:00 2001 From: sebastian Date: Tue, 4 Aug 2026 14:42:57 +0200 Subject: [PATCH] ADD: SphereFactory --- .../src/renderer/primitives/SphereFactory.cpp | 67 +++++++++++++++++++ .../src/renderer/primitives/SphereFactory.h | 17 +++++ 2 files changed, 84 insertions(+) create mode 100644 engine/src/renderer/primitives/SphereFactory.cpp create mode 100644 engine/src/renderer/primitives/SphereFactory.h diff --git a/engine/src/renderer/primitives/SphereFactory.cpp b/engine/src/renderer/primitives/SphereFactory.cpp new file mode 100644 index 0000000..ed6699e --- /dev/null +++ b/engine/src/renderer/primitives/SphereFactory.cpp @@ -0,0 +1,67 @@ +// +// Created by sebastian on 04.08.26. +// + +#include "SphereFactory.h" + +#include +#include + +#include "utils/openglWrapper/openglObjects/Vao.h" + +std::shared_ptr 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 vertices; + vertices.reserve(static_cast(stackCount + 1) * (sectorCount + 1) * 3); + + for (int i = 0; i <= stackCount; ++i) { + const float stackAngle = PI / 2.0f - static_cast(i) * PI / static_cast(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(j) * 2.0f * PI / static_cast(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 indices; + indices.reserve(static_cast(stackCount) * sectorCount * 6); + + for (int i = 0; i < stackCount; ++i) { + unsigned int k1 = static_cast(i * (sectorCount + 1)); // Anfang des aktuellen Rings + unsigned int k2 = k1 + static_cast(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> attribs; + attribs.push_back(std::make_unique(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(std::move(vao), static_cast(indices.size()), true); +} diff --git a/engine/src/renderer/primitives/SphereFactory.h b/engine/src/renderer/primitives/SphereFactory.h new file mode 100644 index 0000000..aababa9 --- /dev/null +++ b/engine/src/renderer/primitives/SphereFactory.h @@ -0,0 +1,17 @@ +// +// Created by sebastian on 04.08.26. +// + +#ifndef COLORRACE_SPHEREFACTORY_H +#define COLORRACE_SPHEREFACTORY_H +#include + +#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 createUVSphere(float radius, int sectorCount = 16, int stackCount = 12); +} + +#endif //COLORRACE_SPHEREFACTORY_H