Files
coven/renderer/mesh.jai
2024-10-18 16:12:24 +02:00

192 lines
7.4 KiB
Plaintext

Skin_Vertex :: struct {
bone_index: [4] float;
bone_weight: [4] float;
}
Mesh_Vertex_Data_Type :: enum {
NONE;
POSITION;
NORMAL;
TEXCOORD;
TANGENT;
COLOR;
BITANGENT;
BONE_INDICES;
BONE_WEIGHTS;
}
Mesh_Handle :: #type, distinct u32;
Mesh :: struct {
name : string;
positions : [..] Vector3;
normals : [..] Vector3;
texcoords : [..] Vector2;
tangents : [..] Vector3;
bitangents : [..] Vector3;
colors : [..] Vector4;
skin_data : [..] Skin_Vertex;
bone_indices: [..] s32;
bone_matrices: [..] Matrix4;
num_bones: s32;
indices : [..] u32;
ib : Buffer_Handle;
vbs : Table(u32, Buffer_Handle);
//vb : Buffer_Handle;
}
get_mesh_vb :: (mesh: *Mesh, pipeline_handle: Pipeline_State_Handle = 0) -> Buffer_Handle {
handle := ifx pipeline_handle == 0 then engine.renderer.current_state.last_set_pipeline else pipeline_handle;
pipeline_state := *engine.renderer.pipeline_states[handle-1];
return get_mesh_vb(mesh, pipeline_state.mesh_data_types);
}
get_mesh_vb :: (mesh: *Mesh, input: [] Mesh_Vertex_Data_Type) -> Buffer_Handle {
hash : u32 = 0;
nums : [8] u32 : .[13, 61, 84, 86, 65, 10000, 100000, 126];
for input, i: input {
hash += nums[i] * cast(u32)input;
}
if !table_contains(*mesh.vbs, hash) {
final_vertices : [..] float;
final_vertices.allocator = temp;
stride : u32 = 0;
for input: input {
if input == {
case .POSITION; stride += 3;
case .NORMAL; stride += 3;
case .TEXCOORD; stride += 2;
case .COLOR; stride += 4;
case .TANGENT; stride += 3;
case .BITANGENT; stride += 3;
case .BONE_INDICES; stride += 4;
case .BONE_WEIGHTS; stride += 4;
}
}
for 0..mesh.positions.count-1 {
for input: input {
if input == {
case .POSITION; {
array_add(*final_vertices, mesh.positions[it].x);
array_add(*final_vertices, mesh.positions[it].y);
array_add(*final_vertices, mesh.positions[it].z);
}
case .NORMAL; {
if mesh.normals.count > 0 {
array_add(*final_vertices, mesh.normals[it].x);
array_add(*final_vertices, mesh.normals[it].y);
array_add(*final_vertices, mesh.normals[it].z);
} else {
array_add(*final_vertices, 0.0);
array_add(*final_vertices, 0.0);
array_add(*final_vertices, 0.0);
log_error("Mesh didn't have required normals\n");
}
}
case .TEXCOORD; {
if mesh.texcoords.count > 0 {
array_add(*final_vertices, mesh.texcoords[it].x);
array_add(*final_vertices, mesh.texcoords[it].y);
} else {
array_add(*final_vertices, 0.0);
array_add(*final_vertices, 0.0);
log_error("Mesh didn't have required texcoords\n");
}
}
case .COLOR; {
if mesh.colors.count > 0 {
array_add(*final_vertices, mesh.colors[it].x);
array_add(*final_vertices, mesh.colors[it].y);
array_add(*final_vertices, mesh.colors[it].z);
array_add(*final_vertices, mesh.colors[it].w);
} else {
array_add(*final_vertices, 0.0);
array_add(*final_vertices, 0.0);
array_add(*final_vertices, 0.0);
array_add(*final_vertices, 0.0);
log_error("Mesh didn't have required colors\n");
}
}
case .TANGENT; {
if mesh.tangents.count > 0 {
array_add(*final_vertices, mesh.tangents[it].x);
array_add(*final_vertices, mesh.tangents[it].y);
array_add(*final_vertices, mesh.tangents[it].z);
} else {
array_add(*final_vertices, 0.0);
array_add(*final_vertices, 0.0);
array_add(*final_vertices, 0.0);
log_error("Mesh didn't have required tangents\n");
}
}
case .BITANGENT; {
if mesh.bitangents.count > 0 {
array_add(*final_vertices, mesh.bitangents[it].x);
array_add(*final_vertices, mesh.bitangents[it].y);
array_add(*final_vertices, mesh.bitangents[it].z);
} else {
array_add(*final_vertices, 0.0);
array_add(*final_vertices, 0.0);
array_add(*final_vertices, 0.0);
log_error("Mesh didn't have required bitangents\n");
}
}
case .BONE_INDICES; {
if mesh.skin_data.count > 0 {
for index: 0..3 {
array_add(*final_vertices, mesh.skin_data[it].bone_index[index]);
}
} else {
array_add(*final_vertices, 0.0);
array_add(*final_vertices, 0.0);
array_add(*final_vertices, 0.0);
array_add(*final_vertices, 0.0);
log_error("Mesh didn't have required bone indices\n");
}
}
case .BONE_WEIGHTS; {
if mesh.skin_data.count > 0 {
for index: 0..3 {
array_add(*final_vertices, mesh.skin_data[it].bone_weight[index]);
}
} else {
array_add(*final_vertices, 0.0);
array_add(*final_vertices, 0.0);
array_add(*final_vertices, 0.0);
array_add(*final_vertices, 0.0);
log_error("Mesh didn't have required bone weights\n");
}
}
}
}
}
vb_size := size_of(float)*stride*mesh.positions.count;
vb := create_vertex_buffer(engine.renderer, final_vertices.data, xx vb_size, stride=size_of(float)*stride);
table_add(*mesh.vbs, hash, vb);
}
value, success := table_find(*mesh.vbs, hash);
return value;
}
delete_mesh :: (handle: Mesh_Handle) {
mesh := parray_get(*engine.renderer.meshes, handle);
for mesh.vbs {
destroy_buffer(engine.renderer, it);
}
deinit(*mesh.vbs);
parray_remove(*engine.renderer.meshes, handle);
}