Files
coven/core/entity.jai

195 lines
4.8 KiB
Plaintext

Entity_Id :: #type, isa s64;
Entity_Flags :: enum_flags u16 {
NONE;
RENDERABLE;
COLLISION;
PHYSICS;
STATIC;
TRIGGER;
ANIMATED;
SNAP_TO_GRID;
UNIFORM_SCALE;
DONT_SAVE;
DELETED;
}
Renderable_Type :: enum {
MODEL;
}
Entity_Material :: struct {
base_color : Vector4;
}
MAX_NODES :: 256;
Node_Render_Data :: struct {
enabled : bool = true;
transform: Transform;
material : Entity_Material;
has_sampled_animation: bool;
// Buffers
transform_buffer: Buffer_Handle;
material_buffer: Buffer_Handle;
bone_buffers : [MAX_BONES] Buffer_Handle;
num_bones: s64;
}
Renderable :: struct {
visible: bool = true;
type : Renderable_Type;
model: *Model;
nodes: [MAX_NODES] Node_Render_Data;
num_nodes: s64;
}
MAX_CHILDREN :: 16;
Entity :: struct {
id: Entity_Id;
type : Type;
enabled: bool = true;
name: string;
parent: *Entity; @DontSerialize
children: [MAX_CHILDREN] *Entity; @DontSerialize
num_children: s64; @DontSerialize
attach_node_index: s64 = -1; @DontSerialize
flags : Entity_Flags;
transform: Transform;
rendering_offset: Vector3;
snap_offset: Vector3;
snap_intervals: Vector3;
renderable: Renderable; @DontSerialize
animator: Animator; @DontSerialize
// Physics
body : Physics_Body; @DontSerialize
collider : Collider; @DontSerialize
// End physics
#if NETWORKING {
remote_id: Entity_Id; @DontSerialize
is_proxy: bool; @DontSerialize
last_replication_time: float; @DontSerialize
}
_locator: Bucket_Locator; @DontSerialize
scene: *Scene; @DontSerialize
}
add_child :: (e: *Entity, child: *Entity, node_name: string = "") {
set_parent(child, e, node_name);
}
set_parent :: (e: *Entity, parent: *Entity, node_name: string = "") {
parent.children[parent.num_children] = e;
e.parent = parent;
parent.num_children += 1;
for node, index: parent.renderable.model.nodes {
if node.name == node_name {
e.attach_node_index = index;
break;
}
}
}
set_base_color :: (e: *Entity, color: Vector4, node_name: string = "") {
if e.renderable.type == .MODEL {
for i: 0..e.renderable.num_nodes-1 {
actual_node := e.renderable.model.nodes[i];
if node_name.count == 0 || node_name == actual_node.name {
data := *e.renderable.nodes[i];
if data.material_buffer > 0 {
material : Entity_Material = ---;
material.base_color = color;
upload_data_to_buffer(engine.renderer, data.material_buffer, *material, size_of(Entity_Material));
}
}
}
}
}
set_node_enabled :: (e: *Entity, node_name: string, enabled : bool) {
if e.renderable.type == .MODEL {
for i: 0..e.renderable.num_nodes-1 {
actual_node := e.renderable.model.nodes[i];
if node_name.count == 0 || node_name == actual_node.name {
data := *e.renderable.nodes[i];
data.enabled = enabled;
}
}
}
}
load_model_into_entity :: (e: *Entity, model: *Model) {
e.renderable.type = .MODEL;
assert(model.nodes.count <= MAX_NODES);
e.renderable.num_nodes = model.nodes.count;
e.renderable.model = model;
for *model.nodes {
data : Node_Render_Data;
data.transform = it.transform;
update_matrix(*it.transform);
if it.meshes.count > 0 {
material : Entity_Material = ---;
material.base_color = it.material_defaults[0].base_color; // @Incomplete: What if there are multiple meshes?
data.material = material;
data.transform_buffer = create_constant_buffer(engine.renderer, null, size_of(Matrix4), mappable=true);
data.material_buffer = create_constant_buffer(engine.renderer, *material, size_of(Entity_Material), mappable=true);
data.num_bones = it.num_bones;
if it.num_bones > 0 {
for bone_index: 0..it.num_bones-1 {
data.bone_buffers[bone_index] = create_constant_buffer(engine.renderer, null, size_of(Matrix4) * MAX_BONES, mappable=true);
}
}
}
e.renderable.nodes[it_index] = data;
}
}
mark_entity_deleted :: (e: *Entity) {
e.flags |= .DELETED;
}
destroy_entity :: (e: *Entity) {
for 0..e.renderable.num_nodes-1 {
node_data := e.renderable.nodes[it];
if node_data.transform_buffer > 0 {
destroy_buffer(engine.renderer, node_data.transform_buffer);
}
if node_data.material_buffer > 0 {
destroy_buffer(engine.renderer, node_data.material_buffer);
}
for bi: 0..node_data.num_bones-1 {
destroy_buffer(engine.renderer, node_data.bone_buffers[bi]);
}
}
free(e.name);
}