camera position fixing

This commit is contained in:
Masashi 2025-12-19 11:06:12 +05:30
commit fcb0280549
4 changed files with 48 additions and 12 deletions

Binary file not shown.

View file

@ -1,4 +1,3 @@
// game/client.c - SMOOTH TERRAIN VERSION WITH DIRECTIONAL LIGHT & SHADOWS
#include "raylib.h" #include "raylib.h"
#include <math.h> #include <math.h>
#include <stdint.h> #include <stdint.h>
@ -394,6 +393,9 @@ static Vector3 v3_add(Vector3 a, Vector3 b) {
static Vector3 v3_sub(Vector3 a, Vector3 b) { static Vector3 v3_sub(Vector3 a, Vector3 b) {
return v3(a.x - b.x, a.y - b.y, a.z - b.z); return v3(a.x - b.x, a.y - b.y, a.z - b.z);
} }
static Vector3 v3_mul(Vector3 a, float s) {
return v3(a.x * s, a.y * s, a.z * s);
}
static float v3_dot(Vector3 a, Vector3 b) { static float v3_dot(Vector3 a, Vector3 b) {
return a.x * b.x + a.y * b.y + a.z * b.z; return a.x * b.x + a.y * b.y + a.z * b.z;
} }
@ -585,6 +587,7 @@ typedef struct MsgRoomState {
typedef struct RemotePlayer { typedef struct RemotePlayer {
int present, alive, hp; int present, alive, hp;
Vector3 pos; Vector3 pos;
Vector3 prevPos;
float yaw, pitch; float yaw, pitch;
uint8_t weapon; uint8_t weapon;
int16_t pistolMag, rifleMag, pistolAmmo, rifleAmmo, medkits; int16_t pistolMag, rifleMag, pistolAmmo, rifleAmmo, medkits;
@ -717,6 +720,10 @@ int main(void) {
Vector3 camPos = v3(0, 5.0f, 6); Vector3 camPos = v3(0, 5.0f, 6);
float yaw = 0.0f, pitch = 0.0f; float yaw = 0.0f, pitch = 0.0f;
Vector3 prevBodyPos = v3(0, 5.0f, 6);
Vector3 currentTargetBody = v3(0, 5.0f, 6);
float interpTimer = 0.0f;
float recoilYaw = 0.0f, recoilPitch = 0.0f, crossSpread = 0.0f; float recoilYaw = 0.0f, recoilPitch = 0.0f, crossSpread = 0.0f;
int scoped = 0; int scoped = 0;
float fireCooldown = 0.0f; float fireCooldown = 0.0f;
@ -793,6 +800,7 @@ int main(void) {
continue; continue;
RemotePlayer *p = &rp[ps->id]; RemotePlayer *p = &rp[ps->id];
p->prevPos = p->pos;
p->present = 1; p->present = 1;
p->alive = ps->alive; p->alive = ps->alive;
p->hp = ps->hp; p->hp = ps->hp;
@ -811,14 +819,9 @@ int main(void) {
} }
if (myId != 255 && rp[myId].present) { if (myId != 255 && rp[myId].present) {
Vector3 body = rp[myId].pos; prevBodyPos = currentTargetBody;
camPos.x = body.x; currentTargetBody = rp[myId].pos;
camPos.y = body.y + 1.0f; interpTimer = 0.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)) { } else if (type == MSG_ITEMS && n >= (int)sizeof(MsgItems)) {
MsgItems *m = (MsgItems *)buf; MsgItems *m = (MsgItems *)buf;
@ -843,6 +846,23 @@ int main(void) {
} }
} }
// Interpolate camera position
if (myId != 255 && rp[myId].present) {
float interpFactor = interpTimer / (1.0f / 20.0f);
if (interpFactor > 1.0f)
interpFactor = 1.0f;
Vector3 interpBody = v3_add(v3_mul(prevBodyPos, 1.0f - interpFactor),
v3_mul(currentTargetBody, interpFactor));
camPos.x = interpBody.x;
camPos.y = interpBody.y + 1.0f;
camPos.z = interpBody.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);
}
interpTimer += dt;
Vector2 md = GetMouseDelta(); Vector2 md = GetMouseDelta();
const float sens = 0.0025f; const float sens = 0.0025f;
yaw -= md.x * sens; yaw -= md.x * sens;
@ -931,6 +951,14 @@ int main(void) {
Vector3 forward = v3(sinf(viewYaw) * cosf(viewPitch), sinf(viewPitch), Vector3 forward = v3(sinf(viewYaw) * cosf(viewPitch), sinf(viewPitch),
cosf(viewYaw) * cosf(viewPitch)); cosf(viewYaw) * cosf(viewPitch));
// Offset camera position: 0.3m in front, 0.2m below
camPos = v3_add(camPos, v3_mul(forward, 0.3f));
camPos.y -= 0.2f;
// Ensure camera doesn't clip into terrain after offset
float terrain_h = get_terrain_height(camPos.x, camPos.z);
camPos.y = fmaxf(camPos.y, terrain_h + 1.5f);
Camera3D cam = {0}; Camera3D cam = {0};
cam.position = camPos; cam.position = camPos;
cam.target = v3_add(camPos, forward); cam.target = v3_add(camPos, forward);
@ -1000,7 +1028,11 @@ int main(void) {
for (int i = 0; i < MAX_PLAYERS; i++) { for (int i = 0; i < MAX_PLAYERS; i++) {
if (!rp[i].present) if (!rp[i].present)
continue; continue;
Vector3 p = rp[i].pos; float interpFactor = interpTimer / (1.0f / 20.0f);
if (interpFactor > 1.0f)
interpFactor = 1.0f;
Vector3 p = v3_add(v3_mul(rp[i].prevPos, 1.0f - interpFactor),
v3_mul(rp[i].pos, interpFactor));
Color c = Color c =
(i == myId) ? (Color){80, 180, 255, 255} : (Color){255, 80, 80, 255}; (i == myId) ? (Color){80, 180, 255, 255} : (Color){255, 80, 80, 255};
if (!rp[i].alive) if (!rp[i].alive)
@ -1020,7 +1052,12 @@ int main(void) {
for (int i = 0; i < MAX_PLAYERS; i++) { for (int i = 0; i < MAX_PLAYERS; i++) {
if (!rp[i].present || !rp[i].username[0]) if (!rp[i].present || !rp[i].username[0])
continue; continue;
Vector3 head = v3(rp[i].pos.x, rp[i].pos.y + 1.2f, rp[i].pos.z); float interpFactor = interpTimer / (1.0f / 20.0f);
if (interpFactor > 1.0f)
interpFactor = 1.0f;
Vector3 p = v3_add(v3_mul(rp[i].prevPos, 1.0f - interpFactor),
v3_mul(rp[i].pos, interpFactor));
Vector3 head = v3(p.x, p.y + 1.2f, p.z);
Vector3 camForward = v3_norm(v3_sub(cam.target, cam.position)); Vector3 camForward = v3_norm(v3_sub(cam.target, cam.position));
Vector3 toHead = v3_sub(head, cam.position); Vector3 toHead = v3_sub(head, cam.position);
if (v3_dot(camForward, toHead) <= 0.0f) if (v3_dot(camForward, toHead) <= 0.0f)

BIN
game/client.o Normal file

Binary file not shown.

View file

@ -1,4 +1,3 @@
// game/server.c - SMOOTH TERRAIN VERSION
#include <math.h> #include <math.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>