feat: new block custom models implementation (WIP)
This commit is contained in:
parent
c95c97430a
commit
5e0bcf8ec0
@ -224,9 +224,9 @@ void ContentLoader::loadBlock(
|
|||||||
if (auto model = BlockModel_from(modelName)) {
|
if (auto model = BlockModel_from(modelName)) {
|
||||||
if (*model == BlockModel::custom) {
|
if (*model == BlockModel::custom) {
|
||||||
if (root.has("model-primitives")) {
|
if (root.has("model-primitives")) {
|
||||||
loadCustomBlockModel(def, root["model-primitives"]);
|
def.customModelRaw = root["model-primitives"];
|
||||||
} else {
|
} else {
|
||||||
logger.error() << name << ": no 'model-primitives' found";
|
throw std::runtime_error(name + ": no 'model-primitives' found");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
def.model = *model;
|
def.model = *model;
|
||||||
@ -277,8 +277,6 @@ void ContentLoader::loadBlock(
|
|||||||
);
|
);
|
||||||
aabb.b += aabb.a;
|
aabb.b += aabb.a;
|
||||||
def.hitboxes = {aabb};
|
def.hitboxes = {aabb};
|
||||||
} else if (!def.modelBoxes.empty()) {
|
|
||||||
def.hitboxes = def.modelBoxes;
|
|
||||||
} else {
|
} else {
|
||||||
def.hitboxes = {AABB()};
|
def.hitboxes = {AABB()};
|
||||||
}
|
}
|
||||||
@ -350,61 +348,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(
|
void ContentLoader::loadItem(
|
||||||
ItemDef& def, const std::string& name, const fs::path& file
|
ItemDef& def, const std::string& name, const fs::path& file
|
||||||
) {
|
) {
|
||||||
|
|||||||
@ -42,7 +42,6 @@ class ContentLoader {
|
|||||||
GeneratorDef& def, const std::string& full, const std::string& name
|
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);
|
static void loadBlockMaterial(BlockMaterial& def, const fs::path& file);
|
||||||
void loadBlock(
|
void loadBlock(
|
||||||
Block& def, const std::string& name, const fs::path& file
|
Block& def, const std::string& name, const fs::path& file
|
||||||
|
|||||||
@ -286,6 +286,18 @@ void Engine::loadAssets() {
|
|||||||
assets = std::move(new_assets);
|
assets = std::move(new_assets);
|
||||||
|
|
||||||
if (content) {
|
if (content) {
|
||||||
|
for (auto& [name, def] : content->blocks.getDefs()) {
|
||||||
|
if (def->model == BlockModel::custom) {
|
||||||
|
assets->store(
|
||||||
|
std::make_unique<model::Model>(
|
||||||
|
ModelsGenerator::loadCustomBlockModel(
|
||||||
|
def->customModelRaw, *assets, !def->shadeless
|
||||||
|
)
|
||||||
|
),
|
||||||
|
name + ".model"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
for (auto& [name, def] : content->items.getDefs()) {
|
for (auto& [name, def] : content->items.getDefs()) {
|
||||||
assets->store(
|
assets->store(
|
||||||
std::make_unique<model::Model>(
|
std::make_unique<model::Model>(
|
||||||
|
|||||||
@ -1,24 +1,25 @@
|
|||||||
#include "ContentGfxCache.hpp"
|
#include "ContentGfxCache.hpp"
|
||||||
|
|
||||||
#include "UiDocument.hpp"
|
#include <string>
|
||||||
|
|
||||||
|
#include "UiDocument.hpp"
|
||||||
#include "assets/Assets.hpp"
|
#include "assets/Assets.hpp"
|
||||||
#include "content/Content.hpp"
|
#include "content/Content.hpp"
|
||||||
#include "content/ContentPack.hpp"
|
#include "content/ContentPack.hpp"
|
||||||
#include "core_defs.hpp"
|
#include "core_defs.hpp"
|
||||||
|
#include "graphics/commons/Model.hpp"
|
||||||
#include "graphics/core/Atlas.hpp"
|
#include "graphics/core/Atlas.hpp"
|
||||||
#include "maths/UVRegion.hpp"
|
#include "maths/UVRegion.hpp"
|
||||||
#include "voxels/Block.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();
|
auto indices = content->getIndices();
|
||||||
sideregions = std::make_unique<UVRegion[]>(indices->blocks.count() * 6);
|
sideregions = std::make_unique<UVRegion[]>(indices->blocks.count() * 6);
|
||||||
auto atlas = assets->get<Atlas>("blocks");
|
auto atlas = assets->get<Atlas>("blocks");
|
||||||
|
|
||||||
const auto& blocks = indices->blocks.getIterable();
|
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];
|
auto def = blocks[i];
|
||||||
for (uint side = 0; side < 6; side++) {
|
for (uint side = 0; side < 6; side++) {
|
||||||
const std::string& tex = def->textureFaces[side];
|
const std::string& tex = def->textureFaces[side];
|
||||||
@ -28,13 +29,9 @@ ContentGfxCache::ContentGfxCache(const Content* content, Assets* assets) : conte
|
|||||||
sideregions[i * 6 + side] = atlas->get(TEXTURE_NOTFOUND);
|
sideregions[i * 6 + side] = atlas->get(TEXTURE_NOTFOUND);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (uint side = 0; side < def->modelTextures.size(); side++) {
|
if (def->model == BlockModel::custom) {
|
||||||
const std::string& tex = def->modelTextures[side];
|
models[def->rt.id] =
|
||||||
if (atlas->has(tex)) {
|
assets->require<model::Model>(def->name + ".model");
|
||||||
def->modelUVs.push_back(atlas->get(tex));
|
|
||||||
} else if (atlas->has(TEXTURE_NOTFOUND)) {
|
|
||||||
def->modelUVs.push_back(atlas->get(TEXTURE_NOTFOUND));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -44,3 +41,11 @@ ContentGfxCache::~ContentGfxCache() = default;
|
|||||||
const Content* ContentGfxCache::getContent() const {
|
const Content* ContentGfxCache::getContent() const {
|
||||||
return content;
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@ -3,15 +3,22 @@
|
|||||||
#include "typedefs.hpp"
|
#include "typedefs.hpp"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
class Content;
|
class Content;
|
||||||
class Assets;
|
class Assets;
|
||||||
struct UVRegion;
|
struct UVRegion;
|
||||||
|
|
||||||
|
namespace model {
|
||||||
|
struct Model;
|
||||||
|
}
|
||||||
|
|
||||||
class ContentGfxCache {
|
class ContentGfxCache {
|
||||||
const Content* content;
|
const Content* content;
|
||||||
// array of block sides uv regions (6 per block)
|
// array of block sides uv regions (6 per block)
|
||||||
std::unique_ptr<UVRegion[]> sideregions;
|
std::unique_ptr<UVRegion[]> sideregions;
|
||||||
|
std::unordered_map<blockid_t, model::Model> models;
|
||||||
public:
|
public:
|
||||||
ContentGfxCache(const Content* content, Assets* assets);
|
ContentGfxCache(const Content* content, Assets* assets);
|
||||||
~ContentGfxCache();
|
~ContentGfxCache();
|
||||||
@ -20,5 +27,7 @@ public:
|
|||||||
return sideregions[id * 6 + side];
|
return sideregions[id * 6 + side];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const model::Model& getModel(blockid_t id) const;
|
||||||
|
|
||||||
const Content* getContent() const;
|
const Content* getContent() const;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -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.u1, uv.v1}, norm});
|
||||||
vertices.push_back({pos+right+up, {uv.u2, uv.v2}, 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) {
|
void Mesh::addBox(const glm::vec3& pos, const glm::vec3& size) {
|
||||||
|
|||||||
@ -64,41 +64,41 @@ std::unique_ptr<ImageData> BlocksPreview::draw(
|
|||||||
{
|
{
|
||||||
glm::vec3 pmul = glm::vec3(size * 0.63f);
|
glm::vec3 pmul = glm::vec3(size * 0.63f);
|
||||||
glm::vec3 hitbox = glm::vec3();
|
glm::vec3 hitbox = glm::vec3();
|
||||||
for (const auto& box : def.modelBoxes) {
|
// for (const auto& box : def.modelBoxes) {
|
||||||
hitbox = glm::max(hitbox, box.size());
|
// hitbox = glm::max(hitbox, box.size());
|
||||||
}
|
// }
|
||||||
offset.y += (1.0f - hitbox).y * 0.5f;
|
offset.y += (1.0f - hitbox).y * 0.5f;
|
||||||
shader->uniformMatrix("u_apply", glm::translate(glm::mat4(1.0f), offset));
|
shader->uniformMatrix("u_apply", glm::translate(glm::mat4(1.0f), offset));
|
||||||
for (size_t i = 0; i < def.modelBoxes.size(); i++) {
|
// for (size_t i = 0; i < def.modelBoxes.size(); i++) {
|
||||||
const UVRegion (&boxtexfaces)[6] = {
|
// const UVRegion (&boxtexfaces)[6] = {
|
||||||
def.modelUVs[i * 6],
|
// def.modelUVs[i * 6],
|
||||||
def.modelUVs[i * 6 + 1],
|
// def.modelUVs[i * 6 + 1],
|
||||||
def.modelUVs[i * 6 + 2],
|
// def.modelUVs[i * 6 + 2],
|
||||||
def.modelUVs[i * 6 + 3],
|
// def.modelUVs[i * 6 + 3],
|
||||||
def.modelUVs[i * 6 + 4],
|
// def.modelUVs[i * 6 + 4],
|
||||||
def.modelUVs[i * 6 + 5]
|
// def.modelUVs[i * 6 + 5]
|
||||||
};
|
// };
|
||||||
batch->cube(
|
// batch->cube(
|
||||||
def.modelBoxes[i].a * glm::vec3(1.0f, 1.0f, -1.0f) * pmul,
|
// def.modelBoxes[i].a * glm::vec3(1.0f, 1.0f, -1.0f) * pmul,
|
||||||
def.modelBoxes[i].size() * pmul,
|
// def.modelBoxes[i].size() * pmul,
|
||||||
boxtexfaces, glm::vec4(1.0f), !def.rt.emissive
|
// boxtexfaces, glm::vec4(1.0f), !def.rt.emissive
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
|
||||||
auto& points = def.modelExtraPoints;
|
// auto& points = def.modelExtraPoints;
|
||||||
glm::vec3 poff = glm::vec3(0.0f, 0.0f, 1.0f);
|
// glm::vec3 poff = glm::vec3(0.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
for (size_t i = 0; i < def.modelExtraPoints.size() / 4; i++) {
|
// for (size_t i = 0; i < def.modelExtraPoints.size() / 4; i++) {
|
||||||
const UVRegion& reg = def.modelUVs[def.modelBoxes.size() * 6 + 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 + 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 + 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 + 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 + 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 + 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));
|
// batch->vertex((points[i * 4 + 3] - poff) * pmul, glm::vec2(reg.u1, reg.v2), glm::vec4(1.0));
|
||||||
}
|
// }
|
||||||
batch->flush();
|
// batch->flush();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BlockModel::xsprite: {
|
case BlockModel::xsprite: {
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#include "BlocksRenderer.hpp"
|
#include "BlocksRenderer.hpp"
|
||||||
|
|
||||||
#include "graphics/core/Mesh.hpp"
|
#include "graphics/core/Mesh.hpp"
|
||||||
|
#include "graphics/commons/Model.hpp"
|
||||||
#include "maths/UVRegion.hpp"
|
#include "maths/UVRegion.hpp"
|
||||||
#include "constants.hpp"
|
#include "constants.hpp"
|
||||||
#include "content/Content.hpp"
|
#include "content/Content.hpp"
|
||||||
@ -303,6 +304,7 @@ void BlocksRenderer::blockAABB(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
void BlocksRenderer::blockCustomModel(
|
void BlocksRenderer::blockCustomModel(
|
||||||
const glm::ivec3& icoord, const Block* block, ubyte rotation, bool lights, bool ao
|
const glm::ivec3& icoord, const Block* block, ubyte rotation, bool lights, bool ao
|
||||||
) {
|
) {
|
||||||
@ -319,29 +321,31 @@ void BlocksRenderer::blockCustomModel(
|
|||||||
Z = orient.axisZ;
|
Z = orient.axisZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < block->modelBoxes.size(); i++) {
|
const auto& model = cache->getModel(block->rt.id);
|
||||||
AABB box = block->modelBoxes[i];
|
for (const auto& mesh : model.meshes) {
|
||||||
auto size = box.size();
|
if (vertexOffset + BlocksRenderer::VERTEX_SIZE * mesh.vertices.size() > capacity) {
|
||||||
if (block->rotatable) {
|
overflow = true;
|
||||||
orient.transform(box);
|
return;
|
||||||
|
}
|
||||||
|
int i = 0;
|
||||||
|
for (const auto& vertex : mesh.vertices) {
|
||||||
|
if ((i++) % 6 < 3) {
|
||||||
|
// continue;
|
||||||
|
}
|
||||||
|
float d = glm::dot(glm::normalize(vertex.normal), SUN_VECTOR);
|
||||||
|
d = 0.8f + d * 0.2f;
|
||||||
|
const auto& n = vertex.normal;
|
||||||
|
vertexAO(
|
||||||
|
coord + vertex.coord - 0.5f,
|
||||||
|
vertex.uv.x,
|
||||||
|
vertex.uv.y,
|
||||||
|
glm::vec4(1, 1, 1, 0),
|
||||||
|
glm::vec3(n.x, -n.z, n.y),
|
||||||
|
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -59,13 +59,14 @@ model::Model ModelsGenerator::fromCustom(
|
|||||||
for (size_t i = 0; i < modelBoxes.size(); i++) {
|
for (size_t i = 0; i < modelBoxes.size(); i++) {
|
||||||
auto& mesh = model.addMesh("blocks:" + modelTextures[i * 6]);
|
auto& mesh = model.addMesh("blocks:" + modelTextures[i * 6]);
|
||||||
mesh.lighting = lighting;
|
mesh.lighting = lighting;
|
||||||
const UVRegion(&boxtexfaces)[6] = {
|
const UVRegion boxtexfaces[6] = {
|
||||||
get_region_for(modelTextures[i * 6], assets),
|
get_region_for(modelTextures[i * 6], assets),
|
||||||
get_region_for(modelTextures[i * 6 + 1], assets),
|
get_region_for(modelTextures[i * 6 + 1], assets),
|
||||||
get_region_for(modelTextures[i * 6 + 2], assets),
|
get_region_for(modelTextures[i * 6 + 2], assets),
|
||||||
get_region_for(modelTextures[i * 6 + 3], assets),
|
get_region_for(modelTextures[i * 6 + 3], assets),
|
||||||
get_region_for(modelTextures[i * 6 + 4], assets),
|
get_region_for(modelTextures[i * 6 + 4], assets),
|
||||||
get_region_for(modelTextures[i * 6 + 5], assets)};
|
get_region_for(modelTextures[i * 6 + 5], assets)
|
||||||
|
};
|
||||||
mesh.addBox(
|
mesh.addBox(
|
||||||
modelBoxes[i].center(), modelBoxes[i].size() * 0.5f, boxtexfaces
|
modelBoxes[i].center(), modelBoxes[i].size() * 0.5f, boxtexfaces
|
||||||
);
|
);
|
||||||
@ -112,13 +113,7 @@ model::Model ModelsGenerator::generate(
|
|||||||
"blocks:" + blockDef.textureFaces.at(0), assets
|
"blocks:" + blockDef.textureFaces.at(0), assets
|
||||||
);
|
);
|
||||||
} else if (blockDef.model == BlockModel::custom) {
|
} else if (blockDef.model == BlockModel::custom) {
|
||||||
model = fromCustom(
|
model = assets.require<model::Model>(blockDef.name+".model");
|
||||||
assets,
|
|
||||||
blockDef.modelBoxes,
|
|
||||||
blockDef.modelTextures,
|
|
||||||
blockDef.modelExtraPoints,
|
|
||||||
!blockDef.shadeless
|
|
||||||
);
|
|
||||||
for (auto& mesh : model.meshes) {
|
for (auto& mesh : model.meshes) {
|
||||||
mesh.scale(glm::vec3(0.3f));
|
mesh.scale(glm::vec3(0.3f));
|
||||||
}
|
}
|
||||||
@ -146,3 +141,67 @@ model::Model ModelsGenerator::generate(
|
|||||||
return model::Model();
|
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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@ -2,10 +2,12 @@
|
|||||||
|
|
||||||
#include "graphics/commons/Model.hpp"
|
#include "graphics/commons/Model.hpp"
|
||||||
#include "maths/aabb.hpp"
|
#include "maths/aabb.hpp"
|
||||||
|
#include "data/dv.hpp"
|
||||||
|
|
||||||
struct ItemDef;
|
struct ItemDef;
|
||||||
class Assets;
|
class Assets;
|
||||||
class Content;
|
class Content;
|
||||||
|
struct Block;
|
||||||
|
|
||||||
class ModelsGenerator {
|
class ModelsGenerator {
|
||||||
public:
|
public:
|
||||||
@ -20,4 +22,8 @@ public:
|
|||||||
const std::vector<glm::vec3>& points,
|
const std::vector<glm::vec3>& points,
|
||||||
bool lighting
|
bool lighting
|
||||||
);
|
);
|
||||||
|
|
||||||
|
static model::Model loadCustomBlockModel(
|
||||||
|
const dv::value& primitives, const Assets& assets, bool lighting
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <glm/vec2.hpp>
|
||||||
|
|
||||||
struct UVRegion {
|
struct UVRegion {
|
||||||
float u1;
|
float u1;
|
||||||
@ -33,4 +34,10 @@ struct UVRegion {
|
|||||||
u2 = u1 + uvw * w;
|
u2 = u1 + uvw * w;
|
||||||
v2 = v1 + uvh * h;
|
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);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -114,12 +114,8 @@ Block::Block(std::string name, const std::string& texture)
|
|||||||
void Block::cloneTo(Block& dst) {
|
void Block::cloneTo(Block& dst) {
|
||||||
dst.caption = caption;
|
dst.caption = caption;
|
||||||
for (int i = 0; i < 6; i++) {
|
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;
|
dst.material = material;
|
||||||
std::copy(&emission[0], &emission[3], dst.emission);
|
std::copy(&emission[0], &emission[3], dst.emission);
|
||||||
dst.size = size;
|
dst.size = size;
|
||||||
@ -143,7 +139,10 @@ void Block::cloneTo(Block& dst) {
|
|||||||
dst.inventorySize = inventorySize;
|
dst.inventorySize = inventorySize;
|
||||||
dst.tickInterval = tickInterval;
|
dst.tickInterval = tickInterval;
|
||||||
dst.overlayTexture = overlayTexture;
|
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 {
|
static std::set<std::string, std::less<>> RESERVED_BLOCK_FIELDS {
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
|
#include "data/dv.hpp"
|
||||||
#include "maths/UVRegion.hpp"
|
#include "maths/UVRegion.hpp"
|
||||||
#include "maths/aabb.hpp"
|
#include "maths/aabb.hpp"
|
||||||
#include "typedefs.hpp"
|
#include "typedefs.hpp"
|
||||||
@ -116,12 +117,6 @@ public:
|
|||||||
/// @brief Textures set applied to block sides
|
/// @brief Textures set applied to block sides
|
||||||
std::array<std::string, 6> textureFaces; // -x,x, -y,y, -z,z
|
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
|
/// @brief id of used BlockMaterial, may specify non-existing material
|
||||||
std::string material = DEFAULT_MATERIAL;
|
std::string material = DEFAULT_MATERIAL;
|
||||||
|
|
||||||
@ -137,6 +132,9 @@ public:
|
|||||||
/// @brief Block model type
|
/// @brief Block model type
|
||||||
BlockModel model = BlockModel::block;
|
BlockModel model = BlockModel::block;
|
||||||
|
|
||||||
|
/// @brief Custom model raw data
|
||||||
|
dv::value customModelRaw = nullptr;
|
||||||
|
|
||||||
/// @brief Does the block passing lights into itself
|
/// @brief Does the block passing lights into itself
|
||||||
bool lightPassing = false;
|
bool lightPassing = false;
|
||||||
|
|
||||||
|
|||||||
@ -597,8 +597,7 @@ glm::vec3 Chunks::rayCastToObstacle(
|
|||||||
if (def.obstacle) {
|
if (def.obstacle) {
|
||||||
if (!def.rt.solid) {
|
if (!def.rt.solid) {
|
||||||
const std::vector<AABB>& hitboxes =
|
const std::vector<AABB>& hitboxes =
|
||||||
def.rotatable ? def.rt.hitboxes[voxel->state.rotation]
|
def.rt.hitboxes[voxel->state.rotation];
|
||||||
: def.modelBoxes;
|
|
||||||
|
|
||||||
scalar_t distance;
|
scalar_t distance;
|
||||||
glm::ivec3 norm;
|
glm::ivec3 norm;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user