Wire trail prepass into generation
This commit is contained in:
Binary file not shown.
@@ -218,7 +218,7 @@ void worldgen_prepass(worldgen_ctx *ctx, int min_x, int max_x, int min_z, int ma
|
||||
ctx->trail_segment_cap = 0;
|
||||
|
||||
const int step = 64;
|
||||
const int max_points = 48;
|
||||
const int max_points = 64;
|
||||
const double min_spacing = 96.0;
|
||||
int cap = max_points;
|
||||
int count = 0;
|
||||
@@ -227,7 +227,7 @@ void worldgen_prepass(worldgen_ctx *ctx, int min_x, int max_x, int min_z, int ma
|
||||
double *pv = (double *)malloc((size_t)cap * sizeof(double));
|
||||
if (!px || !pz || !pv) {
|
||||
free(px); free(pz); free(pv);
|
||||
goto done;
|
||||
return;
|
||||
}
|
||||
for (int z = min_z; z <= max_z; z += step) {
|
||||
for (int x = min_x; x <= max_x; x += step) {
|
||||
@@ -259,58 +259,90 @@ void worldgen_prepass(worldgen_ctx *ctx, int min_x, int max_x, int min_z, int ma
|
||||
pv = (double *)realloc(pv, sizeof(double));
|
||||
if (!px || !pz || !pv) {
|
||||
free(px); free(pz); free(pv);
|
||||
goto done;
|
||||
return;
|
||||
}
|
||||
px[0] = (min_x + max_x) / 2;
|
||||
pz[0] = (min_z + max_z) / 2;
|
||||
pv[0] = 1.0;
|
||||
count = 1;
|
||||
}
|
||||
int root = 0;
|
||||
|
||||
/* Select hubs: pick top valued, then farthest from existing hubs */
|
||||
const int max_hubs = 3;
|
||||
int hub_indices[3] = {0, 0, 0};
|
||||
int hub_count = 0;
|
||||
int first = 0;
|
||||
for (int i = 1; i < count; ++i) {
|
||||
if (pv[i] > pv[root]) root = i;
|
||||
if (pv[i] > pv[first]) first = 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]);
|
||||
hub_indices[hub_count++] = first;
|
||||
for (int h = 1; h < max_hubs && hub_count < count; ++h) {
|
||||
int best = -1;
|
||||
double best_d2 = -1.0;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
int already_hub = 0;
|
||||
for (int k = 0; k < hub_count; ++k) if (hub_indices[k] == i) { already_hub = 1; break; }
|
||||
if (already_hub) continue;
|
||||
double min_d2 = DBL_MAX;
|
||||
for (int k = 0; k < hub_count; ++k) {
|
||||
double dx = (double)(px[i] - px[hub_indices[k]]);
|
||||
double dz = (double)(pz[i] - pz[hub_indices[k]]);
|
||||
double d2 = dx * dx + dz * dz;
|
||||
if (d2 < best_d2) {
|
||||
best_d2 = d2;
|
||||
best_u = u;
|
||||
best_v = v;
|
||||
if (d2 < min_d2) min_d2 = d2;
|
||||
}
|
||||
if (min_d2 > best_d2) {
|
||||
best_d2 = min_d2;
|
||||
best = i;
|
||||
}
|
||||
}
|
||||
if (best >= 0) {
|
||||
hub_indices[hub_count++] = best;
|
||||
}
|
||||
if (best_u == -1 || best_v == -1) break;
|
||||
}
|
||||
|
||||
/* Connect hubs together */
|
||||
for (int i = 0; i < hub_count; ++i) {
|
||||
for (int j = i + 1; j < hub_count; ++j) {
|
||||
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);
|
||||
if (build_trail_path(ctx, (double)px[hub_indices[i]], (double)pz[hub_indices[i]],
|
||||
(double)px[hub_indices[j]], (double)pz[hub_indices[j]], &pts, &path_count) && pts && path_count >= 2) {
|
||||
append_trail_segment(ctx, px[hub_indices[i]], pz[hub_indices[i]], px[hub_indices[j]], pz[hub_indices[j]], pts, path_count);
|
||||
} else {
|
||||
free(pts);
|
||||
}
|
||||
connected[best_v] = 1;
|
||||
connected_count++;
|
||||
}
|
||||
free(connected);
|
||||
}
|
||||
|
||||
/* Connect every non-hub point to nearest hub */
|
||||
for (int i = 0; i < count; ++i) {
|
||||
int is_hub = 0;
|
||||
for (int k = 0; k < hub_count; ++k) if (hub_indices[k] == i) { is_hub = 1; break; }
|
||||
if (is_hub) continue;
|
||||
int nearest_hub = hub_indices[0];
|
||||
double best_d2 = DBL_MAX;
|
||||
for (int k = 0; k < hub_count; ++k) {
|
||||
double dx = (double)(px[i] - px[hub_indices[k]]);
|
||||
double dz = (double)(pz[i] - pz[hub_indices[k]]);
|
||||
double d2 = dx * dx + dz * dz;
|
||||
if (d2 < best_d2) {
|
||||
best_d2 = d2;
|
||||
nearest_hub = hub_indices[k];
|
||||
}
|
||||
}
|
||||
int *pts = NULL;
|
||||
int path_count = 0;
|
||||
if (build_trail_path(ctx, (double)px[i], (double)pz[i], (double)px[nearest_hub], (double)pz[nearest_hub], &pts, &path_count) && pts && path_count >= 2) {
|
||||
append_trail_segment(ctx, px[i], pz[i], px[nearest_hub], pz[nearest_hub], pts, path_count);
|
||||
} else {
|
||||
free(pts);
|
||||
}
|
||||
}
|
||||
|
||||
free(px);
|
||||
free(pz);
|
||||
free(pv);
|
||||
|
||||
done:
|
||||
ctx->prepass_done = 1;
|
||||
ctx->prepass_min_x = min_x;
|
||||
ctx->prepass_max_x = max_x;
|
||||
|
||||
Reference in New Issue
Block a user