rework mesh/materials and start gltf loading
This commit is contained in:
parent
50b9ce9ee8
commit
9bc34ca4b9
26
assets.d
26
assets.d
@ -88,6 +88,12 @@ struct AssetInfo
|
||||
AssetType type;
|
||||
}
|
||||
|
||||
struct Mesh
|
||||
{
|
||||
Vertex[] vtx;
|
||||
u32[] idx;
|
||||
}
|
||||
|
||||
struct MeshPart
|
||||
{
|
||||
u64 start;
|
||||
@ -97,15 +103,28 @@ struct MeshPart
|
||||
struct ModelData
|
||||
{
|
||||
string name;
|
||||
Vertex[] vtx;
|
||||
u32[] idx;
|
||||
Mesh[] meshes;
|
||||
MaterialData[] mats;
|
||||
MeshPart[] parts;
|
||||
}
|
||||
|
||||
struct MaterialMap
|
||||
{
|
||||
u32 texture_id;
|
||||
Vec4 color;
|
||||
f32 value;
|
||||
}
|
||||
|
||||
struct Material
|
||||
{
|
||||
u32 shader_id;
|
||||
MaterialMap[] maps;
|
||||
Vec4 params;
|
||||
}
|
||||
|
||||
struct MaterialData
|
||||
{
|
||||
string name;
|
||||
|
||||
Vec3[MatColor.max] colors;
|
||||
string[MatMap.max] maps;
|
||||
f32[MatFloat.max] props = 0.0;
|
||||
@ -133,6 +152,7 @@ struct Vertex
|
||||
Vec3 pos;
|
||||
Vec3 normal;
|
||||
Vec2 uv;
|
||||
Vec2 uv2;
|
||||
}
|
||||
|
||||
enum IllumModel : u32
|
||||
|
||||
7228
external/cgltf/cgltf.h
vendored
Normal file
7228
external/cgltf/cgltf.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -24,3 +24,6 @@
|
||||
#define CGLM_FORCE_DEPTH_ZERO_TO_ONE
|
||||
#include "external/cglm/cglm.h"
|
||||
|
||||
#define CGLTF_IMPLEMENTATION
|
||||
#include "external/cgltf/cgltf.h"
|
||||
|
||||
|
||||
145
packer.d
145
packer.d
@ -5,6 +5,7 @@ import dlib.util;
|
||||
import dlib.aliases;
|
||||
import dlib.assets;
|
||||
import dlib.platform;
|
||||
import dlib.alloc;
|
||||
|
||||
import std.stdio;
|
||||
import std.string;
|
||||
@ -79,9 +80,9 @@ union MeshIdx
|
||||
{
|
||||
struct
|
||||
{
|
||||
u32 v, uv, n;
|
||||
u32 v, uv, n, t;
|
||||
};
|
||||
u32[3] arr;
|
||||
u32[4] arr;
|
||||
}
|
||||
|
||||
struct Model
|
||||
@ -451,9 +452,20 @@ TokenizeLines(u8[] data)
|
||||
u8[]
|
||||
OpenFile(string file_name)
|
||||
{
|
||||
File f = File(file_name, "rb");
|
||||
u8[] data = new u8[f.size()];
|
||||
File f;
|
||||
u8[] data;
|
||||
|
||||
try
|
||||
{
|
||||
f = File(file_name, "rb");
|
||||
data = new u8[f.size()];
|
||||
f.rawRead(data);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
data = null;
|
||||
}
|
||||
|
||||
f.close();
|
||||
|
||||
return data;
|
||||
@ -494,14 +506,14 @@ ConvertObj(string file_name)
|
||||
Vec3[] positions = new Vec3[vcount];
|
||||
Vec3[] normals = new Vec3[ncount];
|
||||
Vec2[] uvs = new Vec2[uvcount];
|
||||
MeshIdx[][] idx = [];
|
||||
MeshIdx[3][][] idx = [];
|
||||
MaterialData[] mtls = [];
|
||||
|
||||
vcount = 0;
|
||||
ncount = 0;
|
||||
uvcount = 0;
|
||||
|
||||
MeshIdx[] part_idx = [];
|
||||
MeshIdx[3][] part_idx = [];
|
||||
for(u64 i = 0; i < tokens.length; i += 1)
|
||||
{
|
||||
if(tokens[i][0] == "#") continue;
|
||||
@ -536,17 +548,18 @@ ConvertObj(string file_name)
|
||||
|
||||
if(tokens[i].length == 4)
|
||||
{
|
||||
MeshIdx[3] face;
|
||||
for(u64 j = 1; j < tokens[i].length; j += 1)
|
||||
{
|
||||
string[] parts = tokens[i][j].split('/');
|
||||
|
||||
if(sep_count == 0)
|
||||
{
|
||||
part_idx ~= MeshIdx(v: to!u32(parts[0]));
|
||||
face[j-1] = MeshIdx(v: to!u32(parts[0]));
|
||||
}
|
||||
if(sep_count == 1)
|
||||
{
|
||||
part_idx ~= MeshIdx(v: to!u32(parts[0]), uv: to!u32(parts[1]));
|
||||
face[j-1] = MeshIdx(v: to!u32(parts[0]), uv: to!u32(parts[1]));
|
||||
}
|
||||
if(sep_count == 2)
|
||||
{
|
||||
@ -557,9 +570,11 @@ ConvertObj(string file_name)
|
||||
mesh_idx.arr[ipart] = to!u32(part);
|
||||
}
|
||||
|
||||
part_idx ~= mesh_idx;
|
||||
face[j-1] = mesh_idx;
|
||||
}
|
||||
}
|
||||
|
||||
part_idx ~= face;
|
||||
}
|
||||
else assert(false, "Only triangles or quads supported for mesh face");
|
||||
|
||||
@ -569,7 +584,6 @@ ConvertObj(string file_name)
|
||||
if(tokens[i][0] == "g" && part_idx.length > 0)
|
||||
{
|
||||
idx ~= part_idx;
|
||||
Logf("%s %s", idx.length, part_idx.length);
|
||||
part_idx = [];
|
||||
continue;
|
||||
}
|
||||
@ -645,69 +659,110 @@ ConvertObj(string file_name)
|
||||
face_count += part.length;
|
||||
}
|
||||
|
||||
positions = Deduplicate(positions, idx, 0);
|
||||
uvs = Deduplicate(uvs, idx, 1);
|
||||
normals = Deduplicate(normals, idx, 2);
|
||||
|
||||
ModelData md = {
|
||||
name: baseName(file_name, ".obj"),
|
||||
vtx: new Vertex[face_count*3],
|
||||
meshes: [
|
||||
{ vtx: new Vertex[face_count*3] },
|
||||
]
|
||||
};
|
||||
|
||||
Logf("%s %s", (Vertex.sizeof * md.vtx.length), (positions.length*Vec3.sizeof + uvs.length*Vec2.sizeof + normals.length*Vec3.sizeof));
|
||||
|
||||
u64 vtx_count = 0;
|
||||
foreach(part; idx)
|
||||
{
|
||||
for(u64 i = 0; i < part.length; i += 1)
|
||||
{
|
||||
MeshIdx* mi = part.ptr + i;
|
||||
for(u64 j = 0; j < 3; j += 1)
|
||||
{
|
||||
MeshIdx* mi = part[i].ptr + j;
|
||||
if(mi.v ) md.meshes[0].vtx[vtx_count+j].pos = positions[mi.v-1];
|
||||
if(mi.n ) md.meshes[0].vtx[vtx_count+j].normal = normals[mi.n-1];
|
||||
if(mi.uv) md.meshes[0].vtx[vtx_count+j].uv = uvs[mi.uv-1];
|
||||
}
|
||||
|
||||
if(mi.v ) md.vtx[vtx_count].pos = positions[mi.v-1];
|
||||
if(mi.n ) md.vtx[vtx_count].normal = normals[mi.n-1];
|
||||
if(mi.uv) md.vtx[vtx_count].uv = uvs[mi.uv-1];
|
||||
|
||||
vtx_count += 1;
|
||||
vtx_count += 3;
|
||||
}
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
T[]
|
||||
Deduplicate(T)(T[] values, MeshIdx[][] indices, u32 arr_idx)
|
||||
extern (C) cgltf_result
|
||||
GLTFLoadCallback(cgltf_memory_options* memory_opts, cgltf_file_options* file_opts, const(char)* path, cgltf_size* size, void** data)
|
||||
{
|
||||
u64 dup_count;
|
||||
for(u64 i = 0; i < values.length; i += 1)
|
||||
{
|
||||
for(u64 j = i+1; j < values.length; j += 1)
|
||||
{
|
||||
if(values[i] == values[j])
|
||||
{
|
||||
dup_count += 1;
|
||||
u8[] file_data = OpenFile(ConvToStr(path[0 .. strlen(path)]));
|
||||
|
||||
Logf("before");
|
||||
values[j .. $] = values[j+1 .. values.length-1];
|
||||
Logf("after");
|
||||
if(file_data == null) return cgltf_result_io_error;
|
||||
|
||||
foreach(ref part; indices)
|
||||
*size = cast(cgltf_size)file_data.length;
|
||||
*data = Alloc!(u8)(file_data).ptr;
|
||||
|
||||
return cgltf_result_success;
|
||||
}
|
||||
|
||||
extern (C) void
|
||||
GLTFFreeCallback(cgltf_memory_options* memory_opts, cgltf_file_options* file_opts, void* data, cgltf_size size)
|
||||
{
|
||||
Free(data[0 .. size]);
|
||||
}
|
||||
|
||||
ModelData
|
||||
LoadGLTF(string file_name)
|
||||
{
|
||||
ModelData model;
|
||||
|
||||
u8[] file_data = OpenFile(file_name);
|
||||
|
||||
cgltf_options opts;
|
||||
cgltf_data* data;
|
||||
|
||||
opts.file.read = &GLTFLoadCallback;
|
||||
opts.file.release = &GLTFFreeCallback;
|
||||
|
||||
cgltf_result result = cgltf_parse(&opts, file_data.ptr, file_data.length, &data);
|
||||
|
||||
if(result == cgltf_result_success)
|
||||
{
|
||||
for(u64 k = 0; k < part.length; k += 1)
|
||||
result = cgltf_load_buffers(&opts, data, file_name.ptr);
|
||||
if(result != cgltf_result_success)
|
||||
{
|
||||
if(part[k].arr[arr_idx] > j+1)
|
||||
{
|
||||
part[k].arr[arr_idx] -= 1;
|
||||
Logf("%s Failure: Unable to load buffers", __FUNCTION__);
|
||||
}
|
||||
|
||||
if(part[k].arr[arr_idx] == j+1)
|
||||
u64 primitive_count;
|
||||
|
||||
for(u64 i = 0; i < data.nodes_count; i += 1)
|
||||
{
|
||||
part[k].arr[arr_idx] = cast(u32)(i+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
cgltf_node* node = &data.nodes[i];
|
||||
|
||||
if(node.mesh == null) continue;
|
||||
|
||||
for(u64 j = 0; j < mesh.primitives_count; j += 1)
|
||||
{
|
||||
if(mesh.primitives[j].type == cgltf_primtive_type_triangles)
|
||||
{
|
||||
primitive_count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return values[0 .. values.length-dup_count];
|
||||
model.meshes = new Mesh[primitive_count];
|
||||
model.mats = new MaterialData[data.materials_count+1];
|
||||
|
||||
// Make and load default material into model.mats[0]
|
||||
|
||||
string file_path = GetFilePath(file_name);
|
||||
for(u64 i = 0; i < data.materials_count; i += 1)
|
||||
{
|
||||
// model.mats[i+1] = default_material;
|
||||
|
||||
if(data.materials[i].has_pbr_metallic_roughness)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string
|
||||
|
||||
2
test.sh
2
test.sh
@ -2,7 +2,7 @@
|
||||
|
||||
name="Test_Runner"
|
||||
|
||||
ldc2 platform.d aliases.d math.d util.d alloc.d assets.d packer.d external/xxhash/xxhash.d -P-I/usr/include/freetype2 -L-lfreetype --main --unittest --of=$name
|
||||
ldc2 platform.d aliases.d math.d util.d alloc.d assets.d packer.d external/xxhash/xxhash.d -P-I/usr/include/freetype2 -L-lfreetype --main --unittest -g --of=$name
|
||||
|
||||
rm $name.o
|
||||
./$name
|
||||
|
||||
10
util.d
10
util.d
@ -66,11 +66,17 @@ CastArr(T, U)(U[] input_array)
|
||||
}
|
||||
|
||||
void
|
||||
Logf(Args...)(string fmt, Args args)
|
||||
Debugf(Args...)(string fmt, Args args)
|
||||
{
|
||||
debug Logf(fmt, args, "[DEBUG]: ");
|
||||
}
|
||||
|
||||
void
|
||||
Logf(Args...)(string fmt, Args args, string prefix = "[INFO]: ")
|
||||
{
|
||||
try
|
||||
{
|
||||
write("[INFO]: ");
|
||||
write(prefix);
|
||||
writefln(fmt, args);
|
||||
}
|
||||
catch (Exception e)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user