Setting up flower generation

This commit is contained in:
Carlos Sanchez 2024-09-21 08:54:58 -04:00
parent dcca92ee43
commit 20a8c65266
3 changed files with 90 additions and 36 deletions

View File

@ -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]);
}

112
terrain.c
View File

@ -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);

View File

@ -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