add is_stairs and generate trile heightmaps for triles
This commit is contained in:
parent
eeddecb63c
commit
c55f26178f
@ -498,7 +498,10 @@ add_trile :: (name: string, x: s32, y: s32, z: s32, orientation: u8 = 0) {
|
||||
array_add(*chunk.groups, group);
|
||||
}
|
||||
invalidate_buried_around(*curworld.world, x, y, z);
|
||||
chunk_set_occupancy_mask_at(chunk, lx, ly, lz, true);
|
||||
trile, ok := get_trile(name);
|
||||
if !ok || trile.skip_collision then return;
|
||||
new_state : Occupancy_State = ifx trile.is_stairs then .OCCUPIED_STAIRS else .OCCUPIED;
|
||||
chunk_set_occupancy_mask_at(chunk, lx, ly, lz, new_state);
|
||||
} @Command
|
||||
|
||||
remove_trile :: (x: s32, y: s32, z: s32) {
|
||||
@ -525,7 +528,7 @@ remove_trile :: (x: s32, y: s32, z: s32) {
|
||||
if removed break;
|
||||
}
|
||||
if removed invalidate_buried_around(*curworld.world, x, y, z);
|
||||
chunk_set_occupancy_mask_at(chunk, lx, ly, lz, false);
|
||||
chunk_set_occupancy_mask_at(chunk, lx, ly, lz, .FREE);
|
||||
} @Command
|
||||
|
||||
|
||||
|
||||
@ -64,6 +64,7 @@ ntrile :: (name: string) {
|
||||
newt.name = sprint("%", name);
|
||||
set_trile(newt.name, newt);
|
||||
editor_current_trile = get_trile(newt.name);
|
||||
trile_gen_heightmap(editor_current_trile);
|
||||
} @Command
|
||||
|
||||
cpytrile :: (trile: string, destination: string) {
|
||||
@ -73,6 +74,7 @@ cpytrile :: (trile: string, destination: string) {
|
||||
newt.trixels = get_trile(trile).trixels;
|
||||
set_trile(newt.name, newt);
|
||||
editor_current_trile = get_trile(newt.name);
|
||||
trile_gen_heightmap(editor_current_trile);
|
||||
} @Command
|
||||
|
||||
ltrile :: (name: string) {
|
||||
@ -83,6 +85,7 @@ ltrile :: (name: string) {
|
||||
return;
|
||||
}
|
||||
editor_current_trile = nt;
|
||||
trile_gen_heightmap(editor_current_trile);
|
||||
} @Command
|
||||
|
||||
#scope_file
|
||||
@ -104,6 +107,7 @@ do_undo :: () {
|
||||
undo_head = (undo_head - 1 + UNDO_MAX) % UNDO_MAX;
|
||||
undo_count -= 1;
|
||||
editor_current_trile.trixels = undo_trixels[undo_head];
|
||||
trile_gen_heightmap(editor_current_trile);
|
||||
}
|
||||
|
||||
do_redo :: () {
|
||||
@ -114,6 +118,7 @@ do_redo :: () {
|
||||
redo_head = (redo_head - 1 + UNDO_MAX) % UNDO_MAX;
|
||||
redo_count -= 1;
|
||||
editor_current_trile.trixels = redo_trixels[redo_head];
|
||||
trile_gen_heightmap(editor_current_trile);
|
||||
}
|
||||
|
||||
apply_tool_to_trixel :: (x: s64, y: s64, z: s64) {
|
||||
@ -187,7 +192,7 @@ handle_tool_click :: () {
|
||||
area_start_z = hovered_trixel_z;
|
||||
}
|
||||
}
|
||||
|
||||
trile_gen_heightmap(editor_current_trile);
|
||||
}
|
||||
|
||||
#scope_export
|
||||
@ -202,6 +207,7 @@ reset_trile :: () {
|
||||
}
|
||||
}
|
||||
}
|
||||
trile_gen_heightmap(editor_current_trile);
|
||||
} @Command
|
||||
|
||||
trile_copy :: (from: string) {
|
||||
@ -213,6 +219,7 @@ trile_copy :: (from: string) {
|
||||
}
|
||||
}
|
||||
}
|
||||
trile_gen_heightmap(editor_current_trile);
|
||||
} @Command
|
||||
|
||||
tick_trile_editor :: () {
|
||||
@ -577,6 +584,12 @@ draw_meta_tab :: (theme: *GR.Overall_Theme, area: GR.Rect) {
|
||||
r.h = row_h;
|
||||
changed := GR.base_checkbox(r, "Opaque (occludes neighbors)", editor_current_trile.is_opaque, *theme.checkbox_theme);
|
||||
if changed editor_current_trile.is_opaque = !editor_current_trile.is_opaque;
|
||||
r.y += row_h;
|
||||
changed = GR.base_checkbox(r, "Skip collision", editor_current_trile.skip_collision, *theme.checkbox_theme);
|
||||
if changed editor_current_trile.skip_collision = !editor_current_trile.skip_collision;
|
||||
r.y += row_h;
|
||||
changed = GR.base_checkbox(r, "Is stairs", editor_current_trile.is_stairs, *theme.checkbox_theme);
|
||||
if changed editor_current_trile.is_stairs = !editor_current_trile.is_stairs;
|
||||
r.y += row_h * 2;
|
||||
|
||||
r.h = row_h;
|
||||
|
||||
@ -3,10 +3,12 @@ is_trile_collision :: (fx: float, fy: float, fz: float) -> bool {
|
||||
y := cast(s32)floor(fy);
|
||||
z := cast(s32)floor(fz);
|
||||
world := get_current_world();
|
||||
if !world.valid then return false;
|
||||
|
||||
key := world_to_chunk_coord(x, y, z);
|
||||
chunk := table_find_pointer(*world.world.chunks, key);
|
||||
if !chunk then return false;
|
||||
|
||||
lx, ly, lz := world_to_local(x, y, z);
|
||||
return chunk_get_occupancy_mask_at(chunk, lx, ly, lz);
|
||||
return chunk_get_occupancy_mask_at(chunk, lx, ly, lz) != .FREE;
|
||||
}
|
||||
|
||||
@ -30,6 +30,22 @@ get_trile_table_ptr :: () -> *Table(string, Trile) {
|
||||
return *trile_table;
|
||||
}
|
||||
|
||||
trile_gen_heightmap :: (trile: *Trile) {
|
||||
for x: 0..15 {
|
||||
for z: 0..15 {
|
||||
height : u8 = 16;
|
||||
for y: 0..15 {
|
||||
if trile.trixels[x][15-y][z].empty == true {
|
||||
height -= 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
trile.heightmap[x][z] = height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// @Note: Creates the gfx things if they are not yet created.
|
||||
// Could be a bad idea to do this implicitly. Think about it
|
||||
// once it's more clear how this whole trile storage thing
|
||||
@ -215,23 +231,38 @@ Trile :: struct {
|
||||
name : string = "test";
|
||||
is_opaque : bool = true;
|
||||
trixels : [16][16][16] Trixel;
|
||||
|
||||
skip_collision : bool;
|
||||
|
||||
// if the trile is something that should
|
||||
// be able to be used so that the player
|
||||
// moves in the Y direction, it needs to
|
||||
// be marked as stairs and a heightmap
|
||||
// in the Y axis is generated for it.
|
||||
is_stairs : bool;
|
||||
heightmap : [16][16]u8;
|
||||
};
|
||||
|
||||
TrixelSerialize :: [5]u8;
|
||||
|
||||
TrileSerialize :: struct {
|
||||
name : string = "test";
|
||||
version : int = 0;
|
||||
is_opaque : u8 = 1;
|
||||
trixels : [16][16][16] TrixelSerialize;
|
||||
name : string = "test";
|
||||
version : int = 0;
|
||||
is_opaque : u8 = 1;
|
||||
is_stairs : u8 = 0;
|
||||
skip_collision : u8 = 0;
|
||||
trixels : [16][16][16] TrixelSerialize;
|
||||
};
|
||||
|
||||
trile_to_serialize_form :: (t: Trile) -> TrileSerialize {
|
||||
ts := TrileSerialize.{
|
||||
name = t.name,
|
||||
version = 2,
|
||||
is_opaque = ifx t.is_opaque then cast(u8)1 else cast(u8)0,
|
||||
name = t.name,
|
||||
version = 3,
|
||||
is_opaque = ifx t.is_opaque then cast(u8)1 else cast(u8)0,
|
||||
is_stairs = ifx t.is_stairs then cast(u8)1 else cast(u8)0,
|
||||
skip_collision = ifx t.skip_collision then cast(u8)1 else cast(u8)0,
|
||||
};
|
||||
|
||||
for i: 0..15 {
|
||||
for j: 0..15 {
|
||||
for k: 0..15 {
|
||||
@ -247,6 +278,10 @@ trile_from_serialize_form :: (ts: TrileSerialize) -> Trile {
|
||||
t := Trile.{ name = sprint("%", ts.name) };
|
||||
if ts.version >= 2 t.is_opaque = ts.is_opaque != 0;
|
||||
else t.is_opaque = true;
|
||||
if ts.version >= 3 t.is_stairs = ts.is_stairs != 0;
|
||||
else t.is_stairs = false;
|
||||
if ts.version >= 3 t.skip_collision = ts.skip_collision != 0;
|
||||
else t.skip_collision = false;
|
||||
for i: 0..15 {
|
||||
for j: 0..15 {
|
||||
for k: 0..15 {
|
||||
@ -270,6 +305,7 @@ trile_from_serialize_form :: (ts: TrileSerialize) -> Trile {
|
||||
}
|
||||
}
|
||||
}
|
||||
trile_gen_heightmap(*t);
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
@ -63,23 +63,42 @@ Chunk :: struct {
|
||||
// that is useful when we're checking for ground under
|
||||
// entities
|
||||
occupancy_mask : [32][32]u32;
|
||||
// We want to be easily able to identify stairs from the chunk.
|
||||
stairs_mask : [32][32]u32;
|
||||
|
||||
sh_probe_grid: sg_image; // 192x4096 RGBA16F 2D texture (2 probes/trile/axis)
|
||||
sh_valid: bool;
|
||||
sh_dirty: bool;
|
||||
}
|
||||
|
||||
// @Note: these are local coords inside the chunk
|
||||
chunk_get_occupancy_mask_at :: inline (chunk: *Chunk, lx: u32, ly: u32, lz: u32) -> bool {
|
||||
return (chunk.occupancy_mask[lx][lz] & (cast(u32)1 << ly)) != 0;
|
||||
Occupancy_State :: enum {
|
||||
FREE;
|
||||
OCCUPIED;
|
||||
OCCUPIED_STAIRS;
|
||||
}
|
||||
|
||||
// @Note: these are local coords inside the chunk
|
||||
chunk_set_occupancy_mask_at :: inline (chunk: *Chunk, lx: u32, ly: u32, lz: u32, occupied: bool) {
|
||||
if occupied {
|
||||
chunk.occupancy_mask[lx][lz] |= (cast(u32)1 << ly);
|
||||
chunk_get_occupancy_mask_at :: inline (chunk: *Chunk, lx: u32, ly: u32, lz: u32) -> Occupancy_State {
|
||||
if (chunk.occupancy_mask[lx][lz] & (cast(u32)1 << ly)) != 0 {
|
||||
if (chunk.stairs_mask[lx][lz] & (cast(u32)1 << ly)) != 0 then return .OCCUPIED_STAIRS;
|
||||
return .OCCUPIED;
|
||||
}
|
||||
return .FREE;
|
||||
}
|
||||
|
||||
// @Note: these are local coords inside the chunk
|
||||
chunk_set_occupancy_mask_at :: inline (chunk: *Chunk, lx: u32, ly: u32, lz: u32, occupied: Occupancy_State) {
|
||||
if occupied != .FREE {
|
||||
if occupied == .OCCUPIED_STAIRS {
|
||||
chunk.occupancy_mask[lx][lz] |= (cast(u32)1 << ly);
|
||||
chunk.stairs_mask[lx][lz] |= (cast(u32)1 << ly);
|
||||
} else {
|
||||
chunk.occupancy_mask[lx][lz] |= (cast(u32)1 << ly);
|
||||
chunk.stairs_mask[lx][lz] &= ~(cast(u32)1 << ly);
|
||||
}
|
||||
} else {
|
||||
chunk.occupancy_mask[lx][lz] &= ~(cast(u32)1 << ly);
|
||||
chunk.stairs_mask[lx][lz] &= ~(cast(u32)1 << ly);
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,6 +106,7 @@ chunk_clear_full_occupancy_mask :: (chunk: *Chunk) {
|
||||
for i: 0..31 {
|
||||
for j: 0..31 {
|
||||
chunk.occupancy_mask[cast(u32)i][cast(u32)j] = 0;
|
||||
chunk.stairs_mask[cast(u32)i][cast(u32)j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -128,11 +148,12 @@ calculate_and_set_chunk_occupancy_mask :: (chunk: *Chunk) {
|
||||
chunk_clear_full_occupancy_mask(chunk);
|
||||
|
||||
for group: chunk.groups {
|
||||
// @ToDo: Handle non-colliding triles by getting the
|
||||
// trile data here and continuing if it's non-colliding.
|
||||
trile, ok := get_trile(group.trile_name);
|
||||
if !ok || trile.skip_collision then continue;
|
||||
new_state : Occupancy_State = ifx trile.is_stairs then .OCCUPIED_STAIRS else .OCCUPIED;
|
||||
|
||||
for instance : group.instances {
|
||||
|
||||
chunk_set_occupancy_mask_at(chunk, instance.x, instance.y, instance.z, true);
|
||||
chunk_set_occupancy_mask_at(chunk, instance.x, instance.y, instance.z, new_state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user