1319 lines
43 KiB
C
1319 lines
43 KiB
C
#ifndef UFBXT_HASH_SCENE_H_INCLUDED
|
|
#define UFBXT_HASH_SCENE_H_INCLUDED
|
|
|
|
#include "testing_basics.h"
|
|
|
|
#include <stdio.h>
|
|
#include <assert.h>
|
|
|
|
typedef struct ufbxt_hash {
|
|
uint64_t state;
|
|
bool dumping;
|
|
FILE *dump_file;
|
|
size_t indent;
|
|
bool at_tag;
|
|
bool at_value;
|
|
bool big_endian;
|
|
} ufbxt_hash;
|
|
|
|
ufbxt_noinline static void ufbxt_hash_init(ufbxt_hash *h, FILE *dump_file)
|
|
{
|
|
memset(h, 0, sizeof(ufbxt_hash));
|
|
h->state = UINT64_C(0xcbf29ce484222325);
|
|
{
|
|
uint8_t buf[2];
|
|
uint16_t val = 0xbbaa;
|
|
memcpy(buf, &val, 2);
|
|
h->big_endian = buf[0] == 0xbb;
|
|
}
|
|
|
|
if (dump_file) {
|
|
h->dumping = true;
|
|
h->dump_file = dump_file;
|
|
}
|
|
}
|
|
|
|
ufbxt_noinline static uint64_t ufbxt_hash_finish(ufbxt_hash *h)
|
|
{
|
|
if (h->dump_file) {
|
|
fflush(h->dump_file);
|
|
}
|
|
return h->state;
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_push_tag(ufbxt_hash *h, const char *tag)
|
|
{
|
|
if (!h->dumping) return;
|
|
if (tag[0] == '&') {
|
|
tag++;
|
|
}
|
|
if (!strncmp(tag, "v->", 3)) {
|
|
tag += 3;
|
|
} else if (!strncmp(tag, "v.", 2)) {
|
|
tag += 2;
|
|
}
|
|
|
|
if (h->at_tag) {
|
|
fprintf(h->dump_file, "{\n");
|
|
h->indent += 1;
|
|
}
|
|
for (size_t i = 0; i < h->indent; i++) {
|
|
fprintf(h->dump_file, " ");
|
|
}
|
|
fprintf(h->dump_file, "%s: ", tag);
|
|
h->at_tag = true;
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_push_tag_index(ufbxt_hash *h, size_t index)
|
|
{
|
|
if (!h->dumping) return;
|
|
char buf[128];
|
|
snprintf(buf, sizeof(buf), "[%zu]", index);
|
|
ufbxt_push_tag(h, buf);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_pop_tag(ufbxt_hash *h)
|
|
{
|
|
if (!h->dumping) return;
|
|
if (h->at_value || h->at_tag) {
|
|
fprintf(h->dump_file, "\n");
|
|
h->at_value = false;
|
|
h->at_tag = false;
|
|
} else {
|
|
h->indent -= 1;
|
|
for (size_t i = 0; i < h->indent; i++) {
|
|
fprintf(h->dump_file, " ");
|
|
}
|
|
fprintf(h->dump_file, "}\n");
|
|
}
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_dump_data(ufbxt_hash *h, const void *data, size_t size, bool reverse)
|
|
{
|
|
assert(h->at_tag && !h->at_value);
|
|
h->at_tag = false;
|
|
h->at_value = true;
|
|
|
|
const char *d = (const char*)data;
|
|
if (reverse) {
|
|
for (size_t i = size; i > 0; i--) {
|
|
uint32_t b = (uint32_t)(uint8_t)d[i - 1];
|
|
fprintf(h->dump_file, "%02x", b);
|
|
}
|
|
} else {
|
|
for (size_t i = 0; i < size; i++) {
|
|
uint32_t b = (uint32_t)(uint8_t)d[i];
|
|
fprintf(h->dump_file, "%02x", b);
|
|
}
|
|
}
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_data(ufbxt_hash *h, const void *data, size_t size)
|
|
{
|
|
const char *d = (const char*)data;
|
|
uint64_t state = h->state;
|
|
for (size_t i = 0; i < size; i++) {
|
|
state = (state ^ (uint8_t)d[i]) * UINT64_C(0x00000100000001B3);
|
|
}
|
|
h->state = state;
|
|
|
|
if (h->dumping) {
|
|
ufbxt_dump_data(h, data, size, false);
|
|
}
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_endian_data(ufbxt_hash *h, const void *data, size_t size)
|
|
{
|
|
bool reverse = !h->big_endian;
|
|
assert(size == 1 || size == 2 || size == 4 || size == 8);
|
|
|
|
const char *d = (const char*)data;
|
|
uint64_t state = h->state;
|
|
if (reverse) {
|
|
for (size_t i = size; i > 0; i--) {
|
|
state = (state ^ (uint8_t)d[i - 1]) * UINT64_C(0x00000100000001B3);
|
|
}
|
|
} else {
|
|
for (size_t i = 0; i < size; i++) {
|
|
state = (state ^ (uint8_t)d[i]) * UINT64_C(0x00000100000001B3);
|
|
}
|
|
}
|
|
h->state = state;
|
|
|
|
if (h->dumping) {
|
|
ufbxt_dump_data(h, data, size, true);
|
|
}
|
|
}
|
|
|
|
#define ufbxt_hash_pod_imp(h, v) ufbxt_hash_endian_data((h), &(v), sizeof((v)))
|
|
#define ufbxt_hash_pod(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_pod_imp(h, v), ufbxt_pop_tag(h))
|
|
|
|
ufbxt_noinline static void ufbxt_hash_float_imp(ufbxt_hash *h, float v)
|
|
{
|
|
if (v == v) {
|
|
ufbxt_hash_pod_imp(h, v);
|
|
} else {
|
|
uint32_t u = UINT32_MAX;
|
|
ufbxt_hash_pod_imp(h, u);
|
|
}
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_double_imp(ufbxt_hash *h, double v)
|
|
{
|
|
if (v == v) {
|
|
ufbxt_hash_pod_imp(h, v);
|
|
} else {
|
|
uint64_t u = UINT64_MAX;
|
|
ufbxt_hash_pod_imp(h, u);
|
|
}
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_real_imp(ufbxt_hash *h, ufbx_real v)
|
|
{
|
|
if (v == v) {
|
|
ufbxt_hash_pod_imp(h, v);
|
|
} else {
|
|
uint64_t u = UINT64_MAX;
|
|
ufbxt_hash_pod_imp(h, u);
|
|
}
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_size_t_imp(ufbxt_hash *h, size_t v)
|
|
{
|
|
uint64_t u = v;
|
|
ufbxt_hash_pod_imp(h, u);
|
|
}
|
|
|
|
#define ufbxt_hash_float(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_float_imp(h, v), ufbxt_pop_tag(h))
|
|
#define ufbxt_hash_double(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_double_imp(h, v), ufbxt_pop_tag(h))
|
|
#define ufbxt_hash_real(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_real_imp(h, v), ufbxt_pop_tag(h))
|
|
#define ufbxt_hash_size_t(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_size_t_imp(h, v), ufbxt_pop_tag(h))
|
|
|
|
ufbxt_noinline static void ufbxt_hash_vec2_imp(ufbxt_hash *h, ufbx_vec2 v)
|
|
{
|
|
ufbxt_hash_real(h, v.x);
|
|
ufbxt_hash_real(h, v.y);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_vec3_imp(ufbxt_hash *h, ufbx_vec3 v)
|
|
{
|
|
ufbxt_hash_real(h, v.x);
|
|
ufbxt_hash_real(h, v.y);
|
|
ufbxt_hash_real(h, v.z);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_vec4_imp(ufbxt_hash *h, ufbx_vec4 v)
|
|
{
|
|
ufbxt_hash_real(h, v.x);
|
|
ufbxt_hash_real(h, v.y);
|
|
ufbxt_hash_real(h, v.z);
|
|
ufbxt_hash_real(h, v.w);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_quat_imp(ufbxt_hash *h, ufbx_quat v)
|
|
{
|
|
ufbxt_hash_real(h, v.x);
|
|
ufbxt_hash_real(h, v.y);
|
|
ufbxt_hash_real(h, v.z);
|
|
ufbxt_hash_real(h, v.w);
|
|
}
|
|
|
|
#define ufbxt_hash_vec2(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_vec2_imp(h, v), ufbxt_pop_tag(h))
|
|
#define ufbxt_hash_vec3(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_vec3_imp(h, v), ufbxt_pop_tag(h))
|
|
#define ufbxt_hash_vec4(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_vec4_imp(h, v), ufbxt_pop_tag(h))
|
|
#define ufbxt_hash_quat(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_quat_imp(h, v), ufbxt_pop_tag(h))
|
|
|
|
ufbxt_noinline static void ufbxt_hash_transform_imp(ufbxt_hash *h, ufbx_transform v)
|
|
{
|
|
ufbxt_hash_vec3(h, v.translation);
|
|
ufbxt_hash_quat(h, v.rotation);
|
|
ufbxt_hash_vec3(h, v.scale);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_matrix_imp(ufbxt_hash *h, ufbx_matrix v)
|
|
{
|
|
ufbxt_hash_vec3(h, v.cols[0]);
|
|
ufbxt_hash_vec3(h, v.cols[1]);
|
|
ufbxt_hash_vec3(h, v.cols[2]);
|
|
ufbxt_hash_vec3(h, v.cols[3]);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_string_imp(ufbxt_hash *h, ufbx_string v)
|
|
{
|
|
ufbxt_hash_size_t(h, v.length);
|
|
ufbxt_push_tag(h, "v.data");
|
|
ufbxt_hash_data(h, v.data, v.length + 1);
|
|
ufbxt_pop_tag(h);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_blob_imp(ufbxt_hash *h, ufbx_blob v)
|
|
{
|
|
ufbxt_hash_size_t(h, v.size);
|
|
ufbxt_push_tag(h, "v.data");
|
|
ufbxt_hash_data(h, v.data, v.size);
|
|
ufbxt_pop_tag(h);
|
|
}
|
|
|
|
#define ufbxt_hash_transform(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_transform_imp(h, v), ufbxt_pop_tag(h))
|
|
#define ufbxt_hash_matrix(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_matrix_imp(h, v), ufbxt_pop_tag(h))
|
|
#define ufbxt_hash_string(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_string_imp(h, v), ufbxt_pop_tag(h))
|
|
#define ufbxt_hash_blob(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_blob_imp(h, v), ufbxt_pop_tag(h))
|
|
|
|
ufbxt_noinline static void ufbxt_hash_element_ref_imp(ufbxt_hash *h, const void *v)
|
|
{
|
|
const ufbx_element *elem = (const ufbx_element*)v;
|
|
uint32_t id = elem ? elem->element_id : UINT32_MAX;
|
|
ufbxt_hash_pod(h, id);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_prop_ref_imp(ufbxt_hash *h, const ufbx_prop *prop)
|
|
{
|
|
if (!prop) {
|
|
uint32_t zero = UINT32_MAX;
|
|
ufbxt_hash_pod(h, zero);
|
|
} else {
|
|
ufbxt_hash_string(h, prop->name);
|
|
}
|
|
}
|
|
|
|
#define ufbxt_hash_prop_ref(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_prop_ref_imp(h, v), ufbxt_pop_tag(h))
|
|
#define ufbxt_hash_element_ref(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_element_ref_imp(h, v), ufbxt_pop_tag(h))
|
|
|
|
ufbxt_noinline static void ufbxt_hash_connection_imp(ufbxt_hash *h, ufbx_connection v)
|
|
{
|
|
ufbxt_hash_element_ref(h, v.src);
|
|
ufbxt_hash_element_ref(h, v.dst);
|
|
ufbxt_hash_string(h, v.src_prop);
|
|
ufbxt_hash_string(h, v.dst_prop);
|
|
}
|
|
|
|
#define ufbxt_hash_connection(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_connection_imp(h, v), ufbxt_pop_tag(h))
|
|
|
|
#define ufbxt_hash_array(h, v, func) do { \
|
|
ufbxt_push_tag(h, #v); \
|
|
for (size_t i = 0; i < sizeof(v) / sizeof(*(v)); i++) { \
|
|
ufbxt_push_tag_index(h, i); \
|
|
func((h), (v)[i]); \
|
|
ufbxt_pop_tag(h); \
|
|
} \
|
|
ufbxt_pop_tag(h); \
|
|
} while (0)
|
|
|
|
#define ufbxt_hash_list(h, v, func) do { \
|
|
ufbxt_push_tag(h, #v); \
|
|
size_t count = (v).count; \
|
|
ufbxt_hash_size_t((h), count); \
|
|
ufbxt_push_tag(h, "data"); \
|
|
for (size_t i = 0; i < count; i++) { \
|
|
ufbxt_push_tag_index(h, i); \
|
|
func((h), (v).data[i]); \
|
|
ufbxt_pop_tag(h); \
|
|
} \
|
|
ufbxt_pop_tag(h); \
|
|
ufbxt_pop_tag(h); \
|
|
} while (0)
|
|
|
|
#define ufbxt_hash_list_ptr(h, v, func) do { \
|
|
ufbxt_push_tag(h, #v); \
|
|
size_t count = (v).count; \
|
|
ufbxt_hash_size_t((h), count); \
|
|
ufbxt_push_tag(h, "data"); \
|
|
for (size_t i = 0; i < count; i++) { \
|
|
ufbxt_push_tag_index(h, i); \
|
|
func((h), &(v).data[i]); \
|
|
ufbxt_pop_tag(h); \
|
|
} \
|
|
ufbxt_pop_tag(h); \
|
|
ufbxt_pop_tag(h); \
|
|
} while (0)
|
|
|
|
ufbxt_noinline static void ufbxt_hash_prop_imp(ufbxt_hash *h, const ufbx_prop *v)
|
|
{
|
|
ufbxt_hash_string(h, v->name);
|
|
ufbxt_hash_pod(h, v->_internal_key);
|
|
ufbxt_hash_pod(h, v->type);
|
|
ufbxt_hash_pod(h, v->flags);
|
|
ufbxt_hash_string(h, v->value_str);
|
|
ufbxt_hash_blob(h, v->value_blob);
|
|
ufbxt_hash_pod(h, v->value_int);
|
|
ufbxt_hash_vec4(h, v->value_vec4);
|
|
}
|
|
|
|
#define ufbxt_hash_prop(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_prop_imp(h, v), ufbxt_pop_tag(h))
|
|
|
|
ufbxt_noinline static void ufbxt_hash_dom_value_imp(ufbxt_hash *h, const ufbx_dom_value *v)
|
|
{
|
|
ufbxt_hash_pod(h, v->type);
|
|
ufbxt_hash_string(h, v->value_str);
|
|
size_t count = (size_t)v->value_int;
|
|
if (v->type == UFBX_DOM_VALUE_ARRAY_RAW_STRING) {
|
|
const ufbx_string *vs = (const ufbx_string*)v->value_blob.data;
|
|
for (size_t i = 0; i < count; i++) {
|
|
ufbxt_hash_string(h, vs[i]);
|
|
}
|
|
} else if (v->type == UFBX_DOM_VALUE_ARRAY_F32) {
|
|
const float *vs = (const float*)v->value_blob.data;
|
|
for (size_t i = 0; i < count; i++) {
|
|
ufbxt_hash_float(h, vs[i]);
|
|
}
|
|
} else if (v->type == UFBX_DOM_VALUE_ARRAY_F64) {
|
|
const double *vs = (const double*)v->value_blob.data;
|
|
for (size_t i = 0; i < count; i++) {
|
|
ufbxt_hash_double(h, vs[i]);
|
|
}
|
|
} else {
|
|
ufbxt_hash_blob(h, v->value_blob);
|
|
}
|
|
ufbxt_hash_pod(h, v->value_int);
|
|
ufbxt_hash_double(h, v->value_float);
|
|
}
|
|
|
|
#define ufbxt_hash_dom_value(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_dom_value_imp(h, v), ufbxt_pop_tag(h))
|
|
|
|
ufbxt_noinline static void ufbxt_hash_dom_node_imp(ufbxt_hash *h, const ufbx_dom_node *v)
|
|
{
|
|
ufbxt_hash_string(h, v->name);
|
|
ufbxt_hash_list(h, v->children, ufbxt_hash_dom_node_imp);
|
|
ufbxt_hash_list_ptr(h, v->values, ufbxt_hash_dom_value_imp);
|
|
}
|
|
|
|
#define ufbxt_hash_dom_node(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_dom_node_imp(h, v), ufbxt_pop_tag(h))
|
|
|
|
ufbxt_noinline static void ufbxt_hash_props_imp(ufbxt_hash *h, const ufbx_props *v)
|
|
{
|
|
ufbxt_hash_list_ptr(h, v->props, ufbxt_hash_prop_imp);
|
|
ufbxt_hash_size_t(h, v->num_animated);
|
|
if (v->defaults) {
|
|
ufbxt_push_tag(h, "defaults");
|
|
ufbxt_hash_props_imp(h, v->defaults);
|
|
ufbxt_pop_tag(h);
|
|
}
|
|
}
|
|
|
|
#define ufbxt_hash_props(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_props_imp(h, v), ufbxt_pop_tag(h))
|
|
|
|
ufbxt_noinline static void ufbxt_hash_element_imp(ufbxt_hash *h, const ufbx_element *v)
|
|
{
|
|
ufbxt_hash_string(h, v->name);
|
|
ufbxt_hash_props(h, &v->props);
|
|
ufbxt_hash_pod(h, v->element_id);
|
|
ufbxt_hash_pod(h, v->typed_id);
|
|
ufbxt_hash_list(h, v->instances, ufbxt_hash_element_ref_imp);
|
|
ufbxt_hash_pod(h, v->type);
|
|
ufbxt_hash_list(h, v->connections_src, ufbxt_hash_connection_imp);
|
|
ufbxt_hash_list(h, v->connections_dst, ufbxt_hash_connection_imp);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_unknown_imp(ufbxt_hash *h, const ufbx_unknown *v)
|
|
{
|
|
ufbxt_hash_string(h, v->type);
|
|
ufbxt_hash_string(h, v->super_type);
|
|
ufbxt_hash_string(h, v->sub_type);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_node_imp(ufbxt_hash *h, const ufbx_node *v)
|
|
{
|
|
ufbxt_hash_element_ref(h, v->parent);
|
|
ufbxt_hash_list(h, v->children, ufbxt_hash_element_ref_imp);
|
|
ufbxt_hash_element_ref(h, v->mesh);
|
|
ufbxt_hash_element_ref(h, v->light);
|
|
ufbxt_hash_element_ref(h, v->camera);
|
|
ufbxt_hash_element_ref(h, v->bone);
|
|
ufbxt_hash_element_ref(h, v->attrib);
|
|
ufbxt_hash_element_ref(h, v->geometry_transform_helper);
|
|
ufbxt_hash_pod(h, v->attrib_type);
|
|
ufbxt_hash_list(h, v->all_attribs, ufbxt_hash_element_ref_imp);
|
|
ufbxt_hash_pod(h, v->inherit_type);
|
|
ufbxt_hash_transform(h, v->local_transform);
|
|
ufbxt_hash_transform(h, v->geometry_transform);
|
|
ufbxt_hash_pod(h, v->rotation_order);
|
|
ufbxt_hash_vec3(h, v->euler_rotation);
|
|
ufbxt_hash_transform(h, v->world_transform);
|
|
ufbxt_hash_matrix(h, v->node_to_parent);
|
|
ufbxt_hash_matrix(h, v->node_to_world);
|
|
ufbxt_hash_matrix(h, v->geometry_to_node);
|
|
ufbxt_hash_matrix(h, v->geometry_to_world);
|
|
ufbxt_hash_quat(h, v->adjust_pre_rotation);
|
|
ufbxt_hash_vec3(h, v->adjust_pre_scale);
|
|
ufbxt_hash_quat(h, v->adjust_post_rotation);
|
|
ufbxt_hash_pod(h, v->visible);
|
|
ufbxt_hash_pod(h, v->is_root);
|
|
ufbxt_hash_pod(h, v->has_geometry_transform);
|
|
ufbxt_hash_pod(h, v->has_adjust_transform);
|
|
ufbxt_hash_pod(h, v->is_geometry_transform_helper);
|
|
ufbxt_hash_pod(h, v->node_depth);
|
|
ufbxt_hash_list(h, v->materials, ufbxt_hash_element_ref_imp);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_vertex_real_imp(ufbxt_hash *h, const ufbx_vertex_real *v)
|
|
{
|
|
ufbxt_hash_pod(h, v->exists);
|
|
ufbxt_hash_list(h, v->values, ufbxt_hash_real_imp);
|
|
ufbxt_hash_list(h, v->indices, ufbxt_hash_pod_imp);
|
|
ufbxt_hash_size_t(h, v->value_reals);
|
|
ufbxt_hash_pod(h, v->unique_per_vertex);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_vertex_vec2_imp(ufbxt_hash *h, const ufbx_vertex_vec2 *v)
|
|
{
|
|
ufbxt_hash_pod(h, v->exists);
|
|
ufbxt_hash_list(h, v->values, ufbxt_hash_vec2_imp);
|
|
ufbxt_hash_list(h, v->indices, ufbxt_hash_pod_imp);
|
|
ufbxt_hash_size_t(h, v->value_reals);
|
|
ufbxt_hash_pod(h, v->unique_per_vertex);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_vertex_vec3_imp(ufbxt_hash *h, const ufbx_vertex_vec3 *v)
|
|
{
|
|
ufbxt_hash_pod(h, v->exists);
|
|
ufbxt_hash_list(h, v->values, ufbxt_hash_vec3_imp);
|
|
ufbxt_hash_list(h, v->indices, ufbxt_hash_pod_imp);
|
|
ufbxt_hash_size_t(h, v->value_reals);
|
|
ufbxt_hash_pod(h, v->unique_per_vertex);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_vertex_vec4_imp(ufbxt_hash *h, const ufbx_vertex_vec4 *v)
|
|
{
|
|
ufbxt_hash_pod(h, v->exists);
|
|
ufbxt_hash_list(h, v->values, ufbxt_hash_vec4);
|
|
ufbxt_hash_list(h, v->indices, ufbxt_hash_pod);
|
|
ufbxt_hash_size_t(h, v->value_reals);
|
|
ufbxt_hash_pod(h, v->unique_per_vertex);
|
|
}
|
|
|
|
#define ufbxt_hash_vertex_real(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_vertex_real_imp(h, v), ufbxt_pop_tag(h))
|
|
#define ufbxt_hash_vertex_vec2(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_vertex_vec2_imp(h, v), ufbxt_pop_tag(h))
|
|
#define ufbxt_hash_vertex_vec3(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_vertex_vec3_imp(h, v), ufbxt_pop_tag(h))
|
|
#define ufbxt_hash_vertex_vec4(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_vertex_vec4_imp(h, v), ufbxt_pop_tag(h))
|
|
|
|
ufbxt_noinline static void ufbxt_hash_uv_set_imp(ufbxt_hash *h, const ufbx_uv_set *v)
|
|
{
|
|
ufbxt_hash_string(h, v->name);
|
|
ufbxt_hash_pod(h, v->index);
|
|
ufbxt_hash_vertex_vec2(h, &v->vertex_uv);
|
|
ufbxt_hash_vertex_vec3(h, &v->vertex_tangent);
|
|
ufbxt_hash_vertex_vec3(h, &v->vertex_bitangent);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_color_set_imp(ufbxt_hash *h, const ufbx_color_set *v)
|
|
{
|
|
ufbxt_hash_string(h, v->name);
|
|
ufbxt_hash_pod(h, v->index);
|
|
ufbxt_hash_vertex_vec4(h, &v->vertex_color);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_mesh_material_imp(ufbxt_hash *h, const ufbx_mesh_material *v)
|
|
{
|
|
ufbxt_hash_element_ref(h, v->material);
|
|
ufbxt_hash_size_t(h, v->num_faces);
|
|
ufbxt_hash_size_t(h, v->num_triangles);
|
|
ufbxt_hash_size_t(h, v->num_empty_faces);
|
|
ufbxt_hash_size_t(h, v->num_point_faces);
|
|
ufbxt_hash_size_t(h, v->num_line_faces);
|
|
ufbxt_hash_list(h, v->face_indices, ufbxt_hash_pod_imp);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_face_group_imp(ufbxt_hash *h, const ufbx_face_group *v)
|
|
{
|
|
ufbxt_hash_pod(h, v->id);
|
|
ufbxt_hash_string(h, v->name);
|
|
ufbxt_hash_size_t(h, v->num_faces);
|
|
ufbxt_hash_size_t(h, v->num_triangles);
|
|
ufbxt_hash_list(h, v->face_indices, ufbxt_hash_pod_imp);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_subdivision_weight_range_imp(ufbxt_hash *h, ufbx_subdivision_weight_range v)
|
|
{
|
|
ufbxt_hash_pod(h, v.weight_begin);
|
|
ufbxt_hash_pod(h, v.num_weights);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_subdivision_weight_imp(ufbxt_hash *h, ufbx_subdivision_weight v)
|
|
{
|
|
ufbxt_hash_real(h, v.weight);
|
|
ufbxt_hash_pod(h, v.index);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_subdivision_result_imp(ufbxt_hash *h, const ufbx_subdivision_result *v)
|
|
{
|
|
ufbxt_hash_list(h, v->source_vertex_ranges, ufbxt_hash_subdivision_weight_range_imp);
|
|
ufbxt_hash_list(h, v->source_vertex_weights, ufbxt_hash_subdivision_weight_imp);
|
|
ufbxt_hash_list(h, v->skin_cluster_ranges, ufbxt_hash_subdivision_weight_range_imp);
|
|
ufbxt_hash_list(h, v->skin_cluster_weights, ufbxt_hash_subdivision_weight_imp);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_face_imp(ufbxt_hash *h, ufbx_face v)
|
|
{
|
|
ufbxt_hash_pod(h, v.index_begin);
|
|
ufbxt_hash_pod(h, v.num_indices);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_edge_imp(ufbxt_hash *h, ufbx_edge v)
|
|
{
|
|
ufbxt_hash_pod(h, v.a);
|
|
ufbxt_hash_pod(h, v.b);
|
|
}
|
|
|
|
#define ufbxt_hash_subdivision_result(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_subdivision_result_imp(h, v), ufbxt_pop_tag(h))
|
|
|
|
ufbxt_noinline static void ufbxt_hash_mesh_imp(ufbxt_hash *h, const ufbx_mesh *v)
|
|
{
|
|
ufbxt_hash_size_t(h, v->num_vertices);
|
|
ufbxt_hash_size_t(h, v->num_indices);
|
|
ufbxt_hash_size_t(h, v->num_faces);
|
|
ufbxt_hash_size_t(h, v->num_triangles);
|
|
ufbxt_hash_size_t(h, v->num_edges);
|
|
|
|
ufbxt_hash_list(h, v->faces, ufbxt_hash_face_imp);
|
|
ufbxt_hash_list(h, v->face_smoothing, ufbxt_hash_pod_imp);
|
|
ufbxt_hash_list(h, v->face_material, ufbxt_hash_pod_imp);
|
|
ufbxt_hash_list(h, v->face_group, ufbxt_hash_pod_imp);
|
|
ufbxt_hash_list(h, v->face_hole, ufbxt_hash_pod_imp);
|
|
ufbxt_hash_size_t(h, v->max_face_triangles);
|
|
ufbxt_hash_size_t(h, v->num_empty_faces);
|
|
ufbxt_hash_size_t(h, v->num_point_faces);
|
|
ufbxt_hash_size_t(h, v->num_line_faces);
|
|
|
|
ufbxt_hash_list(h, v->edges, ufbxt_hash_edge_imp);
|
|
ufbxt_hash_list(h, v->edge_smoothing, ufbxt_hash_pod_imp);
|
|
ufbxt_hash_list(h, v->edge_crease, ufbxt_hash_real_imp);
|
|
ufbxt_hash_list(h, v->edge_visibility, ufbxt_hash_pod_imp);
|
|
|
|
ufbxt_hash_list(h, v->vertex_indices, ufbxt_hash_pod_imp);
|
|
ufbxt_hash_list(h, v->vertices, ufbxt_hash_vec3_imp);
|
|
ufbxt_hash_list(h, v->vertex_first_index, ufbxt_hash_pod_imp);
|
|
|
|
ufbxt_hash_vertex_vec3(h, &v->vertex_position);
|
|
ufbxt_hash_vertex_vec3(h, &v->vertex_normal);
|
|
ufbxt_hash_vertex_vec2(h, &v->vertex_uv);
|
|
ufbxt_hash_vertex_vec3(h, &v->vertex_tangent);
|
|
ufbxt_hash_vertex_vec3(h, &v->vertex_bitangent);
|
|
ufbxt_hash_vertex_vec4(h, &v->vertex_color);
|
|
ufbxt_hash_vertex_real(h, &v->vertex_crease);
|
|
|
|
ufbxt_hash_list_ptr(h, v->uv_sets, ufbxt_hash_uv_set_imp);
|
|
ufbxt_hash_list_ptr(h, v->color_sets, ufbxt_hash_color_set_imp);
|
|
|
|
ufbxt_hash_list_ptr(h, v->materials, ufbxt_hash_mesh_material_imp);
|
|
ufbxt_hash_list_ptr(h, v->face_groups, ufbxt_hash_face_group_imp);
|
|
|
|
ufbxt_hash_pod(h, v->skinned_is_local);
|
|
ufbxt_hash_vertex_vec3(h, &v->skinned_position);
|
|
ufbxt_hash_vertex_vec3(h, &v->skinned_normal);
|
|
|
|
ufbxt_hash_list(h, v->skin_deformers, ufbxt_hash_element_ref_imp);
|
|
ufbxt_hash_list(h, v->blend_deformers, ufbxt_hash_element_ref_imp);
|
|
ufbxt_hash_list(h, v->cache_deformers, ufbxt_hash_element_ref_imp);
|
|
ufbxt_hash_list(h, v->all_deformers, ufbxt_hash_element_ref_imp);
|
|
|
|
ufbxt_hash_pod(h, v->subdivision_preview_levels);
|
|
ufbxt_hash_pod(h, v->subdivision_render_levels);
|
|
ufbxt_hash_pod(h, v->subdivision_display_mode);
|
|
ufbxt_hash_pod(h, v->subdivision_boundary);
|
|
ufbxt_hash_pod(h, v->subdivision_uv_boundary);
|
|
|
|
ufbxt_hash_pod(h, v->subdivision_evaluated);
|
|
if (v->subdivision_result) ufbxt_hash_subdivision_result(h, v->subdivision_result);
|
|
ufbxt_hash_pod(h, v->from_tessellated_nurbs);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_light_imp(ufbxt_hash *h, const ufbx_light *v)
|
|
{
|
|
ufbxt_hash_vec3(h, v->color);
|
|
ufbxt_hash_real(h, v->intensity);
|
|
ufbxt_hash_vec3(h, v->local_direction);
|
|
ufbxt_hash_pod(h, v->type);
|
|
ufbxt_hash_pod(h, v->decay);
|
|
ufbxt_hash_pod(h, v->area_shape);
|
|
ufbxt_hash_real(h, v->inner_angle);
|
|
ufbxt_hash_real(h, v->outer_angle);
|
|
ufbxt_hash_pod(h, v->cast_light);
|
|
ufbxt_hash_pod(h, v->cast_shadows);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_camera_imp(ufbxt_hash *h, const ufbx_camera *v)
|
|
{
|
|
ufbxt_hash_pod(h, v->resolution_is_pixels);
|
|
ufbxt_hash_vec2(h, v->resolution);
|
|
ufbxt_hash_vec2(h, v->field_of_view_deg);
|
|
ufbxt_hash_vec2(h, v->field_of_view_tan);
|
|
ufbxt_hash_pod(h, v->aspect_mode);
|
|
ufbxt_hash_pod(h, v->aperture_mode);
|
|
ufbxt_hash_pod(h, v->gate_fit);
|
|
ufbxt_hash_pod(h, v->aperture_format);
|
|
ufbxt_hash_real(h, v->focal_length_mm);
|
|
ufbxt_hash_vec2(h, v->film_size_inch);
|
|
ufbxt_hash_vec2(h, v->aperture_size_inch);
|
|
ufbxt_hash_real(h, v->squeeze_ratio);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_bone_imp(ufbxt_hash *h, const ufbx_bone *v)
|
|
{
|
|
ufbxt_hash_real(h, v->radius);
|
|
ufbxt_hash_real(h, v->relative_length);
|
|
ufbxt_hash_pod(h, v->is_root);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_empty_imp(ufbxt_hash *h, const ufbx_empty *v)
|
|
{
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_nurbs_basis_imp(ufbxt_hash *h, const ufbx_nurbs_basis *v)
|
|
{
|
|
ufbxt_hash_pod(h, v->order);
|
|
ufbxt_hash_pod(h, v->topology);
|
|
ufbxt_hash_list(h, v->knot_vector, ufbxt_hash_real_imp);
|
|
ufbxt_hash_real(h, v->t_min);
|
|
ufbxt_hash_real(h, v->t_max);
|
|
ufbxt_hash_list(h, v->spans, ufbxt_hash_real_imp);
|
|
ufbxt_hash_pod(h, v->is_2d);
|
|
ufbxt_hash_size_t(h, v->num_wrap_control_points);
|
|
ufbxt_hash_pod(h, v->valid);
|
|
}
|
|
|
|
#define ufbxt_hash_nurbs_basis(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_nurbs_basis_imp(h, v), ufbxt_pop_tag(h))
|
|
|
|
ufbxt_noinline static void ufbxt_hash_line_segment_imp(ufbxt_hash *h, ufbx_line_segment v)
|
|
{
|
|
ufbxt_hash_pod(h, v.index_begin);
|
|
ufbxt_hash_pod(h, v.num_indices);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_line_curve_imp(ufbxt_hash *h, const ufbx_line_curve *v)
|
|
{
|
|
ufbxt_hash_vec3(h, v->color);
|
|
ufbxt_hash_list(h, v->control_points, ufbxt_hash_vec3_imp);
|
|
ufbxt_hash_list(h, v->point_indices, ufbxt_hash_pod_imp);
|
|
ufbxt_hash_list(h, v->segments, ufbxt_hash_line_segment_imp);
|
|
ufbxt_hash_pod(h, v->from_tessellated_nurbs);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_nurbs_curve_imp(ufbxt_hash *h, const ufbx_nurbs_curve *v)
|
|
{
|
|
ufbxt_hash_nurbs_basis(h, &v->basis);
|
|
ufbxt_hash_list(h, v->control_points, ufbxt_hash_vec4_imp);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_nurbs_surface_imp(ufbxt_hash *h, const ufbx_nurbs_surface *v)
|
|
{
|
|
ufbxt_hash_nurbs_basis(h, &v->basis_u);
|
|
ufbxt_hash_nurbs_basis(h, &v->basis_v);
|
|
ufbxt_hash_size_t(h, v->num_control_points_u);
|
|
ufbxt_hash_size_t(h, v->num_control_points_v);
|
|
ufbxt_hash_list(h, v->control_points, ufbxt_hash_vec4_imp);
|
|
ufbxt_hash_pod(h, v->span_subdivision_u);
|
|
ufbxt_hash_pod(h, v->span_subdivision_v);
|
|
ufbxt_hash_pod(h, v->flip_normals);
|
|
ufbxt_hash_element_ref(h, v->material);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_nurbs_trim_surface_imp(ufbxt_hash *h, const ufbx_nurbs_trim_surface *v)
|
|
{
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_nurbs_trim_boundary_imp(ufbxt_hash *h, const ufbx_nurbs_trim_boundary *v)
|
|
{
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_procedural_geometry_imp(ufbxt_hash *h, const ufbx_procedural_geometry *v)
|
|
{
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_stereo_camera_imp(ufbxt_hash *h, const ufbx_stereo_camera *v)
|
|
{
|
|
ufbxt_hash_element_ref(h, v->left);
|
|
ufbxt_hash_element_ref(h, v->right);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_camera_switcher_imp(ufbxt_hash *h, const ufbx_camera_switcher *v)
|
|
{
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_marker_imp(ufbxt_hash *h, const ufbx_marker *v)
|
|
{
|
|
ufbxt_hash_pod(h, v->type);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_lod_level_imp(ufbxt_hash *h, ufbx_lod_level v)
|
|
{
|
|
ufbxt_hash_real(h, v.distance);
|
|
ufbxt_hash_pod(h, v.display);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_lod_group_imp(ufbxt_hash *h, const ufbx_lod_group *v)
|
|
{
|
|
ufbxt_hash_pod(h, v->relative_distances);
|
|
ufbxt_hash_list(h, v->lod_levels, ufbxt_hash_lod_level_imp);
|
|
ufbxt_hash_pod(h, v->ignore_parent_transform);
|
|
ufbxt_hash_pod(h, v->use_distance_limit);
|
|
ufbxt_hash_real(h, v->distance_limit_min);
|
|
ufbxt_hash_real(h, v->distance_limit_max);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_skin_vertex_imp(ufbxt_hash *h, ufbx_skin_vertex v)
|
|
{
|
|
ufbxt_hash_pod(h, v.weight_begin);
|
|
ufbxt_hash_pod(h, v.num_weights);
|
|
ufbxt_hash_real(h, v.dq_weight);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_skin_weight_imp(ufbxt_hash *h, ufbx_skin_weight v)
|
|
{
|
|
ufbxt_hash_pod(h, v.cluster_index);
|
|
ufbxt_hash_real(h, v.weight);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_skin_deformer_imp(ufbxt_hash *h, const ufbx_skin_deformer *v)
|
|
{
|
|
ufbxt_hash_pod(h, v->skinning_method);
|
|
ufbxt_hash_list(h, v->clusters, ufbxt_hash_element_ref_imp);
|
|
ufbxt_hash_list(h, v->vertices, ufbxt_hash_skin_vertex_imp);
|
|
ufbxt_hash_list(h, v->weights, ufbxt_hash_skin_weight_imp);
|
|
ufbxt_hash_size_t(h, v->max_weights_per_vertex);
|
|
ufbxt_hash_size_t(h, v->num_dq_weights);
|
|
ufbxt_hash_list(h, v->dq_vertices, ufbxt_hash_pod_imp);
|
|
ufbxt_hash_list(h, v->dq_weights, ufbxt_hash_real_imp);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_skin_cluster_imp(ufbxt_hash *h, const ufbx_skin_cluster *v)
|
|
{
|
|
ufbxt_hash_element_ref(h, v->bone_node);
|
|
ufbxt_hash_matrix(h, v->geometry_to_bone);
|
|
ufbxt_hash_matrix(h, v->mesh_node_to_bone);
|
|
ufbxt_hash_matrix(h, v->bind_to_world);
|
|
ufbxt_hash_matrix(h, v->geometry_to_world);
|
|
ufbxt_hash_transform(h, v->geometry_to_world_transform);
|
|
ufbxt_hash_size_t(h, v->num_weights);
|
|
ufbxt_hash_list(h, v->vertices, ufbxt_hash_pod_imp);
|
|
ufbxt_hash_list(h, v->weights, ufbxt_hash_real_imp);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_blend_deformer_imp(ufbxt_hash *h, const ufbx_blend_deformer *v)
|
|
{
|
|
ufbxt_hash_list(h, v->channels, ufbxt_hash_element_ref_imp);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_blend_keyframe_imp(ufbxt_hash *h, const ufbx_blend_keyframe *v)
|
|
{
|
|
ufbxt_hash_element_ref(h, v->shape);
|
|
ufbxt_hash_real(h, v->target_weight);
|
|
ufbxt_hash_real(h, v->effective_weight);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_blend_channel_imp(ufbxt_hash *h, const ufbx_blend_channel *v)
|
|
{
|
|
ufbxt_hash_real(h, v->weight);
|
|
ufbxt_hash_list_ptr(h, v->keyframes, ufbxt_hash_blend_keyframe_imp);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_blend_shape_imp(ufbxt_hash *h, const ufbx_blend_shape *v)
|
|
{
|
|
ufbxt_hash_size_t(h, v->num_offsets);
|
|
ufbxt_hash_list(h, v->offset_vertices, ufbxt_hash_pod_imp);
|
|
ufbxt_hash_list(h, v->position_offsets, ufbxt_hash_vec3_imp);
|
|
ufbxt_hash_list(h, v->normal_offsets, ufbxt_hash_vec3_imp);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_cache_frame_imp(ufbxt_hash *h, const ufbx_cache_frame *v)
|
|
{
|
|
ufbxt_hash_string(h, v->channel);
|
|
ufbxt_hash_double(h, v->time);
|
|
ufbxt_hash_pod(h, v->file_format);
|
|
ufbxt_hash_pod(h, v->data_format);
|
|
ufbxt_hash_pod(h, v->data_encoding);
|
|
ufbxt_hash_pod(h, v->data_offset);
|
|
ufbxt_hash_pod(h, v->data_count);
|
|
ufbxt_hash_pod(h, v->data_element_bytes);
|
|
ufbxt_hash_pod(h, v->data_total_bytes);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_cache_channel_imp(ufbxt_hash *h, const ufbx_cache_channel *v)
|
|
{
|
|
ufbxt_hash_string(h, v->name);
|
|
ufbxt_hash_pod(h, v->interpretation);
|
|
ufbxt_hash_string(h, v->interpretation_name);
|
|
ufbxt_hash_list_ptr(h, v->frames, ufbxt_hash_cache_frame_imp);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_geometry_cache_imp(ufbxt_hash *h, const ufbx_geometry_cache *v)
|
|
{
|
|
ufbxt_hash_list_ptr(h, v->channels, ufbxt_hash_cache_channel_imp);
|
|
ufbxt_hash_list_ptr(h, v->frames, ufbxt_hash_cache_frame_imp);
|
|
ufbxt_hash_list(h, v->extra_info, ufbxt_hash_string_imp);
|
|
}
|
|
|
|
#define ufbxt_hash_geometry_cache(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_geometry_cache_imp(h, v), ufbxt_pop_tag(h))
|
|
|
|
ufbxt_noinline static void ufbxt_hash_cache_deformer_imp(ufbxt_hash *h, const ufbx_cache_deformer *v)
|
|
{
|
|
ufbxt_hash_string(h, v->channel);
|
|
ufbxt_hash_element_ref(h, v->file);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_cache_file_imp(ufbxt_hash *h, const ufbx_cache_file *v)
|
|
{
|
|
ufbxt_hash_string(h, v->absolute_filename);
|
|
ufbxt_hash_string(h, v->relative_filename);
|
|
ufbxt_hash_blob(h, v->raw_absolute_filename);
|
|
ufbxt_hash_blob(h, v->raw_relative_filename);
|
|
|
|
if (v->external_cache) ufbxt_hash_geometry_cache(h, v->external_cache);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_material_map_imp(ufbxt_hash *h, const ufbx_material_map *v)
|
|
{
|
|
ufbxt_hash_vec4(h, v->value_vec4);
|
|
ufbxt_hash_pod(h, v->value_int);
|
|
ufbxt_hash_element_ref(h, v->texture);
|
|
ufbxt_hash_pod(h, v->has_value);
|
|
ufbxt_hash_pod(h, v->texture_enabled);
|
|
ufbxt_hash_pod(h, v->value_components);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_material_feature_imp(ufbxt_hash *h, const ufbx_material_feature_info *v)
|
|
{
|
|
ufbxt_hash_pod(h, v->enabled);
|
|
ufbxt_hash_pod(h, v->is_explicit);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_material_texture_imp(ufbxt_hash *h, const ufbx_material_texture *v)
|
|
{
|
|
ufbxt_hash_string(h, v->material_prop);
|
|
ufbxt_hash_string(h, v->shader_prop);
|
|
ufbxt_hash_element_ref(h, v->texture);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_material_imp(ufbxt_hash *h, const ufbx_material *v)
|
|
{
|
|
ufbxt_push_tag(h, "fbx");
|
|
for (size_t i = 0; i < UFBX_MATERIAL_FBX_MAP_COUNT; i++) {
|
|
ufbxt_push_tag_index(h, i);
|
|
ufbxt_hash_material_map_imp(h, &v->fbx.maps[i]);
|
|
ufbxt_pop_tag(h);
|
|
}
|
|
ufbxt_pop_tag(h);
|
|
|
|
ufbxt_push_tag(h, "pbr");
|
|
for (size_t i = 0; i < UFBX_MATERIAL_PBR_MAP_COUNT; i++) {
|
|
ufbxt_push_tag_index(h, i);
|
|
ufbxt_hash_material_map_imp(h, &v->pbr.maps[i]);
|
|
ufbxt_pop_tag(h);
|
|
}
|
|
ufbxt_pop_tag(h);
|
|
|
|
ufbxt_push_tag(h, "features");
|
|
for (size_t i = 0; i < UFBX_MATERIAL_FEATURE_COUNT; i++) {
|
|
ufbxt_push_tag_index(h, i);
|
|
ufbxt_hash_material_feature_imp(h, &v->features.features[i]);
|
|
ufbxt_pop_tag(h);
|
|
}
|
|
ufbxt_pop_tag(h);
|
|
|
|
ufbxt_hash_pod(h, v->shader_type);
|
|
ufbxt_hash_element_ref(h, v->shader);
|
|
ufbxt_hash_string(h, v->shading_model_name);
|
|
|
|
ufbxt_hash_string(h, v->shader_prop_prefix);
|
|
ufbxt_hash_list_ptr(h, v->textures, ufbxt_hash_material_texture_imp);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_texture_layer_imp(ufbxt_hash *h, const ufbx_texture_layer v)
|
|
{
|
|
ufbxt_hash_element_ref(h, v.texture);
|
|
ufbxt_hash_pod(h, v.blend_mode);
|
|
ufbxt_hash_real(h, v.alpha);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_shader_texture_input_imp(ufbxt_hash *h, const ufbx_shader_texture_input *v)
|
|
{
|
|
ufbxt_hash_string(h, v->name);
|
|
ufbxt_hash_vec4(h, v->value_vec4);
|
|
ufbxt_hash_pod(h, v->value_int);
|
|
ufbxt_hash_string(h, v->value_str);
|
|
ufbxt_hash_blob(h, v->value_blob);
|
|
ufbxt_hash_element_ref(h, v->texture);
|
|
ufbxt_hash_pod(h, v->texture_enabled);
|
|
ufbxt_hash_prop_ref(h, v->prop);
|
|
ufbxt_hash_prop_ref(h, v->texture_prop);
|
|
ufbxt_hash_prop_ref(h, v->texture_enabled_prop);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_shader_texture_imp(ufbxt_hash *h, const ufbx_shader_texture *v)
|
|
{
|
|
ufbxt_hash_pod(h, v->type);
|
|
ufbxt_hash_string(h, v->shader_name);
|
|
ufbxt_hash_pod(h, v->shader_type_id);
|
|
ufbxt_hash_list_ptr(h, v->inputs, ufbxt_hash_shader_texture_input_imp);
|
|
ufbxt_hash_string(h, v->shader_source);
|
|
ufbxt_hash_blob(h, v->raw_shader_source);
|
|
ufbxt_hash_element_ref(h, v->main_texture);
|
|
ufbxt_hash_pod(h, v->main_texture_output_index);
|
|
ufbxt_hash_string(h, v->prop_prefix);
|
|
}
|
|
|
|
#define ufbxt_hash_shader_texture(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_shader_texture_imp(h, v), ufbxt_pop_tag(h))
|
|
|
|
ufbxt_noinline static void ufbxt_hash_texture_imp(ufbxt_hash *h, const ufbx_texture *v)
|
|
{
|
|
ufbxt_hash_pod(h, v->type);
|
|
|
|
ufbxt_hash_string(h, v->absolute_filename);
|
|
ufbxt_hash_string(h, v->relative_filename);
|
|
ufbxt_hash_blob(h, v->raw_absolute_filename);
|
|
ufbxt_hash_blob(h, v->raw_relative_filename);
|
|
|
|
ufbxt_hash_blob(h, v->content);
|
|
ufbxt_hash_element_ref(h, v->video);
|
|
|
|
ufbxt_hash_pod(h, v->file_index);
|
|
ufbxt_hash_pod(h, v->has_file);
|
|
|
|
ufbxt_hash_list(h, v->layers, ufbxt_hash_texture_layer_imp);
|
|
|
|
ufbxt_hash_string(h, v->uv_set);
|
|
ufbxt_hash_pod(h, v->wrap_u);
|
|
ufbxt_hash_pod(h, v->wrap_v);
|
|
ufbxt_hash_pod(h, v->has_uv_transform);
|
|
ufbxt_hash_transform(h, v->uv_transform);
|
|
ufbxt_hash_matrix(h, v->texture_to_uv);
|
|
ufbxt_hash_matrix(h, v->uv_to_texture);
|
|
|
|
ufbxt_hash_list(h, v->file_textures, ufbxt_hash_element_ref_imp);
|
|
|
|
if (v->shader) {
|
|
ufbxt_hash_shader_texture(h, v->shader);
|
|
}
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_video_imp(ufbxt_hash *h, const ufbx_video *v)
|
|
{
|
|
ufbxt_hash_string(h, v->absolute_filename);
|
|
ufbxt_hash_string(h, v->relative_filename);
|
|
ufbxt_hash_blob(h, v->raw_absolute_filename);
|
|
ufbxt_hash_blob(h, v->raw_relative_filename);
|
|
|
|
ufbxt_hash_blob(h, v->content);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_shader_imp(ufbxt_hash *h, const ufbx_shader *v)
|
|
{
|
|
ufbxt_hash_pod(h, v->type);
|
|
ufbxt_hash_list(h, v->bindings, ufbxt_hash_element_ref_imp);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_shader_prop_binding_imp(ufbxt_hash *h, ufbx_shader_prop_binding v)
|
|
{
|
|
ufbxt_hash_string(h, v.shader_prop);
|
|
ufbxt_hash_string(h, v.material_prop);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_shader_binding_imp(ufbxt_hash *h, const ufbx_shader_binding *v)
|
|
{
|
|
ufbxt_hash_list(h, v->prop_bindings, ufbxt_hash_shader_prop_binding_imp);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_anim_layer_desc_imp(ufbxt_hash *h, ufbx_anim_layer_desc v)
|
|
{
|
|
ufbxt_hash_element_ref(h, v.layer);
|
|
ufbxt_hash_real(h, v.weight);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_anim_imp(ufbxt_hash *h, const ufbx_anim *v)
|
|
{
|
|
ufbxt_hash_list(h, v->layers, ufbxt_hash_anim_layer_desc_imp);
|
|
ufbxt_hash_pod(h, v->ignore_connections);
|
|
ufbxt_hash_double(h, v->time_begin);
|
|
ufbxt_hash_double(h, v->time_end);
|
|
}
|
|
|
|
#define ufbxt_hash_anim(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_anim_imp(h, v), ufbxt_pop_tag(h))
|
|
|
|
ufbxt_noinline static void ufbxt_hash_anim_stack_imp(ufbxt_hash *h, const ufbx_anim_stack *v)
|
|
{
|
|
ufbxt_hash_double(h, v->time_begin);
|
|
ufbxt_hash_double(h, v->time_end);
|
|
|
|
ufbxt_hash_list(h, v->layers, ufbxt_hash_element_ref_imp);
|
|
ufbxt_hash_anim(h, &v->anim);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_anim_prop_imp(ufbxt_hash *h, const ufbx_anim_prop *v)
|
|
{
|
|
ufbxt_hash_element_ref(h, v->element);
|
|
ufbxt_hash_pod(h, v->_internal_key);
|
|
ufbxt_hash_string(h, v->prop_name);
|
|
ufbxt_hash_element_ref(h, v->anim_value);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_anim_layer_imp(ufbxt_hash *h, const ufbx_anim_layer *v)
|
|
{
|
|
ufbxt_hash_real(h, v->weight);
|
|
ufbxt_hash_pod(h, v->weight_is_animated);
|
|
ufbxt_hash_pod(h, v->blended);
|
|
ufbxt_hash_pod(h, v->additive);
|
|
ufbxt_hash_pod(h, v->compose_rotation);
|
|
ufbxt_hash_pod(h, v->compose_scale);
|
|
|
|
ufbxt_hash_list(h, v->anim_values, ufbxt_hash_element_ref_imp);
|
|
ufbxt_hash_list_ptr(h, v->anim_props, ufbxt_hash_anim_prop_imp);
|
|
|
|
ufbxt_hash_anim(h, &v->anim);
|
|
|
|
ufbxt_hash_pod(h, v->_min_element_id);
|
|
ufbxt_hash_pod(h, v->_max_element_id);
|
|
ufbxt_hash_pod(h, v->_element_id_bitmask[0]);
|
|
ufbxt_hash_pod(h, v->_element_id_bitmask[1]);
|
|
ufbxt_hash_pod(h, v->_element_id_bitmask[2]);
|
|
ufbxt_hash_pod(h, v->_element_id_bitmask[3]);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_anim_value_imp(ufbxt_hash *h, const ufbx_anim_value *v)
|
|
{
|
|
ufbxt_hash_vec3(h, v->default_value);
|
|
ufbxt_hash_array(h, v->curves, ufbxt_hash_element_ref_imp);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_tangent_imp(ufbxt_hash *h, ufbx_tangent v)
|
|
{
|
|
ufbxt_hash_float(h, v.dx);
|
|
ufbxt_hash_float(h, v.dy);
|
|
}
|
|
|
|
#define ufbxt_hash_tangent(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_tangent_imp(h, v), ufbxt_pop_tag(h))
|
|
|
|
ufbxt_noinline static void ufbxt_hash_keyframe_imp(ufbxt_hash *h, const ufbx_keyframe *v)
|
|
{
|
|
ufbxt_hash_double(h, v->time);
|
|
ufbxt_hash_real(h, v->value);
|
|
ufbxt_hash_pod(h, v->interpolation);
|
|
ufbxt_hash_tangent(h, v->left);
|
|
ufbxt_hash_tangent(h, v->right);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_anim_curve_imp(ufbxt_hash *h, const ufbx_anim_curve *v)
|
|
{
|
|
ufbxt_hash_list_ptr(h, v->keyframes, ufbxt_hash_keyframe_imp);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_display_layer_imp(ufbxt_hash *h, const ufbx_display_layer *v)
|
|
{
|
|
ufbxt_hash_list(h, v->nodes, ufbxt_hash_element_ref_imp);
|
|
ufbxt_hash_pod(h, v->visible);
|
|
ufbxt_hash_pod(h, v->frozen);
|
|
ufbxt_hash_vec3(h, v->ui_color);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_selection_set_imp(ufbxt_hash *h, const ufbx_selection_set *v)
|
|
{
|
|
ufbxt_hash_list(h, v->nodes, ufbxt_hash_element_ref_imp);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_selection_node_imp(ufbxt_hash *h, const ufbx_selection_node *v)
|
|
{
|
|
ufbxt_hash_element_ref(h, v->target_node);
|
|
ufbxt_hash_element_ref(h, v->target_mesh);
|
|
ufbxt_hash_pod(h, v->include_node);
|
|
|
|
ufbxt_hash_list(h, v->vertices, ufbxt_hash_pod_imp);
|
|
ufbxt_hash_list(h, v->edges, ufbxt_hash_pod_imp);
|
|
ufbxt_hash_list(h, v->faces, ufbxt_hash_pod_imp);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_character_imp(ufbxt_hash *h, const ufbx_character *v)
|
|
{
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_constraint_target_imp(ufbxt_hash *h, const ufbx_constraint_target *v)
|
|
{
|
|
ufbxt_hash_element_ref(h, v->node);
|
|
ufbxt_hash_real(h, v->weight);
|
|
ufbxt_hash_transform(h, v->transform);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_constraint_imp(ufbxt_hash *h, const ufbx_constraint *v)
|
|
{
|
|
ufbxt_hash_pod(h, v->type);
|
|
ufbxt_hash_string(h, v->type_name);
|
|
ufbxt_hash_element_ref(h, v->node);
|
|
ufbxt_hash_list_ptr(h, v->targets, ufbxt_hash_constraint_target_imp);
|
|
ufbxt_hash_real(h, v->weight);
|
|
ufbxt_hash_pod(h, v->active);
|
|
|
|
ufbxt_hash_array(h, v->constrain_translation, ufbxt_hash_pod_imp);
|
|
ufbxt_hash_array(h, v->constrain_rotation, ufbxt_hash_pod_imp);
|
|
ufbxt_hash_array(h, v->constrain_scale, ufbxt_hash_pod_imp);
|
|
|
|
ufbxt_hash_transform(h, v->transform_offset);
|
|
|
|
ufbxt_hash_vec3(h, v->aim_vector);
|
|
ufbxt_hash_pod(h, v->aim_up_type);
|
|
ufbxt_hash_element_ref(h, v->aim_up_node);
|
|
ufbxt_hash_vec3(h, v->aim_up_vector);
|
|
|
|
ufbxt_hash_element_ref(h, v->ik_effector);
|
|
ufbxt_hash_element_ref(h, v->ik_end_node);
|
|
ufbxt_hash_vec3(h, v->ik_pole_vector);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_bone_pose_imp(ufbxt_hash *h, const ufbx_bone_pose *v)
|
|
{
|
|
ufbxt_hash_element_ref(h, v->bone_node);
|
|
ufbxt_hash_matrix(h, v->bone_to_world);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_pose_imp(ufbxt_hash *h, const ufbx_pose *v)
|
|
{
|
|
ufbxt_hash_pod(h, v->bind_pose);
|
|
ufbxt_hash_list_ptr(h, v->bone_poses, ufbxt_hash_bone_pose_imp);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_metadata_object_imp(ufbxt_hash *h, const ufbx_metadata_object *v)
|
|
{
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_texture_file_imp(ufbxt_hash *h, const ufbx_texture_file *v)
|
|
{
|
|
ufbxt_hash_pod(h, v->index);
|
|
ufbxt_hash_string(h, v->absolute_filename);
|
|
ufbxt_hash_string(h, v->relative_filename);
|
|
ufbxt_hash_blob(h, v->raw_absolute_filename);
|
|
ufbxt_hash_blob(h, v->raw_relative_filename);
|
|
ufbxt_hash_blob(h, v->content);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_name_element_imp(ufbxt_hash *h, const ufbx_name_element *v)
|
|
{
|
|
ufbxt_hash_string(h, v->name);
|
|
ufbxt_hash_pod(h, v->type);
|
|
ufbxt_hash_pod(h, v->_internal_key);
|
|
ufbxt_hash_element_ref(h, v->element);
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_application_imp(ufbxt_hash *h, const ufbx_application *v)
|
|
{
|
|
ufbxt_hash_string(h, v->vendor);
|
|
ufbxt_hash_string(h, v->name);
|
|
ufbxt_hash_string(h, v->version);
|
|
}
|
|
|
|
#define ufbxt_hash_application(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_application_imp(h, v), ufbxt_pop_tag(h))
|
|
|
|
ufbxt_noinline static void ufbxt_hash_warning_imp(ufbxt_hash *h, const ufbx_warning *v)
|
|
{
|
|
ufbxt_hash_pod(h, v->type);
|
|
ufbxt_hash_size_t(h, v->count);
|
|
// `v->description` omitted as it contains path-specific string
|
|
}
|
|
|
|
ufbxt_noinline static void ufbxt_hash_metadata_imp(ufbxt_hash *h, const ufbx_metadata *v)
|
|
{
|
|
ufbxt_hash_pod(h, v->ascii);
|
|
ufbxt_hash_pod(h, v->version);
|
|
ufbxt_hash_string(h, v->creator);
|
|
ufbxt_hash_pod(h, v->is_unsafe);
|
|
ufbxt_hash_pod(h, v->big_endian);
|
|
ufbxt_hash_pod(h, v->exporter);
|
|
ufbxt_hash_pod(h, v->exporter_version);
|
|
ufbxt_hash_props(h, &v->scene_props);
|
|
ufbxt_hash_application(h, &v->original_application);
|
|
ufbxt_hash_application(h, &v->latest_application);
|
|
ufbxt_hash_list_ptr(h, v->warnings, ufbxt_hash_warning_imp);
|
|
}
|
|
|
|
#define ufbxt_hash_metadata(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_metadata_imp(h, v), ufbxt_pop_tag(h))
|
|
|
|
ufbxt_noinline static void ufbxt_hash_coordinate_axes_imp(ufbxt_hash *h, ufbx_coordinate_axes v)
|
|
{
|
|
ufbxt_hash_pod(h, v.right);
|
|
ufbxt_hash_pod(h, v.up);
|
|
ufbxt_hash_pod(h, v.front);
|
|
}
|
|
|
|
#define ufbxt_hash_coordinate_axes(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_coordinate_axes_imp(h, v), ufbxt_pop_tag(h))
|
|
|
|
ufbxt_noinline static void ufbxt_hash_scene_settings_imp(ufbxt_hash *h, const ufbx_scene_settings *v)
|
|
{
|
|
ufbxt_hash_props(h, &v->props);
|
|
ufbxt_hash_coordinate_axes(h, v->axes);
|
|
ufbxt_hash_real(h, v->unit_meters);
|
|
ufbxt_hash_double(h, v->frames_per_second);
|
|
ufbxt_hash_vec3(h, v->ambient_color);
|
|
ufbxt_hash_pod(h, v->time_mode);
|
|
ufbxt_hash_pod(h, v->time_protocol);
|
|
ufbxt_hash_pod(h, v->snap_mode);
|
|
ufbxt_hash_pod(h, v->original_axis_up);
|
|
ufbxt_hash_pod(h, v->original_unit_meters);
|
|
}
|
|
|
|
#define ufbxt_hash_scene_settings(h, v) (ufbxt_push_tag(h, #v), ufbxt_hash_scene_settings_imp(h, v), ufbxt_pop_tag(h))
|
|
|
|
ufbxt_noinline static void ufbxt_hash_scene_imp(ufbxt_hash *h, const ufbx_scene *v)
|
|
{
|
|
ufbxt_hash_metadata(h, &v->metadata);
|
|
ufbxt_hash_scene_settings(h, &v->settings);
|
|
ufbxt_hash_element_ref(h, v->root_node);
|
|
ufbxt_hash_anim(h, &v->anim);
|
|
ufbxt_hash_anim(h, &v->combined_anim);
|
|
|
|
ufbxt_hash_list(h, v->elements, ufbxt_hash_element_imp);
|
|
|
|
ufbxt_hash_list(h, v->unknowns, ufbxt_hash_unknown_imp);
|
|
ufbxt_hash_list(h, v->nodes, ufbxt_hash_node_imp);
|
|
ufbxt_hash_list(h, v->meshes, ufbxt_hash_mesh_imp);
|
|
ufbxt_hash_list(h, v->lights, ufbxt_hash_light_imp);
|
|
ufbxt_hash_list(h, v->cameras, ufbxt_hash_camera_imp);
|
|
ufbxt_hash_list(h, v->bones, ufbxt_hash_bone_imp);
|
|
ufbxt_hash_list(h, v->empties, ufbxt_hash_empty_imp);
|
|
ufbxt_hash_list(h, v->line_curves, ufbxt_hash_line_curve_imp);
|
|
ufbxt_hash_list(h, v->nurbs_curves, ufbxt_hash_nurbs_curve_imp);
|
|
ufbxt_hash_list(h, v->nurbs_surfaces, ufbxt_hash_nurbs_surface_imp);
|
|
ufbxt_hash_list(h, v->nurbs_trim_surfaces, ufbxt_hash_nurbs_trim_surface_imp);
|
|
ufbxt_hash_list(h, v->nurbs_trim_boundaries, ufbxt_hash_nurbs_trim_boundary_imp);
|
|
ufbxt_hash_list(h, v->procedural_geometries, ufbxt_hash_procedural_geometry_imp);
|
|
ufbxt_hash_list(h, v->stereo_cameras, ufbxt_hash_stereo_camera_imp);
|
|
ufbxt_hash_list(h, v->camera_switchers, ufbxt_hash_camera_switcher_imp);
|
|
ufbxt_hash_list(h, v->markers, ufbxt_hash_marker_imp);
|
|
ufbxt_hash_list(h, v->lod_groups, ufbxt_hash_lod_group_imp);
|
|
ufbxt_hash_list(h, v->skin_deformers, ufbxt_hash_skin_deformer_imp);
|
|
ufbxt_hash_list(h, v->skin_clusters, ufbxt_hash_skin_cluster_imp);
|
|
ufbxt_hash_list(h, v->blend_deformers, ufbxt_hash_blend_deformer_imp);
|
|
ufbxt_hash_list(h, v->blend_channels, ufbxt_hash_blend_channel_imp);
|
|
ufbxt_hash_list(h, v->blend_shapes, ufbxt_hash_blend_shape_imp);
|
|
ufbxt_hash_list(h, v->cache_deformers, ufbxt_hash_cache_deformer_imp);
|
|
ufbxt_hash_list(h, v->cache_files, ufbxt_hash_cache_file_imp);
|
|
ufbxt_hash_list(h, v->materials, ufbxt_hash_material_imp);
|
|
ufbxt_hash_list(h, v->textures, ufbxt_hash_texture_imp);
|
|
ufbxt_hash_list(h, v->videos, ufbxt_hash_video_imp);
|
|
ufbxt_hash_list(h, v->shaders, ufbxt_hash_shader_imp);
|
|
ufbxt_hash_list(h, v->shader_bindings, ufbxt_hash_shader_binding_imp);
|
|
ufbxt_hash_list(h, v->anim_stacks, ufbxt_hash_anim_stack_imp);
|
|
ufbxt_hash_list(h, v->anim_layers, ufbxt_hash_anim_layer_imp);
|
|
ufbxt_hash_list(h, v->anim_values, ufbxt_hash_anim_value_imp);
|
|
ufbxt_hash_list(h, v->anim_curves, ufbxt_hash_anim_curve_imp);
|
|
ufbxt_hash_list(h, v->display_layers, ufbxt_hash_display_layer_imp);
|
|
ufbxt_hash_list(h, v->selection_sets, ufbxt_hash_selection_set_imp);
|
|
ufbxt_hash_list(h, v->selection_nodes, ufbxt_hash_selection_node_imp);
|
|
ufbxt_hash_list(h, v->characters, ufbxt_hash_character_imp);
|
|
ufbxt_hash_list(h, v->constraints, ufbxt_hash_constraint_imp);
|
|
ufbxt_hash_list(h, v->poses, ufbxt_hash_pose_imp);
|
|
ufbxt_hash_list(h, v->metadata_objects, ufbxt_hash_metadata_object_imp);
|
|
|
|
ufbxt_hash_list_ptr(h, v->texture_files, ufbxt_hash_texture_file_imp);
|
|
|
|
ufbxt_hash_list(h, v->connections_src, ufbxt_hash_connection_imp);
|
|
ufbxt_hash_list(h, v->connections_dst, ufbxt_hash_connection_imp);
|
|
ufbxt_hash_list_ptr(h, v->elements_by_name, ufbxt_hash_name_element_imp);
|
|
|
|
if (v->dom_root) ufbxt_hash_dom_node(h, v->dom_root);
|
|
}
|
|
|
|
ufbxt_noinline static uint64_t ufbxt_hash_scene(const ufbx_scene *v, FILE *dump_file)
|
|
{
|
|
ufbxt_hash h;
|
|
ufbxt_hash_init(&h, dump_file);
|
|
ufbxt_hash_scene_imp(&h, v);
|
|
return ufbxt_hash_finish(&h);
|
|
}
|
|
|
|
#endif
|