2021-11-30 21:29:18 -06:00
|
|
|
#include "model.h"
|
|
|
|
|
2023-04-24 17:22:18 -05:00
|
|
|
#include "log.h"
|
2021-11-30 21:29:18 -06:00
|
|
|
#include "resources.h"
|
2023-04-24 17:22:18 -05:00
|
|
|
#include "stb_ds.h"
|
2023-11-03 08:31:06 -05:00
|
|
|
#include "gameobject.h"
|
2023-05-12 13:22:05 -05:00
|
|
|
|
2023-09-04 09:48:44 -05:00
|
|
|
#include "render.h"
|
2023-05-12 13:22:05 -05:00
|
|
|
|
|
|
|
#include "HandmadeMath.h"
|
|
|
|
|
|
|
|
#include "math.h"
|
|
|
|
#include "time.h"
|
|
|
|
|
2021-11-30 21:29:18 -06:00
|
|
|
#include <cgltf.h>
|
2023-12-20 17:20:29 -06:00
|
|
|
|
2024-04-26 16:04:31 -05:00
|
|
|
#include <limits.h>
|
2022-02-06 10:14:57 -06:00
|
|
|
#include <stdlib.h>
|
2023-04-24 17:22:18 -05:00
|
|
|
#include <string.h>
|
2024-04-26 16:04:31 -05:00
|
|
|
#include "yugine.h"
|
2021-11-30 21:29:18 -06:00
|
|
|
|
2024-05-06 21:59:22 -05:00
|
|
|
#include "jsffi.h"
|
|
|
|
|
2023-05-12 13:22:05 -05:00
|
|
|
#include "texture.h"
|
|
|
|
|
|
|
|
#include "sokol/sokol_gfx.h"
|
|
|
|
|
2024-08-08 17:32:58 -05:00
|
|
|
#include "jsffi.h"
|
2023-05-12 13:22:05 -05:00
|
|
|
|
2023-12-20 17:20:29 -06:00
|
|
|
unsigned short pack_short_tex(float c) { return c * USHRT_MAX; }
|
|
|
|
|
2024-05-06 21:59:22 -05:00
|
|
|
sg_buffer texcoord_floats(float *f, int n)
|
2023-12-19 15:34:36 -06:00
|
|
|
{
|
2023-12-20 17:20:29 -06:00
|
|
|
unsigned short packed[n];
|
2024-05-06 21:59:22 -05:00
|
|
|
for (int i = 0; i < n; i++) {
|
|
|
|
float v = f[i];
|
|
|
|
if (v < 0) v = 0;
|
|
|
|
if (v > 1) v = 1;
|
|
|
|
packed[i] = pack_short_tex(v);
|
|
|
|
}
|
2023-12-19 15:34:36 -06:00
|
|
|
|
|
|
|
return sg_make_buffer(&(sg_buffer_desc){
|
2024-04-23 18:12:45 -05:00
|
|
|
.data = SG_RANGE(packed),
|
2024-04-09 16:48:15 -05:00
|
|
|
.label = "tex coord vert buffer",
|
|
|
|
});
|
2023-12-19 15:34:36 -06:00
|
|
|
}
|
|
|
|
|
2024-05-06 21:59:22 -05:00
|
|
|
sg_buffer par_idx_buffer(uint32_t *p, int v)
|
2023-12-19 15:34:36 -06:00
|
|
|
{
|
2024-05-06 21:59:22 -05:00
|
|
|
uint16_t idx[v];
|
|
|
|
for (int i = 0; i < v; i++) idx[i] = p[i];
|
|
|
|
|
|
|
|
return sg_make_buffer(&(sg_buffer_desc){
|
|
|
|
.data = SG_RANGE(idx),
|
|
|
|
.type = SG_BUFFERTYPE_INDEXBUFFER
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
sg_buffer float_buffer(float *f, int v)
|
|
|
|
{
|
|
|
|
return sg_make_buffer(&(sg_buffer_desc){
|
|
|
|
.data = (sg_range){
|
|
|
|
.ptr = f,
|
|
|
|
.size = sizeof(*f)*v
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
sg_buffer index_buffer(float *f, int verts)
|
|
|
|
{
|
|
|
|
uint16_t idxs[verts];
|
|
|
|
for (int i = 0; i < verts; i++)
|
|
|
|
idxs[i] = f[i];
|
|
|
|
|
|
|
|
return sg_make_buffer(&(sg_buffer_desc){
|
|
|
|
.data = SG_RANGE(idxs),
|
|
|
|
.type = SG_BUFFERTYPE_INDEXBUFFER,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2024-05-13 14:07:00 -05:00
|
|
|
uint32_t pack_int10_n2(float *norm)
|
|
|
|
{
|
|
|
|
uint32_t ret = 0;
|
|
|
|
for (int i = 0; i < 3; i++) {
|
|
|
|
int n = (norm[i]+1.0)*511;
|
|
|
|
ret |= (n & 0x3ff) << (10*i);
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2024-08-09 14:39:31 -05:00
|
|
|
// Pack an array of normals into
|
2024-05-06 21:59:22 -05:00
|
|
|
sg_buffer normal_floats(float *f, int n)
|
|
|
|
{
|
2024-05-14 15:22:24 -05:00
|
|
|
return float_buffer(f, n);
|
2024-05-06 21:59:22 -05:00
|
|
|
uint32_t packed_norms[n/3];
|
|
|
|
for (int v = 0, i = 0; v < n/3; v++, i+= 3)
|
2023-12-19 17:28:45 -06:00
|
|
|
packed_norms[v] = pack_int10_n2(f+i);
|
2023-12-19 15:34:36 -06:00
|
|
|
|
|
|
|
return sg_make_buffer(&(sg_buffer_desc){
|
2024-04-23 18:12:45 -05:00
|
|
|
.data = SG_RANGE(packed_norms),
|
2024-04-09 16:48:15 -05:00
|
|
|
.label = "normal vert buffer",
|
|
|
|
});
|
2023-12-19 15:34:36 -06:00
|
|
|
}
|
|
|
|
|
2024-05-06 21:59:22 -05:00
|
|
|
sg_buffer ubyten_buffer(float *f, int v)
|
2024-05-02 13:52:28 -05:00
|
|
|
{
|
2024-05-06 21:59:22 -05:00
|
|
|
unsigned char b[v];
|
|
|
|
for (int i = 0; i < (v); i++)
|
2024-05-02 13:52:28 -05:00
|
|
|
b[i] = f[i]*255;
|
|
|
|
|
|
|
|
return sg_make_buffer(&(sg_buffer_desc){.data=SG_RANGE(b)});
|
|
|
|
}
|
|
|
|
|
2024-05-06 21:59:22 -05:00
|
|
|
sg_buffer ubyte_buffer(float *f, int v)
|
2024-05-02 13:52:28 -05:00
|
|
|
{
|
2024-05-06 21:59:22 -05:00
|
|
|
unsigned char b[v];
|
|
|
|
for (int i = 0; i < (v); i++)
|
2024-05-02 13:52:28 -05:00
|
|
|
b[i] = f[i];
|
|
|
|
|
|
|
|
return sg_make_buffer(&(sg_buffer_desc){.data=SG_RANGE(b)});
|
|
|
|
}
|
|
|
|
|
2024-08-08 17:32:58 -05:00
|
|
|
sg_buffer accessor2buffer(cgltf_accessor *a, int type)
|
2024-05-06 21:59:22 -05:00
|
|
|
{
|
2024-08-08 17:32:58 -05:00
|
|
|
int n = cgltf_accessor_unpack_floats(a, NULL, 0);
|
|
|
|
float vs[n];
|
|
|
|
cgltf_accessor_unpack_floats(a, vs, n);
|
2024-04-26 16:04:31 -05:00
|
|
|
|
2024-08-08 17:32:58 -05:00
|
|
|
switch(type) {
|
2024-08-09 14:39:31 -05:00
|
|
|
case MAT_POS:
|
2024-08-08 17:32:58 -05:00
|
|
|
return sg_make_buffer(&(sg_buffer_desc){
|
2024-04-09 16:48:15 -05:00
|
|
|
.data.ptr = vs,
|
2024-08-08 17:32:58 -05:00
|
|
|
.data.size = sizeof(float)*n
|
|
|
|
});
|
2024-08-09 14:39:31 -05:00
|
|
|
case MAT_NORM:
|
2024-08-08 17:32:58 -05:00
|
|
|
return normal_floats(vs,n);
|
2024-08-09 14:39:31 -05:00
|
|
|
case MAT_TAN:
|
2024-08-08 17:32:58 -05:00
|
|
|
return normal_floats(vs,n); // TODO: MAKE A TANGENT READER
|
2024-08-09 14:39:31 -05:00
|
|
|
case MAT_COLOR:
|
2024-08-08 17:32:58 -05:00
|
|
|
return ubyten_buffer(vs,n);
|
2024-08-09 14:39:31 -05:00
|
|
|
case MAT_WEIGHT:
|
2024-08-08 17:32:58 -05:00
|
|
|
return ubyten_buffer(vs,n);
|
2024-08-09 14:39:31 -05:00
|
|
|
case MAT_BONE:
|
2024-08-08 17:32:58 -05:00
|
|
|
return ubyte_buffer(vs,n);
|
2024-08-09 14:39:31 -05:00
|
|
|
case MAT_UV:
|
2024-08-08 17:32:58 -05:00
|
|
|
return texcoord_floats(vs,n);
|
2024-08-09 14:39:31 -05:00
|
|
|
case MAT_INDEX:
|
2024-08-08 17:32:58 -05:00
|
|
|
return index_buffer(vs,n);
|
2024-05-02 13:52:28 -05:00
|
|
|
}
|
2024-04-28 13:33:37 -05:00
|
|
|
|
2024-08-08 17:32:58 -05:00
|
|
|
return sg_make_buffer(&(sg_buffer_desc) {
|
|
|
|
.data.size = 4,
|
|
|
|
.usage = SG_USAGE_STREAM
|
|
|
|
});
|
2024-04-26 16:04:31 -05:00
|
|
|
}
|
2023-12-04 13:38:37 -06:00
|
|
|
|
2024-04-26 16:04:31 -05:00
|
|
|
void packFloats(float *src, float *dest, int srcLength) {
|
2024-08-08 17:32:58 -05:00
|
|
|
int i, j;
|
|
|
|
for (i = 0, j = 0; i < srcLength; i += 3, j += 4) {
|
|
|
|
dest[j] = src[i];
|
|
|
|
dest[j + 1] = src[i + 1];
|
|
|
|
dest[j + 2] = src[i + 2];
|
|
|
|
dest[j + 3] = 0.0f;
|
|
|
|
}
|
2023-12-04 13:38:37 -06:00
|
|
|
}
|
|
|
|
|
2024-08-10 04:06:44 -05:00
|
|
|
static md5joint *node2joint(skin *sk, cgltf_node *n, cgltf_skin *skin)
|
|
|
|
{
|
|
|
|
int k = 0;
|
|
|
|
while (skin->joints[k] != n && k < skin->joints_count) k++;
|
|
|
|
return sk->joints+k;
|
|
|
|
}
|
|
|
|
|
|
|
|
animation *gltf_anim(cgltf_animation *anim, skin *sk, cgltf_skin *skin)
|
2023-12-04 13:38:37 -06:00
|
|
|
{
|
2024-08-08 17:32:58 -05:00
|
|
|
animation *ret = calloc(sizeof(*ret), 1);
|
|
|
|
animation an = *ret;
|
2024-04-26 16:04:31 -05:00
|
|
|
arrsetlen(an.samplers, anim->samplers_count);
|
|
|
|
|
|
|
|
for (int i = 0; i < anim->samplers_count; i++) {
|
|
|
|
cgltf_animation_sampler s = anim->samplers[i];
|
|
|
|
sampler samp = (sampler){0};
|
|
|
|
int n = cgltf_accessor_unpack_floats(s.input, NULL, 0);
|
|
|
|
arrsetlen(samp.times, n);
|
|
|
|
cgltf_accessor_unpack_floats(s.input, samp.times, n);
|
|
|
|
|
|
|
|
n = cgltf_accessor_unpack_floats(s.output, NULL, 0);
|
|
|
|
int comp = cgltf_num_components(s.output->type);
|
|
|
|
arrsetlen(samp.data, n/comp);
|
|
|
|
if (comp == 4)
|
|
|
|
cgltf_accessor_unpack_floats(s.output, samp.data, n);
|
|
|
|
else {
|
|
|
|
float *out = malloc(sizeof(*out)*n);
|
|
|
|
cgltf_accessor_unpack_floats(s.output, out, n);
|
|
|
|
packFloats(out, samp.data, n);
|
|
|
|
free(out);
|
|
|
|
}
|
|
|
|
|
|
|
|
samp.type = s.interpolation;
|
|
|
|
|
|
|
|
if (samp.type == LINEAR && comp == 4)
|
|
|
|
samp.type = SLERP;
|
|
|
|
|
|
|
|
an.samplers[i] = samp;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < anim->channels_count; i++) {
|
|
|
|
cgltf_animation_channel ch = anim->channels[i];
|
|
|
|
struct anim_channel ach = (struct anim_channel){0};
|
2024-08-10 04:06:44 -05:00
|
|
|
md5joint *md = node2joint(sk, ch.target_node, skin);
|
2024-04-26 16:04:31 -05:00
|
|
|
switch(ch.target_path) {
|
|
|
|
case cgltf_animation_path_type_translation:
|
|
|
|
ach.target = &md->pos;
|
|
|
|
break;
|
|
|
|
case cgltf_animation_path_type_rotation:
|
|
|
|
ach.target = &md->rot;
|
|
|
|
break;
|
|
|
|
case cgltf_animation_path_type_scale:
|
|
|
|
ach.target = &md->scale;
|
|
|
|
break;
|
2024-05-20 13:50:57 -05:00
|
|
|
default: break;
|
2024-04-26 16:04:31 -05:00
|
|
|
}
|
|
|
|
ach.sampler = an.samplers+(ch.sampler-anim->samplers);
|
|
|
|
|
|
|
|
arrput(an.channels, ach);
|
|
|
|
}
|
2024-08-08 17:32:58 -05:00
|
|
|
|
2024-08-10 04:06:44 -05:00
|
|
|
an.time = 0;
|
|
|
|
|
2024-08-08 17:32:58 -05:00
|
|
|
*ret = an;
|
2024-08-10 04:06:44 -05:00
|
|
|
return ret;
|
2023-12-04 13:38:37 -06:00
|
|
|
}
|
|
|
|
|
2024-08-10 04:06:44 -05:00
|
|
|
skin *make_gltf_skin(cgltf_skin *skin, cgltf_data *data)
|
2023-12-04 13:38:37 -06:00
|
|
|
{
|
2024-04-26 16:04:31 -05:00
|
|
|
int n = cgltf_accessor_unpack_floats(skin->inverse_bind_matrices, NULL, 0);
|
2024-08-08 17:32:58 -05:00
|
|
|
struct skin *sk = NULL;
|
|
|
|
sk = calloc(sizeof(*sk),1);
|
|
|
|
arrsetlen(sk->invbind, n/16);
|
|
|
|
cgltf_accessor_unpack_floats(skin->inverse_bind_matrices, sk->invbind, n);
|
2024-04-26 16:04:31 -05:00
|
|
|
|
2024-08-08 17:32:58 -05:00
|
|
|
arrsetlen(sk->joints, skin->joints_count);
|
2024-04-26 16:04:31 -05:00
|
|
|
|
|
|
|
for (int i = 0; i < 50; i++)
|
2024-08-08 17:32:58 -05:00
|
|
|
sk->binds[i] = MAT1;
|
2024-04-26 16:04:31 -05:00
|
|
|
|
|
|
|
for (int i = 0; i < skin->joints_count; i++) {
|
|
|
|
cgltf_node *n = skin->joints[i];
|
2024-08-10 04:06:44 -05:00
|
|
|
md5joint *j = sk->joints+i;
|
|
|
|
|
|
|
|
if (n == skin->skeleton)
|
|
|
|
j->parent = NULL;
|
|
|
|
else
|
|
|
|
j->parent = node2joint(sk, n->parent, skin);
|
|
|
|
|
2024-04-26 16:04:31 -05:00
|
|
|
for (int i = 0; i < 3; i++) {
|
|
|
|
j->pos.e[i] = n->translation[i];
|
|
|
|
j->scale.e[i] = n->scale[i];
|
|
|
|
}
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
|
j->rot.e[i] = n->rotation[i];
|
|
|
|
}
|
2023-04-24 17:22:18 -05:00
|
|
|
|
2024-08-10 04:06:44 -05:00
|
|
|
sk->anim = gltf_anim(data->animations+0, sk, skin);
|
|
|
|
|
2024-08-08 17:32:58 -05:00
|
|
|
return sk;
|
2024-04-30 10:32:27 -05:00
|
|
|
}
|
|
|
|
|
2024-08-08 17:32:58 -05:00
|
|
|
void skin_calculate(skin *sk)
|
2024-04-20 12:55:20 -05:00
|
|
|
{
|
2024-08-10 04:06:44 -05:00
|
|
|
animation_run(sk->anim, apptime());
|
2024-05-02 13:52:28 -05:00
|
|
|
for (int i = 0; i < arrlen(sk->joints); i++) {
|
2024-08-08 17:32:58 -05:00
|
|
|
md5joint *md = sk->joints+i;
|
2024-08-10 04:06:44 -05:00
|
|
|
md->t = HMM_M4TRS(md->pos.xyz, md->rot, md->scale.xyz);
|
2024-05-02 13:52:28 -05:00
|
|
|
if (md->parent)
|
2024-08-10 04:06:44 -05:00
|
|
|
md->t = HMM_MulM4(md->parent->t, md->t);
|
|
|
|
|
2024-05-02 13:52:28 -05:00
|
|
|
sk->binds[i] = HMM_MulM4(md->t, sk->invbind[i]);
|
2024-04-26 16:04:31 -05:00
|
|
|
}
|
2024-02-25 17:31:48 -06:00
|
|
|
}
|