From a092c1001723bc198c05c9dea5ed24105c591de2 Mon Sep 17 00:00:00 2001 From: Masashi Date: Thu, 18 Dec 2025 21:41:17 +0530 Subject: [PATCH] BETTER TERRAIN --- game/client | Bin 30248 -> 30248 bytes game/client.c | 169 ++++++++++++++++++++++++++++++-------------------- game/server | Bin 35160 -> 35160 bytes game/server.c | 9 +-- 4 files changed, 106 insertions(+), 72 deletions(-) diff --git a/game/client b/game/client index 09033d3f38765b7bb5af2aebc2b3e6cf44ce0e1d..b57a50bfa8e44b4f4c0913b8889194a7f623074a 100755 GIT binary patch delta 8602 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 0) ? mesh.vertices[(z * size + (x - 1)) * 3 + 1] : mesh.vertices[idx * 3 + 1]; - float h_down = (z + 1 < size) ? mesh.vertices[((z + 1) * size + x) * 3 + 1] : mesh.vertices[idx * 3 + 1]; - float h_up = (z - 1 >= 0) ? mesh.vertices[((z - 1) * size + x) * 3 + 1] : mesh.vertices[idx * 3 + 1]; - + float h_right = (x + 1 < size) + ? mesh.vertices[(z * size + (x + 1)) * 3 + 1] + : mesh.vertices[idx * 3 + 1]; + float h_left = (x - 1 >= 0) ? mesh.vertices[(z * size + (x - 1)) * 3 + 1] + : mesh.vertices[idx * 3 + 1]; + float h_down = (z + 1 < size) + ? mesh.vertices[((z + 1) * size + x) * 3 + 1] + : mesh.vertices[idx * 3 + 1]; + float h_up = (z - 1 >= 0) ? mesh.vertices[((z - 1) * size + x) * 3 + 1] + : mesh.vertices[idx * 3 + 1]; + // Compute finite differences float dh_dx = (h_right - h_left) / (2.0f * TERRAIN_SCALE); float dh_dz = (h_down - h_up) / (2.0f * TERRAIN_SCALE); - + // Normal from height field: (-dh/dx, 1, -dh/dz) then normalized float nx = -dh_dx; float ny = 1.0f; float nz = -dh_dz; - + float len = sqrtf(nx * nx + ny * ny + nz * nz); if (len > 0.0001f) { mesh.normals[idx * 3 + 0] = nx / len; @@ -377,11 +383,11 @@ static Color apply_lighting_with_shadows(Color baseColor, Vector3 normal, } static Vector3 v3_normalize(Vector3 v) { - float len = sqrtf(v.x * v.x + v.y * v.y + v.z * v.z); - if (len < 0.0001f) - return (Vector3){0, 1, 0}; - return (Vector3){v.x / len, v.y / len, v.z / len}; - } + float len = sqrtf(v.x * v.x + v.y * v.y + v.z * v.z); + if (len < 0.0001f) + return (Vector3){0, 1, 0}; + return (Vector3){v.x / len, v.y / len, v.z / len}; +} // ============== VECTOR3 HELPERS ============== static Vector3 v3(float x, float y, float z) { @@ -410,24 +416,25 @@ static Vector3 v3_norm(Vector3 a) { // ============== ENHANCED LIGHTING & AMBIENT OCCLUSION ============== -// calculate_ambient_occlusion: Estimates how occluded a point is based on terrain curvature -// Samples heights in cardinal directions and computes horizon angle to terrain -// Returns occlusion factor from 0 (fully occluded) to 1 (fully lit) +// calculate_ambient_occlusion: Estimates how occluded a point is based on +// terrain curvature Samples heights in cardinal directions and computes horizon +// angle to terrain Returns occlusion factor from 0 (fully occluded) to 1 (fully +// lit) static float calculate_ambient_occlusion(Vector3 worldPos, Vector3 normal) { // AO based on terrain curvature: check if terrain rises around the point float sampleRadius = 3.0f; float aoAccum = 0.0f; int numSamples = 8; - + float centerHeight = worldPos.y; - + // Sample 8 directions around the point for (int i = 0; i < numSamples; i++) { float angle = (2.0f * 3.14159265f * (float)i) / (float)numSamples; float sx = worldPos.x + cosf(angle) * sampleRadius; float sz = worldPos.z + sinf(angle) * sampleRadius; float sh = get_terrain_height(sx, sz); - + // Check if terrain is higher relative to surface normal // Higher terrain in shadow-casting areas reduces occlusion float heightDiff = sh - centerHeight; @@ -437,53 +444,63 @@ static float calculate_ambient_occlusion(Vector3 worldPos, Vector3 normal) { aoAccum += aoAmount; } } - - float aoFactor = 1.0f - (aoAccum / (float)numSamples) * 0.6f; // 60% max occlusion - return fmaxf(0.2f, aoFactor); // Min 20% brightness + + float aoFactor = + 1.0f - (aoAccum / (float)numSamples) * 0.6f; // 60% max occlusion + return fmaxf(0.2f, aoFactor); // Min 20% brightness } -// apply_phong_lighting_per_pixel: Advanced Phong lighting with per-pixel normals -// Includes diffuse, specular highlight, and ambient occlusion for geometry detail +// apply_phong_lighting_per_pixel: Advanced Phong lighting with per-pixel +// normals Includes diffuse, specular highlight, and ambient occlusion for +// geometry detail static Color apply_phong_lighting_per_pixel(Color baseColor, Vector3 normal, Vector3 worldPos, Vector3 camPos, DirectionalLight light) { // Normalize inputs Vector3 lightDir = v3_normalize(light.direction); Vector3 normal_norm = v3_normalize(normal); - + // Compute view direction (from surface to camera) Vector3 viewDir = v3_normalize(v3_sub(camPos, worldPos)); - + // Diffuse component: Lambertian shading float diffuse = fmaxf(0.0f, -v3_dot(lightDir, normal_norm)); - + // Specular component: Blinn-Phong specular highlight - Vector3 halfVec = v3_normalize(v3_add(v3_norm((Vector3){-lightDir.x, -lightDir.y, -lightDir.z}), viewDir)); - float specular = powf(fmaxf(0.0f, v3_dot(halfVec, normal_norm)), 32.0f) * 0.5f; - + Vector3 halfVec = v3_normalize(v3_add( + v3_norm((Vector3){-lightDir.x, -lightDir.y, -lightDir.z}), viewDir)); + float specular = + powf(fmaxf(0.0f, v3_dot(halfVec, normal_norm)), 32.0f) * 0.5f; + // Ambient occlusion from terrain geometry float ao = calculate_ambient_occlusion(worldPos, normal_norm); - + // Shadow based on height (distant higher terrain casts softer shadows) - float shadowFactor = calculate_shadow_factor(worldPos, light.direction, 10.0f); - + float shadowFactor = + calculate_shadow_factor(worldPos, light.direction, 10.0f); + // Combine lighting components float brightness = light.ambientIntensity * ao; - brightness += diffuse * light.intensity * shadowFactor * (1.0f - light.ambientIntensity) * ao; - brightness += specular * light.intensity * shadowFactor * 0.6f; // Specular less affected by AO - + brightness += diffuse * light.intensity * shadowFactor * + (1.0f - light.ambientIntensity) * ao; + brightness += specular * light.intensity * shadowFactor * + 0.6f; // Specular less affected by AO + brightness = fminf(1.0f, brightness); - + // Apply brightness to base color int r = (int)(baseColor.r * brightness); int g = (int)(baseColor.g * brightness); int b = (int)(baseColor.b * brightness); - + // Clamp to valid RGB range - if (r > 255) r = 255; - if (g > 255) g = 255; - if (b > 255) b = 255; - + if (r > 255) + r = 255; + if (g > 255) + g = 255; + if (b > 255) + b = 255; + return (Color){r, g, b, baseColor.a}; } @@ -663,9 +680,12 @@ int main(void) { // Load terrain shader TerrainShader terrainShader = load_terrain_shader(); if (terrainShader.shader.id == 0) { - fprintf(stderr, "Warning: Failed to load terrain shader, using default rendering\n"); + fprintf( + stderr, + "Warning: Failed to load terrain shader, using default rendering\n"); // Fallback: Make terrain very bright red to show shader failed - terrainModel.materials[0].maps[MATERIAL_MAP_DIFFUSE].color = (Color){255, 100, 100, 255}; + terrainModel.materials[0].maps[MATERIAL_MAP_DIFFUSE].color = + (Color){255, 100, 100, 255}; } else { terrainModel.materials[0].shader = terrainShader.shader; fprintf(stderr, "Shader loaded successfully!\n"); @@ -692,12 +712,10 @@ int main(void) { Vector3 camPos = v3(0, 5.0f, 6); float yaw = 0.0f, pitch = 0.0f; - float recoilYaw = 0.0f, recoilPitch = 0.0f, crossSpread = 0.0f; - float fireCooldown = 0.0f; - int shotsInBurst = 0; - float burstResetTimer = 0.0f; - - + float recoilYaw = 0.0f, recoilPitch = 0.0f, crossSpread = 0.0f; + float fireCooldown = 0.0f; + int shotsInBurst = 0; + float burstResetTimer = 0.0f; const float pistolFireRate = 4.0f, rifleFireRate = 12.0f; const float recoilReturn = 18.0f, crossReturn = 14.0f; @@ -790,6 +808,10 @@ int main(void) { camPos.x = body.x; camPos.y = body.y + 1.0f; camPos.z = body.z + 0.0001f; + + // Prevent camera from clipping into terrain + float terrain_h = get_terrain_height(camPos.x, camPos.z); + camPos.y = fmaxf(camPos.y, terrain_h + 1.5f); } } else if (type == MSG_ITEMS && n >= (int)sizeof(MsgItems)) { MsgItems *m = (MsgItems *)buf; @@ -846,8 +868,6 @@ int main(void) { if (IsKeyPressed(KEY_SPACE)) buttons |= BTN_JUMP; - - if (myId != 255) { MsgInput in = {0}; in.type = MSG_INPUT; @@ -908,25 +928,36 @@ int main(void) { // Set up shader uniforms for terrain rendering if (terrainShader.shader.id != 0) { - // Convert light direction to shader format (should be pointing TO the light) - float lightDirArray[3] = {-dirLight.direction.x, -dirLight.direction.y, -dirLight.direction.z}; - float lightColorArray[3] = {dirLight.color.x, dirLight.color.y, dirLight.color.z}; + // Convert light direction to shader format (should be pointing TO the + // light) + float lightDirArray[3] = {-dirLight.direction.x, -dirLight.direction.y, + -dirLight.direction.z}; + float lightColorArray[3] = {dirLight.color.x, dirLight.color.y, + dirLight.color.z}; float viewPosArray[3] = {camPos.x, camPos.y, camPos.z}; // Terrain color in 0-1 range (80, 140, 70) / 255 - float terrainColorArray[3] = {80.0f/255.0f, 140.0f/255.0f, 70.0f/255.0f}; + float terrainColorArray[3] = {80.0f / 255.0f, 140.0f / 255.0f, + 70.0f / 255.0f}; // Debug mode: 0=normal lighting, 1=show normals as colors, 2=show AO only - SetShaderValue(terrainShader.shader, terrainShader.locViewPos, viewPosArray, SHADER_UNIFORM_VEC3); - SetShaderValue(terrainShader.shader, terrainShader.locLightDir, lightDirArray, SHADER_UNIFORM_VEC3); - SetShaderValue(terrainShader.shader, terrainShader.locLightColor, lightColorArray, SHADER_UNIFORM_VEC3); - SetShaderValue(terrainShader.shader, terrainShader.locLightIntensity, &dirLight.intensity, SHADER_UNIFORM_FLOAT); - SetShaderValue(terrainShader.shader, terrainShader.locAmbientIntensity, &dirLight.ambientIntensity, SHADER_UNIFORM_FLOAT); - SetShaderValue(terrainShader.shader, terrainShader.locTerrainColor, terrainColorArray, SHADER_UNIFORM_VEC3); + SetShaderValue(terrainShader.shader, terrainShader.locViewPos, + viewPosArray, SHADER_UNIFORM_VEC3); + SetShaderValue(terrainShader.shader, terrainShader.locLightDir, + lightDirArray, SHADER_UNIFORM_VEC3); + SetShaderValue(terrainShader.shader, terrainShader.locLightColor, + lightColorArray, SHADER_UNIFORM_VEC3); + SetShaderValue(terrainShader.shader, terrainShader.locLightIntensity, + &dirLight.intensity, SHADER_UNIFORM_FLOAT); + SetShaderValue(terrainShader.shader, terrainShader.locAmbientIntensity, + &dirLight.ambientIntensity, SHADER_UNIFORM_FLOAT); + SetShaderValue(terrainShader.shader, terrainShader.locTerrainColor, + terrainColorArray, SHADER_UNIFORM_VEC3); } - + // Draw terrain with shader - terrainModel.materials[0].maps[MATERIAL_MAP_DIFFUSE].color = (Color){80, 140, 70, 255}; + terrainModel.materials[0].maps[MATERIAL_MAP_DIFFUSE].color = + (Color){80, 140, 70, 255}; DrawModel(terrainModel, (Vector3){0, 0, 0}, 1.0f, WHITE); // Items with basic lighting (no shader for now to keep it simple) @@ -943,7 +974,8 @@ int main(void) { // Apply basic lighting to items Vector3 itemNormal = v3(0, 1, 0); - Color litColor = apply_lighting_with_shadows(ic, itemNormal, wi[i].pos, dirLight); + Color litColor = + apply_lighting_with_shadows(ic, itemNormal, wi[i].pos, dirLight); DrawSphere(wi[i].pos, 0.3f, litColor); } @@ -959,7 +991,8 @@ int main(void) { // Apply basic lighting to players Vector3 playerNormal = v3(0, 1, 0); - Color litPlayerColor = apply_lighting_with_shadows(c, playerNormal, p, dirLight); + Color litPlayerColor = + apply_lighting_with_shadows(c, playerNormal, p, dirLight); DrawCapsule(v3(p.x, p.y - 0.5f, p.z), v3(p.x, p.y + 0.5f, p.z), 0.35f, 8, 8, litPlayerColor); } diff --git a/game/server b/game/server index 1b9cead009e6f19583bcf60134dfe74d15ab3adf..f9cddc2ebdaac3b72e0cc239fb1d29de81633af8 100755 GIT binary patch delta 8901 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 & BTN_JUMP) { const dReal *lvel = dBodyGetLinearVel(p->body); - dBodySetLinearVel(p->body, lvel[0], 12.0f, lvel[2]); // Set upward velocity + dBodySetLinearVel(p->body, lvel[0], 12.0f, + lvel[2]); // Set upward velocity printf("Player %d jumped\n", pid); } }