1
0
Fork 0
Univerxel/src/core/world/Universe.hpp

64 lines
2.2 KiB
C++

#pragma once
#include <variant>
#include "forward.h"
#include "Voxel.hpp"
#include "position.h"
#include "../geometry/Ray.hpp"
namespace world {
/// Whole abstract universe container
class Universe {
public:
virtual ~Universe() {}
/// Distance management
struct options {
/// Radius in chunks to load if missing
uint16_t loadDistance = 5;
/// Radius in chunks to keep in memory
uint16_t keepDistance = 6;
};
/// Universe voxel ray intersection
struct ray_target {
ray_target(area_<voxel_pos> pos, Voxel value, voxel_pos offset):
pos(pos), value(value), offset(offset) { }
area_<voxel_pos> pos;
Voxel value;
voxel_pos offset;
};
/// Universe unloaded chunk ray intersection
struct ray_out_of_range {
ray_out_of_range(area_<chunk_pos> pos, voxel_pos offset):
pos(pos), offset(offset) { }
area_<chunk_pos> pos;
voxel_pos offset;
};
/// Universe ray intersection
/// @return target voxel, unloaded chunk or none
using ray_result = std::variant<std::monostate, ray_target, ray_out_of_range>;
/// Get nearest voxel colliding ray
/// @note ray in world scale
virtual ray_result raycast(const geometry::Ray &ray) const = 0;
/// Check for collision on movement
bool collide(const glm::ifvec3 &pos, const glm::vec3 &vel, int density, float radius = 0) const;
/// Move with collision check
/// @note must remove velocity after colision
bool move(glm::ifvec3 &pos, const glm::vec3 &vel, int density, float radius = 0) const;
/// Entities commun properties
struct Entity {
Entity(const glm::vec3& size = glm::vec3(1), const glm::vec3& scale = glm::vec3(1)): size(size), scale(scale) { };
glm::vec3 size;
glm::vec3 scale;
struct Instance {
glm::ifvec3 pos;
glm::vec3 velocity;
};
data::generational::vector<Instance> instances;
};
};
}