Skip to content

Commit 3f03c60

Browse files
authored
Feat/fullscreen (#440)
2 parents cc7ee5c + 1a09102 commit 3f03c60

247 files changed

Lines changed: 114539 additions & 2031 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

common/math/Light.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@
1717
///////////////////////////////////////////////////////////////////////////////
1818

1919
#include "Light.hpp"
20+
#include <cmath>
2021

2122
namespace nexo::math {
22-
std::pair<float, float> computeAttenuationFromDistance(float distance)
23+
std::pair<float, float> computeAttenuationFromDistance(const float distance)
2324
{
2425
// Clamp distance to the min/max of the table
2526
if (distance <= s_attenuationTable[0].distance)
@@ -56,4 +57,26 @@ namespace nexo::math {
5657

5758
return { linear, quadratic };
5859
}
60+
61+
float computeDistanceFromAttenuation(const float linear, const float quadratic)
62+
{
63+
// Find the closest matching entry in the table
64+
float closestDistance = s_attenuationTable[0].distance;
65+
float minDiff = std::abs(s_attenuationTable[0].linear - linear) +
66+
std::abs(s_attenuationTable[0].quadratic - quadratic);
67+
68+
for (int i = 1; i < s_attenuationCount; ++i)
69+
{
70+
const float diff = std::abs(s_attenuationTable[i].linear - linear) +
71+
std::abs(s_attenuationTable[i].quadratic - quadratic);
72+
if (diff < minDiff)
73+
{
74+
minDiff = diff;
75+
closestDistance = s_attenuationTable[i].distance;
76+
}
77+
}
78+
79+
return closestDistance;
80+
}
81+
5982
}

common/math/Light.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,16 @@ namespace nexo::math {
5858
* @return A pair of floats where the first is the linear attenuation factor and the second is the quadratic attenuation factor.
5959
*/
6060
std::pair<float, float> computeAttenuationFromDistance(float distance);
61+
62+
/**
63+
* @brief Estimates the distance at which a light would have the specified linear and quadratic attenuation factors.
64+
*
65+
* The function searches the attenuation table for the entry that best matches the provided linear and
66+
* quadratic factors and returns the corresponding distance.
67+
*
68+
* @param linear The linear attenuation factor.
69+
* @param quadratic The quadratic attenuation factor.
70+
* @return The estimated distance from the light source.
71+
*/
72+
float computeDistanceFromAttenuation(float linear, float quadratic);
6173
}

editor/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ set(SRCS
118118
editor/src/DocumentWindows/GameWindow/Setup.cpp
119119
editor/src/DocumentWindows/GameWindow/Show.cpp
120120
editor/src/DocumentWindows/GameWindow/Update.cpp
121+
editor/src/DocumentWindows/PerformanceWindow/PerformanceWindow.cpp
121122
)
122123

123124
# Windows App Icon

editor/main.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "src/DocumentWindows/MaterialInspector/MaterialInspector.hpp"
2424
#include "src/DocumentWindows/PrimitiveWindow/PrimitiveWindow.hpp"
2525
#include "src/DocumentWindows/SceneTreeWindow/SceneTreeWindow.hpp"
26+
#include "src/DocumentWindows/PerformanceWindow/PerformanceWindow.hpp"
2627
#include "src/Editor.hpp"
2728

2829
#include <core/exceptions/Exceptions.hpp>
@@ -46,6 +47,7 @@ try {
4647
editor.registerWindow<nexo::editor::MaterialInspector>(NEXO_WND_USTRID_MATERIAL_INSPECTOR);
4748
editor.registerWindow<nexo::editor::PrimitiveWindow>(NEXO_WND_USTRID_PRIMITIVE_WINDOW);
4849
editor.registerWindow<nexo::editor::AssetManagerWindow>(NEXO_WND_USTRID_ASSET_MANAGER);
50+
editor.registerWindow<nexo::editor::PerformanceMonitorWindow>(NEXO_WND_USTRID_PERFORMANCE_MONITOR);
4951

5052
if (const auto defaultScene = editor
5153
.getWindow<nexo::editor::EditorScene>(

editor/src/ADocumentWindow.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ namespace nexo::editor {
3838
#define NEXO_WND_USTRID_BOTTOM_BAR "###CommandsBar"
3939
#define NEXO_WND_USTRID_TEST "###TestWindow"
4040
#define NEXO_WND_USTRID_GAME_WINDOW "###GameWindow"
41+
#define NEXO_WND_USTRID_PERFORMANCE_MONITOR "###Performance Monitor"
4142

4243
class ADocumentWindow : public IDocumentWindow {
4344
public:

editor/src/DocumentWindows/AssetManager/Init.cpp

Lines changed: 209 additions & 28 deletions
Large diffs are not rendered by default.

editor/src/DocumentWindows/EditorScene/EditorScene.hpp

Lines changed: 5 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ namespace nexo::editor {
6060
* Finally, it renders both the scene view and transformation gizmos within the window.
6161
*/
6262
void show() override;
63+
void showFullscreen(bool fullscreen);
6364

6465
bool showToolbar = true;
6566
bool isPhysicsRunning = false;
@@ -271,10 +272,10 @@ namespace nexo::editor {
271272
/**
272273
* @brief Populates the scene with default entities.
273274
*
274-
* Creates standard light sources (ambient, directional, point, spot)
275-
* and a simple ground plane in the scene.
275+
*
276+
* @param offset A glm::vec3 representing the positional offset to apply to all spheres.
276277
*/
277-
static void loadDefaultEntities();
278+
void loadDefaultEntities(const glm::vec3& offset = {0.0f, 0.0f, 0.0f}) const;
278279

279280
/**
280281
* @brief Creates a physics-enabled entity in the scene.
@@ -460,21 +461,6 @@ namespace nexo::editor {
460461
*/
461462
static void captureInitialTransformStates(const std::vector<int>& entities);
462463

463-
/** * @brief Applies a world transformation delta to multiple entities.
464-
*
465-
* This function takes a source entity's old and new world transformation matrices,
466-
* computes the delta transformation, and applies this delta to a list of target entities.
467-
* Each target entity's TransformComponent is updated to reflect the new world position,
468-
* rotation, and scale based on the computed delta.
469-
*
470-
* @param sourceEntity The entity whose transformation change is the basis for the delta.
471-
* @param oldWorldMatrix The original world transformation matrix of the source entity.
472-
* @param newWorldMatrix The new world transformation matrix of the source entity.
473-
* @param targetEntities A vector of entity IDs to which the delta transformation will be applied.
474-
*/
475-
static void applyTransformToEntities(ecs::Entity sourceEntity, const glm::mat4& oldWorldMatrix,
476-
const glm::mat4& newWorldMatrix, const std::vector<int>& targetEntities);
477-
478464
/** * @brief Creates undo actions for transform changes on multiple entities.
479465
*
480466
* This method generates and records undo actions for a set of entities that have undergone
@@ -674,16 +660,6 @@ namespace nexo::editor {
674660
*/
675661
void createOrFocusGameWindow();
676662

677-
/** @brief Spawns a scene with multiple balls for physics testing.
678-
*
679-
* Creates a grid of sphere entities with physics properties, arranged in
680-
* a 5x5x5 formation. Each sphere is given a random color and positioned
681-
* based on the provided offset.
682-
*
683-
* @param offset A glm::vec3 representing the positional offset to apply to all spheres.
684-
*/
685-
void spawnBallsScene(const glm::vec3& offset = {0.0f, 0.0f, 0.0f}) const;
686-
687663
/**
688664
* @brief Creates a scene with multiple light sources.
689665
*
@@ -723,6 +699,7 @@ namespace nexo::editor {
723699
* @param offset Position offset to apply to all forest elements.
724700
*/
725701
void forestScene(const glm::vec3& offset = {0.0f, 0.0f, 0.0f}) const;
702+
void spawnBallsScene(const glm::vec3& offset = {0.0f, 0.0f, 0.0f}) const;
726703

727704
enum class EditorState { GLOBAL, GIZMO, GIZMO_TRANSLATE, GIZMO_ROTATE, GIZMO_SCALE, NB_STATE };
728705

editor/src/DocumentWindows/EditorScene/Gizmo.cpp

Lines changed: 39 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -198,15 +198,36 @@ namespace nexo::editor {
198198
{
199199
const glm::mat4 parentWorldMatrix = getEntityParentWorldMatrix(entity);
200200

201-
// Calculate local matrix by inverting parent world matrix and multiplying by entity's world matrix
202-
const glm::mat4 localMatrix = glm::inverse(parentWorldMatrix) * worldMatrix;
201+
// Calculate what the local matrix should be to achieve the desired world matrix
202+
const glm::mat4 desiredLocalMatrix = glm::inverse(parentWorldMatrix) * worldMatrix;
203203

204+
// Decompose the desired local matrix back to local transform properties
204205
glm::vec3 skew;
205206
glm::vec4 perspective;
206-
glm::decompose(localMatrix, transform.size, transform.quat, transform.pos, skew, perspective);
207+
glm::decompose(desiredLocalMatrix, transform.size, transform.quat, transform.pos, skew, perspective);
207208

208-
transform.quat = glm::normalize(transform.quat);
209+
transform.quat = glm::normalize(transform.quat);
209210
transform.worldMatrix = worldMatrix;
211+
transform.dirty = true;
212+
Application::getInstance().markHierarchyDirty(entity);
213+
}
214+
215+
static glm::mat4 getCurrentWorldMatrix(const ecs::Entity entity)
216+
{
217+
const auto& coord = nexo::Application::m_coordinator;
218+
const auto transform = coord->tryGetComponent<components::TransformComponent>(entity);
219+
220+
if (!transform) return glm::mat4(1.0f);
221+
222+
// If the transform is dirty, we need to compute what the world matrix would be
223+
if (transform->get().dirty) {
224+
const glm::mat4 parentWorldMatrix = getEntityParentWorldMatrix(entity);
225+
const glm::mat4 localMatrix = calculateWorldMatrix(transform->get());
226+
return parentWorldMatrix * localMatrix;
227+
}
228+
229+
// Use the cached world matrix if it's up to date
230+
return transform->get().worldMatrix;
210231
}
211232

212233
float* EditorScene::getSnapSettingsForOperation(const ImGuizmo::OPERATION operation)
@@ -231,26 +252,6 @@ namespace nexo::editor {
231252
}
232253
}
233254

234-
void EditorScene::applyTransformToEntities(const ecs::Entity sourceEntity, const glm::mat4& oldWorldMatrix,
235-
const glm::mat4& newWorldMatrix, const std::vector<int>& targetEntities)
236-
{
237-
const auto& coord = Application::m_coordinator;
238-
239-
const glm::mat4 deltaMatrix = newWorldMatrix * glm::inverse(oldWorldMatrix);
240-
241-
// Apply to all selected entities except the source
242-
for (const auto& entity : targetEntities) {
243-
if (entity == static_cast<int>(sourceEntity)) continue;
244-
245-
const auto entityTransform = coord->tryGetComponent<components::TransformComponent>(entity);
246-
if (!entityTransform) continue;
247-
248-
// Apply world space delta and convert back to local space
249-
glm::mat4 newEntityWorldMatrix = deltaMatrix * entityTransform->get().worldMatrix;
250-
updateLocalTransformFromWorld(entityTransform->get(), newEntityWorldMatrix, entity);
251-
}
252-
}
253-
254255
/**
255256
* @brief Compares two TransformComponent states to determine if any properties have changed.
256257
*
@@ -359,18 +360,14 @@ namespace nexo::editor {
359360

360361
// 1) M₀ = parentWorld * T(pos) * R(quat) * S(size)
361362
const glm::mat4 parentWorld = getEntityParentWorldMatrix(primaryEntity);
362-
const glm::mat4 Tpos = glm::translate(glm::mat4(1.0f), primaryTransform->get().pos);
363-
const glm::mat4 Rrot = glm::toMat4(primaryTransform->get().quat);
364-
const glm::mat4 Sscale = glm::scale(glm::mat4(1.0f), primaryTransform->get().size);
365-
const glm::mat4 M0 = parentWorld * Tpos * Rrot * Sscale;
363+
const glm::mat4 localMatrix = calculateWorldMatrix(primaryTransform->get());
364+
const glm::mat4 M0 = parentWorld * localMatrix;
366365

367-
// 2) centroid offset” = T(centroidLocal)
366+
// 2) Apply centroid offset for gizmo display
368367
const glm::mat4 C_offset = glm::translate(glm::mat4(1.0f), primaryTransform->get().localCenter);
369-
370-
// 3) M1 = M0 * C_offset
371368
glm::mat4 worldTransformMatrix = M0 * C_offset;
372369

373-
// (We’ll need “M₀” again after manipulation for decomposing back.)
370+
// Store original for delta calculation
374371
const glm::mat4 originalWorldMatrix_ModelOrigin = M0;
375372

376373
if (!ImGuizmo::IsUsing()) s_lastOperation = getActiveGuizmoOperation();
@@ -386,30 +383,30 @@ namespace nexo::editor {
386383
const bool isUsingGizmo = ImGuizmo::IsUsing();
387384

388385
if (isUsingGizmo) {
389-
// Disable camera movement during manipulation
390386
camera.active = false;
391387

392-
const glm::mat4 newWorldMatrix_Centroid = worldTransformMatrix;
393-
const glm::mat4 invCentroidOffset = glm::inverse(C_offset);
388+
const glm::mat4 newWorldMatrix_Centroid = worldTransformMatrix;
389+
const glm::mat4 invCentroidOffset = glm::inverse(C_offset);
394390
const glm::mat4 newWorldMatrix_ModelOrigin = newWorldMatrix_Centroid * invCentroidOffset;
395391

396-
// Update the primary entity's local transform based on the new world transform
392+
// Update local transform properties (NOT world matrix)
397393
updateLocalTransformFromWorld(primaryTransform->get(), newWorldMatrix_ModelOrigin, primaryEntity);
398394

395+
// Apply same transformation to other selected entities
399396
const glm::mat4 deltaMatrix = newWorldMatrix_ModelOrigin * glm::inverse(originalWorldMatrix_ModelOrigin);
400397

401398
for (const auto entity : selectedEntities) {
402399
if (static_cast<unsigned int>(entity) == primaryEntity) continue;
400+
403401
const auto tComp = coord->tryGetComponent<components::TransformComponent>(entity);
404402
if (!tComp) continue;
405403

406-
// “OtherEntity_world₀” = tComp->worldMatrix
407-
glm::mat4 otherWorldMatrix_0 = tComp->get().worldMatrix;
408-
// “OtherEntity_world₁” = deltaMatrix * otherWorldMatrix_0
409-
glm::mat4 otherWorldMatrix_1 = deltaMatrix * otherWorldMatrix_0;
404+
// Get the current world matrix for this entity
405+
const glm::mat4 otherCurrentWorld = getCurrentWorldMatrix(entity);
406+
const glm::mat4 otherNewWorld = deltaMatrix * otherCurrentWorld;
410407

411-
// Now convert that new world matrix back to local space of “entity”:
412-
updateLocalTransformFromWorld(tComp->get(), otherWorldMatrix_1, entity);
408+
// Update local properties only
409+
updateLocalTransformFromWorld(tComp->get(), otherNewWorld, entity);
413410
}
414411
} else if (s_wasUsingGizmo) {
415412
// Re-enable camera when done

0 commit comments

Comments
 (0)