Add grow animation for newly created block meshes
parent
98fa5e0c4e
commit
411b1eaaed
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue