Loading...
Searching...
No Matches
Sphere.cpp
Go to the documentation of this file.
1//
2// Created by denzel on 11/08/2025.
3//
4#include <hellfire/graphics/geometry/Sphere.h>
5
6#include "hellfire/ecs/RenderableComponent.h"
7#include "hellfire/ecs/TransformComponent.h"
8#include "hellfire/ecs/components/MeshComponent.h"
9#include "hellfire/scene/Scene.h"
10
11namespace hellfire {
12 EntityID Sphere::create(Scene *scene, const std::string &name, const Config &config) {
13 const EntityID id = scene->create_entity(name);
14 Entity *entity = scene->get_entity(id);
15
16 // Add mesh component
17 auto *mesh_comp = entity->add_component<MeshComponent>();
18 std::vector<Vertex> vertices;
19 std::vector<unsigned int> indices;
20
21 // Generate sphere geometry
22 get_sphere_data(vertices, indices, 1.0f, config.rings, config.sectors);
23
24 // Apply color to vertices
25 for (auto &vertex: vertices) {
26 vertex.color = config.color;
27 }
28
29 mesh_comp->set_mesh(std::make_shared<Mesh>(vertices, indices));
30 mesh_comp->set_source(MeshSource::INTERNAL);
31
32 // Add renderable component
33 auto *renderable = entity->add_component<RenderableComponent>();
34 if (config.material) {
35 renderable->set_material(config.material);
36 } else {
37 const auto material = MaterialBuilder::create("Sphere Material");
38 renderable->set_material(material);
39 }
40
41 // Apply transform
42 entity->transform()->set_position(config.position);
43 entity->transform()->set_scale(config.scale);
44
45 return id;
46 }
47
48 std::shared_ptr<Mesh> Sphere::create_mesh(int rings, int sectors) {
49 std::vector<Vertex> vertices;
50 std::vector<unsigned int> indices;
51 get_sphere_data(vertices, indices, 1.0f, rings, sectors);
52 return std::make_shared<Mesh>(vertices, indices);
53 }
54
55 void Sphere::get_sphere_data(std::vector<Vertex> &vertices, std::vector<unsigned int> &indices,
56 float radius, int rings, int sectors) {
57 vertices.clear();
58 indices.clear();
59
60 // Generate vertices
61 for (int ring = 0; ring <= rings; ++ring) {
62 constexpr float PI = 3.14159265359f;
63 const float phi = PI * static_cast<float>(ring) / static_cast<float>(rings);
64 float y = cos(phi);
65 const float ring_radius = sin(phi);
66
67 for (int sector = 0; sector <= sectors; ++sector) {
68 const float theta = 2.0f * PI * static_cast<float>(sector) / static_cast<float>(sectors);
69 float x = ring_radius * cos(theta);
70 float z = ring_radius * sin(theta);
71
72 Vertex vertex;
73 vertex.normal = glm::normalize(glm::vec3(x, y, z));
74 vertex.position = vertex.normal * radius;
75 vertex.color = glm::vec3(1.0f);
76
77 // UV coordinates
78 vertex.texCoords = glm::vec2(
79 static_cast<float>(sector) / static_cast<float>(sectors),
80 static_cast<float>(ring) / static_cast<float>(rings)
81 );
82
83 vertices.push_back(vertex);
84 }
85 }
86
87 for (int ring = 0; ring < rings; ++ring) {
88 for (int sector = 0; sector < sectors; ++sector) {
89 const int current = ring * (sectors + 1) + sector;
90 const int next = current + sectors + 1;
91
92 // Create two triangles for each quad
93 indices.push_back(current);
94 indices.push_back(current + 1);
95 indices.push_back(next);
96
97 indices.push_back(current + 1);
98 indices.push_back(next + 1);
99 indices.push_back(next);
100 }
101 }
102 }
103
104 void Sphere::subdivide_triangle(std::vector<glm::vec3> &vertices, const glm::vec3 &v1, const glm::vec3 &v2, const glm::vec3 &v3,
105 const int depth) {
106 if (depth == 0) {
107 vertices.push_back(v1);
108 vertices.push_back(v2);
109 vertices.push_back(v3);
110 return;
111 }
112
113 // Calculate midpoints and normalize to sphere surface
114 const glm::vec3 v12 = glm::normalize((v1 + v2) * 0.5f);
115 const glm::vec3 v23 = glm::normalize((v2 + v3) * 0.5f);
116 const glm::vec3 v31 = glm::normalize((v3 + v1) * 0.5f);
117
118 // Recursively subdivide
119 subdivide_triangle(vertices, v1, v12, v31, depth - 1);
120 subdivide_triangle(vertices, v2, v23, v12, depth - 1);
121 subdivide_triangle(vertices, v3, v31, v23, depth - 1);
122 subdivide_triangle(vertices, v12, v23, v31, depth - 1);
123 }
124};
TransformComponent * transform()
Definition Entity.cpp:42
Manages a collection of entities and their hierarchical relationships.
Definition Scene.h:24
Entity * get_entity(EntityID id)
Retrieves an entity by its ID.
Definition Scene.cpp:81
EntityID create_entity(const std::string &name="GameObject")
Creates a new entity in the scene.
Definition Scene.cpp:29
static std::shared_ptr< Mesh > create_mesh(int rings=32, int sectors=32)
Definition Sphere.cpp:48
static EntityID create(Scene *scene, const std::string &name, const Config &config)
Definition Sphere.cpp:12
void set_position(float x, float y, float z)
Definition Vertex.h:5