]> git.lizzy.rs Git - dragonblocks_alpha.git/commitdiff
Add grow animation for newly created block meshes
authorElias Fleckenstein <eliasfleckenstein@web.de>
Wed, 29 Sep 2021 19:30:48 +0000 (21:30 +0200)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Wed, 29 Sep 2021 19:30:48 +0000 (21:30 +0200)
src/client/blockmesh.c
src/client/client_map.c
src/client/client_map.h
src/client/game.c
src/client/object.c
src/client/object.h
src/client/scene.c
src/client/scene.h

index 26ca2bacea878275bc7d2a41debd408afcbb445b..f822092d7b71577812e4484ea139b4bcc7ef446c 100644 (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;
 
index ca1bfafbd2774cae7ea4061f126b29d409c521c4..6524573b4872b3f84e2a3db3622693c641114f3e 100644 (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);
 }
index ce4056b9cdb280850ea5533b6e5a279d78522964..8f75da896a832d5623d3f03bb9475a4457b09837 100644 (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
index 0f66bf03ee8b878d04bf91e418bd29897f71e117..0564dbfd8b4d330ba6faaf80e632cfb1c2d774eb 100644 (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
index def0e4f5fab28bdf7ec5c7d77af5c9e9165173d0..6dd487166ed9350a8ac1771d36957ebe8fac191f 100644 (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;
 
index 9d0630237f68489ddbe8c4828fe451981abdee1a..8c2fcdc9d1699677491912b1f202bec5cf03b0d0 100644 (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
index 9d076ab65cb11a772b40be7434f6693ca81add7e..979bdcca59e7b672ff61f575760b942155b99848 100644 (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;
                }
        }
index 639dc9a241f23c78427adbcc15e0c9e3a1e26222..29013de592edf75902fd7238ab6183be05590c66 100644 (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);