1 #ifndef BLANK_WORLD_WORLD_HPP_
2 #define BLANK_WORLD_WORLD_HPP_
4 #include "ChunkStore.hpp"
6 #include "Generator.hpp"
13 #include <glm/glm.hpp>
18 class BlockTypeRegistry;
19 class EntityCollision;
27 std::string name = "default";
28 // chunk base where new players are spawned
29 glm::ivec3 spawn = { 0, 0, 0 };
30 // direction facing towards(!) the light
31 glm::vec3 light_direction = { -1.0f, -3.0f, -2.0f };
32 // fade out reaches 1/e (0.3679) at 1/fog_density,
33 // gets less than 0.01 at e/(2 * fog_density)
34 // I chose 0.011 because it yields 91 and 124 for those, so
35 // slightly less than 6 and 8 chunks
36 float fog_density = 0.011f;
39 World(const BlockTypeRegistry &, const Config &);
42 const std::string &Name() const noexcept { return config.name; }
44 /// check if this ray hits a block
45 /// depth in the collision is the distance between the ray's
46 /// origin and the intersection point
47 /// reference is the chunk offset of the ray in world space
50 const ExactLocation::Coarse &reference,
53 /// check if this ray hits an entity
54 /// intersections with the reference are not tested
55 /// the ray is assumed to be in world space offset by entity's chunk coords
58 const Entity &reference,
61 /// check if given entity intersects with the world
62 bool Intersection(const Entity &e, const EntityState &, std::vector<WorldCollision> &);
63 /// combine contacts into a single penetration vector
64 /// depth is given to point towards position of given state
65 static glm::vec3 CombinedInterpenetration(
67 const std::vector<WorldCollision> &) noexcept;
69 /// check if given box (M * AABB) intersects with the world
70 /// M is assumed to be calculated in reference to given chunk coords
74 const glm::ivec3 &reference,
75 std::vector<WorldCollision> &);
77 const BlockTypeRegistry &BlockTypes() noexcept { return block_type; }
78 ChunkStore &Chunks() noexcept { return chunks; }
80 /// add player with given name
81 /// returns nullptr if the name is already taken
82 Player *AddPlayer(const std::string &name);
83 /// add player with given name and ID
84 /// returns nullptr if the name or ID is already taken
85 Player *AddPlayer(const std::string &name, std::uint32_t id);
86 /// add an entity with an autogenerated ID
88 /// add entity with given ID
89 /// returns nullptr if the ID is already taken
90 Entity *AddEntity(std::uint32_t id);
91 /// add entity with given ID
92 /// returs an existing entity if ID is already taken
93 Entity &ForceAddEntity(std::uint32_t id);
95 std::list<Player> &Players() noexcept { return players; }
96 const std::list<Player> &Players() const noexcept { return players; }
97 std::list<Entity> &Entities() noexcept { return entities; }
98 const std::list<Entity> &Entities() const noexcept { return entities; }
103 /// fix state so entity doesn't intersect with the solid world
104 void ResolveWorldCollision(const Entity &, EntityState &);
105 /// get force due to gravity at given location
106 glm::vec3 GravityAt(const ExactLocation &) const noexcept;
108 void Render(Viewport &);
109 void RenderDebug(Viewport &);
112 using EntityHandle = std::list<Entity>::iterator;
113 EntityHandle RemoveEntity(EntityHandle &);
115 /// calculate light direction and intensity at entity's location
117 const Entity &entity,
118 glm::vec3 &direction,
126 const BlockTypeRegistry &block_type;
130 std::list<Player> players;
131 std::list<Entity> entities;
133 glm::vec3 light_direction;