});
client_map.queue = queue_create();
client_map.cancel = false;
- client_map.meshgen_thread = client_map.sync_thread = 0;
+ client_map.sync_thread = 0;
client_map_set_simulation_distance(10);
+
+ for (int i = 0; i < NUM_MESHGEN_THREADS; i++)
+ client_map.meshgen_threads[i] = 0;
}
// ClientMap singleton destructor
// start meshgen and sync threads
void client_map_start()
{
- pthread_create(&client_map.meshgen_thread, NULL, &meshgen_thread, NULL);
+ for (int i = 0; i < NUM_MESHGEN_THREADS; i++)
+ pthread_create(&client_map.meshgen_threads[i], NULL, &meshgen_thread, NULL);
+
pthread_create(&client_map.sync_thread, NULL, &sync_thread, NULL);
}
{
client_map.cancel = true;
- if (client_map.meshgen_thread)
- pthread_join(client_map.meshgen_thread, NULL);
+ for (int i = 0; i < NUM_MESHGEN_THREADS; i++)
+ if (client_map.meshgen_threads[i])
+ pthread_join(client_map.meshgen_threads[i], NULL);
if (client_map.sync_thread)
pthread_join(client_map.sync_thread, NULL);
#include <dragontype/queue.h>
#include "map.h"
#include "client/object.h"
+#define NUM_MESHGEN_THREADS 4
typedef enum
{
Map *map; // map object
Queue *queue; // MapBlock * queue (thread safe)
bool cancel; // used to notify meshgen and sync thread about quit
- pthread_t meshgen_thread; // consumer thread for meshgen queue
+ pthread_t meshgen_threads[NUM_MESHGEN_THREADS]; // consumer threads for meshgen queue
pthread_t sync_thread; // this thread requests new / changed blocks from server
u32 simulation_distance; // simulation distance sent by server
size_t blocks_count; // cached number of facecache positions to process every sync step (matches simulation distance)
SO_MOUNTAIN,
SO_OCEAN,
SO_MOUNTAIN_HEIGHT,
- SO_BOULDER_CENTER,
SO_BOULDER,
SO_WETNESS,
SO_TEXTURE_OFFSET_S,
SO_TEXTURE_OFFSET_T,
SO_TEMPERATURE,
- SO_PINE_AREA,
- SO_PINE,
- SO_PINE_HEIGHT,
- SO_PINE_BRANCH,
SO_VULCANO,
SO_VULCANO_HEIGHT,
SO_VULCANO_STONE,
// hills biome
+static bool boulder_touching_ground(v3s32 pos, s32 diff)
+{
+ for (s32 dir = diff > 0 ? -1 : +1; dir > 0 ? diff <= 0 : diff >= 0; pos.y += dir, diff += dir) {
+ if (smooth3d(U32(pos.x) / 12.0, U32(pos.y) / 6.0, U32(pos.z) / 12.0, 0, seed + SO_BOULDER) < 0.8)
+ return false;
+ }
+
+ return true;
+}
+
static s32 height_hills(unused v2s32 pos, unused f64 factor, s32 height, unused void *row_data, unused void *block_data)
{
return height;
}
-static Node generate_hills(v3s32 pos, s32 diff, unused f64 humidity, unused f64 temperature, unused f64 factor, unused MapBlock *block, List *changed_blocks, unused void *row_data, unused void *block_data)
+static Node generate_hills(v3s32 pos, s32 diff, unused f64 humidity, unused f64 temperature, unused f64 factor, unused MapBlock *block, unused List *changed_blocks, unused void *row_data, unused void *block_data)
{
- if (diff == 2 && noise2d(pos.x, pos.z, 0, seed + SO_BOULDER_CENTER) > 0.999) {
- for (s8 bx = -1; bx <= 1; bx++) {
- for (s8 by = -1; by <= 1; by++) {
- for (s8 bz = -1; bz <= 1; bz++) {
- v3s32 bpos = {pos.x + bx, pos.y + by, pos.z + bz};
- if (noise3d(bpos.x, bpos.y, bpos.z, 0, seed + SO_BOULDER) > 0.0)
- mapgen_set_node(bpos, map_node_create(NODE_STONE), MGS_BOULDERS, changed_blocks);
- }
- }
- }
- }
+ if (boulder_touching_ground(pos, diff))
+ return NODE_STONE;
if (diff <= -5)
return NODE_STONE;