Merge branch 'dev' into more-about-projects
This commit is contained in:
commit
dc0e388eec
@ -119,13 +119,13 @@ block.seek_origin(x: int, y: int, z: int) -> int, int, int
|
|||||||
|
|
||||||
Part of a voxel data used for scripting. Size: 8 bit.
|
Part of a voxel data used for scripting. Size: 8 bit.
|
||||||
|
|
||||||
```python
|
```lua
|
||||||
block.get_user_bits(x: int, y: int, z: int, offset: int, bits: int) -> int
|
block.get_user_bits(x: int, y: int, z: int, offset: int, bits: int) -> int
|
||||||
```
|
```
|
||||||
|
|
||||||
Get specified bits as an unsigned integer.
|
Get specified bits as an unsigned integer.
|
||||||
|
|
||||||
```python
|
```lua
|
||||||
block.set_user_bits(x: int, y: int, z: int, offset: int, bits: int, value: int) -> int
|
block.set_user_bits(x: int, y: int, z: int, offset: int, bits: int, value: int) -> int
|
||||||
```
|
```
|
||||||
Set specified bits.
|
Set specified bits.
|
||||||
@ -151,6 +151,21 @@ The function returns a table with the results or nil if the ray does not hit any
|
|||||||
|
|
||||||
The result will use the destination table instead of creating a new one if the optional argument specified.
|
The result will use the destination table instead of creating a new one if the optional argument specified.
|
||||||
|
|
||||||
|
## Model
|
||||||
|
|
||||||
|
Block model information.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
-- returns block model type (block/aabb/custom/...)
|
||||||
|
block.get_model(id: int) -> str
|
||||||
|
|
||||||
|
-- returns block model name
|
||||||
|
block.model_name(id: int) -> str
|
||||||
|
|
||||||
|
-- returns array of 6 textures assigned to sides of block
|
||||||
|
block.get_textures(id: int) -> string table
|
||||||
|
```
|
||||||
|
|
||||||
## Data fields
|
## Data fields
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
|
|||||||
@ -171,6 +171,9 @@ block.get_hitbox(id: int, rotation_index: int) -> {vec3, vec3}
|
|||||||
-- возвращает тип модели блока (block/aabb/custom/...)
|
-- возвращает тип модели блока (block/aabb/custom/...)
|
||||||
block.get_model(id: int) -> str
|
block.get_model(id: int) -> str
|
||||||
|
|
||||||
|
-- возвращает имя модели блока
|
||||||
|
block.model_name(id: int) -> str
|
||||||
|
|
||||||
-- возвращает массив из 6 текстур, назначенных на стороны блока
|
-- возвращает массив из 6 текстур, назначенных на стороны блока
|
||||||
block.get_textures(id: int) -> таблица строк
|
block.get_textures(id: int) -> таблица строк
|
||||||
```
|
```
|
||||||
|
|||||||
69
flake.nix
69
flake.nix
@ -1,16 +1,69 @@
|
|||||||
{
|
{
|
||||||
|
description = "VoxelCore – voxel game engine in C++";
|
||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||||
flake-utils.url = "github:numtide/flake-utils";
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, nixpkgs, flake-utils }:
|
outputs =
|
||||||
flake-utils.lib.eachDefaultSystem (system: {
|
{
|
||||||
devShells.default = with nixpkgs.legacyPackages.${system}; mkShell {
|
self,
|
||||||
nativeBuildInputs = [ cmake pkg-config ];
|
nixpkgs,
|
||||||
buildInputs = [ glm glfw glew zlib libpng libvorbis openal luajit curl ]; # libglvnd
|
flake-utils,
|
||||||
packages = [ glfw mesa freeglut entt ];
|
}:
|
||||||
LD_LIBRARY_PATH = "${wayland}/lib:$LD_LIBRARY_PATH";
|
flake-utils.lib.eachDefaultSystem (
|
||||||
|
system:
|
||||||
|
let
|
||||||
|
pkgs = import nixpkgs { inherit system; };
|
||||||
|
voxel-core = pkgs.stdenv.mkDerivation {
|
||||||
|
name = "voxel-core";
|
||||||
|
|
||||||
|
src = ./.;
|
||||||
|
|
||||||
|
nativeBuildInputs = with pkgs; [
|
||||||
|
cmake
|
||||||
|
pkg-config
|
||||||
|
];
|
||||||
|
|
||||||
|
buildInputs = with pkgs; [
|
||||||
|
glm
|
||||||
|
glfw
|
||||||
|
glew
|
||||||
|
zlib
|
||||||
|
libpng
|
||||||
|
libvorbis
|
||||||
|
openal
|
||||||
|
luajit
|
||||||
|
curl
|
||||||
|
entt
|
||||||
|
mesa
|
||||||
|
freeglut
|
||||||
|
]; # libglvnd
|
||||||
|
|
||||||
|
packages = with pkgs; [
|
||||||
|
glfw
|
||||||
|
mesa
|
||||||
|
freeglut
|
||||||
|
entt
|
||||||
|
];
|
||||||
|
cmakeFlags = [
|
||||||
|
"-DCMAKE_PREFIX_PATH=${pkgs.entt}"
|
||||||
|
"-DCMAKE_INCLUDE_PATH=${pkgs.entt}/include"
|
||||||
|
];
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
cp VoxelEngine $out/bin/
|
||||||
|
'';
|
||||||
};
|
};
|
||||||
});
|
in
|
||||||
|
{
|
||||||
|
packages.default = voxel-core;
|
||||||
|
apps.default = {
|
||||||
|
type = "app";
|
||||||
|
program = "${voxel-core}/bin/VoxelCore";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -538,6 +538,7 @@ void Hud::closeInventory() {
|
|||||||
exchangeSlotInv = nullptr;
|
exchangeSlotInv = nullptr;
|
||||||
inventoryOpen = false;
|
inventoryOpen = false;
|
||||||
inventoryView = nullptr;
|
inventoryView = nullptr;
|
||||||
|
secondInvView = nullptr;
|
||||||
secondUI = nullptr;
|
secondUI = nullptr;
|
||||||
|
|
||||||
for (auto& element : elements) {
|
for (auto& element : elements) {
|
||||||
@ -597,6 +598,9 @@ void Hud::remove(const std::shared_ptr<UINode>& node) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
cleanup();
|
cleanup();
|
||||||
|
if (node == secondUI) {
|
||||||
|
closeInventory();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hud::setDebug(bool flag) {
|
void Hud::setDebug(bool flag) {
|
||||||
|
|||||||
@ -126,7 +126,15 @@ void Batch3D::sprite(
|
|||||||
float scale = 1.0f / static_cast<float>(atlasRes);
|
float scale = 1.0f / static_cast<float>(atlasRes);
|
||||||
float u = (index % atlasRes) * scale;
|
float u = (index % atlasRes) * scale;
|
||||||
float v = 1.0f - ((index / atlasRes) * scale) - scale;
|
float v = 1.0f - ((index / atlasRes) * scale) - scale;
|
||||||
sprite(pos, up, right, w, h, UVRegion(u, v, u+scale, v+scale), tint);
|
sprite(
|
||||||
|
pos + right * w + up * h, // revert centering
|
||||||
|
up,
|
||||||
|
right,
|
||||||
|
w,
|
||||||
|
h,
|
||||||
|
UVRegion(u, v, u + scale, v + scale),
|
||||||
|
tint
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Batch3D::sprite(
|
void Batch3D::sprite(
|
||||||
|
|||||||
@ -171,6 +171,9 @@ const Mesh<ChunkVertex>* ChunksRenderer::retrieveChunk(
|
|||||||
if (mesh == nullptr) {
|
if (mesh == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
if (chunk->flags.dirtyHeights) {
|
||||||
|
chunk->updateHeights();
|
||||||
|
}
|
||||||
if (culling) {
|
if (culling) {
|
||||||
glm::vec3 min(chunk->x * CHUNK_W, chunk->bottom, chunk->z * CHUNK_D);
|
glm::vec3 min(chunk->x * CHUNK_W, chunk->bottom, chunk->z * CHUNK_D);
|
||||||
glm::vec3 max(
|
glm::vec3 max(
|
||||||
|
|||||||
@ -51,6 +51,7 @@ void TextsRenderer::renderNote(
|
|||||||
glm::vec3 yvec = note.getAxisY();
|
glm::vec3 yvec = note.getAxisY();
|
||||||
|
|
||||||
int width = font.calcWidth(text, text.length());
|
int width = font.calcWidth(text, text.length());
|
||||||
|
int height = font.getLineHeight();
|
||||||
if (preset.displayMode == NoteDisplayMode::Y_FREE_BILLBOARD ||
|
if (preset.displayMode == NoteDisplayMode::Y_FREE_BILLBOARD ||
|
||||||
preset.displayMode == NoteDisplayMode::XY_FREE_BILLBOARD) {
|
preset.displayMode == NoteDisplayMode::XY_FREE_BILLBOARD) {
|
||||||
xvec = camera.position - pos;
|
xvec = camera.position - pos;
|
||||||
@ -96,8 +97,11 @@ void TextsRenderer::renderNote(
|
|||||||
|
|
||||||
pos = screenPos / screenPos.w;
|
pos = screenPos / screenPos.w;
|
||||||
}
|
}
|
||||||
} else if (!frustum.isBoxVisible(pos - xvec * (width * 0.5f * preset.scale),
|
} else if (!frustum.isBoxVisible(
|
||||||
pos + xvec * (width * 0.5f * preset.scale))) {
|
pos - xvec * (width * 0.5f) * preset.scale,
|
||||||
|
pos + xvec * (width * 0.5f) * preset.scale +
|
||||||
|
yvec * static_cast<float>(height) * preset.scale
|
||||||
|
)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto color = preset.color;
|
auto color = preset.color;
|
||||||
|
|||||||
@ -54,7 +54,7 @@ static int l_get_gravity_scale(lua::State* L) {
|
|||||||
|
|
||||||
static int l_set_gravity_scale(lua::State* L) {
|
static int l_set_gravity_scale(lua::State* L) {
|
||||||
if (auto entity = get_entity(L, 1)) {
|
if (auto entity = get_entity(L, 1)) {
|
||||||
entity->getRigidbody().hitbox.gravityScale = lua::tonumber(L, 2);
|
entity->getRigidbody().hitbox.gravityScale = lua::tovec3(L, 2).y;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -101,12 +101,9 @@ static int l_set(lua::State* L) {
|
|||||||
if (static_cast<size_t>(id) >= indices->blocks.count()) {
|
if (static_cast<size_t>(id) >= indices->blocks.count()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int cx = floordiv<CHUNK_W>(x);
|
if (!blocks_agent::set(*level->chunks, x, y, z, id, int2blockstate(state))) {
|
||||||
int cz = floordiv<CHUNK_D>(z);
|
|
||||||
if (!blocks_agent::get_chunk(*level->chunks, cx, cz)) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
blocks_agent::set(*level->chunks, x, y, z, id, int2blockstate(state));
|
|
||||||
|
|
||||||
auto chunksController = controller->getChunksController();
|
auto chunksController = controller->getChunksController();
|
||||||
if (chunksController == nullptr) {
|
if (chunksController == nullptr) {
|
||||||
@ -364,6 +361,19 @@ static int l_get_textures(lua::State* L) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int l_model_name(lua::State* L) {
|
||||||
|
if (auto def = require_block(L)) {
|
||||||
|
// TODO: variant argument
|
||||||
|
const auto& modelName = def->defaults.model.name;
|
||||||
|
if (modelName.empty()) {
|
||||||
|
return lua::pushlstring(L, def->name + ".model");
|
||||||
|
}
|
||||||
|
return lua::pushlstring(L, modelName);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int l_get_model(lua::State* L) {
|
static int l_get_model(lua::State* L) {
|
||||||
if (auto def = require_block(L)) {
|
if (auto def = require_block(L)) {
|
||||||
// TODO: variant argument
|
// TODO: variant argument
|
||||||
@ -713,6 +723,7 @@ const luaL_Reg blocklib[] = {
|
|||||||
{"get_size", lua::wrap<l_get_size>},
|
{"get_size", lua::wrap<l_get_size>},
|
||||||
{"is_segment", lua::wrap<l_is_segment>},
|
{"is_segment", lua::wrap<l_is_segment>},
|
||||||
{"seek_origin", lua::wrap<l_seek_origin>},
|
{"seek_origin", lua::wrap<l_seek_origin>},
|
||||||
|
{"model_name", lua::wrap<l_model_name>},
|
||||||
{"get_textures", lua::wrap<l_get_textures>},
|
{"get_textures", lua::wrap<l_get_textures>},
|
||||||
{"get_model", lua::wrap<l_get_model>},
|
{"get_model", lua::wrap<l_get_model>},
|
||||||
{"get_hitbox", lua::wrap<l_get_hitbox>},
|
{"get_hitbox", lua::wrap<l_get_hitbox>},
|
||||||
|
|||||||
@ -46,7 +46,7 @@ static int l_open(lua::State* L) {
|
|||||||
}
|
}
|
||||||
return lua::pushinteger(L, hud->openInventory(
|
return lua::pushinteger(L, hud->openInventory(
|
||||||
layout,
|
layout,
|
||||||
level->inventories->get(invid),
|
lua::isnoneornil(L, 3) ? nullptr : level->inventories->get(invid),
|
||||||
playerInventory
|
playerInventory
|
||||||
)->getId());
|
)->getId());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@ Chunk::Chunk(int xpos, int zpos) : x(xpos), z(zpos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Chunk::updateHeights() {
|
void Chunk::updateHeights() {
|
||||||
|
flags.dirtyHeights = false;
|
||||||
for (uint i = 0; i < CHUNK_VOL; i++) {
|
for (uint i = 0; i < CHUNK_VOL; i++) {
|
||||||
if (voxels[i].id != 0) {
|
if (voxels[i].id != 0) {
|
||||||
bottom = i / (CHUNK_D * CHUNK_W);
|
bottom = i / (CHUNK_D * CHUNK_W);
|
||||||
|
|||||||
@ -37,6 +37,7 @@ public:
|
|||||||
bool loadedLights : 1;
|
bool loadedLights : 1;
|
||||||
bool entities : 1;
|
bool entities : 1;
|
||||||
bool blocksData : 1;
|
bool blocksData : 1;
|
||||||
|
bool dirtyHeights : 1;
|
||||||
} flags {};
|
} flags {};
|
||||||
|
|
||||||
/// @brief Block inventories map where key is index of block in voxels array
|
/// @brief Block inventories map where key is index of block in voxels array
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
using namespace blocks_agent;
|
using namespace blocks_agent;
|
||||||
|
|
||||||
template <class Storage>
|
template <class Storage>
|
||||||
static inline void set_block(
|
static inline bool set_block(
|
||||||
Storage& chunks,
|
Storage& chunks,
|
||||||
int32_t x,
|
int32_t x,
|
||||||
int32_t y,
|
int32_t y,
|
||||||
@ -16,14 +16,14 @@ static inline void set_block(
|
|||||||
blockstate state
|
blockstate state
|
||||||
) {
|
) {
|
||||||
if (y < 0 || y >= CHUNK_H) {
|
if (y < 0 || y >= CHUNK_H) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
const auto& indices = chunks.getContentIndices();
|
const auto& indices = chunks.getContentIndices();
|
||||||
int cx = floordiv<CHUNK_W>(x);
|
int cx = floordiv<CHUNK_W>(x);
|
||||||
int cz = floordiv<CHUNK_D>(z);
|
int cz = floordiv<CHUNK_D>(z);
|
||||||
Chunk* chunk = get_chunk(chunks, cx, cz);
|
Chunk* chunk = get_chunk(chunks, cx, cz);
|
||||||
if (chunk == nullptr) {
|
if (chunk == nullptr) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
int lx = x - cx * CHUNK_W;
|
int lx = x - cx * CHUNK_W;
|
||||||
int lz = z - cz * CHUNK_D;
|
int lz = z - cz * CHUNK_D;
|
||||||
@ -60,7 +60,8 @@ static inline void set_block(
|
|||||||
else if (y + 1 > chunk->top)
|
else if (y + 1 > chunk->top)
|
||||||
chunk->top = y + 1;
|
chunk->top = y + 1;
|
||||||
else if (id == 0)
|
else if (id == 0)
|
||||||
chunk->updateHeights();
|
chunk->flags.dirtyHeights = true;
|
||||||
|
|
||||||
|
|
||||||
if (lx == 0 && (chunk = get_chunk(chunks, cx - 1, cz))) {
|
if (lx == 0 && (chunk = get_chunk(chunks, cx - 1, cz))) {
|
||||||
chunk->flags.modified = true;
|
chunk->flags.modified = true;
|
||||||
@ -74,9 +75,10 @@ static inline void set_block(
|
|||||||
if (lz == CHUNK_D - 1 && (chunk = get_chunk(chunks, cx, cz + 1))) {
|
if (lz == CHUNK_D - 1 && (chunk = get_chunk(chunks, cx, cz + 1))) {
|
||||||
chunk->flags.modified = true;
|
chunk->flags.modified = true;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void blocks_agent::set(
|
bool blocks_agent::set(
|
||||||
Chunks& chunks,
|
Chunks& chunks,
|
||||||
int32_t x,
|
int32_t x,
|
||||||
int32_t y,
|
int32_t y,
|
||||||
@ -84,10 +86,10 @@ void blocks_agent::set(
|
|||||||
uint32_t id,
|
uint32_t id,
|
||||||
blockstate state
|
blockstate state
|
||||||
) {
|
) {
|
||||||
set_block(chunks, x, y, z, id, state);
|
return set_block(chunks, x, y, z, id, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void blocks_agent::set(
|
bool blocks_agent::set(
|
||||||
GlobalChunks& chunks,
|
GlobalChunks& chunks,
|
||||||
int32_t x,
|
int32_t x,
|
||||||
int32_t y,
|
int32_t y,
|
||||||
@ -95,7 +97,7 @@ void blocks_agent::set(
|
|||||||
uint32_t id,
|
uint32_t id,
|
||||||
blockstate state
|
blockstate state
|
||||||
) {
|
) {
|
||||||
set_block(chunks, x, y, z, id, state);
|
return set_block(chunks, x, y, z, id, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Storage>
|
template <class Storage>
|
||||||
|
|||||||
@ -119,7 +119,7 @@ inline bool is_replaceable_at(const Storage& chunks, int32_t x, int32_t y, int32
|
|||||||
/// @param z block position Z
|
/// @param z block position Z
|
||||||
/// @param id new block id
|
/// @param id new block id
|
||||||
/// @param state new block state
|
/// @param state new block state
|
||||||
void set(
|
bool set(
|
||||||
Chunks& chunks,
|
Chunks& chunks,
|
||||||
int32_t x,
|
int32_t x,
|
||||||
int32_t y,
|
int32_t y,
|
||||||
@ -135,7 +135,7 @@ void set(
|
|||||||
/// @param z block position Z
|
/// @param z block position Z
|
||||||
/// @param id new block id
|
/// @param id new block id
|
||||||
/// @param state new block state
|
/// @param state new block state
|
||||||
void set(
|
bool set(
|
||||||
GlobalChunks& chunks,
|
GlobalChunks& chunks,
|
||||||
int32_t x,
|
int32_t x,
|
||||||
int32_t y,
|
int32_t y,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user