Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
e1b8f56
feat: add example scenes
Sauterelle57 Sep 12, 2025
fbdee27
fix(demo): init cpp scene
ThomasParenteau Sep 12, 2025
5ef8fbe
fix(demo/scenes): code style + sonar + doc + clang tidy errors and wa…
Sauterelle57 Sep 17, 2025
b15a66b
fix(demo/scenes): clean files + code style + sonar errors + documenta…
Sauterelle57 Sep 17, 2025
8228809
fix(demo/scenes): clean files + code style + sonar errors + documenta…
Sauterelle57 Sep 17, 2025
c1858e4
fix(demo/scenes): clean files + code style + sonar errors + documenta…
Sauterelle57 Sep 28, 2025
6440ddc
fix(demo/scenes): clean files + code style + sonar errors + documenta…
Sauterelle57 Sep 28, 2025
eca77b1
feat(demo/EIP-trophies): add demo scene
Sauterelle57 Nov 8, 2025
ded07f2
fix(demo/EIP-trophies): compilation on ubuntu
Sauterelle57 Nov 8, 2025
f754e6f
fix(demo/EIP-trophies): polaroid and pictures
Sauterelle57 Nov 9, 2025
01569a8
fix(demo/EIP-trophies): polaroid and pictures
Sauterelle57 Nov 9, 2025
5ff79a2
feat(demo/EIP-trophies): rotating earth / fan & plane
ThomasParenteau Nov 9, 2025
611fd23
fix(demo/EIP-trophies): compilation, plane model with splited helix a…
Sauterelle57 Nov 9, 2025
e684170
feat(demo/EIP-trophies): add epitech and nexo 3d logo
Sauterelle57 Nov 9, 2025
6efaf07
feat(demo/EIP-trophies): add epitech and nexo 3d logo
Sauterelle57 Nov 9, 2025
9d782c9
feat(performance-maintenance): add performance window
iMeaNz Oct 29, 2025
77613a9
feat(performance-maintenance): add number of entities to performance …
iMeaNz Oct 29, 2025
7d6f716
fix(performance-maitenance): now setting global uniforms in the piepl…
iMeaNz Oct 29, 2025
a3450e7
feat(performance-maintenance): remove redundant check in uniform caching
iMeaNz Oct 29, 2025
70dbd7f
feat(performance-maintenance): add type erased uniform value to avoid…
iMeaNz Oct 29, 2025
d7eba50
fix(performance-maitenance): add unique name to root component for al…
iMeaNz Nov 8, 2025
473b703
refactor(performance-maitenance): add ubo for light and camera infos …
iMeaNz Nov 8, 2025
d89c1e0
chore(performance-maintenance): add source files
iMeaNz Nov 8, 2025
66c5b08
feat(performance-maitenance): add shader uniform buffer
iMeaNz Nov 8, 2025
eb4dc37
refactor(performance-maintenance): store capacity
iMeaNz Nov 8, 2025
3a887f0
feat(performance-maitenance): remove useless field + now use per view…
iMeaNz Nov 8, 2025
97606f4
feat(performance-maitenance): add ubo and ssbo to render pipeline
iMeaNz Nov 8, 2025
41917bf
feat(performance-maintenance): add per view ubo and light ubo to pers…
iMeaNz Nov 8, 2025
cdbbbd3
feat(performance-maintenance): now upload to gpu the lights directly …
iMeaNz Nov 8, 2025
4023224
refactor(performance-maintenance): pass render context to light system
iMeaNz Nov 8, 2025
6b8d52c
refactor(performance-maintenance): remove useless uniform set
iMeaNz Nov 8, 2025
85715a7
feat(performance-maintenance): add gpu resources types def + constants
iMeaNz Nov 8, 2025
bad5aa0
feat(performance-maitenance): mat model are now passed via ssbo
iMeaNz Nov 8, 2025
4e54b67
feat(performance-maintenance): add instanced draw in the renderer api
iMeaNz Nov 8, 2025
88c5cc5
feat(performance-maintenance): draw commands now supports instanced r…
iMeaNz Nov 8, 2025
bbec486
feat(performance-maintenance): add gpu instance data
iMeaNz Nov 8, 2025
3820068
feat(performance-maitenance): instance buffer now use gpu instance data
iMeaNz Nov 8, 2025
6c8a51c
refactor(performance-maintenance): render system and render billboard…
iMeaNz Nov 8, 2025
33989e6
refactor(performance-maintenance): modify shaders to support the new …
iMeaNz Nov 8, 2025
6bd0963
feat(performance-maintenance): add materials ubo
iMeaNz Nov 8, 2025
00f89d3
refactor(performance-maintenance): now use ssbo to pass materials to …
iMeaNz Nov 8, 2025
917f3c2
fix(performance-maintenance): fix windows build
iMeaNz Nov 8, 2025
2657617
fix(performance-maintenance): fix windows build
iMeaNz Nov 8, 2025
66c5615
fix(performance-maintenance): fix windows build
iMeaNz Nov 8, 2025
4805694
fix(performance-maintenance): fix windows build
iMeaNz Nov 8, 2025
0ba1387
fix(performance-maintenance): fix windows build
iMeaNz Nov 8, 2025
d8892ab
fix(performance-maintenance): fix windows build
iMeaNz Nov 8, 2025
c3f2d78
refactor(performance-maitenance): split Application.cpp with Init.cpp…
iMeaNz Nov 8, 2025
60a471d
refactor(performance-maintenance): update editor transform modif to u…
iMeaNz Nov 9, 2025
4167481
feat(performance-maintenance): add new transform system
iMeaNz Nov 9, 2025
7e9531f
feat(performance-maintenance): add helper func to notify the root com…
iMeaNz Nov 9, 2025
08f776b
feat(performance-maintenance): add flag in the root component to upda…
iMeaNz Nov 9, 2025
6d58bf4
feat(performance-maintenance): add dirty flag
iMeaNz Nov 9, 2025
a644a70
chore(performance-maintenance): add source files
iMeaNz Nov 9, 2025
26e2d73
feat(performance-maintenance): add transform system init
iMeaNz Nov 9, 2025
bf87a2b
feat(performance-maintenance): add dirty flag to csharp transform com…
iMeaNz Nov 9, 2025
8ec5236
refactor(performance-maintenance): add dirtying to new scripts
iMeaNz Nov 9, 2025
ca5885e
fix(performance-maintenance): fix get transform func + feat: add func…
iMeaNz Nov 9, 2025
4bbfb80
feat(performance-maitenance): add api func to mark transform hierarch…
iMeaNz Nov 9, 2025
fff7b17
fix(performance-maitenance): fix early return that would not update e…
iMeaNz Nov 9, 2025
c67a5e5
chore(performance-maintenance): remove comment on scripting
iMeaNz Nov 9, 2025
b4d9607
assets(pbr): add new models
iMeaNz Nov 9, 2025
bd0ddee
feat(pbr): add pbr shader
iMeaNz Nov 9, 2025
9dd633c
feat(pbr): load and init new models
iMeaNz Nov 9, 2025
69bc1e4
feat(pbr): model and texture importers now supports pbr
iMeaNz Nov 9, 2025
34280b6
feat(pbr): improve material component and gpu material to support pbr
iMeaNz Nov 9, 2025
c19408a
feat(pbr): load and init pbr shader
iMeaNz Nov 9, 2025
d228028
feat(pbr): textures now supports pbr images and maps
iMeaNz Nov 9, 2025
e062a92
refactor(pbr): refactor render system to support pbr
iMeaNz Nov 9, 2025
91a46bf
chore(pbr): remove useless model loaded
iMeaNz Nov 10, 2025
649b0ef
feat(pbr): reduce ambient light
iMeaNz Nov 10, 2025
a8ca540
refactor(pbr): add texture batch to avoid overbinding
iMeaNz Nov 10, 2025
f74c32e
refactor(pbr): create texture batch when needed to avoid overbindind
iMeaNz Nov 10, 2025
0c6008e
refactor(pbr): bind texture batches when needed
iMeaNz Nov 10, 2025
733e852
fix(pbr): fix billboards shader
iMeaNz Nov 10, 2025
c22dcb0
style(pbr): remove some logs
iMeaNz Nov 10, 2025
dfa51a3
feat(shadows): add shadow pass to camera
iMeaNz Nov 10, 2025
56218f8
feat(shadows): add shadow pass
iMeaNz Nov 10, 2025
1c47fe6
chore(shadows): add source files
iMeaNz Nov 10, 2025
5cfd065
style(shadows): remove log
iMeaNz Nov 10, 2025
acf4b9b
feat(shadows): add shadow depth shader
iMeaNz Nov 10, 2025
f7aecfb
refactor(shadows): framebuffer with only depth attachment now use lin…
iMeaNz Nov 10, 2025
b64801f
feat(shadows): set directional light uniform
iMeaNz Nov 10, 2025
4142474
feat(shadows): add point light shadow pass to camera
iMeaNz Nov 10, 2025
d051ffb
chore(shadows): add source files
iMeaNz Nov 10, 2025
ad828f5
feat(shadows): add point depth map support in the render pipeline
iMeaNz Nov 10, 2025
c869775
feat(shadows): add point shadow pass
iMeaNz Nov 10, 2025
44109de
feat(shadows): point light systems now also upload point light info t…
iMeaNz Nov 10, 2025
8e7ef63
refactor(shadows): modoify gpu point light struct to include far plane
iMeaNz Nov 10, 2025
e540c2a
feat(shadows): add shadow pass to enum
iMeaNz Nov 10, 2025
dc10d72
feat(shadows): add point light shadow depth shader
iMeaNz Nov 10, 2025
21909db
fix(shadows): fix billboard system to comply with the new texture bat…
iMeaNz Nov 10, 2025
7723159
fix(physics): fix collision step that was too big + now only retrieve…
iMeaNz Nov 10, 2025
3bf79a7
feat: full screen with tab
jcardonne Nov 11, 2025
ecc5078
feat: real full screen
jcardonne Nov 11, 2025
a878b1b
fix(fullscreen): fix wrong rebase
iMeaNz Feb 7, 2026
1a09102
fix(fullscreen): fix wrong rebase
iMeaNz Feb 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion common/math/Light.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@
///////////////////////////////////////////////////////////////////////////////

#include "Light.hpp"
#include <cmath>

namespace nexo::math {
std::pair<float, float> computeAttenuationFromDistance(float distance)
std::pair<float, float> computeAttenuationFromDistance(const float distance)
{
// Clamp distance to the min/max of the table
if (distance <= s_attenuationTable[0].distance)
Expand Down Expand Up @@ -56,4 +57,26 @@ namespace nexo::math {

return { linear, quadratic };
}

float computeDistanceFromAttenuation(const float linear, const float quadratic)
{
// Find the closest matching entry in the table
float closestDistance = s_attenuationTable[0].distance;
float minDiff = std::abs(s_attenuationTable[0].linear - linear) +
std::abs(s_attenuationTable[0].quadratic - quadratic);

for (int i = 1; i < s_attenuationCount; ++i)
{
const float diff = std::abs(s_attenuationTable[i].linear - linear) +
std::abs(s_attenuationTable[i].quadratic - quadratic);
if (diff < minDiff)
{
minDiff = diff;
closestDistance = s_attenuationTable[i].distance;
}
}

return closestDistance;
}

}
12 changes: 12 additions & 0 deletions common/math/Light.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,16 @@ namespace nexo::math {
* @return A pair of floats where the first is the linear attenuation factor and the second is the quadratic attenuation factor.
*/
std::pair<float, float> computeAttenuationFromDistance(float distance);

/**
* @brief Estimates the distance at which a light would have the specified linear and quadratic attenuation factors.
*
* The function searches the attenuation table for the entry that best matches the provided linear and
* quadratic factors and returns the corresponding distance.
*
* @param linear The linear attenuation factor.
* @param quadratic The quadratic attenuation factor.
* @return The estimated distance from the light source.
*/
float computeDistanceFromAttenuation(float linear, float quadratic);
}
1 change: 1 addition & 0 deletions editor/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ set(SRCS
editor/src/DocumentWindows/GameWindow/Setup.cpp
editor/src/DocumentWindows/GameWindow/Show.cpp
editor/src/DocumentWindows/GameWindow/Update.cpp
editor/src/DocumentWindows/PerformanceWindow/PerformanceWindow.cpp
)

# Windows App Icon
Expand Down
2 changes: 2 additions & 0 deletions editor/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "src/DocumentWindows/MaterialInspector/MaterialInspector.hpp"
#include "src/DocumentWindows/PrimitiveWindow/PrimitiveWindow.hpp"
#include "src/DocumentWindows/SceneTreeWindow/SceneTreeWindow.hpp"
#include "src/DocumentWindows/PerformanceWindow/PerformanceWindow.hpp"
#include "src/Editor.hpp"

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

if (const auto defaultScene = editor
.getWindow<nexo::editor::EditorScene>(
Expand Down
1 change: 1 addition & 0 deletions editor/src/ADocumentWindow.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ namespace nexo::editor {
#define NEXO_WND_USTRID_BOTTOM_BAR "###CommandsBar"
#define NEXO_WND_USTRID_TEST "###TestWindow"
#define NEXO_WND_USTRID_GAME_WINDOW "###GameWindow"
#define NEXO_WND_USTRID_PERFORMANCE_MONITOR "###Performance Monitor"

class ADocumentWindow : public IDocumentWindow {
public:
Expand Down
237 changes: 209 additions & 28 deletions editor/src/DocumentWindows/AssetManager/Init.cpp

Large diffs are not rendered by default.

33 changes: 5 additions & 28 deletions editor/src/DocumentWindows/EditorScene/EditorScene.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ namespace nexo::editor {
* Finally, it renders both the scene view and transformation gizmos within the window.
*/
void show() override;
void showFullscreen(bool fullscreen);

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

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

/** * @brief Applies a world transformation delta to multiple entities.
*
* This function takes a source entity's old and new world transformation matrices,
* computes the delta transformation, and applies this delta to a list of target entities.
* Each target entity's TransformComponent is updated to reflect the new world position,
* rotation, and scale based on the computed delta.
*
* @param sourceEntity The entity whose transformation change is the basis for the delta.
* @param oldWorldMatrix The original world transformation matrix of the source entity.
* @param newWorldMatrix The new world transformation matrix of the source entity.
* @param targetEntities A vector of entity IDs to which the delta transformation will be applied.
*/
static void applyTransformToEntities(ecs::Entity sourceEntity, const glm::mat4& oldWorldMatrix,
const glm::mat4& newWorldMatrix, const std::vector<int>& targetEntities);

/** * @brief Creates undo actions for transform changes on multiple entities.
*
* This method generates and records undo actions for a set of entities that have undergone
Expand Down Expand Up @@ -674,16 +660,6 @@ namespace nexo::editor {
*/
void createOrFocusGameWindow();

/** @brief Spawns a scene with multiple balls for physics testing.
*
* Creates a grid of sphere entities with physics properties, arranged in
* a 5x5x5 formation. Each sphere is given a random color and positioned
* based on the provided offset.
*
* @param offset A glm::vec3 representing the positional offset to apply to all spheres.
*/
void spawnBallsScene(const glm::vec3& offset = {0.0f, 0.0f, 0.0f}) const;

/**
* @brief Creates a scene with multiple light sources.
*
Expand Down Expand Up @@ -723,6 +699,7 @@ namespace nexo::editor {
* @param offset Position offset to apply to all forest elements.
*/
void forestScene(const glm::vec3& offset = {0.0f, 0.0f, 0.0f}) const;
void spawnBallsScene(const glm::vec3& offset = {0.0f, 0.0f, 0.0f}) const;

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

Expand Down
81 changes: 39 additions & 42 deletions editor/src/DocumentWindows/EditorScene/Gizmo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,15 +198,36 @@ namespace nexo::editor {
{
const glm::mat4 parentWorldMatrix = getEntityParentWorldMatrix(entity);

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

// Decompose the desired local matrix back to local transform properties
glm::vec3 skew;
glm::vec4 perspective;
glm::decompose(localMatrix, transform.size, transform.quat, transform.pos, skew, perspective);
glm::decompose(desiredLocalMatrix, transform.size, transform.quat, transform.pos, skew, perspective);

transform.quat = glm::normalize(transform.quat);
transform.quat = glm::normalize(transform.quat);
transform.worldMatrix = worldMatrix;
transform.dirty = true;
Application::getInstance().markHierarchyDirty(entity);
}

static glm::mat4 getCurrentWorldMatrix(const ecs::Entity entity)
{
const auto& coord = nexo::Application::m_coordinator;
const auto transform = coord->tryGetComponent<components::TransformComponent>(entity);

if (!transform) return glm::mat4(1.0f);

// If the transform is dirty, we need to compute what the world matrix would be
if (transform->get().dirty) {
const glm::mat4 parentWorldMatrix = getEntityParentWorldMatrix(entity);
const glm::mat4 localMatrix = calculateWorldMatrix(transform->get());
return parentWorldMatrix * localMatrix;
}

// Use the cached world matrix if it's up to date
return transform->get().worldMatrix;
}

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

void EditorScene::applyTransformToEntities(const ecs::Entity sourceEntity, const glm::mat4& oldWorldMatrix,
const glm::mat4& newWorldMatrix, const std::vector<int>& targetEntities)
{
const auto& coord = Application::m_coordinator;

const glm::mat4 deltaMatrix = newWorldMatrix * glm::inverse(oldWorldMatrix);

// Apply to all selected entities except the source
for (const auto& entity : targetEntities) {
if (entity == static_cast<int>(sourceEntity)) continue;

const auto entityTransform = coord->tryGetComponent<components::TransformComponent>(entity);
if (!entityTransform) continue;

// Apply world space delta and convert back to local space
glm::mat4 newEntityWorldMatrix = deltaMatrix * entityTransform->get().worldMatrix;
updateLocalTransformFromWorld(entityTransform->get(), newEntityWorldMatrix, entity);
}
}

/**
* @brief Compares two TransformComponent states to determine if any properties have changed.
*
Expand Down Expand Up @@ -359,18 +360,14 @@ namespace nexo::editor {

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

// 2) centroid offset” = T(centroidLocal)
// 2) Apply centroid offset for gizmo display
const glm::mat4 C_offset = glm::translate(glm::mat4(1.0f), primaryTransform->get().localCenter);

// 3) M1 = M0 * C_offset
glm::mat4 worldTransformMatrix = M0 * C_offset;

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

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

if (isUsingGizmo) {
// Disable camera movement during manipulation
camera.active = false;

const glm::mat4 newWorldMatrix_Centroid = worldTransformMatrix;
const glm::mat4 invCentroidOffset = glm::inverse(C_offset);
const glm::mat4 newWorldMatrix_Centroid = worldTransformMatrix;
const glm::mat4 invCentroidOffset = glm::inverse(C_offset);
const glm::mat4 newWorldMatrix_ModelOrigin = newWorldMatrix_Centroid * invCentroidOffset;

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

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

for (const auto entity : selectedEntities) {
if (static_cast<unsigned int>(entity) == primaryEntity) continue;

const auto tComp = coord->tryGetComponent<components::TransformComponent>(entity);
if (!tComp) continue;

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

// Now convert that new world matrix back to local space of “entity”:
updateLocalTransformFromWorld(tComp->get(), otherWorldMatrix_1, entity);
// Update local properties only
updateLocalTransformFromWorld(tComp->get(), otherNewWorld, entity);
}
} else if (s_wasUsingGizmo) {
// Re-enable camera when done
Expand Down
Loading
Loading