feat: add imguizmo + trigger buxfix

This commit is contained in:
2026-10-18 11:45:37 +02:00
parent 70c940c476
commit 4bd99b25d1
37 changed files with 700 additions and 58 deletions
+125 -3
View File
@@ -18,6 +18,7 @@
#include <components/FirstPersonController.h>
#include <components/Door.h>
#include <components/InteractableButton.h>
#include <components/LightToggle.h>
#include <components/TriggerLoggerComponent.h>
#include <glm/gtc/constants.hpp>
@@ -26,11 +27,13 @@
#include <spdlog/spdlog.h>
#include <memory>
#include <optional>
#include <string>
namespace {
// The visible ground plane is at y = -1
constexpr float GroundHeight = -1.0f;
constexpr float GroundHalfExtent = 25.0f;
ModelDoc::LoadOptions StaticModelOptions()
{
@@ -80,12 +83,12 @@ namespace {
planeMeshComp->SetMeshID(resources.meshes().addMesh(gfxDevice, planePrimitive.mesh));
planeMeshComp->SetMaterialID(planeMaterialID);
planeObj->GetTransform().SetWorldPosition(glm::vec3(0.f, GroundHeight, 0.f));
planeObj->GetTransform().SetWorldScale(glm::vec3(10.f, 1.f, 10.f));
planeObj->GetTransform().SetWorldScale(glm::vec3(GroundHalfExtent, 1.f, GroundHalfExtent));
// The plane mesh is flat, so the floor collider sits right below it
GameObject* groundObj = scene.CreateGameObject("GroundCollider");
groundObj->GetTransform().SetWorldPosition(glm::vec3(0.f, GroundHeight - 0.5f, 0.f));
groundObj->AddComponent<BoxCollider>(glm::vec3{10.0f, 0.5f, 10.0f});
groundObj->AddComponent<BoxCollider>(glm::vec3{GroundHalfExtent, 0.5f, GroundHalfExtent});
groundObj->AddComponent<Rigidbody>()->SetType(RigidbodyType::Static);
scene.GetPhysics().RegisterGameObject(*groundObj);
}
@@ -201,6 +204,124 @@ namespace {
button->AddComponent<InteractableButton>()->AddTarget(target);
}
struct WallOpening {
float offset;
float width;
float bottom;
float top;
};
void CreateWall(Scene& scene, GfxDevice& gfxDevice, RenderResources& resources, const std::string& name,
const glm::vec3& floorCenter, float length, float height, bool alongX, MaterialID materialID,
const std::optional<WallOpening>& opening = std::nullopt)
{
constexpr float thickness = 0.3f;
const auto createPiece = [&](const std::string& suffix, float from, float to, float bottom, float top)
{
if (to <= from || top <= bottom) {
return;
}
const float along = (from + to) * 0.5f;
const glm::vec3 alongOffset = alongX ? glm::vec3{along, 0.0f, 0.0f} : glm::vec3{0.0f, 0.0f, along};
const glm::vec3 center = floorCenter + alongOffset + glm::vec3{0.0f, (bottom + top) * 0.5f, 0.0f};
const glm::vec3 size = alongX
? glm::vec3{to - from, top - bottom, thickness}
: glm::vec3{thickness, top - bottom, to - from};
CreateBox(scene, gfxDevice, resources, name + suffix, center, size, materialID, RigidbodyType::Static);
};
const float halfLength = length * 0.5f;
if (!opening) {
createPiece("", -halfLength, halfLength, 0.0f, height);
return;
}
const float openingStart = opening->offset - opening->width * 0.5f;
const float openingEnd = opening->offset + opening->width * 0.5f;
createPiece("_Left", -halfLength, openingStart, 0.0f, height);
createPiece("_Right", openingEnd, halfLength, 0.0f, height);
createPiece("_Below", openingStart, openingEnd, 0.0f, opening->bottom);
createPiece("_Above", openingStart, openingEnd, opening->top, height);
}
GameObject* CreateCeilingLight(Scene& scene, GfxDevice& gfxDevice, RenderResources& resources,
const glm::vec3& position)
{
GameObject* lightObj = scene.CreateGameObject("CeilingLight");
lightObj->GetTransform().SetWorldPosition(position);
// Every bulb needs its own material, the toggle changes its glow
Material bulbMaterial = Material::SimpleColor(glm::vec3{1.0f, 0.95f, 0.85f}, "BulbMaterial");
auto* bulbMesh = lightObj->AddComponent<MeshRendererComponent>();
bulbMesh->SetMeshID(resources.meshes().addMesh(gfxDevice, PrimitiveMeshes::MakeBox({0.35f, 0.12f, 0.35f})));
bulbMesh->SetMaterialID(resources.materials().addMaterial(std::move(bulbMaterial)));
auto* light = lightObj->AddComponent<LightComponent>(LightType::Point);
light->SetColor(glm::vec3{1.0f, 0.82f, 0.55f});
light->SetIntensity(4.0f);
light->SetRange(7.0f);
lightObj->AddComponent<LightToggle>();
return lightObj;
}
void CreateHouse(Scene& scene, GfxDevice& gfxDevice, RenderResources& resources)
{
const MaterialID wallMaterial = AddPrototypeMaterial(gfxDevice, resources, "Light", 0.8f);
const MaterialID floorMaterial = AddPrototypeMaterial(gfxDevice, resources, "Orange", 0.7f);
const MaterialID roofMaterial = AddPrototypeMaterial(gfxDevice, resources, "Red", 0.8f);
const glm::vec3 center{0.0f, GroundHeight, -16.0f};
constexpr float width = 8.0f;
constexpr float depth = 6.0f;
constexpr float wallHeight = 3.0f;
constexpr float doorOffset = -1.5f;
constexpr float doorWidth = 1.2f;
CreateBox(scene, gfxDevice, resources, "House_Floor", center + glm::vec3{0.0f, 0.03f, 0.0f},
{width, 0.06f, depth}, floorMaterial, RigidbodyType::Static);
CreateWall(scene, gfxDevice, resources, "House_FrontWall", center + glm::vec3{0.0f, 0.0f, depth * 0.5f},
width + 0.3f, wallHeight, true, wallMaterial,
WallOpening{.offset = doorOffset, .width = doorWidth, .bottom = 0.0f, .top = 2.2f});
CreateWall(scene, gfxDevice, resources, "House_BackWall", center - glm::vec3{0.0f, 0.0f, depth * 0.5f},
width + 0.3f, wallHeight, true, wallMaterial,
WallOpening{.offset = 1.5f, .width = 1.4f, .bottom = 1.0f, .top = 2.0f});
CreateWall(scene, gfxDevice, resources, "House_LeftWall", center - glm::vec3{width * 0.5f, 0.0f, 0.0f},
depth - 0.3f, wallHeight, false, wallMaterial);
CreateWall(scene, gfxDevice, resources, "House_RightWall", center + glm::vec3{width * 0.5f, 0.0f, 0.0f},
depth - 0.3f, wallHeight, false, wallMaterial,
WallOpening{.offset = 0.0f, .width = 1.6f, .bottom = 1.0f, .top = 2.0f});
CreateBox(scene, gfxDevice, resources, "House_Roof", center + glm::vec3{0.0f, wallHeight + 0.15f, 0.0f},
{width + 0.8f, 0.3f, depth + 0.8f}, roofMaterial, RigidbodyType::Static);
const GameObject* ceilingLight =
CreateCeilingLight(scene, gfxDevice, resources, center + glm::vec3{0.0f, wallHeight - 0.06f, 0.0f});
// Inside, next to the door
Material switchMaterial = Material::SimpleColor(glm::vec3{0.9f}, "LightSwitchMaterial");
switchMaterial.roughnessFactor = 0.5f;
const glm::vec3 switchPosition =
center + glm::vec3{doorOffset + doorWidth * 0.5f + 0.4f, 1.3f, depth * 0.5f - 0.15f - 0.03f};
GameObject* lightSwitch = CreateBox(scene, gfxDevice, resources, "LightSwitch", switchPosition,
{0.12f, 0.2f, 0.06f},
resources.materials().addMaterial(std::move(switchMaterial)),
RigidbodyType::Static);
auto* switchButton = lightSwitch->AddComponent<InteractableButton>();
switchButton->SetCycleColors(false);
switchButton->AddTarget(*ceilingLight);
GameObject* sofa = ModelSpawner::SpawnStaticModel(
scene, gfxDevice, resources, "game://sofa.glb", StaticModelOptions(),
"Sofa"
);
sofa->GetTransform().SetWorldPosition({-3.7, -1, -17.5});
sofa->GetTransform().SetWorldRotation({180, 0, 180});
sofa->GetTransform().SetWorldScale({3, 3, 3});
}
void CreateFlightHelmet(Scene& scene, GfxDevice& gfxDevice, RenderResources& resources)
{
GameObject* helmetObj = ModelSpawner::SpawnStaticModel(
@@ -323,10 +444,11 @@ MainSceneObjects BuildMainScene(Scene& scene, GfxDevice& gfxDevice, RenderResour
CreateParkourCourse(scene, gfxDevice, resources);
CreateFlightHelmet(scene, gfxDevice, resources);
CreateTree(scene, gfxDevice, resources);
CreateCapybara(scene, gfxDevice, resources);
// CreateCapybara(scene, gfxDevice, resources);
CreateTriggerZone(scene);
const GameObject* door = CreateDoorway(scene, gfxDevice, resources);
CreateButton(scene, gfxDevice, resources, *door);
CreateHouse(scene, gfxDevice, resources);
CreatePlayer(scene, objects);
LoadSpawnBallResources(gfxDevice, resources, objects);