Add grow animation for newly created block meshes

master
Elias Fleckenstein 2021-09-29 21:30:48 +02:00
parent 98fa5e0c4e
commit 411b1eaaed
8 changed files with 66 additions and 39 deletions

View File

@ -14,7 +14,7 @@ static v3s8 fdir[6] = {
static s32 half_block_size = MAPBLOCK_SIZE / 2;
static void make_vertices(Object *object, MapBlock *block)
static void make_vertices(Object *object, MapBlock *block, bool hide_edges)
{
v3s32 node_bp = {block->pos.x * MAPBLOCK_SIZE, block->pos.y * MAPBLOCK_SIZE, block->pos.z * MAPBLOCK_SIZE};
@ -23,7 +23,7 @@ static void make_vertices(Object *object, MapBlock *block)
ClientNodeDefintion *def = &client_node_definitions[node->type];
if (def->visibility != NV_NONE) {
v3f32 offset = {x + (f32) MAPBLOCK_SIZE / 2.0f, y + (f32) MAPBLOCK_SIZE / 2.0f, z + (f32) MAPBLOCK_SIZE / 2.0f};
v3f32 offset = {x - half_block_size - 0.5, y - half_block_size - 0.5, z - half_block_size - 0.5};
for (int f = 0; f < 6; f++) {
v3s8 npos = {
@ -36,9 +36,11 @@ static void make_vertices(Object *object, MapBlock *block)
if (npos.x >= 0 && npos.x < MAPBLOCK_SIZE && npos.y >= 0 && npos.y < MAPBLOCK_SIZE && npos.z >= 0 && npos.z < MAPBLOCK_SIZE)
neighbor = block->data[npos.x][npos.y][npos.z].type;
else {
else if (hide_edges) {
MapNode nn = map_get_node(client_map.map, (v3s32) {npos.x + node_bp.x, npos.y + node_bp.y, npos.z + node_bp.z});
neighbor = nn.type;
} else {
neighbor = NODE_AIR;
}
if (neighbor != NODE_UNLOADED && client_node_definitions[neighbor].visibility != NV_SOLID && (def->visibility != NV_TRANSPARENT || neighbor != node->type)) {
@ -61,23 +63,40 @@ static void make_vertices(Object *object, MapBlock *block)
}
}
static void animate_mapblock_mesh(Object *obj, f64 dtime)
{
obj->scale.x += dtime * 2.0;
if (obj->scale.x > 1.0f) {
obj->scale.x = 1.0f;
client_map_schedule_update_block_mesh(obj->extra);
}
obj->scale.z = obj->scale.y = obj->scale.x;
object_transform(obj);
}
void blockmesh_make(MapBlock *block)
{
MapBlockExtraData *extra = block->extra;
Object *obj = object_create();
obj->pos = (v3f32) {block->pos.x * MAPBLOCK_SIZE - half_block_size, block->pos.y * MAPBLOCK_SIZE - half_block_size, block->pos.z * MAPBLOCK_SIZE - half_block_size};
obj->pos = (v3f32) {block->pos.x * MAPBLOCK_SIZE + half_block_size + 0.5f, block->pos.y * MAPBLOCK_SIZE + half_block_size + 0.5f, block->pos.z * MAPBLOCK_SIZE + half_block_size + 0.5f};
obj->scale = extra->obj ? extra->obj->scale : (v3f32) {0.1f, 0.1f, 0.1f};
obj->frustum_culling = false;
obj->box = (aabb3f32) {{-half_block_size, -half_block_size, -half_block_size}, {half_block_size, half_block_size, half_block_size}};
obj->on_render = (obj->scale.x == 1.0f) ? NULL : &animate_mapblock_mesh;
obj->extra = block;
make_vertices(obj, block);
make_vertices(obj, block, obj->scale.x == 1.0f);
if (! object_add_to_scene(obj)) {
object_delete(obj);
obj = NULL;
}
MapBlockExtraData *extra = block->extra;
if (extra->obj)
extra->obj->remove = true;

View File

@ -42,21 +42,6 @@ static void *meshgen_thread(unused void *arg)
return NULL;
}
// enqueue mesh to block update queue
static void schedule_update_block_mesh(MapBlock *block)
{
if (! block)
return;
pthread_mutex_lock(&block->mtx);
MapBlockExtraData *extra = block->extra;
if (! extra->queue) {
extra->queue = true;
queue_enqueue(client_map.queue, block);
}
pthread_mutex_unlock(&block->mtx);
}
// sync functions
// send block request command to server
@ -229,12 +214,27 @@ void client_map_block_received(MapBlock *block)
extra->state = MBS_FRESH;
pthread_mutex_unlock(&block->mtx);
schedule_update_block_mesh(block);
client_map_schedule_update_block_mesh(block);
schedule_update_block_mesh(map_get_block(client_map.map, (v3s32) {block->pos.x + 1, block->pos.y + 0, block->pos.z + 0}, false));
schedule_update_block_mesh(map_get_block(client_map.map, (v3s32) {block->pos.x + 0, block->pos.y + 1, block->pos.z + 0}, false));
schedule_update_block_mesh(map_get_block(client_map.map, (v3s32) {block->pos.x + 0, block->pos.y + 0, block->pos.z + 1}, false));
schedule_update_block_mesh(map_get_block(client_map.map, (v3s32) {block->pos.x - 1, block->pos.y - 0, block->pos.z - 0}, false));
schedule_update_block_mesh(map_get_block(client_map.map, (v3s32) {block->pos.x - 0, block->pos.y - 1, block->pos.z - 0}, false));
schedule_update_block_mesh(map_get_block(client_map.map, (v3s32) {block->pos.x - 0, block->pos.y - 0, block->pos.z - 1}, false));
client_map_schedule_update_block_mesh(map_get_block(client_map.map, (v3s32) {block->pos.x + 1, block->pos.y + 0, block->pos.z + 0}, false));
client_map_schedule_update_block_mesh(map_get_block(client_map.map, (v3s32) {block->pos.x + 0, block->pos.y + 1, block->pos.z + 0}, false));
client_map_schedule_update_block_mesh(map_get_block(client_map.map, (v3s32) {block->pos.x + 0, block->pos.y + 0, block->pos.z + 1}, false));
client_map_schedule_update_block_mesh(map_get_block(client_map.map, (v3s32) {block->pos.x - 1, block->pos.y - 0, block->pos.z - 0}, false));
client_map_schedule_update_block_mesh(map_get_block(client_map.map, (v3s32) {block->pos.x - 0, block->pos.y - 1, block->pos.z - 0}, false));
client_map_schedule_update_block_mesh(map_get_block(client_map.map, (v3s32) {block->pos.x - 0, block->pos.y - 0, block->pos.z - 1}, false));
}
// enqueue block to mesh update queue
void client_map_schedule_update_block_mesh(MapBlock *block)
{
if (! block)
return;
pthread_mutex_lock(&block->mtx);
MapBlockExtraData *extra = block->extra;
if (! extra->queue) {
extra->queue = true;
queue_enqueue(client_map.queue, block);
}
pthread_mutex_unlock(&block->mtx);
}

View File

@ -39,5 +39,6 @@ void client_map_set_simulation_distance(u32 simulation_distance); // update simu
void client_map_start(); // start meshgen and sync threads
void client_map_stop(); // stop meshgen and sync threads
void client_map_block_received(MapBlock *block); // called when a block was actually recieved from server
void client_map_schedule_update_block_mesh(MapBlock *block); // enqueue block to mesh update queue
#endif

View File

@ -39,7 +39,7 @@ static void crosshair_init()
});
}
static void render()
static void render(f64 dtime)
{
glEnable(GL_DEPTH_TEST);
glEnable(GL_ALPHA_TEST);
@ -53,7 +53,7 @@ static void render()
glFrontFace(GL_CCW);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
scene_render();
scene_render(dtime);
glDisable(GL_CULL_FACE);
sky_render();
@ -90,7 +90,7 @@ static void game_loop(Client *client)
debug_menu_update_daylight();
debug_menu_update_sun_angle();
render();
render(dtime);
glfwSwapBuffers(window.handle);
glfwPollEvents();
@ -190,7 +190,7 @@ void take_screenshot()
// render scene
glBindFramebuffer(GL_FRAMEBUFFER, FBOs[0]);
render();
render(0.0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// blit AA-buffer into no-AA buffer

View File

@ -60,6 +60,8 @@ Object *object_create()
obj->frustum_culling = false;
obj->current_face = NULL;
obj->faces = array_create(sizeof(ObjectFace));
obj->on_render = NULL;
obj->extra = NULL;
return obj;
}
@ -204,8 +206,11 @@ static bool inside_frustum(aabb3f32 box, mat4x4 MVP)
#pragma GCC diagnostic pop
void object_render(Object *obj)
void object_render(Object *obj, f64 dtime)
{
if (obj->on_render)
obj->on_render(obj, dtime);
if (! obj->visible)
return;

View File

@ -45,7 +45,7 @@ typedef struct
Array vertices;
} ObjectFace;
typedef struct
typedef struct Object
{
v3f32 pos, rot, scale;
f32 angle;
@ -59,6 +59,8 @@ typedef struct
aabb3f32 box;
ObjectFace *current_face;
Array faces;
void (*on_render)(struct Object *obj, f64 dtime);
void *extra;
} Object;
Object *object_create();
@ -67,6 +69,6 @@ void object_set_texture(Object *obj, Texture *texture);
void object_add_vertex(Object *obj, Vertex3D *vertex);
bool object_add_to_scene(Object *obj);
void object_transform(Object *obj);
void object_render(Object *obj);
void object_render(Object *obj, f64 dtime);
#endif

View File

@ -61,7 +61,7 @@ void scene_add_object(Object *obj)
pthread_mutex_unlock(&scene.mtx);
}
void scene_render()
void scene_render(f64 dtime)
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
@ -91,7 +91,7 @@ void scene_render()
free(pair);
object_delete(obj);
} else {
object_render(obj);
object_render(obj, dtime);
pairptr = &pair->next;
}
}

View File

@ -28,7 +28,7 @@ extern struct Scene
bool scene_init();
void scene_deinit();
void scene_add_object(Object *obj);
void scene_render();
void scene_render(f64 dtime);
void scene_on_resize(int width, int height);
GLuint scene_get_max_texture_units();
void scene_get_view_proj(mat4x4 target);