diff --git a/src/client/Client.cpp b/src/client/Client.cpp index 18433e48..db0711b8 100644 --- a/src/client/Client.cpp +++ b/src/client/Client.cpp @@ -12,10 +12,7 @@ Client::Client(ivec2 window) : std::cout << Log::info << "Starting Zepha Client." << Log::endl; scene.setScene(make_unique(*this)); - while (!renderer.window.shouldClose()) - { - loop(); - } + while (!renderer.window.shouldClose()) loop(); } f64 Client::getDelta() { diff --git a/src/client/entity/ParticleEntity.cpp b/src/client/entity/ParticleEntity.cpp index 896dc6fa..03d37c9c 100644 --- a/src/client/entity/ParticleEntity.cpp +++ b/src/client/entity/ParticleEntity.cpp @@ -1,71 +1,65 @@ -// -// Created by aurailus on 15/05/19. -// - -#include - #include "ParticleEntity.h" #include "game/def/BlockDef.h" -#include "game/atlas/asset/AtlasRef.h" +#include "game/atlas/asset/AtlasTexture.h" -ParticleEntity::ParticleEntity(SubgamePtr game, DimensionPtr dim, glm::vec3 pos, BlockDef& block) : +ParticleEntity::ParticleEntity(SubgamePtr game, DimensionPtr dim, vec3 pos, BlockDef& block) : DrawableEntity(game, dim, std::make_shared()), Entity(game, dim) { - setPos(pos + glm::vec3(.5, .3, .5)); + setPos(pos + vec3 { .5, .3, .5 }); - std::set>& textureRefs = block.model.textureRefs; - auto it = textureRefs.cbegin(); - advance(it, rand() % textureRefs.size()); + let it = block.model.textures.cbegin(); + advance(it, rand() % block.model.textures.size()); - auto uv = (*it)->uv; + vec4 uv = (*it).getUVPos(); - auto spanX = uv.z - uv.x; - auto spanY = uv.w - uv.y; + f32 spanX = uv.z - uv.x; + f32 spanY = uv.w - uv.y; - float offX = spanX / 16 * (rand() % 12); - float offY = spanX / 16 * (rand() % 12); + f32 offX = spanX / 16 * (rand() % 12); + f32 offY = spanX / 16 * (rand() % 12); - uv -= glm::vec4(0, 0, spanX * 0.75, spanY * 0.75); - uv += glm::vec4(offX, offY, offX, offY); + uv -= vec4(0, 0, spanX * 0.75, spanY * 0.75); + uv += vec4(offX, offY, offX, offY); - std::vector vertices{ + vec vertices{ {{ -0.05, -0.05, 0 }, { uv.x, uv.w, 0, 1 }, { 1, 1, 1 }, true, { 0, 0, 1 }, {}, {}}, {{ -0.05, 0.05, 0 }, { uv.x, uv.y, 0, 1 }, { 1, 1, 1 }, true, { 0, 0, 1 }, {}, {}}, {{ 0.05, 0.05, 0 }, { uv.z, uv.y, 0, 1 }, { 1, 1, 1 }, true, { 0, 0, 1 }, {}, {}}, {{ 0.05, -0.05, 0 }, { uv.z, uv.w, 0, 1 }, { 1, 1, 1 }, true, { 0, 0, 1 }, {}, {}}, }; - std::vector indices{ + + vec indices{ 0, 1, 2, 2, 3, 0, 0, 2, 1, 2, 0, 3, }; - auto dir = glm::radians(static_cast(rand() % 360)); - float xDir = sinf(dir); - float zDir = cosf(dir); + f32 dir = glm::radians(static_cast(rand() % 360)); + f32 xDir = sinf(dir); + f32 zDir = cosf(dir); - float horiScale = 0.5f + (rand() % 100 / 100.f); + f32 horiScale = 0.5f + (rand() % 100 / 100.f); - velocity.y = 6.f; - velocity.x = xDir * 2.f * horiScale; - velocity.z = zDir * 2.f * horiScale; + vel.y = 6.f; + vel.x = xDir * 2.f * horiScale; + vel.z = zDir * 2.f * horiScale; - setPos(getPos() + glm::vec3(xDir, 0, zDir) / 4.f); + setPos(getPos() + vec3(xDir, 0, zDir) / 4.f); - std::unique_ptr mesh = std::make_unique(); + uptr mesh = make_unique(); mesh->create(vertices, indices); - this->model->fromMesh(std::move(mesh)); - this->setScale(0.75f + (rand() % 10 / 20.f)); + model->fromMesh(std::move(mesh)); + setScale(0.75f + (rand() % 10 / 20.f)); } -void ParticleEntity::update(double delta, glm::vec3 player) { +void ParticleEntity::update(f64 delta, vec3 player) { time += delta; - setPos(getPos() + velocity * glm::vec3(static_cast(delta))); + setPos(getPos() + vel * glm::vec3(static_cast(delta))); - double angle = -glm::degrees(std::atan2(player.z - pos.z, player.x - pos.x)) + 90.f; - setRotateY(static_cast(angle)); + f32 angle = -glm::degrees(std::atan2(player.z - pos.z, player.x - pos.x)) + 90.f; + setRotateY(angle); - velocity.y -= 32.f * delta; + vel.y -= 32.f * delta; } void ParticleEntity::draw(Renderer& renderer) { diff --git a/src/client/entity/ParticleEntity.h b/src/client/entity/ParticleEntity.h index 82b62ee4..b0c97256 100644 --- a/src/client/entity/ParticleEntity.h +++ b/src/client/entity/ParticleEntity.h @@ -1,23 +1,21 @@ -// -// Created by aurailus on 15/05/19. -// - #pragma once +#include "util/Types.h" #include "world/dim/ent/DrawableEntity.h" class BlockDef; class ParticleEntity : public DrawableEntity { - public: - ParticleEntity(SubgamePtr game, DimensionPtr dim, glm::vec3 pos, BlockDef& block); +public: + ParticleEntity(SubgamePtr game, DimensionPtr dim, vec3 pos, BlockDef& block); - void update(double delta, glm::vec3 player); + void update(f64 delta, vec3 player); void draw(Renderer& renderer) override; - float time = 0; - private: - glm::vec3 velocity{}; + f32 time = 0; + +private: + vec3 vel; }; diff --git a/src/client/graph/Font.cpp b/src/client/graph/Font.cpp index 19e7c80a..2f4b6325 100644 --- a/src/client/graph/Font.cpp +++ b/src/client/graph/Font.cpp @@ -1,71 +1,57 @@ -// -// Created by aurailus on 13/08/19. -// - -#include - #include "Font.h" -#include "game/atlas/asset/AtlasRef.h" -#include "game/atlas/TextureAtlas.h" +#include "game/atlas/asset/AtlasTexture.h" -Font::Font(TextureAtlas& atlas, std::shared_ptr tex) : - fontTex(std::move(tex)), - atlasSize(atlas.canvasSize) { - - getCharWidths(atlas); -} - -u16 Font::getCharWidth(char c) { - unsigned int index = static_cast(c) - 32; - if (index >= C_COUNT) return charWidths[C_COUNT]; - return charWidths[index]; -} - -void Font::getCharWidths(TextureAtlas& atlas) { - auto& data = atlas.atlasData; - +Font::Font(const AtlasTexture& texture) : texture(texture) { charWidths[0] = 2; + const let data = texture.getBytes(); for (u16 i = 1; i < C_COUNT + 1; i++) { - glm::vec2 charPos = { i % 18 * C_WIDTH, std::floor(i / 18) * C_HEIGHT }; - - u32 xBase = static_cast(fontTex->rawPos.x) + static_cast(charPos.x); - u32 yBase = static_cast(fontTex->rawPos.y) + static_cast(charPos.y); + u16vec2 charPos(i % C_ROWSIZE * C_WIDTH, i / C_ROWSIZE * C_HEIGHT); u16 width = 0; - for (u16 j = 0; j < C_WIDTH; j++) { bool empty = true; + for (u16 k = 0; k < C_HEIGHT; k++) { - u32 xx = xBase + j; - u32 yy = yBase + k; + u32 xx = charPos.x + j; + u32 yy = charPos.y + k; - u32 offset = yy * static_cast(atlasSize.x) * 4 + xx * 4 + 3; + u32 offset = yy * texture.getSize().x * 4 + xx * 4 + 3; if (data[offset] != 0) { empty = false; break; } } - if (!empty) width = static_cast(j); + + if (!empty) { + width = j; + } } charWidths[i] = width; } } +u16 Font::getCharWidth(char c) { + u16 index = static_cast(c) - 32; + if (index >= C_COUNT) return charWidths[C_COUNT]; + return charWidths[index]; +} + vec4 Font::getCharUVs(char c) { u16 index = static_cast(c) - 32; if (index >= C_COUNT) index = C_COUNT; - vec2 charPos = { (index % 18) * C_WIDTH, std::floor(index / 18) * C_HEIGHT }; - vec4 uv = { - fontTex->uv.x + (charPos.x) / atlasSize.x, - fontTex->uv.y + (charPos.y) / atlasSize.y, - fontTex->uv.x + (charPos.x + getCharWidth(c) + 1) / atlasSize.x, - fontTex->uv.y + (charPos.y + C_HEIGHT) / atlasSize.y - }; + vec4 texUVs = texture.getUVPos(); + u16vec2 texSize = texture.getSize(); + u16vec2 charPos((index % C_ROWSIZE) * C_WIDTH, index / C_ROWSIZE * C_HEIGHT); - return uv; + return { + texUVs.x + charPos.x * (texUVs.z - texUVs.x) / texSize.x, + texUVs.y + charPos.y * (texUVs.w - texUVs.y) / texSize.y, + texUVs.x + (charPos.x + getCharWidth(c) + 1) * (texUVs.z - texUVs.x) / texSize.x, + texUVs.y + (charPos.y + C_HEIGHT) * (texUVs.w - texUVs.y) / texSize.y + }; } diff --git a/src/client/graph/Font.h b/src/client/graph/Font.h index eb028449..005a2ebf 100644 --- a/src/client/graph/Font.h +++ b/src/client/graph/Font.h @@ -1,29 +1,26 @@ #pragma once #include "util/Types.h" +#include "game/atlas/asset/AtlasTexture.h" -class AtlasRef; -class TextureAtlas; +/** + * Stores information about a font, + * like the texture, UVs and widths of characters. + */ class Font { public: - Font() = default; - - Font(TextureAtlas& atlas, std::shared_ptr tex); + Font(const AtlasTexture& texture); u16 getCharWidth(char c); - vec4 getCharUVs(char c); + constexpr static u16 C_ROWSIZE = 18; constexpr static u16 C_COUNT = 95; constexpr static u16 C_WIDTH = 7; constexpr static u16 C_HEIGHT = 9; private: - void getCharWidths(TextureAtlas& atlas); - - vec2 atlasSize {}; - - sptr fontTex = nullptr; + AtlasTexture texture; array charWidths {}; }; diff --git a/src/client/graph/Model.cpp b/src/client/graph/Model.cpp index 49216aa4..3a983fa3 100644 --- a/src/client/graph/Model.cpp +++ b/src/client/graph/Model.cpp @@ -13,7 +13,7 @@ #include "util/Log.h" #include "util/Mat4Conv.h" -#include "game/atlas/asset/AtlasRef.h" +#include "game/atlas/asset/AtlasTexture.h" #include "game/atlas/asset/SerializedModel.h" void Model::fromMesh(std::unique_ptr mesh) { @@ -21,7 +21,7 @@ void Model::fromMesh(std::unique_ptr mesh) { meshes.push_back(std::move(mesh)); } -int Model::fromFile(const std::string& path, const std::vector>& textures) { +int Model::fromFile(const std::string& path, const std::vector& textures) { this->textures = textures; Assimp::Importer importer; @@ -42,7 +42,7 @@ int Model::fromFile(const std::string& path, const std::vector>& textures) { +int Model::fromSerialized(const SerializedModel& model, const std::vector& textures) { this->textures = textures; Assimp::Importer importer; @@ -111,10 +111,11 @@ void Model::loadMeshAndBone(aiMesh* mesh, std::unique_ptr& target) { auto& texture = textures[mesh->mMaterialIndex]; //Set texture coordinates + vec4 uvs = texture.getUVPos(); vertex.useTex = true; vertex.colorData = { - texture->uv.x + mesh->mTextureCoords[0][i].x * (texture->uv.z - texture->uv.x), - texture->uv.y + mesh->mTextureCoords[0][i].y * (texture->uv.w - texture->uv.y), 0, 1 //Alpha + uvs.x + mesh->mTextureCoords[0][i].x * (uvs.z - uvs.x), + uvs.y + mesh->mTextureCoords[0][i].y * (uvs.w - uvs.y), 0, 1 //Alpha }; } else vertex.colorData = { 1, 1, 1, 1 }; diff --git a/src/client/graph/Model.h b/src/client/graph/Model.h index 5fa7e509..f93cc82b 100644 --- a/src/client/graph/Model.h +++ b/src/client/graph/Model.h @@ -14,20 +14,19 @@ #include "ModelBone.h" #include "ModelAnimation.h" #include "client/graph/mesh/EntityMesh.h" - -class AtlasRef; +#include "game/atlas/asset/AtlasTexture.h" class SerializedModel; class Model { - public: +public: Model() = default; void fromMesh(std::unique_ptr mesh); - int fromFile(const std::string& path, const std::vector>& texture); + int fromFile(const std::string& path, const std::vector& texture); - int fromSerialized(const SerializedModel& model, const std::vector>& texture); + int fromSerialized(const SerializedModel& model, const std::vector& texture); void getTransformsByFrame(double frame, glm::ivec2 bounds, std::vector& transforms); // void getTransformsByTime(double time, std::tuple bounds, std::vector& transforms); @@ -77,7 +76,7 @@ private: ModelAnimation animation {}; std::vector rootBones {}; std::vector bones {}; - std::vector> textures {}; + std::vector textures {}; glm::mat4 globalInverseTransform {}; }; diff --git a/src/client/graph/Renderer.cpp b/src/client/graph/Renderer.cpp index 3224ae4f..2b371ea1 100644 --- a/src/client/graph/Renderer.cpp +++ b/src/client/graph/Renderer.cpp @@ -10,7 +10,7 @@ Renderer::Renderer() : Renderer({ 1366, 768 }) {}; Renderer::Renderer(glm::ivec2 win) : - activeTexture(nullptr), +// activeTexture(nullptr), window(win), world(win, 2), @@ -62,7 +62,7 @@ void Renderer::update(double delta) { } void Renderer::beginChunkDeferredCalls() { - activeTexture = nullptr; +// activeTexture = nullptr; currentModelUniform = world.uniforms.model; glClearColor(0, 0, 0, 0); @@ -105,7 +105,7 @@ void Renderer::beginEntityDeferredCalls() { void Renderer::endDeferredCalls() { glDisable(GL_BLEND); - activeTexture = nullptr; +// activeTexture = nullptr; glBindFramebuffer(GL_FRAMEBUFFER, ssao.fbo); glClearColor(clearColor.x, clearColor.y, clearColor.z, 0); @@ -163,7 +163,7 @@ void Renderer::endDeferredCalls() { } void Renderer::beginGUIDrawCalls() { - activeTexture = nullptr; +// activeTexture = nullptr; currentModelUniform = gu.model; glClear(GL_DEPTH_BUFFER_BIT); @@ -211,11 +211,11 @@ void Renderer::setClipBounds(glm::vec4 bounds) { guiShader.set(gu.clipBounds, { bounds.x, window.getSize().y - bounds.w, bounds.z, window.getSize().y - bounds.y }); } -void Renderer::enableTexture(Texture* texture) { - if (texture != activeTexture) { - activeTexture = texture; - texture->use(0); - } +void Renderer::enableTexture(const Texture& texture) { +// if (texture != *activeTexture) { +// activeTexture = texture; + texture.use(0); +// } } void Renderer::renderQuad() { diff --git a/src/client/graph/Renderer.h b/src/client/graph/Renderer.h index bc972de7..df90182d 100644 --- a/src/client/graph/Renderer.h +++ b/src/client/graph/Renderer.h @@ -48,7 +48,7 @@ public: void setClipBounds(glm::vec4 bounds); - void enableTexture(Texture* texture); + void enableTexture(const Texture& texture); Window window; Camera camera; @@ -60,7 +60,7 @@ private: unsigned int quadVBO = 0; glm::vec4 clearColor{ 0, 0, 0, 1 }; - Texture* activeTexture; +// Texture* activeTexture; WorldGeometryShader world; EntityGeometryShader entity; diff --git a/src/client/graph/Texture.cpp b/src/client/graph/Texture.cpp index 98cfb684..bbd7b2cc 100644 --- a/src/client/graph/Texture.cpp +++ b/src/client/graph/Texture.cpp @@ -12,6 +12,10 @@ Texture::Texture(const std::string& file) : loadFromFile(this->fileLocation); } +bool Texture::operator==(const Texture& o) const { + return o.textureID == textureID; +} + void Texture::loadFromFile(std::string file) { unsigned char* texData = stbi_load(file.c_str(), &width, &height, &bitDepth, 0); if (!texData) throw std::runtime_error("Failed to find texture at " + file + "."); @@ -46,7 +50,7 @@ void Texture::updateTexture(int x, int y, int width, int height, unsigned char* } -void Texture::use(GLuint position) { +void Texture::use(GLuint position) const { glActiveTexture(GL_TEXTURE0 + position); glBindTexture(GL_TEXTURE_2D, textureID); } diff --git a/src/client/graph/Texture.h b/src/client/graph/Texture.h index 040fe08e..c2acb5f5 100644 --- a/src/client/graph/Texture.h +++ b/src/client/graph/Texture.h @@ -8,11 +8,13 @@ #include "util/GL.h" class Texture { - public: +public: Texture() = default; explicit Texture(const std::string& file); + bool operator==(const Texture& o) const; + void loadFromFile(std::string file); void loadFromBytes(unsigned char* bytes, int width, int height, GLint interpolation = GL_NEAREST, @@ -20,13 +22,13 @@ class Texture { void updateTexture(int x, int y, int width, int height, unsigned char* bytes); - void use(GLuint position = 0); + void use(GLuint position = 0) const; void clear(); ~Texture(); - protected: +protected: unsigned int textureID = 0; int width = 0; int height = 0; diff --git a/src/client/gui/BoxElement.cpp b/src/client/gui/BoxElement.cpp index 454ce07b..42a2ac5a 100644 --- a/src/client/gui/BoxElement.cpp +++ b/src/client/gui/BoxElement.cpp @@ -27,7 +27,7 @@ void Gui::BoxElement::updateElement() { else if (bgColor) { let mesh = make_unique(); - tex = nullptr; + tex = {}; mesh->create({ { { 0, 0, 0 }, *bgColor, vec3(1), false, {}, {}, {} }, { { 0, 1, 0 }, *bgColor, vec3(1), false, {}, {}, {} }, @@ -43,11 +43,12 @@ void Gui::BoxElement::updateElement() { let mesh = make_unique(); tex = root.atlas[bgImage]; + let uv = tex->getUVPos(); mesh->create({ - { { 0, 0, 0 }, { tex->uv.x, tex->uv.y, 0, 1 }, vec3(1), true, {}, {}, {} }, - { { 0, 1, 0 }, { tex->uv.x, tex->uv.w, 0, 1 }, vec3(1), true, {}, {}, {} }, - { { 1, 1, 0 }, { tex->uv.z, tex->uv.w, 0, 1 }, vec3(1), true, {}, {}, {} }, - { { 1, 0, 0 }, { tex->uv.z, tex->uv.y, 0, 1 }, vec3(1), true, {}, {}, {} } + { { 0, 0, 0 }, { uv.x, uv.y, 0, 1 }, vec3(1), true, {}, {}, {} }, + { { 0, 1, 0 }, { uv.x, uv.w, 0, 1 }, vec3(1), true, {}, {}, {} }, + { { 1, 1, 0 }, { uv.z, uv.w, 0, 1 }, vec3(1), true, {}, {}, {} }, + { { 1, 0, 0 }, { uv.z, uv.y, 0, 1 }, vec3(1), true, {}, {}, {} } }, { 0, 1, 2, 2, 3, 0 }); let model = make_shared(); diff --git a/src/client/gui/BoxElement.h b/src/client/gui/BoxElement.h index 8ef362d8..e3f74c89 100644 --- a/src/client/gui/BoxElement.h +++ b/src/client/gui/BoxElement.h @@ -2,7 +2,7 @@ #include "Element.h" -#include "game/atlas/asset/AtlasRef.h" +#include "game/atlas/asset/AtlasTexture.h" namespace Gui { @@ -17,7 +17,7 @@ namespace Gui { virtual void updateElement() override; protected: - sptr tex; optional curBg; + optional tex; }; } \ No newline at end of file diff --git a/src/client/gui/DebugDisplay.cpp b/src/client/gui/DebugDisplay.cpp index 935d8d9b..730f8766 100644 --- a/src/client/gui/DebugDisplay.cpp +++ b/src/client/gui/DebugDisplay.cpp @@ -140,9 +140,9 @@ void DebugDisplay::update(sptr player, f64 delta, u32 interpolatedC << "R: " << posOffsetFromRegion << " [" << regionPos << "]" << std::endl << std::endl - << "Texture Slots: " << game.l()->textures.textureSlotsUsed << " / " << game.l()->textures.maxTextureSlots + << "Texture Slots: " << game.l()->textures.getTilesUsed() << " / " << game.l()->textures.getTilesTotal() << " (" - << round(game.l()->textures.textureSlotsUsed / static_cast(game.l()->textures.maxTextureSlots) * 100) + << round(game.l()->textures.getTilesUsed() / static_cast(game.l()->textures.getTilesTotal()) * 100) << "%)" << std::endl << std::endl << "Biome: " << onBiomeDef.identifier << " [" << onBiomeDef.index << "]" << std::endl << std::endl; diff --git a/src/client/gui/TextElement.cpp b/src/client/gui/TextElement.cpp index 8ce1cd00..9a707d3b 100644 --- a/src/client/gui/TextElement.cpp +++ b/src/client/gui/TextElement.cpp @@ -9,7 +9,7 @@ void Gui::TextElement::updateElement() { const string text = getStyle(Prop::CONTENT, ""); - if (!font) font = std::make_unique(root.atlas, root.atlas["font"]); + if (!font) font = make_unique(root.atlas["font"]); usize newHash = std::hash{}(text); if (hash != newHash) { diff --git a/src/client/menu/MenuSandbox.cpp b/src/client/menu/MenuSandbox.cpp index 7e8c44f0..b7d0d03e 100644 --- a/src/client/menu/MenuSandbox.cpp +++ b/src/client/menu/MenuSandbox.cpp @@ -54,8 +54,8 @@ void MenuSandbox::load(const SubgameDef& subgame) { subgameName = subgame.config.name; try { - loadMod(subgame.subgamePath + "/../../assets/base"); - loadMod(subgame.subgamePath + "/menu"); + loadMod(subgame.subgamePath / "../../assets/base"); + loadMod(subgame.subgamePath / "menu"); } catch (sol::error e) { string err = static_cast(e).what(); @@ -132,7 +132,7 @@ void MenuSandbox::loadMod(const std::filesystem::path& path) { mod = { path, true }; if (std::filesystem::exists(path / "textures")) - menuAssets = client.game->textures.loadDirectory((path / "textures").string(), false); + menuAssets = client.game->textures.addDirectory((path / "textures"), false); loadFile("/main"); } diff --git a/src/client/menu/MenuSandbox.h b/src/client/menu/MenuSandbox.h index 46372205..e87ef27b 100644 --- a/src/client/menu/MenuSandbox.h +++ b/src/client/menu/MenuSandbox.h @@ -1,7 +1,3 @@ -// -// Created by aurailus on 2019-12-12. -// - #pragma once #include "lua/LuaParser.h" @@ -9,10 +5,10 @@ #include "lua/Mod.h" #include "client/gui/Root.h" #include "client/gui/Element.h" +#include "game/atlas/asset/AtlasTexture.h" class Client; class Subgame; -class AtlasRef; class SubgameDef; class GuiContainer; @@ -48,7 +44,7 @@ private: Gui::Root& root; sptr sandboxRoot; - vec> menuAssets {}; + vec menuAssets {}; double accumulatedDelta = 0; diff --git a/src/client/menu/SubgameDef.h b/src/client/menu/SubgameDef.h index 574f70db..1fa1f3ac 100644 --- a/src/client/menu/SubgameDef.h +++ b/src/client/menu/SubgameDef.h @@ -1,18 +1,11 @@ -// -// Created by aurailus on 2019-12-11. -// - #pragma once -#include - -#include "SubgameConfig.h" - -class AtlasRef; +#include "client/menu/SubgameConfig.h" +#include "game/atlas/asset/AtlasTexture.h" class SubgameDef { - public: - std::shared_ptr iconRef = nullptr; - SubgameConfig config{}; - std::string subgamePath = ""; +public: + AtlasTexture iconRef; + SubgameConfig config {}; + std::filesystem::path subgamePath; }; diff --git a/src/client/scene/ConnectScene.cpp b/src/client/scene/ConnectScene.cpp index 942e3cde..db54b053 100644 --- a/src/client/scene/ConnectScene.cpp +++ b/src/client/scene/ConnectScene.cpp @@ -136,7 +136,7 @@ void ConnectScene::update() { const u8* dataPtr = reinterpret_cast(const_cast(uncompressed.data())); const vec tex(dataPtr, dataPtr + width * height * 4); - client.game->textures.addImage(assetName, true, u16vec2(width, height), tex); + client.game->textures.addBytes(assetName, true, u16vec2(width, height), tex); } else if (t == AssetType::MODEL) { string format = p.d.read(); @@ -210,7 +210,7 @@ void ConnectScene::draw() { renderer.beginChunkDeferredCalls(); renderer.endDeferredCalls(); renderer.beginGUIDrawCalls(); - renderer.enableTexture(&client.game->textures.texture); + renderer.enableTexture(client.game->textures.getTexture()); root.draw(renderer); } \ No newline at end of file diff --git a/src/client/scene/GameScene.cpp b/src/client/scene/GameScene.cpp index 893f9ede..296a5c95 100644 --- a/src/client/scene/GameScene.cpp +++ b/src/client/scene/GameScene.cpp @@ -46,19 +46,19 @@ void GameScene::draw() { Camera& camera = renderer.camera; perf.start("draw:world"); + renderer.enableTexture(client.game->textures.getTexture()); renderer.beginChunkDeferredCalls(); - renderer.enableTexture(&client.game->textures.texture); world.l()->drawChunks(); perf.start("draw:entities"); + renderer.enableTexture(client.game->textures.getTexture()); renderer.beginEntityDeferredCalls(); - renderer.enableTexture(&client.game->textures.texture); world.l()->drawEntities(); renderer.endDeferredCalls(); perf.start("draw:interface"); + renderer.enableTexture(client.game->textures.getTexture()); renderer.beginGUIDrawCalls(); - renderer.enableTexture(&client.game->textures.texture); world.l()->drawInterface(); perf.start("idle"); diff --git a/src/client/scene/LuaErrorScene.cpp b/src/client/scene/LuaErrorScene.cpp index 92f551bb..31710f82 100644 --- a/src/client/scene/LuaErrorScene.cpp +++ b/src/client/scene/LuaErrorScene.cpp @@ -36,7 +36,7 @@ void LuaErrorScene::draw() { renderer.beginChunkDeferredCalls(); renderer.endDeferredCalls(); renderer.beginGUIDrawCalls(); - renderer.enableTexture(&client.game->textures.texture); + renderer.enableTexture(client.game->textures.getTexture()); root.draw(renderer); } \ No newline at end of file diff --git a/src/client/scene/MainMenuScene.cpp b/src/client/scene/MainMenuScene.cpp index 782a9c6f..4795d3c5 100644 --- a/src/client/scene/MainMenuScene.cpp +++ b/src/client/scene/MainMenuScene.cpp @@ -11,7 +11,7 @@ #include "client/gui/TextElement.h" #include "client/menu/SubgameDef.h" #include "client/gui/basic/GuiText.h" -#include "game/atlas/asset/AtlasRef.h" +#include "game/atlas/asset/AtlasTexture.h" #include "client/gui/basic/GuiContainer.h" #include "client/gui/compound/GuiImageButton.h" @@ -104,11 +104,11 @@ MainMenuScene::MainMenuScene(Client& client) : Scene(client), if (!json["version"].is_string() || json["version"] == "") throw std::runtime_error("conf.json is missing 'version'"); - const let icon = std::filesystem::exists(file.path() / "icon.png") - ? client.game->textures.loadImage((file.path() / "icon.png").string(), json["name"]) + const AtlasTexture icon = std::filesystem::exists(file.path() / "icon.png") + ? client.game->textures.addFile((file.path() / "icon.png").string(), false) : client.game->textures["menu_flag_missing"]; - subgames.push_back({ icon, { json["name"], json["description"], json["version"] }, file.path().string() }); + subgames.push_back({ icon, { json["name"], json["description"], json["version"] }, file.path() }); } catch(const std::runtime_error& e) { std::cout << Log::err << "Failed to load subgame '" @@ -124,8 +124,8 @@ MainMenuScene::MainMenuScene(Client& client) : Scene(client), let elem = navigationList->append({{ { Gui::Prop::CLASS, vec { "navigationButton" } }, - { Gui::Prop::BACKGROUND, string("crop(0, 0, 16, 16, " + subgame.iconRef->name + ")") }, - { Gui::Prop::BACKGROUND_HOVER, string("crop(16, 0, 16, 16, " + subgame.iconRef->name + ")") } + { Gui::Prop::BACKGROUND, string("crop(0, 0, 16, 16, " + subgame.iconRef.getIdentifier() + ")") }, + { Gui::Prop::BACKGROUND_HOVER, string("crop(16, 0, 16, 16, " + subgame.iconRef.getIdentifier() + ")") } }}); elem->onClick([&](u32 button, bool down) { @@ -171,7 +171,7 @@ void MainMenuScene::draw() { renderer.beginChunkDeferredCalls(); renderer.endDeferredCalls(); + renderer.enableTexture(client.game->textures.getTexture()); renderer.beginGUIDrawCalls(); - renderer.enableTexture(&client.game->textures.texture); root.draw(renderer); } \ No newline at end of file diff --git a/src/client/stream/MeshGenStream.cpp b/src/client/stream/MeshGenStream.cpp index 219253da..55b1cd8e 100644 --- a/src/client/stream/MeshGenStream.cpp +++ b/src/client/stream/MeshGenStream.cpp @@ -87,7 +87,8 @@ void MeshGenStream::Thread::exec() { assert(u.thisChunk); for (int i = 0; i < u.adjacentChunks.size(); i++) assert(u.adjacentChunks[i]); ChunkMeshGenerator m(u.meshDetails, game.getDefs(), game.getBiomes(), - std::move(u.thisChunk), std::move(u.adjacentChunks), offsetSamplers, ChunkMeshGenerator::Detail::HIGH); + std::move(u.thisChunk), std::move(u.adjacentChunks), offsetSamplers, + glm::distance(vec3(u.thisChunk->getPos()), vec3()) <= 16 ? ChunkMeshGenerator::Detail::HIGH : ChunkMeshGenerator::Detail::LOW); empty = false; u.busy = false; } diff --git a/src/game/LocalSubgame.cpp b/src/game/LocalSubgame.cpp index ed74a311..336f886f 100644 --- a/src/game/LocalSubgame.cpp +++ b/src/game/LocalSubgame.cpp @@ -12,13 +12,13 @@ */ LocalSubgame::LocalSubgame(const std::string& baseAssets) : - textures(u16vec2(2048)), + textures(u16vec2(512)), lua(std::make_unique(*this)), biomes(std::make_unique()), defs(std::make_unique(textures)) { - textures.loadDirectory(baseAssets); + textures.addDirectory(baseAssets, true); } diff --git a/src/game/atlas/LocalDefinitionAtlas.cpp b/src/game/atlas/LocalDefinitionAtlas.cpp index d13bd4f5..d8088444 100644 --- a/src/game/atlas/LocalDefinitionAtlas.cpp +++ b/src/game/atlas/LocalDefinitionAtlas.cpp @@ -9,7 +9,7 @@ LocalDefinitionAtlas::LocalDefinitionAtlas(TextureAtlas& atlas) { //Invalid Node - BlockModel invalidModel = BlockModel::createCube({ atlas["_missing"] }, {}, {}); + BlockModel invalidModel = BlockModel({{ atlas["_missing"], {}, {} }}); BlockDef* invalid = new BlockDef(); invalid->identifier = "invalid"; invalid->name = "INVALID"; @@ -22,7 +22,7 @@ LocalDefinitionAtlas::LocalDefinitionAtlas(TextureAtlas& atlas) { defTable.insert({ "invalid", 0 }); //Air Node - BlockModel nullModel{}; + BlockModel nullModel {}; BlockDef* air = new BlockDef(); air->lightPropagates = true; air->identifier = "air"; diff --git a/src/game/atlas/ServerDefinitionAtlas.cpp b/src/game/atlas/ServerDefinitionAtlas.cpp index 535cd5c4..b02cd70d 100644 --- a/src/game/atlas/ServerDefinitionAtlas.cpp +++ b/src/game/atlas/ServerDefinitionAtlas.cpp @@ -8,7 +8,7 @@ ServerDefinitionAtlas::ServerDefinitionAtlas() { //Invalid Node - BlockModel invalidModel = BlockModel::createCube({}, {}, {}); + BlockModel invalidModel = BlockModel {}; BlockDef* invalid = new BlockDef(); invalid->identifier = "invalid"; invalid->name = "INVALID"; @@ -20,7 +20,7 @@ ServerDefinitionAtlas::ServerDefinitionAtlas() { registerDef(invalid); //Air Node - BlockModel nullModel{}; + BlockModel nullModel {}; BlockDef* air = new BlockDef(); air->lightPropagates = true; air->identifier = "air"; diff --git a/src/game/atlas/TextureAtlas.cpp b/src/game/atlas/TextureAtlas.cpp index 5d8bf97e..575032c9 100644 --- a/src/game/atlas/TextureAtlas.cpp +++ b/src/game/atlas/TextureAtlas.cpp @@ -1,144 +1,19 @@ #include -#include #include #include "TextureAtlas.h" #include "util/Log.h" #include "util/Util.h" -#include "game/atlas/asset/AtlasRef.h" +#include "game/atlas/asset/AtlasTexture.h" TextureAtlas::TextureAtlas(uvec2 size) : canvasSize(size), canvasTileSize(size / 16u), - atlasData(size.x * 4 * size.y), - maxTextureSlots(canvasTileSize.x * canvasTileSize.y), - empty(canvasTileSize.x * canvasTileSize.y, true) { - - /** - * Rect Function. - * Creates a rectangular image with the color specified. - * - * @param w - The width of the rect. - * @param h - The height of the rect. - * @param fill - The color to fill the rectangle with. - */ - - parser.addFn("rect", [](u16 w, u16 h, string hex) { - vec4 color = Util::hexToColorVec(hex); - vec newData(w * h * 4); - for (u32 i = 0; i < w * h * 4; i++) newData[i] = color[i % 4] * 255; - return TexParserData { std::make_shared(newData, uvec2 { w, h }) }; - }); - - /** - * Alpha Function. - * Adjusts the opacity of the provided image by a factor. - * - * @param factor - The factor that the opacity should be scaled by. 0 = transparent, 1 = opaque. - * @param tex - The texture to scale the alpha of. - */ - - parser.addFn("alpha", [](f32 factor, TexParserData tex) { - for (u32 i = 0; i < tex.data->size.x * tex.data->size.y; i++) - tex.data->data[i * 4 + 3] = (tex.data->data[i * 4 + 3] / 255.f * factor) * 255; - return tex; - }); - - /** - * Crop Function. - * Crops the texture to the specified dimensions and position. - * - * @param x - The left edge of the crop on the base texture. - * @param y - The top edge of the crop on the base texture. - * @param w - The width of the crop. - * @param h - The height of the crop. - * @param tex - The texture to crop. - */ - - parser.addFn("crop", [](u16 x, u16 y, u16 w, u16 h, TexParserData tex) { - let newData = vec(w * h * 4); - for (u32 i = 0; i < w * h * 4; i++) newData[i] = - tex.data->data[((x + i / 4 % w) + (y + i / 4 / w) * tex.data->size.x) * 4 + i % 4]; - - tex.data->data = newData; - tex.data->size = { w, h }; - return tex; - }); - - /** - * Multiply Function. - * Multiplies the texture by the specified color. - * - * @param hex - The hex code of the color to multiply the image by. - * @param tex - The texture to multiply. - */ - - parser.addFn("multiply", [](string hex, TexParserData tex) { - vec4 multiple = Util::hexToColorVec(hex); - - for (u32 i = 0; i < tex.data->size.x * tex.data->size.y * 4; i++) - tex.data->data[i] *= multiple[i % 4]; - - return tex; - }); - - /** - * Stack function. () - * Stacks the provided textures on top of each other, blending partially opaque pixels. - * Requires at least two textures. The maximum is currently eight textures, - * however that could be removed later with some tweaks to StringParser. - * - * @param b - The base texture to stack onto. - * @param s1 - A texture to stack on top of the base texture. - * @param s2 - Another texture to stack on top of s1. - * @param s3 - ... - */ - - parser.addFn, - optional, optional, optional, - optional, optional, optional>("", []( - TexParserData b, TexParserData s1, optional s2, - optional s3, optional s4, optional s5, - optional s6, optional s7, optional s8) { - - vec stack; - stack.reserve(8); - stack.emplace_back(s1); - if (s2) stack.emplace_back(*s2); - if (s3) stack.emplace_back(*s3); - if (s4) stack.emplace_back(*s4); - if (s5) stack.emplace_back(*s5); - if (s6) stack.emplace_back(*s6); - if (s7) stack.emplace_back(*s7); - if (s8) stack.emplace_back(*s8); - - for (const let& s : stack) { - for (u32 i = 0; i < b.data->size.x * b.data->size.y; i++) { - const f32 factor = s.data->data[i * 4 + 3] / 255.f; - b.data->data[i * 4] = b.data->data[i * 4] * (1 - factor) + s.data->data[i * 4] * factor; - b.data->data[i * 4 + 1] = b.data->data[i * 4 + 1] * (1 - factor) + s.data->data[i * 4 + 1] * factor; - b.data->data[i * 4 + 2] = b.data->data[i * 4 + 2] * (1 - factor) + s.data->data[i * 4 + 2] * factor; - b.data->data[i * 4 + 3] = std::min((u16)(b.data->data[i * 4 + 3]) + s.data->data[i * 4 + 3], 255); - } - } - - return b; - }); - - /** - * Literal Function. - * Converts raw strings to texture data by indexing the atlas. - * - * @param tex - The string of the texture to convert. - */ - - parser.addLiteralFnCtx([](TexParser::Ctx& ctx, string tex) { - return TexParser::Data { std::make_shared(ctx.atlas.getBytesOfTex(tex)) }; - }); + tilesTotal(canvasTileSize.x * canvasTileSize.y), + tiles(canvasTileSize.x * canvasTileSize.y, false) { // Get GPU texture capabilites and log it. - i32 maxTexSize, texUnits; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize); @@ -148,158 +23,98 @@ TextureAtlas::TextureAtlas(uvec2 size) : std::cout << Log::info << "This GPU supports " << texUnits << " texture units." << Log::endl; // Initialize the texture atlas. - - texture.loadFromBytes(&atlasData[0], size.x, size.y); - + texture.loadFromBytes(&vec(size.x * size.y * 4)[0], size.x, size.y); createMissingTexture(); } -vec> TextureAtlas::loadDirectory(const string& path, bool base) { - vec> refs {}; - +void TextureAtlas::update() { + if (texturesUnused.empty()) return; + std::cout << texturesUnused.size() << std::endl; + for (let& identifier : texturesUnused) { + let& texture = textures.at(identifier); + if (texture.shouldBeRemoved()) { + std::cout << "removing " << identifier << std::endl; + removeTexture(texture); + } + } + texturesUnused.clear(); +} + + +vec TextureAtlas::addDirectory(const std::filesystem::path& path, bool base) { + vec refs {}; for (let file : std::filesystem::recursive_directory_iterator(path)) - if (file.path().extension() == ".png") refs.push_back( - loadImage(file.path().string(), file.path().stem().string(), base)); - + if (file.path().extension() == ".png") refs.push_back(addFile(file.path(), base)); return refs; } -sptr TextureAtlas::loadImage(const string& path, const string& name, bool base) { +AtlasTexture TextureAtlas::addFile(const std::filesystem::path& path, bool base) { i32 width, height; - u8* rawData = stbi_load(path.data(), &width, &height, nullptr, 4); + u8* rawData = stbi_load(path.string().data(), &width, &height, nullptr, 4); vec data(rawData, rawData + width * height * 4); free(rawData); - let ref = addImage(name, base, u16vec2(width, height), data); + let ref = addBytes(path.stem().string(), base, u16vec2(width, height), data); return ref; } -void TextureAtlas::update() { - for (let it = textures.begin(); it != textures.end();) { - if (!it->second->base && it->second.unique()) { - deleteImage(it->second); - it = textures.erase(it); - } - else it++; - } -} - -vec4 TextureAtlas::getPixel(const sptr& ref, ivec2 pos) { - uvec2 absPos = { ref->rawPos.x + pos.x, ref->rawPos.y + pos.y }; - u32 index = (static_cast(absPos.y) * canvasSize.x + static_cast(absPos.x)) * 4; - - return { atlasData[index] / 255.f, atlasData[index + 1] / 255.f, - atlasData[index + 2] / 255.f, atlasData[index + 3] / 255.f }; -} - -sptr TextureAtlas::addImage(const string& name, bool base, u16vec2 size, vec data) { - u16vec2 tileSize = u16vec2(glm::ceil(vec2(size) / 16.f)); - - let posOpt = findImageSpace(tileSize); +AtlasTexture TextureAtlas::addBytes(const string& identifier, bool persistent, u16vec2 size, vec data) { + let tileSize = u16vec2(glm::ceil(vec2(size) / 16.f)); + let posOpt = findAtlasSpace(tileSize); + std::cout << tileSize << ", " << identifier << std::endl; if (!posOpt) throw std::runtime_error("Failed to find space in the dynamic definition atlas."); - u16vec2 pos = *posOpt; + u16vec2 pos = *posOpt * static_cast(16); - textureSlotsUsed += tileSize.x * tileSize.y; + tilesUsed += tileSize.x * tileSize.y; + textures.erase(identifier); + AtlasTexture ref(*this, identifier, pos, size, data); + ref.setPersistent(persistent); + if (!persistent) texturesUnused.insert(identifier); + addTexture(ref); - textures.erase(name); - let ref = make_shared(AtlasRef { - pos, - tileSize, - uvec2(pos) * 16u, - size, - vec4(pos.x * 16 / static_cast(canvasSize.x), pos.y * 16 / static_cast(canvasSize.y), - (pos.x * 16 + size.x) / static_cast(canvasSize.x), (pos.y * 16 + size.y) / static_cast(canvasSize.y)), - name, - base - }); - - textures.insert({ name, ref }); - - updateAtlas(ref->rawPos, ref->rawSize, data); return ref; } -sptr TextureAtlas::generateCrackImage(const string& name, u8 crackLevel) { - RawTexData base = getBytesOfTex(name); +AtlasTexture TextureAtlas::operator[](const string& identifier) { + const let tex = get(identifier); + if (tex.getIdentifier() != "_missing") return tex; - std::string crackStr("zeus:default:crack_" + std::to_string(crackLevel)); - RawTexData crack = getBytesOfTex(crackStr); - - for (int i = 0; i < base.size.x * base.size.y; i++) { - float alpha = crack.data[i * 4 + 3] / 255.f; - - base.data[i * 4 + 0] = static_cast(base.data[i * 4 + 0] * (1 - alpha) + crack.data[i * 4 + 0] * alpha); - base.data[i * 4 + 1] = static_cast(base.data[i * 4 + 1] * (1 - alpha) + crack.data[i * 4 + 1] * alpha); - base.data[i * 4 + 2] = static_cast(base.data[i * 4 + 2] * (1 - alpha) + crack.data[i * 4 + 2] * alpha); - } - - auto ref = addImage(name + "_crack_" + std::to_string(crackLevel), false, base.size, base.data); - return ref; + const let data = texBuilder.build(identifier); + let texture = addBytes(identifier, false, data.size, data.data); + if (data.tintMask) texture.setTintData(*data.tintInd, + addBytes(identifier + ":tint", false, data.size, *data.tintMask)); + return texture; } -sptr TextureAtlas::operator[](const string& name) { - if (textures.count(name)) return textures[name]; - - sptr gen = generateTexture(name); - if (gen) return gen; - - throw std::runtime_error("Invalid texture: '" + name + "'"); +AtlasTexture TextureAtlas::get(const string& identifier) const { + if (textures.count(identifier)) return textures.at(identifier); + return textures.at("_missing"); } -sptr TextureAtlas::generateTexture(string req) { - TexParserCtx ctx { *this }; - const let data = parser.parse(req, ctx); - return addImage(req, false, data.data->size, data.data->data); +const uvec2 TextureAtlas::getCanvasSize() { + return canvasSize; } -TextureAtlas::RawTexData TextureAtlas::getBytesOfTex(const string& name) { - let it = textures.find(name); - if (it != textures.end()) return getBytesAtPos(it->second->rawPos, it->second->rawSize); - std::cout << Log::err << "Invalid base texture '" << name << "'." << Log::endl; - let& missing = textures["_missing"]; - return getBytesAtPos(missing->rawPos, missing->rawSize); -} - -TextureAtlas::RawTexData TextureAtlas::getBytesAtPos(uvec2 pos, uvec2 size) { - RawTexData tex { vec(size.x * size.y * 4), size }; - - for (u32 i = 0; i < size.x * size.y; i++) { - u32 x = pos.x + (i % size.x); - u32 y = pos.y + (i / size.x); - - tex.data[i * 4 + 0] = atlasData[x * 4 + y * (canvasSize.x * 4)]; - tex.data[i * 4 + 1] = atlasData[x * 4 + 1 + y * (canvasSize.x * 4)]; - tex.data[i * 4 + 2] = atlasData[x * 4 + 2 + y * (canvasSize.x * 4)]; - tex.data[i * 4 + 3] = atlasData[x * 4 + 3 + y * (canvasSize.x * 4)]; - } - - return tex; -} - -optional TextureAtlas::findImageSpace(u16vec2 tileSize) { +optional TextureAtlas::findAtlasSpace(u16vec2 tileSize) { for (u16 j = 0; j < canvasTileSize.y - (tileSize.y - 1); j++) { for (u16 i = 0; i < canvasTileSize.x - (tileSize.x - 1); i++) { - if (empty[j * canvasTileSize.x + i]) { - bool space = true; - - for (int k = 0; k < tileSize.y; k++) { - for (int l = 0; l < tileSize.x; l++) { - if (!empty[(j + k) * canvasTileSize.x + (i + l)]) { - space = false; - break; - } + bool space = true; + + for (u16 k = 0; k < tileSize.y; k++) { + for (u16 l = 0; l < tileSize.x; l++) { + if (tiles[(j + k) * canvasTileSize.x + (i + l)]) { + space = false; + break; } - - if (!space) break; } - if (space) { - for (int k = 0; k < tileSize.y; k++) { - for (int l = 0; l < tileSize.x; l++) { - empty[(j + k) * canvasTileSize.x + (i + l)] = false; - } - } - return u16vec2(i, j); - } + if (!space) break; + } + + if (space) { + for (u16 k = 0; k < tileSize.y; k++) + for (u16 l = 0; l < tileSize.x; l++) + tiles[(j + k) * canvasTileSize.x + (i + l)] = true; + return u16vec2(i, j); } } } @@ -319,38 +134,45 @@ void TextureAtlas::createMissingTexture() { data[i * 4 + 3] = 255; } - addImage("_missing", true, u16vec2(16), data); + addBytes("_missing", true, u16vec2(16), data); } -void TextureAtlas::updateAtlas(u16vec2 pos, u16vec2 size, vec data) { - texture.updateTexture(pos.x, pos.y, size.x, size.y, data.data()); +void TextureAtlas::addTexture(const AtlasTexture& tex) { + let pos = tex.getPos(); + let size = tex.getSize(); + textures.insert({ tex.getIdentifier(), tex }); + texture.updateTexture(pos.x, pos.y, size.x, size.y, tex.getBytes().data()); +} + +void TextureAtlas::removeTexture(const AtlasTexture& tex) { + textures.erase(tex.getIdentifier()); - for (u32 i = 0; i < size.x * size.y * 4; i++) { - u32 x = (i / 4) % size.x; - u32 y = (i / 4) / size.x; - u32 of = i % 4; + let tilePos = tex.getTilePos(); + let tileSize = tex.getTileSize(); + + tilesUsed -= tileSize.x * tileSize.y; + + for (u16 x = tilePos.x; x < tilePos.x + tileSize.x; x++) + for (u16 y = tilePos.y; y < tilePos.y + tileSize.y; y++) + tiles[y * canvasTileSize.x + x] = false; - atlasData[(pos.x + x + (pos.y + y) * canvasSize.x) * 4 + of] = data[(x + y * size.x) * 4 + of]; - } + // For debugging + vec clear(tileSize.x * 16 * tileSize.y * 16 * 4); + texture.updateTexture(tilePos.x * 16, tilePos.y * 16, tileSize.x * 16, tileSize.y * 16, clear.data()); } -void TextureAtlas::deleteImage(sptr ref) { - // Actually delete the image from the texture (for debugging) - - //auto data = new unsigned char[ref->width * ref->height * 4]; - // - //for (int i = 0; i < ref->width * ref->height * 4; i++) { - // data[i] = 0; - //} - // - //updateAtlas(ref->tileX, ref->tileY, ref->width, ref->height, data); - //delete[] data; - - textureSlotsUsed -= ref->size.x * ref->size.y; - - for (u32 x = ref->pos.x; x < ref->pos.x + ref->size.x; x++) { - for (u32 y = ref->pos.y; y < ref->pos.y + ref->size.y; y++) { - empty[y * canvasTileSize.x + x] = true; - } - } +const u32 TextureAtlas::getTilesUsed() { + return tilesUsed; +} + +const u32 TextureAtlas::getTilesTotal() { + return tilesTotal; +} + +const Texture& TextureAtlas::getTexture() { + return texture; +} + +void TextureAtlas::alertUnused(const string& identifier) { + texturesUnused.insert(identifier); } \ No newline at end of file diff --git a/src/game/atlas/TextureAtlas.h b/src/game/atlas/TextureAtlas.h index 5b74d01a..721d8a40 100644 --- a/src/game/atlas/TextureAtlas.h +++ b/src/game/atlas/TextureAtlas.h @@ -1,81 +1,70 @@ #pragma once +#include +#include +#include #include #include "util/Types.h" #include "util/StringParser.h" #include "client/graph/Texture.h" +#include "game/atlas/TextureBuilder.h" +#include "game/atlas/asset/AtlasTexture.h" -class AtlasRef; +class AtlasTexture; + +/** + * Manages loading and generating images into a single atlas texture, + * with reference counting and runtime manipulations. + */ class TextureAtlas { public: - struct RawTexData { - RawTexData(const vec& data, const uvec2& size): - data(data), size(size) {}; - - vec data; - uvec2 size; - }; - TextureAtlas() = default; explicit TextureAtlas(uvec2 size); void update(); - vec> loadDirectory(const string& path, bool base = true); + vec addDirectory(const std::filesystem::path& path, bool base); - sptr loadImage(const string& path, const string& name, bool base = false); + AtlasTexture addFile(const std::filesystem::path& path, bool base); - sptr addImage(const string& name, bool base, u16vec2 size, vec data); + AtlasTexture addBytes(const string& identifier, bool base, u16vec2 size, vec data); - sptr operator[](const string& name); + AtlasTexture operator[](const string& identifier); - vec4 getPixel(const sptr& ref, ivec2 pos); + AtlasTexture get(const string& identifier) const; - sptr generateCrackImage(const string& name, u8 crackLevel); + const uvec2 getCanvasSize(); - ivec2 canvasSize; - ivec2 canvasTileSize; + const u32 getTilesUsed(); - Texture texture {}; - vec atlasData; + const u32 getTilesTotal(); - u32 textureSlotsUsed = 0; - u32 maxTextureSlots = 0; - + const Texture& getTexture(); + + void alertUnused(const string& identifier); private: - sptr generateTexture(string req); - - RawTexData getBytesOfTex(const string& name); - - RawTexData getBytesAtPos(uvec2 pos, uvec2 size); - - optional findImageSpace(u16vec2 tileSize); - void createMissingTexture(); - void updateAtlas(u16vec2 pos, u16vec2 size, vec data); + optional findAtlasSpace(u16vec2 tileSize); - void deleteImage(sptr ref); + void addTexture(const AtlasTexture& tex); - struct TexParserData { - TexParserData() = default; - explicit TexParserData(sptr data): data(data) {}; - - sptr data; - }; + void removeTexture(const AtlasTexture& tex); - struct TexParserCtx { - TextureAtlas& atlas; - }; + uvec2 canvasSize; + uvec2 canvasTileSize; - using TexParser = StringParser; + u32 tilesUsed = 0; + u32 tilesTotal = 0; - TexParser parser {}; + vec tiles; + std::unordered_set texturesUnused {}; + std::unordered_map textures {}; - vec empty; - std::unordered_map> textures; + Texture texture {}; + const TextureBuilder texBuilder { *this }; }; diff --git a/src/game/atlas/TextureBuilder.cpp b/src/game/atlas/TextureBuilder.cpp new file mode 100644 index 00000000..57839124 --- /dev/null +++ b/src/game/atlas/TextureBuilder.cpp @@ -0,0 +1,113 @@ +#include "TextureAtlas.h" +#include "TextureBuilder.h" +#include "game/atlas/asset/AtlasTexture.h" + +TextureBuilder::Data TextureBuilder::Data::literal(Context& ctx, string str) { + let tex = ctx.atlas.get(str); + return Data(tex.getSize(), tex.getBytes()); +} + +TextureBuilder::Data TextureBuilder::Data::canvas(u16 w, optional> h, optional fill) { + u16vec2 size = { w, h && std::holds_alternative(*h) ? std::get(*h) : w }; + vec4 color = Util::hexToColorVec(fill ? *fill : h && + std::holds_alternative(*h) ? std::get(*h) : "#0000"); + + vec data(size.x * size.y * 4); + for (u32 i = 0; i < size.x * size.y * 4; i++) data[i] = color[i % 4] * 255; + return Data(size, data); +} + +TextureBuilder::Data TextureBuilder::Data::alpha(f32 factor, Data tex) { + for (u32 i = 0; i < tex.size.x * tex.size.y; i++) + tex.data[i * 4 + 3] = (tex.data[i * 4 + 3] / 255.f * factor) * 255; + return tex; +} + +TextureBuilder::Data TextureBuilder::Data::crop(u16 x, u16 y, u16 w, variant hV, optional texO) { + u16 h = std::holds_alternative(hV) ? std::get(hV) : w; + Data& tex = std::holds_alternative(hV) ? std::get(hV) : *texO; + + vec data(w * h * 4); + for (u32 i = 0; i < w * h * 4; i++) data[i] = + tex.data[((x + i / 4 % w) + (y + i / 4 / w) * tex.size.x) * 4 + i % 4]; + tex.data = data; + + if (tex.tintMask) { + vec mask(w * h * 4); + for (u32 i = 0; i < w * h * 4; i++) mask[i] = + (*tex.tintMask)[((x + i / 4 % w) + (y + i / 4 / w) * tex.size.x) * 4 + i % 4]; + tex.tintMask = mask; + } + + tex.size = { w, h }; + return tex; +} + +TextureBuilder::Data TextureBuilder::Data::multiply(variant multiple, Data tex) { + if (std::holds_alternative(multiple)) { + Data& data = std::get(multiple); + for (u32 i = 0; i < tex.size.x * tex.size.y * 4; i++) tex.data[i] *= data.data[i % 4]; + } + else { + vec4 mul = Util::hexToColorVec(std::get(multiple)); + for (u32 i = 0; i < tex.size.x * tex.size.y * 4; i++) tex.data[i] *= mul[i % 4]; + } + + return tex; +} + +TextureBuilder::Data TextureBuilder::Data::stack(Data b, Data s1, optional s2, optional s3, + optional s4, optional s5, optional s6, optional s7, optional s8) { + vec stack; + stack.reserve(8); + stack.emplace_back(s1); + if (s2) stack.emplace_back(*s2); + if (s3) stack.emplace_back(*s3); + if (s4) stack.emplace_back(*s4); + if (s5) stack.emplace_back(*s5); + if (s6) stack.emplace_back(*s6); + if (s7) stack.emplace_back(*s7); + if (s8) stack.emplace_back(*s8); + + for (const Data& s : stack) { + for (u32 i = 0; i < b.size.x * b.size.y; i++) { + const f32 factor = s.data[i * 4 + 3] / 255.f; + b.data[i * 4] = b.data[i * 4] * (1 - factor) + s.data[i * 4] * factor; + b.data[i * 4 + 1] = b.data[i * 4 + 1] * (1 - factor) + s.data[i * 4 + 1] * factor; + b.data[i * 4 + 2] = b.data[i * 4 + 2] * (1 - factor) + s.data[i * 4 + 2] * factor; + b.data[i * 4 + 3] = std::min(static_cast(b.data[i * 4 + 3]) + s.data[i * 4 + 3], 255); + + if (s.tintMask) { + if (!b.tintMask) b.tintMask = canvas(b.size.x, b.size.y, {}).data; + (*b.tintMask)[i * 4] = (*b.tintMask)[i * 4] * (1 - factor) + (*s.tintMask)[i * 4] * factor; + (*b.tintMask)[i * 4 + 1] = (*b.tintMask)[i * 4 + 1] * (1 - factor) + (*s.tintMask)[i * 4 + 1] * factor; + (*b.tintMask)[i * 4 + 2] = (*b.tintMask)[i * 4 + 2] * (1 - factor) + (*s.tintMask)[i * 4 + 2] * factor; + (*b.tintMask)[i * 4 + 3] = factor * 255; + } + } + } + + return b; +} + +TextureBuilder::Data TextureBuilder::Data::tint(u32 tint, TextureBuilder::Data tex, optional mask) { + tex.tintInd = tint; + if (mask) tex.tintMask = mask->data; + else tex.tintMask = canvas(tex.size.x, tex.size.y, "#fff").data; + return tex; +} + +TextureBuilder::TextureBuilder(TextureAtlas& atlas): ctx({ atlas }) { + parser.addLiteralFnCtx(&TextureBuilder::Data::literal); + parser.addFn>, optional>("canvas", &TextureBuilder::Data::canvas); + parser.addFn("alpha", &TextureBuilder::Data::alpha); + parser.addFn, optional>("crop", &TextureBuilder::Data::crop); + parser.addFn, Data>("multiply", &TextureBuilder::Data::multiply); + parser.addFn, optional, optional, optional, + optional, optional, optional>("", &TextureBuilder::Data::stack); + parser.addFn>("tint", &TextureBuilder::Data::tint); +} + +TextureBuilder::Data TextureBuilder::build(const string& str) const { + return parser.parse(str, ctx); +} \ No newline at end of file diff --git a/src/game/atlas/TextureBuilder.h b/src/game/atlas/TextureBuilder.h new file mode 100644 index 00000000..6d7002ec --- /dev/null +++ b/src/game/atlas/TextureBuilder.h @@ -0,0 +1,115 @@ +#pragma once + +#include "util/StringParser.h" +//#include "game/atlas/TextureAtlas.h" + +class TextureAtlas; + +class TextureBuilder { +public: + struct Data; + +private: + struct Context { + TextureAtlas& atlas; + }; + + typedef StringParser Parser; + +public: + class Data { + friend class TextureBuilder; + + /** + * Loads a texture identified by a string into a Data. + * + * @param str - The string texture name to load. + */ + + static Parser::Data literal(Parser::Ctx& ctx, string str); + + /** + * Creates an empty canvas of a specified color. + * + * @param w - The width of the canvas. + * @param h - [optional] The height of the canvas, defaults to the width otherwise. + * @param fill - [optional] The color to fill the canvas with, defaults to transparent. + */ + + static Parser::Data canvas(u16 w, optional> h, optional fill); + + /** + * Adjusts the opacity of the provided texture by a factor. + * + * @param factor - The factor that the opacity should be scaled by. 0 = transparent, 1 = opaque. + * @param tex - The texture to scale the alpha of. + */ + + static Parser::Data alpha(f32 factor, Parser::Data tex); + + /** + * Crops the texture to the specified dimensions and offset. + * + * @param x - The left edge of the crop on the base texture. + * @param y - The top edge of the crop on the base texture. + * @param w - The width of the crop. + * @param h - The height of the crop. + * @param tex - The texture to crop. + */ + + static Parser::Data crop(u16 x, u16 y, u16 w, variant hV, optional texO); + + /** + * Multiplies the texture by the specified color or texture. + * + * @param multiple - A color to multiply the texture by, or another texture to multiply it by. + * @param tex - The texture to multiply. + */ + + static Parser::Data multiply(variant multiple, Data tex); + + /** + * Stacks the provided textures on top of each other, blending partially opaque pixels. + * Requires at least two textures. The maximum is currently eight textures, + * however that could be removed later with some tweaks to StringParser. + * + * @param b - The base texture to stack onto. + * @param s1 - A texture to stack on top of the base texture. + * @param s2 - Another texture to stack on top of s1. + * @param s3 - ... + */ + + static Parser::Data stack(Data b, Data s1, optional s2, optional s3, + optional s4, optional s5, optional s6, optional s7, optional s8); + + /** + * Tints the texture specified with a specific tint map, usually controlled by biome parameters. + * @param tint - The tint map to use. + * @param tex - The texture to tint. + * @param mask - An image whose red channel determines the strength of the tint for every pixel. + */ + + static Parser::Data tint(u32 tint, Data tex, optional mask); + + public: + Data() = default; + explicit Data(u16vec2 size): size(size) {}; + Data(u16vec2 size, const vec& data): size(size), data(data) {}; + + u16vec2 size; + vec data; + optional tintInd; + optional> tintMask; + }; + + TextureBuilder(TextureAtlas& atlas); + + Data build(const string& str) const; + +private: + + mutable Context ctx; + Parser parser {}; +}; + + diff --git a/src/game/atlas/asset/AtlasRef.h b/src/game/atlas/asset/AtlasRef.h deleted file mode 100644 index a499b263..00000000 --- a/src/game/atlas/asset/AtlasRef.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// Created by aurailus on 17/04/19. -// - -#pragma once - -#include "util/Util.h" - -struct AtlasRef { - u16vec2 pos {}; - u16vec2 size {}; - uvec2 rawPos {}; - uvec2 rawSize {}; - vec4 uv {}; - - string name = ""; - bool base = false; -}; - diff --git a/src/game/atlas/asset/AtlasTexture.cpp b/src/game/atlas/asset/AtlasTexture.cpp new file mode 100644 index 00000000..faaa6ad0 --- /dev/null +++ b/src/game/atlas/asset/AtlasTexture.cpp @@ -0,0 +1,44 @@ +#include "AtlasTexture.h" + +#include "game/atlas/TextureAtlas.h" + +vec4 AtlasTexture::getUVPos() const { + const uvec2 size = holds_alternative(shr->data) ? + get(shr->data).size : get(shr->data).size; + const uvec2 pos = holds_alternative(shr->data) ? + shr->pos : shr->pos + get(shr->data).pos; + const f32 divX = atlas.getCanvasSize().x, divY = atlas.getCanvasSize().y; + + return vec4(pos.x / divX, pos.y / divY, (pos.x + size.x) / divX, (pos.y + size.y) / divY); +} + +vec AtlasTexture::getBytes() const { + if (std::holds_alternative(shr->data)) return get(shr->data).data; + throw std::runtime_error("cant"); +} + +optional AtlasTexture::getTintInd() const { + if (!shr->tintData) return std::nullopt; + return shr->tintData->first; +} + +optional AtlasTexture::getTintMask() const { + if (!shr->tintData) return std::nullopt; + return *shr->tintData->second.get(); +} + +void AtlasTexture::setPersistent(bool persistent) { + shr->persistent = persistent; +} + +void AtlasTexture::setTintData(u32 tintInd, const AtlasTexture& tintMask) { + shr->tintData = {{ tintInd, make_unique(tintMask) }}; +} + +bool AtlasTexture::shouldBeRemoved() { + return shr.use_count() == 1 && !shr->persistent; +} + +AtlasTexture::~AtlasTexture() { + if (shr.use_count() == 2 && !shr->persistent) atlas.alertUnused(shr->identifier); +} \ No newline at end of file diff --git a/src/game/atlas/asset/AtlasTexture.h b/src/game/atlas/asset/AtlasTexture.h new file mode 100644 index 00000000..dee5f7c6 --- /dev/null +++ b/src/game/atlas/asset/AtlasTexture.h @@ -0,0 +1,147 @@ +#pragma once + +#include "util/Util.h" + +class TextureAtlas; + +/** + * Represents a single drawable texture from the texture atlas. + * Will either contain its own data, or reference another atlas texture as a crop of it. + * AtlasTextures will automatically remove themselves from the texture atlas once all copies of them are destroyed. + */ + +class AtlasTexture { + /** Stores byte data for an atlas texture. */ + struct ByteData { + ByteData(uvec2 size, const vec& data): data(data), size(size) {}; + + /** The size of the texture. */ + uvec2 size; + + /** The raw bytes of the texture. */ + vec data; + }; + + /** Stores a reference to another atlas texture and a crop region. */ + struct CropData { + CropData(uvec2 pos, uvec2 size, const sptr& source): pos(pos), size(size), source(source) {} + + /** The top-left position of the crop region. */ + uvec2 pos; + + /** The sise of the crop region. */ + uvec2 size; + + /** The image to crop from. */ + sptr source; + }; + + /** + * The main data container for the AtlasTexture. It is stored in a + * shared pointer so that it may be reference counted. + * Contains the identifier, atlas position, and data of a texture in the atlas. + * The data may be a ByteData storing raw texture bytes, + * or a CropData referencing another texture to crop this one from. + * May also store a reference to a tint index and mask, if the texture is to be biome tinted. + */ + + struct SharedData { + SharedData(const string& identifier, uvec2 pos, const variant& data): + identifier(identifier), pos(pos), data(data) {} + + /** The position of the top-left point of the texture in the texture atlas. */ + uvec2 pos {}; + + /** The identifier of the texture. */ + string identifier; + + /** Whether or not the texture should be kept even if it is not in use. */ + bool persistent = false; + + /** The data of the texture, either bytes or a crop region. */ + variant data; + + /** An optional pair containing biome tint data. */ + optional>> tintData; + }; + +public: + AtlasTexture(const AtlasTexture& o): shr(o.shr), atlas(o.atlas) {} + + AtlasTexture& operator=(const AtlasTexture& o) { shr = o.shr; return *this; } + + AtlasTexture(TextureAtlas& atlas, const string& identifier, uvec2 pos, uvec2 size, const sptr& source): + AtlasTexture(atlas, identifier, source->getPos(), CropData { pos, size, source }) {} + + AtlasTexture(TextureAtlas& atlas, const string& identifier, uvec2 pos, uvec2 size, vec data): + AtlasTexture(atlas, identifier, pos, ByteData { size, data }) {} + + AtlasTexture(TextureAtlas& atlas, const string& identifier, uvec2 pos, const variant& data): + shr(std::make_shared(identifier, pos, data)), atlas(atlas) {} + + /** Returns the texture's identifier. */ + inline const string& getIdentifier() const { + return shr->identifier; + } + + /** Returns the texture's atlas position in pixels. */ + inline const uvec2& getPos() const { + return shr->pos; + } + + /** Returns the texture's altas size in pixels. */ + inline const uvec2& getSize() const { + return holds_alternative(shr->data) ? + get(shr->data).size : get(shr->data).size; + } + + /** Returns the texture's atlas position in tiles. */ + inline u16vec2 getTilePos() const { + return u16vec2(shr->pos / 16u); + } + + /** Returns the texture's atlas size in tiles. */ + inline u16vec2 getTileSize() const { + return u16vec2(glm::ceil(vec2(getSize()) / 16.f)); + } + + /** Returns the texture's UVs, in a four-dimensional vector. */ + vec4 getUVPos() const; + + /** + * Returns the bytes of the texture. + * This is an expensive operation because the bytes may need to be cloned from a crop region, + * so a reference cannot be returned. In the future, + * a ref-counted object may be returned instead to reduce overhead. + */ + + vec getBytes() const; + + /** Returns the biome tint index of the texture, if it is to be tinted. */ + optional getTintInd() const; + + /** Returns the biome tint mask texture of this texture, if it is to be tinted. */ + optional getTintMask() const; + + /** Sets the persistence of the texture, if it is persistent, it will not be deleted when it is no longer in use. */ + void setPersistent(bool persistent); + + /** Sets the tint information of the texture. */ + void setTintData(u32 tintInd, const AtlasTexture& tintMask); + + /** Returns true if the texture is only referenced by the texture atlas and is not persistent. */ + bool shouldBeRemoved(); + + ~AtlasTexture(); + +private: + + // IF YOU ARE PUTTING SOMETHING ELSE HERE, YOU PROBABLY SHOULDN'T BE. + // PUT ANY ATLASTEXTURE DATA IN THE SHAREDDATA STRUCT INSTEAD. + + /** A reference to the texture atlas holding this texture. */ + TextureAtlas& atlas; + + /** The actual ref-counted data of the AtlasTexture. */ + sptr shr; +}; \ No newline at end of file diff --git a/src/game/def/CraftItemDef.cpp b/src/game/def/CraftItemDef.cpp index 98ec0a8e..c30d89eb 100644 --- a/src/game/def/CraftItemDef.cpp +++ b/src/game/def/CraftItemDef.cpp @@ -5,103 +5,99 @@ #include "CraftItemDef.h" #include "game/atlas/TextureAtlas.h" -#include "game/atlas/asset/AtlasRef.h" -CraftItemDef::CraftItemDef(const std::string& identifier, const std::string& name, unsigned short maxStackSize, - const std::vector& textures, const std::vector>& textureRefs) : +CraftItemDef::CraftItemDef(const string& identifier, const string& name, u16 maxStackSize, + const vec& textures, const vec& textureRefs) : CraftItemDef(identifier, 0, name, maxStackSize, textures, textureRefs) {} -CraftItemDef::CraftItemDef(const std::string& identifier, unsigned int index, const std::string& name, - unsigned short maxStackSize, const std::vector& textures, - const std::vector>& textureRefs) : - +CraftItemDef::CraftItemDef(const string& identifier, u16 index, const string& name, + u16 maxStackSize, const vec& textures, const vec& textureRefs) : ItemDef(ItemDef::Type::CRAFTITEM, identifier, name, index, maxStackSize), - textures(textures), - textureRefs(textureRefs) {} + textures(textures), textureRefs(textureRefs) {} void CraftItemDef::createModel(TextureAtlas& atlas) { - std::unique_ptr mesh = std::make_unique(); + uptr mesh = make_unique(); - std::vector vertices; - std::vector indices{ 0, 1, 2, 2, 3, 0, 4, 7, 6, 6, 5, 4 }; + vec vertices; + vec indices { 0, 1, 2, 2, 3, 0, 4, 7, 6, 6, 5, 4 }; - const std::shared_ptr& ref = textureRefs[0]; - static const float xo = 0.040f; + static const f32 xo = 0.040f; + vec4 uv = textureRefs[0].getUVPos(); - for (unsigned int i = 0; i <= 1; i++) { - float xx = xo * (i == 1 ? -1 : 1); - std::vector myVerts = { - {{ xx, -0.5, -0.5 }, { ref->uv.x, ref->uv.w, 0, 1 }, { 1, 1, 1 }, true, { (i == 1 ? -1 : 1), 0, 0 }, {}, - {}}, - {{ xx, 0.5, -0.5 }, { ref->uv.x, ref->uv.y, 0, 1 }, { 1, 1, 1 }, true, { (i == 1 ? -1 : 1), 0, 0 }, {}, {}}, - {{ xx, 0.5, 0.5 }, { ref->uv.z, ref->uv.y, 0, 1 }, { 1, 1, 1 }, true, { (i == 1 ? -1 : 1), 0, 0 }, {}, {}}, - {{ xx, -0.5, 0.5 }, { ref->uv.z, ref->uv.w, 0, 1 }, { 1, 1, 1 }, true, { (i == 1 ? -1 : 1), 0, 0 }, {}, {}} + for (u8 i = 0; i <= 1; i++) { + f32 xx = xo * (i == 1 ? -1 : 1); + vec myVerts = { + {{ xx, -0.5, -0.5 }, { uv.x, uv.w, 0, 1 }, { 1, 1, 1 }, true, { (i == 1 ? -1 : 1), 0, 0 }, {}, {}}, + {{ xx, 0.5, -0.5 }, { uv.x, uv.y, 0, 1 }, { 1, 1, 1 }, true, { (i == 1 ? -1 : 1), 0, 0 }, {}, {}}, + {{ xx, 0.5, 0.5 }, { uv.z, uv.y, 0, 1 }, { 1, 1, 1 }, true, { (i == 1 ? -1 : 1), 0, 0 }, {}, {}}, + {{ xx, -0.5, 0.5 }, { uv.z, uv.w, 0, 1 }, { 1, 1, 1 }, true, { (i == 1 ? -1 : 1), 0, 0 }, {}, {}} }; vertices.insert(vertices.end(), myVerts.begin(), myVerts.end()); } - unsigned int indOffset = 8; - for (unsigned int i = 0; i < 16 * 16; i++) { - glm::vec2 samplePos = { i % 16, i / 16 }; - glm::vec2 off{ samplePos.x / 16.f, samplePos.y / 16.f }; - glm::vec4 col = atlas.getPixel(ref, samplePos); - - if (col.w < 0.5) continue; - - if (samplePos.y == 0 || atlas.getPixel(ref, { samplePos.x, samplePos.y - 1 }).w < 0.5) { - std::vector myVerts = { - {{ -xo, 0.5 - off.y, -0.5 + off.x }, col, { 1, 1, 1 }, false, { 0, 1, 0 }, {}, {}}, - {{ -xo, 0.5 - off.y, -0.5 + off.x + 0.0625 }, col, { 1, 1, 1 }, false, { 0, 1, 0 }, {}, {}}, - {{ xo, 0.5 - off.y, -0.5 + off.x + 0.0625 }, col, { 1, 1, 1 }, false, { 0, 1, 0 }, {}, {}}, - {{ xo, 0.5 - off.y, -0.5 + off.x }, col, { 1, 1, 1 }, false, { 0, 1, 0 }, {}, {}}}; - vertices.insert(vertices.end(), myVerts.begin(), myVerts.end()); - std::vector myInds = { indOffset, indOffset + 1, indOffset + 2, indOffset + 2, indOffset + 3, - indOffset }; - indices.insert(indices.end(), myInds.begin(), myInds.end()); - indOffset += 4; - } - - if (samplePos.y == 15 || atlas.getPixel(ref, { samplePos.x, samplePos.y + 1 }).w < 0.5) { - std::vector myVerts = { - {{ -xo, 0.5 - off.y - 0.0625, -0.5 + off.x }, col, { 1, 1, 1 }, false, { 0, -1, 0 }, {}, {}}, - {{ -xo, 0.5 - off.y - 0.0625, -0.5 + off.x + 0.0625 }, col, { 1, 1, 1 }, false, { 0, -1, 0 }, {}, {}}, - {{ xo, 0.5 - off.y - 0.0625, -0.5 + off.x + 0.0625 }, col, { 1, 1, 1 }, false, { 0, -1, 0 }, {}, {}}, - {{ xo, 0.5 - off.y - 0.0625, -0.5 + off.x }, col, { 1, 1, 1 }, false, { 0, -1, 0 }, {}, {}}}; - vertices.insert(vertices.end(), myVerts.begin(), myVerts.end()); - std::vector myInds = { indOffset, indOffset + 3, indOffset + 2, indOffset + 2, indOffset + 1, - indOffset }; - indices.insert(indices.end(), myInds.begin(), myInds.end()); - indOffset += 4; - } - - if (samplePos.x == 0 || atlas.getPixel(ref, { samplePos.x - 1, samplePos.y }).w < 0.5) { - std::vector myVerts = { - {{ -xo, 0.5 - off.y - 0.0625, -0.5 + off.x }, col, { 1, 1, 1 }, false, { 0, 0, 1 }, {}, {}}, - {{ -xo, 0.5 - off.y, -0.5 + off.x }, col, { 1, 1, 1 }, false, { 0, 0, 1 }, {}, {}}, - {{ xo, 0.5 - off.y, -0.5 + off.x }, col, { 1, 1, 1 }, false, { 0, 0, 1 }, {}, {}}, - {{ xo, 0.5 - off.y - 0.0625, -0.5 + off.x }, col, { 1, 1, 1 }, false, { 0, 0, 1 }, {}, {}}}; - vertices.insert(vertices.end(), myVerts.begin(), myVerts.end()); - std::vector myInds = { indOffset, indOffset + 1, indOffset + 2, indOffset + 2, indOffset + 3, - indOffset }; - indices.insert(indices.end(), myInds.begin(), myInds.end()); - indOffset += 4; - } - - if (samplePos.x == 15 || atlas.getPixel(ref, { samplePos.x + 1, samplePos.y }).w < 0.5) { - std::vector myVerts = { - {{ -xo, 0.5 - off.y - 0.0625, -0.5 + off.x + 0.0625 }, col, { 1, 1, 1 }, false, { 0, 0, -1 }, {}, {}}, - {{ -xo, 0.5 - off.y, -0.5 + off.x + 0.0625 }, col, { 1, 1, 1 }, false, { 0, 0, -1 }, {}, {}}, - {{ xo, 0.5 - off.y, -0.5 + off.x + 0.0625 }, col, { 1, 1, 1 }, false, { 0, 0, -1 }, {}, {}}, - {{ xo, 0.5 - off.y - 0.0625, -0.5 + off.x + 0.0625 }, col, { 1, 1, 1 }, false, { 0, 0, -1 }, {}, {}}}; - vertices.insert(vertices.end(), myVerts.begin(), myVerts.end()); - std::vector myInds = { indOffset, indOffset + 3, indOffset + 2, indOffset + 2, indOffset + 1, - indOffset }; - indices.insert(indices.end(), myInds.begin(), myInds.end()); - indOffset += 4; - } - } - - mesh->create(vertices, indices); +// u16 indOffset = 8; +// vec data = ref.getBytes(); +// for (u16 i = 0; i < 16 * 16; i++) { +// vec2 samplePos = { i % 16, i / 16 }; +// vec2 off { samplePos.x / 16.f, samplePos.y / 16.f }; +// vec4 col = atlas.getPixel(ref, samplePos); +// +// if (col.w < 0.5) continue; +// +// if (samplePos.y == 0 || atlas.getPixel(ref, { samplePos.x, samplePos.y - 1 }).w < 0.5) { +// std::vector myVerts = { +// {{ -xo, 0.5 - off.y, -0.5 + off.x }, col, { 1, 1, 1 }, false, { 0, 1, 0 }, {}, {}}, +// {{ -xo, 0.5 - off.y, -0.5 + off.x + 0.0625 }, col, { 1, 1, 1 }, false, { 0, 1, 0 }, {}, {}}, +// {{ xo, 0.5 - off.y, -0.5 + off.x + 0.0625 }, col, { 1, 1, 1 }, false, { 0, 1, 0 }, {}, {}}, +// {{ xo, 0.5 - off.y, -0.5 + off.x }, col, { 1, 1, 1 }, false, { 0, 1, 0 }, {}, {}}}; +// vertices.insert(vertices.end(), myVerts.begin(), myVerts.end()); +// std::vector myInds = { indOffset, indOffset + 1, indOffset + 2, indOffset + 2, indOffset + 3, +// indOffset }; +// indices.insert(indices.end(), myInds.begin(), myInds.end()); +// indOffset += 4; +// } +// +// if (samplePos.y == 15 || atlas.getPixel(ref, { samplePos.x, samplePos.y + 1 }).w < 0.5) { +// std::vector myVerts = { +// {{ -xo, 0.5 - off.y - 0.0625, -0.5 + off.x }, col, { 1, 1, 1 }, false, { 0, -1, 0 }, {}, {}}, +// {{ -xo, 0.5 - off.y - 0.0625, -0.5 + off.x + 0.0625 }, col, { 1, 1, 1 }, false, { 0, -1, 0 }, {}, {}}, +// {{ xo, 0.5 - off.y - 0.0625, -0.5 + off.x + 0.0625 }, col, { 1, 1, 1 }, false, { 0, -1, 0 }, {}, {}}, +// {{ xo, 0.5 - off.y - 0.0625, -0.5 + off.x }, col, { 1, 1, 1 }, false, { 0, -1, 0 }, {}, {}}}; +// vertices.insert(vertices.end(), myVerts.begin(), myVerts.end()); +// std::vector myInds = { indOffset, indOffset + 3, indOffset + 2, indOffset + 2, indOffset + 1, +// indOffset }; +// indices.insert(indices.end(), myInds.begin(), myInds.end()); +// indOffset += 4; +// } +// +// if (samplePos.x == 0 || atlas.getPixel(ref, { samplePos.x - 1, samplePos.y }).w < 0.5) { +// std::vector myVerts = { +// {{ -xo, 0.5 - off.y - 0.0625, -0.5 + off.x }, col, { 1, 1, 1 }, false, { 0, 0, 1 }, {}, {}}, +// {{ -xo, 0.5 - off.y, -0.5 + off.x }, col, { 1, 1, 1 }, false, { 0, 0, 1 }, {}, {}}, +// {{ xo, 0.5 - off.y, -0.5 + off.x }, col, { 1, 1, 1 }, false, { 0, 0, 1 }, {}, {}}, +// {{ xo, 0.5 - off.y - 0.0625, -0.5 + off.x }, col, { 1, 1, 1 }, false, { 0, 0, 1 }, {}, {}}}; +// vertices.insert(vertices.end(), myVerts.begin(), myVerts.end()); +// std::vector myInds = { indOffset, indOffset + 1, indOffset + 2, indOffset + 2, indOffset + 3, +// indOffset }; +// indices.insert(indices.end(), myInds.begin(), myInds.end()); +// indOffset += 4; +// } +// +// if (samplePos.x == 15 || atlas.getPixel(ref, { samplePos.x + 1, samplePos.y }).w < 0.5) { +// std::vector myVerts = { +// {{ -xo, 0.5 - off.y - 0.0625, -0.5 + off.x + 0.0625 }, col, { 1, 1, 1 }, false, { 0, 0, -1 }, {}, {}}, +// {{ -xo, 0.5 - off.y, -0.5 + off.x + 0.0625 }, col, { 1, 1, 1 }, false, { 0, 0, -1 }, {}, {}}, +// {{ xo, 0.5 - off.y, -0.5 + off.x + 0.0625 }, col, { 1, 1, 1 }, false, { 0, 0, -1 }, {}, {}}, +// {{ xo, 0.5 - off.y - 0.0625, -0.5 + off.x + 0.0625 }, col, { 1, 1, 1 }, false, { 0, 0, -1 }, {}, {}}}; +// vertices.insert(vertices.end(), myVerts.begin(), myVerts.end()); +// std::vector myInds = { indOffset, indOffset + 3, indOffset + 2, indOffset + 2, indOffset + 1, +// indOffset }; +// indices.insert(indices.end(), myInds.begin(), myInds.end()); +// indOffset += 4; +// } +// } +// mesh->create(vertices, indices); + entityModel->fromMesh(std::move(mesh)); } diff --git a/src/game/def/CraftItemDef.h b/src/game/def/CraftItemDef.h index ef10014b..4f94ba18 100644 --- a/src/game/def/CraftItemDef.h +++ b/src/game/def/CraftItemDef.h @@ -1,11 +1,10 @@ #pragma once -#include - -#include "lua/Lua.h" #include "ItemDef.h" -class AtlasRef; +#include "lua/Lua.h" +#include "game/atlas/asset/AtlasTexture.h" + class TextureAtlas; /** @@ -22,19 +21,18 @@ public: CraftItemDef(): ItemDef(ItemDef::Type::CRAFTITEM) {}; - CraftItemDef(const std::string& identifier, const std::string& name, unsigned short maxStackSize, - const std::vector& textures, const std::vector>& textureRefs); + CraftItemDef(const string& identifier, const string& name, u16 maxStackSize, + const vec& textures, const vec& texturesRefs); - CraftItemDef(const std::string& identifier, unsigned int index, const std::string& name, - unsigned short maxStackSize, const std::vector& textures, - const std::vector>& textureRefs); + CraftItemDef(const string& identifier, u16 index, const string& name, + u16 maxStackSize, const vec& textures, const vec& texturesRefs); void createModel(TextureAtlas& atlas); bool hasUse(); - std::vector textures {}; - std::vector> textureRefs {}; + vec textures {}; + vec textureRefs {}; std::unordered_map callbacks {}; }; diff --git a/src/game/def/mesh/BlockModel.cpp b/src/game/def/mesh/BlockModel.cpp index f80be2e7..89b36a0b 100644 --- a/src/game/def/mesh/BlockModel.cpp +++ b/src/game/def/mesh/BlockModel.cpp @@ -1,95 +1,84 @@ -// -// Created by aurailus on 2020-07-06. -// - #include "BlockModel.h" #include "util/Vec.h" -BlockModel -BlockModel::createCube(std::vector> textureRefs, - std::vector blendInds, std::vector> blendMaskRefs) { + +BlockModel::BlockModel(vec, optional>> data): + visible(true), culls(true) { - BlockModel blockModel; - blockModel.visible = true; - blockModel.culls = true; + textures.reserve(data.size()); + for (let& tuple : data) textures.emplace_back(get<0>(tuple)); + if (textures.size() == 0) throw std::runtime_error("Created cube with empty textures array."); - std::vector vertices{}; - std::vector indices{}; - unsigned int accessInd; - - for (auto& ref : textureRefs) if (ref != nullptr) blockModel.textureRefs.insert(ref); - - if (textureRefs.empty()) textureRefs.emplace_back(nullptr); - if (blendInds.empty()) blendInds.emplace_back(0); - if (blendMaskRefs.empty()) blendMaskRefs.emplace_back(nullptr); - - //Left Face - vertices = { - {{ 0, 0, 0 }, {}, { 0, 1 }, { 0, 1 }}, - {{ 0, 0, 1 }, {}, { 1, 1 }, { 1, 1 }}, - {{ 0, 1, 1 }, {}, { 1, 0 }, { 1, 0 }}, - {{ 0, 1, 0 }, {}, { 0, 0 }, { 0, 0 }}}; - indices = { 0, 1, 2, 2, 3, 0 }; - accessInd = (std::max)(0, (std::min)(static_cast(textureRefs.size() - 1), 2)); - MeshPart leftMeshPart(vertices, indices, textureRefs[accessInd], blendInds[accessInd], blendMaskRefs[accessInd]); - blockModel.parts[static_cast(EVec::LEFT)].push_back(leftMeshPart); - - //Right Face - vertices = { - {{ 1, 1, 1 }, {}, { 1, 0 }, { 1, 0 }}, - {{ 1, 0, 1 }, {}, { 1, 1 }, { 1, 1 }}, - {{ 1, 0, 0 }, {}, { 0, 1 }, { 0, 1 }}, - {{ 1, 1, 0 }, {}, { 0, 0 }, { 0, 0 }}}; - indices = { 0, 1, 2, 2, 3, 0 }; - accessInd = (std::max)(0, (std::min)(static_cast(textureRefs.size() - 1), 3)); - MeshPart rightMeshPart(vertices, indices, textureRefs[accessInd], blendInds[accessInd], blendMaskRefs[accessInd]); - blockModel.parts[static_cast(EVec::RIGHT)].push_back(rightMeshPart); - - //Top Face - vertices = { + /* Top Face */ + vec vertices = { {{ 0, 1, 0 }, {}, { 0, 0 }, { 0, 0 }}, {{ 0, 1, 1 }, {}, { 0, 1 }, { 0, 1 }}, {{ 1, 1, 1 }, {}, { 1, 1 }, { 1, 1 }}, {{ 1, 1, 0 }, {}, { 1, 0 }, { 1, 0 }}}; - indices = { 0, 1, 2, 2, 3, 0 }; - accessInd = (std::max)(0, (std::min)(static_cast(textureRefs.size() - 1), 0)); - MeshPart topMeshPart(vertices, indices, textureRefs[accessInd], blendInds[accessInd], blendMaskRefs[accessInd]); - blockModel.parts[static_cast(EVec::TOP)].push_back(topMeshPart); + vec indices = { 0, 1, 2, 2, 3, 0 }; - //Bottom Face + u32 accessInd = (std::max)(0, (std::min)(static_cast(data.size() - 1), 0)); + parts[static_cast(EVec::TOP)].emplace_back(vertices, indices, + get<0>(data[accessInd]), get<1>(data[accessInd]), get<2>(data[accessInd])); + + /* Bottom Face */ vertices = { {{ 0, 0, 0 }, {}, { 0, 0 }, { 0, 0 }}, {{ 1, 0, 0 }, {}, { 1, 0 }, { 1, 0 }}, {{ 1, 0, 1 }, {}, { 1, 1 }, { 1, 1 }}, {{ 0, 0, 1 }, {}, { 0, 1 }, { 0, 1 }}}; indices = { 0, 1, 2, 2, 3, 0 }; - accessInd = (std::max)(0, (std::min)(static_cast(textureRefs.size() - 1), 1)); - MeshPart bottomMeshPart(vertices, indices, textureRefs[accessInd], blendInds[accessInd], blendMaskRefs[accessInd]); - blockModel.parts[static_cast(EVec::BOTTOM)].push_back(bottomMeshPart); - //Front Face + accessInd = (std::max)(0, (std::min)(static_cast(data.size() - 1), 1)); + parts[static_cast(EVec::BOTTOM)].emplace_back(vertices, indices, + get<0>(data[accessInd]), get<1>(data[accessInd]), get<2>(data[accessInd])); + + /* Back Face */ + vertices = { + {{ 0, 0, 0 }, {}, { 0, 1 }, { 0, 1 }}, + {{ 0, 0, 1 }, {}, { 1, 1 }, { 1, 1 }}, + {{ 0, 1, 1 }, {}, { 1, 0 }, { 1, 0 }}, + {{ 0, 1, 0 }, {}, { 0, 0 }, { 0, 0 }}}; + indices = { 0, 1, 2, 2, 3, 0 }; + + accessInd = (std::max)(0, (std::min)(static_cast(data.size() - 1), 2)); + parts[static_cast(EVec::BACK)].emplace_back(vertices, indices, + get<0>(data[accessInd]), get<1>(data[accessInd]), get<2>(data[accessInd])); + + /* Front Face */ + vertices = { + {{ 1, 1, 1 }, {}, { 1, 0 }, { 1, 0 }}, + {{ 1, 0, 1 }, {}, { 1, 1 }, { 1, 1 }}, + {{ 1, 0, 0 }, {}, { 0, 1 }, { 0, 1 }}, + {{ 1, 1, 0 }, {}, { 0, 0 }, { 0, 0 }}}; + indices = { 0, 1, 2, 2, 3, 0 }; + + accessInd = (std::max)(0, (std::min)(static_cast(data.size() - 1), 3)); + parts[static_cast(EVec::FRONT)].emplace_back(vertices, indices, + get<0>(data[accessInd]), get<1>(data[accessInd]), get<2>(data[accessInd])); + + /* Left Face */ vertices = { {{ 0, 0, 1 }, {}, { 0, 1 }, { 0, 1 }}, {{ 1, 0, 1 }, {}, { 1, 1 }, { 1, 1 }}, {{ 1, 1, 1 }, {}, { 1, 0 }, { 1, 0 }}, {{ 0, 1, 1 }, {}, { 0, 0 }, { 0, 0 }}}; indices = { 0, 1, 2, 2, 3, 0 }; - accessInd = (std::max)(0, (std::min)(static_cast(textureRefs.size() - 1), 4)); - MeshPart frontMeshPart(vertices, indices, textureRefs[accessInd], blendInds[accessInd], blendMaskRefs[accessInd]); - blockModel.parts[static_cast(EVec::FRONT)].push_back(frontMeshPart); - //Back Face + accessInd = (std::max)(0, (std::min)(static_cast(data.size() - 1), 4)); + parts[static_cast(EVec::LEFT)].emplace_back(vertices, indices, + get<0>(data[accessInd]), get<1>(data[accessInd]), get<2>(data[accessInd])); + + /* Back Face */ vertices = { {{ 0, 0, 0 }, {}, { 0, 1 }, { 0, 1 }}, {{ 0, 1, 0 }, {}, { 0, 0 }, { 0, 0 }}, {{ 1, 1, 0 }, {}, { 1, 0 }, { 1, 0 }}, {{ 1, 0, 0 }, {}, { 1, 1 }, { 1, 1 }}}; indices = { 0, 1, 2, 2, 3, 0 }; - accessInd = (std::max)(0, (std::min)(static_cast(textureRefs.size() - 1), 5)); - MeshPart backMeshPart(vertices, indices, textureRefs[accessInd], blendInds[accessInd], blendMaskRefs[accessInd]); - blockModel.parts[static_cast(EVec::BACK)].push_back(backMeshPart); - return blockModel; + accessInd = (std::max)(0, (std::min)(static_cast(data.size() - 1), 5)); + parts[static_cast(EVec::RIGHT)].emplace_back(vertices, indices, + get<0>(data[accessInd]), get<1>(data[accessInd]), get<2>(data[accessInd])); } - diff --git a/src/game/def/mesh/BlockModel.h b/src/game/def/mesh/BlockModel.h index 80e0d43a..cd629006 100644 --- a/src/game/def/mesh/BlockModel.h +++ b/src/game/def/mesh/BlockModel.h @@ -1,22 +1,16 @@ -// -// Created by aurailus on 13/08/19. -// - #pragma once -#include -#include - #include "MeshPart.h" +#include "util/Types.h" struct BlockModel { - std::array, 7> parts {}; - std::vector> meshMods {}; - std::set> textureRefs {}; + BlockModel() = default; + explicit BlockModel(vec, optional>> data); + + vec textures {}; + array, 7> parts {}; + vec> meshMods {}; bool culls = false; bool visible = false; - - static BlockModel createCube(std::vector> textureRefs, - std::vector blendInds, std::vector> blendMaskRefs); }; \ No newline at end of file diff --git a/src/game/def/mesh/MeshPart.cpp b/src/game/def/mesh/MeshPart.cpp index ace06292..ef8a55d4 100644 --- a/src/game/def/mesh/MeshPart.cpp +++ b/src/game/def/mesh/MeshPart.cpp @@ -1,70 +1,71 @@ -// -// Created by aurailus on 02/12/18. -// - #define GLM_ENABLE_EXPERIMENTAL - #include #include "MeshPart.h" -#include "game/atlas/asset/AtlasRef.h" - -MeshPart::MeshPart(const std::vector& vertices, const std::vector& indices, - std::shared_ptr texture, unsigned int blendInd, std::shared_ptr blendMask) : +MeshPart::MeshPart(const vec& vertices, const vec& indices, + optional texture, optional blendInd, optional blendTexture) : vertices(vertices), indices(indices), texture(texture), blendInd(blendInd), - blendMask(blendMask) { + blendTexture(blendTexture) { - //We assume these vertex structs do not have normals, and generate them here from the triangle information. - //To do this, we have to assume that each group of 3 indices is a triangle (which it would be hard for it to not be) - //and that no vertexes are shared on corners or places where vectors should be interpolated. + /* + * We assume these vertex structs do not have normals, and generate them here from the triangle information. + * To do this, we have to assume that each group of 3 indices is a triangle (which it would be hard for it to not be) + * and that no vertexes are shared on corners or places where vectors should be interpolated. + */ - //Iterate through the indices to find all used vertices to add normals and adjust texture coordinates. - for (int i = 0; i < this->indices.size() / 3; i++) { - //Get the three vertices - BlockModelVertex& p1 = this->vertices[this->indices[i * 3]]; - BlockModelVertex& p2 = this->vertices[this->indices[i * 3 + 1]]; - BlockModelVertex& p3 = this->vertices[this->indices[i * 3 + 2]]; + /* Iterate through the indices to find all used vertices to add normals and adjust texture coordinates. */ + for (usize i = 0; i < this->indices.size() / 3; i++) { + /* Get the three vertices. */ + let& p1 = this->vertices[this->indices[i * 3]]; + let& p2 = this->vertices[this->indices[i * 3 + 1]]; + let& p3 = this->vertices[this->indices[i * 3 + 2]]; - //Get the normal of the formed triangle - glm::vec3 normal = glm::triangleNormal(p1.pos, p2.pos, p3.pos); + /* Get the normal of the formed triangle. */ + vec3 normal = glm::triangleNormal(p1.pos, p2.pos, p3.pos); - //Set the normal on the vertices + /* Set the normal on the vertices. */ p1.nml = normal; p2.nml = normal; p3.nml = normal; } - //If the MeshPart is being initialized on the client with an AtlasRef to base it's values off of, - //it will set the UVs to the coordinates of the texture relative to the TextureAtlas. + /* + * If the MeshPart is being initialized on the client with an AtlasRef to base its values off of, + * it will set the UVs to the coordinates of the texture relative to the TextureAtlas. + */ + if (texture) { - auto uv = texture->uv; + auto uv = texture->getUVPos(); - //Iterate through the vertices to adjust the texture coordinates to fit the textureAtlas. - for (BlockModelVertex& vertex : this->vertices) { - //Store the old positions in texUVs + /* Iterate through the vertices to adjust the texture coordinates to fit the textureAtlas. */ + for (BlockModelVertex& vertex: this->vertices) { + + /* Store the old positions in texUVs. */ vertex.texUVs.x = vertex.tex.x; vertex.texUVs.y = vertex.tex.y; - //Generate solid coordinates for the defs positions + + /* Generate solid coordinates for the defs positions. */ vertex.tex.x = uv.x + ((uv.z - uv.x) * vertex.tex.x); vertex.tex.y = uv.y + ((uv.w - uv.y) * vertex.tex.y); - if (blendMask) { - auto bUV = blendMask->uv; + if (blendTexture) { + auto bUV = blendTexture->getUVPos(); - //Store the old positions in blendMaskUVs + /* Store the old positions in blendMaskUVs. */ vertex.blendMaskUVs.x = vertex.blendMask.x; vertex.blendMaskUVs.y = vertex.blendMask.y; - //Generate solid coordinates for the defs positions + + /* Generate solid coordinates for the defs positions. */ vertex.blendMask.x = bUV.x + ((bUV.z - bUV.x) * vertex.blendMask.x); vertex.blendMask.y = bUV.y + ((bUV.w - bUV.y) * vertex.blendMask.y); } else { - // Negative One denotes full blend on fragment shader. + /* Negative One denotes full blend on fragment shader. */ vertex.blendMask.x = -1; vertex.blendMask.y = -1; } diff --git a/src/game/def/mesh/MeshPart.h b/src/game/def/mesh/MeshPart.h index 4876bce7..12f3ecac 100644 --- a/src/game/def/mesh/MeshPart.h +++ b/src/game/def/mesh/MeshPart.h @@ -1,29 +1,22 @@ -// -// Created by aurailus on 02/12/18. -// - #pragma once -#include -#include - -#include "ShaderMod.h" -#include "BlockModelVertex.h" - -class AtlasRef; +#include "util/Types.h" +#include "game/def/mesh/ShaderMod.h" +#include "game/atlas/asset/AtlasTexture.h" +#include "game/def/mesh/BlockModelVertex.h" struct MeshPart { - MeshPart(const std::vector& vertices, const std::vector& indices, - std::shared_ptr texture, unsigned int blendInd, std::shared_ptr blendMask); + MeshPart(const vec& vertices, const vec& indices, + optional texture = std::nullopt, optional blendInd = std::nullopt, + optional blendTexture = std::nullopt); - std::vector vertices; - std::vector indices; + vec vertices; + vec indices; - std::shared_ptr texture; - - unsigned int blendInd = 0; - std::shared_ptr blendMask; + optional blendInd; + optional texture; + optional blendTexture; ShaderMod shaderMod = ShaderMod::NONE; - float modValue = 0; + f32 modValue = 0; }; \ No newline at end of file diff --git a/src/lua/register/RegisterBlock.h b/src/lua/register/RegisterBlock.h index a819ace3..128e5380 100644 --- a/src/lua/register/RegisterBlock.h +++ b/src/lua/register/RegisterBlock.h @@ -9,21 +9,12 @@ #include "game/def/CraftItemDef.h" #include "game/def/mesh/BlockModel.h" #include "game/def/mesh/SelectionBox.h" +#include "game/atlas/asset/AtlasTexture.h" #include "game/atlas/LocalDefinitionAtlas.h" #include "game/atlas/ServerDefinitionAtlas.h" namespace RegisterBlock { - namespace { - struct TintParserData { - string tex; - optional tint; - optional mask; - }; - - using TintParser = StringParser; - TintParser parser {}; - bool parserReady = false; /** * Takes a lua selection box table list, and returns a vector of selection boxes. @@ -32,16 +23,15 @@ namespace RegisterBlock { * @returns a vector of selection boxes. */ - static std::vector parseBoxes(sol::table boxesTable) { - std::vector boxes{}; + static vec parseBoxes(sol::table boxesTable) { + vec boxes{}; for (auto pair : boxesTable) { if (!pair.second.is()) throw std::runtime_error("must be a table"); sol::table table = pair.second; if (table.size() != 6) throw std::runtime_error("must contain exactly 6 elements"); - boxes.emplace_back(glm::vec3{ table[1], table[2], table[3] }, - glm::vec3{ table[4], table[5], table[6] }); + boxes.emplace_back(vec3 { table[1], table[2], table[3] }, vec3 { table[4], table[5], table[6] }); } return boxes; @@ -60,8 +50,8 @@ namespace RegisterBlock { static std::pair createBlockModel(sol::table blockTable, sol::table blockModels, TextureAtlas* atlas) { // Get the specified block model - auto modelStr = blockTable.get_or("model", "zepha:base:block"); - auto modelOpt = blockModels.get>(modelStr); + let modelStr = blockTable.get_or("model", "zepha:base:block"); + let modelOpt = blockModels.get>(modelStr); if (!modelOpt) throw std::runtime_error("Non-existent model \"" + modelStr + "\" specified"); sol::table modelTable = *modelOpt; @@ -72,55 +62,55 @@ namespace RegisterBlock { model.visible = blockTable.get_or("visible", true); // Convert textures and low-def textures into vectors - auto texturesOpt = blockTable.get>("textures"); - auto ldTexturesOpt = blockTable.get>("lowdef_textures"); + let texturesOpt = blockTable.get>("textures"); + let ldTexturesOpt = blockTable.get>("lowdef_textures"); if (!texturesOpt) throw std::runtime_error("Missing textures property"); - std::vector textures; - for (auto pair : *texturesOpt) { - if (!pair.second.is()) - throw std::runtime_error("textures table contains non-string value"); - textures.push_back(pair.second.as()); + vec textures; + for (let& pair : *texturesOpt) { + if (!pair.second.is()) throw std::runtime_error( + "textures table contains non-string value"); + textures.push_back(pair.second.as()); } - if (textures.size() == 0) textures.push_back("_missing"); + if (textures.empty()) textures.push_back("_missing"); - std::vector lowdef_textures; + vec lowdef_textures; if (!ldTexturesOpt) lowdef_textures = textures; else { - for (auto pair : *ldTexturesOpt) { - if (!pair.second.is()) - throw std::runtime_error("lowdef_textures table has non-string value!"); - lowdef_textures.push_back(pair.second.as()); + for (let& pair : *ldTexturesOpt) { + if (!pair.second.is()) throw std::runtime_error( + "lowdef_textures table has non-string value!"); + lowdef_textures.push_back(pair.second.as()); } } - if (lowdef_textures.size() == 0) lowdef_textures.push_back("_missing"); + if (lowdef_textures.empty()) lowdef_textures.push_back("_missing"); // Parse through mesh mods and add them - sol::optional meshModTable = modelTable.get>("mesh_mods"); + optional meshModTable = modelTable.get>("mesh_mods"); if (meshModTable) { for (auto& modEntry : *meshModTable) { auto modTable = modEntry.second.as(); - std::string meshMod = modTable.get_or("type", "none"); + string meshMod = modTable.get_or("type", "none"); if (meshMod == "none") continue; else if (meshMod == "offset_x") - model.meshMods.emplace_back(MeshMod::OFFSET_X, modTable.get_or("amplitude", 1)); + model.meshMods.emplace_back(MeshMod::OFFSET_X, modTable.get_or("amplitude", 1)); else if (meshMod == "offset_y") - model.meshMods.emplace_back(MeshMod::OFFSET_Y, modTable.get_or("amplitude", 1)); + model.meshMods.emplace_back(MeshMod::OFFSET_Y, modTable.get_or("amplitude", 1)); else if (meshMod == "offset_z") - model.meshMods.emplace_back(MeshMod::OFFSET_Z, modTable.get_or("amplitude", 1)); + model.meshMods.emplace_back(MeshMod::OFFSET_Z, modTable.get_or("amplitude", 1)); else if (meshMod == "rotate_x") - model.meshMods.emplace_back(MeshMod::ROTATE_X, modTable.get_or("amplitude", 1)); + model.meshMods.emplace_back(MeshMod::ROTATE_X, modTable.get_or("amplitude", 1)); else if (meshMod == "rotate_y") - model.meshMods.emplace_back(MeshMod::ROTATE_Y, modTable.get_or("amplitude", 1)); + model.meshMods.emplace_back(MeshMod::ROTATE_Y, modTable.get_or("amplitude", 1)); else if (meshMod == "rotate_z") - model.meshMods.emplace_back(MeshMod::ROTATE_Z, modTable.get_or("amplitude", 1)); + model.meshMods.emplace_back(MeshMod::ROTATE_Z, modTable.get_or("amplitude", 1)); } } // Parse through all the parts and add them to the model - auto partsOpt = modelTable.get>("parts"); + let partsOpt = modelTable.get>("parts"); if (!partsOpt) throw std::runtime_error("blockmodel is missing parts table"); partsOpt->for_each([&](sol::object key, sol::object value) { @@ -128,7 +118,7 @@ namespace RegisterBlock { if (!value.is()) throw std::runtime_error("meshpart must be a table"); sol::table meshPartTable = value.as(); - auto points_optional = meshPartTable.get>("points"); + let points_optional = meshPartTable.get>("points"); if (!points_optional) throw std::runtime_error("Meshpart is missing a points table"); sol::table points = *points_optional; @@ -136,20 +126,20 @@ namespace RegisterBlock { throw std::runtime_error("Points table must contain a multiple of 20 values"); // Populate the Vertices and Indices vectors from the points table - std::vector vertices; - std::vector indices; + vec vertices; + vec indices; - for (int i = 1; i <= points.size() / 5; i++) { - int offset = (i - 1) * 5 + 1; + for (u32 i = 1; i <= points.size() / 5; i++) { + u32 offset = (i - 1) * 5 + 1; - glm::vec3 pos(points[offset], points[offset + 1], points[offset + 2]); - glm::vec2 tex(points[offset + 3], points[offset + 4]); + vec3 pos(points[offset], points[offset + 1], points[offset + 2]); + vec2 tex(points[offset + 3], points[offset + 4]); - vertices.push_back(BlockModelVertex{ pos, {}, tex, tex, {}, {}}); + vertices.push_back(BlockModelVertex { pos, {}, tex, tex, {}, {} }); } - int ind = 0; - for (int i = 1; i <= points.size() / 20; i++) { + u32 ind = 0; + for (u32 i = 1; i <= points.size() / 20; i++) { indices.push_back(ind); indices.push_back(ind + 1); indices.push_back(ind + 2); @@ -159,25 +149,22 @@ namespace RegisterBlock { ind += 4; } - // Get the part's texture - int tex = std::max(static_cast(meshPartTable.get_or("tex", 1)), 1); - let data = parser.parse(textures[std::min(tex - 1, (int) textures.size() - 1)]); - u32 blendInd = data.tint ? *data.tint + 1 : 0; + // Get texture, and add texture refs to blockModel if the atlas is provided + u32 tex = std::max(meshPartTable.get_or("tex", 1), 1u); + + optional tintInd {}; + optional textureRef {}; + optional tintTextureRef = {}; - // Add texture refs to blockModel if the textures table is provided - std::shared_ptr textureRef = nullptr, blendMaskRef = nullptr; if (atlas) { - textureRef = (*atlas)[data.tex]; - model.textureRefs.insert(textureRef); - - if (blendInd && data.mask) { - blendMaskRef = (*atlas)[*data.mask]; - model.textureRefs.insert(blendMaskRef); - } + textureRef = (*atlas)[textures[std::min(tex - 1, static_cast(textures.size()) - 1)]]; + model.textures.push_back(*textureRef); + tintInd = textureRef->getTintInd(); + tintTextureRef = textureRef->getTintMask(); } // Create the meshpart object - MeshPart meshPart(std::move(vertices), std::move(indices), textureRef, blendInd, blendMaskRef); + MeshPart meshPart(std::move(vertices), std::move(indices), textureRef, tintInd, tintTextureRef); // Add the shader mod, if it exists sol::optional shaderModTable = meshPartTable.get>("shader_mod"); @@ -225,27 +212,18 @@ namespace RegisterBlock { }); // Create the far model - BlockModel farModel; + BlockModel farModel {}; auto ldRender = blockTable.get_or("lowdef_render", true); if (atlas) { - std::vector> textureRefs; - std::vector blendInds; - std::vector> blendMaskRefs; + vec, optional>> modelData; - for (auto i = 0; i < lowdef_textures.size(); i++) { - let data = parser.parse(lowdef_textures[i]); - u32 blendInd = data.tint ? *data.tint + 1 : 0; - - textureRefs.push_back((*atlas)[data.tex]); - blendInds.push_back(blendInd); - blendMaskRefs.push_back(data.mask ? (*atlas)[*data.mask] : nullptr); + for (let i = 0; i < lowdef_textures.size(); i++) { + let textureRef = (*atlas)[lowdef_textures[i]]; + modelData.emplace_back(textureRef, textureRef.getTintInd(), textureRef.getTintMask()); } - farModel = BlockModel::createCube(textureRefs, blendInds, blendMaskRefs); - } - else { - farModel = BlockModel::createCube({}, {}, {}); + farModel = BlockModel { modelData }; } farModel.culls = ldRender; @@ -386,28 +364,6 @@ namespace RegisterBlock { } } - /** - * Initializes the parser with the necessary parse functions. - * In the future, this could be cleaned up, but as it is it's totally fine. - */ - - static void initParser() { - if (parserReady) return; - - parser.setUnknownFnsAreLiteral(true); - - parser.addFn>("tint", - [](u32 tint, TintParserData tex, optional mask) { - return TintParserData { tex.tex, tint, mask ? optional(mask->tex) : std::nullopt }; - }); - - parser.addLiteralFn([](string tex) { - return TintParserData { tex, std::nullopt, std::nullopt }; - }); - - parserReady = true; - } - /** * Server method to register a block. Calls registerBlock with the necessary parameters. * Registers a block to the DefinitionAtlas. @@ -417,8 +373,7 @@ namespace RegisterBlock { * @param identifier - The identifier of the block to register. */ - static void server(sol::table& core, ServerSubgame& game, const std::string& identifier) { - initParser(); + static void server(sol::table& core, ServerSubgame& game, const string& identifier) { registerBlock(core["registered_blocks"], core["registered_blockmodels"], identifier, game.getDefs(), nullptr); } @@ -432,8 +387,7 @@ namespace RegisterBlock { * @param identifier - The identifier of the block to register. */ - static void client(sol::table& core, LocalSubgame& game, const std::string& identifier) { - initParser(); + static void client(sol::table& core, LocalSubgame& game, const string& identifier) { registerBlock(core["registered_blocks"], core["registered_blockmodels"], identifier, game.getDefs(), &game.textures); } diff --git a/src/lua/register/RegisterItem.h b/src/lua/register/RegisterItem.h index 12ef274c..90f5804c 100644 --- a/src/lua/register/RegisterItem.h +++ b/src/lua/register/RegisterItem.h @@ -5,13 +5,13 @@ #include "game/def/BiomeDef.h" #include "game/ServerSubgame.h" #include "game/def/CraftItemDef.h" +#include "game/atlas/asset/AtlasTexture.h" #include "game/atlas/LocalDefinitionAtlas.h" #include "game/atlas/ServerDefinitionAtlas.h" namespace RegisterItem { namespace { - /** * Attempts to add a callback of the type specified from the block table provided * to the block definition provided. Does nothing if the block table doesn't have a callback of said type. @@ -23,9 +23,9 @@ namespace RegisterItem { */ static void addCallback(CraftItemDef& itemDef, sol::table& itemTable, - const std::string& name, CraftItemDef::Callback cbType) { + const string& name, CraftItemDef::Callback cbType) { - auto cb = itemTable.get>(name); + auto cb = itemTable.get>(name); if (cb) itemDef.callbacks.insert({ cbType, *cb }); } @@ -40,26 +40,25 @@ namespace RegisterItem { * @param atlas - The Texture Atlas, pass in if running on the client, otherwise pass nullptr. */ - static void - registerItem(sol::table items, const std::string& identifier, DefinitionAtlas& defs, TextureAtlas* atlas) { - + static void registerItem(sol::table items, const string& identifier, + DefinitionAtlas& defs, TextureAtlas* atlas) { sol::table itemTable = items[identifier]; // Basic item properties - auto nameOpt = itemTable.get>("name"); - auto texturesOpt = itemTable.get>("textures"); - auto maxStack = itemTable.get_or("stack", 64); + let nameOpt = itemTable.get>("name"); + let texturesOpt = itemTable.get>("textures"); + let maxStack = itemTable.get_or("stack", 64); if (!nameOpt) throw std::runtime_error(identifier + " is missing name property!"); if (!texturesOpt) throw std::runtime_error(identifier + " is missing textures property!"); //Convert Textures Table to Vector - std::vector textures; - std::vector> textureRefs; + vec textures; + vec textureRefs; for (auto pair : *texturesOpt) { - if (!pair.second.is()) throw std::runtime_error("textures table has non-string value"); - textures.push_back(pair.second.as()); - if (atlas) textureRefs.push_back((*atlas)[pair.second.as()]); + if (!pair.second.is()) throw std::runtime_error("textures table has non-string value"); + textures.push_back(pair.second.as()); + if (atlas) textureRefs.push_back((*atlas)[pair.second.as()]); } if (textures.size() == 0) { textures.push_back("_missing"); @@ -89,7 +88,6 @@ namespace RegisterItem { } } - /** * Server method to register an item. Calls registerItem with the necessary parameters. * Registers an item to the DefinitionAtlas. @@ -99,11 +97,10 @@ namespace RegisterItem { * @param identifier - The identifier of the item to register. */ - static void server(sol::table& core, ServerSubgame& game, const std::string& identifier) { + static void server(sol::table& core, ServerSubgame& game, const string& identifier) { registerItem(core["registered_items"], identifier, game.getDefs(), nullptr); } - /** * Client method to register an item. Calls registerItem with the necessary parameters. * Registers an item to the DefinitionAtlas. @@ -113,7 +110,7 @@ namespace RegisterItem { * @param identifier - The identifier of the item to register. */ - static void client(sol::table& core, LocalSubgame& game, const std::string& identifier) { + static void client(sol::table& core, LocalSubgame& game, const string& identifier) { registerItem(core["registered_items"], identifier, game.getDefs(), &game.textures); } } \ No newline at end of file diff --git a/src/world/ServerWorld.h b/src/world/ServerWorld.h index 70a3f83d..0e5d2a9d 100644 --- a/src/world/ServerWorld.h +++ b/src/world/ServerWorld.h @@ -79,10 +79,10 @@ private: vec generateOrder; /** The range in mapblocks to generate around clients. */ - const ivec2 mapBlockGenRange = { 4, 4 }; + const ivec2 mapBlockGenRange = { 6, 6 }; /** The range in mapblocks to send to clients. */ - const ivec2 sendRange = { 4, 4 }; + const ivec2 sendRange = { 6, 6 }; /** The range around clients that chunks should be updated. */ const ivec2 activeChunkRange = { 4, 4 }; diff --git a/src/world/dim/LocalDimension.h b/src/world/dim/LocalDimension.h index 2f4f0cbc..959bb3de 100644 --- a/src/world/dim/LocalDimension.h +++ b/src/world/dim/LocalDimension.h @@ -101,7 +101,7 @@ private: u32 mapBlockScanY = 0; const static u32 MAPBLOCK_SCAN_Y_INTERVAL = 8; - const ivec2 retainMapBlockRange = { 4, 4 }; + const ivec2 retainMapBlockRange = { 6, 6 }; i64 entityInd = -1; }; diff --git a/src/world/gen/MapGen.h b/src/world/gen/MapGen.h index 99d77085..f1f01e58 100644 --- a/src/world/gen/MapGen.h +++ b/src/world/gen/MapGen.h @@ -20,11 +20,6 @@ class DefinitionAtlas; class MapGen { public: - /** The precision of the Biome map, as a divisor of the chunk size. */ -// constexpr static u8 BIOP = 4; - - /** The precision of the Terrain maps, as a divisor of the chunk size. */ -// constexpr static u8 TERP = 4; /** A type alias for the type the map of Chunks stored in the Job. */ typedef std::unordered_map, Vec::ivec3> ChunkMap; diff --git a/subgames/zeus/key_mock.xcf b/subgames/zeus/key_mock.xcf new file mode 100644 index 00000000..e9152d81 Binary files /dev/null and b/subgames/zeus/key_mock.xcf differ diff --git a/subgames/zeus/mods/auri_hot_wheel/textures/hot_wheel.png b/subgames/zeus/mods/auri_hot_wheel/textures/hot_wheel.png deleted file mode 100644 index 208894ec..00000000 Binary files a/subgames/zeus/mods/auri_hot_wheel/textures/hot_wheel.png and /dev/null differ diff --git a/subgames/zeus/mods/zeus_default/script/blocks/grass.lua b/subgames/zeus/mods/zeus_default/script/blocks/grass.lua index 3e3ad1a7..d20bf66c 100644 --- a/subgames/zeus/mods/zeus_default/script/blocks/grass.lua +++ b/subgames/zeus/mods/zeus_default/script/blocks/grass.lua @@ -5,13 +5,13 @@ zepha.register_block(":grass", { textures = { "tint(0, zeus:default:grass_top)", "zeus:default:dirt", - "tint(0, zeus:default:grass_side_under, zeus:default:grass_side_under_mask)", + "(zeus:default:dirt, tint(0, zeus:default:grass_side))", "tint(0, zeus:default:grass_floating)", }, lowdef_textures = { "tint(0, zeus:default:grass_top)", "zeus:default:dirt", - "tint(0, zeus:default:grass_side_ld, zeus:default:grass_side_ld_mask)" + "(zeus:default:dirt, tint(0, zeus:default:grass_floating))" }, tool_props = { diff --git a/subgames/zeus/mods/zeus_default/script/blocks/leaves.lua b/subgames/zeus/mods/zeus_default/script/blocks/leaves.lua index 9c1c70e6..d6ccbdfc 100644 --- a/subgames/zeus/mods/zeus_default/script/blocks/leaves.lua +++ b/subgames/zeus/mods/zeus_default/script/blocks/leaves.lua @@ -8,7 +8,7 @@ zepha.register_block(":leaves", { "zeus:default:leaves_puff" }, lowdef_textures = { - "tint(0, zeus:default:leaves_opaque)", + "zeus:default:leaves_opaque", }, tool_props = { diff --git a/subgames/zeus/mods/zeus_default/textures/grass_side.png b/subgames/zeus/mods/zeus_default/textures/grass_side.png index 397db30f..200f179f 100644 Binary files a/subgames/zeus/mods/zeus_default/textures/grass_side.png and b/subgames/zeus/mods/zeus_default/textures/grass_side.png differ diff --git a/subgames/zeus/mods/zeus_default/textures/grass_side_ld.png b/subgames/zeus/mods/zeus_default/textures/grass_side_ld.png deleted file mode 100644 index 7cb1dcaf..00000000 Binary files a/subgames/zeus/mods/zeus_default/textures/grass_side_ld.png and /dev/null differ diff --git a/subgames/zeus/mods/zeus_default/textures/leaves_opaque.png b/subgames/zeus/mods/zeus_default/textures/leaves_opaque.png index 2a5ff712..1edde62d 100644 Binary files a/subgames/zeus/mods/zeus_default/textures/leaves_opaque.png and b/subgames/zeus/mods/zeus_default/textures/leaves_opaque.png differ diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/acacia_bush_stem.png b/subgames/zeus/mods/zeus_default/textures_unused/acacia_bush_stem.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/acacia_bush_stem.png rename to subgames/zeus/mods/zeus_default/textures_unused/acacia_bush_stem.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/acacia_leaves.png b/subgames/zeus/mods/zeus_default/textures_unused/acacia_leaves.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/acacia_leaves.png rename to subgames/zeus/mods/zeus_default/textures_unused/acacia_leaves.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/acacia_leaves_opaque.png b/subgames/zeus/mods/zeus_default/textures_unused/acacia_leaves_opaque.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/acacia_leaves_opaque.png rename to subgames/zeus/mods/zeus_default/textures_unused/acacia_leaves_opaque.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/acacia_log_side.png b/subgames/zeus/mods/zeus_default/textures_unused/acacia_log_side.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/acacia_log_side.png rename to subgames/zeus/mods/zeus_default/textures_unused/acacia_log_side.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/acacia_log_top.png b/subgames/zeus/mods/zeus_default/textures_unused/acacia_log_top.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/acacia_log_top.png rename to subgames/zeus/mods/zeus_default/textures_unused/acacia_log_top.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/acacia_planks.png b/subgames/zeus/mods/zeus_default/textures_unused/acacia_planks.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/acacia_planks.png rename to subgames/zeus/mods/zeus_default/textures_unused/acacia_planks.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/aspen_leaves.png b/subgames/zeus/mods/zeus_default/textures_unused/aspen_leaves.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/aspen_leaves.png rename to subgames/zeus/mods/zeus_default/textures_unused/aspen_leaves.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/aspen_log_side.png b/subgames/zeus/mods/zeus_default/textures_unused/aspen_log_side.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/aspen_log_side.png rename to subgames/zeus/mods/zeus_default/textures_unused/aspen_log_side.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/aspen_log_top.png b/subgames/zeus/mods/zeus_default/textures_unused/aspen_log_top.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/aspen_log_top.png rename to subgames/zeus/mods/zeus_default/textures_unused/aspen_log_top.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/aspen_planks.png b/subgames/zeus/mods/zeus_default/textures_unused/aspen_planks.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/aspen_planks.png rename to subgames/zeus/mods/zeus_default/textures_unused/aspen_planks.png diff --git a/subgames/zeus/mods/zeus_default/textures/brick.png b/subgames/zeus/mods/zeus_default/textures_unused/brick.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/brick.png rename to subgames/zeus/mods/zeus_default/textures_unused/brick.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/cobblestone.png b/subgames/zeus/mods/zeus_default/textures_unused/cobblestone.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/cobblestone.png rename to subgames/zeus/mods/zeus_default/textures_unused/cobblestone.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/copper_block.png b/subgames/zeus/mods/zeus_default/textures_unused/copper_block.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/copper_block.png rename to subgames/zeus/mods/zeus_default/textures_unused/copper_block.png diff --git a/subgames/zeus/mods/zeus_default/textures/crack/crack_0.png b/subgames/zeus/mods/zeus_default/textures_unused/crack/crack_0.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/crack/crack_0.png rename to subgames/zeus/mods/zeus_default/textures_unused/crack/crack_0.png diff --git a/subgames/zeus/mods/zeus_default/textures/crack/crack_1.png b/subgames/zeus/mods/zeus_default/textures_unused/crack/crack_1.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/crack/crack_1.png rename to subgames/zeus/mods/zeus_default/textures_unused/crack/crack_1.png diff --git a/subgames/zeus/mods/zeus_default/textures/crack/crack_2.png b/subgames/zeus/mods/zeus_default/textures_unused/crack/crack_2.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/crack/crack_2.png rename to subgames/zeus/mods/zeus_default/textures_unused/crack/crack_2.png diff --git a/subgames/zeus/mods/zeus_default/textures/crack/crack_3.png b/subgames/zeus/mods/zeus_default/textures_unused/crack/crack_3.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/crack/crack_3.png rename to subgames/zeus/mods/zeus_default/textures_unused/crack/crack_3.png diff --git a/subgames/zeus/mods/zeus_default/textures/crack/crack_4.png b/subgames/zeus/mods/zeus_default/textures_unused/crack/crack_4.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/crack/crack_4.png rename to subgames/zeus/mods/zeus_default/textures_unused/crack/crack_4.png diff --git a/subgames/zeus/mods/zeus_default/textures/crack/crack_5.png b/subgames/zeus/mods/zeus_default/textures_unused/crack/crack_5.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/crack/crack_5.png rename to subgames/zeus/mods/zeus_default/textures_unused/crack/crack_5.png diff --git a/subgames/zeus/mods/zeus_default/textures/crack/crack_6.png b/subgames/zeus/mods/zeus_default/textures_unused/crack/crack_6.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/crack/crack_6.png rename to subgames/zeus/mods/zeus_default/textures_unused/crack/crack_6.png diff --git a/subgames/zeus/mods/zeus_default/textures/crack/crack_7.png b/subgames/zeus/mods/zeus_default/textures_unused/crack/crack_7.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/crack/crack_7.png rename to subgames/zeus/mods/zeus_default/textures_unused/crack/crack_7.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/desert_cobblestone.png b/subgames/zeus/mods/zeus_default/textures_unused/desert_cobblestone.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/desert_cobblestone.png rename to subgames/zeus/mods/zeus_default/textures_unused/desert_cobblestone.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/desert_sand.png b/subgames/zeus/mods/zeus_default/textures_unused/desert_sand.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/desert_sand.png rename to subgames/zeus/mods/zeus_default/textures_unused/desert_sand.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/desert_stone.png b/subgames/zeus/mods/zeus_default/textures_unused/desert_stone.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/desert_stone.png rename to subgames/zeus/mods/zeus_default/textures_unused/desert_stone.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/desert_stone_blcok.png b/subgames/zeus/mods/zeus_default/textures_unused/desert_stone_blcok.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/desert_stone_blcok.png rename to subgames/zeus/mods/zeus_default/textures_unused/desert_stone_blcok.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/desert_stone_brick.png b/subgames/zeus/mods/zeus_default/textures_unused/desert_stone_brick.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/desert_stone_brick.png rename to subgames/zeus/mods/zeus_default/textures_unused/desert_stone_brick.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/glass.png b/subgames/zeus/mods/zeus_default/textures_unused/glass.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/glass.png rename to subgames/zeus/mods/zeus_default/textures_unused/glass.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/gold_block.png b/subgames/zeus/mods/zeus_default/textures_unused/gold_block.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/gold_block.png rename to subgames/zeus/mods/zeus_default/textures_unused/gold_block.png diff --git a/subgames/zeus/mods/zeus_default/textures_unused/grass_side_ld.png b/subgames/zeus/mods/zeus_default/textures_unused/grass_side_ld.png new file mode 100644 index 00000000..a0857a12 Binary files /dev/null and b/subgames/zeus/mods/zeus_default/textures_unused/grass_side_ld.png differ diff --git a/subgames/zeus/mods/zeus_default/textures/grass_side_ld_mask.png b/subgames/zeus/mods/zeus_default/textures_unused/grass_side_ld_mask.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/grass_side_ld_mask.png rename to subgames/zeus/mods/zeus_default/textures_unused/grass_side_ld_mask.png diff --git a/subgames/zeus/mods/zeus_default/textures/grass_side_under.png b/subgames/zeus/mods/zeus_default/textures_unused/grass_side_under.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/grass_side_under.png rename to subgames/zeus/mods/zeus_default/textures_unused/grass_side_under.png diff --git a/subgames/zeus/mods/zeus_default/textures/grass_side_under_mask.png b/subgames/zeus/mods/zeus_default/textures_unused/grass_side_under_mask.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/grass_side_under_mask.png rename to subgames/zeus/mods/zeus_default/textures_unused/grass_side_under_mask.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/gravel.png b/subgames/zeus/mods/zeus_default/textures_unused/gravel.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/gravel.png rename to subgames/zeus/mods/zeus_default/textures_unused/gravel.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/jungle_grass.png b/subgames/zeus/mods/zeus_default/textures_unused/jungle_grass.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/jungle_grass.png rename to subgames/zeus/mods/zeus_default/textures_unused/jungle_grass.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/jungle_leaves.png b/subgames/zeus/mods/zeus_default/textures_unused/jungle_leaves.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/jungle_leaves.png rename to subgames/zeus/mods/zeus_default/textures_unused/jungle_leaves.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/jungle_leaves_opaque.png b/subgames/zeus/mods/zeus_default/textures_unused/jungle_leaves_opaque.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/jungle_leaves_opaque.png rename to subgames/zeus/mods/zeus_default/textures_unused/jungle_leaves_opaque.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/jungle_planks.png b/subgames/zeus/mods/zeus_default/textures_unused/jungle_planks.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/jungle_planks.png rename to subgames/zeus/mods/zeus_default/textures_unused/jungle_planks.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/jungle_tree_side.png b/subgames/zeus/mods/zeus_default/textures_unused/jungle_tree_side.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/jungle_tree_side.png rename to subgames/zeus/mods/zeus_default/textures_unused/jungle_tree_side.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/jungle_tree_top.png b/subgames/zeus/mods/zeus_default/textures_unused/jungle_tree_top.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/jungle_tree_top.png rename to subgames/zeus/mods/zeus_default/textures_unused/jungle_tree_top.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/mossy_cobblestone.png b/subgames/zeus/mods/zeus_default/textures_unused/mossy_cobblestone.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/mossy_cobblestone.png rename to subgames/zeus/mods/zeus_default/textures_unused/mossy_cobblestone.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/oak_leaves_opaque.png b/subgames/zeus/mods/zeus_default/textures_unused/oak_leaves_opaque.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/oak_leaves_opaque.png rename to subgames/zeus/mods/zeus_default/textures_unused/oak_leaves_opaque.png diff --git a/subgames/zeus/mods/zeus_default/textures/painting/16x_d1.png b/subgames/zeus/mods/zeus_default/textures_unused/painting/16x_d1.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/painting/16x_d1.png rename to subgames/zeus/mods/zeus_default/textures_unused/painting/16x_d1.png diff --git a/subgames/zeus/mods/zeus_default/textures/painting/16x_d2.png b/subgames/zeus/mods/zeus_default/textures_unused/painting/16x_d2.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/painting/16x_d2.png rename to subgames/zeus/mods/zeus_default/textures_unused/painting/16x_d2.png diff --git a/subgames/zeus/mods/zeus_default/textures/painting/32x16_d1.png b/subgames/zeus/mods/zeus_default/textures_unused/painting/32x16_d1.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/painting/32x16_d1.png rename to subgames/zeus/mods/zeus_default/textures_unused/painting/32x16_d1.png diff --git a/subgames/zeus/mods/zeus_default/textures/painting/32x_d1.png b/subgames/zeus/mods/zeus_default/textures_unused/painting/32x_d1.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/painting/32x_d1.png rename to subgames/zeus/mods/zeus_default/textures_unused/painting/32x_d1.png diff --git a/subgames/zeus/mods/zeus_default/textures/painting/32x_d2.png b/subgames/zeus/mods/zeus_default/textures_unused/painting/32x_d2.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/painting/32x_d2.png rename to subgames/zeus/mods/zeus_default/textures_unused/painting/32x_d2.png diff --git a/subgames/zeus/mods/zeus_default/textures/painting/32x_d3.png b/subgames/zeus/mods/zeus_default/textures_unused/painting/32x_d3.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/painting/32x_d3.png rename to subgames/zeus/mods/zeus_default/textures_unused/painting/32x_d3.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/pine_leaves.png b/subgames/zeus/mods/zeus_default/textures_unused/pine_leaves.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/pine_leaves.png rename to subgames/zeus/mods/zeus_default/textures_unused/pine_leaves.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/pine_leaves_opaque.png b/subgames/zeus/mods/zeus_default/textures_unused/pine_leaves_opaque.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/pine_leaves_opaque.png rename to subgames/zeus/mods/zeus_default/textures_unused/pine_leaves_opaque.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/pine_leaves_puff.png b/subgames/zeus/mods/zeus_default/textures_unused/pine_leaves_puff.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/pine_leaves_puff.png rename to subgames/zeus/mods/zeus_default/textures_unused/pine_leaves_puff.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/pine_log_top.png b/subgames/zeus/mods/zeus_default/textures_unused/pine_log_top.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/pine_log_top.png rename to subgames/zeus/mods/zeus_default/textures_unused/pine_log_top.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/pine_planks.png b/subgames/zeus/mods/zeus_default/textures_unused/pine_planks.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/pine_planks.png rename to subgames/zeus/mods/zeus_default/textures_unused/pine_planks.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/ping_log_side.png b/subgames/zeus/mods/zeus_default/textures_unused/ping_log_side.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/ping_log_side.png rename to subgames/zeus/mods/zeus_default/textures_unused/ping_log_side.png diff --git a/subgames/zeus/mods/zeus_default/textures/podzol.png b/subgames/zeus/mods/zeus_default/textures_unused/podzol.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/podzol.png rename to subgames/zeus/mods/zeus_default/textures_unused/podzol.png diff --git a/subgames/zeus/mods/zeus_default/textures/podzol_side.png b/subgames/zeus/mods/zeus_default/textures_unused/podzol_side.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/podzol_side.png rename to subgames/zeus/mods/zeus_default/textures_unused/podzol_side.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/snow.png b/subgames/zeus/mods/zeus_default/textures_unused/snow.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/snow.png rename to subgames/zeus/mods/zeus_default/textures_unused/snow.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/snow_side.png b/subgames/zeus/mods/zeus_default/textures_unused/snow_side.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/snow_side.png rename to subgames/zeus/mods/zeus_default/textures_unused/snow_side.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/stone_block.png b/subgames/zeus/mods/zeus_default/textures_unused/stone_block.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/stone_block.png rename to subgames/zeus/mods/zeus_default/textures_unused/stone_block.png diff --git a/subgames/zeus/mods/zeus_default/textures/unimplemented/stone_bricks.png b/subgames/zeus/mods/zeus_default/textures_unused/stone_bricks.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/unimplemented/stone_bricks.png rename to subgames/zeus/mods/zeus_default/textures_unused/stone_bricks.png diff --git a/subgames/zeus/mods/zeus_default/textures/workbench.png b/subgames/zeus/mods/zeus_default/textures_unused/workbench.png similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/workbench.png rename to subgames/zeus/mods/zeus_default/textures_unused/workbench.png diff --git a/subgames/zeus/mods/zeus_default/textures/workbench.xcf b/subgames/zeus/mods/zeus_default/textures_unused/workbench.xcf similarity index 100% rename from subgames/zeus/mods/zeus_default/textures/workbench.xcf rename to subgames/zeus/mods/zeus_default/textures_unused/workbench.xcf diff --git a/subgames/zeus/mods/zeus_inventory/textures/chest.png b/subgames/zeus/mods/zeus_inventory/textures/chest.png deleted file mode 100644 index eafb7550..00000000 Binary files a/subgames/zeus/mods/zeus_inventory/textures/chest.png and /dev/null differ diff --git a/subgames/zeus/mods/zeus_inventory/textures/container.png b/subgames/zeus/mods/zeus_inventory/textures/container.png deleted file mode 100644 index c377b9fb..00000000 Binary files a/subgames/zeus/mods/zeus_inventory/textures/container.png and /dev/null differ diff --git a/subgames/zeus/mods/zeus_inventory/textures/crafting.png b/subgames/zeus/mods/zeus_inventory/textures/crafting.png deleted file mode 100644 index 7033d4cc..00000000 Binary files a/subgames/zeus/mods/zeus_inventory/textures/crafting.png and /dev/null differ diff --git a/subgames/zeus/mods/zeus_inventory/textures/inventory_new.png b/subgames/zeus/mods/zeus_inventory/textures/inventory_new.png deleted file mode 100644 index c12b4946..00000000 Binary files a/subgames/zeus/mods/zeus_inventory/textures/inventory_new.png and /dev/null differ diff --git a/subgames/zeus/mods/zeus_inventory/textures/inventory_new_alt.png b/subgames/zeus/mods/zeus_inventory/textures/inventory_new_alt.png deleted file mode 100644 index 4bf0b55b..00000000 Binary files a/subgames/zeus/mods/zeus_inventory/textures/inventory_new_alt.png and /dev/null differ diff --git a/subgames/zeus/mods/zeus_inventory/textures/minecraft_inventory.png b/subgames/zeus/mods/zeus_inventory/textures/minecraft_inventory.png deleted file mode 100644 index bb44d409..00000000 Binary files a/subgames/zeus/mods/zeus_inventory/textures/minecraft_inventory.png and /dev/null differ diff --git a/subgames/zeus/mods/zeus_inventory/textures/minecraft_inventory_grid.png b/subgames/zeus/mods/zeus_inventory/textures/minecraft_inventory_grid.png deleted file mode 100644 index b9f8445c..00000000 Binary files a/subgames/zeus/mods/zeus_inventory/textures/minecraft_inventory_grid.png and /dev/null differ diff --git a/subgames/zeus/mods/zeus_inventory/textures/background.xcf b/subgames/zeus/mods/zeus_inventory/textures/xcf/background.xcf similarity index 100% rename from subgames/zeus/mods/zeus_inventory/textures/background.xcf rename to subgames/zeus/mods/zeus_inventory/textures/xcf/background.xcf diff --git a/subgames/zeus/mods/zeus_inventory/textures/chest.xcf b/subgames/zeus/mods/zeus_inventory/textures/xcf/chest.xcf similarity index 100% rename from subgames/zeus/mods/zeus_inventory/textures/chest.xcf rename to subgames/zeus/mods/zeus_inventory/textures/xcf/chest.xcf diff --git a/subgames/zeus/mods/zeus_inventory/textures/container.xcf b/subgames/zeus/mods/zeus_inventory/textures/xcf/container.xcf similarity index 100% rename from subgames/zeus/mods/zeus_inventory/textures/container.xcf rename to subgames/zeus/mods/zeus_inventory/textures/xcf/container.xcf diff --git a/subgames/zeus/mods/zeus_inventory/textures/crafting.xcf b/subgames/zeus/mods/zeus_inventory/textures/xcf/crafting.xcf similarity index 100% rename from subgames/zeus/mods/zeus_inventory/textures/crafting.xcf rename to subgames/zeus/mods/zeus_inventory/textures/xcf/crafting.xcf diff --git a/subgames/zeus/mods/zeus_inventory/textures/inventory_new.xcf b/subgames/zeus/mods/zeus_inventory/textures/xcf/inventory_new.xcf similarity index 100% rename from subgames/zeus/mods/zeus_inventory/textures/inventory_new.xcf rename to subgames/zeus/mods/zeus_inventory/textures/xcf/inventory_new.xcf diff --git a/subgames/zeus/mods/zeus_inventory/textures/inventory_new_alt.xcf b/subgames/zeus/mods/zeus_inventory/textures/xcf/inventory_new_alt.xcf similarity index 100% rename from subgames/zeus/mods/zeus_inventory/textures/inventory_new_alt.xcf rename to subgames/zeus/mods/zeus_inventory/textures/xcf/inventory_new_alt.xcf diff --git a/subgames/zeus/mods/zeus_inventory/textures/minecraft_inventory.xcf b/subgames/zeus/mods/zeus_inventory/textures/xcf/minecraft_inventory.xcf similarity index 100% rename from subgames/zeus/mods/zeus_inventory/textures/minecraft_inventory.xcf rename to subgames/zeus/mods/zeus_inventory/textures/xcf/minecraft_inventory.xcf diff --git a/subgames/zeus/mods/zeus_materials/textures/flint_outlined.png b/subgames/zeus/mods/zeus_materials/textures_unused/flint_outlined.png similarity index 100% rename from subgames/zeus/mods/zeus_materials/textures/flint_outlined.png rename to subgames/zeus/mods/zeus_materials/textures_unused/flint_outlined.png diff --git a/subgames/zeus/mods/zeus_materials/textures/plant_fibre_outlined.png b/subgames/zeus/mods/zeus_materials/textures_unused/plant_fibre_outlined.png similarity index 100% rename from subgames/zeus/mods/zeus_materials/textures/plant_fibre_outlined.png rename to subgames/zeus/mods/zeus_materials/textures_unused/plant_fibre_outlined.png diff --git a/subgames/zeus/mods/zeus_materials/textures/plant_twine_outlined.png b/subgames/zeus/mods/zeus_materials/textures_unused/plant_twine_outlined.png similarity index 100% rename from subgames/zeus/mods/zeus_materials/textures/plant_twine_outlined.png rename to subgames/zeus/mods/zeus_materials/textures_unused/plant_twine_outlined.png diff --git a/subgames/zeus/mods/zeus_materials/textures/rock_outlined.png b/subgames/zeus/mods/zeus_materials/textures_unused/rock_outlined.png similarity index 100% rename from subgames/zeus/mods/zeus_materials/textures/rock_outlined.png rename to subgames/zeus/mods/zeus_materials/textures_unused/rock_outlined.png diff --git a/subgames/zeus/mods/zeus_materials/textures/stick_0.png b/subgames/zeus/mods/zeus_materials/textures_unused/stick_0.png similarity index 100% rename from subgames/zeus/mods/zeus_materials/textures/stick_0.png rename to subgames/zeus/mods/zeus_materials/textures_unused/stick_0.png diff --git a/subgames/zeus/mods/zeus_materials/textures/stick_1.png b/subgames/zeus/mods/zeus_materials/textures_unused/stick_1.png similarity index 100% rename from subgames/zeus/mods/zeus_materials/textures/stick_1.png rename to subgames/zeus/mods/zeus_materials/textures_unused/stick_1.png diff --git a/subgames/zeus/mods/zeus_materials/textures/stick_2.png b/subgames/zeus/mods/zeus_materials/textures_unused/stick_2.png similarity index 100% rename from subgames/zeus/mods/zeus_materials/textures/stick_2.png rename to subgames/zeus/mods/zeus_materials/textures_unused/stick_2.png diff --git a/subgames/zeus/mods/zeus_materials/textures/stick_3.png b/subgames/zeus/mods/zeus_materials/textures_unused/stick_3.png similarity index 100% rename from subgames/zeus/mods/zeus_materials/textures/stick_3.png rename to subgames/zeus/mods/zeus_materials/textures_unused/stick_3.png diff --git a/subgames/zeus/mods/zeus_materials/textures/stick_outlined.png b/subgames/zeus/mods/zeus_materials/textures_unused/stick_outlined.png similarity index 100% rename from subgames/zeus/mods/zeus_materials/textures/stick_outlined.png rename to subgames/zeus/mods/zeus_materials/textures_unused/stick_outlined.png diff --git a/subgames/zeus/mods/zeus_vegetation/script/main.lua b/subgames/zeus/mods/zeus_vegetation/script/main.lua index 6e7eae8e..05d3679a 100644 --- a/subgames/zeus/mods/zeus_vegetation/script/main.lua +++ b/subgames/zeus/mods/zeus_vegetation/script/main.lua @@ -42,8 +42,8 @@ register_vegetation('mushroom_brown', { name = 'Brown Mushroom', model = 'zepha: register_vegetation('clover', { model = 'zeus:vegetation:clover', textures = { - 'tint(0, crop(0, 0, 16, 16, zeus:vegetation:clover))', - 'tint(0, crop(16, 0, 16, 16, zeus:vegetation:clover))' + '(canvas(16),tint(0, crop(0, 0, 16, 16, zeus:vegetation:clover)))', + '(canvas(16),tint(0, crop(16, 0, 16, 16, zeus:vegetation:clover)))' }, selection_box = { { 1/16, 0, 1/16, 15/16, 4/16, 15/16 } diff --git a/subgames/zeus/mods/zeus_world/script/biomes/plains.lua b/subgames/zeus/mods/zeus_world/script/biomes/plains.lua index 5442ceba..89c9035f 100644 --- a/subgames/zeus/mods/zeus_world/script/biomes/plains.lua +++ b/subgames/zeus/mods/zeus_world/script/biomes/plains.lua @@ -148,33 +148,42 @@ table.insert(structures, zepha.create_structure({ })) local noise = { --- heightmap = { --- module = "add", --- sources = { --- require('./world_noise'), --- { --- module = "max", --- smoothness = 50, --- scalar = 0, --- source = { --- module = "add", --- scalar = -50, --- source = { --- module = "multiply", --- scalar = 400, --- source = { --- module = "simplex", --- frequency = 0.00025, --- lacunarity = 2.5, --- octaves = 8, --- persistence = 0.55 --- } --- } --- } --- } --- } --- } - volume = require './world_noise' + heightmap = { + module = "add", + sources = { + { + module = "multiply", + scalar = 100, + source = { + module = "simplex", + frequency = 0.0002, + octaves = 5, + lacunarity = 3, + persistence = 0.45 + } + }, { + module = "max", + smoothness = 50, + scalar = 0, + source = { + module = "add", + scalar = -50, + source = { + module = "multiply", + scalar = 400, + source = { + module = "simplex", + frequency = 0.00025, + lacunarity = 2.5, + octaves = 8, + persistence = 0.55 + } + } + } + } + } + } +-- volume = require './world_noise' -- volume = { -- module = "scale", -- y_scale = 2, diff --git a/untitled.lua b/untitled.lua new file mode 100644 index 00000000..8de9e7ca --- /dev/null +++ b/untitled.lua @@ -0,0 +1,6 @@ +function zepha.reconcile_available(old_block, old_meta, block, meta) + local meta_def = (zepha.registered_blocks[block] or {}).meta or {} + for k, v in pairs(old_meta) do + if meta_def[k] == type(v) then meta[k] = v end + end +end