1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
/* SPDX-License-Identifier: MIT */
/*
* konworld.h
*
* Copyright (c) 2026 KonAki
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef KONWORLD_H
#define KONWORLD_H
#include "konmath.h"
#include "kontile.h"
#include "kon3d.h"
#include "konsector.h"
/*** definition ***/
/* one place to ask "can I stand here, can I walk there" for everything a 3d game is built from: the rooms of a sector map,
a terrain, a tilemap, and any shapes you add yourself. x and z are the plan, y is up. a world only points at the maps and the
terrain, they stay yours and can change between frames. nothing here knows what a door or a monster is, a door is a box that
the game moves */
#define KON_NO_GROUND (-1.0e30f)
typedef enum kon_colliderType {
KON_COLLIDER_NONE = 0,
KON_COLLIDER_BOX, /* min and max, sides line up with the axes */
KON_COLLIDER_CYLINDER, /* standing on the ground, center is the middle of its bottom */
KON_COLLIDER_SPHERE, /* blocks only, you can't stand on one */
KON_COLLIDER_PLANE /* everything behind the plane is solid. a plane that faces mostly up is a floor, a ramp if it is tilted */
} kon_colliderType_t;
typedef struct kon_collider {
int type;
int enabled; /* 0 and it is ignored, 1 */
int user; /* yours, like the entity this belongs to */
kon_vec3_t min, max; /* box */
kon_vec3_t center; /* cylinder, sphere */
float radius, height; /* cylinder, sphere (no height) */
kon_vec3_t normal; /* plane, the side it faces, length 1. points p with dot(normal, p) < offset are solid */
float offset;
} kon_collider_t;
kon_collider_t kon_colliderBox(kon_vec3_t min, kon_vec3_t max);
kon_collider_t kon_colliderCylinder(kon_vec3_t bottom, float radius, float height);
kon_collider_t kon_colliderSphere(kon_vec3_t center, float radius);
kon_collider_t kon_colliderPlane(kon_vec3_t point, kon_vec3_t normal);
typedef struct kon_world {
const kon_sectorMap_t *sectors; /* any of these three can be NULL */
const kon_terrain_t *terrain;
const kon_tilemap_t *tiles; /* one unit per tile like the rest of kon3d */
const uint8_t *solid; /* indexed by tile id like kon_tilemapMove */
int solidCount;
float tileHeight; /* how tall the solid tiles are, 1 */
kon_collider_t *colliders;
int colliderCount, colliderCap;
float gravity; /* 20 */
float stepHeight; /* the biggest step you walk up without jumping, 0.35 */
float maxSlope; /* rise over run you can climb on terrain, 1 is 45 degrees */
} kon_world_t;
/* a thing that walks. position is where the feet are, the body is a cylinder going up from there */
typedef struct kon_body {
kon_vec3_t position;
float radius, height; /* 0.2 and 1.0 are fine for a person in this scale */
float vy; /* up speed, only jumps and falls change it */
int onGround;
int sector; /* the room it is in, -1 if none, kept up to date by kon_worldMove */
int touching; /* the collider it was pushed by in the last move, -1 if none. a monster hitting a door, say */
} kon_body_t;
/*** the world ***/
void kon_worldInit(kon_world_t *world);
void kon_worldFree(kon_world_t *world);
/* returns the index, or -1 if there is no memory. the index stays the same until the collider is removed */
int kon_worldAdd(kon_world_t *world, kon_collider_t collider);
/* NULL if the index is not a collider. change it any time, a door opens by raising min.y */
kon_collider_t *kon_worldCollider(kon_world_t *world, int index);
void kon_worldRemove(kon_world_t *world, int index);
/* the height of the highest thing to stand on at x, z that is not more than a step above feet, or KON_NO_GROUND outside the world.
hint is the sector you were in, -1 if you have none. sector gets the room the point is in, it can be NULL */
float kon_worldGround(const kon_world_t *world, float x, float z, float feet, int hint, int *sector);
/*** bodies ***/
void kon_bodyInit(kon_body_t *body, float x, float y, float z, float radius, float height);
void kon_bodyJump(kon_body_t *body, float speed);
/* puts the feet on the ground under them right away */
void kon_worldPlace(const kon_world_t *world, kon_body_t *body);
/* moves by dx, dz and slides along whatever is in the way: walls, shapes, steps that are too high, slopes that are too steep, the edge
of the world. then gravity: steps up are taken at once and drops are falls. dt is seconds */
void kon_worldMove(kon_world_t *world, kon_body_t *body, float dx, float dz, double dt);
#endif
|