diff options
| author | KonAki <konaki@anokonaki.org> | 2026-10-11 16:56:18 +0800 |
|---|---|---|
| committer | KonAki <konaki@anokonaki.org> | 2026-10-11 16:56:18 +0800 |
| commit | 34798983688b97bfddc7f5c53ee07b618fed9e17 (patch) | |
| tree | 877a48012351223f99b0df5f75efb04c49976be1 /examples/sectorview.c | |
| parent | 78f5f7c803494ae2108b98ff1a646f8c571d040c (diff) | |
sectorview: door and button are flat panels facing their angle
Diffstat (limited to 'examples/sectorview.c')
| -rw-r--r-- | examples/sectorview.c | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/examples/sectorview.c b/examples/sectorview.c index beafc36..dadd0b1 100644 --- a/examples/sectorview.c +++ b/examples/sectorview.c @@ -41,10 +41,10 @@ typedef struct state { kon_sectorMesh_t *mesh; kon_image *images[MAX_TEXTURES]; kon_material_t materials[MAX_TEXTURES]; - kon_image *marker; kon_fp_t input; /* only used for the mouse and keys, the position is ours */ kon_world_t world; kon_body_t body; + kon_material_t doorMaterial, buttonMaterial; kon_vec3_t eye; float feet; /* what the eyes follow, it catches up with the body after a step */ int door[MAX_ENTITIES]; /* the collider of a door entity, -1 for the others */ @@ -174,6 +174,23 @@ static void update(kon_program_t *program, double dt, void *user) if (state->body.onGround == 0) state->feet = state->body.position.y; } +/* a flat rectangle standing on the entity's position, facing the way it does. the door is a thing the program moves, so this is + all the engine knows about it. lift slides it up, the bottom edge is the entity's y (the middle for a small one) */ +static void drawPanel(kon_framebuffer_t *fb, kon_mat4_t vp, const kon_entity_t *e, float width, float height, float lift, + const kon_material_t *material, const kon_light_t *light) +{ + float rx = -cosf(e->angle) * width * 0.5f, rz = -sinf(e->angle) * width * 0.5f; + float bottom = e->position.y + lift - (height < 0.5f ? height * 0.5f : 0.0f); + kon_vec3_t normal = KON_VEC3(sinf(e->angle), 0.0f, -cosf(e->angle)); + kon_vertex_t bl = { KON_VEC3(e->position.x - rx, bottom, e->position.z - rz), normal, KON_VEC2(0, 1) }; + kon_vertex_t br = { KON_VEC3(e->position.x + rx, bottom, e->position.z + rz), normal, KON_VEC2(1, 1) }; + kon_vertex_t tr = { KON_VEC3(e->position.x + rx, bottom + height, e->position.z + rz), normal, KON_VEC2(1, 0) }; + kon_vertex_t tl = { KON_VEC3(e->position.x - rx, bottom + height, e->position.z - rz), normal, KON_VEC2(0, 0) }; + + kon_drawTriangle3D(fb, vp, bl, br, tr, material, light, KON_RENDER_DEPTH); + kon_drawTriangle3D(fb, vp, bl, tr, tl, material, light, KON_RENDER_DEPTH); +} + static void draw(kon_program_t *program, kon_framebuffer_t *game, void *user) { state_t *state = user; @@ -197,13 +214,17 @@ static void draw(kon_program_t *program, kon_framebuffer_t *game, void *user) light.ambient = 0.5f; kon_sectorDraw(game, &camera, state->mesh, state->materials, state->map->textureCount, &light); - /* things without a picture of their own are shown as markers, a door slides up as it opens */ for (i = 0; i < state->map->entityCount; i++) { const kon_entity_t *e = &state->map->entities[i]; - float lift = i < MAX_ENTITIES ? state->open[i] * 1.5f : 0.0f; - if (strcmp(e->kind, "spawn") == 0 || strcmp(e->kind, "light") == 0) continue; - kon_drawBillboard(game, vp, KON_VEC3(e->position.x, e->position.y + lift, e->position.z), 0.3f, 0.4f, state->marker, KON_RECT(0, 0, 0, 0), 1.0f, KON_RENDER_DEPTH); + if (strcmp(e->kind, "door") == 0) { + float width = kon_entityFloat(e, "width", 1.2f), height = kon_entityFloat(e, "height", 2.2f); + float lift = i < MAX_ENTITIES ? state->open[i] * height : 0.0f; + + drawPanel(game, vp, e, width, height, lift, &state->doorMaterial, &light); + } else if (strcmp(e->kind, "button") == 0) { + drawPanel(game, vp, e, 0.2f, 0.2f, 0.0f, &state->buttonMaterial, &light); + } } kon_fillRectangle(game, game->width / 2 - 3, game->height / 2, 7, 1, COL_NOTE); @@ -229,8 +250,7 @@ static int init(kon_program_t *program, void *user) return 0; } state->mesh = kon_sectorBuild(state->map); - state->marker = makeMarker(); - if (!state->mesh || !state->marker || state->map->textureCount > MAX_TEXTURES) return 0; + if (!state->mesh || state->map->textureCount > MAX_TEXTURES) return 0; for (i = 0; i < state->map->textureCount; i++) { state->images[i] = makeTexture(state->map->textures[i]); @@ -248,6 +268,8 @@ static int init(kon_program_t *program, void *user) break; } } + state->doorMaterial = kon_materialColor(0xFF8A7A50); + state->buttonMaterial = kon_materialColor(0xFFF2A7C3); kon_worldInit(&state->world); state->world.sectors = state->map; for (i = 0; i < MAX_ENTITIES; i++) state->door[i] = -1; @@ -278,7 +300,6 @@ static void shutdown(kon_program_t *program, void *user) (void)program; for (i = 0; i < state->map->textureCount; i++) kon_freeFramebuffer(state->images[i]); - kon_freeFramebuffer(state->marker); kon_sectorMeshFree(state->mesh); kon_worldFree(&state->world); kon_sectorFree(state->map); |
