From 3a487f44c26f9bb9d1a1c831406b6497b2b3b425 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Tue, 13 Oct 2015 14:38:30 +0200 Subject: [PATCH] actually load shapes load, not use :P --- assets | 2 +- src/app/Assets.hpp | 2 ++ src/app/app.cpp | 33 +++++++++++++++++++-- src/client/InteractiveState.hpp | 2 ++ src/client/client.cpp | 2 ++ src/model/Shape.hpp | 2 +- src/model/ShapeRegistry.hpp | 29 ++++++++++++++++++ src/model/{Shape.cpp => shape.cpp} | 47 ++++++++++++++++++++++++++---- src/server/ServerState.cpp | 2 ++ src/server/ServerState.hpp | 2 ++ src/standalone/MasterState.cpp | 2 ++ src/standalone/MasterState.hpp | 2 ++ src/world/BlockType.hpp | 3 +- src/world/block.cpp | 14 +++++++-- 14 files changed, 131 insertions(+), 13 deletions(-) create mode 100644 src/model/ShapeRegistry.hpp rename src/model/{Shape.cpp => shape.cpp} (76%) diff --git a/assets b/assets index 0a3fe35..d49b4a9 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 0a3fe3553f0e6fe9a9cd8d8994c15c873d247e34 +Subproject commit d49b4a9e4d4b4afe6f483139f3c37db58376bfae diff --git a/src/app/Assets.hpp b/src/app/Assets.hpp index db0933f..b9d62e2 100644 --- a/src/app/Assets.hpp +++ b/src/app/Assets.hpp @@ -11,6 +11,7 @@ namespace blank { class ArrayTexture; class BlockTypeRegistry; class CubeMap; +class ShapeRegistry; class Sound; class Texture; class TextureIndex; @@ -23,6 +24,7 @@ public: void LoadBlockTypes(const std::string &set_name, BlockTypeRegistry &, TextureIndex &) 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; Sound LoadSound(const std::string &name) const; Texture LoadTexture(const std::string &name) const; void LoadTexture(const std::string &name, ArrayTexture &, int layer) const; diff --git a/src/app/app.cpp b/src/app/app.cpp index 4f2a6ec..eb3dac1 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -14,6 +14,8 @@ #include "../graphics/Texture.hpp" #include "../io/TokenStreamReader.hpp" #include "../model/bounds.hpp" +#include "../model/Shape.hpp" +#include "../model/ShapeRegistry.hpp" #include "../world/BlockType.hpp" #include "../world/BlockTypeRegistry.hpp" #include "../world/Entity.hpp" @@ -311,7 +313,7 @@ CuboidBounds slab_shape({{ -0.5f, -0.5f, -0.5f }, { 0.5f, 0.0f, 0.5f }}); } -void AssetLoader::LoadBlockTypes(const std::string &set_name, BlockTypeRegistry ®, TextureIndex &tex_index) const { +void AssetLoader::LoadBlockTypes(const string &set_name, BlockTypeRegistry ®, TextureIndex &tex_index) const { string full = data + set_name + ".types"; std::ifstream file(full); if (!file) { @@ -336,7 +338,17 @@ void AssetLoader::LoadBlockTypes(const std::string &set_name, BlockTypeRegistry type.visible = in.GetBool(); } else if (name == "texture") { in.ReadString(tex_name); - type.texture = tex_index.GetID(tex_name); + type.textures.push_back(tex_index.GetID(tex_name)); + } else if (name == "textures") { + in.Skip(Token::BRACKET_OPEN); + while (in.Peek().type != Token::BRACKET_CLOSE) { + in.ReadString(tex_name); + type.textures.push_back(tex_index.GetID(tex_name)); + if (in.Peek().type == Token::COMMA) { + in.Skip(Token::COMMA); + } + } + in.Skip(Token::BRACKET_CLOSE); } else if (name == "rgb_mod") { in.ReadVec(type.rgb_mod); } else if (name == "hsl_mod") { @@ -485,6 +497,23 @@ Font AssetLoader::LoadFont(const string &name, int size) const { return Font(full.c_str(), size); } +void AssetLoader::LoadShapes(const string &set_name, ShapeRegistry &shapes) const { + string full = data + set_name + ".shapes"; + std::ifstream file(full); + if (!file) { + throw std::runtime_error("failed to open shape file " + full); + } + TokenStreamReader in(file); + string shape_name; + while (in.HasMore()) { + in.ReadIdentifier(shape_name); + in.Skip(Token::EQUALS); + Shape &shape = shapes.Add(shape_name); + shape.Read(in); + in.Skip(Token::SEMICOLON); + } +} + Sound AssetLoader::LoadSound(const string &name) const { string full = sounds + name + ".wav"; return Sound(full.c_str()); diff --git a/src/client/InteractiveState.hpp b/src/client/InteractiveState.hpp index 8e7064e..86757a2 100644 --- a/src/client/InteractiveState.hpp +++ b/src/client/InteractiveState.hpp @@ -9,6 +9,7 @@ #include "../app/IntervalTimer.hpp" #include "../graphics/SkyBox.hpp" #include "../io/WorldSave.hpp" +#include "../model/ShapeRegistry.hpp" #include "../model/Skeletons.hpp" #include "../net/Packet.hpp" #include "../ui/HUD.hpp" @@ -58,6 +59,7 @@ public: private: MasterState &master; + ShapeRegistry shapes; BlockTypeRegistry block_types; WorldSave save; World world; diff --git a/src/client/client.cpp b/src/client/client.cpp index 7e8c04e..00966dc 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -48,6 +48,7 @@ void InitialState::Render(Viewport &viewport) { // TODO: this clutter is a giant mess InteractiveState::InteractiveState(MasterState &master, uint32_t player_id) : master(master) +, shapes() , block_types() , save(master.GetEnv().config.GetWorldPath(master.GetWorldConf().name, master.GetConfig().net.host)) , world(block_types, master.GetWorldConf()) @@ -65,6 +66,7 @@ InteractiveState::InteractiveState(MasterState &master, uint32_t player_id) save.Write(master.GetWorldConf()); } TextureIndex tex_index; + master.GetEnv().loader.LoadShapes("default", shapes); master.GetEnv().loader.LoadBlockTypes("default", block_types, tex_index); interface.SetInventorySlots(block_types.size() - 1); chunk_renderer.LoadTextures(master.GetEnv().loader, tex_index); diff --git a/src/model/Shape.hpp b/src/model/Shape.hpp index 2160270..ac4dc80 100644 --- a/src/model/Shape.hpp +++ b/src/model/Shape.hpp @@ -45,7 +45,7 @@ private: struct Vertex { glm::vec3 position; glm::vec3 normal; - glm::vec3 tex_st; + glm::vec2 tex_st; std::size_t tex_id; }; std::vector vertices; diff --git a/src/model/ShapeRegistry.hpp b/src/model/ShapeRegistry.hpp new file mode 100644 index 0000000..53db569 --- /dev/null +++ b/src/model/ShapeRegistry.hpp @@ -0,0 +1,29 @@ +#ifndef BLANK_MODEL_SHAPEREGISTRY_HPP_ +#define BLANK_MODEL_SHAPEREGISTRY_HPP_ + +#include "Shape.hpp" + +#include +#include + + +namespace blank { + +class ShapeRegistry { + +public: + ShapeRegistry(); + + Shape &Add(const std::string &); + + Shape &Get(const std::string &); + const Shape &Get(const std::string &) const; + +private: + std::map shapes; + +}; + +} + +#endif diff --git a/src/model/Shape.cpp b/src/model/shape.cpp similarity index 76% rename from src/model/Shape.cpp rename to src/model/shape.cpp index 7be434d..e88c0e1 100644 --- a/src/model/Shape.cpp +++ b/src/model/shape.cpp @@ -1,4 +1,5 @@ #include "Shape.hpp" +#include "ShapeRegistry.hpp" #include "bounds.hpp" #include "../io/TokenStreamReader.hpp" @@ -17,20 +18,20 @@ Shape::Shape() } - void Shape::Read(TokenStreamReader &in) { bounds.reset(); vertices.clear(); indices.clear(); string name; - while (in.HasMore()) { + in.Skip(Token::ANGLE_BRACKET_OPEN); + while (in.HasMore() && in.Peek().type != Token::ANGLE_BRACKET_CLOSE) { in.ReadIdentifier(name); in.Skip(Token::EQUALS); if (name == "bounds") { string bounds_class; in.ReadIdentifier(bounds_class); - in.Skip(Token::BRACKET_OPEN); + in.Skip(Token::PARENTHESIS_OPEN); if (bounds_class == "Cuboid") { glm::vec3 min; glm::vec3 max; @@ -49,11 +50,11 @@ void Shape::Read(TokenStreamReader &in) { in.ReadVec(split); bounds.reset(new StairBounds(AABB{min, max}, split)); } else { - while (in.Peek().type != Token::BRACKET_CLOSE) { + while (in.Peek().type != Token::PARENTHESIS_CLOSE) { in.Next(); } } - in.Skip(Token::BRACKET_CLOSE); + in.Skip(Token::PARENTHESIS_CLOSE); } else if (name == "vertices") { in.Skip(Token::ANGLE_BRACKET_OPEN); @@ -75,6 +76,7 @@ void Shape::Read(TokenStreamReader &in) { in.Skip(Token::COMMA); } } + in.Skip(Token::ANGLE_BRACKET_CLOSE); } else if (name == "indices") { in.Skip(Token::ANGLE_BRACKET_OPEN); @@ -84,6 +86,7 @@ void Shape::Read(TokenStreamReader &in) { in.Skip(Token::COMMA); } } + in.Skip(Token::ANGLE_BRACKET_CLOSE); } else { // try to skip, might fail though @@ -93,6 +96,7 @@ void Shape::Read(TokenStreamReader &in) { } in.Skip(Token::SEMICOLON); } + in.Skip(Token::ANGLE_BRACKET_CLOSE); } float Shape::TexR(const vector &tex_map, size_t off) noexcept { @@ -149,4 +153,37 @@ void Shape::Fill( } } + +ShapeRegistry::ShapeRegistry() +: shapes() { + +} + +Shape &ShapeRegistry::Add(const string &name) { + auto result = shapes.emplace(name, Shape()); + if (result.second) { + return result.first->second; + } else { + throw runtime_error("duplicate shape " + name); + } +} + +Shape &ShapeRegistry::Get(const string &name) { + auto entry = shapes.find(name); + if (entry != shapes.end()) { + return entry->second; + } else { + throw runtime_error("unknown shape " + name); + } +} + +const Shape &ShapeRegistry::Get(const string &name) const { + auto entry = shapes.find(name); + if (entry != shapes.end()) { + return entry->second; + } else { + throw runtime_error("unknown shape " + name); + } +} + } diff --git a/src/server/ServerState.cpp b/src/server/ServerState.cpp index fc0da82..23740be 100644 --- a/src/server/ServerState.cpp +++ b/src/server/ServerState.cpp @@ -19,6 +19,7 @@ ServerState::ServerState( const Config &config ) : env(env) +, shapes() , block_types() , world(block_types, wc) , generator(gc) @@ -28,6 +29,7 @@ ServerState::ServerState( , server(config.net, world, wc, ws) , loop_timer(16) { TextureIndex tex_index; + env.loader.LoadShapes("default", shapes); env.loader.LoadBlockTypes("default", block_types, tex_index); generator.LoadTypes(block_types); skeletons.LoadHeadless(); diff --git a/src/server/ServerState.hpp b/src/server/ServerState.hpp index 3a48514..bfefccf 100644 --- a/src/server/ServerState.hpp +++ b/src/server/ServerState.hpp @@ -5,6 +5,7 @@ #include "../ai/Spawner.hpp" #include "../app/IntervalTimer.hpp" #include "../app/State.hpp" +#include "../model/ShapeRegistry.hpp" #include "../model/Skeletons.hpp" #include "../world/BlockTypeRegistry.hpp" #include "../world/ChunkLoader.hpp" @@ -39,6 +40,7 @@ public: private: HeadlessEnvironment &env; + ShapeRegistry shapes; BlockTypeRegistry block_types; World world; Generator generator; diff --git a/src/standalone/MasterState.cpp b/src/standalone/MasterState.cpp index 68e49a9..c66c8fa 100644 --- a/src/standalone/MasterState.cpp +++ b/src/standalone/MasterState.cpp @@ -21,6 +21,7 @@ MasterState::MasterState( ) : config(config) , env(env) +, shapes() , block_types() , save(save) , world(block_types, wc) @@ -40,6 +41,7 @@ MasterState::MasterState( , preload(env, chunk_loader, chunk_renderer) , unload(env, world.Chunks(), save) { TextureIndex tex_index; + env.loader.LoadShapes("default", shapes); env.loader.LoadBlockTypes("default", block_types, tex_index); interface.SetInventorySlots(block_types.size() - 1); generator.LoadTypes(block_types); diff --git a/src/standalone/MasterState.hpp b/src/standalone/MasterState.hpp index 9e0b8e4..680bb5e 100644 --- a/src/standalone/MasterState.hpp +++ b/src/standalone/MasterState.hpp @@ -8,6 +8,7 @@ #include "UnloadState.hpp" #include "../ai/Spawner.hpp" #include "../graphics/SkyBox.hpp" +#include "../model/ShapeRegistry.hpp" #include "../model/Skeletons.hpp" #include "../ui/DirectInput.hpp" #include "../ui/HUD.hpp" @@ -62,6 +63,7 @@ public: private: Config &config; Environment &env; + ShapeRegistry shapes; BlockTypeRegistry block_types; const WorldSave &save; World world; diff --git a/src/world/BlockType.hpp b/src/world/BlockType.hpp index 4208d94..429bdaa 100644 --- a/src/world/BlockType.hpp +++ b/src/world/BlockType.hpp @@ -8,6 +8,7 @@ #include "../model/bounds.hpp" #include +#include namespace blank { @@ -17,7 +18,7 @@ namespace blank { struct BlockType { const CollisionBounds *shape; - float texture; + std::vector textures; glm::vec3 hsl_mod; glm::vec3 rgb_mod; glm::vec3 outline_color; diff --git a/src/world/block.cpp b/src/world/block.cpp index 727fcad..1a5d88d 100644 --- a/src/world/block.cpp +++ b/src/world/block.cpp @@ -71,7 +71,7 @@ std::ostream &operator <<(std::ostream &out, const Block::Turn &turn) { BlockType::BlockType() noexcept : shape(&DEFAULT_SHAPE) -, texture(0) +, textures() , hsl_mod(0.0f, 1.0f, 1.0f) , rgb_mod(1.0f, 1.0f, 1.0f) , outline_color(-1, -1, -1) @@ -105,7 +105,11 @@ void BlockType::FillEntityMesh( const glm::mat4 &transform, EntityMesh::Index idx_offset ) const noexcept { - shape->Vertices(buf, transform, texture, idx_offset); + if (textures.empty()) { + shape->Vertices(buf, transform, 0.0f, idx_offset); + } else { + shape->Vertices(buf, transform, textures[0], 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); } @@ -115,7 +119,11 @@ void BlockType::FillBlockMesh( const glm::mat4 &transform, BlockMesh::Index idx_offset ) const noexcept { - shape->Vertices(buf, transform, texture, idx_offset); + if (textures.empty()) { + shape->Vertices(buf, transform, 0.0f, idx_offset); + } else { + shape->Vertices(buf, transform, textures[0], 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); } -- 2.39.2