Added peripheral boundaries with stone walls
This commit is contained in:
120
main.c
120
main.c
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user