aabb block shape WIP + common refactor

This commit is contained in:
MihailRis 2023-11-30 14:48:38 +03:00
parent 73d87ae451
commit 0c35eeb072
21 changed files with 177 additions and 76 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@ -22,10 +22,12 @@ Content* ContentBuilder::build() {
vector<Block*> blockDefsIndices;
for (const string& name : blockIds) {
Block* def = blockDefs[name];
def->id = blockDefsIndices.size();
// Generating runtime info
def->rt.id = blockDefsIndices.size();
def->rt.emissive = *((uint32_t*)def->emission);
// build hitbox grid 3d for raycasts
// building hitbox grid 3d for raycasts
const AABB& hitbox = def->hitbox;
for (uint gy = 0; gy < BLOCK_AABB_GRID; gy++) {
for (uint gz = 0; gz < BLOCK_AABB_GRID; gz++) {

View File

@ -106,6 +106,18 @@ void setup_definitions(ContentBuilder* builder) {
block = new Block("base:blue_lamp", "blue_lamp");
block->emission[2] = 15;
builder->add(block);
// block added for test
block = new Block("base:pane", "pane");
block->textureFaces[FACE_MX] = "pane_side";
block->textureFaces[FACE_PX] = "pane_side";
block->textureFaces[FACE_MY] = "pane_side_2";
block->textureFaces[FACE_PY] = "pane_side_2";
block->model = BlockModel::aabb;
block->hitbox.scale(vec3(1.0f, 1.0f, 0.2f), vec3(0.5f, 0.5f, 0.0f));
block->lightPassing = true;
block->skyLightPassing = true;
builder->add(block);
}
void setup_bindings() {

View File

@ -12,6 +12,8 @@
#include "../../window/input.h"
#include "../../window/Camera.h"
using glm::vec2;
using glm::vec3;
using std::string;
using std::shared_ptr;
using namespace gui;

View File

@ -11,6 +11,8 @@ using std::string;
using std::wstring;
using std::shared_ptr;
using glm::vec2;
using glm::vec3;
using glm::vec4;
#define KEY_ESCAPE 256
#define KEY_ENTER 257

View File

@ -171,7 +171,7 @@ void Panel::refresh() {
}
if (resizing_) {
if (maxLength_)
this->size(vec2(size.x, min(maxLength_, (int)(y+padding.w))));
this->size(vec2(size.x, glm::min(maxLength_, (int)(y+padding.w))));
else
this->size(vec2(size.x, y+padding.w));
}
@ -193,7 +193,7 @@ void Panel::refresh() {
bool increased = maxh > size.y;
if (resizing_) {
if (maxLength_)
this->size(vec2(min(maxLength_, (int)(x+padding.z)), size.y));
this->size(vec2(glm::min(maxLength_, (int)(x+padding.z)), size.y));
else
this->size(vec2(x+padding.z, size.y));
}

View File

@ -91,11 +91,15 @@ HudRenderer::HudRenderer(Engine* engine,
L" visible: "+std::to_wstring(level->chunks->visible);
})));
panel->add(shared_ptr<Label>(create_label([this](){
auto player = this->level->player;
auto indices = this->level->content->indices;
auto def = indices->getBlockDef(player->selectedVoxel.id);
std::wstringstream stream;
stream << std::hex << this->level->player->selectedVoxel.states;
auto player = this->level->player;
return L"block-selected: "+std::to_wstring(player->selectedVoxel.id)+
if (def) {
stream << L" (" << util::str2wstr_utf8(def->name) << L")";
}
return L"block: "+std::to_wstring(player->selectedVoxel.id)+
L" "+stream.str();
})));
panel->add(shared_ptr<Label>(create_label([this](){
@ -236,12 +240,17 @@ void HudRenderer::drawContentAccess(const GfxContext& ctx, Player* player) {
} else {
tint = vec4(1.0f);
}
if (cblock->model == BlockModel::block){
batch->blockSprite(x, y, icon_size, icon_size, &cache->getRegion(cblock->id, 0), tint);
} else if (cblock->model == BlockModel::xsprite){
batch->sprite(x, y, icon_size, icon_size, cache->getRegion(cblock->id, 3), tint);
}
drawBlockPreview(cblock, x, y, icon_size, icon_size, tint);
}
}
void HudRenderer::drawBlockPreview(const Block* def, float x, float y, float w, float h, vec4 tint) {
if (def->model == BlockModel::block){
batch->blockSprite(x, y, w, h, &cache->getRegion(def->rt.id, 0), tint);
} else if (def->model == BlockModel::aabb) {
batch->blockSprite(x, y, w, h, &cache->getRegion(def->rt.id, 0), tint, def->hitbox.size());
} else if (def->model == BlockModel::xsprite){
batch->sprite(x, y, w, h, cache->getRegion(def->rt.id, 3), tint);
}
}
@ -311,11 +320,7 @@ void HudRenderer::draw(const GfxContext& ctx){
{
Block* cblock = contentIds->getBlockDef(player->choosenBlock);
assert(cblock != nullptr);
if (cblock->model == BlockModel::block){
batch->blockSprite(width-56, uicamera->fov - 56, 48, 48, &cache->getRegion(cblock->id, 0), vec4(1.0f));
} else if (cblock->model == BlockModel::xsprite){
batch->sprite(width-56, uicamera->fov - 56, 48, 48, cache->getRegion(cblock->id, 3), vec4(1.0f));
}
drawBlockPreview(cblock, width - 56, uicamera->fov - 56, 48, 48, vec4(1.0f));
}
if (pause) {

View File

@ -4,11 +4,14 @@
#include <string>
#include <memory>
#include <glm/glm.hpp>
#include "../graphics/GfxContext.h"
class Batch2D;
class Camera;
class Level;
class Block;
class Assets;
class Player;
class Level;
@ -38,6 +41,8 @@ class HudRenderer {
gui::GUI* gui;
const ContentGfxCache* const cache;
WorldRenderer* renderer;
void drawBlockPreview(const Block* def, float x, float y, float w, float h, glm::vec4 tint);
public:
HudRenderer(Engine* engine,
Level* level,

View File

@ -7,6 +7,10 @@
#define VERTEX_SIZE 8
using glm::vec2;
using glm::vec3;
using glm::vec4;
Batch2D::Batch2D(size_t capacity) : capacity(capacity), offset(0), color(1.0f, 1.0f, 1.0f, 1.0f){
const vattr attrs[] = {
{2}, {2}, {4}, {0}
@ -47,8 +51,8 @@ void Batch2D::vertex(float x, float y,
buffer[index++] = a;
}
void Batch2D::vertex(vec2 point,
vec2 uvpoint,
float r, float g, float b, float a) {
vec2 uvpoint,
float r, float g, float b, float a) {
buffer[index++] = point.x;
buffer[index++] = point.y;
buffer[index++] = uvpoint.x;
@ -299,8 +303,11 @@ void Batch2D::sprite(float x, float y, float w, float h, int atlasRes, int index
rect(x, y, w, h, u, v, scale, scale, tint.r, tint.g, tint.b, tint.a);
}
void Batch2D::blockSprite(float x, float y, float w, float h, const UVRegion regions[], vec4 tint){
// TODO: rewrite it
#include <iostream>
void Batch2D::blockSprite(float x, float y, float w, float h, const UVRegion regions[], vec4 tint, vec3 size){
// TODO: replace it using actual 3D with ortho projection
float uu = (regions[3].u1);
float vu = (regions[3].v1);
@ -313,16 +320,24 @@ void Batch2D::blockSprite(float x, float y, float w, float h, const UVRegion reg
if (this->index + 18*VERTEX_SIZE >= capacity)
render();
float d = (w + h) * 0.5f;
float ar = 0.88f;
float ox = x + (w * 0.5f);
float sx = w * 0.5f * ar;
vec2 points[7] = {vec2(ox, y+(h*0.5f)),
vec2(ox-sx, y+(h*0.25f)),
vec2(ox, y),
vec2(ox+sx, y+(h*0.25f)),
vec2(ox+sx, y+(h*0.75f)),
vec2(ox, y+h),
vec2(ox-sx, y+(h*0.75f))};
float hh = h * 0.25f;
float ww = w * 0.25f;
float dd = d * 0.25f;
vec3 half = size * h * 0.25f;
y += hh * 2.0f;
vec2 points[7] = {vec2(ox-ww+half.x+dd-half.z, y+hh-half.y), // center
vec2(ox-sx+ww-half.x+dd-half.z, y-half.y+ww-half.x), // left
vec2(ox+ww-half.x-dd+half.z, y-hh-half.y+ww-half.x+dd-half.z), // top
vec2(ox+sx-ww+half.x-dd+half.z, y-half.y+dd-half.z), // right
vec2(ox+sx-ww+half.x-dd+half.z, y+half.y+dd-half.z), // b-right
vec2(ox-ww+half.x+dd-half.z, y+hh+half.y), // bottom
vec2(ox-sx+ww-half.x+dd-half.z, y+half.y+ww-half.x)}; // b-left
vec2 uvpoints[8] = {vec2(uu, vu),
vec2(uu+scalex, vu),

View File

@ -6,8 +6,6 @@
#include "UVRegion.h"
using namespace glm;
class Mesh;
class Texture;
class Sprite;
@ -25,8 +23,8 @@ class Batch2D {
void vertex(float x, float y,
float u, float v,
float r, float g, float b, float a);
void vertex(vec2 point,
vec2 uvpoint,
void vertex(glm::vec2 point,
glm::vec2 uvpoint,
float r, float g, float b, float a);
public:
@ -37,10 +35,10 @@ public:
void begin();
void texture(Texture* texture);
void sprite(float x, float y, float w, float h, const UVRegion& region, vec4 tint);
void sprite(float x, float y, float w, float h, const UVRegion& region, glm::vec4 tint);
void sprite(Sprite* sprite);
void sprite(float x, float y, float w, float h, int atlasRes, int index, vec4 tint);
void blockSprite(float x, float y, float w, float h, const UVRegion regions[], vec4 tint);
void sprite(float x, float y, float w, float h, int atlasRes, int index, glm::vec4 tint);
void blockSprite(float x, float y, float w, float h, const UVRegion regions[], glm::vec4 tint, glm::vec3 size=glm::vec3(1.0f, 1.0f, 1.0f));
void point(float x, float y, float r, float g, float b, float a);
void line(float x1, float y1, float x2, float y2, float r, float g, float b, float a);
void rect(float x, float y,
@ -48,7 +46,7 @@ public:
float ox, float oy,
float angle, UVRegion region,
bool flippedX, bool flippedY,
vec4 tint);
glm::vec4 tint);
void rect(float x, float y, float w, float h);
void rect(float x, float y, float w, float h,

View File

@ -189,6 +189,57 @@ void BlocksRenderer::blockXSprite(int x, int y, int z, const vec3& size, const U
vec3(-1.0f, 0, 1.0f), vec3(0, 1, 0), texface2, lights, do_tint(0.8f));
}
void BlocksRenderer::blockCubeShaded(const vec3& pos, const vec3& size, const UVRegion(&texfaces)[6], const Block* block, ubyte states) {
int rot = 0;
float x = pos.x;
float y = pos.y;
float z = pos.z;
{
vec4 lights[]{
pickSoftLight(x, y, z + 1, {1, 0, 0}, {0, 1, 0}),
pickSoftLight(x + 1, y, z + 1, {1, 0, 0}, {0, 1, 0}),
pickSoftLight(x + 1, y + 1, z + 1, {1, 0, 0}, {0, 1, 0}),
pickSoftLight(x, y + 1, z + 1, {1, 0, 0}, {0, 1, 0}) };
face(vec3(x, y, z), size.x, size.y, vec3(1, 0, 0), vec3(0, 1, 0), texfaces[5], lights, do_tint(0.9f), rot == 1);
} {
vec4 lights[]{
pickSoftLight(pos.x, pos.y, pos.z - 1, {-1, 0, 0}, {0, 1, 0}),
pickSoftLight(pos.x - 1, pos.y, pos.z - 1, {-1, 0, 0}, {0, 1, 0}),
pickSoftLight(pos.x - 1, pos.y + 1, pos.z - 1, {-1, 0, 0}, {0, 1, 0}),
pickSoftLight(pos.x, pos.y + 1, pos.z - 1, {-1, 0, 0}, {0, 1, 0}) };
face(vec3(x + size.x, y, z - size.z), size.x, size.y, vec3(-1, 0, 0), vec3(0, 1, 0), texfaces[4], lights, do_tint(0.75f), rot == 1);
} {
vec4 lights[]{
pickSoftLight(x, pos.y + 1, pos.z + 1, {1, 0, 0}, {0, 0, 1}),
pickSoftLight(x + 1, pos.y + 1, pos.z + 1, {1, 0, 0}, {0, 0, 1}),
pickSoftLight(x + 1, pos.y + 1, pos.z, {1, 0, 0}, {0, 0, 1}),
pickSoftLight(x, pos.y + 1, pos.z, {1, 0, 0}, {0, 0, 1}) };
face(vec3(x, y + size.y, z), size.x, size.z, vec3(1, 0, 0), vec3(0, 0, -1), texfaces[3], lights, vec4(1.0f), rot == 1);
} {
vec4 lights[]{
pickSoftLight(pos.x, pos.y - 1, pos.z - 1, {1, 0, 0}, {0, 0, -1}),
pickSoftLight(pos.x + 1, y - 1, pos.z - 1, {1, 0, 0}, {0, 0,-1}),
pickSoftLight(pos.x + 1, y - 1, pos.z, {1, 0, 0}, {0, 0, -1}),
pickSoftLight(x, y - 1, z, {1, 0, 0}, {0, 0, -1}) };
face(vec3(x, y, z - size.z), size.x, size.z, vec3(1, 0, 0), vec3(0, 0, 1), texfaces[2], lights, do_tint(0.6f), rot == 1);
} {
vec4 lights[]{
pickSoftLight(x - 1, y, z - 1, {0, 0, -1}, {0, 1, 0}),
pickSoftLight(x - 1, y, z, {0, 0, -1}, {0, 1, 0}),
pickSoftLight(x - 1, y + 1, z, {0, 0, -1}, {0, 1, 0}),
pickSoftLight(x - 1, y + 1, z - 1, {0, 0, -1}, {0, 1, 0}) };
face(vec3(x, y, z - size.z), size.z, size.y, vec3(0, 0, 1), vec3(0, 1, 0), texfaces[0], lights, do_tint(0.7f), rot == 3);
} {
vec4 lights[]{
pickSoftLight(x + 1, y, z, {0, 0, -1}, {0, 1, 0}),
pickSoftLight(x + 1, y, z - 1, {0, 0, -1}, {0, 1, 0}),
pickSoftLight(x + 1, y + 1, z - 1, {0, 0, -1}, {0, 1, 0}),
pickSoftLight(x + 1, y + 1, z, {0, 0, -1}, {0, 1, 0}) };
face(vec3(x + size.x, y, z), size.z, size.y, vec3(0, 0, -1), vec3(0, 1, 0), texfaces[1], lights, do_tint(0.8f), rot == 3);
}
}
void BlocksRenderer::blockCubeShaded(int x, int y, int z, const vec3& size, const UVRegion(&texfaces_)[6], const Block* block, ubyte states) {
ubyte group = block->drawGroup;
UVRegion texfaces[6];
@ -277,7 +328,7 @@ bool BlocksRenderer::isOpen(int x, int y, int z, ubyte group) const {
if (id == BLOCK_VOID)
return false;
const Block& block = *blockDefsCache[id];
if (block.drawGroup != group && block.lightPassing) {
if ((block.drawGroup != group && block.lightPassing) || !block.rt.solid) {
return true;
}
return !id;
@ -315,6 +366,11 @@ vec4 BlocksRenderer::pickSoftLight(int x, int y, int z,
pickLight(x - right.x, y - right.y, z - right.z)) * 0.25f;
}
vec4 BlocksRenderer::pickSoftLight(float x, float y, float z,
const ivec3& right, const ivec3& up) const {
return pickSoftLight(int(round(x)), int(round(y)), int(round(z)), right, up);
}
void BlocksRenderer::render(const voxel* voxels, int atlas_size) {
int begin = chunk->bottom * (CHUNK_W * CHUNK_D);
int end = chunk->top * (CHUNK_W * CHUNK_D);
@ -344,6 +400,14 @@ void BlocksRenderer::render(const voxel* voxels, int atlas_size) {
blockXSprite(x, y, z, vec3(1.0f), texfaces[FACE_MX], texfaces[FACE_MZ], 1.0f);
break;
}
case BlockModel::aabb: {
vec3 size = def.hitbox.size();
vec3 off = def.hitbox.min();
off.z *= -1.0f;
off.z = -1.0f-off.z + size.z;
blockCubeShaded(off+vec3(x,y,z), size, texfaces, &def, vox.states);
break;
}
default:
break;
}

View File

@ -63,6 +63,7 @@ class BlocksRenderer {
void cube(const glm::vec3& coord, const glm::vec3& size, const UVRegion(&faces)[6]);
void blockCube(int x, int y, int z, const glm::vec3& size, const UVRegion(&faces)[6], ubyte group);
void blockCubeShaded(int x, int y, int z, const glm::vec3& size, const UVRegion(&faces)[6], const Block* block, ubyte states);
void blockCubeShaded(const glm::vec3& pos, const glm::vec3& size, const UVRegion(&faces)[6], const Block* block, ubyte states);
void blockXSprite(int x, int y, int z, const glm::vec3& size, const UVRegion& face1, const UVRegion& face2, float spread);
bool isOpenForLight(int x, int y, int z) const;
@ -70,6 +71,7 @@ class BlocksRenderer {
glm::vec4 pickLight(int x, int y, int z) const;
glm::vec4 pickSoftLight(int x, int y, int z, const glm::ivec3& right, const glm::ivec3& up) const;
glm::vec4 pickSoftLight(float x, float y, float z, const glm::ivec3& right, const glm::ivec3& up) const;
void render(const voxel* voxels, int atlas_size);
public:
BlocksRenderer(size_t capacity, const Content* content, const ContentGfxCache* cache, const EngineSettings& settings);

View File

@ -2,6 +2,8 @@
#include "Texture.h"
#include "Batch2D.h"
using glm::vec4;
Font::Font(std::vector<Texture*> pages, int lineHeight) : lineHeight_(lineHeight), pages(pages) {
}
@ -10,22 +12,6 @@ Font::~Font(){
delete texture;
}
// int Font::getGlyphWidth(char c) {
// switch (c){
// case 'l':
// case 'i':
// case 'j':
// case '|':
// case '.':
// case ',':
// case ':':
// case ';': return 7;
// case 't': return 8;
// case ' ': return 7;
// }
// return 7;
// }
int Font::lineHeight() const {
return lineHeight_;
}

View File

@ -4,10 +4,12 @@
#include "ImageData.h"
Texture::Texture(unsigned int id, int width, int height) : id(id), width(width), height(height) {
Texture::Texture(uint id, int width, int height)
: id(id), width(width), height(height) {
}
Texture::Texture(unsigned char* data, int width, int height, uint format) : width(width), height(height) {
Texture::Texture(ubyte* data, int width, int height, uint format)
: width(width), height(height) {
glGenTextures(1, &id);
glBindTexture(GL_TEXTURE_2D, id);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
@ -28,7 +30,7 @@ void Texture::bind(){
glBindTexture(GL_TEXTURE_2D, id);
}
void Texture::reload(unsigned char* data){
void Texture::reload(ubyte* data){
glBindTexture(GL_TEXTURE_2D, id);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *) data);
@ -36,6 +38,8 @@ void Texture::reload(unsigned char* data){
}
Texture* Texture::from(const ImageData* image) {
uint width = image->getWidth();
uint height = image->getHeight();
uint format;
const void* data = image->getData();
switch (image->getFormat()) {
@ -44,5 +48,5 @@ Texture* Texture::from(const ImageData* image) {
default:
throw std::runtime_error("unsupported image data format");
}
return new Texture((unsigned char*)data, image->getWidth(), image->getHeight(), format);
return new Texture((ubyte*)data, width, height, format);
}

View File

@ -8,15 +8,15 @@ class ImageData;
class Texture {
public:
unsigned int id;
uint id;
int width;
int height;
Texture(unsigned int id, int width, int height);
Texture(unsigned char* data, int width, int height, uint format);
Texture(uint id, int width, int height);
Texture(ubyte* data, int width, int height, uint format);
~Texture();
void bind();
void reload(unsigned char* data);
void reload(ubyte* data);
static Texture* from(const ImageData* image);
};

View File

@ -180,7 +180,7 @@ void PlayerController::updateControls(float delta){
}
void PlayerController::updateInteraction(){
const ContentIndices* contentIds = level->contentIds;
auto contentIds = level->content->indices;
Chunks* chunks = level->chunks;
Player* player = level->player;
Lighting* lighting = level->lighting;

View File

@ -4,6 +4,7 @@
#include <string>
#include "../maths/aabb.h"
#include "../typedefs.h"
#define FACE_MX 0
#define FACE_PX 1
@ -15,13 +16,15 @@
#define BLOCK_AABB_GRID 16
enum class BlockModel {
none, block, xsprite
none, // invisible
block, // default shape
xsprite, // X-shape (grass)
aabb // box shaped as block hitbox
};
class Block {
public:
std::string const name;
unsigned int id;
// 0 1 2 3 4 5
std::string textureFaces[6]; // -x,x, -y,y, -z,z
unsigned char emission[4];
@ -36,6 +39,7 @@ public:
AABB hitbox;
struct {
blockid_t id;
bool solid = true;
bool emissive = false;
bool hitboxGrid[BLOCK_AABB_GRID][BLOCK_AABB_GRID][BLOCK_AABB_GRID];

View File

@ -97,16 +97,16 @@ float calc_height(fnl_state *noise, int real_x, int real_z){
}
WorldGenerator::WorldGenerator(const Content* content)
: idStone(content->require("base:stone")->id),
idDirt(content->require("base:dirt")->id),
idGrassBlock(content->require("base:grass_block")->id),
idSand(content->require("base:sand")->id),
idWater(content->require("base:water")->id),
idWood(content->require("base:wood")->id),
idLeaves(content->require("base:leaves")->id),
idGrass(content->require("base:grass")->id),
idFlower(content->require("base:flower")->id),
idBedrock(content->require("base:bedrock")->id) {;
: idStone(content->require("base:stone")->rt.id),
idDirt(content->require("base:dirt")->rt.id),
idGrassBlock(content->require("base:grass_block")->rt.id),
idSand(content->require("base:sand")->rt.id),
idWater(content->require("base:water")->rt.id),
idWood(content->require("base:wood")->rt.id),
idLeaves(content->require("base:leaves")->rt.id),
idGrass(content->require("base:grass")->rt.id),
idFlower(content->require("base:flower")->rt.id),
idBedrock(content->require("base:bedrock")->rt.id) {;
}
int generate_tree(fnl_state *noise,

View File

@ -17,10 +17,10 @@ class ChunksStorage;
class PlayerController;
class Level {
const ContentIndices* const contentIds;
public:
World* world;
const Content* const content;
const ContentIndices* const contentIds;
Player* player;
Chunks* chunks;
ChunksStorage* chunksStorage;