From: Daniel Karbach Date: Tue, 13 Oct 2015 14:59:15 +0000 (+0200) Subject: use (and fix) new shape implementation X-Git-Url: https://git.localhorst.tv/?a=commitdiff_plain;h=ba55bf4293f3abc742eef710545a4b207ba2c820;p=blank.git use (and fix) new shape implementation --- diff --git a/assets b/assets index d49b4a9..82ab376 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit d49b4a9e4d4b4afe6f483139f3c37db58376bfae +Subproject commit 82ab37629683a73061240c2d7da64f0a612fde42 diff --git a/src/app/Assets.hpp b/src/app/Assets.hpp index b9d62e2..941fa1b 100644 --- a/src/app/Assets.hpp +++ b/src/app/Assets.hpp @@ -21,7 +21,11 @@ class AssetLoader { public: explicit AssetLoader(const std::string &base); - void LoadBlockTypes(const std::string &set_name, BlockTypeRegistry &, TextureIndex &) const; + void LoadBlockTypes( + const std::string &set_name, + BlockTypeRegistry &, + TextureIndex &, + const ShapeRegistry &) const; CubeMap LoadCubeMap(const std::string &name) const; Font LoadFont(const std::string &name, int size) const; void LoadShapes(const std::string &set_name, ShapeRegistry &) const; diff --git a/src/app/app.cpp b/src/app/app.cpp index eb3dac1..367f3c2 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -313,7 +313,12 @@ CuboidBounds slab_shape({{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.0f, 0.5f }}); } -void AssetLoader::LoadBlockTypes(const string &set_name, BlockTypeRegistry ®, TextureIndex &tex_index) const { +void AssetLoader::LoadBlockTypes( + const string &set_name, + BlockTypeRegistry ®, + TextureIndex &tex_index, + const ShapeRegistry &shapes +) const { string full = data + set_name + ".types"; std::ifstream file(full); if (!file) { @@ -395,20 +400,12 @@ void AssetLoader::LoadBlockTypes(const string &set_name, BlockTypeRegistry ®, type.commonness = in.GetFloat(); } else if (name == "shape") { in.ReadIdentifier(shape_name); - if (shape_name == "block") { - type.shape = &block_shape; - type.fill = { true, true, true, true, true, true }; - } else if (shape_name == "slab") { - type.shape = &slab_shape; - type.fill = { false, true, false, false, false, false }; - } else if (shape_name == "stair") { - type.shape = &stair_shape; - type.fill = { false, true, false, false, false, true }; - } else { - throw runtime_error("unknown block shape: " + shape_name); - } + type.shape = &shapes.Get(shape_name); } else { - throw runtime_error("unknown block property: " + name); + std::cerr << "warning: unknown block type property " << name << std::endl; + while (in.Peek().type != Token::SEMICOLON) { + in.Next(); + } } in.Skip(Token::SEMICOLON); } diff --git a/src/client/client.cpp b/src/client/client.cpp index 00966dc..6a2dd32 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -67,11 +67,11 @@ InteractiveState::InteractiveState(MasterState &master, uint32_t player_id) } TextureIndex tex_index; master.GetEnv().loader.LoadShapes("default", shapes); - master.GetEnv().loader.LoadBlockTypes("default", block_types, tex_index); + master.GetEnv().loader.LoadBlockTypes("default", block_types, tex_index, shapes); + skeletons.Load(shapes, tex_index); interface.SetInventorySlots(block_types.size() - 1); chunk_renderer.LoadTextures(master.GetEnv().loader, tex_index); chunk_renderer.FogDensity(master.GetWorldConf().fog_density); - skeletons.Load(); loop_timer.Start(); if (save.Exists(player)) { save.Read(player); diff --git a/src/model/CollisionBounds.hpp b/src/model/CollisionBounds.hpp index 15c4fe1..78eb0dd 100644 --- a/src/model/CollisionBounds.hpp +++ b/src/model/CollisionBounds.hpp @@ -1,8 +1,6 @@ #ifndef BLANK_MODEL_COLLISIONBOUNDS_HPP_ #define BLANK_MODEL_COLLISIONBOUNDS_HPP_ -#include "../graphics/BlockMesh.hpp" -#include "../graphics/EntityMesh.hpp" #include "../graphics/OutlineMesh.hpp" #include @@ -15,43 +13,12 @@ class Ray; struct CollisionBounds { - /// the number of vertices (and normals) this shape has - size_t VertexCount() const noexcept { return vtx_pos.size(); } - /// the number of vertex indices this shape has - size_t VertexIndexCount() const noexcept { return vtx_idx.size(); } - - const EntityMesh::Normal &VertexNormal(size_t idx) const noexcept { return vtx_nrm[idx]; } - EntityMesh::Normal VertexNormal( - size_t idx, const glm::mat4 &transform - ) const noexcept { - return EntityMesh::Normal(transform * glm::vec4(vtx_nrm[idx], 0.0f)); - } - - /// fill given buffers with this shape's elements with an - /// optional transform and offset - void Vertices( - EntityMesh::Buffer &out, - float tex_offset = 0.0f - ) const; - void Vertices( - EntityMesh::Buffer &out, - const glm::mat4 &transform, - float tex_offset = 0.0f, - EntityMesh::Index idx_offset = 0 - ) const; - void Vertices( - BlockMesh::Buffer &out, - const glm::mat4 &transform, - float tex_offset = 0.0f, - BlockMesh::Index idx_offset = 0 - ) const; - /// the number of vertices this shape's outline has - size_t OutlineCount() const { return out_pos.size(); } + std::size_t OutlineCount() const { return out_pos.size(); } /// the number of vertex indices this shape's outline has - size_t OutlineIndexCount() const { return out_idx.size(); } + std::size_t OutlineIndexCount() const { return out_idx.size(); } - /// fill given buffers with this shape's outline's elements + /// fill given buffers with these bounds' outline's elements void Outline(OutlineMesh::Buffer &out) const; /// Check if given ray would pass though this shape if it were @@ -76,23 +43,11 @@ struct CollisionBounds { ) const noexcept = 0; protected: - void SetShape( - const EntityMesh::Positions &pos, - const EntityMesh::Normals &nrm, - const EntityMesh::Indices &idx); - void SetTexture( - const BlockMesh::TexCoords &tex_coords); void SetOutline( const OutlineMesh::Positions &pos, const OutlineMesh::Indices &idx); private: - EntityMesh::Positions vtx_pos; - EntityMesh::Normals vtx_nrm; - EntityMesh::Indices vtx_idx; - - BlockMesh::TexCoords vtx_tex_coords; - OutlineMesh::Positions out_pos; OutlineMesh::Indices out_idx; diff --git a/src/model/Shape.hpp b/src/model/Shape.hpp index ac4dc80..2f79f82 100644 --- a/src/model/Shape.hpp +++ b/src/model/Shape.hpp @@ -1,8 +1,11 @@ #ifndef BLANK_MODEL_SHAPE_HPP_ #define BLANK_MODEL_SHAPE_HPP_ +#include "CollisionBounds.hpp" +#include "geometry.hpp" #include "../graphics/BlockMesh.hpp" #include "../graphics/EntityMesh.hpp" +#include "../world/Block.hpp" #include #include @@ -11,16 +14,44 @@ namespace blank { -struct CollisionBounds; class TokenStreamReader; class Shape { +public: + struct Faces { + bool face[Block::FACE_COUNT]; + Faces &operator =(const Faces &other) noexcept { + for (int i = 0; i < Block::FACE_COUNT; ++i) { + face[i] = other.face[i]; + } + return *this; + } + bool operator [](Block::Face f) const noexcept { + return face[f]; + } + }; + + public: Shape(); void Read(TokenStreamReader &); + bool FaceFilled(Block::Face face) const noexcept { + return fill[face]; + } + + std::size_t VertexCount() const noexcept { return vertices.size(); } + std::size_t IndexCount() const noexcept { return indices.size(); } + + const glm::vec3 &VertexNormal(size_t idx) const noexcept { + return vertices[idx].normal; + } + glm::vec3 VertexNormal(size_t idx, const glm::mat4 &M) const noexcept { + return glm::vec3(M * glm::vec4(VertexNormal(idx), 0.0f)); + } + void Fill( EntityMesh::Buffer &, const std::vector &tex_map @@ -37,6 +68,24 @@ public: std::size_t idx_offset = 0 ) const; + size_t OutlineCount() const noexcept; + size_t OutlineIndexCount() const noexcept; + void Outline(OutlineMesh::Buffer &out) const; + + bool Intersects( + const Ray &, + const glm::mat4 &, + float &dist, + glm::vec3 &normal + ) const noexcept; + bool Intersects( + const glm::mat4 &M, + const AABB &box, + const glm::mat4 &box_M, + float &depth, + glm::vec3 &normal + ) const noexcept; + private: static float TexR(const std::vector &, std::size_t) noexcept; @@ -50,6 +99,7 @@ private: }; std::vector vertices; std::vector indices; + Faces fill; }; diff --git a/src/model/Skeletons.hpp b/src/model/Skeletons.hpp index 8d106d9..90affd3 100644 --- a/src/model/Skeletons.hpp +++ b/src/model/Skeletons.hpp @@ -10,6 +10,8 @@ namespace blank { class Model; class EntityMesh; +class ShapeRegistry; +class TextureIndex; class Skeletons { @@ -23,7 +25,7 @@ public: ~Skeletons(); void LoadHeadless(); - void Load(); + void Load(const ShapeRegistry &, TextureIndex &); size_type size() const noexcept { return skeletons.size(); } diff --git a/src/model/bounds.cpp b/src/model/bounds.cpp index c1c04e1..c6cb386 100644 --- a/src/model/bounds.cpp +++ b/src/model/bounds.cpp @@ -4,82 +4,11 @@ namespace blank { -void CollisionBounds::Vertices( - EntityMesh::Buffer &out, - float tex_offset -) const { - for (const auto &pos : vtx_pos) { - out.vertices.emplace_back(pos); - } - for (const auto &coord : vtx_tex_coords) { - out.tex_coords.emplace_back(coord.x, coord.y, coord.z + tex_offset); - } - for (const auto &nrm : vtx_nrm) { - out.normals.emplace_back(nrm); - } - for (auto idx : vtx_idx) { - out.indices.emplace_back(idx); - } -} - -void CollisionBounds::Vertices( - EntityMesh::Buffer &out, - const glm::mat4 &transform, - float tex_offset, - EntityMesh::Index idx_offset -) const { - for (const auto &pos : vtx_pos) { - out.vertices.emplace_back(transform * glm::vec4(pos, 1.0f)); - } - for (const auto &coord : vtx_tex_coords) { - out.tex_coords.emplace_back(coord.x, coord.y, coord.z + tex_offset); - } - for (const auto &nrm : vtx_nrm) { - out.normals.emplace_back(transform * glm::vec4(nrm, 0.0f)); - } - for (auto idx : vtx_idx) { - out.indices.emplace_back(idx_offset + idx); - } -} - -void CollisionBounds::Vertices( - BlockMesh::Buffer &out, - const glm::mat4 &transform, - float tex_offset, - BlockMesh::Index idx_offset -) const { - for (const auto &pos : vtx_pos) { - out.vertices.emplace_back(transform * glm::vec4(pos, 1.0f)); - } - for (const auto &coord : vtx_tex_coords) { - out.tex_coords.emplace_back(coord.x, coord.y, coord.z + tex_offset); - } - for (auto idx : vtx_idx) { - out.indices.emplace_back(idx_offset + idx); - } -} - void CollisionBounds::Outline(OutlineMesh::Buffer &out) const { out.vertices.insert(out.vertices.end(), out_pos.begin(), out_pos.end()); out.indices.insert(out.indices.end(), out_idx.begin(), out_idx.end()); } -void CollisionBounds::SetShape( - const EntityMesh::Positions &pos, - const EntityMesh::Normals &nrm, - const EntityMesh::Indices &idx -) { - vtx_pos = pos; - vtx_nrm = nrm; - vtx_idx = idx; -} - -void CollisionBounds::SetTexture( - const BlockMesh::TexCoords &tex_coords -) { - vtx_tex_coords = tex_coords; -} - void CollisionBounds::SetOutline( const OutlineMesh::Positions &pos, const OutlineMesh::Indices &idx @@ -89,118 +18,10 @@ void CollisionBounds::SetOutline( } -NullBounds::NullBounds() -: CollisionBounds() { - -} - -bool NullBounds::Intersects( - const Ray &, - const glm::mat4 &, - float &, glm::vec3 & -) const noexcept { - return false; -} - -bool NullBounds::Intersects( - const glm::mat4 &, - const AABB &, - const glm::mat4 &, - float &, - glm::vec3 & -) const noexcept { - return false; -} - - CuboidBounds::CuboidBounds(const AABB &b) : CollisionBounds() , bb(b) { bb.Adjust(); - SetShape({ - { bb.min.x, bb.min.y, bb.max.z }, // front - { bb.max.x, bb.min.y, bb.max.z }, - { bb.min.x, bb.max.y, bb.max.z }, - { bb.max.x, bb.max.y, bb.max.z }, - { bb.min.x, bb.min.y, bb.min.z }, // back - { bb.min.x, bb.max.y, bb.min.z }, - { bb.max.x, bb.min.y, bb.min.z }, - { bb.max.x, bb.max.y, bb.min.z }, - { bb.min.x, bb.max.y, bb.min.z }, // top - { bb.min.x, bb.max.y, bb.max.z }, - { bb.max.x, bb.max.y, bb.min.z }, - { bb.max.x, bb.max.y, bb.max.z }, - { bb.min.x, bb.min.y, bb.min.z }, // bottom - { bb.max.x, bb.min.y, bb.min.z }, - { bb.min.x, bb.min.y, bb.max.z }, - { bb.max.x, bb.min.y, bb.max.z }, - { bb.min.x, bb.min.y, bb.min.z }, // left - { bb.min.x, bb.min.y, bb.max.z }, - { bb.min.x, bb.max.y, bb.min.z }, - { bb.min.x, bb.max.y, bb.max.z }, - { bb.max.x, bb.min.y, bb.min.z }, // right - { bb.max.x, bb.max.y, bb.min.z }, - { bb.max.x, bb.min.y, bb.max.z }, - { bb.max.x, bb.max.y, bb.max.z }, - }, { - { 0.0f, 0.0f, 1.0f }, // front - { 0.0f, 0.0f, 1.0f }, - { 0.0f, 0.0f, 1.0f }, - { 0.0f, 0.0f, 1.0f }, - { 0.0f, 0.0f, -1.0f }, // back - { 0.0f, 0.0f, -1.0f }, - { 0.0f, 0.0f, -1.0f }, - { 0.0f, 0.0f, -1.0f }, - { 0.0f, 1.0f, 0.0f }, // top - { 0.0f, 1.0f, 0.0f }, - { 0.0f, 1.0f, 0.0f }, - { 0.0f, 1.0f, 0.0f }, - { 0.0f, -1.0f, 0.0f }, // bottom - { 0.0f, -1.0f, 0.0f }, - { 0.0f, -1.0f, 0.0f }, - { 0.0f, -1.0f, 0.0f }, - { -1.0f, 0.0f, 0.0f }, // left - { -1.0f, 0.0f, 0.0f }, - { -1.0f, 0.0f, 0.0f }, - { -1.0f, 0.0f, 0.0f }, - { 1.0f, 0.0f, 0.0f }, // right - { 1.0f, 0.0f, 0.0f }, - { 1.0f, 0.0f, 0.0f }, - { 1.0f, 0.0f, 0.0f }, - }, { - 0, 1, 2, 2, 1, 3, // front - 4, 5, 6, 6, 5, 7, // back - 8, 9, 10, 10, 9, 11, // top - 12, 13, 14, 14, 13, 15, // bottom - 16, 17, 18, 18, 17, 19, // left - 20, 21, 22, 22, 21, 23, // right - }); - SetTexture({ - { 0.0f, 1.0f, 0.0f }, // front - { 1.0f, 1.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f }, - { 1.0f, 0.0f, 0.0f }, - { 1.0f, 1.0f, 0.0f }, // back - { 1.0f, 0.0f, 0.0f }, - { 0.0f, 1.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f }, // top - { 0.0f, 1.0f, 0.0f }, - { 1.0f, 0.0f, 0.0f }, - { 1.0f, 1.0f, 0.0f }, - { 1.0f, 0.0f, 0.0f }, // bottom - { 0.0f, 0.0f, 0.0f }, - { 1.0f, 1.0f, 0.0f }, - { 0.0f, 1.0f, 0.0f }, - { 0.0f, 1.0f, 0.0f }, // left - { 1.0f, 1.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f }, - { 1.0f, 0.0f, 0.0f }, - { 1.0f, 1.0f, 0.0f }, // right - { 1.0f, 0.0f, 0.0f }, - { 0.0f, 1.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f }, - }); SetOutline({ { bb.min.x, bb.min.y, bb.min.z }, // back { bb.max.x, bb.min.y, bb.min.z }, @@ -240,142 +61,6 @@ StairBounds::StairBounds(const AABB &bb, const glm::vec2 &clip) : CollisionBounds() , top({ { bb.min.x, clip.y, bb.min.z }, { bb.max.x, bb.max.y, clip.x } }) , bot({ bb.min, { bb.max.x, clip.y, bb.max.z } }) { - SetShape({ - { top.min.x, top.min.y, top.max.z }, // front, upper - { top.max.x, top.min.y, top.max.z }, - { top.min.x, top.max.y, top.max.z }, - { top.max.x, top.max.y, top.max.z }, - { bot.min.x, bot.min.y, bot.max.z }, // front, lower - { bot.max.x, bot.min.y, bot.max.z }, - { bot.min.x, bot.max.y, bot.max.z }, - { bot.max.x, bot.max.y, bot.max.z }, - { bot.min.x, bot.min.y, bot.min.z }, // back - { bot.min.x, top.max.y, bot.min.z }, - { top.max.x, bot.min.y, bot.min.z }, - { top.max.x, top.max.y, bot.min.z }, - { top.min.x, top.max.y, top.min.z }, // top, upper - { top.min.x, top.max.y, top.max.z }, - { top.max.x, top.max.y, top.min.z }, - { top.max.x, top.max.y, top.max.z }, - { bot.min.x, bot.max.y, top.max.z }, // top, lower - { bot.min.x, bot.max.y, bot.max.z }, - { bot.max.x, bot.max.y, top.max.z }, - { bot.max.x, bot.max.y, bot.max.z }, - { bot.min.x, bot.min.y, bot.min.z }, // bottom - { bot.max.x, bot.min.y, bot.min.z }, - { bot.min.x, bot.min.y, bot.max.z }, - { bot.max.x, bot.min.y, bot.max.z }, - { top.min.x, top.min.y, top.min.z }, // left, upper - { top.min.x, top.min.y, top.max.z }, - { top.min.x, top.max.y, top.min.z }, - { top.min.x, top.max.y, top.max.z }, - { bot.min.x, bot.min.y, bot.min.z }, // left, lower - { bot.min.x, bot.min.y, bot.max.z }, - { bot.min.x, bot.max.y, bot.min.z }, - { bot.min.x, bot.max.y, bot.max.z }, - { top.max.x, top.min.y, top.min.z }, // right, upper - { top.max.x, top.max.y, top.min.z }, - { top.max.x, top.min.y, top.max.z }, - { top.max.x, top.max.y, top.max.z }, - { bot.max.x, bot.min.y, bot.min.z }, // right, lower - { bot.max.x, bot.max.y, bot.min.z }, - { bot.max.x, bot.min.y, bot.max.z }, - { bot.max.x, bot.max.y, bot.max.z }, - }, { - { 0.0f, 0.0f, 1.0f }, // front x2 - { 0.0f, 0.0f, 1.0f }, - { 0.0f, 0.0f, 1.0f }, - { 0.0f, 0.0f, 1.0f }, - { 0.0f, 0.0f, 1.0f }, - { 0.0f, 0.0f, 1.0f }, - { 0.0f, 0.0f, 1.0f }, - { 0.0f, 0.0f, 1.0f }, - { 0.0f, 0.0f, -1.0f }, // back - { 0.0f, 0.0f, -1.0f }, - { 0.0f, 0.0f, -1.0f }, - { 0.0f, 0.0f, -1.0f }, - { 0.0f, 1.0f, 0.0f }, // top x2 - { 0.0f, 1.0f, 0.0f }, - { 0.0f, 1.0f, 0.0f }, - { 0.0f, 1.0f, 0.0f }, - { 0.0f, 1.0f, 0.0f }, - { 0.0f, 1.0f, 0.0f }, - { 0.0f, 1.0f, 0.0f }, - { 0.0f, 1.0f, 0.0f }, - { 0.0f, -1.0f, 0.0f }, // bottom - { 0.0f, -1.0f, 0.0f }, - { 0.0f, -1.0f, 0.0f }, - { 0.0f, -1.0f, 0.0f }, - { -1.0f, 0.0f, 0.0f }, // left x2 - { -1.0f, 0.0f, 0.0f }, - { -1.0f, 0.0f, 0.0f }, - { -1.0f, 0.0f, 0.0f }, - { -1.0f, 0.0f, 0.0f }, - { -1.0f, 0.0f, 0.0f }, - { -1.0f, 0.0f, 0.0f }, - { -1.0f, 0.0f, 0.0f }, - { 1.0f, 0.0f, 0.0f }, // right x2 - { 1.0f, 0.0f, 0.0f }, - { 1.0f, 0.0f, 0.0f }, - { 1.0f, 0.0f, 0.0f }, - { 1.0f, 0.0f, 0.0f }, - { 1.0f, 0.0f, 0.0f }, - { 1.0f, 0.0f, 0.0f }, - { 1.0f, 0.0f, 0.0f }, - }, { - 0, 1, 2, 2, 1, 3, // front, upper - 4, 5, 6, 6, 5, 7, // front, lower - 8, 9, 10, 10, 9, 11, // back - 12, 13, 14, 14, 13, 15, // top, upper - 16, 17, 18, 18, 17, 19, // top, lower - 20, 21, 22, 22, 21, 23, // bottom - 24, 25, 26, 26, 25, 27, // left, upper - 28, 29, 30, 30, 29, 31, // left, lower - 32, 33, 34, 34, 33, 35, // right, upper - 36, 37, 38, 38, 37, 39, // right, lower - }); - SetTexture({ - { 0.0f, 0.5f, 0.0f }, // front, upper - { 1.0f, 0.5f, 0.0f }, - { 0.0f, 0.0f, 0.0f }, - { 1.0f, 0.0f, 0.0f }, - { 0.0f, 1.0f, 0.0f }, // front, lower - { 1.0f, 1.0f, 0.0f }, - { 0.0f, 0.5f, 0.0f }, - { 1.0f, 0.5f, 0.0f }, - { 1.0f, 1.0f, 0.0f }, // back - { 1.0f, 0.0f, 0.0f }, - { 0.0f, 1.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f }, // top, upper - { 0.0f, 0.5f, 0.0f }, - { 1.0f, 0.0f, 0.0f }, - { 1.0f, 0.5f, 0.0f }, - { 0.0f, 0.5f, 0.0f }, // top, lower - { 0.0f, 1.0f, 0.0f }, - { 1.0f, 0.5f, 0.0f }, - { 1.0f, 1.0f, 0.0f }, - { 1.0f, 0.0f, 0.0f }, // bottom - { 0.0f, 0.0f, 0.0f }, - { 1.0f, 1.0f, 0.0f }, - { 0.0f, 1.0f, 0.0f }, - { 0.0f, 0.5f, 0.0f }, // left, upper - { 0.5f, 0.5f, 0.0f }, - { 0.0f, 0.0f, 0.0f }, - { 0.5f, 0.0f, 0.0f }, - { 0.0f, 1.0f, 0.0f }, // left, lower - { 1.0f, 1.0f, 0.0f }, - { 0.0f, 0.5f, 0.0f }, - { 1.0f, 0.5f, 0.0f }, - { 1.0f, 0.5f, 0.0f }, // right, upper - { 1.0f, 0.0f, 0.0f }, - { 0.5f, 0.5f, 0.0f }, - { 0.5f, 0.0f, 0.0f }, - { 1.0f, 1.0f, 0.0f }, // right, lower - { 1.0f, 0.5f, 0.0f }, - { 0.0f, 1.0f, 0.0f }, - { 0.0f, 0.5f, 0.0f }, - }); SetOutline({ { bot.min.x, bot.min.y, bot.min.z }, // bottom { bot.max.x, bot.min.y, bot.min.z }, diff --git a/src/model/bounds.hpp b/src/model/bounds.hpp index 05f8df1..3bbb6d7 100644 --- a/src/model/bounds.hpp +++ b/src/model/bounds.hpp @@ -10,18 +10,6 @@ namespace blank { -class NullBounds -: public CollisionBounds { - -public: - NullBounds(); - - bool Intersects(const Ray &, const glm::mat4 &, float &, glm::vec3 &) const noexcept override; - bool Intersects(const glm::mat4 &, const AABB &, const glm::mat4 &, float &, glm::vec3 &) const noexcept override; - -}; - - class CuboidBounds : public CollisionBounds { diff --git a/src/model/model.cpp b/src/model/model.cpp index 22d2bed..70a1fc2 100644 --- a/src/model/model.cpp +++ b/src/model/model.cpp @@ -2,7 +2,9 @@ #include "Instance.hpp" #include "Skeletons.hpp" -#include "bounds.hpp" +#include "Shape.hpp" +#include "ShapeRegistry.hpp" +#include "../app/TextureIndex.hpp" #include "../graphics/DirectionalLighting.hpp" #include "../graphics/EntityMesh.hpp" @@ -118,66 +120,64 @@ Skeletons::~Skeletons() { void Skeletons::LoadHeadless() { skeletons.clear(); skeletons.reserve(4); + AABB bounds{{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f }}; { - AABB bounds{{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f }}; skeletons.emplace_back(new Model); skeletons[0]->ID(1); skeletons[0]->Bounds(bounds); } { - AABB bounds{{ -0.5f, -0.25f, -0.5f }, { 0.5f, 0.25f, 0.5f }}; skeletons.emplace_back(new Model); skeletons[1]->ID(2); skeletons[1]->Bounds(bounds); } { - AABB bounds{{ -0.25f, -0.5f, -0.25f }, { 0.25f, 0.5f, 0.25f }}; skeletons.emplace_back(new Model); skeletons[2]->ID(3); skeletons[2]->Bounds(bounds); } { - AABB bounds{{ -0.25f, -0.5f, -0.35f }, { 0.25f, 0.5f, 0.35f }}; skeletons.emplace_back(new Model); skeletons[3]->ID(4); skeletons[3]->Bounds(bounds); } } -void Skeletons::Load() { +void Skeletons::Load(const ShapeRegistry &shapes, TextureIndex &tex_index) { LoadHeadless(); meshes.resize(4); + const Shape &shape = shapes.Get("player_head_block"); EntityMesh::Buffer buf; + std::vector tex_map; + tex_map.push_back(tex_index.GetID("rock-1")); + tex_map.push_back(tex_index.GetID("rock-face")); + buf.Reserve(shape.VertexCount(), shape.IndexCount()); { - CuboidBounds shape(skeletons[0]->Bounds()); - shape.Vertices(buf, 3.0f); + shape.Fill(buf, tex_map); buf.hsl_mods.resize(shape.VertexCount(), { 0.0f, 1.0f, 1.0f }); buf.rgb_mods.resize(shape.VertexCount(), { 1.0f, 1.0f, 0.0f }); meshes[0].Update(buf); skeletons[0]->SetNodeMesh(&meshes[0]); } { - CuboidBounds shape(skeletons[1]->Bounds()); buf.Clear(); - shape.Vertices(buf, 0.0f); + shape.Fill(buf, tex_map); buf.hsl_mods.resize(shape.VertexCount(), { 0.0f, 1.0f, 1.0f }); buf.rgb_mods.resize(shape.VertexCount(), { 0.0f, 1.0f, 1.0f }); meshes[1].Update(buf); skeletons[1]->SetNodeMesh(&meshes[1]); } { - StairBounds shape(skeletons[2]->Bounds(), { 0.4f, 0.4f }); buf.Clear(); - shape.Vertices(buf, 1.0f); + shape.Fill(buf, tex_map); buf.hsl_mods.resize(shape.VertexCount(), { 0.0f, 1.0f, 1.0f }); buf.rgb_mods.resize(shape.VertexCount(), { 1.0f, 0.0f, 1.0f }); meshes[2].Update(buf); skeletons[2]->SetNodeMesh(&meshes[2]); } { - CuboidBounds shape(skeletons[3]->Bounds()); buf.Clear(); - shape.Vertices(buf, 2.0f); + shape.Fill(buf, tex_map); buf.hsl_mods.resize(shape.VertexCount(), { 0.0f, 1.0f, 1.0f }); buf.rgb_mods.resize(shape.VertexCount(), { 1.0f, 0.25f, 0.5f }); meshes[3].Update(buf); diff --git a/src/model/shape.cpp b/src/model/shape.cpp index e88c0e1..66eb25e 100644 --- a/src/model/shape.cpp +++ b/src/model/shape.cpp @@ -14,7 +14,8 @@ namespace blank { Shape::Shape() : bounds() , vertices() -, indices() { +, indices() +, fill({ false, false, false, false, false, false }) { } @@ -22,6 +23,7 @@ void Shape::Read(TokenStreamReader &in) { bounds.reset(); vertices.clear(); indices.clear(); + fill = { false, false, false, false, false, false }; string name; in.Skip(Token::ANGLE_BRACKET_OPEN); @@ -75,6 +77,7 @@ void Shape::Read(TokenStreamReader &in) { if (in.Peek().type == Token::COMMA) { in.Skip(Token::COMMA); } + vertices.push_back(vtx); } in.Skip(Token::ANGLE_BRACKET_CLOSE); @@ -88,6 +91,21 @@ void Shape::Read(TokenStreamReader &in) { } in.Skip(Token::ANGLE_BRACKET_CLOSE); + } else if (name == "fill") { + in.Skip(Token::BRACKET_OPEN); + fill.face[Block::FACE_UP] = in.GetBool(); + in.Skip(Token::COMMA); + fill.face[Block::FACE_DOWN] = in.GetBool(); + in.Skip(Token::COMMA); + fill.face[Block::FACE_RIGHT] = in.GetBool(); + in.Skip(Token::COMMA); + fill.face[Block::FACE_LEFT] = in.GetBool(); + in.Skip(Token::COMMA); + fill.face[Block::FACE_FRONT] = in.GetBool(); + in.Skip(Token::COMMA); + fill.face[Block::FACE_BACK] = in.GetBool(); + in.Skip(Token::BRACKET_CLOSE); + } else { // try to skip, might fail though while (in.Peek().type != Token::SEMICOLON) { @@ -153,6 +171,55 @@ void Shape::Fill( } } +size_t Shape::OutlineCount() const noexcept { + if (bounds) { + return bounds->OutlineCount(); + } else { + return 0; + } +} + +size_t Shape::OutlineIndexCount() const noexcept { + if (bounds) { + return bounds->OutlineIndexCount(); + } else { + return 0; + } +} + +void Shape::Outline(OutlineMesh::Buffer &out) const { + if (bounds) { + bounds->Outline(out); + } +} + +bool Shape::Intersects( + const Ray &ray, + const glm::mat4 &M, + float &dist, + glm::vec3 &normal +) const noexcept { + if (bounds) { + return bounds->Intersects(ray, M, dist, normal); + } else { + return false; + } +} + +bool Shape::Intersects( + const glm::mat4 &M, + const AABB &box, + const glm::mat4 &box_M, + float &depth, + glm::vec3 &normal +) const noexcept { + if (bounds) { + return bounds->Intersects(M, box, box_M, depth, normal); + } else { + return false; + } +} + ShapeRegistry::ShapeRegistry() : shapes() { diff --git a/src/server/ServerState.cpp b/src/server/ServerState.cpp index 23740be..7617b41 100644 --- a/src/server/ServerState.cpp +++ b/src/server/ServerState.cpp @@ -30,7 +30,7 @@ ServerState::ServerState( , loop_timer(16) { TextureIndex tex_index; env.loader.LoadShapes("default", shapes); - env.loader.LoadBlockTypes("default", block_types, tex_index); + env.loader.LoadBlockTypes("default", block_types, tex_index, shapes); generator.LoadTypes(block_types); skeletons.LoadHeadless(); spawner.LimitSkeletons(1, skeletons.size()); diff --git a/src/standalone/MasterState.cpp b/src/standalone/MasterState.cpp index c66c8fa..d357a84 100644 --- a/src/standalone/MasterState.cpp +++ b/src/standalone/MasterState.cpp @@ -42,12 +42,12 @@ MasterState::MasterState( , unload(env, world.Chunks(), save) { TextureIndex tex_index; env.loader.LoadShapes("default", shapes); - env.loader.LoadBlockTypes("default", block_types, tex_index); + env.loader.LoadBlockTypes("default", block_types, tex_index, shapes); + skeletons.Load(shapes, tex_index); interface.SetInventorySlots(block_types.size() - 1); generator.LoadTypes(block_types); chunk_renderer.LoadTextures(env.loader, tex_index); chunk_renderer.FogDensity(wc.fog_density); - skeletons.Load(); spawner.LimitSkeletons(0, skeletons.size()); if (save.Exists(player)) { save.Read(player); diff --git a/src/world/BlockType.hpp b/src/world/BlockType.hpp index 429bdaa..1ea34a1 100644 --- a/src/world/BlockType.hpp +++ b/src/world/BlockType.hpp @@ -5,7 +5,7 @@ #include "../graphics/BlockMesh.hpp" #include "../graphics/EntityMesh.hpp" #include "../graphics/OutlineMesh.hpp" -#include "../model/bounds.hpp" +#include "../model/Shape.hpp" #include #include @@ -17,7 +17,7 @@ namespace blank { /// attributes of a type of block struct BlockType { - const CollisionBounds *shape; + const Shape *shape; std::vector textures; glm::vec3 hsl_mod; glm::vec3 rgb_mod; @@ -61,31 +61,15 @@ struct BlockType { /// commonness factor, random chance is multiplied by this float commonness; - struct Faces { - bool face[Block::FACE_COUNT]; - Faces &operator =(const Faces &other) noexcept { - for (int i = 0; i < Block::FACE_COUNT; ++i) { - face[i] = other.face[i]; - } - return *this; - } - bool operator [](Block::Face f) const noexcept { - return face[f]; - } - } fill; - BlockType() noexcept; - static const NullBounds DEFAULT_SHAPE; - bool FaceFilled(const Block &block, Block::Face face) const noexcept { - return fill[block.OrientedFace(face)]; + return shape && shape->FaceFilled(block.OrientedFace(face)); } void FillEntityMesh( EntityMesh::Buffer &m, - const glm::mat4 &transform = glm::mat4(1.0f), - EntityMesh::Index idx_offset = 0 + const glm::mat4 &transform = glm::mat4(1.0f) ) const noexcept; void FillBlockMesh( BlockMesh::Buffer &m, diff --git a/src/world/block.cpp b/src/world/block.cpp index 1a5d88d..954a112 100644 --- a/src/world/block.cpp +++ b/src/world/block.cpp @@ -11,9 +11,6 @@ namespace blank { -const NullBounds BlockType::DEFAULT_SHAPE; - - std::ostream &operator <<(std::ostream &out, const Block &block) { return out << "Block(" << block.type << ", " << block.GetFace() << ", " << block.GetTurn() << ')'; } @@ -70,7 +67,7 @@ std::ostream &operator <<(std::ostream &out, const Block::Turn &turn) { BlockType::BlockType() noexcept -: shape(&DEFAULT_SHAPE) +: shape(nullptr) , textures() , hsl_mod(0.0f, 1.0f, 1.0f) , rgb_mod(1.0f, 1.0f, 1.0f) @@ -95,21 +92,16 @@ BlockType::BlockType() noexcept , min_richness(-1.0f) , mid_richness(0.0f) , max_richness(1.0f) -, commonness(1.0f) -, fill({ false, false, false, false, false, false }) { +, commonness(1.0f) { } void BlockType::FillEntityMesh( EntityMesh::Buffer &buf, - const glm::mat4 &transform, - EntityMesh::Index idx_offset + const glm::mat4 &transform ) const noexcept { - if (textures.empty()) { - shape->Vertices(buf, transform, 0.0f, idx_offset); - } else { - shape->Vertices(buf, transform, textures[0], idx_offset); - } + if (!shape) return; + shape->Fill(buf, transform, textures); buf.hsl_mods.insert(buf.hsl_mods.end(), shape->VertexCount(), hsl_mod); buf.rgb_mods.insert(buf.rgb_mods.end(), shape->VertexCount(), rgb_mod); } @@ -119,16 +111,14 @@ void BlockType::FillBlockMesh( const glm::mat4 &transform, BlockMesh::Index idx_offset ) const noexcept { - if (textures.empty()) { - shape->Vertices(buf, transform, 0.0f, idx_offset); - } else { - shape->Vertices(buf, transform, textures[0], idx_offset); - } + if (!shape) return; + shape->Fill(buf, transform, textures, idx_offset); buf.hsl_mods.insert(buf.hsl_mods.end(), shape->VertexCount(), hsl_mod); buf.rgb_mods.insert(buf.rgb_mods.end(), shape->VertexCount(), rgb_mod); } void BlockType::FillOutlineMesh(OutlineMesh::Buffer &buf) const noexcept { + if (!shape) return; shape->Outline(buf); buf.colors.insert(buf.colors.end(), shape->OutlineCount(), outline_color); } diff --git a/src/world/chunk.cpp b/src/world/chunk.cpp index bd2d426..800012e 100644 --- a/src/world/chunk.cpp +++ b/src/world/chunk.cpp @@ -371,7 +371,7 @@ bool Chunk::Intersection( for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x, ++idx) { const BlockType &type = Type(idx); - if (!type.visible) { + if (!type.collision || !type.shape) { continue; } float cur_dist; @@ -412,7 +412,7 @@ bool Chunk::Intersection( for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x, ++idx) { const BlockType &type = Type(idx); - if (!type.collision) { + if (!type.collision || !type.shape) { continue; } if (type.shape->Intersects(Mchunk * ToTransform(Pos(x, y, z), idx), box, Mbox, penetration, normal)) { @@ -435,33 +435,37 @@ BlockMesh::Buffer buf; void Chunk::Update(BlockMesh &model) noexcept { int vtx_count = 0, idx_count = 0; for (const auto &block : blocks) { - const CollisionBounds *shape = Type(block).shape; - vtx_count += shape->VertexCount(); - idx_count += shape->VertexIndexCount(); + const BlockType &type = Type(block); + if (type.visible && type.shape) { + vtx_count += type.shape->VertexCount(); + idx_count += type.shape->IndexCount(); + } } buf.Clear(); buf.Reserve(vtx_count, idx_count); - int idx = 0; - BlockMesh::Index vtx_counter = 0; - for (size_t z = 0; z < depth; ++z) { - for (size_t y = 0; y < height; ++y) { - for (size_t x = 0; x < width; ++x, ++idx) { - const BlockType &type = Type(BlockAt(idx)); - const Pos pos(x, y, z); - - if (!type.visible || Obstructed(pos).All()) continue; - - type.FillBlockMesh(buf, ToTransform(pos, idx), vtx_counter); - size_t vtx_begin = vtx_counter; - vtx_counter += type.shape->VertexCount(); - - for (size_t vtx = vtx_begin; vtx < vtx_counter; ++vtx) { - buf.lights.emplace_back(GetVertexLight( - pos, - buf.vertices[vtx], - type.shape->VertexNormal(vtx - vtx_begin, BlockAt(idx).Transform()) - )); + if (idx_count > 0) { + int idx = 0; + BlockMesh::Index vtx_counter = 0; + for (size_t z = 0; z < depth; ++z) { + for (size_t y = 0; y < height; ++y) { + for (size_t x = 0; x < width; ++x, ++idx) { + const BlockType &type = Type(BlockAt(idx)); + const Pos pos(x, y, z); + + if (!type.visible || !type.shape || Obstructed(pos).All()) continue; + + type.FillBlockMesh(buf, ToTransform(pos, idx), vtx_counter); + size_t vtx_begin = vtx_counter; + vtx_counter += type.shape->VertexCount(); + + for (size_t vtx = vtx_begin; vtx < vtx_counter; ++vtx) { + buf.lights.emplace_back(GetVertexLight( + pos, + buf.vertices[vtx], + type.shape->VertexNormal(vtx - vtx_begin, BlockAt(idx).Transform()) + )); + } } } }