Files
coven/core/scene.jai
2024-10-11 22:21:32 +02:00

142 lines
3.7 KiB
Plaintext

#load "../renderer/directional_light.jai";
#load "particles.jai";
#placeholder Entity_Storage;
MAX_CACHED_PILES :: 8;
Scene :: struct {
name: string;
entities : [..] *Entity;
particle_systems : Bucket_Array(Particle_System, 64);
bullet_impact_particle_systems : [..] *Particle_System;
by_type : Entity_Storage;
pool : Flat_Pool;
allocator : Allocator;
camera : Camera;
directional_light : Directional_Light;
}
Entity_File_Info :: struct {
id: s64;
full_path: string;
}
visitor :: (info : *File_Visit_Info, files: *[..] Entity_File_Info) {
if info.is_directory
return;
path, basename, ext := path_decomp (info.full_name);
// Entity text files
if ext == "ent" && basename != "cam" {
file_info : Entity_File_Info;
file_info.id = cast(s32)string_to_int(basename);
file_info.full_path = copy_temporary_string(info.full_name);
array_add(files, file_info);
}
}
load_scene :: (path: string) -> *Scene {
scene := create_scene("", 1024);
files : [..] Entity_File_Info;
files.allocator = temp;
visit_files(path, true, *files, visitor);
for file: files {
deserialize_entity(scene, file.full_path);
}
return scene;
}
save_scene :: (scene: *Scene, path: string) {
scene.camera = game_state.camera;
builder : String_Builder;
builder.allocator = temp;
full_path := tprint("%/%", path, scene.name);
make_directory_if_it_does_not_exist(full_path);
for scene.entities {
if it.flags & .DONT_SAVE continue;
serialize_entity(it, full_path);
}
// Save camera
//print_to_builder(*builder, "Camera: % % % % %\n", scene.camera.position.x, scene.camera.position.y, scene.camera.position.z, scene.camera.rotation.yaw, scene.camera.rotation.pitch);
//write_entire_file(path, builder_to_string(*builder));
}
unload_scene :: (scene: *Scene) {
for e: scene.entities {
destroy_entity(e, false);
}
fini(*scene.pool);
free(scene);
}
create_scene :: (name: string, max_entities: s64 = 256) -> *Scene {
scene := New(Scene);
scene.name = copy_string(name);
// Setup allocator
scene.pool = .{};
scene.allocator.data = *scene.pool;
scene.allocator.proc = flat_pool_allocator_proc;
// Assign allocator to everything that needs allocations
scene.entities.allocator = scene.allocator;
scene.particle_systems.allocator = scene.allocator;
scene.bullet_impact_particle_systems.allocator = scene.allocator;
array_reserve(*scene.entities, max_entities);
scene.directional_light.color_and_intensity = .{1,1,1,1};
scene.directional_light.direction = to_v4(normalize(Vector3.{0.3, -0.3, 0.5}));
dir_light_data : Directional_Light_Buffer_Data;
dir_light_data.color_and_intensity = scene.directional_light.color_and_intensity;
dir_light_data.direction = scene.directional_light.direction;
upload_data_to_buffer(renderer, directional_light_buffer, *dir_light_data, size_of(Directional_Light_Buffer_Data));
array_resize(*scene.bullet_impact_particle_systems, 32);
for 0..31 {
scene.bullet_impact_particle_systems[it] = create_particle_system(particle_pipeline, on_update_bullet_hit_particles, null, scene);
}
return scene;
}
register_entity :: (scene: *Scene, entity: *Entity) {
entity.scene = scene;
entity.id = next_entity_id;
array_add(*scene.entities, entity);
next_entity_id += 1;
if net_data.net_mode == {
case .LISTEN_SERVER; #through;
case .DEDICATED_SERVER; {
//net_spawn_entity(entity);
}
}
}
unregister_entity :: (scene: *Scene, entity: *Entity) {
array_unordered_remove_by_value(*scene.entities, entity);
}
#scope_file
next_entity_id: Entity_Id;