This commit is contained in:
Carlos Sanchez 2024-09-20 23:37:58 -04:00
parent a1182995ae
commit 1db028c814
2 changed files with 106 additions and 70 deletions

View File

@ -18,6 +18,10 @@
#define TREETRUNKWIDTH 0.2 #define TREETRUNKWIDTH 0.2
#endif #endif
#define COMVERT(m, _x, _y, _z) \
haloo3d_obj_addvertex(m, (struct vec4){.x = _x, .y = _y, .z = _z, .w = 1})
#define COMCOL(m, col) haloo3d_obj_addvtexture(m, haloo3d_gen_paletteuv(col))
// Fill a face with a solid color given by the tex // Fill a face with a solid color given by the tex
void fastface(haloo3d_facei face, uint16_t tex, uint16_t v0, uint16_t v1, void fastface(haloo3d_facei face, uint16_t tex, uint16_t v0, uint16_t v1,
uint16_t v2) { uint16_t v2) {
@ -29,42 +33,53 @@ void fastface(haloo3d_facei face, uint16_t tex, uint16_t v0, uint16_t v1,
face[2].posi = v2; face[2].posi = v2;
} }
static inline uint16_t fastface2(haloo3d_obj *model, uint16_t tex, uint16_t v0,
uint16_t v1, uint16_t v2) {
haloo3d_facei face;
fastface(face, tex, v0, v1, v2);
return haloo3d_obj_addface(model, face);
}
// Generate a basic tree model // Generate a basic tree model
void gen_tree_model(haloo3d_obj *tree) { void gen_tree_model(haloo3d_obj *tree) {
haloo3d_obj_resetfixed(tree, 12, 24); haloo3d_obj_resetfixed(tree, 12, 24);
struct vec3 treecol = haloo3d_gen_paletteuv(TREECOL); int treeuv = COMCOL(tree, TREECOL);
int treeuv = haloo3d_obj_addvtexture(tree, treecol); int trunkuv = COMCOL(tree, TREETRUNKCOL);
struct vec3 trunkcol = haloo3d_gen_paletteuv(TREETRUNKCOL); uint16_t top = COMVERT(tree, 0, 1, 0);
int trunkuv = haloo3d_obj_addvtexture(tree, trunkcol); uint16_t tree1 = COMVERT(tree, -TREETOPWIDTH, TREEBOTTOM, -TREETOPWIDTH);
// clang-format off uint16_t tree2 = COMVERT(tree, TREETOPWIDTH, TREEBOTTOM, -TREETOPWIDTH);
uint16_t top = haloo3d_obj_addvertex(tree, uint16_t tree3 = COMVERT(tree, 0, TREEBOTTOM, TREETOPWIDTH);
(struct vec4){.x = 0, .y = 1, .z = 0, .w = 1}); uint16_t trunk1 = COMVERT(tree, -TREETRUNKWIDTH, -1, -TREETRUNKWIDTH);
uint16_t tree1 = haloo3d_obj_addvertex(tree, uint16_t trunk2 = COMVERT(tree, TREETRUNKWIDTH, -1, -TREETRUNKWIDTH);
(struct vec4){.x = -TREETOPWIDTH, .y = TREEBOTTOM, .z = -TREETOPWIDTH, .w = 1}); uint16_t trunk3 = COMVERT(tree, 0, -1, TREETRUNKWIDTH);
uint16_t tree2 = haloo3d_obj_addvertex(tree, fastface2(tree, treeuv, top, tree1, tree3);
(struct vec4){.x = TREETOPWIDTH, .y = TREEBOTTOM, .z = -TREETOPWIDTH, .w = 1}); fastface2(tree, treeuv, top, tree3, tree2);
uint16_t tree3 = haloo3d_obj_addvertex(tree, fastface2(tree, treeuv, top, tree2, tree1);
(struct vec4){.x = 0, .y = TREEBOTTOM, .z = TREETOPWIDTH, .w = 1}); fastface2(tree, trunkuv, top, trunk1, trunk3);
uint16_t trunk1 = haloo3d_obj_addvertex(tree, fastface2(tree, trunkuv, top, trunk3, trunk2);
(struct vec4){ .x = -TREETRUNKWIDTH, .y = -1, .z = -TREETRUNKWIDTH, .w = 1}); fastface2(tree, trunkuv, top, trunk2, trunk1);
uint16_t trunk2 = haloo3d_obj_addvertex(tree,
(struct vec4){ .x = TREETRUNKWIDTH, .y = -1, .z = -TREETRUNKWIDTH, .w = 1});
uint16_t trunk3 = haloo3d_obj_addvertex(tree,
(struct vec4){.x = 0, .y = -1, .z = TREETRUNKWIDTH, .w = 1});
// clang-format on
haloo3d_facei face;
fastface(face, treeuv, top, tree1, tree3);
haloo3d_obj_addface(tree, face);
fastface(face, treeuv, top, tree3, tree2);
haloo3d_obj_addface(tree, face);
fastface(face, treeuv, top, tree2, tree1);
haloo3d_obj_addface(tree, face);
fastface(face, trunkuv, top, trunk1, trunk3);
haloo3d_obj_addface(tree, face);
fastface(face, trunkuv, top, trunk3, trunk2);
haloo3d_obj_addface(tree, face);
fastface(face, trunkuv, top, trunk2, trunk1);
haloo3d_obj_addface(tree, face);
haloo3d_obj_shrinktofit(tree); haloo3d_obj_shrinktofit(tree);
} }
void gen_circle_model(haloo3d_obj *model, uint16_t color, int vertices) {
haloo3d_obj_resetfixed(model, vertices, vertices + 1);
int circleuv = COMCOL(model, color);
// Add the center
uint16_t middle = COMVERT(model, 0, 0, 0);
// Go in a circle of course
float angle = 0;
float angle_inc = MPI * 2 / vertices;
uint16_t lastv = 0;
uint16_t firstv = 0;
for (int i = 0; i < vertices; i++) {
uint16_t thisv = COMVERT(model, cos(angle), sin(angle), 0);
if (i == 0) {
firstv = thisv;
} else {
fastface2(model, circleuv, middle, lastv, thisv);
}
angle += angle_inc;
lastv = thisv;
}
fastface2(model, circleuv, middle, lastv, firstv);
}

View File

@ -39,20 +39,29 @@
#define MAXCHUNKPERFRAME PLBOXEDGE #define MAXCHUNKPERFRAME PLBOXEDGE
// Generation consts / things for looks // Generation consts / things for looks
#define LANDHEIGHT 4.0
#define LANDCOL 0xF6D2 // 0xF4E1 #define LANDCOL 0xF6D2 // 0xF4E1
#define SEACOL 0xF28D // 0xF26C #define SEACOL 0xF28D // 0xF26C
#define LANDHEIGHT 4.0
#define SKYCOL 0xF97F // 0xF77F #define SKYCOL 0xF97F // 0xF77F
#define CLOUDCOL 0xFFFF
#define TREECOL 0xF070 #define TREECOL 0xF070
#define TREETRUNKCOL 0xF950 #define TREETRUNKCOL 0xF950
#define TREEBOTTOM -0.333 #define TREEBOTTOM -0.333
#define TREETRUNKWIDTH 0.2 #define TREETRUNKWIDTH 0.2
#define SEATRANS 0.75 #define SEATRANS 0.75
#define CLOUDTRANSMIN 0.1
#define CLOUDTRANSMAX 0.2
#define CLOUDHEIGHT 2
#define CLOUDSTRETCH 2
#define CLOUDCHANCE 0.1
#define INIT_LIGHTPITCH MPI_2 * 1.65 #define INIT_LIGHTPITCH MPI_2 * 1.65
#define INIT_LIGHTYAW MPI_2 * 0.65 #define INIT_LIGHTYAW MPI_2 * 0.65
#define INIT_MINLIGHT 0.2 #define INIT_MINLIGHT 0.2
#define INIT_DITHERSTART 3.5 #define INIT_DITHERSTART 3.5
#define INIT_DITHEREND VIEWDISTANCE - 0.5 #define INIT_DITHEREND VIEWDISTANCE - 0.5
#define MAXTREEPERCELL 9
#define MAXTREEACROSS 3
#define MAXTREECLOSENESS 0.2
// Player things // Player things
#define INIT_FOV 90.0 #define INIT_FOV 90.0
@ -68,6 +77,7 @@ int fps = 60;
#define PALETTEKEY "palette" #define PALETTEKEY "palette"
#define TREEKEY "tree" #define TREEKEY "tree"
#define CLOUDKEY "cloud"
#include "commonobj.c" #include "commonobj.c"
@ -78,8 +88,9 @@ void gen_terrain(struct vec3i pos, haloo3d_obj *model,
eprintf("Generating terrain at %d,%d\n", pos.x, pos.z); eprintf("Generating terrain at %d,%d\n", pos.x, pos.z);
haloo3d_obj *tree = haloo3d_easystore_getobj(storage, TREEKEY); haloo3d_obj *tree = haloo3d_easystore_getobj(storage, TREEKEY);
// Don't allow the model to have more than some amount of faces/vertices. // Don't allow the model to have more than some amount of faces/vertices.
haloo3d_obj_resetfixed(model, CHUNKVSIZE * CHUNKVSIZE * 16, haloo3d_obj_resetfixed(model, H3D_OBJ_MAXFACES, H3D_OBJ_MAXVERTICES);
CHUNKVSIZE * CHUNKVSIZE * 16); // CHUNKVSIZE * CHUNKVSIZE * 32,
// CHUNKVSIZE * CHUNKVSIZE * 32);
// if (rand() & 3) return; // if (rand() & 3) return;
struct vec3 landcol = haloo3d_gen_paletteuv(LANDCOL); // 0xF2C0); struct vec3 landcol = haloo3d_gen_paletteuv(LANDCOL); // 0xF2C0);
int landuv = haloo3d_obj_addvtexture(model, landcol); int landuv = haloo3d_obj_addvtexture(model, landcol);
@ -122,30 +133,39 @@ void gen_terrain(struct vec3i pos, haloo3d_obj *model,
triedge[t][v].z = model->vertices[model->faces[faces[t]][v].posi].y; triedge[t][v].z = model->vertices[model->faces[faces[t]][v].posi].y;
} }
} }
// Change frequency for trees
// ns.seed = 0;
ns.frequency = 0.02;
ns.fractal_type = FNL_FRACTAL_NONE;
// Generate up to 4 trees per cell (usually not) // Generate up to 4 trees per cell (usually not)
for (int t = 0; t < 4; t++) { for (int t = 0; t < MAXTREEPERCELL; t++) {
// We know that the first vec in the first triangle is bl, which is our // We know that the first vec in the first triangle is bl, which is our
// base to start generating trees // base to start generating trees
struct vec2 treepos = { struct vec2 treepos = {
.x = triedge[0][0].x + 0.5 * (t & 1) + 0.3 * RANDF(), .x = triedge[0][0].x +
.y = triedge[0][0].y - (0.5 * (t >> 1) + 0.3 * RANDF())}; (1.0 / MAXTREEACROSS) *
((t % MAXTREEACROSS) + (1.0 - MAXTREECLOSENESS) * RANDF()),
.y = triedge[0][0].y -
((1.0 / MAXTREEACROSS) * ((int)(t / MAXTREEACROSS) +
(1.0 - MAXTREECLOSENESS) * RANDF()))};
mfloat_t we[3]; mfloat_t we[3];
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
we[0] = haloo3d_edgefunc(triedge[i][1].v, triedge[i][2].v, treepos.v); 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[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); we[2] = haloo3d_edgefunc(triedge[i][0].v, triedge[i][1].v, treepos.v);
if (we[0] < 0 || we[1] < 0 || we[2] < 0) { if (we[0] < 0 || we[1] < 0 || we[2] < 0) {
// eprintf("BAD: %f,%f, (%f, %f)\n", treepos.x, treepos.y,
// model->vertices[bl].x, model->vertices[bl].z);
continue; continue;
} }
// We know this is the triangle to check. Let's figure out a y. // 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 // 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 + float y = we[0] * triedge[i][0].z + we[1] * triedge[i][1].z +
we[2] * triedge[i][2].z; we[2] * triedge[i][2].z;
// eprintf("TREE Y: %f\n", y); float pick = RANDF(); // pow(RANDF(), 2);
// For now, only generate trees if they're above a certain height if (pick < y *
if (RANDF() < 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 scale = 0.1 + RANDF() * 0.05;
float height = 0.5 + RANDF() * 0.5; float height = 0.5 + RANDF() * 0.5;
haloo3d_obj_addobj( haloo3d_obj_addobj(
@ -157,34 +177,30 @@ void gen_terrain(struct vec3i pos, haloo3d_obj *model,
} }
} }
} }
// struct vec4 corn = model->vertices[bl];
// if (corn.y > 0.1) {
// float scale = 0.1 + RANDF() * 0.05;
// float height = 0.5 + RANDF() * 0.5;
// // for (int b = 1; b <= 4; b++) {
// haloo3d_obj_addobj(
// model, tree,
// (struct vec3){.x = corn.x, .y = corn.y + scale * height, .z =
// corn.z}, (struct vec3)DEFAULTLOOK, (struct vec3)DEFAULTUP, (struct
// vec3){.x = scale, .y = scale * height, .z = scale});
// //}
// // haloo3d_obj_addobj(
// // model, tree,
// // (struct vec3){
// // .x = corn.x, .y = corn.y + scale * height * 2, .z = corn.z},
// // (struct vec3)DEFAULTLOOK, (struct vec3)DEFAULTUP,
// // (struct vec3){.x = scale, .y = scale * height, .z = scale});
// }
} }
// haloo3d_obj_addobj(
// model, tree,
// (struct vec3){.x = CHUNKSIZE / 2.0, .y = 1.0, .z = -CHUNKSIZE / 2.0},
// (struct vec3)DEFAULTLOOK, (struct vec3)DEFAULTUP,
// (struct vec3){.x = 1.0, .y = 1.0, .z = 1.0});
haloo3d_obj_shrinktofit(model); haloo3d_obj_shrinktofit(model);
} }
void gen_cloud(render_context *ctx, tecs *ecs, struct vec3i pos) {
haloo3d_obj *cloud = haloo3d_easystore_getobj(&ecs->storage, CLOUDKEY);
ecs_eid cloudid = tecs_newentity(ecs, 0);
ECS_SETCOMPONENT(ecs, cloudid, ecs_playergarbage){};
ECS_SETCOMPONENT(ecs, cloudid, ecs_placement){
.up = DEFAULTUP,
.lookvec = DEFAULTLOOK,
.pos = {
.x = pos.x + RANDF(), .y = CLOUDHEIGHT + 0.0 * RANDF(), .z = pos.z}};
ECS_SETCOMPONENT(ecs, cloudid, ecs_object){
.flatdither = CLOUDTRANSMIN + (CLOUDTRANSMAX - CLOUDTRANSMIN) * RANDF(),
.texture = haloo3d_easystore_gettex(&ecs->storage, PALETTEKEY),
.scale = {.x = 1 + RANDF(), .y = 1.0 / CLOUDSTRETCH, .z = 1},
.lighting = NULL, //&ecs->chunklight,
.model = cloud,
.cullbackface = 1,
.context = {ctx},
.contextcount = 1};
}
// Generate the entity/components/terrain for the chunk at the given // Generate the entity/components/terrain for the chunk at the given
// coordinates. // coordinates.
// NOTE: chunks are per x/y tile (terrain inside is just scaled // NOTE: chunks are per x/y tile (terrain inside is just scaled
@ -214,6 +230,9 @@ void gen_chunk(render_context *ctx, tecs *ecs, struct vec3i pos) {
.cullbackface = 1, .cullbackface = 1,
.context = {ctx}, .context = {ctx},
.contextcount = 1}; .contextcount = 1};
// Generate a cloud
if (RANDF() < CLOUDCHANCE)
gen_cloud(ctx, ecs, pos);
} }
void player_chunkload(ecs_placement *ppos, render_context *ctx, tecs *ecs) { void player_chunkload(ecs_placement *ppos, render_context *ctx, tecs *ecs) {
@ -594,6 +613,8 @@ int main() { // int argc, char **argv) {
haloo3d_gen_palettetex(palettetex); haloo3d_gen_palettetex(palettetex);
haloo3d_obj *treemodel = haloo3d_easystore_addobj(&ecs.storage, TREEKEY); haloo3d_obj *treemodel = haloo3d_easystore_addobj(&ecs.storage, TREEKEY);
gen_tree_model(treemodel); gen_tree_model(treemodel);
haloo3d_obj *cloudmodel = haloo3d_easystore_addobj(&ecs.storage, CLOUDKEY);
gen_circle_model(cloudmodel, CLOUDCOL, 32);
eprintf("Setup ECS system + obj/tex storage (%d bytes)\n", tecs_size); eprintf("Setup ECS system + obj/tex storage (%d bytes)\n", tecs_size);