Merge pull request #350 from MihailRis/block-models-advanced

Improve block custom models
This commit is contained in:
MihailRis 2024-11-05 22:43:36 +03:00 committed by GitHub
commit 1aeaa667c9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
24 changed files with 259 additions and 255 deletions

View File

@ -19,10 +19,10 @@
#include "graphics/core/Atlas.hpp"
#include "graphics/core/Font.hpp"
#include "graphics/core/ImageData.hpp"
#include "graphics/core/Model.hpp"
#include "graphics/core/Shader.hpp"
#include "graphics/core/Texture.hpp"
#include "graphics/core/TextureAnimation.hpp"
#include "graphics/commons/Model.hpp"
#include "objects/rigging.hpp"
#include "util/stringutil.hpp"
#include "Assets.hpp"

View File

@ -1,6 +1,6 @@
#include "obj.hpp"
#include "graphics/core/Model.hpp"
#include "graphics/commons/Model.hpp"
#include "commons.hpp"
using namespace model;

View File

@ -5,7 +5,7 @@
#include "byte_utils.hpp"
#include "util/data_io.hpp"
#include "util/stringutil.hpp"
#include "graphics/core/Model.hpp"
#include "graphics/commons/Model.hpp"
inline constexpr int VERSION = 1;

View File

@ -8,7 +8,7 @@
#include "typedefs.hpp"
#include "util/Buffer.hpp"
#include "graphics/core/Model.hpp"
#include "graphics/commons/Model.hpp"
/// See /doc/specs/vec3_model_spec.md
namespace vec3 {

View File

@ -219,19 +219,26 @@ void ContentLoader::loadBlock(
}
// block model
std::string modelName;
root.at("model").get(modelName);
if (auto model = BlockModel_from(modelName)) {
std::string modelTypeName;
root.at("model").get(modelTypeName);
root.at("model-name").get(def.modelName);
if (auto model = BlockModel_from(modelTypeName)) {
if (*model == BlockModel::custom) {
if (root.has("model-primitives")) {
loadCustomBlockModel(def, root["model-primitives"]);
} else {
logger.error() << name << ": no 'model-primitives' found";
def.customModelRaw = root["model-primitives"];
} else if (def.modelName.empty()) {
throw std::runtime_error(name + ": no 'model-primitives' or 'model-name' found");
}
for (uint i = 0; i < 6; i++) {
std::string& texture = def.textureFaces[i];
if (texture == TEXTURE_NOTFOUND) {
texture = "";
}
}
}
def.model = *model;
} else if (!modelName.empty()) {
logger.error() << "unknown model " << modelName;
} else if (!modelTypeName.empty()) {
logger.error() << "unknown model " << modelTypeName;
def.model = BlockModel::none;
}
@ -277,8 +284,6 @@ void ContentLoader::loadBlock(
);
aabb.b += aabb.a;
def.hitboxes = {aabb};
} else if (!def.modelBoxes.empty()) {
def.hitboxes = def.modelBoxes;
} else {
def.hitboxes = {AABB()};
}
@ -350,61 +355,6 @@ void ContentLoader::loadBlock(
}
}
void ContentLoader::loadCustomBlockModel(Block& def, const dv::value& primitives) {
if (primitives.has("aabbs")) {
const auto& modelboxes = primitives["aabbs"];
for (uint i = 0; i < modelboxes.size(); i++) {
// Parse aabb
const auto& boxarr = modelboxes[i];
AABB modelbox;
modelbox.a = glm::vec3(
boxarr[0].asNumber(), boxarr[1].asNumber(), boxarr[2].asNumber()
);
modelbox.b = glm::vec3(
boxarr[3].asNumber(), boxarr[4].asNumber(), boxarr[5].asNumber()
);
modelbox.b += modelbox.a;
def.modelBoxes.push_back(modelbox);
if (boxarr.size() == 7) {
for (uint j = 6; j < 12; j++) {
def.modelTextures.emplace_back(boxarr[6].asString());
}
} else if (boxarr.size() == 12) {
for (uint j = 6; j < 12; j++) {
def.modelTextures.emplace_back(boxarr[j].asString());
}
} else {
for (uint j = 6; j < 12; j++) {
def.modelTextures.emplace_back("notfound");
}
}
}
}
if (primitives.has("tetragons")) {
const auto& modeltetragons = primitives["tetragons"];
for (uint i = 0; i < modeltetragons.size(); i++) {
// Parse tetragon to points
const auto& tgonobj = modeltetragons[i];
glm::vec3 p1(
tgonobj[0].asNumber(), tgonobj[1].asNumber(), tgonobj[2].asNumber()
);
glm::vec3 xw(
tgonobj[3].asNumber(), tgonobj[4].asNumber(), tgonobj[5].asNumber()
);
glm::vec3 yh(
tgonobj[6].asNumber(), tgonobj[7].asNumber(), tgonobj[8].asNumber()
);
def.modelExtraPoints.push_back(p1);
def.modelExtraPoints.push_back(p1 + xw);
def.modelExtraPoints.push_back(p1 + xw + yh);
def.modelExtraPoints.push_back(p1 + yh);
def.modelTextures.emplace_back(tgonobj[9].asString());
}
}
}
void ContentLoader::loadItem(
ItemDef& def, const std::string& name, const fs::path& file
) {

View File

@ -42,7 +42,6 @@ class ContentLoader {
GeneratorDef& def, const std::string& full, const std::string& name
);
static void loadCustomBlockModel(Block& def, const dv::value& primitives);
static void loadBlockMaterial(BlockMaterial& def, const fs::path& file);
void loadBlock(
Block& def, const std::string& name, const fs::path& file

View File

@ -286,6 +286,21 @@ void Engine::loadAssets() {
assets = std::move(new_assets);
if (content) {
for (auto& [name, def] : content->blocks.getDefs()) {
if (def->model == BlockModel::custom) {
if (def->modelName.empty()) {
assets->store(
std::make_unique<model::Model>(
ModelsGenerator::loadCustomBlockModel(
def->customModelRaw, *assets, !def->shadeless
)
),
name + ".model"
);
def->modelName = def->name + ".model";
}
}
}
for (auto& [name, def] : content->items.getDefs()) {
assets->store(
std::make_unique<model::Model>(

View File

@ -1,7 +1,8 @@
#include "ContentGfxCache.hpp"
#include "UiDocument.hpp"
#include <string>
#include "UiDocument.hpp"
#include "assets/Assets.hpp"
#include "content/Content.hpp"
#include "content/ContentPack.hpp"
@ -10,15 +11,14 @@
#include "maths/UVRegion.hpp"
#include "voxels/Block.hpp"
#include <string>
ContentGfxCache::ContentGfxCache(const Content* content, Assets* assets) : content(content) {
ContentGfxCache::ContentGfxCache(const Content* content, Assets* assets)
: content(content) {
auto indices = content->getIndices();
sideregions = std::make_unique<UVRegion[]>(indices->blocks.count() * 6);
auto atlas = assets->get<Atlas>("blocks");
const auto& blocks = indices->blocks.getIterable();
for (uint i = 0; i < blocks.size(); i++) {
for (blockid_t i = 0; i < blocks.size(); i++) {
auto def = blocks[i];
for (uint side = 0; side < 6; side++) {
const std::string& tex = def->textureFaces[side];
@ -28,13 +28,9 @@ ContentGfxCache::ContentGfxCache(const Content* content, Assets* assets) : conte
sideregions[i * 6 + side] = atlas->get(TEXTURE_NOTFOUND);
}
}
for (uint side = 0; side < def->modelTextures.size(); side++) {
const std::string& tex = def->modelTextures[side];
if (atlas->has(tex)) {
def->modelUVs.push_back(atlas->get(tex));
} else if (atlas->has(TEXTURE_NOTFOUND)) {
def->modelUVs.push_back(atlas->get(TEXTURE_NOTFOUND));
}
if (def->model == BlockModel::custom) {
models[def->rt.id] =
assets->require<model::Model>(def->modelName);
}
}
}
@ -44,3 +40,11 @@ ContentGfxCache::~ContentGfxCache() = default;
const Content* ContentGfxCache::getContent() const {
return content;
}
const model::Model& ContentGfxCache::getModel(blockid_t id) const {
const auto& found = models.find(id);
if (found == models.end()) {
throw std::runtime_error("model not found");
}
return found->second;
}

View File

@ -3,15 +3,24 @@
#include "typedefs.hpp"
#include <memory>
#include <stdexcept>
#include <unordered_map>
#include "graphics/commons/Model.hpp"
class Content;
class Assets;
struct UVRegion;
namespace model {
struct Model;
}
class ContentGfxCache {
const Content* content;
// array of block sides uv regions (6 per block)
std::unique_ptr<UVRegion[]> sideregions;
std::unordered_map<blockid_t, model::Model> models;
public:
ContentGfxCache(const Content* content, Assets* assets);
~ContentGfxCache();
@ -19,6 +28,8 @@ public:
inline const UVRegion& getRegion(blockid_t id, int side) const {
return sideregions[id * 6 + side];
}
const model::Model& getModel(blockid_t id) const;
const Content* getContent() const;
};

View File

@ -36,7 +36,7 @@ void Mesh::addPlane(
vertices.push_back({pos-right-up, {uv.u1, uv.v1}, norm});
vertices.push_back({pos+right+up, {uv.u2, uv.v2}, norm});
vertices.push_back({pos-right+up, {uv.u1, uv.u2}, norm});
vertices.push_back({pos-right+up, {uv.u1, uv.v2}, norm});
}
void Mesh::addBox(const glm::vec3& pos, const glm::vec3& size) {

View File

@ -60,47 +60,24 @@ std::unique_ptr<ImageData> BlocksPreview::draw(
}
batch->flush();
break;
case BlockModel::custom:
{
glm::vec3 pmul = glm::vec3(size * 0.63f);
glm::vec3 hitbox = glm::vec3();
for (const auto& box : def.modelBoxes) {
hitbox = glm::max(hitbox, box.size());
}
offset.y += (1.0f - hitbox).y * 0.5f;
shader->uniformMatrix("u_apply", glm::translate(glm::mat4(1.0f), offset));
for (size_t i = 0; i < def.modelBoxes.size(); i++) {
const UVRegion (&boxtexfaces)[6] = {
def.modelUVs[i * 6],
def.modelUVs[i * 6 + 1],
def.modelUVs[i * 6 + 2],
def.modelUVs[i * 6 + 3],
def.modelUVs[i * 6 + 4],
def.modelUVs[i * 6 + 5]
};
batch->cube(
def.modelBoxes[i].a * glm::vec3(1.0f, 1.0f, -1.0f) * pmul,
def.modelBoxes[i].size() * pmul,
boxtexfaces, glm::vec4(1.0f), !def.rt.emissive
);
}
auto& points = def.modelExtraPoints;
glm::vec3 poff = glm::vec3(0.0f, 0.0f, 1.0f);
for (size_t i = 0; i < def.modelExtraPoints.size() / 4; i++) {
const UVRegion& reg = def.modelUVs[def.modelBoxes.size() * 6 + i];
batch->vertex((points[i * 4 + 0] - poff) * pmul, glm::vec2(reg.u1, reg.v1), glm::vec4(1.0));
batch->vertex((points[i * 4 + 1] - poff) * pmul, glm::vec2(reg.u2, reg.v1), glm::vec4(1.0));
batch->vertex((points[i * 4 + 2] - poff) * pmul, glm::vec2(reg.u2, reg.v2), glm::vec4(1.0));
batch->vertex((points[i * 4 + 0] - poff) * pmul, glm::vec2(reg.u1, reg.v1), glm::vec4(1.0));
batch->vertex((points[i * 4 + 2] - poff) * pmul, glm::vec2(reg.u2, reg.v2), glm::vec4(1.0));
batch->vertex((points[i * 4 + 3] - poff) * pmul, glm::vec2(reg.u1, reg.v2), glm::vec4(1.0));
case BlockModel::custom:{
glm::vec3 pmul = glm::vec3(size * 0.63f);
glm::vec3 hitbox = glm::vec3(1.0f);
glm::vec3 poff = glm::vec3(0.0f, 0.0f, 1.0f);
offset.y += (1.0f - hitbox).y * 0.5f;
shader->uniformMatrix("u_apply", glm::translate(glm::mat4(1.0f), offset));
const auto& model = cache->getModel(def.rt.id);
for (const auto& mesh : model.meshes) {
for (const auto& vertex : mesh.vertices) {
float d = glm::dot(glm::normalize(vertex.normal), glm::vec3(0.2, 0.8, 0.4));
d = 0.8f + d * 0.2f;
batch->vertex((vertex.coord - poff)*pmul, vertex.uv, glm::vec4(d, d, d, 1.0f));
}
batch->flush();
}
break;
}
case BlockModel::xsprite: {
shader->uniformMatrix("u_apply", glm::translate(glm::mat4(1.0f), offset));
glm::vec3 right = glm::normalize(glm::vec3(1.f, 0.f, -1.f));

View File

@ -1,6 +1,7 @@
#include "BlocksRenderer.hpp"
#include "graphics/core/Mesh.hpp"
#include "graphics/commons/Model.hpp"
#include "maths/UVRegion.hpp"
#include "constants.hpp"
#include "content/Content.hpp"
@ -180,40 +181,6 @@ void BlocksRenderer::face(
index(0, 1, 2, 0, 2, 3);
}
void BlocksRenderer::tetragonicFace(
const glm::vec3& coord,
const glm::vec3& p1, const glm::vec3& p2,
const glm::vec3& p3, const glm::vec3& p4,
const glm::vec3& X, const glm::vec3& Y, const glm::vec3& Z,
const UVRegion& texreg,
bool lights
) {
const auto fp1 = (p1.x - 0.5f) * X + (p1.y - 0.5f) * Y + (p1.z - 0.5f) * Z;
const auto fp2 = (p2.x - 0.5f) * X + (p2.y - 0.5f) * Y + (p2.z - 0.5f) * Z;
const auto fp3 = (p3.x - 0.5f) * X + (p3.y - 0.5f) * Y + (p3.z - 0.5f) * Z;
const auto fp4 = (p4.x - 0.5f) * X + (p4.y - 0.5f) * Y + (p4.z - 0.5f) * Z;
glm::vec4 tint(1.0f);
if (lights) {
auto dir = glm::cross(fp2 - fp1, fp3 - fp1);
auto normal = glm::normalize(dir);
float d = glm::dot(normal, SUN_VECTOR);
d = 0.8f + d * 0.2f;
tint *= d;
tint *= pickLight(coord);
// debug normal
// tint.x = normal.x * 0.5f + 0.5f;
// tint.y = normal.y * 0.5f + 0.5f;
// tint.z = normal.z * 0.5f + 0.5f;
}
vertex(coord + fp1, texreg.u1, texreg.v1, tint);
vertex(coord + fp2, texreg.u2, texreg.v1, tint);
vertex(coord + fp3, texreg.u2, texreg.v2, tint);
vertex(coord + fp4, texreg.u1, texreg.v2, tint);
index(0, 1, 3, 1, 2, 3);
}
void BlocksRenderer::blockXSprite(
int x, int y, int z,
const glm::vec3& size,
@ -319,29 +286,30 @@ void BlocksRenderer::blockCustomModel(
Z = orient.axisZ;
}
for (size_t i = 0; i < block->modelBoxes.size(); i++) {
AABB box = block->modelBoxes[i];
auto size = box.size();
if (block->rotatable) {
orient.transform(box);
const auto& model = cache->getModel(block->rt.id);
for (const auto& mesh : model.meshes) {
if (vertexOffset + BlocksRenderer::VERTEX_SIZE * mesh.vertices.size() > capacity) {
overflow = true;
return;
}
int i = 0;
for (const auto& vertex : mesh.vertices) {
auto n =
vertex.normal.x * X + vertex.normal.y * Y + vertex.normal.z * Z;
float d = glm::dot(glm::normalize(n), SUN_VECTOR);
d = 0.8f + d * 0.2f;
const auto& vcoord = vertex.coord - 0.5f;
vertexAO(
coord + vcoord.x * X + vcoord.y * Y + vcoord.z * Z,
vertex.uv.x,
vertex.uv.y,
glm::vec4(1, 1, 1, 1),
glm::vec3(1, 0, 0),
glm::vec3(0, 1, 0),
n
);
indexBuffer[indexSize++] = indexOffset++;
}
glm::vec3 center_coord = coord - glm::vec3(0.5f) + box.center();
faceAO(center_coord, X * size.x, Y * size.y, Z * size.z, block->modelUVs[i * 6 + 5], lights); // north
faceAO(center_coord, -X * size.x, Y * size.y, -Z * size.z, block->modelUVs[i * 6 + 4], lights); // south
faceAO(center_coord, X * size.x, -Z * size.z, Y * size.y, block->modelUVs[i * 6 + 3], lights); // top
faceAO(center_coord, -X * size.x, -Z * size.z, -Y * size.y, block->modelUVs[i * 6 + 2], lights); // bottom
faceAO(center_coord, -Z * size.z, Y * size.y, X * size.x, block->modelUVs[i * 6 + 1], lights); // west
faceAO(center_coord, Z * size.z, Y * size.y, -X * size.x, block->modelUVs[i * 6 + 0], lights); // east
}
for (size_t i = 0; i < block->modelExtraPoints.size()/4; i++) {
tetragonicFace(coord,
block->modelExtraPoints[i * 4 + 0],
block->modelExtraPoints[i * 4 + 1],
block->modelExtraPoints[i * 4 + 2],
block->modelExtraPoints[i * 4 + 3],
X, Y, Z,
block->modelUVs[block->modelBoxes.size()*6 + i], lights);
}
}

View File

@ -82,16 +82,6 @@ class BlocksRenderer {
const UVRegion& region,
bool lights
);
void tetragonicFace(
const glm::vec3& coord,
const glm::vec3& p1, const glm::vec3& p2,
const glm::vec3& p3, const glm::vec3& p4,
const glm::vec3& X,
const glm::vec3& Y,
const glm::vec3& Z,
const UVRegion& texreg,
bool lights
);
void blockCube(
const glm::ivec3& coord,
const UVRegion(&faces)[6],

View File

@ -1,8 +1,8 @@
#include "ModelBatch.hpp"
#include "assets/assets_util.hpp"
#include "graphics/commons/Model.hpp"
#include "graphics/core/Mesh.hpp"
#include "graphics/core/Model.hpp"
#include "graphics/core/Atlas.hpp"
#include "graphics/core/Texture.hpp"
#include "assets/Assets.hpp"

View File

@ -48,6 +48,60 @@ static inline UVRegion get_region_for(
return texreg.region;
}
model::Model ModelsGenerator::fromCustom(
const Assets& assets,
const std::vector<BoxModel>& modelBoxes,
const std::vector<std::string>& modelTextures,
const std::vector<glm::vec3>& points,
bool lighting
) {
auto model = model::Model();
for (size_t i = 0; i < modelBoxes.size(); i++) {
auto& mesh = model.addMesh("blocks:" + modelTextures[i * 6]);
mesh.lighting = lighting;
const UVRegion boxtexfaces[6] = {
get_region_for(modelTextures[i * 6], assets),
get_region_for(modelTextures[i * 6 + 1], assets),
get_region_for(modelTextures[i * 6 + 2], assets),
get_region_for(modelTextures[i * 6 + 3], assets),
get_region_for(modelTextures[i * 6 + 4], assets),
get_region_for(modelTextures[i * 6 + 5], assets)
};
mesh.addBox(
modelBoxes[i].center(), modelBoxes[i].size() * 0.5f, boxtexfaces
);
}
glm::vec3 poff = glm::vec3(0.0f, 0.0f, 1.0f);
glm::vec3 norm {0, 1, 0};
for (size_t i = 0; i < points.size() / 4; i++) {
auto texture = "blocks:" + modelTextures[modelBoxes.size() * 6 + i];
auto& mesh = model.addMesh(texture);
mesh.lighting = lighting;
auto reg = get_region_for(texture, assets);
mesh.vertices.push_back(
{points[i * 4 + 0] - poff, glm::vec2(reg.u1, reg.v1), norm}
);
mesh.vertices.push_back(
{points[i * 4 + 1] - poff, glm::vec2(reg.u2, reg.v1), norm}
);
mesh.vertices.push_back(
{points[i * 4 + 2] - poff, glm::vec2(reg.u2, reg.v2), norm}
);
mesh.vertices.push_back(
{points[i * 4 + 3] - poff, glm::vec2(reg.u1, reg.v1), norm}
);
mesh.vertices.push_back(
{points[i * 4 + 4] - poff, glm::vec2(reg.u2, reg.v2), norm}
);
mesh.vertices.push_back(
{points[i * 4 + 0] - poff, glm::vec2(reg.u1, reg.v2), norm}
);
}
return model;
}
model::Model ModelsGenerator::generate(
const ItemDef& def, const Content& content, const Assets& assets
) {
@ -59,55 +113,7 @@ model::Model ModelsGenerator::generate(
"blocks:" + blockDef.textureFaces.at(0), assets
);
} else if (blockDef.model == BlockModel::custom) {
model = model::Model();
for (size_t i = 0; i < blockDef.modelBoxes.size(); i++) {
auto& mesh =
model.addMesh("blocks:" + blockDef.modelTextures[i * 6]);
mesh.lighting = !blockDef.shadeless;
const UVRegion (&boxtexfaces)[6] = {
get_region_for(blockDef.modelTextures[i * 6], assets),
get_region_for(blockDef.modelTextures[i * 6 + 1], assets),
get_region_for(blockDef.modelTextures[i * 6 + 2], assets),
get_region_for(blockDef.modelTextures[i * 6 + 3], assets),
get_region_for(blockDef.modelTextures[i * 6 + 4], assets),
get_region_for(blockDef.modelTextures[i * 6 + 5], assets)
};
mesh.addBox(
blockDef.modelBoxes[i].center(),
blockDef.modelBoxes[i].size()*0.5f, boxtexfaces
);
}
const auto& points = blockDef.modelExtraPoints;
glm::vec3 poff = glm::vec3(0.0f, 0.0f, 1.0f);
glm::vec3 norm {0, 1, 0};
for (size_t i = 0; i < blockDef.modelExtraPoints.size() / 4; i++) {
auto texture =
"blocks:" +
blockDef.modelTextures[blockDef.modelBoxes.size() * 6 + i];
auto& mesh = model.addMesh(texture);
mesh.lighting = !blockDef.shadeless;
auto reg = get_region_for(texture, assets);
mesh.vertices.push_back(
{points[i * 4 + 0] - poff, glm::vec2(reg.u1, reg.v1), norm}
);
mesh.vertices.push_back(
{points[i * 4 + 1] - poff, glm::vec2(reg.u2, reg.v1), norm}
);
mesh.vertices.push_back(
{points[i * 4 + 2] - poff, glm::vec2(reg.u2, reg.v2), norm}
);
mesh.vertices.push_back(
{points[i * 4 + 3] - poff, glm::vec2(reg.u1, reg.v1), norm}
);
mesh.vertices.push_back(
{points[i * 4 + 4] - poff, glm::vec2(reg.u2, reg.v2), norm}
);
mesh.vertices.push_back(
{points[i * 4 + 0] - poff, glm::vec2(reg.u1, reg.v2), norm}
);
}
model = assets.require<model::Model>(blockDef.modelName);
for (auto& mesh : model.meshes) {
mesh.scale(glm::vec3(0.3f));
}
@ -135,3 +141,67 @@ model::Model ModelsGenerator::generate(
return model::Model();
}
}
model::Model ModelsGenerator::loadCustomBlockModel(
const dv::value& primitives, const Assets& assets, bool lighting
) {
std::vector<AABB> modelBoxes;
std::vector<std::string> modelTextures;
std::vector<glm::vec3> modelExtraPoints;
if (primitives.has("aabbs")) {
const auto& modelboxes = primitives["aabbs"];
for (uint i = 0; i < modelboxes.size(); i++) {
// Parse aabb
const auto& boxarr = modelboxes[i];
AABB modelbox;
modelbox.a = glm::vec3(
boxarr[0].asNumber(), boxarr[1].asNumber(), boxarr[2].asNumber()
);
modelbox.b = glm::vec3(
boxarr[3].asNumber(), boxarr[4].asNumber(), boxarr[5].asNumber()
);
modelbox.b += modelbox.a;
modelBoxes.push_back(modelbox);
if (boxarr.size() == 7) {
for (uint j = 6; j < 12; j++) {
modelTextures.emplace_back(boxarr[6].asString());
}
} else if (boxarr.size() == 12) {
for (uint j = 6; j < 12; j++) {
modelTextures.emplace_back(boxarr[j].asString());
}
} else {
for (uint j = 6; j < 12; j++) {
modelTextures.emplace_back("notfound");
}
}
}
}
if (primitives.has("tetragons")) {
const auto& modeltetragons = primitives["tetragons"];
for (uint i = 0; i < modeltetragons.size(); i++) {
// Parse tetragon to points
const auto& tgonobj = modeltetragons[i];
glm::vec3 p1(
tgonobj[0].asNumber(), tgonobj[1].asNumber(), tgonobj[2].asNumber()
);
glm::vec3 xw(
tgonobj[3].asNumber(), tgonobj[4].asNumber(), tgonobj[5].asNumber()
);
glm::vec3 yh(
tgonobj[6].asNumber(), tgonobj[7].asNumber(), tgonobj[8].asNumber()
);
modelExtraPoints.push_back(p1);
modelExtraPoints.push_back(p1 + xw);
modelExtraPoints.push_back(p1 + xw + yh);
modelExtraPoints.push_back(p1 + yh);
modelTextures.emplace_back(tgonobj[9].asString());
}
}
return fromCustom(
assets, modelBoxes, modelTextures, modelExtraPoints, lighting
);
}

View File

@ -1,14 +1,29 @@
#pragma once
#include "graphics/core/Model.hpp"
#include "graphics/commons/Model.hpp"
#include "maths/aabb.hpp"
#include "data/dv.hpp"
struct ItemDef;
class Assets;
class Content;
struct Block;
class ModelsGenerator {
public:
static model::Model generate(
const ItemDef& def, const Content& content, const Assets& assets
);
static model::Model fromCustom(
const Assets& assets,
const std::vector<AABB>& modelBoxes,
const std::vector<std::string>& modelTextures,
const std::vector<glm::vec3>& points,
bool lighting
);
static model::Model loadCustomBlockModel(
const dv::value& primitives, const Assets& assets, bool lighting
);
};

View File

@ -31,12 +31,12 @@
#include "world/Level.hpp"
#include "world/LevelEvents.hpp"
#include "world/World.hpp"
#include "graphics/commons/Model.hpp"
#include "graphics/core/Atlas.hpp"
#include "graphics/core/Batch3D.hpp"
#include "graphics/core/DrawContext.hpp"
#include "graphics/core/LineBatch.hpp"
#include "graphics/core/Mesh.hpp"
#include "graphics/core/Model.hpp"
#include "graphics/core/PostProcessing.hpp"
#include "graphics/core/Shader.hpp"
#include "graphics/core/Texture.hpp"

View File

@ -1,6 +1,7 @@
#pragma once
#include <cmath>
#include <glm/vec2.hpp>
struct UVRegion {
float u1;
@ -33,4 +34,10 @@ struct UVRegion {
u2 = u1 + uvw * w;
v2 = v1 + uvh * h;
}
inline glm::vec2 apply(const glm::vec2& uv) {
float w = getWidth();
float h = getHeight();
return glm::vec2(u1 + uv.x / w, v1 + uv.y / h);
}
};

View File

@ -10,7 +10,7 @@
#include "engine.hpp"
#include "graphics/core/DrawContext.hpp"
#include "graphics/core/LineBatch.hpp"
#include "graphics/core/Model.hpp"
#include "graphics/commons/Model.hpp"
#include "graphics/render/ModelBatch.hpp"
#include "logic/scripting/scripting.hpp"
#include "maths/FrustumCulling.hpp"

View File

@ -3,7 +3,7 @@
#include "assets/Assets.hpp"
#include "coders/json.hpp"
#include "data/dv_util.hpp"
#include "graphics/core/Model.hpp"
#include "graphics/commons/Model.hpp"
#include "graphics/render/ModelBatch.hpp"
#define GLM_ENABLE_EXPERIMENTAL

View File

@ -114,12 +114,8 @@ Block::Block(std::string name, const std::string& texture)
void Block::cloneTo(Block& dst) {
dst.caption = caption;
for (int i = 0; i < 6; i++) {
dst.textureFaces[i] = textureFaces[i];
dst.textureFaces[i] = textureFaces[i];
}
dst.modelTextures = modelTextures;
dst.modelBoxes = modelBoxes;
dst.modelExtraPoints = modelExtraPoints;
dst.modelUVs = modelUVs;
dst.material = material;
std::copy(&emission[0], &emission[3], dst.emission);
dst.size = size;
@ -143,7 +139,10 @@ void Block::cloneTo(Block& dst) {
dst.inventorySize = inventorySize;
dst.tickInterval = tickInterval;
dst.overlayTexture = overlayTexture;
dst.particles = std::make_unique<ParticlesPreset>(*particles);
if (particles) {
dst.particles = std::make_unique<ParticlesPreset>(*particles);
}
dst.customModelRaw = customModelRaw;
}
static std::set<std::string, std::less<>> RESERVED_BLOCK_FIELDS {

View File

@ -6,6 +6,7 @@
#include <vector>
#include <array>
#include "data/dv.hpp"
#include "maths/UVRegion.hpp"
#include "maths/aabb.hpp"
#include "typedefs.hpp"
@ -116,12 +117,6 @@ public:
/// @brief Textures set applied to block sides
std::array<std::string, 6> textureFaces; // -x,x, -y,y, -z,z
std::vector<std::string> modelTextures = {};
std::vector<BoxModel> modelBoxes = {};
// initially made for tetragons
std::vector<glm::vec3> modelExtraPoints = {};
std::vector<UVRegion> modelUVs = {}; // boxes' tex-UVs also there
/// @brief id of used BlockMaterial, may specify non-existing material
std::string material = DEFAULT_MATERIAL;
@ -137,6 +132,11 @@ public:
/// @brief Block model type
BlockModel model = BlockModel::block;
/// @brief Custom model raw data
dv::value customModelRaw = nullptr;
std::string modelName = "";
/// @brief Does the block passing lights into itself
bool lightPassing = false;

View File

@ -597,8 +597,7 @@ glm::vec3 Chunks::rayCastToObstacle(
if (def.obstacle) {
if (!def.rt.solid) {
const std::vector<AABB>& hitboxes =
def.rotatable ? def.rt.hitboxes[voxel->state.rotation]
: def.modelBoxes;
def.rt.hitboxes[voxel->state.rotation];
scalar_t distance;
glm::ivec3 norm;