233 lines
6.1 KiB
Plaintext
233 lines
6.1 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;
|
|
|
|
// 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; @DontSerialize
|
|
|
|
model: Model_Handle; @DontSerialize
|
|
nodes: [MAX_NODES] Node_Render_Data; @DontSerialize
|
|
num_nodes: s64; @DontSerialize
|
|
|
|
//node_buffer : Buffer_Handle; // Structure buffer with all transform + material // TODO
|
|
}
|
|
|
|
MAX_CHILDREN :: 16;
|
|
|
|
Entity :: struct {
|
|
name: string;
|
|
|
|
id: Entity_Id; @ReadOnly @DontSerialize
|
|
type : Type;
|
|
|
|
enabled: bool = true;
|
|
|
|
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 = .{1,1,1};
|
|
|
|
renderable: Renderable;
|
|
animator: Animator; @DontSerialize
|
|
|
|
// Physics
|
|
body : Physics_Body;
|
|
collider : Collider;
|
|
physx_static: *PhysX.PxRigidStatic;
|
|
physx_dynamic: *PhysX.PxRigidDynamic;
|
|
|
|
// End physics
|
|
|
|
#if NETWORKING {
|
|
remote_id: Entity_Id; @DontSerialize
|
|
client_id: Client_Id; @DontSerialize
|
|
is_proxy: bool; @DontSerialize
|
|
last_replication_time: float; @DontSerialize
|
|
}
|
|
|
|
_locator: Bucket_Locator; @DontSerialize
|
|
scene: *Scene; @DontSerialize
|
|
|
|
using custom_fields: _Custom_Entity_Fields;
|
|
}
|
|
|
|
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;
|
|
|
|
model := get_model_by_handle(parent.renderable.model);
|
|
|
|
for node, index: 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 {
|
|
model := get_model_by_handle(e.renderable.model);
|
|
|
|
for i: 0..e.renderable.num_nodes-1 {
|
|
actual_node := 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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
get_node_world_position :: (e: *Entity, node_name: string) -> Vector3 {
|
|
if e.renderable.type == .MODEL {
|
|
model := get_model_by_handle(e.renderable.model);
|
|
for i: 0..e.renderable.num_nodes-1 {
|
|
actual_node := model.nodes[i];
|
|
if node_name.count == 0 || node_name == actual_node.name {
|
|
data := *e.renderable.nodes[i];
|
|
return Vector3.{data.transform.world_matrix._14, data.transform.world_matrix._24, data.transform.world_matrix._34};
|
|
}
|
|
}
|
|
}
|
|
return .{};
|
|
}
|
|
|
|
load_model_into_entity :: (e: *Entity, handle: Model_Handle) {
|
|
model := get_model_by_handle(handle);
|
|
|
|
e.renderable.type = .MODEL;
|
|
|
|
assert(model.nodes.count <= MAX_NODES);
|
|
|
|
e.renderable.num_nodes = model.nodes.count;
|
|
e.renderable.model = handle;
|
|
|
|
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;
|
|
}
|
|
|
|
entity_should_be_rendered :: (e: *Entity) -> bool {
|
|
if !(e.flags & .RENDERABLE) || (e.flags & .DELETED) || !e.enabled return false;
|
|
return true;
|
|
}
|
|
|
|
destroy_entity :: (e: *Entity) {
|
|
call_correct_deinit_entity(e);
|
|
|
|
if e.collider.mesh.vertices.data != null {
|
|
array_free(e.collider.mesh.vertices);
|
|
}
|
|
|
|
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);
|
|
}
|