more reformatting

This commit is contained in:
Bailey Harrison 2023-05-02 12:02:43 +01:00
parent bf6c8d8a02
commit 56b8daa0bf
13 changed files with 456 additions and 474 deletions

View File

@ -193,7 +193,7 @@ RemoveBracesLLVM: false
RequiresClausePosition: OwnLine RequiresClausePosition: OwnLine
SeparateDefinitionBlocks: Leave SeparateDefinitionBlocks: Leave
ShortNamespaceLines: 1 ShortNamespaceLines: 1
SortIncludes: CaseSensitive SortIncludes: false
SortJavaStaticImport: Before SortJavaStaticImport: Before
SortUsingDeclarations: true SortUsingDeclarations: true
SpaceAfterCStyleCast: false SpaceAfterCStyleCast: false

View File

@ -35,7 +35,7 @@ class Scene {
size_t GetComponentSignaturePosition(size_t hash); size_t GetComponentSignaturePosition(size_t hash);
template <typename T> template <typename T>
void registerComponent() { void RegisterComponent() {
size_t hash = typeid(T).hash_code(); size_t hash = typeid(T).hash_code();
assert(component_arrays_.contains(hash) == false && assert(component_arrays_.contains(hash) == false &&
"Registering component type more than once."); "Registering component type more than once.");

View File

@ -2,9 +2,10 @@
#define ENGINE_INCLUDE_SYSTEMS_COLLISIONS_H_ #define ENGINE_INCLUDE_SYSTEMS_COLLISIONS_H_
#include <cstdint> #include <cstdint>
#include <glm/mat4x4.hpp>
#include <vector> #include <vector>
#include <glm/mat4x4.hpp>
#include "components/collider.h" #include "components/collider.h"
#include "ecs_system.h" #include "ecs_system.h"
@ -28,7 +29,6 @@ class PhysicsSystem : public System {
private: private:
// dynamic arrays to avoid realloc on every frame // dynamic arrays to avoid realloc on every frame
// entity, aabb, is_trigger // entity, aabb, is_trigger
std::vector<std::tuple<uint32_t, AABB, bool>> static_aabbs_{}; std::vector<std::tuple<uint32_t, AABB, bool>> static_aabbs_{};
std::vector<std::tuple<uint32_t, AABB, bool>> dynamic_aabbs_{}; std::vector<std::tuple<uint32_t, AABB, bool>> dynamic_aabbs_{};

View File

@ -17,9 +17,9 @@ namespace engine {
// ecs configuration: // ecs configuration:
registerComponent<TransformComponent>(); RegisterComponent<TransformComponent>();
registerComponent<RenderableComponent>(); RegisterComponent<RenderableComponent>();
registerComponent<ColliderComponent>(); RegisterComponent<ColliderComponent>();
// Order here matters: // Order here matters:
RegisterSystem<TransformSystem>(); RegisterSystem<TransformSystem>();

View File

@ -1,183 +1,175 @@
#include "camera_controller.hpp" #include "camera_controller.hpp"
#include "application.h"
#include "window.h"
#include "input_manager.h"
#include "scene_manager.h"
#include "scene.h"
#include "components/transform.h"
#include "components/collider.h"
#include "log.h"
#include <glm/trigonometric.hpp>
#include <glm/gtc/constants.hpp> #include <glm/gtc/constants.hpp>
#include <glm/gtc/quaternion.hpp> #include <glm/gtc/quaternion.hpp>
#include <glm/gtx/rotate_vector.hpp> #include <glm/gtx/rotate_vector.hpp>
#include <glm/trigonometric.hpp>
#include "application.h"
#include "components/collider.h"
#include "components/transform.h"
#include "input_manager.h"
#include "log.h"
#include "scene.h"
#include "scene_manager.h"
#include "window.h"
CameraControllerSystem::CameraControllerSystem(engine::Scene* scene) CameraControllerSystem::CameraControllerSystem(engine::Scene* scene)
: System(scene, { typeid(engine::TransformComponent).hash_code(), typeid(CameraControllerComponent).hash_code() }) : System(scene, {typeid(engine::TransformComponent).hash_code(),
{ typeid(CameraControllerComponent).hash_code()}) {}
}
void CameraControllerSystem::OnUpdate(float ts) void CameraControllerSystem::OnUpdate(float ts) {
{ if (t == nullptr || c == nullptr || col == nullptr) {
for (uint32_t entity : entities_) {
t = scene_->GetComponent<engine::TransformComponent>(entity);
col = scene_->GetComponent<engine::ColliderComponent>(entity);
c = scene_->GetComponent<CameraControllerComponent>(entity);
break;
}
if (t == nullptr) return;
if (c == nullptr) return;
if (col == nullptr) return;
}
if (t == nullptr || c == nullptr || col == nullptr) { const float dt = ts;
for (uint32_t entity : entities_) {
t = scene_->GetComponent<engine::TransformComponent>(entity);
col = scene_->GetComponent<engine::ColliderComponent>(entity);
c = scene_->GetComponent<CameraControllerComponent>(entity);
break;
}
if (t == nullptr) return;
if (c == nullptr) return;
if (col == nullptr) return;
}
// calculate new position
// use one unit per meter constexpr float G = 9.8f;
const float kMaxSlopeAngle = glm::cos(glm::radians(20.0f));
constexpr float kFloorSinkLevel =
0.05f; // how far into the floor to ground the player
const float dt = ts; glm::vec3 norm = c->last_collision_normal;
constexpr float G = 9.8f; glm::vec3 dir =
const float MAX_SLOPE_ANGLE = glm::cos(glm::radians(20.0f)); glm::normalize(glm::rotateY(glm::vec3{1.0f, 0.0f, 0.0f}, c->yaw) +
// constexpr float MAX_SLOPE_ANGLE = glm::radians(1000.0f); // treat every collider as a floor, (TODO: get wall collisions working so this can be removed) glm::rotateY(glm::vec3{0.0f, 0.0f, 1.0f}, c->yaw));
constexpr float FLOOR_SINK_LEVEL = 0.05f; // how far into the floor to ground the player const float slope = glm::dot(dir, norm);
glm::vec3 norm = c->lastCollisionNormal; bool is_sliding = false;
glm::vec3 dir = glm::normalize(glm::rotateY(glm::vec3{ 1.0f, 0.0f, 0.0f }, c->m_yaw) + glm::rotateY(glm::vec3{ 0.0f, 0.0f, 1.0f }, c->m_yaw)); if (c->just_collided) {
const float slope = glm::dot(dir, norm); if (slope > kMaxSlopeAngle) {
// slide across wall
is_sliding = true;
} else {
if (c->dy < 0.0f && c->is_grounded == false) {
// in the ground, push up a bit
float floorY = c->last_collision_point.y;
t->position.y = floorY + 1.5f - kFloorSinkLevel;
c->dy = 0.0f;
c->is_grounded = true;
}
}
}
bool isSliding = false; if (c->just_collided == false && slope <= kMaxSlopeAngle) {
// just stopped colliding with a floor collider
c->is_grounded = false;
}
if (c->justCollided) { if (c->is_grounded == false) c->dy -= G * dt;
if (slope > MAX_SLOPE_ANGLE) {
// slide across wall
isSliding = true;
} else {
if (c->dy < 0.0f && c->isGrounded == false) {
// in the ground, push up a bit
float floorY = c->lastCollisionPoint.y;
t->position.y = floorY + 1.5f - FLOOR_SINK_LEVEL;
c->dy = 0.0f;
c->isGrounded = true;
}
}
}
if (c->justCollided == false && slope <= MAX_SLOPE_ANGLE) { // jumping
// just stopped colliding with a floor collider constexpr float JUMPVEL =
c->isGrounded = false; (float)2.82231110971133017648; // std::sqrt(2 * G * JUMPHEIGHT);
} if (scene_->app()->input_manager()->GetButton("jump") &&
c->is_grounded == true) {
c->dy = JUMPVEL;
}
if (c->isGrounded == false) if (scene_->app()->window()->GetButton(engine::inputs::MouseButton::M_LEFT)) {
c->dy -= G * dt; c->dy += dt * c->kThrust;
}
// jumping // in metres per second
constexpr float JUMPVEL = (float)2.82231110971133017648; //std::sqrt(2 * G * JUMPHEIGHT); float speed = c->kWalkSpeed;
if (scene_->app()->input_manager()->GetButton("jump") && c->isGrounded == true) { if (scene_->app()->input_manager()->GetButton("sprint")) speed *= 10.0f;
c->dy = JUMPVEL;
}
if (scene_->app()->window()->GetButton(engine::inputs::MouseButton::M_LEFT)) { float dx = scene_->app()->input_manager()->GetAxis("movex");
c->dy += dt * c->thrust; float dz = (-scene_->app()->input_manager()->GetAxis("movey"));
}
// in metres per second // calculate new pitch and yaw
float SPEED = c->walk_speed;
if (scene_->app()->input_manager()->GetButton("sprint")) SPEED *= 10.0f;
float dx = scene_->app()->input_manager()->GetAxis("movex"); constexpr float kMaxPitch = glm::half_pi<float>();
float dz = (-scene_->app()->input_manager()->GetAxis("movey")); constexpr float kMinPitch = -kMaxPitch;
// calculate new pitch and yaw float d_pitch = scene_->app()->input_manager()->GetAxis("looky") * -1.0f *
c->kCameraSensitivity;
c->pitch += d_pitch;
if (c->pitch <= kMinPitch || c->pitch >= kMaxPitch) {
c->pitch -= d_pitch;
}
c->yaw += scene_->app()->input_manager()->GetAxis("lookx") * -1.0f *
c->kCameraSensitivity;
constexpr float MAX_PITCH = glm::half_pi<float>(); // update position relative to camera direction in xz plane
constexpr float MIN_PITCH = -MAX_PITCH; const glm::vec3 d2x_rotated = glm::rotateY(glm::vec3{dx, 0.0f, 0.0f}, c->yaw);
const glm::vec3 d2z_rotated = glm::rotateY(glm::vec3{0.0f, 0.0f, dz}, c->yaw);
glm::vec3 h_vel = (d2x_rotated + d2z_rotated);
if (is_sliding) {
h_vel = glm::vec3{norm.z, 0.0f, -norm.x};
}
h_vel *= speed;
t->position += h_vel * dt;
t->position.y += c->dy * dt;
float dPitch = scene_->app()->input_manager()->GetAxis("looky") * -1.0f * c->m_cameraSensitivity; constexpr float kMaxDistanceFromOrigin = 10000.0f;
c->m_pitch += dPitch;
if (c->m_pitch <= MIN_PITCH || c->m_pitch >= MAX_PITCH) {
c->m_pitch -= dPitch;
}
c->m_yaw += scene_->app()->input_manager()->GetAxis("lookx") * -1.0f * c->m_cameraSensitivity;
// update position relative to camera direction in xz plane if (glm::length(t->position) > kMaxDistanceFromOrigin) {
const glm::vec3 d2xRotated = glm::rotateY(glm::vec3{ dx, 0.0f, 0.0f }, c->m_yaw); t->position = {0.0f, 5.0f, 0.0f};
const glm::vec3 d2zRotated = glm::rotateY(glm::vec3{ 0.0f, 0.0f, dz }, c->m_yaw); c->dy = 0.0f;
glm::vec3 hVel = (d2xRotated + d2zRotated); }
if (isSliding) {
hVel = glm::vec3{norm.z, 0.0f, -norm.x};
}
hVel *= SPEED;
t->position += hVel * dt;
t->position.y += c->dy * dt;
constexpr float MAX_DISTANCE_FROM_ORIGIN = 10000.0f; /* ROTATION STUFF */
if (glm::length(t->position) > MAX_DISTANCE_FROM_ORIGIN) { // pitch quaternion
t->position = { 0.0f, 5.0f, 0.0f }; const float half_pitch = c->pitch / 2.0f;
c->dy = 0.0f; glm::quat pitch_quat{};
} pitch_quat.x = glm::sin(half_pitch);
pitch_quat.y = 0.0f;
pitch_quat.z = 0.0f;
pitch_quat.w = glm::cos(half_pitch);
/* ROTATION STUFF */ // yaw quaternion
const float half_yaw = c->yaw / 2.0f;
glm::quat yaw_quat{};
yaw_quat.x = 0.0f;
yaw_quat.y = glm::sin(half_yaw);
yaw_quat.z = 0.0f;
yaw_quat.w = glm::cos(half_yaw);
// pitch quaternion // update rotation
const float halfPitch = c->m_pitch / 2.0f; t->rotation = yaw_quat * pitch_quat;
glm::quat pitchQuat{};
pitchQuat.x = glm::sin(halfPitch);
pitchQuat.y = 0.0f;
pitchQuat.z = 0.0f;
pitchQuat.w = glm::cos(halfPitch);
// yaw quaternion /* user interface inputs */
const float halfYaw = c->m_yaw / 2.0f;
glm::quat yawQuat{};
yawQuat.x = 0.0f;
yawQuat.y = glm::sin(halfYaw);
yawQuat.z = 0.0f;
yawQuat.w = glm::cos(halfYaw);
// update rotation if (scene_->app()->window()->GetKeyPress(engine::inputs::Key::K_P)) {
t->rotation = yawQuat * pitchQuat; std::string pos_string{"x: " + std::to_string(t->position.x) +
" y: " + std::to_string(t->position.y) +
" z: " + std::to_string(t->position.z)};
LOG_INFO("position {}", pos_string);
}
if (scene_->app()->window()->GetKeyPress(engine::inputs::Key::K_R)) {
t->position = {0.0f, 5.0f, 0.0f};
c->dy = 0.0f;
}
/* user interface inputs */ if (scene_->app()->input_manager()->GetButtonPress("fullscreen")) {
scene_->app()->window()->ToggleFullscreen();
}
if (scene_->app()->window()->GetKeyPress(engine::inputs::Key::K_P)) { if (scene_->app()->input_manager()->GetButtonPress("exit")) {
std::string pos_string{ scene_->app()->window()->SetCloseFlag();
"x: " + std::to_string(t->position.x) + }
" y: " + std::to_string(t->position.y) +
" z: " + std::to_string(t->position.z)
};
//scene_->app()->window()->InfoBox("POSITION", pos_string);
LOG_INFO("position: " + pos_string);
}
if (scene_->app()->window()->GetKeyPress(engine::inputs::Key::K_R)) {
t->position = { 0.0f, 5.0f, 0.0f };
c->dy = 0.0f;
}
if (scene_->app()->input_manager()->GetButtonPress("fullscreen")) {
scene_->app()->window()->ToggleFullscreen();
}
if (scene_->app()->input_manager()->GetButtonPress("exit")) {
scene_->app()->window()->SetCloseFlag();
}
c->justCollided = false;
c->just_collided = false;
} }
// called once per frame // called once per frame
void CameraControllerSystem::OnEvent(engine::PhysicsSystem::CollisionEvent info) void CameraControllerSystem::OnEvent(
{ engine::PhysicsSystem::CollisionEvent info) {
c->justCollided = info.is_collision_enter; c->just_collided = info.is_collision_enter;
c->lastCollisionNormal = info.normal; c->last_collision_normal = info.normal;
c->lastCollisionPoint = info.point; c->last_collision_point = info.point;
} }

View File

@ -1,41 +1,45 @@
#pragma once #ifndef ENGINE_TEST_SRC_CAMERA_CONTROLLER_H_
#define ENGINE_TEST_SRC_CAMERA_CONTROLLER_H_
#include "ecs_system.h" #include <glm/vec3.hpp>
#include "event_system.h"
#include "components/transform.h" #include "components/transform.h"
#include "ecs_system.h"
#include "event_system.h"
#include "systems/collisions.h" #include "systems/collisions.h"
struct CameraControllerComponent { struct CameraControllerComponent {
float m_cameraSensitivity = 0.007f; static constexpr float kWalkSpeed = 4.0f;
static constexpr float kThrust = 25.0f;
static constexpr float kCameraSensitivity = 0.007f;
float m_yaw = 0.0f; float yaw = 0.0f;
float m_pitch = 0.0f; float pitch = 0.0f;
float dy = 0.0f;
const float walk_speed = 4.0f; glm::vec3 last_collision_normal{};
glm::vec3 last_collision_point{};
bool isGrounded = false;
float dy = 0.0f; bool just_collided = false;
float standingHeight = 0.0f; bool is_grounded = false;
const float thrust = 25.0f;
glm::vec3 lastCollisionNormal{};
glm::vec3 lastCollisionPoint{};
bool justCollided = false;
}; };
class CameraControllerSystem : public engine::System, public engine::EventHandler<engine::PhysicsSystem::CollisionEvent> { class CameraControllerSystem
: public engine::System,
public engine::EventHandler<engine::PhysicsSystem::CollisionEvent> {
public:
CameraControllerSystem(engine::Scene* scene);
public: // engine::System overrides
CameraControllerSystem(engine::Scene* scene); void OnUpdate(float ts) override;
// engine::System overrides // engine::EventHandler overrides
void OnUpdate(float ts) override; void OnEvent(engine::PhysicsSystem::CollisionEvent info) override;
// engine::EventHandler overrides engine::TransformComponent* t = nullptr;
void OnEvent(engine::PhysicsSystem::CollisionEvent info) override; engine::ColliderComponent* col = nullptr;
CameraControllerComponent* c = nullptr;
engine::TransformComponent* t = nullptr;
engine::ColliderComponent* col = nullptr;
CameraControllerComponent* c = nullptr;
}; };
#endif

View File

@ -1,132 +1,148 @@
#include "game.hpp" #include "game.hpp"
#include "config.h"
#include "camera_controller.hpp"
#include "meshgen.hpp"
#include "application.h" #include "application.h"
#include "window.h" #include "camera_controller.hpp"
#include "input_manager.h"
#include "scene_manager.h"
#include "scene.h"
#include "components/transform.h"
#include "components/collider.h" #include "components/collider.h"
#include "components/renderable.h" #include "components/renderable.h"
#include "systems/transform.h" #include "components/transform.h"
#include "systems/render.h" #include "input_manager.h"
#include "meshgen.hpp"
#include "resources/material.h" #include "resources/material.h"
#include "resources/texture.h" #include "resources/texture.h"
#include "scene.h"
#include "scene_manager.h"
#include "systems/render.h"
#include "systems/transform.h"
#include "util/model_loader.h" #include "util/model_loader.h"
#include "window.h"
static void configureInputs(engine::InputManager* inputManager) #include "config.h"
{
// user interface mappings static void ConfigureInputs(engine::InputManager* input_manager) {
inputManager->AddInputButton("fullscreen", engine::inputs::Key::K_F11); // user interface mappings
inputManager->AddInputButton("exit", engine::inputs::Key::K_ESCAPE); input_manager->AddInputButton("fullscreen", engine::inputs::Key::K_F11);
// game buttons input_manager->AddInputButton("exit", engine::inputs::Key::K_ESCAPE);
inputManager->AddInputButton("fire", engine::inputs::MouseButton::M_LEFT); // game buttons
inputManager->AddInputButton("aim", engine::inputs::MouseButton::M_RIGHT); input_manager->AddInputButton("fire", engine::inputs::MouseButton::M_LEFT);
inputManager->AddInputButton("jump", engine::inputs::Key::K_SPACE); input_manager->AddInputButton("aim", engine::inputs::MouseButton::M_RIGHT);
inputManager->AddInputButton("sprint", engine::inputs::Key::K_LSHIFT); input_manager->AddInputButton("jump", engine::inputs::Key::K_SPACE);
// game movement input_manager->AddInputButton("sprint", engine::inputs::Key::K_LSHIFT);
inputManager->AddInputButtonAsAxis("movex", engine::inputs::Key::K_D, engine::inputs::Key::K_A); // game movement
inputManager->AddInputButtonAsAxis("movey", engine::inputs::Key::K_W, engine::inputs::Key::K_S); input_manager->AddInputButtonAsAxis("movex", engine::inputs::Key::K_D,
// looking around engine::inputs::Key::K_A);
inputManager->AddInputAxis("lookx", engine::inputs::MouseAxis::X); input_manager->AddInputButtonAsAxis("movey", engine::inputs::Key::K_W,
inputManager->AddInputAxis("looky", engine::inputs::MouseAxis::Y); engine::inputs::Key::K_S);
// looking around
input_manager->AddInputAxis("lookx", engine::inputs::MouseAxis::X);
input_manager->AddInputAxis("looky", engine::inputs::MouseAxis::Y);
} }
void playGame(GameSettings settings) void PlayGame(GameSettings settings) {
{ LOG_INFO("FPS limiter: {}", settings.enable_frame_limiter ? "ON" : "OFF");
LOG_INFO("FPS limiter: {}", settings.enableFrameLimiter ? "ON" : "OFF"); LOG_INFO("Graphics Validation: {}",
LOG_INFO("Graphics Validation: {}", settings.enableValidation ? "ON" : "OFF"); settings.enable_validation ? "ON" : "OFF");
engine::gfx::GraphicsSettings graphicsSettings{}; engine::gfx::GraphicsSettings graphics_settings{};
graphicsSettings.enable_validation = settings.enableValidation; graphics_settings.enable_validation = settings.enable_validation;
graphicsSettings.vsync = true; graphics_settings.vsync = true;
graphicsSettings.wait_for_present = false; graphics_settings.wait_for_present = false;
graphicsSettings.msaa_level = engine::gfx::MSAALevel::kOff; graphics_settings.msaa_level = engine::gfx::MSAALevel::kOff;
engine::Application app(PROJECT_NAME, PROJECT_VERSION, graphicsSettings); engine::Application app(PROJECT_NAME, PROJECT_VERSION, graphics_settings);
app.SetFrameLimiter(settings.enableFrameLimiter); app.SetFrameLimiter(settings.enable_frame_limiter);
// configure window // configure window
app.window()->SetRelativeMouseMode(true); app.window()->SetRelativeMouseMode(true);
configureInputs(app.input_manager());
auto myScene = app.scene_manager()->CreateEmptyScene(); ConfigureInputs(app.input_manager());
/* create camera */ auto my_scene = app.scene_manager()->CreateEmptyScene();
{
myScene->registerComponent<CameraControllerComponent>();
myScene->RegisterSystem<CameraControllerSystem>();
auto camera = myScene->CreateEntity("camera"); /* create camera */
myScene->GetComponent<engine::TransformComponent>(camera)->position = { 0.0f, 10.0f, 0.0f }; {
auto cameraCollider = myScene->AddComponent<engine::ColliderComponent>(camera); my_scene->RegisterComponent<CameraControllerComponent>();
cameraCollider->is_static = false; my_scene->RegisterSystem<CameraControllerSystem>();
cameraCollider->is_trigger = true;
cameraCollider->aabb = { { -0.2f, -1.5f, -0.2f }, { 0.2f, 0.2f, 0.2f} }; // Origin is at eye level
myScene->AddComponent<CameraControllerComponent>(camera);
myScene->event_system()->SubscribeToEventType<engine::PhysicsSystem::CollisionEvent>(
engine::EventSubscriberKind::kEntity, camera, myScene->GetSystem<CameraControllerSystem>()
);
auto renderSystem = myScene->GetSystem<engine::RenderSystem>(); auto camera = my_scene->CreateEntity("camera");
renderSystem->SetCameraEntity(camera); my_scene->GetComponent<engine::TransformComponent>(camera)->position = {
} 0.0f, 10.0f, 0.0f};
auto camer_collider =
my_scene->AddComponent<engine::ColliderComponent>(camera);
camer_collider->is_static = false;
camer_collider->is_trigger = true;
camer_collider->aabb = {{-0.2f, -1.5f, -0.2f},
{0.2f, 0.2f, 0.2f}}; // Origin is at eye level
my_scene->AddComponent<CameraControllerComponent>(camera);
my_scene->event_system()
->SubscribeToEventType<engine::PhysicsSystem::CollisionEvent>(
engine::EventSubscriberKind::kEntity, camera,
my_scene->GetSystem<CameraControllerSystem>());
/* shared resources */ auto render_system = my_scene->GetSystem<engine::RenderSystem>();
auto grassTexture = std::make_shared<engine::resources::Texture>( render_system->SetCameraEntity(camera);
&app.render_data_, }
app.GetResourcePath("textures/grass.jpg"),
engine::resources::Texture::Filtering::kAnisotropic
);
auto spaceTexture = std::make_shared<engine::resources::Texture>(
&app.render_data_,
app.GetResourcePath("textures/space2.png"),
engine::resources::Texture::Filtering::kAnisotropic
);
/* cube */ /* shared resources */
{ auto grass_texture = std::make_shared<engine::resources::Texture>(
uint32_t cube = myScene->CreateEntity("cube"); &app.render_data_, app.GetResourcePath("textures/grass.jpg"),
myScene->GetComponent<engine::TransformComponent>(cube)->position = glm::vec3{ -0.5f + 5.0f, -0.5f + 5.0f, -0.5f + 5.0f }; engine::resources::Texture::Filtering::kAnisotropic);
auto cubeRenderable = myScene->AddComponent<engine::RenderableComponent>(cube); auto space_texture = std::make_shared<engine::resources::Texture>(
cubeRenderable->material = std::make_shared<engine::resources::Material>(app.GetResource<engine::resources::Shader>("builtin.standard")); &app.render_data_, app.GetResourcePath("textures/space2.png"),
cubeRenderable->material->texture_ = app.GetResource<engine::resources::Texture>("builtin.white"); engine::resources::Texture::Filtering::kAnisotropic);
cubeRenderable->mesh = genCuboidMesh(app.gfxdev(), 1.0f, 1.0f, 1.0f, 1);
auto cubeCollider = myScene->AddComponent<engine::ColliderComponent>(cube);
cubeCollider->is_static = true;
cubeCollider->aabb = { { 0.0f, 0.0f, 0.0f }, { 1.0f, 1.0f, 1.0f } };
}
/* floor */ /* cube */
{ {
uint32_t floor = myScene->CreateEntity("floor"); uint32_t cube = my_scene->CreateEntity("cube");
myScene->GetComponent<engine::TransformComponent>(floor)->position = glm::vec3{-5000.0f, -1.0f, -5000.0f}; my_scene->GetComponent<engine::TransformComponent>(cube)->position =
auto floorRenderable = myScene->AddComponent<engine::RenderableComponent>(floor); glm::vec3{-0.5f + 5.0f, -0.5f + 5.0f, -0.5f + 5.0f};
floorRenderable->material = std::make_shared<engine::resources::Material>(app.GetResource<engine::resources::Shader>("builtin.standard")); auto cube_renderable =
floorRenderable->material->texture_ = grassTexture; my_scene->AddComponent<engine::RenderableComponent>(cube);
floorRenderable->mesh = genCuboidMesh(app.gfxdev(), 10000.0f, 1.0f, 10000.0f, 5000.0f); cube_renderable->material = std::make_shared<engine::resources::Material>(
floorRenderable->shown = true; app.GetResource<engine::resources::Shader>("builtin.standard"));
auto floorCollider = myScene->AddComponent<engine::ColliderComponent>(floor); cube_renderable->material->texture_ =
floorCollider->is_static = true; app.GetResource<engine::resources::Texture>("builtin.white");
floorCollider->aabb = { { 0.0f, 0.0f, 0.0f }, { 10000.0f, 1.0f, 10000.0f } }; cube_renderable->mesh = GenCuboidMesh(app.gfxdev(), 1.0f, 1.0f, 1.0f, 1);
} auto cube_collider =
my_scene->AddComponent<engine::ColliderComponent>(cube);
cube_collider->is_static = true;
cube_collider->aabb = {{0.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 1.0f}};
}
//engine::util::LoadMeshFromFile(myScene, app.GetResourcePath("models/astronaut/astronaut.dae")); /* floor */
{
uint32_t floor = my_scene->CreateEntity("floor");
my_scene->GetComponent<engine::TransformComponent>(floor)->position =
glm::vec3{-5000.0f, -1.0f, -5000.0f};
auto floor_renderable =
my_scene->AddComponent<engine::RenderableComponent>(floor);
floor_renderable->material = std::make_shared<engine::resources::Material>(
app.GetResource<engine::resources::Shader>("builtin.standard"));
floor_renderable->material->texture_ = grass_texture;
floor_renderable->mesh =
GenCuboidMesh(app.gfxdev(), 10000.0f, 1.0f, 10000.0f, 5000.0f);
floor_renderable->shown = true;
auto floor_collider =
my_scene->AddComponent<engine::ColliderComponent>(floor);
floor_collider->is_static = true;
floor_collider->aabb = {{0.0f, 0.0f, 0.0f}, {10000.0f, 1.0f, 10000.0f}};
}
/* skybox */ engine::util::LoadMeshFromFile(
{ my_scene, app.GetResourcePath("models/astronaut/astronaut.dae"));
uint32_t skybox = myScene->CreateEntity("skybox");
auto skyboxRenderable = myScene->AddComponent<engine::RenderableComponent>(skybox);
skyboxRenderable->material = std::make_unique<engine::resources::Material>(app.GetResource<engine::resources::Shader>("builtin.skybox"));
skyboxRenderable->material->texture_ = spaceTexture;
skyboxRenderable->mesh = genCuboidMesh(app.gfxdev(), 10.0f, 10.0f, 10.0f, 1.0f, true);
myScene->GetComponent<engine::TransformComponent>(skybox)->position = { -5.0f, -5.0f, -5.0f };
}
app.GameLoop(); /* skybox */
{
uint32_t skybox = my_scene->CreateEntity("skybox");
auto skybox_renderable =
my_scene->AddComponent<engine::RenderableComponent>(skybox);
skybox_renderable->material = std::make_unique<engine::resources::Material>(
app.GetResource<engine::resources::Shader>("builtin.skybox"));
skybox_renderable->material->texture_ = space_texture;
skybox_renderable->mesh =
GenCuboidMesh(app.gfxdev(), 10.0f, 10.0f, 10.0f, 1.0f, true);
my_scene->GetComponent<engine::TransformComponent>(skybox)->position = {
-5.0f, -5.0f, -5.0f};
}
app.GameLoop();
} }

View File

@ -1,8 +1,11 @@
#pragma once #ifndef ENGINE_TEST_SRC_GAME_H_
#define ENGINE_TEST_SRC_GAME_H_
struct GameSettings { struct GameSettings {
bool enableFrameLimiter; bool enable_frame_limiter;
bool enableValidation; bool enable_validation;
}; };
void playGame(GameSettings settings); void PlayGame(GameSettings settings);
#endif

View File

@ -1,42 +1,38 @@
#include "config.h" #include <string.h>
#include "game.hpp"
#include <exception>
#include <unordered_set>
// engine
#include "logger.h" #include "logger.h"
#include "window.h" #include "window.h"
// standard library #include "config.h"
#include <exception> #include "game.hpp"
#include <unordered_set>
#include <string.h>
int main(int argc, char* argv[]) int main(int argc, char* argv[]) {
{ GameSettings settings{};
settings.enable_frame_limiter = true;
settings.enable_validation = false;
if (argc >= 2) {
std::unordered_set<std::string> args{};
for (int i = 1; i < argc; i++) {
args.insert(std::string(argv[i]));
}
if (args.contains("nofpslimit")) settings.enable_frame_limiter = false;
if (args.contains("gpuvalidation")) settings.enable_validation = true;
}
GameSettings settings{}; engine::SetupLog(PROJECT_NAME);
settings.enableFrameLimiter = true;
settings.enableValidation = false;
if (argc >= 2) {
std::unordered_set<std::string> args{};
for (int i = 1; i < argc; i++) {
args.insert(std::string(argv[i]));
}
if (args.contains("nofpslimit")) settings.enableFrameLimiter = false;
if (args.contains("gpuvalidation")) settings.enableValidation = true;
}
engine::SetupLog(PROJECT_NAME); LOG_INFO("{} v{}", PROJECT_NAME, PROJECT_VERSION);
LOG_INFO("{} v{}", PROJECT_NAME, PROJECT_VERSION); try {
PlayGame(settings);
} catch (const std::exception& e) {
LOG_CRITICAL("{}", e.what());
engine::Window::ErrorBox(e.what());
return EXIT_FAILURE;
}
try { return EXIT_SUCCESS;
playGame(settings);
}
catch (const std::exception& e) {
LOG_CRITICAL("{}", e.what());
engine::Window::ErrorBox(e.what());
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
} }

View File

@ -1,158 +1,151 @@
#include "meshgen.hpp" #include "meshgen.hpp"
#include "resources/mesh.h" #include <stdexcept>
#include <glm/gtc/constants.hpp> #include <glm/gtc/constants.hpp>
#include <glm/ext.hpp> #include <glm/ext.hpp>
#include <glm/trigonometric.hpp> #include <glm/trigonometric.hpp>
#include <stdexcept> #include "resources/mesh.h"
std::unique_ptr<engine::resources::Mesh> genSphereMesh(engine::GFXDevice* gfx, float r, int detail, bool windInside, bool flipNormals) std::unique_ptr<engine::resources::Mesh> GenSphereMesh(engine::GFXDevice* gfx,
{ float r, int detail,
using namespace glm; bool wind_inside,
bool flip_normals) {
using namespace glm;
std::vector<engine::Vertex> vertices{}; std::vector<engine::Vertex> vertices{};
float angleStep = two_pi<float>() / (float)detail; const float angle_step = two_pi<float>() / (float)detail;
for (int i = 0; i < detail; i++) { for (int i = 0; i < detail; i++) {
// theta goes north-to-south // theta goes north-to-south
float theta = i * angleStep; float theta = i * angle_step;
float theta2 = theta + angleStep; float theta2 = theta + angle_step;
for (int j = 0; j < detail/2; j++) { for (int j = 0; j < detail / 2; j++) {
// phi goes west-to-east // phi goes west-to-east
float phi = j * angleStep; float phi = j * angle_step;
float phi2 = phi + angleStep; float phi2 = phi + angle_step;
vec3 top_left{ r * sin(phi) * cos(theta), vec3 top_left{r * sin(phi) * cos(theta), r * cos(phi),
r * cos(phi), r * sin(phi) * sin(theta)};
r * sin(phi) * sin(theta) }; vec3 bottom_left{r * sin(phi) * cos(theta2), r * cos(phi),
vec3 bottom_left{ r * sin(phi) * cos(theta2), r * sin(phi) * sin(theta2)};
r * cos(phi), vec3 top_right{r * sin(phi2) * cos(theta), r * cos(phi2),
r * sin(phi) * sin(theta2) }; r * sin(phi2) * sin(theta)};
vec3 top_right{ r * sin(phi2) * cos(theta), vec3 bottom_right{r * sin(phi2) * cos(theta2), r * cos(phi2),
r * cos(phi2), r * sin(phi2) * sin(theta2)};
r * sin(phi2) * sin(theta) };
vec3 bottom_right{ r * sin(phi2) * cos(theta2),
r * cos(phi2),
r * sin(phi2) * sin(theta2) };
if (windInside == false) { if (wind_inside == false) {
// tris are visible from outside the sphere // tris are visible from outside the sphere
// triangle 1 // triangle 1
vertices.push_back({ top_left, {}, {0.0f, 0.0f} }); vertices.push_back({top_left, {}, {0.0f, 0.0f}});
vertices.push_back({ bottom_left, {}, {0.0f, 1.0f} }); vertices.push_back({bottom_left, {}, {0.0f, 1.0f}});
vertices.push_back({ bottom_right, {}, {1.0f, 1.0f} }); vertices.push_back({bottom_right, {}, {1.0f, 1.0f}});
// triangle 2 // triangle 2
vertices.push_back({ top_right, {}, {1.0f, 0.0f} }); vertices.push_back({top_right, {}, {1.0f, 0.0f}});
vertices.push_back({ top_left, {}, {0.0f, 0.0f} }); vertices.push_back({top_left, {}, {0.0f, 0.0f}});
vertices.push_back({ bottom_right, {}, {1.0f, 1.0f} }); vertices.push_back({bottom_right, {}, {1.0f, 1.0f}});
} } else {
else { // tris are visible from inside the sphere
// tris are visible from inside the sphere
// triangle 1 // triangle 1
vertices.push_back({ bottom_right, {}, {1.0f, 1.0f} }); vertices.push_back({bottom_right, {}, {1.0f, 1.0f}});
vertices.push_back({ bottom_left, {}, {0.0f, 1.0f} }); vertices.push_back({bottom_left, {}, {0.0f, 1.0f}});
vertices.push_back({ top_left, {}, {0.0f, 0.0f} }); vertices.push_back({top_left, {}, {0.0f, 0.0f}});
// triangle 2
vertices.push_back({ bottom_right, {}, {1.0f, 1.0f} });
vertices.push_back({ top_left, {}, {0.0f, 0.0f} });
vertices.push_back({ top_right, {}, {1.0f, 0.0f} });
} // triangle 2
vertices.push_back({bottom_right, {}, {1.0f, 1.0f}});
vec3 vector1 = (vertices.end() - 1)->pos - (vertices.end() - 2)->pos; vertices.push_back({top_left, {}, {0.0f, 0.0f}});
vec3 vector2 = (vertices.end() - 2)->pos - (vertices.end() - 3)->pos; vertices.push_back({top_right, {}, {1.0f, 0.0f}});
vec3 norm = normalize(cross(vector2, vector1)); }
// NORMALS HAVE BEEN FIXED vec3 vector1 = (vertices.end() - 1)->pos - (vertices.end() - 2)->pos;
vec3 vector2 = (vertices.end() - 2)->pos - (vertices.end() - 3)->pos;
vec3 norm = normalize(cross(vector2, vector1));
if (flipNormals) // NORMALS HAVE BEEN FIXED
norm = -norm;
if (j == (detail / 2) - 1) if (flip_normals) norm = -norm;
norm = -norm;
for (auto it = vertices.end() - 6; it != vertices.end(); it++) { if (j == (detail / 2) - 1) norm = -norm;
it->norm = norm;
}
} for (auto it = vertices.end() - 6; it != vertices.end(); it++) {
} it->norm = norm;
}
}
}
return std::make_unique<engine::resources::Mesh>(gfx, vertices); return std::make_unique<engine::resources::Mesh>(gfx, vertices);
} }
std::unique_ptr<engine::resources::Mesh> genCuboidMesh(engine::GFXDevice* gfx, float x, float y, float z, float tiling, bool windInside) std::unique_ptr<engine::resources::Mesh> GenCuboidMesh(engine::GFXDevice* gfx,
{ float x, float y,
float z, float tiling,
bool wind_inside) {
// x goes ->
// y goes ^
// z goes into the screen
// x goes -> using namespace glm;
// y goes ^
// z goes into the screen
using namespace glm; std::vector<engine::Vertex> v{};
std::vector<engine::Vertex> v{}; // front
v.push_back({{x, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {tiling, 0.0f}});
v.push_back({{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {0.0f, 0.0f}});
v.push_back({{0.0f, y, 0.0f}, {0.0f, 0.0f, -1.0f}, {0.0f, tiling}});
v.push_back({{x, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {tiling, 0.0f}});
v.push_back({{0.0f, y, 0.0f}, {0.0f, 0.0f, -1.0f}, {0.0f, tiling}});
v.push_back({{x, y, 0.0f}, {0.0f, 0.0f, -1.0f}, {tiling, tiling}});
// front // back
v.push_back({{x, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {tiling, 0.0f}}); v.push_back({{0.0f, 0.0f, z}, {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f}});
v.push_back({{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {0.0f, 0.0f}}); v.push_back({{x, 0.0f, z}, {0.0f, 0.0f, 1.0f}, {tiling, 0.0f}});
v.push_back({{0.0f, y, 0.0f}, {0.0f, 0.0f, -1.0f}, {0.0f, tiling}}); v.push_back({{0.0f, y, z}, {0.0f, 0.0f, 1.0f}, {0.0f, tiling}});
v.push_back({{x, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {tiling, 0.0f}}); v.push_back({{x, 0.0f, z}, {0.0f, 0.0f, 1.0f}, {tiling, 0.0f}});
v.push_back({{0.0f, y, 0.0f}, {0.0f, 0.0f, -1.0f}, {0.0f, tiling}}); v.push_back({{x, y, z}, {0.0f, 0.0f, 1.0f}, {tiling, tiling}});
v.push_back({{x, y, 0.0f}, {0.0f, 0.0f, -1.0f}, {tiling, tiling}}); v.push_back({{0.0f, y, z}, {0.0f, 0.0f, 1.0f}, {0.0f, tiling}});
// back // left
v.push_back({{0.0f, 0.0f, z}, {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f}}); v.push_back({{0.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, {0.0f, 0.0f}});
v.push_back({{x, 0.0f, z}, {0.0f, 0.0f, 1.0f}, {tiling, 0.0f}}); v.push_back({{0.0f, 0.0f, x}, {-1.0f, 0.0f, 0.0f}, {0.0f, tiling}});
v.push_back({{0.0f, y, z}, {0.0f, 0.0f, 1.0f}, {0.0f, tiling}}); v.push_back({{0.0f, y, 0.0f}, {-1.0f, 0.0f, 0.0f}, {tiling, 0.0f}});
v.push_back({{x, 0.0f, z}, {0.0f, 0.0f, 1.0f}, {tiling, 0.0f}}); v.push_back({{0.0f, 0.0f, x}, {-1.0f, 0.0f, 0.0f}, {0.0f, tiling}});
v.push_back({{x, y, z}, {0.0f, 0.0f, 1.0f}, {tiling, tiling}}); v.push_back({{0.0f, y, x}, {-1.0f, 0.0f, 0.0f}, {tiling, tiling}});
v.push_back({{0.0f, y, z}, {0.0f, 0.0f, 1.0f}, {0.0f, tiling}}); v.push_back({{0.0f, y, 0.0f}, {-1.0f, 0.0f, 0.0f}, {tiling, 0.0f}});
// left // right
v.push_back({{0.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, {0.0f, 0.0f}}); v.push_back({{x, y, 0.0f}, {1.0f, 0.0f, 0.0f}, {tiling, 0.0f}});
v.push_back({{0.0f, 0.0f, x}, {-1.0f, 0.0f, 0.0f}, {0.0f, tiling}}); v.push_back({{x, 0.0f, x}, {1.0f, 0.0f, 0.0f}, {0.0f, tiling}});
v.push_back({{0.0f, y, 0.0f}, {-1.0f, 0.0f, 0.0f}, {tiling, 0.0f}}); v.push_back({{x, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 0.0f}});
v.push_back({{0.0f, 0.0f, x}, {-1.0f, 0.0f, 0.0f}, {0.0f, tiling}}); v.push_back({{x, y, 0.0f}, {1.0f, 0.0f, 0.0f}, {tiling, 0.0f}});
v.push_back({{0.0f, y, x}, {-1.0f, 0.0f, 0.0f}, {tiling, tiling}}); v.push_back({{x, y, x}, {1.0f, 0.0f, 0.0f}, {tiling, tiling}});
v.push_back({{0.0f, y, 0.0f}, {-1.0f, 0.0f, 0.0f}, {tiling, 0.0f}}); v.push_back({{x, 0.0f, x}, {1.0f, 0.0f, 0.0f}, {0.0f, tiling}});
// right // bottom
v.push_back({{x, y, 0.0f}, {1.0f, 0.0f, 0.0f}, {tiling, 0.0f}}); v.push_back({{0.0f, 0.0f, z}, {0.0f, -1.0f, 0.0f}, {0.0f, tiling}});
v.push_back({{x, 0.0f, x}, {1.0f, 0.0f, 0.0f}, {0.0f, tiling}}); v.push_back({{0.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, {0.0f, 0.0f}});
v.push_back({{x, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 0.0f}}); v.push_back({{x, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, {tiling, 0.0f}});
v.push_back({{x, y, 0.0f}, {1.0f, 0.0f, 0.0f}, {tiling, 0.0f}}); v.push_back({{x, 0.0f, z}, {0.0f, -1.0f, 0.0f}, {tiling, tiling}});
v.push_back({{x, y, x}, {1.0f, 0.0f, 0.0f}, {tiling, tiling}}); v.push_back({{0.0f, 0.0f, z}, {0.0f, -1.0f, 0.0f}, {0.0f, tiling}});
v.push_back({{x, 0.0f, x}, {1.0f, 0.0f, 0.0f}, {0.0f, tiling}}); v.push_back({{x, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, {tiling, 0.0f}});
// bottom // top
v.push_back({{0.0f, 0.0f, z}, {0.0f, -1.0f, 0.0f}, {0.0f, tiling}}); v.push_back({{x, y, 0.0f}, {0.0f, 1.0f, 0.0f}, {tiling, 0.0f}});
v.push_back({{0.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, {0.0f, 0.0f}}); v.push_back({{0.0f, y, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f}});
v.push_back({{x, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, {tiling, 0.0f}}); v.push_back({{0.0f, y, z}, {0.0f, 1.0f, 0.0f}, {0.0f, tiling}});
v.push_back({{x, 0.0f, z}, {0.0f, -1.0f, 0.0f}, {tiling, tiling}}); v.push_back({{x, y, 0.0f}, {0.0f, 1.0f, 0.0f}, {tiling, 0.0f}});
v.push_back({{0.0f, 0.0f, z}, {0.0f, -1.0f, 0.0f}, {0.0f, tiling}}); v.push_back({{0.0f, y, z}, {0.0f, 1.0f, 0.0f}, {0.0f, tiling}});
v.push_back({{x, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, {tiling, 0.0f}}); v.push_back({{x, y, z}, {0.0f, 1.0f, 0.0f}, {tiling, tiling}});
// top if (wind_inside) {
v.push_back({{x, y, 0.0f}, {0.0f, 1.0f, 0.0f}, {tiling, 0.0f}}); for (size_t i = 0; i < v.size(); i += 3) {
v.push_back({{0.0f, y, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f}}); std::swap(v[i], v[i + 2]);
v.push_back({{0.0f, y, z}, {0.0f, 1.0f, 0.0f}, {0.0f, tiling}}); }
v.push_back({{x, y, 0.0f}, {0.0f, 1.0f, 0.0f}, {tiling, 0.0f}}); }
v.push_back({{0.0f, y, z}, {0.0f, 1.0f, 0.0f}, {0.0f, tiling}});
v.push_back({{x, y, z}, {0.0f, 1.0f, 0.0f}, {tiling, tiling}});
if (windInside) {
for (size_t i = 0; i < v.size(); i += 3) {
std::swap(v[i], v[i + 2]);
}
}
return std::make_unique<engine::resources::Mesh>(gfx, v);
return std::make_unique<engine::resources::Mesh>(gfx, v);
} }

View File

@ -1,8 +1,16 @@
#pragma once #ifndef ENGINE_TEST_SRC_MESHGEN_H_
#define ENGINE_TEST_SRC_MESHGEN_H_
#include <memory> #include <memory>
#include "resources/mesh.h" #include "resources/mesh.h"
// generates a UV sphere std::unique_ptr<engine::resources::Mesh> GenSphereMesh(
std::unique_ptr<engine::resources::Mesh> genSphereMesh(engine::GFXDevice* gfx, float r, int detail, bool windInside = false, bool flipNormals = false); engine::GFXDevice* gfx, float r, int detail, bool wind_inside = false,
std::unique_ptr<engine::resources::Mesh> genCuboidMesh(engine::GFXDevice* gfx, float x, float y, float z, float tiling = 1.0f, bool windInside = false); bool flip_normals = false);
std::unique_ptr<engine::resources::Mesh> GenCuboidMesh(
engine::GFXDevice* gfx, float x, float y, float z, float tiling = 1.0f,
bool wind_inside = false);
#endif

View File

@ -1,21 +0,0 @@
#if 0
#include "terrain.hpp"
#include "resources/mesh.hpp"
std::unique_ptr<engine::resources::Mesh> getChunkMesh(int x, int y)
{
(void)x;
(void)y;
std::vector<Vertex> vertices{
{{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f}},
{{1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f}},
{{0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f}}
};
return std::make_unique<engine::resources::Mesh>(vertices);
}
#endif

View File

@ -1,9 +0,0 @@
#pragma once
#include <memory>
namespace engine::resources {
class Mesh;
}
std::unique_ptr<engine::resources::Mesh> getChunkMesh(int x, int y);