feat: add prefabs

This commit is contained in:
2026-10-18 17:51:56 +02:00
parent d21c2ccfd7
commit 7df65f52b5
14 changed files with 1154 additions and 494 deletions
+39 -19
View File
@@ -31,6 +31,7 @@
#include <memory>
#include <optional>
#include <string>
#include <vector>
namespace {
// The visible ground plane is at y = -1
@@ -268,11 +269,12 @@ namespace {
float top;
};
void CreateWall(Scene& scene, GfxDevice& gfxDevice, RenderResources& resources, const std::string& name,
std::vector<GameObject*> 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;
std::vector<GameObject*> pieces;
const auto createPiece = [&](const std::string& suffix, float from, float to, float bottom, float top)
{
@@ -285,13 +287,14 @@ namespace {
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);
pieces.push_back(
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;
return pieces;
}
const float openingStart = opening->offset - opening->width * 0.5f;
@@ -300,6 +303,7 @@ namespace {
createPiece("_Right", openingEnd, halfLength, 0.0f, height);
createPiece("_Below", openingStart, openingEnd, 0.0f, opening->bottom);
createPiece("_Above", openingStart, openingEnd, opening->top, height);
return pieces;
}
GameObject* CreateCeilingLight(Scene& scene, GfxDevice& gfxDevice, RenderResources& resources,
@@ -336,26 +340,40 @@ namespace {
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);
GameObject* house = scene.CreateGameObject("House");
house->GetTransform().SetWorldPosition(center);
const auto addToHouse = [&](GameObject* object)
{
object->GetTransform().SetParent(&house->GetTransform(), true);
};
const auto addWallToHouse = [&](const std::vector<GameObject*>& pieces)
{
for (GameObject* piece : pieces) {
addToHouse(piece);
}
};
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});
addToHouse(CreateBox(scene, gfxDevice, resources, "House_Floor", center + glm::vec3{0.0f, 0.03f, 0.0f},
{width, 0.06f, depth}, floorMaterial, RigidbodyType::Static));
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);
addWallToHouse(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}));
addWallToHouse(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}));
addWallToHouse(CreateWall(scene, gfxDevice, resources, "House_LeftWall", center - glm::vec3{width * 0.5f, 0.0f, 0.0f},
depth - 0.3f, wallHeight, false, wallMaterial));
addWallToHouse(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}));
const GameObject* ceilingLight =
addToHouse(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));
GameObject* ceilingLight =
CreateCeilingLight(scene, gfxDevice, resources, center + glm::vec3{0.0f, wallHeight - 0.06f, 0.0f});
addToHouse(ceilingLight);
// Inside, next to the door
Material switchMaterial = Material::SimpleColor(glm::vec3{0.9f}, "LightSwitchMaterial");
@@ -369,6 +387,7 @@ namespace {
auto* switchButton = lightSwitch->AddComponent<InteractableButton>();
switchButton->SetCycleColors(false);
switchButton->AddTarget(*ceilingLight);
addToHouse(lightSwitch);
GameObject* sofa = ModelSpawner::SpawnStaticModel(
scene, gfxDevice, resources, "game://sofa.glb", StaticModelOptions(),
@@ -377,6 +396,7 @@ namespace {
sofa->GetTransform().SetWorldPosition({-3.7, -1, -17.5});
sofa->GetTransform().SetWorldRotation({180, 0, 180});
sofa->GetTransform().SetWorldScale({3, 3, 3});
addToHouse(sofa);
}
void CreateFlightHelmet(Scene& scene, GfxDevice& gfxDevice, RenderResources& resources)