diff options
Diffstat (limited to 'src/client/meshgen')
-rw-r--r-- | src/client/meshgen/collector.cpp | 104 | ||||
-rw-r--r-- | src/client/meshgen/collector.h | 65 |
2 files changed, 169 insertions, 0 deletions
diff --git a/src/client/meshgen/collector.cpp b/src/client/meshgen/collector.cpp new file mode 100644 index 000000000..c317a0772 --- /dev/null +++ b/src/client/meshgen/collector.cpp @@ -0,0 +1,104 @@ +/* +Minetest +Copyright (C) 2018 numzero, Lobachevskiy Vitaliy <numzer0@yandex.ru> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "collector.h" +#include <stdexcept> +#include "log.h" +#include "mesh.h" + +void MeshCollector::append(const TileSpec &tile, const video::S3DVertex *vertices, + u32 numVertices, const u16 *indices, u32 numIndices) +{ + for (int layernum = 0; layernum < MAX_TILE_LAYERS; layernum++) { + const TileLayer *layer = &tile.layers[layernum]; + if (layer->texture_id == 0) + continue; + append(*layer, vertices, numVertices, indices, numIndices, layernum, + tile.world_aligned); + } +} + +void MeshCollector::append(const TileLayer &layer, const video::S3DVertex *vertices, + u32 numVertices, const u16 *indices, u32 numIndices, u8 layernum, + bool use_scale) +{ + PreMeshBuffer &p = findBuffer(layer, layernum, numVertices); + + f32 scale = 1.0f; + if (use_scale) + scale = 1.0f / layer.scale; + + u32 vertex_count = p.vertices.size(); + for (u32 i = 0; i < numVertices; i++) + p.vertices.emplace_back(vertices[i].Pos, vertices[i].Normal, + vertices[i].Color, scale * vertices[i].TCoords); + + for (u32 i = 0; i < numIndices; i++) + p.indices.push_back(indices[i] + vertex_count); +} + +void MeshCollector::append(const TileSpec &tile, const video::S3DVertex *vertices, + u32 numVertices, const u16 *indices, u32 numIndices, v3f pos, + video::SColor c, u8 light_source) +{ + for (int layernum = 0; layernum < MAX_TILE_LAYERS; layernum++) { + const TileLayer *layer = &tile.layers[layernum]; + if (layer->texture_id == 0) + continue; + append(*layer, vertices, numVertices, indices, numIndices, pos, c, + light_source, layernum, tile.world_aligned); + } +} + +void MeshCollector::append(const TileLayer &layer, const video::S3DVertex *vertices, + u32 numVertices, const u16 *indices, u32 numIndices, v3f pos, + video::SColor c, u8 light_source, u8 layernum, bool use_scale) +{ + PreMeshBuffer &p = findBuffer(layer, layernum, numVertices); + + f32 scale = 1.0f; + if (use_scale) + scale = 1.0f / layer.scale; + + u32 vertex_count = p.vertices.size(); + for (u32 i = 0; i < numVertices; i++) { + video::SColor color = c; + if (!light_source) + applyFacesShading(color, vertices[i].Normal); + p.vertices.emplace_back(vertices[i].Pos + pos, vertices[i].Normal, color, + scale * vertices[i].TCoords); + } + + for (u32 i = 0; i < numIndices; i++) + p.indices.push_back(indices[i] + vertex_count); +} + +PreMeshBuffer &MeshCollector::findBuffer( + const TileLayer &layer, u8 layernum, u32 numVertices) +{ + if (numVertices > U16_MAX) + throw std::invalid_argument( + "Mesh can't contain more than 65536 vertices"); + std::vector<PreMeshBuffer> &buffers = prebuffers[layernum]; + for (PreMeshBuffer &p : buffers) + if (p.layer == layer && p.vertices.size() + numVertices <= U16_MAX) + return p; + buffers.emplace_back(layer); + return buffers.back(); +} diff --git a/src/client/meshgen/collector.h b/src/client/meshgen/collector.h new file mode 100644 index 000000000..e4189088e --- /dev/null +++ b/src/client/meshgen/collector.h @@ -0,0 +1,65 @@ +/* +Minetest +Copyright (C) 2018 numzero, Lobachevskiy Vitaliy <numzer0@yandex.ru> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once +#include <array> +#include <vector> +#include "irrlichttypes.h" +#include <S3DVertex.h> +#include "client/tile.h" + +struct PreMeshBuffer +{ + TileLayer layer; + std::vector<u16> indices; + std::vector<video::S3DVertex> vertices; + + PreMeshBuffer() = default; + explicit PreMeshBuffer(const TileLayer &layer) : layer(layer) {} +}; + +struct MeshCollector +{ + std::array<std::vector<PreMeshBuffer>, MAX_TILE_LAYERS> prebuffers; + + // clang-format off + void append(const TileSpec &material, + const video::S3DVertex *vertices, u32 numVertices, + const u16 *indices, u32 numIndices); + void append(const TileSpec &material, + const video::S3DVertex *vertices, u32 numVertices, + const u16 *indices, u32 numIndices, + v3f pos, video::SColor c, u8 light_source); + // clang-format on + +private: + // clang-format off + void append(const TileLayer &material, + const video::S3DVertex *vertices, u32 numVertices, + const u16 *indices, u32 numIndices, + u8 layernum, bool use_scale = false); + void append(const TileLayer &material, + const video::S3DVertex *vertices, u32 numVertices, + const u16 *indices, u32 numIndices, + v3f pos, video::SColor c, u8 light_source, + u8 layernum, bool use_scale = false); + // clang-format on + + PreMeshBuffer &findBuffer(const TileLayer &layer, u8 layernum, u32 numVertices); +}; |