camera position fixing
This commit is contained in:
parent
7d1a5a3653
commit
fcb0280549
4 changed files with 48 additions and 12 deletions
|
|
@ -1,4 +1,3 @@
|
|||
// game/client.c - SMOOTH TERRAIN VERSION WITH DIRECTIONAL LIGHT & SHADOWS
|
||||
#include "raylib.h"
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
|
|
@ -394,6 +393,9 @@ static Vector3 v3_add(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);
|
||||
}
|
||||
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) {
|
||||
return a.x * b.x + a.y * b.y + a.z * b.z;
|
||||
}
|
||||
|
|
@ -585,6 +587,7 @@ typedef struct MsgRoomState {
|
|||
typedef struct RemotePlayer {
|
||||
int present, alive, hp;
|
||||
Vector3 pos;
|
||||
Vector3 prevPos;
|
||||
float yaw, pitch;
|
||||
uint8_t weapon;
|
||||
int16_t pistolMag, rifleMag, pistolAmmo, rifleAmmo, medkits;
|
||||
|
|
@ -717,6 +720,10 @@ int main(void) {
|
|||
Vector3 camPos = v3(0, 5.0f, 6);
|
||||
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;
|
||||
int scoped = 0;
|
||||
float fireCooldown = 0.0f;
|
||||
|
|
@ -793,6 +800,7 @@ int main(void) {
|
|||
continue;
|
||||
|
||||
RemotePlayer *p = &rp[ps->id];
|
||||
p->prevPos = p->pos;
|
||||
p->present = 1;
|
||||
p->alive = ps->alive;
|
||||
p->hp = ps->hp;
|
||||
|
|
@ -811,14 +819,9 @@ int main(void) {
|
|||
}
|
||||
|
||||
if (myId != 255 && rp[myId].present) {
|
||||
Vector3 body = rp[myId].pos;
|
||||
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);
|
||||
prevBodyPos = currentTargetBody;
|
||||
currentTargetBody = rp[myId].pos;
|
||||
interpTimer = 0.0f;
|
||||
}
|
||||
} else if (type == MSG_ITEMS && n >= (int)sizeof(MsgItems)) {
|
||||
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();
|
||||
const float sens = 0.0025f;
|
||||
yaw -= md.x * sens;
|
||||
|
|
@ -931,6 +951,14 @@ int main(void) {
|
|||
Vector3 forward = v3(sinf(viewYaw) * cosf(viewPitch), sinf(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};
|
||||
cam.position = camPos;
|
||||
cam.target = v3_add(camPos, forward);
|
||||
|
|
@ -1000,7 +1028,11 @@ int main(void) {
|
|||
for (int i = 0; i < MAX_PLAYERS; i++) {
|
||||
if (!rp[i].present)
|
||||
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 =
|
||||
(i == myId) ? (Color){80, 180, 255, 255} : (Color){255, 80, 80, 255};
|
||||
if (!rp[i].alive)
|
||||
|
|
@ -1020,7 +1052,12 @@ int main(void) {
|
|||
for (int i = 0; i < MAX_PLAYERS; i++) {
|
||||
if (!rp[i].present || !rp[i].username[0])
|
||||
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 toHead = v3_sub(head, cam.position);
|
||||
if (v3_dot(camForward, toHead) <= 0.0f)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue