Skip to content

Commit

Permalink
Add support for double precision
Browse files Browse the repository at this point in the history
  • Loading branch information
wheresjames committed Oct 4, 2023
1 parent 271614c commit fb9c02e
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 28 deletions.
46 changes: 25 additions & 21 deletions cgltf.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,11 @@ extern "C" {

typedef size_t cgltf_size;
typedef long long int cgltf_ssize;
#ifdef GLTF_DOUBLE_PRECISION
typedef double cgltf_float;
#else
typedef float cgltf_float;
#endif
typedef int cgltf_int;
typedef unsigned int cgltf_uint;
typedef int cgltf_bool;
Expand Down Expand Up @@ -2141,22 +2145,22 @@ void cgltf_node_transform_local(const cgltf_node* node, cgltf_float* out_matrix)

if (node->has_matrix)
{
memcpy(lm, node->matrix, sizeof(float) * 16);
memcpy(lm, node->matrix, sizeof(cgltf_float) * 16);
}
else
{
float tx = node->translation[0];
float ty = node->translation[1];
float tz = node->translation[2];
cgltf_float tx = node->translation[0];
cgltf_float ty = node->translation[1];
cgltf_float tz = node->translation[2];

float qx = node->rotation[0];
float qy = node->rotation[1];
float qz = node->rotation[2];
float qw = node->rotation[3];
cgltf_float qx = node->rotation[0];
cgltf_float qy = node->rotation[1];
cgltf_float qz = node->rotation[2];
cgltf_float qw = node->rotation[3];

float sx = node->scale[0];
float sy = node->scale[1];
float sz = node->scale[2];
cgltf_float sx = node->scale[0];
cgltf_float sy = node->scale[1];
cgltf_float sz = node->scale[2];

lm[0] = (1 - 2 * qy*qy - 2 * qz*qz) * sx;
lm[1] = (2 * qx*qy + 2 * qz*qw) * sx;
Expand Down Expand Up @@ -2189,18 +2193,18 @@ void cgltf_node_transform_world(const cgltf_node* node, cgltf_float* out_matrix)

while (parent)
{
float pm[16];
cgltf_float pm[16];
cgltf_node_transform_local(parent, pm);

for (int i = 0; i < 4; ++i)
{
float l0 = lm[i * 4 + 0];
float l1 = lm[i * 4 + 1];
float l2 = lm[i * 4 + 2];
cgltf_float l0 = lm[i * 4 + 0];
cgltf_float l1 = lm[i * 4 + 1];
cgltf_float l2 = lm[i * 4 + 2];

float r0 = l0 * pm[0] + l1 * pm[4] + l2 * pm[8];
float r1 = l0 * pm[1] + l1 * pm[5] + l2 * pm[9];
float r2 = l0 * pm[2] + l1 * pm[6] + l2 * pm[10];
cgltf_float r0 = l0 * pm[0] + l1 * pm[4] + l2 * pm[8];
cgltf_float r1 = l0 * pm[1] + l1 * pm[5] + l2 * pm[9];
cgltf_float r2 = l0 * pm[2] + l1 * pm[6] + l2 * pm[10];

lm[i * 4 + 0] = r0;
lm[i * 4 + 1] = r1;
Expand Down Expand Up @@ -2434,7 +2438,7 @@ cgltf_size cgltf_accessor_unpack_floats(const cgltf_accessor* accessor, cgltf_fl
for (cgltf_size reader_index = 0; reader_index < sparse->count; reader_index++, index_data += index_stride, reader_head += accessor->stride)
{
size_t writer_index = cgltf_component_read_index(index_data, sparse->indices_component_type);
float* writer_head = out + writer_index * floats_per_element;
cgltf_float* writer_head = out + writer_index * floats_per_element;

if (!cgltf_element_read_float(reader_head, accessor->type, accessor->component_type, accessor->normalized, writer_head, floats_per_element))
{
Expand Down Expand Up @@ -2756,15 +2760,15 @@ static int cgltf_skip_json(jsmntok_t const* tokens, int i)
return i;
}

static void cgltf_fill_float_array(float* out_array, int size, float value)
static void cgltf_fill_float_array(cgltf_float* out_array, int size, cgltf_float value)
{
for (int j = 0; j < size; ++j)
{
out_array[j] = value;
}
}

static int cgltf_parse_json_float_array(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, float* out_array, int size)
static int cgltf_parse_json_float_array(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_float* out_array, int size)
{
CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_ARRAY);
if (tokens[i].size != size)
Expand Down
2 changes: 1 addition & 1 deletion cgltf_write.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ static void cgltf_write_floatarrayprop(cgltf_write_context* context, const char*
context->needs_comma = 1;
}

static bool cgltf_check_floatarray(const float* vals, int dim, float val) {
static bool cgltf_check_floatarray(const cgltf_float* vals, int dim, cgltf_float val) {
while (dim--)
{
if (vals[dim] != val)
Expand Down
5 changes: 5 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
cmake_minimum_required( VERSION 2.8 )

option(CGLTF_DOUBLE_PRECISION "Double Precision" OFF)
if(CGLTF_DOUBLE_PRECISION)
add_definitions(-DCGLTF_DOUBLE_PRECISION)
endif()

include_directories( ${CMAKE_CURRENT_SOURCE_DIR} )

set( EXE_NAME cgltf_test )
Expand Down
5 changes: 4 additions & 1 deletion test/test_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ def collect_files(path, type, name):
if not os.path.exists("build/"):
os.makedirs("build/")
os.chdir("build/")
os.system("cmake ..")
if '--double-precision' in sys.argv:
os.system("cmake .. -DCGLTF_DOUBLE_PRECISION=ON")
else:
os.system("cmake ..")
if os.system("cmake --build .") != 0:
print("Unable to build.")
exit(1)
Expand Down
9 changes: 6 additions & 3 deletions test/test_conversion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

static bool is_near(cgltf_float a, cgltf_float b)
{
return std::abs(a - b) < 10 * std::numeric_limits<cgltf_float>::min();
return std::abs((float)a - (float)b) < 10 * std::numeric_limits<float>::min();
}

int main(int argc, char** argv)
Expand Down Expand Up @@ -49,15 +49,16 @@ int main(int argc, char** argv)
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");
cgltf_free(data);
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();
cgltf_float min0 = std::numeric_limits<cgltf_float>::max();
cgltf_float max0 = std::numeric_limits<cgltf_float>::lowest();
for (cgltf_size index = 0; index < blob->count; index++)
{
cgltf_accessor_read_float(blob, index, element_float, 16);
Expand All @@ -67,6 +68,7 @@ int main(int argc, char** argv)
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]);
cgltf_free(data);
return -1;
}
}
Expand All @@ -83,6 +85,7 @@ int main(int argc, char** argv)
if ( min0 != (unsigned int) blob->min[0] || max0 != (unsigned int) blob->max[0] )
{
printf( "Computed [%u, %u] but expected [%u, %u]\n", min0, max0, (unsigned int) blob->min[0], (unsigned int) blob->max[0] );
cgltf_free(data);
return -1;
}
}
Expand Down
4 changes: 2 additions & 2 deletions test/test_math.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ static void transform(const cgltf_float matrix[16], const cgltf_float source[4],
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) {
static void set(cgltf_float target[3], cgltf_float x, cgltf_float y, cgltf_float z) {
target[0] = x;
target[1] = y;
target[2] = z;
}

static void check(cgltf_float target[3], float x, float y, float z) {
static void check(cgltf_float target[3], cgltf_float x, cgltf_float y, cgltf_float z) {
if (target[0] != x || target[1] != y || target[2] != z) {
fprintf(stderr, "Mismatch detected.\n");
exit(1);
Expand Down

0 comments on commit fb9c02e

Please sign in to comment.