model skinning

This commit is contained in:
John Alanbrook 2024-08-09 14:39:31 -05:00
parent 57c2285019
commit f5a89915eb
4 changed files with 46 additions and 28 deletions

View file

@ -58,7 +58,7 @@ var attr_map = {
a_pos: 0, a_pos: 0,
a_uv: 1, a_uv: 1,
a_norm: 2, a_norm: 2,
a_bone: 3, a_joint: 3,
a_weight: 4, a_weight: 4,
a_color: 5, a_color: 5,
a_tan: 6, a_tan: 6,
@ -361,6 +361,12 @@ function shader_apply_material(shader, material = {}, old = {})
if (material[p] === old[p]) continue; if (material[p] === old[p]) continue;
assert(p in material, `shader ${shader.name} has no uniform for ${p}`); assert(p in material, `shader ${shader.name} has no uniform for ${p}`);
var s = shader.vs.unimap[p]; var s = shader.vs.unimap[p];
if (p === 'bones') {
render.setunibones(0, s.slot, material[p]);
continue;
}
shader_unisize[s.size](0, s.slot, material[p]); shader_unisize[s.size](0, s.slot, material[p]);
} }

View file

@ -675,8 +675,10 @@ sg_bindings js2bind(JSValue v)
{ {
sg_bindings bind = {0}; sg_bindings bind = {0};
JSValue attrib = js_getpropstr(v, "attrib"); JSValue attrib = js_getpropstr(v, "attrib");
for (int i = 0; i < js_arrlen(attrib); i++)
for (int i = 0; i < js_arrlen(attrib); i++) {
bind.vertex_buffers[i] = *js2sg_buffer(js_getpropidx(attrib,i)); bind.vertex_buffers[i] = *js2sg_buffer(js_getpropidx(attrib,i));
}
JSValue index = js_getpropstr(v, "index"); JSValue index = js_getpropstr(v, "index");
if (!JS_IsUndefined(index)) if (!JS_IsUndefined(index))
@ -870,19 +872,6 @@ sg_shader js2shader(JSValue v)
return sh; return sh;
} }
#define MAT_POS 0
#define MAT_UV 1
#define MAT_NORM 2
#define MAT_BONE 3
#define MAT_WEIGHT 4
#define MAT_COLOR 5
#define MAT_TAN 6
#define MAT_ANGLE 7
#define MAT_WH 8
#define MAT_ST 9
#define MAT_PPOS 10
#define MAT_SCALE 11
static int mat2type(int mat) static int mat2type(int mat)
{ {
switch(mat) { switch(mat) {
@ -894,8 +883,8 @@ static int mat2type(int mat)
case MAT_ST: case MAT_ST:
return SG_VERTEXFORMAT_FLOAT2; return SG_VERTEXFORMAT_FLOAT2;
case MAT_UV: case MAT_UV:
case MAT_TAN:
return SG_VERTEXFORMAT_USHORT2N; return SG_VERTEXFORMAT_USHORT2N;
case MAT_TAN:
return SG_VERTEXFORMAT_UINT10_N2; return SG_VERTEXFORMAT_UINT10_N2;
case MAT_BONE: case MAT_BONE:
return SG_VERTEXFORMAT_UBYTE4; return SG_VERTEXFORMAT_UBYTE4;
@ -906,7 +895,8 @@ static int mat2type(int mat)
case MAT_SCALE: case MAT_SCALE:
return SG_VERTEXFORMAT_FLOAT; return SG_VERTEXFORMAT_FLOAT;
}; };
return 0;
return -1;
} }
sg_vertex_layout_state js2layout(JSValue v) sg_vertex_layout_state js2layout(JSValue v)
@ -989,6 +979,11 @@ JSC_CCALL(render_setunivp,
sg_apply_uniforms(js2number(argv[0]), js2number(argv[1]), SG_RANGE_REF(globalview.vp)); sg_apply_uniforms(js2number(argv[0]), js2number(argv[1]), SG_RANGE_REF(globalview.vp));
) )
JSC_CCALL(render_setunibones,
skin *sk = js2skin(argv[2]);
sg_apply_uniforms(js2number(argv[0]), js2number(argv[1]), SG_RANGE_REF(sk->binds));
)
JSC_CCALL(render_setunim4, JSC_CCALL(render_setunim4,
HMM_Mat4 m = MAT1; HMM_Mat4 m = MAT1;
if (JS_IsArray(js, argv[2])) { if (JS_IsArray(js, argv[2])) {
@ -1146,6 +1141,7 @@ static const JSCFunctionListEntry js_render_funcs[] = {
MIST_FUNC_DEF(render, setuniv3, 2), MIST_FUNC_DEF(render, setuniv3, 2),
MIST_FUNC_DEF(render, setuniv, 2), MIST_FUNC_DEF(render, setuniv, 2),
MIST_FUNC_DEF(render, spdraw, 2), MIST_FUNC_DEF(render, spdraw, 2),
MIST_FUNC_DEF(render, setunibones, 3),
MIST_FUNC_DEF(render, setbind, 1), MIST_FUNC_DEF(render, setbind, 1),
MIST_FUNC_DEF(render, setuniproj, 2), MIST_FUNC_DEF(render, setuniproj, 2),
MIST_FUNC_DEF(render, setuniview, 2), MIST_FUNC_DEF(render, setuniview, 2),
@ -2957,11 +2953,15 @@ JSC_SCALL(os_gltf_skin,
cgltf_parse_file(&options,str,&data); cgltf_parse_file(&options,str,&data);
cgltf_load_buffers(&options,data,str); cgltf_load_buffers(&options,data,str);
printf("file %s has %d skins\n", str, data->skins_count);
if (data->skins_count <= 0) { if (data->skins_count <= 0) {
ret = (JS_UNDEFINED); ret = (JS_UNDEFINED);
goto CLEANUP; goto CLEANUP;
} }
ret = skin2js(make_gltf_skin(data->skins+0));
CLEANUP: CLEANUP:
cgltf_free(data); cgltf_free(data);
) )

View file

@ -88,6 +88,7 @@ uint32_t pack_int10_n2(float *norm)
return ret; return ret;
} }
// Pack an array of normals into
sg_buffer normal_floats(float *f, int n) sg_buffer normal_floats(float *f, int n)
{ {
return float_buffer(f, n); return float_buffer(f, n);
@ -126,27 +127,24 @@ sg_buffer accessor2buffer(cgltf_accessor *a, int type)
cgltf_accessor_unpack_floats(a, vs, n); cgltf_accessor_unpack_floats(a, vs, n);
switch(type) { switch(type) {
case cgltf_attribute_type_position: case MAT_POS:
return sg_make_buffer(&(sg_buffer_desc){ return sg_make_buffer(&(sg_buffer_desc){
.data.ptr = vs, .data.ptr = vs,
.data.size = sizeof(float)*n .data.size = sizeof(float)*n
}); });
case cgltf_attribute_type_normal: case MAT_NORM:
return normal_floats(vs,n); return normal_floats(vs,n);
case cgltf_attribute_type_tangent: case MAT_TAN:
return normal_floats(vs,n); // TODO: MAKE A TANGENT READER return normal_floats(vs,n); // TODO: MAKE A TANGENT READER
break; case MAT_COLOR:
case cgltf_attribute_type_color:
return ubyten_buffer(vs,n); return ubyten_buffer(vs,n);
case cgltf_attribute_type_weights: case MAT_WEIGHT:
return ubyten_buffer(vs,n); return ubyten_buffer(vs,n);
case cgltf_attribute_type_joints: case MAT_BONE:
return ubyte_buffer(vs,n); return ubyte_buffer(vs,n);
case cgltf_attribute_type_texcoord: case MAT_UV:
return texcoord_floats(vs,n); return texcoord_floats(vs,n);
case cgltf_attribute_type_invalid: case MAT_INDEX:
break;
case 100:
return index_buffer(vs,n); return index_buffer(vs,n);
} }

View file

@ -9,6 +9,20 @@
#include "texture.h" #include "texture.h"
#include "cgltf.h" #include "cgltf.h"
#define MAT_POS 0
#define MAT_UV 1
#define MAT_NORM 2
#define MAT_BONE 3
#define MAT_WEIGHT 4
#define MAT_COLOR 5
#define MAT_TAN 6
#define MAT_ANGLE 7
#define MAT_WH 8
#define MAT_ST 9
#define MAT_PPOS 10
#define MAT_SCALE 11
#define MAT_INDEX 100
typedef struct md5joint { typedef struct md5joint {
struct md5joint *parent; struct md5joint *parent;
HMM_Vec4 pos; HMM_Vec4 pos;