mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-08 20:41:49 +00:00
Merge branch 'main' into physics-upgrade
This commit is contained in:
commit
3cd6ce1df2
13 changed files with 93 additions and 26 deletions
|
|
@ -30,7 +30,11 @@ assets.parse_model(
|
||||||
-- Contents of the model file
|
-- Contents of the model file
|
||||||
content: str,
|
content: str,
|
||||||
-- Model name after loading
|
-- Model name after loading
|
||||||
name: str
|
name: str,
|
||||||
|
-- The skeleton name after loading. May be the same as the model name.
|
||||||
|
-- The model will be split by the named bones.
|
||||||
|
[optional]
|
||||||
|
skeleton_name: string
|
||||||
)
|
)
|
||||||
|
|
||||||
-- Creates a Canvas from a loaded texture.
|
-- Creates a Canvas from a loaded texture.
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,11 @@ assets.parse_model(
|
||||||
-- Содержимое файла модели
|
-- Содержимое файла модели
|
||||||
content: string,
|
content: string,
|
||||||
-- Имя модели после загрузки
|
-- Имя модели после загрузки
|
||||||
name: string
|
name: string,
|
||||||
|
-- Имя скелета после загрузки. Может совпадать с именем модели.
|
||||||
|
-- Модель будет разделена по именованным костям.
|
||||||
|
[опционально]
|
||||||
|
skeleton_name: string
|
||||||
)
|
)
|
||||||
|
|
||||||
-- Создаёт холст (Canvas) из загруженной текстуры
|
-- Создаёт холст (Canvas) из загруженной текстуры
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
<panel size='400' color='#00000080' padding='8'>
|
<panel size='400' color='#00000080' padding='8' max-length='400'>
|
||||||
<!-- content is generated in script -->
|
<!-- content is generated in script -->
|
||||||
</panel>
|
</panel>
|
||||||
|
|
|
||||||
|
|
@ -803,8 +803,10 @@ void ALAudio::setAcoustics(Acoustics acoustics) {
|
||||||
AL_CHECK(alEffectf(
|
AL_CHECK(alEffectf(
|
||||||
reverbEffect,
|
reverbEffect,
|
||||||
AL_REVERB_GAIN,
|
AL_REVERB_GAIN,
|
||||||
glm::max(0.1f, glm::min(acoustics.reverbGain, 0.8f) *
|
glm::clamp(glm::min(acoustics.reverbGain, 0.8f) *
|
||||||
(1.0f - glm::min(1.0f, acoustics.reverbAbsorption)))
|
(1.0f - glm::min(1.0f, acoustics.reverbAbsorption)),
|
||||||
|
AL_REVERB_MIN_GAIN,
|
||||||
|
AL_REVERB_MAX_GAIN)
|
||||||
));
|
));
|
||||||
AL_CHECK(alEffectf(
|
AL_CHECK(alEffectf(
|
||||||
reverbEffect,
|
reverbEffect,
|
||||||
|
|
|
||||||
|
|
@ -251,6 +251,10 @@ void BlocksRenderer::blockAABB(
|
||||||
Z = orient.axes[2];
|
Z = orient.axes[2];
|
||||||
orient.transform(hitbox);
|
orient.transform(hitbox);
|
||||||
}
|
}
|
||||||
|
if (block->rt.extended) {
|
||||||
|
meshAABB.addPoint(coord + hitbox.max());
|
||||||
|
meshAABB.addPoint(coord + hitbox.min());
|
||||||
|
}
|
||||||
coord -= glm::vec3(0.5f) - hitbox.center();
|
coord -= glm::vec3(0.5f) - hitbox.center();
|
||||||
|
|
||||||
if (ao) {
|
if (ao) {
|
||||||
|
|
@ -306,6 +310,12 @@ void BlocksRenderer::blockCustomModel(
|
||||||
if (culled) {
|
if (culled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
meshAABB.addPoint(
|
||||||
|
coord + X * glm::vec3(block.size.x) +
|
||||||
|
Y * glm::vec3(block.size.y) +
|
||||||
|
Z * glm::vec3(block.size.z)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& model = cache.getModel(block.rt.id, block.getVariantIndex(states.userbits));
|
const auto& model = cache.getModel(block.rt.id, block.getVariantIndex(states.userbits));
|
||||||
|
|
@ -687,6 +697,7 @@ SortingMeshData BlocksRenderer::renderTranslucent(
|
||||||
void BlocksRenderer::build(
|
void BlocksRenderer::build(
|
||||||
const Chunk* chunk, const VoxelsRenderVolume& volume
|
const Chunk* chunk, const VoxelsRenderVolume& volume
|
||||||
) {
|
) {
|
||||||
|
meshAABB = AABB(glm::vec3(CHUNK_W, CHUNK_H, CHUNK_D));
|
||||||
this->chunk = chunk;
|
this->chunk = chunk;
|
||||||
this->voxelsBuffer = &volume;
|
this->voxelsBuffer = &volume;
|
||||||
if (voxelsBuffer->pickBlockId(
|
if (voxelsBuffer->pickBlockId(
|
||||||
|
|
@ -767,7 +778,8 @@ ChunkMeshData BlocksRenderer::createMesh() {
|
||||||
sizeof(ChunkVertex::ATTRIBUTES) / sizeof(VertexAttribute)
|
sizeof(ChunkVertex::ATTRIBUTES) / sizeof(VertexAttribute)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
std::move(sortingMesh)
|
std::move(sortingMesh),
|
||||||
|
std::move(meshAABB)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -786,7 +798,7 @@ ChunkMesh BlocksRenderer::render(
|
||||||
IndexBufferData {indexBuffer.get(), indexCount},
|
IndexBufferData {indexBuffer.get(), indexCount},
|
||||||
IndexBufferData {denseIndexBuffer.get(), denseIndexCount},
|
IndexBufferData {denseIndexBuffer.get(), denseIndexCount},
|
||||||
}
|
}
|
||||||
), std::move(sortingMesh), nullptr};
|
), std::move(sortingMesh), nullptr, std::move(meshAABB)};
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t BlocksRenderer::getMemoryConsumption() const {
|
size_t BlocksRenderer::getMemoryConsumption() const {
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
#include "voxels/Chunk.hpp"
|
#include "voxels/Chunk.hpp"
|
||||||
#include "voxels/VoxelsVolume.hpp"
|
#include "voxels/VoxelsVolume.hpp"
|
||||||
#include "maths/util.hpp"
|
#include "maths/util.hpp"
|
||||||
|
#include "maths/aabb.hpp"
|
||||||
#include "commons.hpp"
|
#include "commons.hpp"
|
||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
|
|
||||||
|
|
@ -56,6 +57,7 @@ private:
|
||||||
bool cancelled = false;
|
bool cancelled = false;
|
||||||
bool densePass = false;
|
bool densePass = false;
|
||||||
bool denseRender = false;
|
bool denseRender = false;
|
||||||
|
AABB meshAABB {};
|
||||||
const Chunk* chunk = nullptr;
|
const Chunk* chunk = nullptr;
|
||||||
const VoxelsRenderVolume* voxelsBuffer = nullptr;
|
const VoxelsRenderVolume* voxelsBuffer = nullptr;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,9 @@ ChunksRenderer::ChunksRenderer(
|
||||||
meshes[result.key] = ChunkMesh {
|
meshes[result.key] = ChunkMesh {
|
||||||
std::move(chunk),
|
std::move(chunk),
|
||||||
std::move(meshData.sortingMesh),
|
std::move(meshData.sortingMesh),
|
||||||
nullptr};
|
nullptr,
|
||||||
|
std::move(meshData.meshAABB)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
inwork.erase(result.key);
|
inwork.erase(result.key);
|
||||||
},
|
},
|
||||||
|
|
@ -120,7 +122,7 @@ std::shared_ptr<VoxelsRenderVolume> ChunksRenderer::prepareVoxelsVolume(
|
||||||
return voxelsBuffer;
|
return voxelsBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Mesh<ChunkVertex>* ChunksRenderer::render(
|
const ChunkMesh* ChunksRenderer::render(
|
||||||
const std::shared_ptr<Chunk>& chunk, bool important, bool lowPriority
|
const std::shared_ptr<Chunk>& chunk, bool important, bool lowPriority
|
||||||
) {
|
) {
|
||||||
glm::ivec2 key(chunk->x, chunk->z);
|
glm::ivec2 key(chunk->x, chunk->z);
|
||||||
|
|
@ -130,7 +132,7 @@ const Mesh<ChunkVertex>* ChunksRenderer::render(
|
||||||
auto voxelsBuffer = prepareVoxelsVolume(*chunk);
|
auto voxelsBuffer = prepareVoxelsVolume(*chunk);
|
||||||
mesh = renderer->render(chunk.get(), *voxelsBuffer);
|
mesh = renderer->render(chunk.get(), *voxelsBuffer);
|
||||||
meshes[key] = std::move(mesh);
|
meshes[key] = std::move(mesh);
|
||||||
return meshes[key].mesh.get();
|
return &meshes[key];
|
||||||
}
|
}
|
||||||
if (inwork.find(key) != inwork.end() ||
|
if (inwork.find(key) != inwork.end() ||
|
||||||
((inwork.size() >= threadPool.getWorkersCount() ||
|
((inwork.size() >= threadPool.getWorkersCount() ||
|
||||||
|
|
@ -158,7 +160,7 @@ void ChunksRenderer::clear() {
|
||||||
threadPool.clearQueue();
|
threadPool.clearQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
const Mesh<ChunkVertex>* ChunksRenderer::getOrRender(
|
const ChunkMesh* ChunksRenderer::getOrRender(
|
||||||
const std::shared_ptr<Chunk>& chunk, bool important, bool lowPriority
|
const std::shared_ptr<Chunk>& chunk, bool important, bool lowPriority
|
||||||
) {
|
) {
|
||||||
auto found = meshes.find(glm::ivec2(chunk->x, chunk->z));
|
auto found = meshes.find(glm::ivec2(chunk->x, chunk->z));
|
||||||
|
|
@ -168,7 +170,7 @@ const Mesh<ChunkVertex>* ChunksRenderer::getOrRender(
|
||||||
if (chunk->flags.modified && chunk->flags.lighted) {
|
if (chunk->flags.modified && chunk->flags.lighted) {
|
||||||
render(chunk, important, lowPriority);
|
render(chunk, important, lowPriority);
|
||||||
}
|
}
|
||||||
return found->second.mesh.get();
|
return &found->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChunksRenderer::update() {
|
void ChunksRenderer::update() {
|
||||||
|
|
@ -211,16 +213,23 @@ const Mesh<ChunkVertex>* ChunksRenderer::retrieveChunk(
|
||||||
chunk->updateHeights();
|
chunk->updateHeights();
|
||||||
}
|
}
|
||||||
if (culling) {
|
if (culling) {
|
||||||
glm::vec3 min(chunk->x * CHUNK_W, chunk->bottom, chunk->z * CHUNK_D);
|
const auto& meshAABB = mesh->meshAABB;
|
||||||
|
auto aabbMin = meshAABB.min();
|
||||||
|
auto aabbMax = meshAABB.max();
|
||||||
|
glm::vec3 min(
|
||||||
|
chunk->x * CHUNK_W + std::min(0.0f, aabbMin.x),
|
||||||
|
chunk->bottom,
|
||||||
|
chunk->z * CHUNK_D + std::min(0.0f, aabbMin.z)
|
||||||
|
);
|
||||||
glm::vec3 max(
|
glm::vec3 max(
|
||||||
chunk->x * CHUNK_W + CHUNK_W,
|
chunk->x * CHUNK_W + aabbMax.x,
|
||||||
chunk->top,
|
chunk->top,
|
||||||
chunk->z * CHUNK_D + CHUNK_D
|
chunk->z * CHUNK_D + aabbMax.z
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!frustum.isBoxVisible(min, max)) return nullptr;
|
if (!frustum.isBoxVisible(min, max)) return nullptr;
|
||||||
}
|
}
|
||||||
return mesh;
|
return mesh->mesh.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChunksRenderer::drawShadowsPass(
|
void ChunksRenderer::drawShadowsPass(
|
||||||
|
|
|
||||||
|
|
@ -71,13 +71,13 @@ public:
|
||||||
);
|
);
|
||||||
virtual ~ChunksRenderer();
|
virtual ~ChunksRenderer();
|
||||||
|
|
||||||
const Mesh<ChunkVertex>* render(
|
const ChunkMesh* render(
|
||||||
const std::shared_ptr<Chunk>& chunk, bool important, bool lowPriority
|
const std::shared_ptr<Chunk>& chunk, bool important, bool lowPriority
|
||||||
);
|
);
|
||||||
void unload(const Chunk* chunk);
|
void unload(const Chunk* chunk);
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
const Mesh<ChunkVertex>* getOrRender(
|
const ChunkMesh* getOrRender(
|
||||||
const std::shared_ptr<Chunk>& chunk, bool important, bool lowPriority
|
const std::shared_ptr<Chunk>& chunk, bool important, bool lowPriority
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "constants.hpp"
|
#include "constants.hpp"
|
||||||
#include "graphics/core/MeshData.hpp"
|
#include "graphics/core/MeshData.hpp"
|
||||||
|
#include "maths/aabb.hpp"
|
||||||
#include "util/Buffer.hpp"
|
#include "util/Buffer.hpp"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
@ -45,12 +46,14 @@ struct SortingMeshData {
|
||||||
struct ChunkMeshData {
|
struct ChunkMeshData {
|
||||||
MeshData<ChunkVertex> mesh;
|
MeshData<ChunkVertex> mesh;
|
||||||
SortingMeshData sortingMesh;
|
SortingMeshData sortingMesh;
|
||||||
|
AABB meshAABB;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ChunkMesh {
|
struct ChunkMesh {
|
||||||
std::unique_ptr<Mesh<ChunkVertex>> mesh;
|
std::unique_ptr<Mesh<ChunkVertex>> mesh;
|
||||||
SortingMeshData sortingMeshData;
|
SortingMeshData sortingMeshData;
|
||||||
std::unique_ptr<Mesh<ChunkVertex> > sortedMesh;
|
std::unique_ptr<Mesh<ChunkVertex> > sortedMesh;
|
||||||
|
AABB meshAABB;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline constexpr int VOXELS_BUFFER_PADDING = 2;
|
inline constexpr int VOXELS_BUFFER_PADDING = 2;
|
||||||
|
|
|
||||||
|
|
@ -70,17 +70,46 @@ static int l_parse_model(lua::State* L) {
|
||||||
|
|
||||||
auto format = lua::require_lstring(L, 1);
|
auto format = lua::require_lstring(L, 1);
|
||||||
auto string = lua::require_lstring(L, 2);
|
auto string = lua::require_lstring(L, 2);
|
||||||
auto name = lua::require_string(L, 3);
|
std::string name = lua::require_string(L, 3);
|
||||||
|
std::string skeletonName;
|
||||||
|
if (lua::isstring(L, 4)) {
|
||||||
|
skeletonName = lua::require_string(L, 4);
|
||||||
|
}
|
||||||
|
|
||||||
if (format == "xml" || format == "vcm") {
|
if (format != "xml" && format != "vcm") {
|
||||||
auto vcmModel = vcm::parse(name, string, format == "xml");
|
throw std::runtime_error(
|
||||||
|
"unknown format " + util::quote(std::string(format))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto vcmModel = vcm::parse(name, string, format == "xml");
|
||||||
|
|
||||||
|
if (skeletonName.empty()) {
|
||||||
assets.store(
|
assets.store(
|
||||||
std::make_unique<model::Model>(std::move(vcmModel.squash())), name
|
std::make_unique<model::Model>(std::move(vcmModel.squash())), name
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
throw std::runtime_error(
|
auto skeleton = std::make_unique<rigging::SkeletonConfig>(
|
||||||
"unknown format " + util::quote(std::string(format))
|
std::move(*vcmModel.skeleton)
|
||||||
);
|
);
|
||||||
|
if (vcmModel.parts.size() > 1) {
|
||||||
|
for (auto& [partName, model] : vcmModel.parts) {
|
||||||
|
assets.store(
|
||||||
|
std::make_unique<model::Model>(std::move(model)),
|
||||||
|
name + "." + partName
|
||||||
|
);
|
||||||
|
}
|
||||||
|
for (auto& bone : skeleton->getBones()) {
|
||||||
|
bone->setModel(name + "." + bone->model.name);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assets.store(
|
||||||
|
std::make_unique<model::Model>(
|
||||||
|
std::move(vcmModel.parts["root"])), name
|
||||||
|
);
|
||||||
|
skeleton->getRoot()->setModel(name);
|
||||||
|
}
|
||||||
|
assets.store(std::move(skeleton), skeletonName);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
#include "Chunk.hpp"
|
#include "Chunk.hpp"
|
||||||
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include "content/ContentReport.hpp"
|
#include "content/ContentReport.hpp"
|
||||||
#include "items/Inventory.hpp"
|
#include "items/Inventory.hpp"
|
||||||
#include "lighting/Lightmap.hpp"
|
#include "lighting/Lightmap.hpp"
|
||||||
#include "util/data_io.hpp"
|
#include "util/data_io.hpp"
|
||||||
#include "voxel.hpp"
|
#include "voxel.hpp"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
Chunk::Chunk(int xpos, int zpos, std::shared_ptr<Lightmap> lightmap)
|
Chunk::Chunk(int xpos, int zpos, std::shared_ptr<Lightmap> lightmap)
|
||||||
: x(xpos), z(zpos), lightmap(std::move(lightmap)) {
|
: x(xpos), z(zpos), lightmap(std::move(lightmap)) {
|
||||||
bottom = 0;
|
bottom = 0;
|
||||||
|
|
@ -40,6 +40,7 @@ void Chunk::addBlockInventory(
|
||||||
void Chunk::removeBlockInventory(uint x, uint y, uint z) {
|
void Chunk::removeBlockInventory(uint x, uint y, uint z) {
|
||||||
if (inventories.erase(vox_index(x, y, z))) {
|
if (inventories.erase(vox_index(x, y, z))) {
|
||||||
flags.unsaved = true;
|
flags.unsaved = true;
|
||||||
|
flags.inventoriesRemoved = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ public:
|
||||||
bool entities : 1;
|
bool entities : 1;
|
||||||
bool blocksData : 1;
|
bool blocksData : 1;
|
||||||
bool dirtyHeights : 1;
|
bool dirtyHeights : 1;
|
||||||
|
bool inventoriesRemoved : 1;
|
||||||
} flags {};
|
} flags {};
|
||||||
|
|
||||||
uint64_t lastRandomTickId = -1;
|
uint64_t lastRandomTickId = -1;
|
||||||
|
|
|
||||||
|
|
@ -183,7 +183,7 @@ void WorldRegions::put(Chunk* chunk, std::vector<ubyte> entitiesData) {
|
||||||
LIGHTMAP_DATA_LEN);
|
LIGHTMAP_DATA_LEN);
|
||||||
}
|
}
|
||||||
// Writing block inventories
|
// Writing block inventories
|
||||||
if (!chunk->inventories.empty()) {
|
if (!chunk->inventories.empty() || chunk->flags.inventoriesRemoved) {
|
||||||
uint datasize;
|
uint datasize;
|
||||||
auto data = write_inventories(chunk->inventories, datasize);
|
auto data = write_inventories(chunk->inventories, datasize);
|
||||||
put(chunk->x,
|
put(chunk->x,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue