Added peripheral boundaries with stone walls

This commit is contained in:
2025-09-13 15:35:31 -05:00
parent 56fa075716
commit 28f5bde1bc
61 changed files with 114 additions and 6 deletions

120
main.c
View File

@@ -116,6 +116,12 @@ static void ApplyFogShaderToModel(Model *m, Shader fog);
static BoundingBox MakeModelWorldAABB(Model m, Vector3 pos, Vector3 scale, float yawDeg);
static BoundingBox PlayerAABB(Vector3 p);
static void ResolveAgainstBoxXZ(Master* g, BoundingBox box);
static float ModelLengthXUnits(Model m);
static float ModelLengthZUnits(Model m);
static void DrawPerimeter(Model wall, float border, float scale);
static void CollidePerimeter(Master* g, Model wall, float border, float scale); // optional
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
@@ -170,8 +176,9 @@ int main(void)
// Load GLTF model (no animations)
Model wall = LoadModel("resources/3d_models/Tiny_Treats_Homely_House_1.0_FREE/Assets/gltf/fence_straight.gltf");
Vector3 wall_position = { 0.0f, 0.0f, 0.0f };
//Model wall = LoadModel("resources/3d_models/Tiny_Treats_Homely_House_1.0_FREE/Assets/gltf/fence_straight.gltf");
Model wall = LoadModel("resources/3d_models/RuinsGLB/Walls/WallNormalXL.glb");
Vector3 wall_position = { 10.0f, 0.0f, 0.0f };
float wall_yaw = 0.0f; // rotate around Y
float wall_pitch = 0.0f; // rotate around X
float wall_roll = 0.0f; // rotate around Z
@@ -369,6 +376,29 @@ int main(void)
// Collide player vs wall (XZ slide)
ResolveAgainstBoxXZ(&g, wallBox);
// put near your update logic
float B = 123;
float T = 1.0f; // wall half-thickness
float H = 4.0f; // wall height
BoundingBox walls[4] = {
// left (x = -B)
{ (Vector3){-B - T, 0.0f, -B - T}, (Vector3){-B + T, H, B + T} },
// right (x = +B)
{ (Vector3){ B - T, 0.0f, -B - T}, (Vector3){ B + T, H, B + T} },
// bottom (z = -B)
{ (Vector3){-B - T, 0.0f, -B - T}, (Vector3){ B + T, H, -B + T} },
// top (z = +B)
{ (Vector3){-B - T, 0.0f, B - T}, (Vector3){ B + T, H, B + T} },
};
for (int i = 0; i < 4; ++i) ResolveAgainstBoxXZ(&g, walls[i]);
// (Optional) debug draw inside BeginMode3D/EndMode3D:
for (int i = 0; i < 4; ++i) DrawBoundingBox(walls[i], RED);
float delta = GetFrameTime();
g.player.headLerp = Lerp(g.player.headLerp, (crouching ? CROUCH_HEIGHT : STAND_HEIGHT), 20.0f*delta);
g.player.camera.position = (Vector3){
@@ -483,6 +513,8 @@ int main(void)
RenderTrees(&g, tree, treepos, treeSize);
//DrawBillboard(g.player.camera, sign, bbPos, bbSize, WHITE); //zombie
DrawPerimeter(wall, 123.0f, 1.5f);
EndShaderMode();
// Restore opaque cutoff for anything else you draw with that material later
@@ -904,15 +936,27 @@ static BoundingBox TransformAABB(BoundingBox bb, Matrix M)
// Build world AABB for a model using the same T*R*S you render with
static BoundingBox MakeModelWorldAABB(Model m, Vector3 pos, Vector3 scale, float yawDeg)
{
BoundingBox local = ModelLocalAABB(m);
Matrix S = MatrixScale(scale.x, scale.y, scale.z);
Matrix R = MatrixRotateY(DEG2RAD * yawDeg);
Matrix T = MatrixTranslate(pos.x, pos.y, pos.z);
Matrix M = MatrixMultiply(MatrixMultiply(T, R), S); // T * R * S
Matrix SRT = MatrixMultiply(MatrixMultiply(S, R), T); // S * R * T
Matrix M = MatrixMultiply(m.transform, SRT); // model.transform * SRT
return TransformAABB(local, M);
BoundingBox out = { .min = { FLT_MAX, FLT_MAX, FLT_MAX },
.max = { -FLT_MAX, -FLT_MAX, -FLT_MAX } };
for (int i = 0; i < m.meshCount; ++i) {
BoundingBox local = GetMeshBoundingBox(m.meshes[i]);
BoundingBox world = TransformAABB(local, M);
if (world.min.x < out.min.x) out.min.x = world.min.x;
if (world.min.y < out.min.y) out.min.y = world.min.y;
if (world.min.z < out.min.z) out.min.z = world.min.z;
if (world.max.x > out.max.x) out.max.x = world.max.x;
if (world.max.y > out.max.y) out.max.y = world.max.y;
if (world.max.z > out.max.z) out.max.z = world.max.z;
}
return out;
}
// Push player out of a box on the smallest X/Z overlap (slide) and zero that velocity axis
@@ -945,3 +989,67 @@ static void ResolveAgainstBoxXZ(Master* g, BoundingBox box)
g->player.velocity.z = 0.0f;
}
}
// Length of the model along local X (used to tile segments cleanly)
static float ModelLengthXUnits(Model m) {
BoundingBox bb = ModelLocalAABB(m); // you already have this helper
return (bb.max.x - bb.min.x);
}
static float ModelLengthZUnits(Model m) {
BoundingBox bb = ModelLocalAABB(m);
return (bb.max.z - bb.min.z);
}
// Draw repeated wall segments around the perimeter (z=±border, x=±border)
static void DrawPerimeter(Model wall, float border, float scale) {
const float HALF = FLOOR_EXTENT * TILE_SIZE; // e.g. 25*5 = 125
Vector3 scl = { scale, scale, scale };
//float segLen = ModelLengthXUnits(wall) * scale;
float segLen = ModelLengthZUnits(wall) * scale;
if (segLen <= 0.001f) segLen = TILE_SIZE; // safety fallback
int count = (int)ceilf((2.0f * HALF) / segLen) + 1;
scl.x += 0.1;
scl.y += 0.1;
scl.z += 0.1;
// Top & bottom edges: fence runs along +X (yaw 0/180)
for (int i = 0; i < count; ++i) {
float x = -HALF + i * segLen;
DrawModelEx(wall, (Vector3){ x, 0.0f, border }, (Vector3){0,1,0}, 90.0f, scl, WHITE);
DrawModelEx(wall, (Vector3){ x, 0.0f, -border }, (Vector3){0,1,0}, 270.0f, scl, WHITE);
}
// Left & right edges: rotate 90° so fence runs along Z
for (int i = 0; i < count; ++i) {
float z = -HALF + i * segLen;
DrawModelEx(wall, (Vector3){ border, 0.0f, z }, (Vector3){0,1,0}, 0.0f, scl, WHITE);
DrawModelEx(wall, (Vector3){ -border, 0.0f, z }, (Vector3){0,1,0}, 180.0f, scl, WHITE);
}
}
// Optional: collide player with the same perimeter using your AABB helpers
static void CollidePerimeter(Master* g, Model wall, float border, float scale) {
const float HALF = FLOOR_EXTENT * TILE_SIZE;
const Vector3 scl = { scale, scale, scale };
float segLen = ModelLengthXUnits(wall) * scale;
if (segLen <= 0.001f) segLen = TILE_SIZE;
int count = (int)ceilf((2.0f * HALF) / segLen) + 1;
for (int i = 0; i < count; ++i) {
float x = -HALF + i * segLen;
ResolveAgainstBoxXZ(g, MakeModelWorldAABB(wall, (Vector3){ x, 0.0f, border }, scl, 0.0f));
ResolveAgainstBoxXZ(g, MakeModelWorldAABB(wall, (Vector3){ x, 0.0f, -border }, scl, 180.0f));
}
for (int i = 0; i < count; ++i) {
float z = -HALF + i * segLen;
ResolveAgainstBoxXZ(g, MakeModelWorldAABB(wall, (Vector3){ border, 0.0f, z }, scl, 90.0f));
ResolveAgainstBoxXZ(g, MakeModelWorldAABB(wall, (Vector3){ -border, 0.0f, z }, scl, 90.0f));
}
}