ADD: SphereFactory
This commit is contained in:
parent
6ee58d4901
commit
023016c6a2
67
engine/src/renderer/primitives/SphereFactory.cpp
Normal file
67
engine/src/renderer/primitives/SphereFactory.cpp
Normal 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);
|
||||
}
|
||||
17
engine/src/renderer/primitives/SphereFactory.h
Normal file
17
engine/src/renderer/primitives/SphereFactory.h
Normal 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
|
||||
Loading…
Reference in New Issue
Block a user