134 lines
4.2 KiB
C
134 lines
4.2 KiB
C
// playerController.c
|
|
#include "raylib.h"
|
|
#include "raymath.h"
|
|
#include "playerController.h"
|
|
#include "blockTypes.h"
|
|
#include "world.h"
|
|
#include <math.h>
|
|
|
|
inline int FloorDiv(int a, int b) {
|
|
return (a >= 0) ? (a / b) : ((a - b + 1) / b);
|
|
}
|
|
|
|
void UpdatePlayer(Player *player) {
|
|
Vector2 mouseDelta = GetMouseDelta();
|
|
player->playerOrientation.x += mouseDelta.x * -0.002f;
|
|
player->playerOrientation.y += mouseDelta.y * -0.002f;
|
|
|
|
float limit = PI / 1.8f;
|
|
if (player->playerOrientation.y > limit) player->playerOrientation.y = limit;
|
|
if (player->playerOrientation.y < -limit) player->playerOrientation.y = -limit;
|
|
|
|
float yaw = player->playerOrientation.x;
|
|
float pitch = player->playerOrientation.y;
|
|
|
|
player->forward = (Vector3){
|
|
cosf(pitch) * sinf(yaw),
|
|
sinf(pitch),
|
|
cosf(pitch) * cosf(yaw)
|
|
};
|
|
|
|
player->right = (Vector3){
|
|
sinf(yaw - PI/2.0f),
|
|
0.0f,
|
|
cosf(yaw - PI/2.0f)
|
|
};
|
|
|
|
Vector3 movement = {0};
|
|
if (IsKeyDown(KEY_W)) movement = Vector3Add(movement, player->forward);
|
|
if (IsKeyDown(KEY_S)) movement = Vector3Subtract(movement, player->forward);
|
|
if (IsKeyDown(KEY_A)) movement = Vector3Subtract(movement, player->right);
|
|
if (IsKeyDown(KEY_D)) movement = Vector3Add(movement, player->right);
|
|
if (IsKeyDown(KEY_SPACE)) movement.y += 1.0f;
|
|
if (IsKeyDown(KEY_LEFT_SHIFT)) movement.y -= 1.0f;
|
|
|
|
if (Vector3Length(movement) > 0.0f)
|
|
movement = Vector3Scale(Vector3Normalize(movement), player->moveSpeed * GetFrameTime());
|
|
|
|
player->mapPosition = Vector3Add(player->mapPosition, movement);
|
|
player->camera.position = player->mapPosition;
|
|
player->camera.target = Vector3Add(player->mapPosition, player->forward);
|
|
}
|
|
|
|
RaycastHit GetPlayerRaycastHit(Player *player, World *world, float maxDistance) {
|
|
RaycastHit result = {0};
|
|
Vector3 origin = Vector3Add(player->camera.position, Vector3Scale(player->forward, 0.001f));
|
|
Vector3 dir = Vector3Normalize(player->forward);
|
|
|
|
int x = (int)floorf(origin.x);
|
|
int y = (int)floorf(origin.y);
|
|
int z = (int)floorf(origin.z);
|
|
|
|
int stepX = (dir.x > 0) ? 1 : -1;
|
|
int stepY = (dir.y > 0) ? 1 : -1;
|
|
int stepZ = (dir.z > 0) ? 1 : -1;
|
|
|
|
float tMaxX = ((stepX > 0 ? (x + 1) : x) - origin.x) / dir.x;
|
|
float tMaxY = ((stepY > 0 ? (y + 1) : y) - origin.y) / dir.y;
|
|
float tMaxZ = ((stepZ > 0 ? (z + 1) : z) - origin.z) / dir.z;
|
|
|
|
float tDeltaX = fabsf(1.0f / dir.x);
|
|
float tDeltaY = fabsf(1.0f / dir.y);
|
|
float tDeltaZ = fabsf(1.0f / dir.z);
|
|
|
|
float t = 0.0f;
|
|
Vector3 lastNormal = {0};
|
|
|
|
for (int i = 0; i < (int)(maxDistance * 3); i++) {
|
|
int chunkX = FloorDiv(x, CHUNK_SIZE_X);
|
|
int chunkZ = FloorDiv(z, CHUNK_SIZE_Z);
|
|
Chunk *chunk = GetChunk(world, chunkX, chunkZ);
|
|
|
|
if (chunk) {
|
|
int localX = x - chunkX * CHUNK_SIZE_X;
|
|
int localY = y;
|
|
int localZ = z - chunkZ * CHUNK_SIZE_Z;
|
|
|
|
if (localX >= 0 && localX < CHUNK_SIZE_X &&
|
|
localY >= 0 && localY < CHUNK_SIZE_Y &&
|
|
localZ >= 0 && localZ < CHUNK_SIZE_Z) {
|
|
|
|
Block block = chunk->blocks[localX][localY][localZ];
|
|
if (block.type != BLOCK_AIR) {
|
|
result.hit = true;
|
|
result.hitBlockX = x;
|
|
result.hitBlockY = y;
|
|
result.hitBlockZ = z;
|
|
result.normal = lastNormal;
|
|
result.chunkX = chunkX;
|
|
result.chunkZ = chunkZ;
|
|
result.t = t;
|
|
|
|
// For visual debugging
|
|
result.position = Vector3Add((Vector3){x, y, z}, Vector3Scale(lastNormal, 0.5f));
|
|
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
// DDA step
|
|
if (tMaxX < tMaxY && tMaxX < tMaxZ) {
|
|
x += stepX;
|
|
t = tMaxX;
|
|
tMaxX += tDeltaX;
|
|
lastNormal = (Vector3){-stepX, 0, 0};
|
|
} else if (tMaxY < tMaxZ) {
|
|
y += stepY;
|
|
t = tMaxY;
|
|
tMaxY += tDeltaY;
|
|
lastNormal = (Vector3){0, -stepY, 0};
|
|
} else {
|
|
z += stepZ;
|
|
t = tMaxZ;
|
|
tMaxZ += tDeltaZ;
|
|
lastNormal = (Vector3){0, 0, -stepZ};
|
|
}
|
|
|
|
if (t > maxDistance) break;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|