A 3d fps game made in OpenGL
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
Symmetry/src/game/player.c

149 lines
5.5 KiB

#include "player.h"
#include "scene.h"
#include "input.h"
#include "../common/utils.h"
#include "transform.h"
#include "camera.h"
#include "bounding_volumes.h"
#include "../common/hashmap.h"
#include "../common/log.h"
#include "entity.h"
#include "../system/config_vars.h"
#include "../system/platform.h"
#include "game.h"
#include "debug_vars.h"
void player_init(struct Player* player, struct Scene* scene)
{
struct Game_State* game_state = game_state_get();
entity_init(player, "Player", &scene->root_entity);
player->base.flags |= EF_ACTIVE;
player->base.id = 1;
player->base.type = ET_PLAYER;
struct Hashmap* config = game_state->cvars;
player->move_speed = hashmap_int_get(config, "player_move_speed");
player->move_speed_multiplier = hashmap_int_get(config, "player_move_speed_multiplier");
player->turn_speed = hashmap_int_get(config, "player_turn_speed");
player->mesh = scene_static_mesh_create(scene, "Player_Mesh", player, "sphere.symbres", MAT_BLINN);
struct Camera* player_camera = &scene->cameras[CAM_GAME];
entity_rename(player_camera, "Player_Camera");
player_camera->base.flags |= EF_ACTIVE;
player_camera->clear_color.x = 0.6f;
player_camera->clear_color.y = 0.6f;
player_camera->clear_color.z = 0.9f;
player_camera->clear_color.w = 1.f;
player->camera_node = player_camera;
// Mark player camera and mesh as transient for now. We don't need to save them to file since we recreate them here anyway
player->camera_node->base.flags |= EF_TRANSIENT;
player->mesh->base.flags |= EF_TRANSIENT;
if(player_camera->fbo == -1)
{
int render_width = hashmap_int_get(config, "render_width");
int render_height = hashmap_int_get(config, "render_height");
window_get_drawable_size(game_state->window, &render_width, &render_height);
camera_attach_fbo(player_camera, render_width, render_height, true, true, true);
}
transform_parent_set(player_camera, player, true);
vec3 cam_translation = {0.f, 1.5f, 0.f};
transform_translate(player_camera, &cam_translation, TS_LOCAL);
//vec3 cam_axis = {-1.f, 0.f, 0.f};
//transform_rotate(player_camera, &cam_axis, 85.f, TS_LOCAL);
sound_listener_set(game_state->sound, player_camera);
sound_listener_update(game_state->sound);
}
void player_destroy(struct Player* player)
{
entity_reset(player, player->base.id);
scene_entity_base_remove(game_state_get()->scene, &player->base);
player->base.flags = EF_NONE;
}
void player_update(struct Player* player, struct Scene* scene, float dt)
{
/* Look around */
static float total_pitch = 0.f;
float pitch = 0.f;
float yaw = 0.f;
float max_pitch = 80.f;
vec3 rot_axis_pitch = { 1, 0, 0 };
vec3 rot_axis_yaw = { 0, 1, 0 };
if(input_map_state_get("Turn_Up", KS_PRESSED)) pitch += player->turn_speed;
if(input_map_state_get("Turn_Down", KS_PRESSED)) pitch -= player->turn_speed;
if(input_map_state_get("Turn_Right", KS_PRESSED)) yaw += player->turn_speed;
if(input_map_state_get("Turn_Left", KS_PRESSED)) yaw -= player->turn_speed;
int cursor_yaw, cursor_pitch;
input_mouse_delta_get(&cursor_yaw, &cursor_pitch);
if(input_mouse_mode_get() != MM_RELATIVE)
{
input_mouse_mode_set(MM_RELATIVE);
cursor_yaw = cursor_pitch = 0;
}
pitch = -cursor_pitch * player->turn_speed * dt;
yaw = cursor_yaw * player->turn_speed * dt;
total_pitch += pitch;
if(total_pitch >= max_pitch)
{
total_pitch = max_pitch;
pitch = 0.f;
}
else if(total_pitch <= -max_pitch)
{
total_pitch = -max_pitch;
pitch = 0.f;
}
if(yaw != 0.f)
transform_rotate(player, &rot_axis_yaw, -yaw, TS_WORLD);
if(pitch != 0.f)
transform_rotate(player->camera_node, &rot_axis_pitch, pitch, TS_LOCAL);
/* Movement */
float move_speed = player->move_speed;
vec3 offset = {0.f, 0.f, 0.f};
if(input_map_state_get("Sprint", KS_PRESSED)) move_speed *= player->move_speed_multiplier;
if(input_map_state_get("Move_Forward", KS_PRESSED)) offset.z -= move_speed;
if(input_map_state_get("Move_Backward", KS_PRESSED)) offset.z += move_speed;
if(input_map_state_get("Move_Left", KS_PRESSED)) offset.x -= move_speed;
if(input_map_state_get("Move_Right", KS_PRESSED)) offset.x += move_speed;
if(input_map_state_get("Move_Up", KS_PRESSED)) offset.y += move_speed;
if(input_map_state_get("Move_Down", KS_PRESSED)) offset.y -= move_speed;
vec3_scale(&offset, &offset, dt);
if(offset.x != 0 || offset.y != 0 || offset.z != 0)
{
quat_mul_vec3(&offset, &player->camera_node->base.transform.rotation, &offset);
transform_translate(player, &offset, TS_LOCAL);
}
/* Aiming and Projectiles*/
if(input_mousebutton_state_get(MSB_RIGHT, KS_PRESSED))
{
int mouse_x = 0, mouse_y = 0;
platform_mouse_position_get(&mouse_x, &mouse_y);
struct Ray ray = camera_screen_coord_to_ray(player->camera_node, mouse_x, mouse_y);
log_message("Ray: %.3f, %.3f, %.3f", ray.direction.x, ray.direction.y, ray.direction.z);
struct Raycast_Result ray_result;
scene_ray_intersect(scene, &ray, &ray_result);
}
debug_vars_show_vec3("Player Position", &player->base.transform.position);
debug_vars_show_texture("Player Camera Render", player->camera_node->render_tex);
debug_vars_show_texture("Player Camera Depth", player->camera_node->depth_tex);
}