Skip to content

Commit

Permalink
Add EXT_mesh_gpu_instancing support (read/write)
Browse files Browse the repository at this point in the history
  • Loading branch information
bcomb committed Mar 21, 2022
1 parent 4615edc commit 43894d5
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 3 deletions.
44 changes: 44 additions & 0 deletions cgltf.h
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,12 @@ typedef struct cgltf_draco_mesh_compression {
cgltf_size attributes_count;
} cgltf_draco_mesh_compression;

typedef struct cgltf_mesh_gpu_instancing {
cgltf_buffer_view* buffer_view;
cgltf_attribute* attributes;
cgltf_size attributes_count;
} cgltf_mesh_gpu_instancing;

typedef struct cgltf_primitive {
cgltf_primitive_type type;
cgltf_accessor* indices;
Expand Down Expand Up @@ -635,6 +641,8 @@ struct cgltf_node {
cgltf_float scale[3];
cgltf_float matrix[16];
cgltf_extras extras;
cgltf_bool has_mesh_gpu_instancing;
cgltf_mesh_gpu_instancing mesh_gpu_instancing;
cgltf_size extensions_count;
cgltf_extension* extensions;
};
Expand Down Expand Up @@ -2725,6 +2733,37 @@ static int cgltf_parse_json_draco_mesh_compression(cgltf_options* options, jsmnt
return i;
}

static int cgltf_parse_json_mesh_gpu_instancing(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_mesh_gpu_instancing* out_mesh_gpu_instancing)
{
CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT);

int size = tokens[i].size;
++i;

for (int j = 0; j < size; ++j)
{
CGLTF_CHECK_KEY(tokens[i]);

if (cgltf_json_strcmp(tokens + i, json_chunk, "attributes") == 0)
{
i = cgltf_parse_json_attribute_list(options, tokens, i + 1, json_chunk, &out_mesh_gpu_instancing->attributes, &out_mesh_gpu_instancing->attributes_count);
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "bufferView") == 0)
{
++i;
out_mesh_gpu_instancing->buffer_view = CGLTF_PTRINDEX(cgltf_buffer_view, cgltf_json_to_int(tokens + i, json_chunk));
++i;
}

if (i < 0)
{
return i;
}
}

return i;
}

static int cgltf_parse_json_material_mapping_data(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_material_mapping* out_mappings, cgltf_size* offset)
{
(void)options;
Expand Down Expand Up @@ -5223,6 +5262,11 @@ static int cgltf_parse_json_node(cgltf_options* options, jsmntok_t const* tokens
}
}
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "EXT_mesh_gpu_instancing") == 0)
{
out_node->has_mesh_gpu_instancing = 1;
i = cgltf_parse_json_mesh_gpu_instancing(options, tokens, i + 1, json_chunk, &out_node->mesh_gpu_instancing);
}
else
{
i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_node->extensions[out_node->extensions_count++]));
Expand Down
37 changes: 34 additions & 3 deletions cgltf_write.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ cgltf_size cgltf_write(const cgltf_options* options, char* buffer, cgltf_size si
#define CGLTF_EXTENSION_FLAG_MATERIALS_VOLUME (1 << 11)
#define CGLTF_EXTENSION_FLAG_TEXTURE_BASISU (1 << 12)
#define CGLTF_EXTENSION_FLAG_MATERIALS_EMISSIVE_STRENGTH (1 << 13)
#define CGLTF_EXTENSION_FLAG_MESH_GPU_INSTANCING (1 << 14)

typedef struct {
char* buffer;
Expand Down Expand Up @@ -509,6 +510,7 @@ static void cgltf_write_mesh(cgltf_write_context* context, const cgltf_mesh* mes
{
cgltf_write_floatarrayprop(context, "weights", mesh->weights, mesh->weights_count);
}

cgltf_write_extras(context, &mesh->extras);
cgltf_write_line(context, "}");
}
Expand Down Expand Up @@ -545,7 +547,7 @@ static void cgltf_write_material(cgltf_write_context* context, const cgltf_mater
{
cgltf_write_floatprop(context, "alphaCutoff", material->alpha_cutoff, 0.5f);
}
cgltf_write_boolprop_optional(context, "doubleSided", material->double_sided, false);
cgltf_write_boolprop_optional(context, "doubleSided", (bool)material->double_sided, false);
// cgltf_write_boolprop_optional(context, "unlit", material->unlit, false);

if (material->unlit)
Expand Down Expand Up @@ -897,16 +899,42 @@ static void cgltf_write_node(cgltf_write_context* context, const cgltf_node* nod
CGLTF_WRITE_IDXPROP("skin", node->skin, context->data->skins);
}

bool has_extension = node->light || (node->has_mesh_gpu_instancing && node->mesh_gpu_instancing.attributes_count > 0);
if(has_extension)
cgltf_write_line(context, "\"extensions\": {");

if (node->light)
{
context->extension_flags |= CGLTF_EXTENSION_FLAG_LIGHTS_PUNCTUAL;
cgltf_write_line(context, "\"extensions\": {");
cgltf_write_line(context, "\"KHR_lights_punctual\": {");
CGLTF_WRITE_IDXPROP("light", node->light, context->data->lights);
cgltf_write_line(context, "}");
}

if (node->has_mesh_gpu_instancing && node->mesh_gpu_instancing.attributes_count > 0)
{
context->extension_flags |= CGLTF_EXTENSION_FLAG_MESH_GPU_INSTANCING;
context->required_extension_flags |= CGLTF_EXTENSION_FLAG_MESH_GPU_INSTANCING;

cgltf_write_line(context, "\"EXT_mesh_gpu_instancing\": {");
{
CGLTF_WRITE_IDXPROP("bufferView", node->mesh_gpu_instancing.buffer_view, context->data->buffer_views);
cgltf_write_line(context, "\"attributes\": {");
{
for (cgltf_size i = 0; i < node->mesh_gpu_instancing.attributes_count; ++i)
{
const cgltf_attribute* attr = node->mesh_gpu_instancing.attributes + i;
CGLTF_WRITE_IDXPROP(attr->name, attr->data, context->data->accessors);
}
}
cgltf_write_line(context, "}");
}
cgltf_write_line(context, "}");
}

if (has_extension)
cgltf_write_line(context, "}");

if (node->weights_count > 0)
{
cgltf_write_floatarrayprop(context, "weights", node->weights, node->weights_count);
Expand Down Expand Up @@ -938,7 +966,7 @@ static void cgltf_write_accessor(cgltf_write_context* context, const cgltf_acces
cgltf_write_intprop(context, "componentType", cgltf_int_from_component_type(accessor->component_type), 0);
cgltf_write_strprop(context, "type", cgltf_str_from_type(accessor->type));
cgltf_size dim = cgltf_dim_from_type(accessor->type);
cgltf_write_boolprop_optional(context, "normalized", accessor->normalized, false);
cgltf_write_boolprop_optional(context, "normalized", (bool)accessor->normalized, false);
cgltf_write_sizeprop(context, "byteOffset", (int)accessor->offset, 0);
cgltf_write_intprop(context, "count", (int)accessor->count, -1);
if (accessor->has_min)
Expand Down Expand Up @@ -1113,6 +1141,9 @@ static void cgltf_write_extensions(cgltf_write_context* context, uint32_t extens
if (extension_flags & CGLTF_EXTENSION_FLAG_MATERIALS_EMISSIVE_STRENGTH) {
cgltf_write_stritem(context, "KHR_materials_emissive_strength");
}
if (extension_flags & CGLTF_EXTENSION_FLAG_MESH_GPU_INSTANCING) {
cgltf_write_stritem(context, "EXT_mesh_gpu_instancing");
}
}

cgltf_size cgltf_write(const cgltf_options* options, char* buffer, cgltf_size size, const cgltf_data* data)
Expand Down

0 comments on commit 43894d5

Please sign in to comment.