I wrote program that renders sekelton.glb. But what's the point now? It does not draw as expected. Spine and jaw are gone. Hierarchy makes no sense. Plus my game erendering class sucks. And as if it couldn't already be worse, HSE just dropped like 7 homeworks and tomorrow I can't afford to be late for stupid fucking classes. How is it that I hate gltf rendering 10 much more than homework. Fuck this fucking shit. Fuck prob-theory. Fuck caos. Fuck every single zoom lesson. Fuck ML. Fuck khronos group. Fuck blender. Fuck , fuck, fuck. I fucking hate glb format. Fuck this shit. And I am sick of C already

This commit is contained in:
Андреев Григорий 2026-02-09 01:25:43 +03:00
parent 795f675e6a
commit 1e6097ac2a
4 changed files with 246 additions and 39 deletions

View File

@ -97,6 +97,13 @@ mat4 marie_3d_scal_mat4(float scale){
0, 0, 0, 1);
}
mat4 marie_3d_scale_mat4(vec3 scale){
return mat4_new(scale.x, 0, 0, 0,
0, scale.y, 0, 0,
0, 0, scale.z, 0,
0, 0, 0, 1);
}
vec2 ivec2_to_vec2(ivec2 v){
return (vec2){(float)v.x, (float)v.y};
}

View File

@ -841,10 +841,10 @@ ResultGltfFileStructureOrVecU8 glb_file_get_structure(GLBFileSegments* segments)
for (U64 bv = 0; bv < buffer_views.len; bv++) {
const GltfBufferView* buffer_view = &buffer_views.buf[bv];
if (buffer_view->usage_in_accessors >= 2 && buffer_view->stride == 0) {
ret_error = VecU8_fmt("BufferView %u is used by several accessors, but stride isn't specified", bv);
goto destroy_everything_return_error;
}
// if (buffer_view->usage_in_accessors >= 2 && buffer_view->stride == 0) {
// ret_error = VecU8_fmt("BufferView %u is used by several accessors, but stride isn't specified", bv);
// goto destroy_everything_return_error;
// }
U64 buf_id = buffer_view->buffer;
if (buf_id >= buffers.len) {
ret_error = VecU8_fmt("BufferView %u has buffer %u, that is out-of-bounds of buffers array", bv, buf_id);
@ -927,10 +927,10 @@ ResultGltfFileStructureOrVecU8 glb_file_get_structure(GLBFileSegments* segments)
ret_error = VecU8_fmt("Material's %u normal map texture is out-of-bounds of textures array", i);
goto destroy_everything_return_error;
}
if (material->normal_map_tex.some.tex_coord_set_index > 0) {
ret_error = VecU8_fmt("Mmmmm NOPE");
goto destroy_everything_return_error;
}
// if (material->normal_map_tex.some.tex_coord_set_index > 0) {
// ret_error = VecU8_fmt("Mmmmm NOPE");
// goto destroy_everything_return_error;
// }
}
}
@ -1001,7 +1001,11 @@ ResultGltfFileStructureOrVecU8 glb_file_get_structure(GLBFileSegments* segments)
/* ret_error stores nothing, nothing to free */
return (ResultGltfFileStructureOrVecU8){.variant = Result_Ok, .ok = (GltfFileStructure){
.nodes = nodes, .scenes = scenes, .default_scene = default_scene, .external_files = external_files}};
.external_files = external_files,
.nodes = nodes, .scenes = scenes, .default_scene = default_scene,
.buffers = buffers, .buffer_views = buffer_views, .accessors = accessors,
.meshes = meshes, .materials = materials, .textures = textures
}};
destroy_everything_return_error:
VecVecU8_drop(external_files);
VecGltfNode_drop(nodes);

Binary file not shown.

View File

@ -18,7 +18,9 @@ float quad_form3_mul_vec(quad_form3_t Q, vec3 M) {
typedef struct{
vec3 pos;
vec3 color;
float magnitude;
vec3 color_2;
float phase;
float progress;
} LightSourceState;
#include "../../../gen/l1/eve/r4/VecLightSourceState.h"
@ -79,7 +81,7 @@ vec3 project_dir_onto_plane_xz(vec3 v){
return (vec3){xz.x, 0, xz.y};
}
typedef struct{
typedef struct {
Alice* alice;
LucyFace* font_face;
RBTreeNodeLucyFaceFixedSize* font_face_of_size_40;
@ -96,6 +98,8 @@ typedef struct{
U64 misses_count;
U64 hits_count;
Vecvec3 bullets_stuck_on_ROA;
VecRefListNodeAliceGenericMeshHand skeleton_meshes;
} R4BetaState;
/* We are surrounded by a giant cubic mesh of light sources */
@ -116,6 +120,21 @@ void physics_update(R4BetaState* st, float t){
roa_st->rot = mat3_mul_mat3(rot_gain, roa_st->rot);
}
void flickering_lights_update(R4BetaState* st, float t) {
VecLightSourceState* ls = &st->LS_state;
for (size_t i = 0; i < ls->len; i++) {
LightSourceState* light = &ls->buf[i];
light->phase += t;
check(fabsf(light->progress) < 10);
light->progress += t / 2;
while (light->progress > 1) {
light->progress -= 1;
light->color = light->color_2;
light->color_2 = sample_rainbow_color();
}
}
}
/* Changs linear and rotational speed of RigidBody based on the impact with bullet.
* It does not update mass, moment of intertia, center of mass of rigid body. It is as if the bullet was
* very light compared to rigid body.
@ -249,6 +268,7 @@ void main_h_on_another_frame(void* data, float fl){
alice->cam_info.cam.pos = st->hero_pos;
physics_update(st, fl);
flickering_lights_update(st, fl);
AliceGenericMeshHand_set_inst(&st->ROA_mesh->el, 0, (GenericMeshInstanceInc){
.model_t = RigidBodyState_get_tran_mat_of_mesh(&st->ROA_state),
@ -259,12 +279,16 @@ void main_h_on_another_frame(void* data, float fl){
for (size_t i = 0; i < st->LS_state.len; i++) {
LightSourceState* ls = &st->LS_state.buf[i];
float magnitude = 1.3f + 1 * sinf(ls->phase);
vec3 color = vec3_mul_scal(vec3_add_vec3(
vec3_mul_scal(ls->color, 1 - ls->progress), vec3_mul_scal(ls->color_2, ls->progress)),
magnitude);
AliceShinyMeshHand_set_inst(&st->LS_mesh->el, i, (ShinyMeshInstanceInc){
.color_on = ls->color,
.color_on = color,
.model_t = marie_translation_mat4(ls->pos),
});
ubo->point_light_arr[i] = (Pipeline0PointLight){
.pos = ls->pos, .color = vec3_mul_scal(ls->color, 21)};
.pos = ls->pos, .color = vec3_mul_scal(color, 21)};
}
if (st->LS_state.len + st->bullets_stuck_on_ROA.len > st->LS_mesh->el.instance_attr.count) {
AliceShinyMeshHand_resize_instance_arr(alice, &st->LS_mesh->el, st->LS_state.len + st->bullets_stuck_on_ROA.len);
@ -299,6 +323,169 @@ void main_h_on_another_frame(void* data, float fl){
VecU8_drop(text);
}
void gltf_file_structure_get_accessor_iter_range(const GLBFileSegments* segments, const GltfFileStructure* gltf,
const GltfAccessor* accsr, SpanU8* ret_span, U64* ret_stride) {
U64 bv_id = accsr->buffer_view;
const GltfBufferView* buffer_view = &gltf->buffer_views.buf[bv_id];
const GltfBuffer* buffer = &gltf->buffers.buf[buffer_view->buffer];
check(!buffer->is_external); // Not supported yet
SpanU8 s2 = SpanU8_span(segments->bin_segment, buffer_view->offset, buffer_view->length);
*ret_span = SpanU8_span(s2, accsr->offset, s2.len - accsr->offset);
U64 stride = buffer_view->stride;
if (stride == 0)
stride = GltfAccessor_get_type_size(accsr);
*ret_stride = stride;
}
mat4 trs_mat4(vec3 translation, quaternion_t rotation, vec3 scale) {
return mat4_mul_mat4(mat4_mul_mat4(
marie_translation_mat4(translation),
marie_mat3_to_mat4(unit_quaternion_fl_to_rot3d_mat3(rotation))),
marie_3d_scale_mat4(scale));
}
/* This function assumes that we are in little-endian */
void add_meshes_for_gltf_structure__h_rec(Alice* alice, const GLBFileSegments* segments, const GltfFileStructure* gltf,
VecGenericMeshVertexInc* res, mat4 parent_transform, U64 node_id, int rem_depth, int depth) {
check(rem_depth > 0);
check(node_id < gltf->nodes.len);
const GltfNode* node = &gltf->nodes.buf[node_id];
mat4 transform;
if (node->trans.variant == GltfNodeTransformation_mat) {
transform = node->trans.mat;
} else if (node->trans.variant == GltfNodeTransformation_trs) {
transform = trs_mat4(node->trans.trs.translation, node->trans.trs.rotation, node->trans.trs.scale);
} else {
transform = mat4_E;
}
mat4 my_transform = mat4_mul_mat4(parent_transform, transform);
for (int i = 0; i < depth; i++)
printf("====");
VecU8_print(VecU8_fmt("> Node %u \"%r\" %v\n", node_id, node->name,
node->mesh.variant ?
VecU8_fmt("mesh \"%r\"", gltf->meshes.buf[node->mesh.some].name) :
vcstr("no mesh")));
if (node->mesh.variant == Option_Some) {
check(node->mesh.some < gltf->meshes.len);
const GltfMesh* mesh = &gltf->meshes.buf[node->mesh.some];
check(mesh->primitives.len == 1); // Don't you ever dare
const GltfMeshPrimitivePart* prim = &mesh->primitives.buf[0];
check(prim->position.variant == Option_Some);
check(prim->mode == GltfPrimitiveMode_triangles);
const GltfAccessor* position_accsr = &gltf->accessors.buf[prim->position.some];
check(position_accsr->matrix_type == GltfAccessorMatrixType_vec3);
check(position_accsr->component_type == GltfAccessorComponentType_float);
U64 VN = position_accsr->count;
VecGenericMeshVertexInc vert_stuck = VecGenericMeshVertexInc_new_zeroinit(VN);
SpanU8 POSITION;
U64 POSITION_stride;
gltf_file_structure_get_accessor_iter_range(segments, gltf, position_accsr, &POSITION, &POSITION_stride);
for (size_t i = 0; i < VN; i++) {
vec3 pos_here;
memcpy(&pos_here, POSITION.data + POSITION_stride * i, sizeof(vec3));
vec4 pos_over_there = mat4_mul_vec4(my_transform, vec3_and_one(pos_here));
vert_stuck.buf[i].pos = (vec3){pos_over_there.x, pos_over_there.y, pos_over_there.z};
}
if (prim->texcoord_0.variant) {
const GltfAccessor* texcoord_0_accsr = &gltf->accessors.buf[prim->texcoord_0.some];
check(texcoord_0_accsr->matrix_type == GltfAccessorMatrixType_vec2);
check(texcoord_0_accsr->component_type == GltfAccessorComponentType_float);
check(texcoord_0_accsr->count == VN);
SpanU8 TEXCOORD;
U64 TEXCOORD_stride;
gltf_file_structure_get_accessor_iter_range(segments, gltf, texcoord_0_accsr, &TEXCOORD, &TEXCOORD_stride);
for (size_t i = 0; i < VN; i++) {
memcpy(&vert_stuck.buf[i].tex, TEXCOORD.data + TEXCOORD_stride * i, sizeof(vec2));
}
}
if (prim->indices.variant) {
const GltfAccessor* indices_accsr = &gltf->accessors.buf[prim->indices.some];
check(indices_accsr->matrix_type == GltfAccessorMatrixType_scalar);
U64 UN = indices_accsr->count;
check(UN % 3 == 0);
VecU32 indices_stuck = VecU32_new_zeroinit(UN);
SpanU8 INDICES;
U64 INDICES_stride;
gltf_file_structure_get_accessor_iter_range(segments, gltf, indices_accsr, &INDICES, &INDICES_stride);
if (indices_accsr->component_type == GltfAccessorComponentType_unsigned_int) {
check(INDICES_stride == 4);
for (size_t i = 0; i < UN; i++) {
U32 ind;
memcpy(&ind, INDICES.data + INDICES_stride * i, sizeof(U32));
check(ind < VN);
indices_stuck.buf[i] = ind;
}
} else if (indices_accsr->component_type == GltfAccessorComponentType_unsigned_short) {
check(INDICES_stride == 2);
for (size_t i = 0; i < UN; i++) {
U16 ind;
memcpy(&ind, INDICES.data + INDICES_stride * i, sizeof(U16));
check(ind < VN);
indices_stuck.buf[i] = ind;
}
} else {
check(false);
}
VecGenericMeshVertexInc vertexes = VecGenericMeshVertexInc_new_zeroinit(UN);
for (U64 i = 0; i < UN; i++) {
vertexes.buf[i] = vert_stuck.buf[indices_stuck.buf[i]];
}
VecGenericMeshVertexInc_append_vec(res, vertexes);
VecGenericMeshVertexInc_drop(vert_stuck);
VecU32_drop(indices_stuck);
} else {
printf("Primitive without indices\n");
VecGenericMeshVertexInc_append_vec(res, vert_stuck);
}
}
for (size_t chi = 0; chi < node->children.len; chi++) {
U64 child_node = node->children.buf[chi];
add_meshes_for_gltf_structure__h_rec(alice, segments, gltf, res, my_transform, child_node, rem_depth - 1, depth + 1);
}
}
void add_meshes_for_gltf_structure(Alice* alice,
const GLBFileSegments* segments, const GltfFileStructure* gltf, VecRefListNodeAliceGenericMeshHand* res) {
OptionU64 root_node = None_U64();
for (size_t nid = 0; nid < gltf->nodes.len; nid++) {
const GltfNode* node = &gltf->nodes.buf[nid];
if (!node->has_parent) {
root_node = Some_U64(nid);
break;
}
}
/* Right now, it might be not true */
check(root_node.variant == Option_Some);
VecGenericMeshVertexInc vertexes = VecGenericMeshVertexInc_new();
add_meshes_for_gltf_structure__h_rec(alice, segments, gltf, &vertexes, mat4_E, root_node.some, 20, 0);
VecU32 indices_12345 = VecU32_new_zeroinit(vertexes.len);
for (size_t i = 0; i < vertexes.len; i++) {
indices_12345.buf[i] = i;
}
GenericMeshTopology tt = {vertexes, indices_12345};
RefListNodeAliceGenericMeshHand hand = Alice_add_generic_mesh(alice, &tt, (AliceGenericMeshTexturePaths){
.diffuse_texture_path = vcstr("./src/l3/models/bone.png"),
.normal_texture_path = vcstr("./gen/l2/textures/flat_NORMAL.png"),
.specular_texture_path = vcstr("./gen/l2/textures/flat_NORMAL.png"),
});
AliceGenericMeshHand_resize_instance_arr(alice, &hand->el, 1);
AliceGenericMeshHand_set_inst(&hand->el, 0, (GenericMeshInstanceInc){
.model_t = marie_translation_mat4((vec3){10, -25, 10})});
VecRefListNodeAliceGenericMeshHand_append(res, hand);
}
void run_app(){
R4BetaState st;
st.hero_pos = (vec3){0, 0.81f, 0};
@ -373,12 +560,12 @@ void run_app(){
for (U64 i = 0; i < lighting_system_dim; i++) {
for (U64 j = 0; j < lighting_system_dim; j++) {
vec3 clr = sample_rainbow_color();
vec3 clr2 = sample_rainbow_color();
VecLightSourceState_append(&st.LS_state, (LightSourceState){
.pos = vec3_add_vec3(dir, vec3_add_vec3(
vec3_mul_scal(u, -light_cage_rad + light_case_edge_offset + light_case_gap * (float)i),
vec3_mul_scal(v, -light_cage_rad + light_case_edge_offset + light_case_gap * (float)j))),
.color = clr,
.magnitude = 1
.color = clr, .color_2 = clr2, .progress = 0, .phase = frand01() * 1.6f,
});
}
}
@ -395,6 +582,38 @@ void run_app(){
st.hits_count = 0;
st.bullets_stuck_on_ROA = Vecvec3_new();
st.skeleton_meshes = VecRefListNodeAliceGenericMeshHand_new();
{
VecU8 file = read_file_by_path(vcstr("./src/l3/models/skeleton.glb"));
ResultGLBFileSegmentsOrSpanU8 segments_r = glb_file_get_segments(VecU8_to_span(&file));
if (segments_r.variant == Result_Err) {
printf("Something went wrong when reading glb container\n");
SpanU8_print(segments_r.err);
printf("\n");
VecU8_drop(file);
abort();
}
GLBFileSegments segments = segments_r.ok;
VecU8_print(json_encode(&segments.gltf));
printf("\n");
ResultGltfFileStructureOrVecU8 structure_r = glb_file_get_structure(&segments);
if (structure_r.variant == Result_Err) {
printf("Something when parsing gltf\n");
VecU8_print(structure_r.err);
printf("\n");
GLBFileSegments_drop(segments);
VecU8_drop(file);
abort();
}
GltfFileStructure gltf = structure_r.ok;
add_meshes_for_gltf_structure(alice, &segments, &gltf, &st.skeleton_meshes);
// GltfFileStructure_debug_print(&gltf);
GltfFileStructure_drop(gltf);
GLBFileSegments_drop(segments_r.ok);
VecU8_drop(file);
}
Alice_mainloop(st.alice, &(AliceCallbacks){
.on_wl_pointer_button = main_h_on_wl_pointer_button,
.on_wl_keyboard_key = main_h_on_wl_keyboard_key,
@ -403,28 +622,5 @@ void run_app(){
}
int main(){
VecU8 file = read_file_by_path(vcstr("./src/l3/models/skeleton.glb"));
ResultGLBFileSegmentsOrSpanU8 segments_r = glb_file_get_segments(VecU8_to_span(&file));
if (segments_r.variant == Result_Err) {
printf("Something went wrong when reading glb container\n");
SpanU8_print(segments_r.err);
printf("\n");
VecU8_drop(file);
abort();
}
VecU8_print(json_encode(&segments_r.ok.gltf));
printf("\n");
ResultGltfFileStructureOrVecU8 structure_r = glb_file_get_structure(&segments_r.ok);
if (structure_r.variant == Result_Err) {
printf("Something when parsing gltf\n");
VecU8_print(structure_r.err);
printf("\n");
GLBFileSegments_drop(segments_r.ok);
VecU8_drop(file);
abort();
}
GltfFileStructure_debug_print(&structure_r.ok);
GltfFileStructure_drop(structure_r.ok);
GLBFileSegments_drop(segments_r.ok);
VecU8_drop(file);
run_app();
}