code: many improvements and fixes
Changelog:
- fixed world repetition bug caused by wrong indexing 🎉
- wall collisions
- tile-based drag movement multiplier
- various optimizations
- raised default NPC count to 10k
isolation_bkp/dynres
parent
99a65431d8
commit
d0ff81b570
|
@ -19,6 +19,7 @@ char blocks_get_symbol(uint8_t id);
|
|||
uint32_t blocks_get_flags(uint8_t id);
|
||||
uint32_t blocks_get_biome(uint8_t id);
|
||||
uint32_t blocks_get_kind(uint8_t id);
|
||||
float blocks_get_drag(uint8_t id);
|
||||
|
||||
// NOTE(zaklaus): viewer-related functions
|
||||
void *blocks_get_img(uint8_t id);
|
||||
|
|
|
@ -28,8 +28,8 @@ uint64_t entity_spawn(char *name) {
|
|||
pos->x=rand() % world_dim();
|
||||
pos->y=rand() % world_dim();
|
||||
#else
|
||||
pos->x=35;
|
||||
pos->y=33;
|
||||
pos->x=350;
|
||||
pos->y=88;
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ int main(int argc, char** argv) {
|
|||
uint16_t num_viewers = zpl_opts_integer(&opts, "viewer-count", 1);
|
||||
uint16_t chunk_size = DEFAULT_CHUNK_SIZE; //zpl_opts_integer(&opts, "chunk-size", DEFAULT_CHUNK_SIZE);
|
||||
uint16_t world_size = zpl_opts_integer(&opts, "world-size", DEFAULT_WORLD_SIZE);
|
||||
uint32_t npc_count = zpl_opts_integer(&opts, "npc-count", 1000);
|
||||
uint32_t npc_count = zpl_opts_integer(&opts, "npc-count", 10000);
|
||||
|
||||
if (zpl_opts_has_arg(&opts, "random-seed")) {
|
||||
zpl_random rnd={0};
|
||||
|
|
|
@ -23,6 +23,7 @@ typedef struct {
|
|||
uint32_t kind;
|
||||
uint32_t biome;
|
||||
char symbol;
|
||||
float drag;
|
||||
|
||||
// NOTE(zaklaus): viewer data
|
||||
Texture2D img;
|
||||
|
@ -77,6 +78,10 @@ uint32_t blocks_get_kind(uint8_t id) {
|
|||
return blocks[id].kind;
|
||||
}
|
||||
|
||||
float blocks_get_drag(uint8_t id) {
|
||||
return blocks[id].drag;
|
||||
}
|
||||
|
||||
void *blocks_get_img(uint8_t id) {
|
||||
return (void*)&blocks[id].img;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
#include "world/blocks.h"
|
||||
|
||||
static block blocks[] = {
|
||||
{.name = "base-ground", .flags = 0, .kind = BLOCK_KIND_GROUND, .biome = 0, .symbol = '.'},
|
||||
{.name = "base-dirt", .flags = 0, .kind = BLOCK_KIND_DIRT, .biome = 0, .symbol = ','},
|
||||
{.name = "base-wall", .flags = BLOCK_FLAG_COLLISION, .kind = BLOCK_KIND_WALL, .biome = 0, .symbol = '#'},
|
||||
{.name = "base-hill", .flags = BLOCK_FLAG_COLLISION, .kind = BLOCK_KIND_HILL, .biome = 0, .symbol = '^'},
|
||||
{.name = "base-hill-snow", .flags = BLOCK_FLAG_COLLISION, .kind = BLOCK_KIND_HILL_SNOW, .biome = 0, .symbol = '*'},
|
||||
{.name = "base-water", .flags = BLOCK_FLAG_COLLISION, .kind = BLOCK_KIND_WATER, .biome = 0, .symbol = '~'},
|
||||
{.name = "base-ground", .flags = 0, .kind = BLOCK_KIND_GROUND, .biome = 0, .symbol = '.', .drag = 1.0f},
|
||||
{.name = "base-dirt", .flags = 0, .kind = BLOCK_KIND_DIRT, .biome = 0, .symbol = ',', .drag = 4.0f },
|
||||
{.name = "base-wall", .flags = BLOCK_FLAG_COLLISION, .kind = BLOCK_KIND_WALL, .biome = 0, .symbol = '#', .drag = 1.0f },
|
||||
{.name = "base-hill", .flags = BLOCK_FLAG_COLLISION, .kind = BLOCK_KIND_HILL, .biome = 0, .symbol = '^', .drag = 1.0f },
|
||||
{.name = "base-hill-snow", .flags = BLOCK_FLAG_COLLISION, .kind = BLOCK_KIND_HILL_SNOW, .biome = 0, .symbol = '*', .drag = 1.0f },
|
||||
{.name = "base-water", .flags = 0, .kind = BLOCK_KIND_WATER, .biome = 0, .symbol = '~', .drag = 0.11f },
|
||||
};
|
||||
|
|
|
@ -155,11 +155,10 @@ int32_t world_init(int32_t seed, uint16_t chunk_size, uint16_t chunk_amount) {
|
|||
world.block_mapping[i] = zpl_malloc(sizeof(uint8_t)*zpl_square(chunk_size));
|
||||
chunk->id = i;
|
||||
|
||||
for (int y = 0; y < world.chunk_size; y += 1) {
|
||||
for (int x = 0; x < world.chunk_size; x += 1) {
|
||||
int chk = world.chunk_size * i;
|
||||
int chk_x = chk % world.dim;
|
||||
int chk_y = chk / world.dim;
|
||||
for (int y = 0; y < chunk_size; y += 1) {
|
||||
for (int x = 0; x < chunk_size; x += 1) {
|
||||
int chk_x = chunk->x * chunk_size;
|
||||
int chk_y = chunk->y * chunk_size;
|
||||
uint8_t *c = &world.block_mapping[i][(y*chunk_size)+x];
|
||||
*c = world.data[(chk_y+y)*world.dim + (chk_x+x)];
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
#define WORLD_BLOCK_OBSERVER(name) uint8_t name(uint8_t id, uint32_t block_idx)
|
||||
typedef WORLD_BLOCK_OBSERVER(world_block_observer_proc);
|
||||
|
||||
#define WORLD_PERLIN_FREQ 9.34157f
|
||||
#define WORLD_PERLIN_OCTAVES 4
|
||||
#define WORLD_PERLIN_FREQ 100
|
||||
#define WORLD_PERLIN_OCTAVES 1
|
||||
|
||||
static world_data *world;
|
||||
|
||||
|
@ -83,7 +83,7 @@ static uint8_t world_perlin_cond(uint32_t block_idx, double chance) {
|
|||
uint32_t x = block_idx % world->dim;
|
||||
uint32_t y = block_idx / world->dim;
|
||||
|
||||
return perlin_fbm(world->seed, x+rand()%world->dim, y+rand()%world->dim, WORLD_PERLIN_FREQ, WORLD_PERLIN_OCTAVES) < chance;
|
||||
return perlin_fbm(world->seed, x, y, WORLD_PERLIN_FREQ, WORLD_PERLIN_OCTAVES) < chance;
|
||||
}
|
||||
|
||||
#if 1
|
||||
|
@ -138,11 +138,11 @@ int32_t worldgen_test(world_data *wld) {
|
|||
|
||||
// ground
|
||||
world_fill_rect(grnd_id, 1, 1, world->dim-2, world->dim-2, NULL);
|
||||
world_fill_rect(dirt_id, 1, 1, world->dim-2, world->dim-2, shaper_noise50);
|
||||
world_fill_rect(dirt_id, 1, 1, world->dim-2, world->dim-2, shaper_noise33);
|
||||
|
||||
// water
|
||||
#if 1
|
||||
for (int i=0; i<RAND_RANGE(8, 22); i++) {
|
||||
for (int i=0; i<RAND_RANGE(58, 92); i++) {
|
||||
world_fill_rect_anchor(watr_id, RAND_RANGE(0, world->dim), RAND_RANGE(0, world->dim), 4+RAND_RANGE(0,3), 4+RAND_RANGE(0,3), 0.5f, 0.5f, shaper_noise80);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -14,6 +14,7 @@ typedef struct {
|
|||
ECS_DECLARE_ENTITY(MoveWalk);
|
||||
ECS_DECLARE_ENTITY(UpdateTrackerPos);
|
||||
ECS_DECLARE_ENTITY(IntegratePositions);
|
||||
ECS_DECLARE_ENTITY(PushOutOverlappingEntities);
|
||||
} Physics;
|
||||
|
||||
#define PhysicsImportHandles(handles)\
|
||||
|
@ -24,5 +25,6 @@ ECS_IMPORT_COMPONENT(handles, Velocity);\
|
|||
ECS_IMPORT_ENTITY(handles, MoveWalk);\
|
||||
ECS_IMPORT_ENTITY(handles, UpdateTrackerPos);\
|
||||
ECS_IMPORT_ENTITY(handles, IntegratePositions);\
|
||||
ECS_IMPORT_ENTITY(handles, PushOutOverlappingEntities);\
|
||||
|
||||
void PhysicsImport(ecs_world_t *ecs);
|
||||
|
|
|
@ -21,7 +21,7 @@ void MovementImpulse(ecs_iter_t *it) {
|
|||
}
|
||||
|
||||
#define DEMO_NPC_CHANGEDIR_FACTOR 0.1
|
||||
#define DEMO_NPC_MOVE_SPEED 1000
|
||||
#define DEMO_NPC_MOVE_SPEED 1500
|
||||
|
||||
void DemoNPCMoveAround(ecs_iter_t *it) {
|
||||
Velocity *v = ecs_column(it, Velocity, 1);
|
||||
|
@ -47,8 +47,8 @@ void ControllersImport(ecs_world_t *ecs) {
|
|||
ECS_TAG(ecs, EcsBuilder);
|
||||
ECS_TAG(ecs, EcsDemoNPC);
|
||||
|
||||
ECS_SYSTEM(ecs, MovementImpulse, EcsOnUpdate, Input, physics.Velocity);
|
||||
ECS_SYSTEM(ecs, DemoNPCMoveAround, EcsOnUpdate, physics.Velocity, EcsDemoNPC);
|
||||
ECS_SYSTEM(ecs, MovementImpulse, EcsOnLoad, Input, physics.Velocity);
|
||||
ECS_SYSTEM(ecs, DemoNPCMoveAround, EcsOnLoad, physics.Velocity, EcsDemoNPC);
|
||||
|
||||
ECS_PREFAB(ecs, Base, general.Position, physics.Velocity, Input, EcsActor);
|
||||
ECS_TYPE(ecs, Player, INSTANCEOF | Base, SWITCH | physics.Movement, CASE | physics.Walking, EcsActor, EcsPlayer);
|
||||
|
|
|
@ -11,11 +11,14 @@
|
|||
#define PHY_CORRECTION(x) ((zpl_max(0.0f, (WORLD_BLOCK_SIZE/2.0f) - zpl_abs(x))*zpl_sign(x)))*(WORLD_BLOCK_SIZE/2.0f)
|
||||
|
||||
void MoveWalk(ecs_iter_t *it) {
|
||||
Velocity *v = ecs_column(it, Velocity, 1);
|
||||
Position *p = ecs_column(it, Position, 1);
|
||||
Velocity *v = ecs_column(it, Velocity, 2);
|
||||
|
||||
for (int i = 0; i < it->count; i++) {
|
||||
v[i].x = zpl_lerp(v[i].x, 0.0f, PHY_WALK_DRAG);
|
||||
v[i].y = zpl_lerp(v[i].y, 0.0f, PHY_WALK_DRAG);
|
||||
world_block_lookup lookup = world_block_from_realpos(p[i].x, p[i].y);
|
||||
float drag = blocks_get_drag(lookup.block_id);
|
||||
v[i].x = zpl_lerp(v[i].x, 0.0f, PHY_WALK_DRAG*drag);
|
||||
v[i].y = zpl_lerp(v[i].y, 0.0f, PHY_WALK_DRAG*drag);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,6 +61,64 @@ void IntegratePositions(ecs_iter_t *it) {
|
|||
}
|
||||
}
|
||||
|
||||
#define PHY_PUSHOUT_DIST ((64.0f*WORLD_BLOCK_SIZE))
|
||||
|
||||
void PushOutOverlappingEntities(ecs_iter_t *it) {
|
||||
Position *p = ecs_column(it, Position, 1);
|
||||
|
||||
for (int i = 0; i <= it->count; i++) {
|
||||
#if 1
|
||||
// NOTE(zaklaus): slow path. iterate over all the entities in the table.
|
||||
for (int k = 0; k <= it->count; k++) {
|
||||
if (i == k) continue;
|
||||
#else
|
||||
// TODO(zaklaus): use a shared internal buffer instead !!!
|
||||
static int64_t ents[UINT32_MAX];
|
||||
size_t ents_count = UINT32_MAX;
|
||||
librg_world_fetch_chunk(world_tracker(), librg_chunk_from_realpos(world_tracker(), p[i].x, p[i].y, 0), ents, &ents_count);
|
||||
|
||||
// NOTE(zaklaus): iterate over all entities inside this chunk
|
||||
for (size_t j = 0; j < ents_count; j++) {
|
||||
ecs_entity_t e = ents[j];
|
||||
|
||||
if (e == it->entities[i])
|
||||
continue;
|
||||
|
||||
// NOTE(zaklaus): reverse lookup
|
||||
int k = 0;
|
||||
for (; k <= it->count; k++) {
|
||||
if (k == it->count) {
|
||||
k = -1;
|
||||
break;
|
||||
}
|
||||
if (it->entities[k] == e) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (k == -1)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
float dx = p[i].x - p[k].x;
|
||||
float dy = p[i].y - p[k].y;
|
||||
float dist = zpl_sqrt(dx*dx + dy*dy);
|
||||
if (dist < PHY_PUSHOUT_DIST) {
|
||||
p[i].x = zpl_sign(dx);
|
||||
p[i].y = zpl_sign(dy);
|
||||
#if 0
|
||||
p[k].x += zpl_sign(dx);
|
||||
p[k].y += zpl_sign(dy);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
void UpdateTrackerPos(ecs_iter_t *it) {
|
||||
Position *p = ecs_column(it, Position, 1);
|
||||
|
||||
|
@ -76,8 +137,9 @@ void PhysicsImport(ecs_world_t *ecs) {
|
|||
|
||||
ECS_META(ecs, Velocity);
|
||||
|
||||
ECS_SYSTEM(ecs, MoveWalk, EcsOnUpdate, Velocity);
|
||||
ECS_SYSTEM(ecs, MoveWalk, EcsOnUpdate, general.Position, Velocity);
|
||||
ECS_SYSTEM(ecs, IntegratePositions, EcsOnValidate, general.Position, Velocity);
|
||||
//ECS_SYSTEM(ecs, PushOutOverlappingEntities, EcsOnValidate, general.Position, Velocity);
|
||||
ECS_SYSTEM(ecs, UpdateTrackerPos, EcsPostUpdate, general.Position);
|
||||
|
||||
ECS_SET_TYPE(Movement);
|
||||
|
@ -87,4 +149,5 @@ void PhysicsImport(ecs_world_t *ecs) {
|
|||
ECS_SET_ENTITY(MoveWalk);
|
||||
ECS_SET_ENTITY(UpdateTrackerPos);
|
||||
ECS_SET_ENTITY(IntegratePositions);
|
||||
ECS_SET_ENTITY(PushOutOverlappingEntities);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue