Add trail prepass scaffolding
This commit is contained in:
Binary file not shown.
@@ -79,5 +79,6 @@ typedef struct {
|
|||||||
void worldgen_init(worldgen_ctx *ctx, int world_seed, int sea_level, int snow_line);
|
void worldgen_init(worldgen_ctx *ctx, int world_seed, int sea_level, int snow_line);
|
||||||
void worldgen_generate_chunk(worldgen_ctx *ctx, int chunk_x, int chunk_z, chunk_data *out);
|
void worldgen_generate_chunk(worldgen_ctx *ctx, int chunk_x, int chunk_z, chunk_data *out);
|
||||||
void worldgen_prepass(worldgen_ctx *ctx, int min_x, int max_x, int min_z, int max_z);
|
void worldgen_prepass(worldgen_ctx *ctx, int min_x, int max_x, int min_z, int max_z);
|
||||||
|
void worldgen_free_trails(worldgen_ctx *ctx);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -52,6 +52,9 @@ typedef struct {
|
|||||||
pthread_mutex_t *log_mu;
|
pthread_mutex_t *log_mu;
|
||||||
int enable_trails;
|
int enable_trails;
|
||||||
results_buffer *results;
|
results_buffer *results;
|
||||||
|
struct trail_segment *trail_segments;
|
||||||
|
size_t trail_segment_count;
|
||||||
|
int prepass_min_x, prepass_max_x, prepass_min_z, prepass_max_z;
|
||||||
} worker_args;
|
} worker_args;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@@ -654,6 +657,16 @@ static void *worker_fn(void *ptr) {
|
|||||||
worldgen_ctx ctx;
|
worldgen_ctx ctx;
|
||||||
worldgen_init(&ctx, args->world_seed, args->sea_level, args->snow_line);
|
worldgen_init(&ctx, args->world_seed, args->sea_level, args->snow_line);
|
||||||
ctx.enable_trails = args->enable_trails;
|
ctx.enable_trails = args->enable_trails;
|
||||||
|
if (args->trail_segments && args->trail_segment_count > 0) {
|
||||||
|
ctx.trail_segments = args->trail_segments;
|
||||||
|
ctx.trail_segment_count = args->trail_segment_count;
|
||||||
|
ctx.trail_segment_cap = args->trail_segment_count;
|
||||||
|
ctx.prepass_done = 1;
|
||||||
|
ctx.prepass_min_x = args->prepass_min_x;
|
||||||
|
ctx.prepass_max_x = args->prepass_max_x;
|
||||||
|
ctx.prepass_min_z = args->prepass_min_z;
|
||||||
|
ctx.prepass_max_z = args->prepass_max_z;
|
||||||
|
}
|
||||||
while (1) {
|
while (1) {
|
||||||
size_t idx = atomic_fetch_add(&args->queue->next_index, 1);
|
size_t idx = atomic_fetch_add(&args->queue->next_index, 1);
|
||||||
if (idx >= args->queue->count) break;
|
if (idx >= args->queue->count) break;
|
||||||
@@ -698,6 +711,9 @@ int main(int argc, char **argv) {
|
|||||||
const char *out_dir = "output";
|
const char *out_dir = "output";
|
||||||
output_format format = FORMAT_MCA;
|
output_format format = FORMAT_MCA;
|
||||||
|
|
||||||
|
/* Prepass context */
|
||||||
|
worldgen_ctx pre_ctx;
|
||||||
|
int prepass_ready = 0;
|
||||||
for (int i = 1; i < argc; ++i) {
|
for (int i = 1; i < argc; ++i) {
|
||||||
if (strcmp(argv[i], "--radius") == 0 && i + 1 < argc) {
|
if (strcmp(argv[i], "--radius") == 0 && i + 1 < argc) {
|
||||||
radius = (int)parse_long(argv[++i]);
|
radius = (int)parse_long(argv[++i]);
|
||||||
@@ -753,6 +769,18 @@ int main(int argc, char **argv) {
|
|||||||
snow_line = sea_level + 38;
|
snow_line = sea_level + 38;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Global prepass: compute trails based on target area before threading */
|
||||||
|
worldgen_init(&pre_ctx, world_seed, sea_level, snow_line);
|
||||||
|
pre_ctx.enable_trails = enable_trails;
|
||||||
|
int world_min_x = min_x * CHUNK_SIZE;
|
||||||
|
int world_max_x = max_x * CHUNK_SIZE + (CHUNK_SIZE - 1);
|
||||||
|
int world_min_z = min_z * CHUNK_SIZE;
|
||||||
|
int world_max_z = max_z * CHUNK_SIZE + (CHUNK_SIZE - 1);
|
||||||
|
if (enable_trails) {
|
||||||
|
worldgen_prepass(&pre_ctx, world_min_x, world_max_x, world_min_z, world_max_z);
|
||||||
|
prepass_ready = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (!have_rect) {
|
if (!have_rect) {
|
||||||
min_x = center_x - radius;
|
min_x = center_x - radius;
|
||||||
max_x = center_x + radius;
|
max_x = center_x + radius;
|
||||||
@@ -800,7 +828,13 @@ int main(int argc, char **argv) {
|
|||||||
.snow_line = snow_line,
|
.snow_line = snow_line,
|
||||||
.log_mu = &log_mu,
|
.log_mu = &log_mu,
|
||||||
.enable_trails = enable_trails,
|
.enable_trails = enable_trails,
|
||||||
.results = &results};
|
.results = &results,
|
||||||
|
.trail_segments = prepass_ready ? pre_ctx.trail_segments : NULL,
|
||||||
|
.trail_segment_count = prepass_ready ? pre_ctx.trail_segment_count : 0,
|
||||||
|
.prepass_min_x = world_min_x,
|
||||||
|
.prepass_max_x = world_max_x,
|
||||||
|
.prepass_min_z = world_min_z,
|
||||||
|
.prepass_max_z = world_max_z};
|
||||||
|
|
||||||
for (int i = 0; i < threads; ++i) {
|
for (int i = 0; i < threads; ++i) {
|
||||||
pthread_create(&workers[i], NULL, worker_fn, &args);
|
pthread_create(&workers[i], NULL, worker_fn, &args);
|
||||||
@@ -861,5 +895,8 @@ int main(int argc, char **argv) {
|
|||||||
free(results.chunks);
|
free(results.chunks);
|
||||||
free(workers);
|
free(workers);
|
||||||
free(jobs);
|
free(jobs);
|
||||||
|
if (prepass_ready) {
|
||||||
|
worldgen_free_trails(&pre_ctx);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,6 +131,7 @@ static void generate_chunk_grass(worldgen_ctx *ctx, int chunk_x, int chunk_z, co
|
|||||||
static void generate_chunk_flowers(worldgen_ctx *ctx, int chunk_x, int chunk_z, column_data columns[CHUNK_SIZE][CHUNK_SIZE], chunk_data *out);
|
static void generate_chunk_flowers(worldgen_ctx *ctx, int chunk_x, int chunk_z, column_data columns[CHUNK_SIZE][CHUNK_SIZE], chunk_data *out);
|
||||||
static void generate_chunk_cabins(worldgen_ctx *ctx, int chunk_x, int chunk_z, column_data columns[CHUNK_SIZE][CHUNK_SIZE], chunk_data *out);
|
static void generate_chunk_cabins(worldgen_ctx *ctx, int chunk_x, int chunk_z, column_data columns[CHUNK_SIZE][CHUNK_SIZE], chunk_data *out);
|
||||||
static void ensure_trail_prepass(worldgen_ctx *ctx, int chunk_x, int chunk_z);
|
static void ensure_trail_prepass(worldgen_ctx *ctx, int chunk_x, int chunk_z);
|
||||||
|
static void append_trail_segment(worldgen_ctx *ctx, int ax, int az, int bx, int bz, int *points, int count);
|
||||||
static void trail_node_position(worldgen_ctx *ctx, int node_x, int node_z, double spacing, double *out_x, double *out_z);
|
static void trail_node_position(worldgen_ctx *ctx, int node_x, int node_z, double spacing, double *out_x, double *out_z);
|
||||||
static void carve_trail_pad(worldgen_ctx *ctx, int chunk_x, int chunk_z, chunk_data *out, column_data columns[CHUNK_SIZE][CHUNK_SIZE], int center_x, int center_z, int radius, int target_height);
|
static void carve_trail_pad(worldgen_ctx *ctx, int chunk_x, int chunk_z, chunk_data *out, column_data columns[CHUNK_SIZE][CHUNK_SIZE], int center_x, int center_z, int radius, int target_height);
|
||||||
static void carve_trail_span(worldgen_ctx *ctx, int chunk_x, int chunk_z, chunk_data *out, column_data columns[CHUNK_SIZE][CHUNK_SIZE], int x0, int z0, int x1, int z1, int width);
|
static void carve_trail_span(worldgen_ctx *ctx, int chunk_x, int chunk_z, chunk_data *out, column_data columns[CHUNK_SIZE][CHUNK_SIZE], int x0, int z0, int x1, int z1, int width);
|
||||||
@@ -141,6 +142,8 @@ static uint16_t generate_normal_ores(worldgen_ctx *ctx, int x, int y, int z, con
|
|||||||
static void connect_cabin_to_trail(worldgen_ctx *ctx, int chunk_x, int chunk_z,
|
static void connect_cabin_to_trail(worldgen_ctx *ctx, int chunk_x, int chunk_z,
|
||||||
column_data columns[CHUNK_SIZE][CHUNK_SIZE], chunk_data *chunk,
|
column_data columns[CHUNK_SIZE][CHUNK_SIZE], chunk_data *chunk,
|
||||||
int door_x, int door_z, int door_side, int path_width);
|
int door_x, int door_z, int door_side, int path_width);
|
||||||
|
static column_data get_column_data(worldgen_ctx *ctx, int x, int z);
|
||||||
|
static int generate_coal(worldgen_ctx *ctx, int x, int y, int z, int column_height, biome_id biome);
|
||||||
|
|
||||||
static uint32_t hash_coords(int x, int z, uint32_t seed) {
|
static uint32_t hash_coords(int x, int z, uint32_t seed) {
|
||||||
uint32_t h = (uint32_t)(x * 374761393 + z * 668265263) ^ seed;
|
uint32_t h = (uint32_t)(x * 374761393 + z * 668265263) ^ seed;
|
||||||
@@ -179,6 +182,163 @@ static double land_value(worldgen_ctx *ctx, int x, int z) {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void append_trail_segment(worldgen_ctx *ctx, int ax, int az, int bx, int bz, int *points, int count) {
|
||||||
|
if (ctx->trail_segment_count >= ctx->trail_segment_cap) {
|
||||||
|
size_t new_cap = ctx->trail_segment_cap ? ctx->trail_segment_cap * 2 : 32;
|
||||||
|
trail_segment *resized = (trail_segment *)realloc(ctx->trail_segments, new_cap * sizeof(trail_segment));
|
||||||
|
if (!resized) return;
|
||||||
|
ctx->trail_segments = resized;
|
||||||
|
ctx->trail_segment_cap = new_cap;
|
||||||
|
}
|
||||||
|
trail_segment *seg = &ctx->trail_segments[ctx->trail_segment_count];
|
||||||
|
memset(seg, 0, sizeof(*seg));
|
||||||
|
seg->ax = ax;
|
||||||
|
seg->az = az;
|
||||||
|
seg->bx = bx;
|
||||||
|
seg->bz = bz;
|
||||||
|
seg->points = points;
|
||||||
|
seg->count = count;
|
||||||
|
ctx->trail_segment_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void worldgen_prepass(worldgen_ctx *ctx, int min_x, int max_x, int min_z, int max_z) {
|
||||||
|
if (!ctx) return;
|
||||||
|
if (ctx->prepass_done) {
|
||||||
|
if (min_x >= ctx->prepass_min_x && max_x <= ctx->prepass_max_x &&
|
||||||
|
min_z >= ctx->prepass_min_z && max_z <= ctx->prepass_max_z) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < ctx->trail_segment_count; ++i) {
|
||||||
|
free(ctx->trail_segments[i].points);
|
||||||
|
}
|
||||||
|
free(ctx->trail_segments);
|
||||||
|
ctx->trail_segments = NULL;
|
||||||
|
ctx->trail_segment_count = 0;
|
||||||
|
ctx->trail_segment_cap = 0;
|
||||||
|
|
||||||
|
const int step = 64;
|
||||||
|
const int max_points = 48;
|
||||||
|
const double min_spacing = 96.0;
|
||||||
|
int cap = max_points;
|
||||||
|
int count = 0;
|
||||||
|
int *px = (int *)malloc((size_t)cap * sizeof(int));
|
||||||
|
int *pz = (int *)malloc((size_t)cap * sizeof(int));
|
||||||
|
double *pv = (double *)malloc((size_t)cap * sizeof(double));
|
||||||
|
if (!px || !pz || !pv) {
|
||||||
|
free(px); free(pz); free(pv);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
for (int z = min_z; z <= max_z; z += step) {
|
||||||
|
for (int x = min_x; x <= max_x; x += step) {
|
||||||
|
double val = land_value(ctx, x, z);
|
||||||
|
if (val < 0.05) continue;
|
||||||
|
int spaced = 1;
|
||||||
|
for (int i = 0; i < count; ++i) {
|
||||||
|
double dx = (double)(x - px[i]);
|
||||||
|
double dz = (double)(z - pz[i]);
|
||||||
|
if (dx * dx + dz * dz < min_spacing * min_spacing) {
|
||||||
|
spaced = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!spaced) continue;
|
||||||
|
if (count < cap) {
|
||||||
|
px[count] = x;
|
||||||
|
pz[count] = z;
|
||||||
|
pv[count] = val;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
if (count >= max_points) break;
|
||||||
|
}
|
||||||
|
if (count >= max_points) break;
|
||||||
|
}
|
||||||
|
if (count == 0) {
|
||||||
|
px = (int *)realloc(px, sizeof(int));
|
||||||
|
pz = (int *)realloc(pz, sizeof(int));
|
||||||
|
pv = (double *)realloc(pv, sizeof(double));
|
||||||
|
if (!px || !pz || !pv) {
|
||||||
|
free(px); free(pz); free(pv);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
px[0] = (min_x + max_x) / 2;
|
||||||
|
pz[0] = (min_z + max_z) / 2;
|
||||||
|
pv[0] = 1.0;
|
||||||
|
count = 1;
|
||||||
|
}
|
||||||
|
int root = 0;
|
||||||
|
for (int i = 1; i < count; ++i) {
|
||||||
|
if (pv[i] > pv[root]) root = i;
|
||||||
|
}
|
||||||
|
unsigned char *connected = (unsigned char *)calloc((size_t)count, 1);
|
||||||
|
if (!connected) {
|
||||||
|
free(px); free(pz); free(pv);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
connected[root] = 1;
|
||||||
|
int connected_count = 1;
|
||||||
|
while (connected_count < count) {
|
||||||
|
int best_u = -1, best_v = -1;
|
||||||
|
double best_d2 = DBL_MAX;
|
||||||
|
for (int u = 0; u < count; ++u) {
|
||||||
|
if (!connected[u]) continue;
|
||||||
|
for (int v = 0; v < count; ++v) {
|
||||||
|
if (connected[v]) continue;
|
||||||
|
double dx = (double)(px[u] - px[v]);
|
||||||
|
double dz = (double)(pz[u] - pz[v]);
|
||||||
|
double d2 = dx * dx + dz * dz;
|
||||||
|
if (d2 < best_d2) {
|
||||||
|
best_d2 = d2;
|
||||||
|
best_u = u;
|
||||||
|
best_v = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (best_u == -1 || best_v == -1) break;
|
||||||
|
int *pts = NULL;
|
||||||
|
int path_count = 0;
|
||||||
|
if (build_trail_path(ctx, (double)px[best_u], (double)pz[best_u], (double)px[best_v], (double)pz[best_v], &pts, &path_count) && pts && path_count >= 2) {
|
||||||
|
append_trail_segment(ctx, px[best_u], pz[best_u], px[best_v], pz[best_v], pts, path_count);
|
||||||
|
} else {
|
||||||
|
free(pts);
|
||||||
|
}
|
||||||
|
connected[best_v] = 1;
|
||||||
|
connected_count++;
|
||||||
|
}
|
||||||
|
free(connected);
|
||||||
|
free(px);
|
||||||
|
free(pz);
|
||||||
|
free(pv);
|
||||||
|
|
||||||
|
done:
|
||||||
|
ctx->prepass_done = 1;
|
||||||
|
ctx->prepass_min_x = min_x;
|
||||||
|
ctx->prepass_max_x = max_x;
|
||||||
|
ctx->prepass_min_z = min_z;
|
||||||
|
ctx->prepass_max_z = max_z;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ensure_trail_prepass(worldgen_ctx *ctx, int chunk_x, int chunk_z) {
|
||||||
|
if (!ctx) return;
|
||||||
|
if (ctx->prepass_done) return;
|
||||||
|
int min_x = (chunk_x - 8) * CHUNK_SIZE;
|
||||||
|
int max_x = (chunk_x + 8) * CHUNK_SIZE + (CHUNK_SIZE - 1);
|
||||||
|
int min_z = (chunk_z - 8) * CHUNK_SIZE;
|
||||||
|
int max_z = (chunk_z + 8) * CHUNK_SIZE + (CHUNK_SIZE - 1);
|
||||||
|
worldgen_prepass(ctx, min_x, max_x, min_z, max_z);
|
||||||
|
}
|
||||||
|
|
||||||
|
void worldgen_free_trails(worldgen_ctx *ctx) {
|
||||||
|
if (!ctx || !ctx->trail_segments) return;
|
||||||
|
for (size_t i = 0; i < ctx->trail_segment_count; ++i) {
|
||||||
|
free(ctx->trail_segments[i].points);
|
||||||
|
}
|
||||||
|
free(ctx->trail_segments);
|
||||||
|
ctx->trail_segments = NULL;
|
||||||
|
ctx->trail_segment_count = 0;
|
||||||
|
ctx->trail_segment_cap = 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void set_block_with_height(chunk_data *chunk, int local_x, int local_z, int y, uint16_t id) {
|
static void set_block_with_height(chunk_data *chunk, int local_x, int local_z, int y, uint16_t id) {
|
||||||
if (local_x < 0 || local_x >= CHUNK_SIZE || local_z < 0 || local_z >= CHUNK_SIZE) return;
|
if (local_x < 0 || local_x >= CHUNK_SIZE || local_z < 0 || local_z >= CHUNK_SIZE) return;
|
||||||
if (y < 0 || y >= CHUNK_HEIGHT) return;
|
if (y < 0 || y >= CHUNK_HEIGHT) return;
|
||||||
@@ -2636,16 +2796,38 @@ static void carve_trail_span(worldgen_ctx *ctx, int chunk_x, int chunk_z, chunk_
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void generate_chunk_trails(worldgen_ctx *ctx, int chunk_x, int chunk_z, column_data columns[CHUNK_SIZE][CHUNK_SIZE], chunk_data *out) {
|
static void generate_chunk_trails(worldgen_ctx *ctx, int chunk_x, int chunk_z, column_data columns[CHUNK_SIZE][CHUNK_SIZE], chunk_data *out) {
|
||||||
const double spacing = TRAIL_NODE_SPACING;
|
|
||||||
int chunk_min_x = chunk_x * CHUNK_SIZE;
|
int chunk_min_x = chunk_x * CHUNK_SIZE;
|
||||||
int chunk_max_x = chunk_min_x + CHUNK_SIZE - 1;
|
int chunk_max_x = chunk_min_x + CHUNK_SIZE - 1;
|
||||||
int chunk_min_z = chunk_z * CHUNK_SIZE;
|
int chunk_min_z = chunk_z * CHUNK_SIZE;
|
||||||
int chunk_max_z = chunk_min_z + CHUNK_SIZE - 1;
|
int chunk_max_z = chunk_min_z + CHUNK_SIZE - 1;
|
||||||
|
int width = TRAIL_WIDTH;
|
||||||
|
|
||||||
|
if (ctx->trail_segment_count > 0) {
|
||||||
|
for (size_t s = 0; s < ctx->trail_segment_count; ++s) {
|
||||||
|
trail_segment *seg = &ctx->trail_segments[s];
|
||||||
|
if (!seg || seg->count < 2) continue;
|
||||||
|
for (int i = 1; i < seg->count; ++i) {
|
||||||
|
int x0 = seg->points[(i - 1) * 2];
|
||||||
|
int z0 = seg->points[(i - 1) * 2 + 1];
|
||||||
|
int x1 = seg->points[i * 2];
|
||||||
|
int z1 = seg->points[i * 2 + 1];
|
||||||
|
int span_min_x = (x0 < x1) ? x0 : x1;
|
||||||
|
int span_max_x = (x0 > x1) ? x0 : x1;
|
||||||
|
int span_min_z = (z0 < z1) ? z0 : z1;
|
||||||
|
int span_max_z = (z0 > z1) ? z0 : z1;
|
||||||
|
if (span_max_x < chunk_min_x - 4 || span_min_x > chunk_max_x + 4) continue;
|
||||||
|
if (span_max_z < chunk_min_z - 4 || span_min_z > chunk_max_z + 4) continue;
|
||||||
|
carve_trail_span(ctx, chunk_x, chunk_z, out, columns, x0, z0, x1, z1, width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const double spacing = TRAIL_NODE_SPACING;
|
||||||
int min_node_x = (int)floor((chunk_min_x - spacing) / spacing);
|
int min_node_x = (int)floor((chunk_min_x - spacing) / spacing);
|
||||||
int max_node_x = (int)ceil((chunk_max_x + spacing) / spacing);
|
int max_node_x = (int)ceil((chunk_max_x + spacing) / spacing);
|
||||||
int min_node_z = (int)floor((chunk_min_z - spacing) / spacing);
|
int min_node_z = (int)floor((chunk_min_z - spacing) / spacing);
|
||||||
int max_node_z = (int)ceil((chunk_max_z + spacing) / spacing);
|
int max_node_z = (int)ceil((chunk_max_z + spacing) / spacing);
|
||||||
int width = TRAIL_WIDTH;
|
|
||||||
size_t neighbor_count = sizeof(TRAIL_NEIGHBOR_OFFSETS) / sizeof(TRAIL_NEIGHBOR_OFFSETS[0]);
|
size_t neighbor_count = sizeof(TRAIL_NEIGHBOR_OFFSETS) / sizeof(TRAIL_NEIGHBOR_OFFSETS[0]);
|
||||||
for (int nx = min_node_x; nx <= max_node_x; ++nx) {
|
for (int nx = min_node_x; nx <= max_node_x; ++nx) {
|
||||||
for (int nz = min_node_z; nz <= max_node_z; ++nz) {
|
for (int nz = min_node_z; nz <= max_node_z; ++nz) {
|
||||||
@@ -2695,6 +2877,8 @@ void worldgen_generate_chunk(worldgen_ctx *ctx, int chunk_x, int chunk_z, chunk_
|
|||||||
out->chunk_x = chunk_x;
|
out->chunk_x = chunk_x;
|
||||||
out->chunk_z = chunk_z;
|
out->chunk_z = chunk_z;
|
||||||
|
|
||||||
|
ensure_trail_prepass(ctx, chunk_x, chunk_z);
|
||||||
|
|
||||||
// Precompute column data for base terrain
|
// Precompute column data for base terrain
|
||||||
column_data columns[CHUNK_SIZE][CHUNK_SIZE];
|
column_data columns[CHUNK_SIZE][CHUNK_SIZE];
|
||||||
for (int dx = 0; dx < CHUNK_SIZE; ++dx) {
|
for (int dx = 0; dx < CHUNK_SIZE; ++dx) {
|
||||||
|
|||||||
Reference in New Issue
Block a user