Updated cgltf.

This commit is contained in:
Бранимир Караџић 2020-02-04 19:14:34 -08:00
parent 3002159da9
commit 2c9600b8e0
15 changed files with 496 additions and 1111 deletions

View File

@ -1,13 +0,0 @@
os:
- linux
- osx
- windows
language: c
compiler:
- gcc
- clang
sudo: false
script:
- cd test/
- ./test_all.py

View File

@ -1,141 +0,0 @@
# cgltf
**Single-file/stb-style C glTF loader and writer**
[![Build Status](https://travis-ci.org/jkuhlmann/cgltf.svg?branch=master)](https://travis-ci.org/jkuhlmann/cgltf)
## Usage: Loading
Loading from file:
```c
#include "cgltf.h"
cgltf_options options = {0};
cgltf_data* data = NULL;
cgltf_result result = cgltf_parse_file(&options, "scene.gltf", &data);
if (result == cgltf_result_success)
{
/* TODO make awesome stuff */
cgltf_free(data);
}
```
Loading from memory:
```c
#include "cgltf.h"
void* buf; /* Pointer to glb or gltf file data */
size_t size; /* Size of the file data */
cgltf_options options = {0};
cgltf_data* data = NULL;
cgltf_result result = cgltf_parse(&options, buf, size, &data);
if (result == cgltf_result_success)
{
/* TODO make awesome stuff */
cgltf_free(data);
}
```
Note that cgltf does not load the contents of extra files such as buffers or images into memory by default. You'll need to read these files yourself using URIs from `data.buffers[]` or `data.images[]` respectively.
For buffer data, you can alternatively call `cgltf_load_buffers`, which will use `FILE*` APIs to open and read buffer files.
**For more in-depth documentation and a description of the public interface refer to the top of the `cgltf.h` file.**
## Usage: Writing
When writing glTF data, you need a valid `cgltf_data` structure that represents a valid glTF document. You can construct such a structure yourself or load it using the loader functions described above. The writer functions do not deallocate any memory. So, you either have to do it manually or call `cgltf_free()` if you got the data by loading it from a glTF document.
Writing to file:
```c
#include "cgltf_write.h"
cgltf_options options = {0};
cgltf_data* data = /* TODO must be valid data */;
cgltf_result result = cgltf_write_file(&options, "out.gltf", data);
if (result != cgltf_result_success)
{
/* TODO handle error */
}
```
Writing to memory:
```c
#include "cgltf_write.h"
cgltf_options options = {0};
cgltf_data* data = /* TODO must be valid data */;
cgltf_size size = cgltf_write(&options, NULL, 0, data);
char* buf = malloc(size);
cgltf_size written = cgltf_write(&options, buf, size, data);
if (written != size)
{
/* TODO handle error */
}
```
Note that cgltf does not write the contents of extra files such as buffers or images. You'll need to write this data yourself.
Writing does not yet support "extras" data.
**For more in-depth documentation and a description of the public interface refer to the top of the `cgltf_write.h` file.**
## Features
cgltf supports core glTF 2.0:
- glb (binary files) and gltf (JSON files)
- meshes (including accessors, buffer views, buffers)
- materials (including textures, samplers, images)
- scenes and nodes
- skins
- animations
- cameras
- morph targets
- extras data
cgltf also supports some glTF extensions:
- KHR_lights_punctual
- KHR_materials_pbrSpecularGlossiness
- KHR_materials_unlit
- KHR_texture_transform
cgltf does **not** yet support unlisted extensions.
## Building
The easiest approach is to integrate the `cgltf.h` header file into your project. If you are unfamiliar with single-file C libraries (also known as stb-style libraries), this is how it goes:
1. Include `cgltf.h` where you need the functionality.
1. Have exactly one source file that defines `CGLTF_IMPLEMENTATION` before including `cgltf.h`.
1. Use the cgltf functions as described above.
Support for writing can be found in a separate file called `cgltf_write.h` (which includes `cgltf.h`). Building it works analogously using the `CGLTF_WRITE_IMPLEMENTATION` define.
## Contributing
Everyone is welcome to contribute to the library. If you find any problems, you can submit them using [GitHub's issue system](https://github.com/jkuhlmann/cgltf/issues). If you want to contribute code, you should fork the project and then send a pull request.
## Dependencies
None.
C headers being used by implementation:
```
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
```
Note, this library has a copy of the [JSMN JSON parser](https://github.com/zserge/jsmn) embedded in its source.
## Testing
There is a Python script in the `test/` folder that retrieves the glTF 2.0 sample files from the glTF-Sample-Models repository (https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0) and runs the library against all gltf and glb files.
Here's one way to build and run the test:
cd test ; mkdir build ; cd build ; cmake .. -DCMAKE_BUILD_TYPE=Debug
make -j
cd ..
./test_all.py
There is also a llvm-fuzz test in `fuzz/`. See http://llvm.org/docs/LibFuzzer.html for more information.

582
3rdparty/cgltf/cgltf.h vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/**
* cgltf_write - a single-file glTF 2.0 writer written in C99.
*
* Version: 1.3
* Version: 1.5
*
* Website: https://github.com/jkuhlmann/cgltf
*
@ -23,6 +23,11 @@
* buffer. Returns the number of bytes written to `buffer`, including a null
* terminator. If buffer is null, returns the number of bytes that would have
* been written. `data` is not deallocated.
*
* To write custom JSON into the `extras` field, aggregate all the custom JSON
* into a single buffer, then set `file_data` to this buffer. By supplying
* start_offset and end_offset values for various objects, you can select a
* range of characters within the aggregated buffer.
*/
#ifndef CGLTF_WRITE_H_INCLUDED__
#define CGLTF_WRITE_H_INCLUDED__
@ -71,11 +76,11 @@ cgltf_size cgltf_write(const cgltf_options* options, char* buffer, cgltf_size si
typedef struct {
char* buffer;
size_t buffer_size;
size_t remaining;
cgltf_size buffer_size;
cgltf_size remaining;
char* cursor;
size_t tmp;
size_t chars_written;
cgltf_size tmp;
cgltf_size chars_written;
const cgltf_data* data;
int depth;
const char* indent;
@ -83,14 +88,24 @@ typedef struct {
uint32_t extension_flags;
} cgltf_write_context;
#define CGLTF_SPRINTF(fmt, ...) { \
context->tmp = snprintf ( context->cursor, context->remaining, fmt, ## __VA_ARGS__ ); \
#define CGLTF_MIN(a, b) (a < b ? a : b)
#define CGLTF_SPRINTF(...) { \
context->tmp = snprintf ( context->cursor, context->remaining, __VA_ARGS__ ); \
context->chars_written += context->tmp; \
if (context->cursor) { \
context->cursor += context->tmp; \
context->remaining -= context->tmp; \
} }
#define CGLTF_SNPRINTF(length, ...) { \
context->tmp = snprintf ( context->cursor, CGLTF_MIN(length + 1, context->remaining), __VA_ARGS__ ); \
context->chars_written += length; \
if (context->cursor) { \
context->cursor += length; \
context->remaining -= length; \
} }
#define CGLTF_WRITE_IDXPROP(label, val, start) if (val) { \
cgltf_write_indent(context); \
CGLTF_SPRINTF("\"%s\": %d", label, (int) (val - start)); \
@ -99,7 +114,7 @@ typedef struct {
#define CGLTF_WRITE_IDXARRPROP(label, dim, vals, start) if (vals) { \
cgltf_write_indent(context); \
CGLTF_SPRINTF("\"%s\": [", label); \
for (int i = 0; i < dim; ++i) { \
for (int i = 0; i < (int)(dim); ++i) { \
int idx = (int) (vals[i] - start); \
if (i != 0) CGLTF_SPRINTF(","); \
CGLTF_SPRINTF(" %d", idx); \
@ -116,6 +131,7 @@ typedef struct {
context->extension_flags |= CGLTF_EXTENSION_FLAG_TEXTURE_TRANSFORM; \
cgltf_write_texture_transform(context, &info.transform); \
} \
cgltf_write_extras(context, &info.extras); \
cgltf_write_line(context, "}"); }
static void cgltf_write_indent(cgltf_write_context* context)
@ -144,7 +160,7 @@ static void cgltf_write_line(cgltf_write_context* context, const char* line)
}
cgltf_write_indent(context);
CGLTF_SPRINTF("%s", line);
int last = strlen(line) - 1;
cgltf_size last = (cgltf_size)(strlen(line) - 1);
if (line[0] == ']' || line[0] == '}')
{
context->needs_comma = 1;
@ -166,6 +182,19 @@ static void cgltf_write_strprop(cgltf_write_context* context, const char* label,
}
}
static void cgltf_write_extras(cgltf_write_context* context, const cgltf_extras* extras)
{
cgltf_size length = extras->end_offset - extras->start_offset;
if (length > 0 && context->data->file_data)
{
char* json_string = ((char*) context->data->file_data) + extras->start_offset;
cgltf_write_indent(context);
CGLTF_SPRINTF("%s", "\"extras\": ");
CGLTF_SNPRINTF(length, "%s", json_string);
context->needs_comma = 1;
}
}
static void cgltf_write_stritem(cgltf_write_context* context, const char* item)
{
cgltf_write_indent(context);
@ -213,11 +242,11 @@ static void cgltf_write_boolprop_optional(cgltf_write_context* context, const ch
}
}
static void cgltf_write_floatarrayprop(cgltf_write_context* context, const char* label, const cgltf_float* vals, int dim)
static void cgltf_write_floatarrayprop(cgltf_write_context* context, const char* label, const cgltf_float* vals, cgltf_size dim)
{
cgltf_write_indent(context);
CGLTF_SPRINTF("\"%s\": [", label);
for (int i = 0; i < dim; ++i)
for (cgltf_size i = 0; i < dim; ++i)
{
if (i != 0)
{
@ -282,7 +311,7 @@ static const char* cgltf_str_from_type(cgltf_type type)
}
}
static int cgltf_dim_from_type(cgltf_type type)
static cgltf_size cgltf_dim_from_type(cgltf_type type)
{
switch (type)
{
@ -343,6 +372,7 @@ static void cgltf_write_asset(cgltf_write_context* context, const cgltf_asset* a
cgltf_write_strprop(context, "generator", asset->generator);
cgltf_write_strprop(context, "version", asset->version);
cgltf_write_strprop(context, "min_version", asset->min_version);
cgltf_write_extras(context, &asset->extras);
cgltf_write_line(context, "}");
}
@ -374,6 +404,7 @@ static void cgltf_write_primitive(cgltf_write_context* context, const cgltf_prim
}
cgltf_write_line(context, "]");
}
cgltf_write_extras(context, &prim->extras);
}
static void cgltf_write_mesh(cgltf_write_context* context, const cgltf_mesh* mesh)
@ -394,7 +425,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, "}");
}
@ -402,10 +433,11 @@ static void cgltf_write_buffer_view(cgltf_write_context* context, const cgltf_bu
{
cgltf_write_line(context, "{");
CGLTF_WRITE_IDXPROP("buffer", view->buffer, context->data->buffers);
cgltf_write_intprop(context, "byteLength", view->size, -1);
cgltf_write_intprop(context, "byteOffset", view->offset, 0);
cgltf_write_intprop(context, "byteStride", view->stride, 0);
cgltf_write_intprop(context, "byteLength", (int)view->size, -1);
cgltf_write_intprop(context, "byteOffset", (int)view->offset, 0);
cgltf_write_intprop(context, "byteStride", (int)view->stride, 0);
// NOTE: We skip writing "target" because the spec says its usage can be inferred.
cgltf_write_extras(context, &view->extras);
cgltf_write_line(context, "}");
}
@ -414,7 +446,8 @@ static void cgltf_write_buffer(cgltf_write_context* context, const cgltf_buffer*
{
cgltf_write_line(context, "{");
cgltf_write_strprop(context, "uri", buffer->uri);
cgltf_write_intprop(context, "byteLength", buffer->size, -1);
cgltf_write_intprop(context, "byteLength", (int)buffer->size, -1);
cgltf_write_extras(context, &buffer->extras);
cgltf_write_line(context, "}");
}
@ -448,6 +481,7 @@ static void cgltf_write_material(cgltf_write_context* context, const cgltf_mater
{
cgltf_write_floatarrayprop(context, "baseColorFactor", params->base_color_factor, 4);
}
cgltf_write_extras(context, &params->extras);
cgltf_write_line(context, "}");
}
@ -486,6 +520,7 @@ static void cgltf_write_material(cgltf_write_context* context, const cgltf_mater
cgltf_write_floatarrayprop(context, "emissiveFactor", material->emissive_factor, 3);
}
cgltf_write_strprop(context, "alphaMode", cgltf_str_from_alpha_mode(material->alpha_mode));
cgltf_write_extras(context, &material->extras);
cgltf_write_line(context, "}");
}
@ -495,7 +530,8 @@ static void cgltf_write_image(cgltf_write_context* context, const cgltf_image* i
cgltf_write_strprop(context, "name", image->name);
cgltf_write_strprop(context, "uri", image->uri);
CGLTF_WRITE_IDXPROP("bufferView", image->buffer_view, context->data->buffer_views);
cgltf_write_strprop(context, "mime_type", image->mime_type);
cgltf_write_strprop(context, "mimeType", image->mime_type);
cgltf_write_extras(context, &image->extras);
cgltf_write_line(context, "}");
}
@ -505,6 +541,7 @@ static void cgltf_write_texture(cgltf_write_context* context, const cgltf_textur
cgltf_write_strprop(context, "name", texture->name);
CGLTF_WRITE_IDXPROP("source", texture->image, context->data->images);
CGLTF_WRITE_IDXPROP("sampler", texture->sampler, context->data->samplers);
cgltf_write_extras(context, &texture->extras);
cgltf_write_line(context, "}");
}
@ -515,6 +552,7 @@ static void cgltf_write_skin(cgltf_write_context* context, const cgltf_skin* ski
CGLTF_WRITE_IDXPROP("inverseBindMatrices", skin->inverse_bind_matrices, context->data->accessors);
CGLTF_WRITE_IDXARRPROP("joints", skin->joints_count, skin->joints, context->data->nodes);
cgltf_write_strprop(context, "name", skin->name);
cgltf_write_extras(context, &skin->extras);
cgltf_write_line(context, "}");
}
@ -566,6 +604,7 @@ static void cgltf_write_animation_sampler(cgltf_write_context* context, const cg
cgltf_write_interpolation_type(context, "interpolation", animation_sampler->interpolation);
CGLTF_WRITE_IDXPROP("input", animation_sampler->input, context->data->accessors);
CGLTF_WRITE_IDXPROP("output", animation_sampler->output, context->data->accessors);
cgltf_write_extras(context, &animation_sampler->extras);
cgltf_write_line(context, "}");
}
@ -577,6 +616,7 @@ static void cgltf_write_animation_channel(cgltf_write_context* context, const cg
CGLTF_WRITE_IDXPROP("node", animation_channel->target_node, context->data->nodes);
cgltf_write_path_type(context, "path", animation_channel->target_path);
cgltf_write_line(context, "}");
cgltf_write_extras(context, &animation_channel->extras);
cgltf_write_line(context, "}");
}
@ -603,6 +643,7 @@ static void cgltf_write_animation(cgltf_write_context* context, const cgltf_anim
}
cgltf_write_line(context, "]");
}
cgltf_write_extras(context, &animation->extras);
cgltf_write_line(context, "}");
}
@ -613,6 +654,7 @@ static void cgltf_write_sampler(cgltf_write_context* context, const cgltf_sample
cgltf_write_intprop(context, "minFilter", sampler->min_filter, 0);
cgltf_write_intprop(context, "wrapS", sampler->wrap_s, 10497);
cgltf_write_intprop(context, "wrapT", sampler->wrap_t, 10497);
cgltf_write_extras(context, &sampler->extras);
cgltf_write_line(context, "}");
}
@ -663,6 +705,7 @@ static void cgltf_write_node(cgltf_write_context* context, const cgltf_node* nod
CGLTF_WRITE_IDXPROP("camera", node->camera, context->data->cameras);
}
cgltf_write_extras(context, &node->extras);
cgltf_write_line(context, "}");
}
@ -671,6 +714,7 @@ static void cgltf_write_scene(cgltf_write_context* context, const cgltf_scene* s
cgltf_write_line(context, "{");
cgltf_write_strprop(context, "name", scene->name);
CGLTF_WRITE_IDXARRPROP("nodes", scene->nodes_count, scene->nodes, context->data->nodes);
cgltf_write_extras(context, &scene->extras);
cgltf_write_line(context, "}");
}
@ -680,10 +724,10 @@ static void cgltf_write_accessor(cgltf_write_context* context, const cgltf_acces
CGLTF_WRITE_IDXPROP("bufferView", accessor->buffer_view, context->data->buffer_views);
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));
int dim = cgltf_dim_from_type(accessor->type);
cgltf_size dim = cgltf_dim_from_type(accessor->type);
cgltf_write_boolprop_optional(context, "normalized", accessor->normalized, false);
cgltf_write_intprop(context, "byteOffset", accessor->offset, 0);
cgltf_write_intprop(context, "count", accessor->count, -1);
cgltf_write_intprop(context, "byteOffset", (int)accessor->offset, 0);
cgltf_write_intprop(context, "count", (int)accessor->count, -1);
if (accessor->has_min)
{
cgltf_write_floatarrayprop(context, "min", accessor->min, dim);
@ -695,18 +739,22 @@ static void cgltf_write_accessor(cgltf_write_context* context, const cgltf_acces
if (accessor->is_sparse)
{
cgltf_write_line(context, "\"sparse\": {");
cgltf_write_intprop(context, "count", accessor->sparse.count, 0);
cgltf_write_intprop(context, "count", (int)accessor->sparse.count, 0);
cgltf_write_line(context, "\"indices\": {");
cgltf_write_intprop(context, "byteOffset", accessor->sparse.indices_byte_offset, 0);
cgltf_write_intprop(context, "byteOffset", (int)accessor->sparse.indices_byte_offset, 0);
CGLTF_WRITE_IDXPROP("bufferView", accessor->sparse.indices_buffer_view, context->data->buffer_views);
cgltf_write_intprop(context, "componentType", cgltf_int_from_component_type(accessor->sparse.indices_component_type), 0);
cgltf_write_extras(context, &accessor->sparse.indices_extras);
cgltf_write_line(context, "}");
cgltf_write_line(context, "\"values\": {");
cgltf_write_intprop(context, "byteOffset", accessor->sparse.values_byte_offset, 0);
cgltf_write_intprop(context, "byteOffset", (int)accessor->sparse.values_byte_offset, 0);
CGLTF_WRITE_IDXPROP("bufferView", accessor->sparse.values_buffer_view, context->data->buffer_views);
cgltf_write_extras(context, &accessor->sparse.values_extras);
cgltf_write_line(context, "}");
cgltf_write_extras(context, &accessor->sparse.extras);
cgltf_write_line(context, "}");
}
cgltf_write_extras(context, &accessor->extras);
cgltf_write_line(context, "}");
}
@ -722,21 +770,24 @@ static void cgltf_write_camera(cgltf_write_context* context, const cgltf_camera*
if (camera->type == cgltf_camera_type_orthographic)
{
cgltf_write_line(context, "\"orthographic\": {");
cgltf_write_floatprop(context, "xmag", camera->orthographic.xmag, -1.0f);
cgltf_write_floatprop(context, "ymag", camera->orthographic.ymag, -1.0f);
cgltf_write_floatprop(context, "zfar", camera->orthographic.zfar, -1.0f);
cgltf_write_floatprop(context, "znear", camera->orthographic.znear, -1.0f);
cgltf_write_floatprop(context, "xmag", camera->data.orthographic.xmag, -1.0f);
cgltf_write_floatprop(context, "ymag", camera->data.orthographic.ymag, -1.0f);
cgltf_write_floatprop(context, "zfar", camera->data.orthographic.zfar, -1.0f);
cgltf_write_floatprop(context, "znear", camera->data.orthographic.znear, -1.0f);
cgltf_write_extras(context, &camera->data.orthographic.extras);
cgltf_write_line(context, "}");
}
else if (camera->type == cgltf_camera_type_perspective)
{
cgltf_write_line(context, "\"perspective\": {");
cgltf_write_floatprop(context, "aspectRatio", camera->perspective.aspect_ratio, -1.0f);
cgltf_write_floatprop(context, "yfov", camera->perspective.yfov, -1.0f);
cgltf_write_floatprop(context, "zfar", camera->perspective.zfar, -1.0f);
cgltf_write_floatprop(context, "znear", camera->perspective.znear, -1.0f);
cgltf_write_floatprop(context, "aspectRatio", camera->data.perspective.aspect_ratio, -1.0f);
cgltf_write_floatprop(context, "yfov", camera->data.perspective.yfov, -1.0f);
cgltf_write_floatprop(context, "zfar", camera->data.perspective.zfar, -1.0f);
cgltf_write_floatprop(context, "znear", camera->data.perspective.znear, -1.0f);
cgltf_write_extras(context, &camera->data.perspective.extras);
cgltf_write_line(context, "}");
}
cgltf_write_extras(context, &camera->extras);
cgltf_write_line(context, "}");
}
@ -750,7 +801,7 @@ static void cgltf_write_light(cgltf_write_context* context, const cgltf_light* l
}
if (cgltf_check_floatarray(light->color, 3, 1.0f))
{
cgltf_write_floatarrayprop(context, "light", light->color, 3);
cgltf_write_floatarrayprop(context, "color", light->color, 3);
}
cgltf_write_floatprop(context, "intensity", light->intensity, 1.0f);
cgltf_write_floatprop(context, "range", light->range, 0.0f);
@ -767,9 +818,9 @@ static void cgltf_write_light(cgltf_write_context* context, const cgltf_light* l
cgltf_result cgltf_write_file(const cgltf_options* options, const char* path, const cgltf_data* data)
{
size_t expected = cgltf_write(options, NULL, 0, data);
cgltf_size expected = cgltf_write(options, NULL, 0, data);
char* buffer = (char*) malloc(expected);
size_t actual = cgltf_write(options, buffer, expected, data);
cgltf_size actual = cgltf_write(options, buffer, expected, data);
if (expected != actual) {
fprintf(stderr, "Error: expected %zu bytes but wrote %zu bytes.\n", expected, actual);
}
@ -787,6 +838,7 @@ cgltf_result cgltf_write_file(const cgltf_options* options, const char* path, co
cgltf_size cgltf_write(const cgltf_options* options, char* buffer, cgltf_size size, const cgltf_data* data)
{
(void)options;
cgltf_write_context ctx;
ctx.buffer = buffer;
ctx.buffer_size = size;
@ -885,10 +937,7 @@ cgltf_size cgltf_write(const cgltf_options* options, char* buffer, cgltf_size si
cgltf_write_line(context, "]");
}
if (data->scene)
{
cgltf_write_intprop(context, "scene", data->scene - data->scenes, -1);
}
CGLTF_WRITE_IDXPROP("scene", data->scene, data->scenes);
if (data->scenes_count > 0)
{

Binary file not shown.

View File

@ -1,53 +0,0 @@
{
"scenes" : [
{
"nodes" : [ 0 ]
}
],
"nodes" : [
{
"mesh" : 0
}
],
"meshes" : [
{
"primitives" : [ {
"attributes" : {
"POSITION" : 0
}
} ]
}
],
"buffers" : [
{
"uri" : "data:application/octet-stream;base64,AAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAA",
"byteLength" : 36
}
],
"bufferViews" : [
{
"buffer" : 0,
"byteOffset" : 0,
"byteLength" : 36,
"target" : 34962
}
],
"accessors" : [
{
"bufferView" : 0,
"byteOffset" : 0,
"componentType" : 5126,
"count" : 3,
"type" : "VEC3",
"max" : [ 1.0, 1.0, 0.0 ],
"min" : [ 0.0, 0.0, 0.0 ]
}
],
"asset" : {
"version" : "2.0"
}
}

View File

@ -1,172 +0,0 @@
{
"accessors": [
{
"bufferView": 0,
"componentType": 5126,
"count": 2549,
"type": "VEC2"
},
{
"bufferView": 1,
"componentType": 5126,
"count": 2549,
"type": "VEC3"
},
{
"bufferView": 2,
"componentType": 5126,
"count": 2549,
"type": "VEC4"
},
{
"bufferView": 3,
"componentType": 5126,
"count": 2549,
"type": "VEC3",
"max": [
0.05445001,
0.130220339,
0.0544500239
],
"min": [
-0.05445001,
-0.130220339,
-0.0544500239
]
},
{
"bufferView": 4,
"componentType": 5123,
"count": 13530,
"type": "SCALAR"
}
],
"asset": {
"generator": "glTF Tools for Unity",
"version": "2.0"
},
"bufferViews": [
{
"buffer": 0,
"byteLength": 20392
},
{
"buffer": 0,
"byteOffset": 20392,
"byteLength": 30588
},
{
"buffer": 0,
"byteOffset": 50980,
"byteLength": 40784
},
{
"buffer": 0,
"byteOffset": 91764,
"byteLength": 30588
},
{
"buffer": 0,
"byteOffset": 122352,
"byteLength": 27060
}
],
"buffers": [
{
"uri": "WaterBottle.bin",
"byteLength": 149412
}
],
"images": [
{
"uri": "WaterBottle_baseColor.png"
},
{
"uri": "WaterBottle_occlusionRoughnessMetallic.png"
},
{
"uri": "WaterBottle_normal.png"
},
{
"uri": "WaterBottle_emissive.png"
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"TEXCOORD_0": 0,
"NORMAL": 1,
"TANGENT": 2,
"POSITION": 3
},
"indices": 4,
"material": 0
}
],
"name": "WaterBottle"
}
],
"materials": [
{
"pbrMetallicRoughness": {
"baseColorTexture": {
"index": 0
},
"metallicRoughnessTexture": {
"index": 1
}
},
"normalTexture": {
"index": 2
},
"occlusionTexture": {
"index": 1
},
"emissiveFactor": [
1.0,
1.0,
1.0
],
"emissiveTexture": {
"index": 3
},
"name": "BottleMat"
}
],
"nodes": [
{
"mesh": 0,
"rotation": [
0.0,
1.0,
0.0,
0.0
],
"name": "WaterBottle"
}
],
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
],
"textures": [
{
"source": 0
},
{
"source": 1
},
{
"source": 2
},
{
"source": 3
}
]
}

View File

@ -1,201 +0,0 @@
#
# AFL dictionary for JSON
# -----------------------
#
# Just the very basics.
#
# Inspired by a dictionary by Jakub Wilk <jwilk@jwilk.net>
#
"0"
",0"
":0"
"0:"
"-1.2e+3"
"true"
"false"
"null"
"\"\""
",\"\""
":\"\""
"\"\":"
"{}"
",{}"
":{}"
"{\"\":0}"
"{{}}"
"[]"
",[]"
":[]"
"[0]"
"[[]]"
"''"
"\\"
"\\b"
"\\f"
"\\n"
"\\r"
"\\t"
"\\u0000"
"\\x00"
"\\0"
"\\uD800\\uDC00"
"\\uDBFF\\uDFFF"
"\"\":0"
"//"
"/**/"
#
# AFL dictionary for GLTF core
# -----------------------
"5120"
"5121"
"5122"
"5123"
"5125"
"5126"
"\"BLEND\""
"\"CUBICSPLINE\""
"\"LINEAR\""
"\"MASK\""
"\"MAT2\""
"\"MAT3\""
"\"MAT4\""
"\"OPAQUE\""
"\"SCALAR\""
"\"STEP\""
"\"VEC2\""
"\"VEC3\""
"\"VEC4\""
"\"accessor\""
"\"accessors\""
"\"alphaCutoff\""
"\"alphaMode\""
"\"animations\""
"\"aspectRatio\""
"\"asset\""
"\"attributes\""
"\"baseColorFactor\""
"\"baseColorTexture\""
"\"bufferView\""
"\"bufferViews\""
"\"buffer\""
"\"buffers\""
"\"byteLength\""
"\"byteOffset\""
"\"byteStride\""
"\"camera\""
"\"cameras\""
"\"channel\""
"\"channels\""
"\"children\""
"\"componentType\""
"\"copyright\""
"\"count\""
"\"doubleSided\""
"\"emissiveFactor\""
"\"emissiveTexture\""
"\"extensionsRequired\""
"\"extensionsUsed\""
"\"extensions\""
"\"extras\""
"\"generator\""
"\"image\""
"\"images\""
"\"index\""
"\"indices\""
"\"input\""
"\"interpolation\""
"\"inverseBindMatrices\""
"\"joints\""
"\"magFilter\""
"\"material\""
"\"materials\""
"\"matrix\""
"\"max\""
"\"mesh\""
"\"meshes\""
"\"metallicFactor\""
"\"metallicRoughnessTexture\""
"\"mimeType\""
"\"minFilter\""
"\"minVersion\""
"\"min\""
"\"mode\""
"\"name\""
"\"node\""
"\"nodes\""
"\"normalTextureInfo\""
"\"normalTexture\""
"\"normalized\""
"\"occlusionTextureInfo\""
"\"occlusionTexture\""
"\"orthographic\""
"\"output\""
"\"path\""
"\"pbrMetallicRoughness\""
"\"perspective\""
"\"primitive\""
"\"primitives\""
"\"rotation\""
"\"roughnessFactor\""
"\"sampler\""
"\"samplers\""
"\"scale\""
"\"scene\""
"\"scenes\""
"\"skeleton\""
"\"skin\""
"\"skins\""
"\"source\""
"\"sparse\""
"\"strength\""
"\"target\""
"\"targets\""
"\"texCoord\""
"\"textureInfo\""
"\"texture\""
"\"textures\""
"\"translation\""
"\"type\""
"\"uri\""
"\"values\""
"\"version\""
"\"weights\""
"\"wrapS\""
"\"wrapT\""
"\"xmag\""
"\"yfov\""
"\"ymag\""
"\"zfar\""
"\"znear\""
#
# AFL dictionary for GLTF extensions
# -----------------------
"\"KHR_materials_pbrSpecularGlossiness\""
"\"diffuseFactor\""
"\"diffuseTexture\""
"\"specularFactor\""
"\"glossinessFactor\""
"\"specularGlossinessTexture\""
"\"KHR_materials_unlit\""
"\"KHR_texture_transform\""
"\"offset\""
"\"rotation\""
"\"scale\""
"\"texCoord\""
"\"KHR_lights_punctual\""
"\"color\""
"\"intensity\""
"\"type\""
"\"range\""
"\"innerConeAngle\""
"\"outerConeAngle\""

View File

@ -1,22 +0,0 @@
/* How to fuzz:
clang main.c -O2 -g -fsanitize=address,fuzzer -o fuzz
cp -r data temp
./fuzz temp/ -dict=gltf.dict -jobs=12 -workers=12
*/
#define CGLTF_IMPLEMENTATION
#include "../cgltf.h"
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
{
cgltf_options options = {0};
cgltf_data* data = NULL;
cgltf_result res = cgltf_parse(&options, Data, Size, &data);
if (res == cgltf_result_success)
{
cgltf_validate(data);
cgltf_free(data);
}
return 0;
}

View File

@ -1,23 +0,0 @@
cmake_minimum_required( VERSION 2.8 )
include_directories( ${CMAKE_CURRENT_SOURCE_DIR} )
set( EXE_NAME cgltf_test )
add_executable( ${EXE_NAME} main.c )
set_property( TARGET ${EXE_NAME} PROPERTY C_STANDARD 99 )
install( TARGETS ${EXE_NAME} RUNTIME DESTINATION bin )
set( EXE_NAME test_conversion )
add_executable( ${EXE_NAME} test_conversion.cpp )
set_property( TARGET ${EXE_NAME} PROPERTY CXX_STANDARD 11 )
install( TARGETS ${EXE_NAME} RUNTIME DESTINATION bin )
set( EXE_NAME test_write )
add_executable( ${EXE_NAME} test_write.cpp )
set_property( TARGET ${EXE_NAME} PROPERTY CXX_STANDARD 11 )
install( TARGETS ${EXE_NAME} RUNTIME DESTINATION bin )
set( EXE_NAME test_math )
add_executable( ${EXE_NAME} test_math.cpp )
set_property( TARGET ${EXE_NAME} PROPERTY CXX_STANDARD 11 )
install( TARGETS ${EXE_NAME} RUNTIME DESTINATION bin )

View File

@ -1,37 +0,0 @@
#define CGLTF_IMPLEMENTATION
#include "../cgltf.h"
#include <stdio.h>
int main(int argc, char** argv)
{
if (argc < 2)
{
printf("err\n");
return -1;
}
cgltf_options options = {0};
cgltf_data* data = NULL;
cgltf_result result = cgltf_parse_file(&options, argv[1], &data);
if (result == cgltf_result_success)
result = cgltf_load_buffers(&options, data, argv[1]);
if (result == cgltf_result_success)
result = cgltf_validate(data);
printf("Result: %d\n", result);
if (result == cgltf_result_success)
{
printf("Type: %u\n", data->file_type);
printf("Meshes: %lu\n", data->meshes_count);
}
cgltf_free(data);
return result;
}

View File

@ -1,66 +0,0 @@
#!/usr/bin/env python
import os, sys
from sys import platform
num_tested = 0
num_errors = 0
def get_executable_path(name):
if platform == "win32":
return "build\\Debug\\" + name
else:
return "build/" + name
def collect_files(path, type, name):
global num_tested
global num_errors
exe = get_executable_path(name)
for the_file in os.listdir(path):
file_path = os.path.join(os.path.normpath(path), the_file)
if os.path.isfile(file_path):
if the_file.endswith(type):
num_tested = num_tested +1
print("### " + name + " " + file_path)
result = os.system("{0} \"{1}\"".format(exe, file_path))
print("### Result: " + str(result) + "\n")
if result != 0:
num_errors = num_errors + 1
print("Error.")
sys.exit(1)
elif os.path.isdir(file_path):
collect_files(file_path, type, name)
if __name__ == "__main__":
if not os.path.exists("build/"):
os.makedirs("build/")
os.chdir("build/")
os.system("cmake ..")
if os.system("cmake --build .") != 0:
print("Unable to build.")
exit(1)
os.chdir("..")
if not os.path.exists("glTF-Sample-Models/"):
os.system("git init glTF-Sample-Models")
os.chdir("glTF-Sample-Models")
os.system("git remote add origin https://github.com/KhronosGroup/glTF-Sample-Models.git")
os.system("git config core.sparsecheckout true")
f = open(".git/info/sparse-checkout", "w+")
f.write("2.0/*\n")
f.close()
os.system("git pull --depth=1 origin master")
os.chdir("..")
collect_files("glTF-Sample-Models/2.0/", ".glb", "cgltf_test")
collect_files("glTF-Sample-Models/2.0/", ".gltf", "cgltf_test")
collect_files("glTF-Sample-Models/2.0/", ".glb", "test_conversion")
collect_files("glTF-Sample-Models/2.0/", ".gltf", "test_conversion")
collect_files("glTF-Sample-Models/2.0/", ".gltf", "test_write")
result = os.system(get_executable_path("test_math"))
if result != 0:
num_errors = num_errors + 1
print("Error.")
sys.exit(1)
print("Tested files: " + str(num_tested))
print("Errors: " + str(num_errors))

View File

@ -1,69 +0,0 @@
#define CGLTF_IMPLEMENTATION
#include "../cgltf.h"
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <limits>
static bool is_near(cgltf_float a, cgltf_float b)
{
return std::abs(a - b) < 10 * std::numeric_limits<cgltf_float>::min();
}
int main(int argc, char** argv)
{
if (argc < 2)
{
printf("err\n");
return -1;
}
cgltf_options options = {};
cgltf_data* data = NULL;
cgltf_result result = cgltf_parse_file(&options, argv[1], &data);
if (result == cgltf_result_success)
result = cgltf_load_buffers(&options, data, argv[1]);
if (result != cgltf_result_success || strstr(argv[1], "Draco"))
return result;
const cgltf_accessor* blobs = data->accessors;
cgltf_float element[16];
for (cgltf_size blob_index = 0; blob_index < data->accessors_count; ++blob_index)
{
const cgltf_accessor* blob = data->accessors + blob_index;
if (blob->is_sparse)
{
cgltf_size nfloats = cgltf_num_components(blob->type) * blob->count;
cgltf_float* dense = (cgltf_float*) malloc(nfloats * sizeof(cgltf_float));
if (cgltf_accessor_unpack_floats(blob, dense, nfloats) < nfloats) {
printf("Unable to completely unpack a sparse accessor.\n");
return -1;
}
free(dense);
continue;
}
if (blob->has_max && blob->has_min)
{
cgltf_float min0 = std::numeric_limits<float>::max();
cgltf_float max0 = std::numeric_limits<float>::lowest();
for (cgltf_size index = 0; index < blob->count; index++)
{
cgltf_accessor_read_float(blob, index, element, 16);
min0 = std::min(min0, element[0]);
max0 = std::max(max0, element[0]);
}
if (!is_near(min0, blob->min[0]) || !is_near(max0, blob->max[0]))
{
printf("Computed [%f, %f] but expected [%f, %f]\n", min0, max0, blob->min[0], blob->max[0]);
return -1;
}
}
}
cgltf_free(data);
return result;
}

View File

@ -1,52 +0,0 @@
#define CGLTF_IMPLEMENTATION
#include "../cgltf.h"
// Performs matrix-vector multiplication, as in (4x4) * (4x1) = (4x1)
static void transform(const cgltf_float matrix[16], const cgltf_float source[4], cgltf_float target[4]) {
target[0] = matrix[0] * source[0] + matrix[4] * source[1] + matrix[ 8] * source[2] + matrix[12] * source[3];
target[1] = matrix[1] * source[0] + matrix[5] * source[1] + matrix[ 9] * source[2] + matrix[13] * source[3];
target[2] = matrix[2] * source[0] + matrix[6] * source[1] + matrix[10] * source[2] + matrix[14] * source[3];
target[3] = matrix[3] * source[0] + matrix[7] * source[1] + matrix[11] * source[2] + matrix[15] * source[3];
}
static void set(cgltf_float target[3], float x, float y, float z) {
target[0] = x;
target[1] = y;
target[2] = z;
}
static void check(cgltf_float target[3], float x, float y, float z) {
if (target[0] != x || target[1] != y || target[2] != z) {
fprintf(stderr, "Mismatch detected.\n");
exit(1);
}
}
int main(int argc, char** argv)
{
cgltf_node node = {};
cgltf_float matrix[16];
cgltf_float source[4] = {1, 2, 3, 1};
cgltf_float target[4];
set(node.scale, 1, 1, 1);
set(node.translation, 1, 0, 0);
cgltf_node_transform_local(&node, matrix);
transform(matrix, source, target);
check(target, 2, 2, 3);
set(node.scale, 3, 1, 1);
set(node.translation, 0, 0, 0);
cgltf_node_transform_local(&node, matrix);
transform(matrix, source, target);
check(target, 3, 2, 3);
set(node.scale, 1, 3, 1);
set(node.translation, 1, 0, 0);
cgltf_node_transform_local(&node, matrix);
transform(matrix, source, target);
check(target, 2, 6, 3);
return 0;
}

View File

@ -1,45 +0,0 @@
#define CGLTF_IMPLEMENTATION
#define CGLTF_WRITE_IMPLEMENTATION
#include "../cgltf_write.h"
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <limits>
int main(int argc, char** argv)
{
if (argc < 2)
{
printf("err\n");
return -1;
}
cgltf_options options = {};
cgltf_data* data0 = NULL;
cgltf_result result = cgltf_parse_file(&options, argv[1], &data0);
// Silently skip over files that are unreadable since this is a writing test.
if (result != cgltf_result_success)
{
return cgltf_result_success;
}
result = cgltf_write_file(&options, "out.gltf", data0);
if (result != cgltf_result_success)
{
return result;
}
cgltf_data* data1 = NULL;
result = cgltf_parse_file(&options, "out.gltf", &data1);
if (result != cgltf_result_success)
{
return result;
}
if (data0->meshes_count != data1->meshes_count) {
return -1;
}
cgltf_free(data1);
cgltf_free(data0);
return cgltf_result_success;
}