From 81ab2a8a4a7ef0fac7835a7b2cec75649250ea06 Mon Sep 17 00:00:00 2001 From: Bram Verhulst Date: Wed, 24 Jun 2026 15:55:57 +0200 Subject: [PATCH] feat: add spherecollidor --- destrum/CMakeLists.txt | 1 + destrum/assets_src/sphere.fbx | Bin 0 -> 13868 bytes .../Components/Physics/SphereCollider.h | 4 +- .../src/Components/Physics/SphereCollider.cpp | 1 + lightkeeper/include/Lightkeeper.h | 5 +- lightkeeper/src/Lightkeeper.cpp | 99 ++++++++++++++---- 6 files changed, 85 insertions(+), 25 deletions(-) create mode 100644 destrum/assets_src/sphere.fbx create mode 100644 destrum/src/Components/Physics/SphereCollider.cpp diff --git a/destrum/CMakeLists.txt b/destrum/CMakeLists.txt index c6136b6..85b2de0 100644 --- a/destrum/CMakeLists.txt +++ b/destrum/CMakeLists.txt @@ -12,6 +12,7 @@ set(SRC_FILES "src/Components/Physics/Rigidbody.cpp" "src/Components/Physics/BoxCollider.cpp" + "src/Components/Physics/SphereCollider.cpp" "src/Graphics/BindlessSetManager.cpp" "src/Graphics/Camera.cpp" diff --git a/destrum/assets_src/sphere.fbx b/destrum/assets_src/sphere.fbx new file mode 100644 index 0000000000000000000000000000000000000000..3a398b7b5bf4eea78b0135ee8fb5a93a35a6cd29 GIT binary patch literal 13868 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 XU#Y?E#|=ew1;Lds20f8RP9OL`rR0fM literal 0 HcmV?d00001 diff --git a/destrum/include/destrum/Components/Physics/SphereCollider.h b/destrum/include/destrum/Components/Physics/SphereCollider.h index 7831fb4..cf511e5 100644 --- a/destrum/include/destrum/Components/Physics/SphereCollider.h +++ b/destrum/include/destrum/Components/Physics/SphereCollider.h @@ -2,7 +2,7 @@ #include -#include +#include class SphereCollider final : public Collider { public: @@ -10,6 +10,8 @@ public: : Collider(owner) , m_Radius(radius) {} + void Update() override {} + [[nodiscard]] PhysicsShapeDesc BuildPhysicsShape() const override { return PhysicsShapeDesc::Sphere(m_Radius, m_CenterOffset, m_IsTrigger); } diff --git a/destrum/src/Components/Physics/SphereCollider.cpp b/destrum/src/Components/Physics/SphereCollider.cpp new file mode 100644 index 0000000..c55ff27 --- /dev/null +++ b/destrum/src/Components/Physics/SphereCollider.cpp @@ -0,0 +1 @@ +#include \ No newline at end of file diff --git a/lightkeeper/include/Lightkeeper.h b/lightkeeper/include/Lightkeeper.h index dbb88db..871634a 100644 --- a/lightkeeper/include/Lightkeeper.h +++ b/lightkeeper/include/Lightkeeper.h @@ -25,9 +25,8 @@ private: Camera camera{glm::vec3(0.f, 0.f, -5.f), glm::vec3(0, 1, 0)}; - CPUMesh testMesh{}; - MeshID testMeshID; - MaterialID testMaterialID; + MeshID sphereMesh; + MaterialID sphereMaterial; std::unique_ptr skyboxCubemap; diff --git a/lightkeeper/src/Lightkeeper.cpp b/lightkeeper/src/Lightkeeper.cpp index 0d9271f..aec3901 100644 --- a/lightkeeper/src/Lightkeeper.cpp +++ b/lightkeeper/src/Lightkeeper.cpp @@ -20,6 +20,7 @@ #include #include "imgui.h" +#include "destrum/Components/Physics/SphereCollider.h" #include "destrum/Util/ModelDocUtils.h" @@ -52,10 +53,10 @@ void LightKeeper::customInit() ModelDocUtils::LogModelDocSummary(kittyModel, "kitty.glb"); const auto& kittyPrimitive = ModelDocUtils::GetFirstPrimitiveOrThrow(kittyModel, "game://kitty.glb"); - testMesh = kittyPrimitive.mesh; + auto testMesh = kittyPrimitive.mesh; testMesh.name = "Test Mesh"; - testMeshID = meshCache.addMesh(gfxDevice, testMesh); + auto testMeshID = meshCache.addMesh(gfxDevice, testMesh); spdlog::info("TestMesh uploaded with id: {}", testMeshID); const auto testTexturePath = ModelDocUtils::PickTexturePath( @@ -67,13 +68,13 @@ void LightKeeper::customInit() const auto testimgID = gfxDevice.loadImageFromFile(testTexturePath); spdlog::info("Test image loaded from '{}' with id: {}", testTexturePath.generic_string(), testimgID); - testMaterialID = materialCache.addMaterial(gfxDevice, { - .baseColor = ModelDocUtils::GetImportedBaseColor( - kittyModel, kittyPrimitive), - .diffuseTexture = testimgID, - .name = ModelDocUtils::GetImportedMaterialName( - kittyModel, kittyPrimitive, "TestMaterial"), - }); + auto testMaterialID = materialCache.addMaterial(gfxDevice, { + .baseColor = ModelDocUtils::GetImportedBaseColor( + kittyModel, kittyPrimitive), + .diffuseTexture = testimgID, + .name = ModelDocUtils::GetImportedMaterialName( + kittyModel, kittyPrimitive, "TestMaterial"), + }); spdlog::info("Test material created with id: {}", testMaterialID); camera.SetRotation(glm::radians(glm::vec2(90.f, 0.f))); @@ -152,7 +153,7 @@ void LightKeeper::customInit() ); ModelDocUtils::LogModelDocSummary(charModel, "capybara.fbx"); - const auto &charPrimitive = ModelDocUtils::GetFirstSkinnedPrimitiveOrFirstOrThrow( + const auto& charPrimitive = ModelDocUtils::GetFirstSkinnedPrimitiveOrFirstOrThrow( charModel, "engine://cotw-capybara-male/source/capybara.fbx" ); @@ -185,7 +186,8 @@ void LightKeeper::customInit() std::string firstAnimationName; - for (auto &clip: charModel.animations) { + for (auto& clip : charModel.animations) + { spdlog::info("Loaded animation: '{}' ({:.2f}s)", clip.name, clip.duration); if (firstAnimationName.empty()) @@ -194,7 +196,8 @@ void LightKeeper::customInit() animator->addClip(std::make_shared(std::move(clip))); } - if (!firstAnimationName.empty()) { + if (!firstAnimationName.empty()) + { spdlog::info("Playing animation: '{}'", firstAnimationName); animator->play(firstAnimationName); } @@ -275,11 +278,11 @@ void LightKeeper::customInit() characterOptions ); - const auto &charPrimitive = - ModelDocUtils::GetFirstSkinnedPrimitiveOrFirstOrThrow( - charModel, - "engine://characterMedium.fbx" - ); + const auto& charPrimitive = + ModelDocUtils::GetFirstSkinnedPrimitiveOrFirstOrThrow( + charModel, + "engine://characterMedium.fbx" + ); const auto charMeshID = meshCache.addMesh(gfxDevice, charPrimitive.mesh); @@ -312,12 +315,14 @@ void LightKeeper::customInit() charModel.skeleton ); - for (auto &clip: runClips) { + for (auto& clip : runClips) + { spdlog::info("Loaded animation: '{}' ({:.2f}s)", clip.name, clip.duration); animator->addClip(std::make_shared(std::move(clip))); } - if (!runClips.empty()) { + if (!runClips.empty()) + { animator->play("Root|Run"); } @@ -379,7 +384,7 @@ void LightKeeper::customInit() // // for (int x = 0; x < cubeCount; x++) // { - // for (int y = 0; y < cubeCount; y++) + // for (int y = 0; y < 3; y++) // { // for (int z = 0; z < cubeCount; z++) // { @@ -394,7 +399,7 @@ void LightKeeper::customInit() // // cube->GetTransform().SetWorldPosition(glm::vec3( // (x - cubeCount / 2.0f) * spacing, - // y * spacing + 5, + // y * spacing + 0, // (z - cubeCount / 2.0f) * spacing // )); // @@ -405,6 +410,37 @@ void LightKeeper::customInit() // } // } // } + + + { + auto sphereModel = ModelDoc::LoadModel( + AssetFS::GetInstance().GetFullPath("engine://sphere.fbx").generic_string(), + staticModelOptions + ); + ModelDocUtils::LogModelDocSummary(sphereModel, "sphere.fbx"); + + const auto& spherePrimitive = ModelDocUtils::GetFirstPrimitiveOrThrow(sphereModel, "game://sphere.fbx"); + + + const auto sphereTexturePath = ModelDocUtils::PickTexturePath( + sphereModel, + spherePrimitive, + AssetFS::GetInstance().GetFullPath("game://238882.png") + ); + + const auto sphereTextureID = gfxDevice.loadImageFromFile(sphereTexturePath); + sphereMaterial = materialCache.addMaterial(gfxDevice, { + .baseColor = ModelDocUtils::GetImportedBaseColor(planeModel, planePrimitive), + .textureFilteringMode =TextureFilteringMode::Anisotropic, + .diffuseTexture = sphereTextureID, + .name = ModelDocUtils::GetImportedMaterialName( + planeModel, planePrimitive, + "GroundPlaneMaterial"), + }); + + sphereMesh = meshCache.addMesh(gfxDevice, spherePrimitive.mesh); + + } } void LightKeeper::customUpdate(float dt) @@ -416,6 +452,27 @@ void LightKeeper::customUpdate(float dt) { renderer.setRenderWireframe(!renderer.getRenderWireframe()); } + + ImGui::Begin("Test"); + if (ImGui::Button("SPawn ball")) + { + auto sphere = std::make_shared("Sphere"); + sphere->AddComponent(1.5f); + auto rb = sphere->AddComponent(); + rb->SetMass(1000); + + auto meshRenderComp = sphere->AddComponent(); + meshRenderComp->SetMaterialID(sphereMaterial); + meshRenderComp->SetMeshID(sphereMesh); + + sphere->GetTransform().SetWorldPosition(0, 100, 0); + sphere->GetTransform().SetWorldScale(glm::vec3{0.015f}); + + + SceneManager::GetInstance().GetCurrentScene().Add(sphere); + SceneManager::GetInstance().GetCurrentScene().GetPhysics().RegisterGameObject(*sphere); + } + ImGui::End(); } void LightKeeper::customDraw()