From 20a8c6526615ec20cbdff74826e201d4e75a16c1 Mon Sep 17 00:00:00 2001 From: Carlos Sanchez Date: Sat, 21 Sep 2024 08:54:58 -0400 Subject: [PATCH] Setting up flower generation --- commonobj.c | 13 ++++++ terrain.c | 112 ++++++++++++++++++++++++++++++--------------- terrain_ecstypes.h | 1 + 3 files changed, 90 insertions(+), 36 deletions(-) diff --git a/commonobj.c b/commonobj.c index 81d15e4..adfa134 100644 --- a/commonobj.c +++ b/commonobj.c @@ -83,3 +83,16 @@ void gen_circle_model(haloo3d_obj *model, uint16_t color, int vertices) { } fastface2(model, circleuv, middle, lastv, firstv); } + +void gen_flower(haloo3d_obj *model, uint16_t color) { + haloo3d_obj_resetfixed(model, 2, 5); + uint16_t vs[5]; + uint16_t col = COMCOL(model, color); + vs[0] = COMVERT(model, 0, -1, 0); // The shared middle + vs[1] = COMVERT(model, 1, 1, 0); + vs[2] = COMVERT(model, -1, 1, 0); + vs[3] = COMVERT(model, 0, 1, 1); + vs[4] = COMVERT(model, 0, 1, -1); + fastface2(model, col, vs[0], vs[1], vs[2]); + fastface2(model, col, vs[0], vs[3], vs[4]); +} diff --git a/terrain.c b/terrain.c index 473463c..b119345 100644 --- a/terrain.c +++ b/terrain.c @@ -59,7 +59,7 @@ #define CHUNKSCALE (1.0 / CHUNKSIZE) // This is how many vertices across a chunk is #define CHUNKVSIZE (CHUNKSIZE + 1) -#define VIEWDISTANCE 10 +#define VIEWDISTANCE 7 #define PLBOXEDGE (VIEWDISTANCE * 2 + 1) #define INIT_NEARCLIP 0.01 #define INIT_FARCLIP 100.0 @@ -76,6 +76,7 @@ #define TREETRUNKCOL 0xF950 #define TREEBOTTOM -0.333 #define TREETRUNKWIDTH 0.2 +#define REDFLOWERCOL 0xFF36 #define SEATRANS 0.75 #define CLOUDTRANSMIN 0.1 #define CLOUDTRANSMAX 0.2 @@ -106,15 +107,34 @@ int fps = 60; #define PALETTEKEY "palette" #define TREEKEY "tree" #define CLOUDKEY "cloud" +#define REDFLOWERKEY "redflower" #include "commonobj.c" static int gen_terrain_seed = 0; +static inline mfloat_t calc_barycentric(mfloat_t *point, mfloat_t *values, + struct vec2 *triedge, int count) { + mfloat_t we[3]; + for (int i = 0; i < count; i++) { + int ofs = i * 3; + we[0] = haloo3d_edgefunc(triedge[ofs + 1].v, triedge[ofs + 2].v, point); + we[1] = haloo3d_edgefunc(triedge[ofs + 2].v, triedge[ofs + 0].v, point); + we[2] = haloo3d_edgefunc(triedge[ofs + 0].v, triedge[ofs + 1].v, point); + if (we[0] < 0 || we[1] < 0 || we[2] < 0) { + continue; + } + return we[0] * values[ofs] + we[1] * values[ofs + 1] + + we[2] * values[ofs + 2]; + } + return 0; +} + void gen_terrain(struct vec3i pos, haloo3d_obj *model, haloo3d_easystore *storage) { eprintf("Generating terrain at %d,%d\n", pos.x, pos.z); haloo3d_obj *tree = haloo3d_easystore_getobj(storage, TREEKEY); + haloo3d_obj *redflower = haloo3d_easystore_getobj(storage, REDFLOWERKEY); // Don't allow the model to have more than some amount of faces/vertices. haloo3d_obj_resetfixed(model, H3D_OBJ_MAXFACES, H3D_OBJ_MAXVERTICES); struct vec3 landcol = haloo3d_gen_paletteuv(LANDCOL); // 0xF2C0); @@ -148,60 +168,76 @@ void gen_terrain(struct vec3i pos, haloo3d_obj *model, faces[0] = haloo3d_obj_addface(model, face); fastface(face, landuv, br, tr, tl); faces[1] = haloo3d_obj_addface(model, face); - struct vec3 triedge[2][3]; + struct vec2 triedge[6]; + mfloat_t heights[6]; for (int t = 0; t < 2; t++) { for (int v = 0; v < 3; v++) { + int ofs = t * 3; // NOTE: WE SWTICH Y AND Z TO MAKE THE EDGE FUNCTION WORK - triedge[t][v].x = model->vertices[model->faces[faces[t]][v].posi].x; - triedge[t][v].y = model->vertices[model->faces[faces[t]][v].posi].z; - triedge[t][v].z = model->vertices[model->faces[faces[t]][v].posi].y; + triedge[ofs + v].x = model->vertices[model->faces[faces[t]][v].posi].x; + triedge[ofs + v].y = model->vertices[model->faces[faces[t]][v].posi].z; + heights[ofs + v] = model->vertices[model->faces[faces[t]][v].posi].y; } } - // Change frequency for trees + // Change frequency for subthings // ns.seed = 0; ns.frequency = 0.02; ns.fractal_type = FNL_FRACTAL_NONE; + // Pick a random place for a flower + struct vec2 flowerpos = {.x = triedge[0].x + 0.8 * RANDF(), + .y = triedge[0].y - 0.8 * RANDF()}; + float y = calc_barycentric(flowerpos.v, heights, triedge, 2); + if (y < 0.4 && y > 0) { + float nlayer = + fnlGetNoise2D(&ns, noisex + flowerpos.x, noisey + flowerpos.y); + float scale = 0.04; + float vertscale = scale; // * CHUNKSCALE * 4; + if (RANDF() < -nlayer) { + haloo3d_obj_addobj( + model, redflower, + (struct vec3){ + .x = flowerpos.x, .y = y + vertscale * 0.5, .z = flowerpos.y}, + (struct vec3)DEFAULTLOOK, + //(struct vec3){.x = -sin(MPI * 0.25), .y = 0, .z = -cos(MPI * + // 0.25)}, + (struct vec3)DEFAULTUP, + (struct vec3){.x = scale, .y = vertscale, .z = scale}); + } + } for (int t = 0; t < MAXTREEPERCELL; t++) { // We know that the first vec in the first triangle is bl, which is our // base to start generating trees struct vec2 treepos = { - .x = triedge[0][0].x + + .x = triedge[0].x + (1.0 / MAXTREEACROSS) * ((t % MAXTREEACROSS) + (1.0 - MAXTREECLOSENESS) * RANDF()), - .y = triedge[0][0].y - + .y = triedge[0].y - ((1.0 / MAXTREEACROSS) * ((int)(t / MAXTREEACROSS) + (1.0 - MAXTREECLOSENESS) * RANDF()))}; - mfloat_t we[3]; - for (int i = 0; i < 2; i++) { - we[0] = haloo3d_edgefunc(triedge[i][1].v, triedge[i][2].v, treepos.v); - we[1] = haloo3d_edgefunc(triedge[i][2].v, triedge[i][0].v, treepos.v); - we[2] = haloo3d_edgefunc(triedge[i][0].v, triedge[i][1].v, treepos.v); - if (we[0] < 0 || we[1] < 0 || we[2] < 0) { - continue; - } - // We know this is the triangle to check. Let's figure out a y. - // NOTE: WE SWTICH Y AND Z TO MAKE THE EDGE FUNCTION WORK - float y = we[0] * triedge[i][0].z + we[1] * triedge[i][1].z + - we[2] * triedge[i][2].z; - float pick = RANDF(); // pow(RANDF(), 2); - if (pick < y * - (1 + fnlGetNoise2D(&ns, noisex + treepos.x, - noisey + treepos.y)) * - 0.5) { - // y * (1 + fnlGetNoise2D(&ns, treepos.x, treepos.y)) * 0.5) { - float scale = 0.1 + RANDF() * 0.05; - float height = 0.5 + RANDF() * 0.5; - haloo3d_obj_addobj( - model, tree, - (struct vec3){ - .x = treepos.x, .y = y + scale * height, .z = treepos.y}, - (struct vec3)DEFAULTLOOK, (struct vec3)DEFAULTUP, - (struct vec3){.x = scale, .y = scale * height, .z = scale}); - } + float y = calc_barycentric(treepos.v, heights, triedge, 2); + float pick = RANDF(); // pow(RANDF(), 2); + float nlayer = fnlGetNoise2D(&ns, noisex + treepos.x, noisey + treepos.y); + if (pick < y * (1 + nlayer) * 0.5) { + float scale = 0.1 + RANDF() * 0.05; + float height = 0.5 + RANDF() * 0.5; + haloo3d_obj_addobj( + model, tree, + (struct vec3){ + .x = treepos.x, .y = y + scale * height, .z = treepos.y}, + (struct vec3)DEFAULTLOOK, (struct vec3)DEFAULTUP, + (struct vec3){.x = scale, .y = scale * height, .z = scale}); } } } - haloo3d_obj_shrinktofit(model); + // uint16_t stoplighting = model->numfaces; + // for (int i = 0; i < CHUNKVSIZE * (CHUNKVSIZE - 1); i++) { + // if ((i & CHUNKSIZE) == CHUNKSIZE) { + // continue; + // } + // uint16_t bl = i; + // } + // haloo3d_obj_shrinktofit(model); + // return stoplighting; } void gen_cloud(render_context *ctx, tecs *ecs, struct vec3i pos) { @@ -218,6 +254,7 @@ void gen_cloud(render_context *ctx, tecs *ecs, struct vec3i pos) { .texture = haloo3d_easystore_gettex(&ecs->storage, PALETTEKEY), .scale = {.x = 1 + RANDF(), .y = 1.0 / CLOUDSTRETCH, .z = 1}, .lighting = NULL, //&ecs->chunklight, + //.stoplighting = 0, .model = cloud, .cullbackface = 1, .context = {ctx}, @@ -249,6 +286,7 @@ void gen_chunk(render_context *ctx, tecs *ecs, struct vec3i pos) { .texture = haloo3d_easystore_gettex(&ecs->storage, PALETTEKEY), .scale = {.x = CHUNKSCALE, .y = CHUNKSCALE * LANDHEIGHT, .z = CHUNKSCALE}, .lighting = &ecs->chunklight, + //.stoplighting = stoplighting, .model = model, .cullbackface = 1, .context = {ctx}, @@ -641,6 +679,8 @@ int main() { // int argc, char **argv) { gen_tree_model(treemodel); haloo3d_obj *cloudmodel = haloo3d_easystore_addobj(&ecs.storage, CLOUDKEY); gen_circle_model(cloudmodel, CLOUDCOL, 32); + haloo3d_obj *redflower = haloo3d_easystore_addobj(&ecs.storage, REDFLOWERKEY); + gen_flower(redflower, REDFLOWERCOL); eprintf("Setup ECS system + obj/tex storage (%d bytes)\n", tecs_size); diff --git a/terrain_ecstypes.h b/terrain_ecstypes.h index ebb6be3..e204aa7 100644 --- a/terrain_ecstypes.h +++ b/terrain_ecstypes.h @@ -51,6 +51,7 @@ typedef struct { object_lighting *lighting; // a pointer to lighting, null for none haloo3d_obj *model; haloo3d_fb *texture; + // uint16_t stoplighting; uint8_t cullbackface; // Whether to cull backfaces (you probably should) uint8_t contextcount; // How many contexts we render into float flatdither; // A flat dither amount. Set to -1 to disable