From 676641b2552b32da2e88c16b67f6c95db9fb6e7b Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Thu, 19 Aug 2021 03:12:15 +0200 Subject: [PATCH] Calculate grass color client side --- src/CMakeLists.txt | 1 + src/biome.c | 9 +++++++++ src/biome.h | 20 ++++++++++++++++++++ src/client/blockmesh.c | 6 ++++-- src/client/client_node.c | 13 +++++++++---- src/client/client_node.h | 2 +- src/map.c | 1 - src/map.h | 1 - src/node.c | 9 ++------- src/node.h | 7 ------- src/server/mapgen.c | 19 ++++++------------- src/types.c | 8 ++++++++ src/types.h | 2 ++ 13 files changed, 62 insertions(+), 36 deletions(-) create mode 100644 src/biome.c create mode 100644 src/biome.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 648ef3a..2c38e74 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -29,6 +29,7 @@ add_compile_options(-Wall -Wextra -Wpedantic -Werror) set(SOURCES_COMMON array.c + biome.c bintree.c list.c map.c diff --git a/src/biome.c b/src/biome.c new file mode 100644 index 0000000..f17ad0e --- /dev/null +++ b/src/biome.c @@ -0,0 +1,9 @@ +#include "biome.h" +#include "perlin.h" + +int seed = 0; + +f64 get_wetness(v3s32 pos) +{ + return smooth2d((((u32) 1 << 31) + pos.x) / 128.0, (((u32) 1 << 31) + pos.z) / 128.0, 0, 3) * 0.5 + 0.5; +} diff --git a/src/biome.h b/src/biome.h new file mode 100644 index 0000000..1529f59 --- /dev/null +++ b/src/biome.h @@ -0,0 +1,20 @@ +#ifndef _BIOME_H_ +#define _BIOME_H_ + +#include "types.h" + +typedef enum +{ + SO_HEIGHT, + SO_MOUNTAIN_FACTOR, + SO_MOUNTAIN_HEIGHT, + SO_BOULDER_CENTER, + SO_BOULDER, + SO_WETNESS, +} SeedOffset; + +f64 get_wetness(v3s32 pos); + +extern int seed; + +#endif diff --git a/src/client/blockmesh.c b/src/client/blockmesh.c index 3ee7422..2bb0fa4 100644 --- a/src/client/blockmesh.c +++ b/src/client/blockmesh.c @@ -14,6 +14,8 @@ static v3s8 fdir[6] = { static void make_vertices(Object *object, MapBlock *block) { + v3s32 node_bp = {block->pos.x * MAPBLOCK_SIZE, block->pos.y * MAPBLOCK_SIZE, block->pos.z * MAPBLOCK_SIZE}; + ITERATE_MAPBLOCK { MapNode *node = &block->data[x][y][z]; @@ -35,7 +37,7 @@ 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 { - MapNode nn = map_get_node(client_map.map, (v3s32) {npos.x + block->pos.x * MAPBLOCK_SIZE, npos.y + block->pos.y * MAPBLOCK_SIZE, npos.z + block->pos.z * MAPBLOCK_SIZE}); + 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; } @@ -47,7 +49,7 @@ static void make_vertices(Object *object, MapBlock *block) vertex.position.z += offset.z; if (client_def->render) - client_def->render(node, &vertex); + client_def->render((v3s32) {x + node_bp.x, y + node_bp.y, z + node_bp.z}, node, &vertex); object_add_vertex(object, &vertex); } diff --git a/src/client/client_node.c b/src/client/client_node.c index 739e7c6..75b740c 100644 --- a/src/client/client_node.c +++ b/src/client/client_node.c @@ -1,12 +1,17 @@ +#include "biome.h" #include "client/client.h" #include "client/client_node.h" #include "node.h" -static void render_state_biome(MapNode *node, Vertex3D *vertex) +static void render_state_biome(v3s32 pos, __attribute__((unused)) MapNode *node, Vertex3D *vertex) { - vertex->color.h = node->state.biome.x; - vertex->color.s = node->state.biome.y; - vertex->color.v = node->state.biome.z; + double min, max; + min = 0.15; + max = 0.45; + + vertex->color.h = get_wetness(pos) * (max - min) + min; + vertex->color.s = 1.0f; + vertex->color.v = 1.0f; } ClientNodeDefintion client_node_definitions[NODE_UNLOADED] = { diff --git a/src/client/client_node.h b/src/client/client_node.h index 0ab64c9..4044ef1 100644 --- a/src/client/client_node.h +++ b/src/client/client_node.h @@ -9,7 +9,7 @@ typedef struct { char *texture_path; Texture *texture; - void (*render)(MapNode *node, Vertex3D *vertex); + void (*render)(v3s32 pos, MapNode *node, Vertex3D *vertex); } ClientNodeDefintion; extern ClientNodeDefintion client_node_definitions[]; diff --git a/src/map.c b/src/map.c index 8bd7268..87a9b3f 100644 --- a/src/map.c +++ b/src/map.c @@ -229,7 +229,6 @@ MapNode map_node_create(Node type) { MapNode node; node.type = type; - memset(&node.state, 0, sizeof(NodeState)); if (node.type != NODE_UNLOADED && node_definitions[node.type].create) node_definitions[node.type].create(&node); diff --git a/src/map.h b/src/map.h index e7b4ad1..c60293f 100644 --- a/src/map.h +++ b/src/map.h @@ -14,7 +14,6 @@ typedef struct MapNode { Node type; - NodeState state; } MapNode; typedef MapNode MapBlockData[MAPBLOCK_SIZE][MAPBLOCK_SIZE][MAPBLOCK_SIZE]; diff --git a/src/node.c b/src/node.c index 7bdc8b4..5ea8bb4 100644 --- a/src/node.c +++ b/src/node.c @@ -2,11 +2,6 @@ #include "node.h" #include "util.h" -static void create_state_biome(MapNode *node) -{ - node->state.biome = (v3f32) {1.0f, 0.0f, 1.0f}; -} - NodeDefintion node_definitions[NODE_UNLOADED] = { // invalid { @@ -28,8 +23,8 @@ NodeDefintion node_definitions[NODE_UNLOADED] = { { .visible = true, .solid = true, - .create = &create_state_biome, - .serialize = NULL, // currently v3f is not serialized + .create = NULL, + .serialize = NULL, .deserialize = NULL, }, // dirt diff --git a/src/node.h b/src/node.h index e9f67ed..04176a3 100644 --- a/src/node.h +++ b/src/node.h @@ -4,13 +4,6 @@ #include #include "types.h" -typedef v3f32 NodeStateBiome; - -typedef union -{ - NodeStateBiome biome; -} NodeState; - typedef enum { NODE_INVALID, // Used for unknown nodes received from server (caused by outdated clients) diff --git a/src/server/mapgen.c b/src/server/mapgen.c index 9cf384b..9b14b9b 100644 --- a/src/server/mapgen.c +++ b/src/server/mapgen.c @@ -1,5 +1,6 @@ #include #include +#include "biome.h" #include "perlin.h" #include "server/mapgen.h" #include "server/server_map.h" @@ -24,13 +25,13 @@ void mapgen_generate_block(MapBlock *block, List *changed_blocks) u32 ux = x + block->pos.x * MAPBLOCK_SIZE + ((u32) 1 << 31); for (u8 z = 0; z < MAPBLOCK_SIZE; z++) { u32 uz = z + block->pos.z * MAPBLOCK_SIZE + ((u32) 1 << 31); - s32 height = smooth2d(ux / 32.0, uz / 32.0, 0, 0) * 16.0 + 128.0; + s32 height = smooth2d(ux / 32.0, uz / 32.0, 0, seed + SO_HEIGHT) * 16.0 + 128.0; bool is_mountain = false; - double mountain_factor = (smooth2d(ux / 1000.0, uz / 1000.0, 0, 1) - 0.3) * 5.0; + double mountain_factor = (smooth2d(ux / 1000.0, uz / 1000.0, 0, seed + SO_MOUNTAIN_FACTOR) - 0.3) * 5.0; if (mountain_factor > 0.0) { - height = pow(height * pow(((smooth2d(ux / 50.0, uz / 50.0, 2, 2) + 1.0) * 256.0 + 128.0), mountain_factor), 1.0 / (mountain_factor + 1.0)); + height = pow(height * pow(((smooth2d(ux / 50.0, uz / 50.0, 2, seed + SO_MOUNTAIN_HEIGHT) + 1.0) * 256.0 + 128.0), mountain_factor), 1.0 / (mountain_factor + 1.0)); is_mountain = true; } @@ -49,12 +50,12 @@ void mapgen_generate_block(MapBlock *block, List *changed_blocks) else if (diff < 1) node = (is_mountain && ay > 256) ? NODE_SNOW : NODE_AIR; - if (! is_mountain && diff == 0 && (smooth2d(x + block->pos.x * 16, z + block->pos.z * 16, 0, 3) * 0.5 + 0.5) < 0.0001f) { + if (! is_mountain && diff == 0 && (smooth2d(x + block->pos.x * 16, z + block->pos.z * 16, 0, seed + SO_BOULDER_CENTER) * 0.5 + 0.5) < 0.0001f) { for (s8 bx = -1; bx <= 1; bx++) { for (s8 by = -1; by <= 1; by++) { for (s8 bz = -1; bz <= 1; bz++) { v3s32 pos = {block->pos.x * MAPBLOCK_SIZE + x + bx, block->pos.y * MAPBLOCK_SIZE + y + by, block->pos.z * MAPBLOCK_SIZE + z + bz}; - if (smooth3d(pos.x, pos.y, pos.z, 0, 4) > 0.0) + if (smooth3d(pos.x, pos.y, pos.z, 0, seed + SO_BOULDER) > 0.0) set_node(pos, map_node_create(NODE_STONE), MGS_BOULDERS, changed_blocks); } } @@ -65,14 +66,6 @@ void mapgen_generate_block(MapBlock *block, List *changed_blocks) if (extra->mgs_buffer[x][y][z] <= MGS_TERRAIN) { block->data[x][y][z] = map_node_create(node); extra->mgs_buffer[x][y][z] = MGS_TERRAIN; - - if (node == NODE_GRASS) { - double min, max; - min = 0.15; - max = 0.45; - block->data[x][y][z].state.biome.x = (smooth2d(ux / 128.0, uz / 128.0, 0, 3) * 0.5 + 0.5) * (max - min) + min; - block->data[x][y][z].state.biome.y = 1.0; - } } pthread_mutex_unlock(&block->mtx); } diff --git a/src/types.c b/src/types.c index 10685f0..4a79da4 100644 --- a/src/types.c +++ b/src/types.c @@ -52,6 +52,10 @@ bool read_full(int fd, char *buffer, size_t size) { \ return a.x == b.x && a.y == b.y; \ } \ + v2 ## type v2 ## type ## _add(v2 ## type a, v2 ## type b) \ + { \ + return (v2 ## type) {a.x + b.x, a.y + b.y}; \ + } \ bool read_v3 ## type(int fd, v3 ## type *ptr) \ { \ READVEC(type, 3) \ @@ -68,6 +72,10 @@ bool read_full(int fd, char *buffer, size_t size) bool v3 ## type ## _equals(v3 ## type a, v3 ## type b) \ { \ return a.x == b.x && a.y == b.y && a.z == b.z; \ + } \ + v3 ## type v3 ## type ## _add(v3 ## type a, v3 ## type b) \ + { \ + return (v3 ## type) {a.x + b.x, a.y + b.y, a.z + b.z}; \ } #define DEFTYP(type, bits) \ diff --git a/src/types.h b/src/types.h index 52b8f34..025e661 100644 --- a/src/types.h +++ b/src/types.h @@ -19,10 +19,12 @@ bool read_full(int fd, char *buffer, size_t size); DEFRW(v2 ## type) \ DEFBOX(2 ## type) \ bool v2 ## type ## _equals(v2 ## type a, v2 ## type b); \ + v2 ## type v2 ## type ## _add(v2 ## type a, v2 ## type b); \ typedef struct {type x, y, z;} v3 ## type; \ DEFRW(v3 ## type) \ DEFBOX(3 ## type) \ bool v3 ## type ## _equals(v3 ## type a, v3 ## type b); \ + v3 ## type v3 ## type ## _add(v3 ## type a, v3 ## type b); #define DEFTYP(from, to) \ typedef from to; \ -- 2.44.0