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));
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.