Compare commits

..

5 Commits

12 changed files with 1388 additions and 26 deletions

View File

@ -15,6 +15,7 @@
#include "lucy.h"
#include "alice.h"
#include "precise_integers.h"
#include "gltf_structures.h"
int main() {
mkdir_nofail("l1");
@ -33,6 +34,7 @@ int main() {
generate_l1_lucy_headers();
generate_code_for_alice_on_l1();
generate_l1_header_for_precise_integers();
generate_l1_gltf_headers();
finish_layer(cstr("l1"));
return 0;
}

View File

@ -0,0 +1,19 @@
#pragma once
/* This file covers codegen for GLTF structures (that represent GLTF objects in memory) */
#include "../codegen/util_template_inst.h"
void generate_l1_gltf_headers() {
SpanU8 l = cstr("l1"), ns = cstr("");
generate_eve_span_company_for_non_primitive_non_clonable(l, ns, cstr("GltfScene"), true, false);
generate_eve_span_company_for_non_primitive_non_clonable(l, ns, cstr("GltfNode"), true, false);
generate_eve_span_company_for_primitive(l, ns, cstr("GltfBuffer"), true, false);
generate_eve_span_company_for_primitive(l, ns, cstr("GltfBufferView"), true, false);
generate_eve_span_company_for_primitive(l, ns, cstr("GltfAccessor"), true, false);
generate_eve_span_company_for_primitive(l, ns, cstr("GltfMeshPrimitivePart"), true, false);
generate_eve_span_company_for_non_primitive_non_clonable(l, ns, cstr("GltfMesh"), true, false);
generate_eve_span_company_for_non_primitive_non_clonable(l, ns, cstr("GltfMaterial"), true, false);
generate_eve_span_company_for_primitive(l, ns, cstr("GltfTexture"), true, false);
generate_Option_templ_inst_eve_header(l, ns, (option_template_instantiation_op){
.T = cstr("GltfTextureInfo"), .t_primitive = true, });
}

View File

@ -5,8 +5,12 @@
/* These headers are guarded */
void generate_util_temp_very_base_headers() {
SpanU8 l = cstr("l1"), ns = cstr("");
SpanU8 T_codegen_VecAndSpan[] = {cstr("U8"), cstr("U16"), cstr("U32"), cstr("S32"), cstr("U64"), cstr("S64")};
SpanU8 T_codegen_Option[] = {cstr("U8"), cstr("U16"), cstr("U32"), cstr("U64"), cstr("S64")};
SpanU8 T_codegen_VecAndSpan[] = {
cstr("U8"), cstr("U16"), cstr("U32"), cstr("S32"), cstr("U64"), cstr("S64"), cstr("Flt32"), cstr("Flt64")
};
SpanU8 T_codegen_Option[] = {
cstr("U8"), cstr("U16"), cstr("U32"), cstr("U64"), cstr("S64"), cstr("Flt32"), cstr("Flt64")
};
SpanU8 T_codegen_VecAndSpan_of_Vec[] = {cstr("U8"), cstr("U16"), cstr("U32"), cstr("U64")};
SpanU8 T_codegen_VecAndSpan_of_Span[] = {cstr("U8"), cstr("U16"), cstr("U32"), cstr("U64")};
for (size_t i = 0; i < ARRAY_SIZE(T_codegen_VecAndSpan); i++) {
@ -47,6 +51,13 @@ void generate_util_temp_very_base_headers() {
VecU8_drop(SpanT);
VecU8_drop(dependency);
}
// todo: maybe make these for all other int types too
generate_Option_templ_inst_guarded_header(l, ns, cstr("#include \"VecAndSpan_U8.h\""),
(option_template_instantiation_op){.T = cstr("SpanU8"), .t_primitive = true});
generate_Option_templ_inst_guarded_header(l, ns, cstr("#include \"VecAndSpan_U64.h\""),
(option_template_instantiation_op){.T = cstr("VecU64"), .t_primitive = false});
generate_guarded_span_company_for_primitive(l, ns, cstr("CSTR"), cstr(""), true, false);
generate_ResultType_templ_inst_guarded_header(l, ns,

View File

@ -12,6 +12,8 @@ typedef int8_t S8;
typedef int16_t S16;
typedef int32_t S32;
typedef int64_t S64;
typedef float Flt32;
typedef double Flt64;
// todo: move these to util (l1) template instantiation too
#define int_minmax_function_Definition(T) \

View File

@ -16,11 +16,11 @@
typedef const char* CSTR;
typedef enum {
Option_Some, Option_None
Option_None = 0, Option_Some = 1
} Option_variant;
typedef enum {
Result_Ok, Result_Err
Result_Err = 0, Result_Ok = 1
} Result_variant;
NORETURN

View File

@ -59,4 +59,4 @@ mat3 unit_quaternion_fl_to_rot3d_mat3(vec4 q){
// e_vc = sinf(t *fi) / qva;
// }
// return (vec4){e_x, e_vc * q.y, e_vc * q.z, e_vc * q.w};
}
// }

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

@ -6,6 +6,7 @@
#include "../../l1/system/fileio.h"
#include "assets.h"
#include "stdalign.h"
#include "../core/glb_file.h"
static_assert(sizeof(float) == 4, "...");
static_assert(sizeof(GenericMeshVertexInc) == 4 * (3 + 2), "...");

File diff suppressed because it is too large Load Diff

View File

@ -92,3 +92,116 @@ Json Json_from_MapVecU8ToJson(json_dictionary_t dict){
// Bonus
#include "../../../gen/l1/eve/OptionJson.h"
// todo: implement _find method in RBTREE template (yes, I WILL do it eventually)
/* Returns nullptr if there is no such field or object is not an */
const Json* Json_dict_at(const Json* self, SpanU8 key) {
if (self->variant != Json_dict)
return NULL;
const json_dictionary_t* d = &self->dict;
RBTreeNode* cur = d->root;
while (cur != d->NIL) {
RBTreeNode_KVPVecU8ToJson* n = (RBTreeNode_KVPVecU8ToJson*)cur;
if (SpanU8_less_SpanU8(VecU8_to_span(&n->key), key)) {
cur = cur->right;
} else if (SpanU8_less_SpanU8(key, VecU8_to_span(&n->key))) {
cur = cur->left;
} else {
return &n->value;
}
}
return NULL;
}
/* Random quality of life json functions */
#include "../../../gen/l1/OptionS64.h"
/* self must not be NULL */
OptionS64 Json_try_as_int(const Json* self) {
return self->variant == Json_integer ? Some_S64(self->integer) : None_S64();
}
#include "../../../gen/l1/OptionU64.h"
OptionU64 Json_try_as_u64(const Json* self) {
return (self->variant == Json_integer && self->integer >= 0) ? Some_U64((U64)self->integer) : None_U64();
}
#include "../../../gen/l1/OptionSpanU8.h"
/* self must not be NULL, returns immutable string reference */
OptionSpanU8 Json_try_as_str(const Json* self) {
return self->variant == Json_str ? Some_SpanU8(VecU8_to_span(&self->str)) : None_SpanU8();
}
#include "../../../gen/l1/OptionFlt32.h"
OptionFlt32 Json_try_as_float(const Json* self) {
if (self->variant == Json_integer)
return Some_Flt32((float)self->integer);
if (self->variant == Json_float)
return Some_Flt32(self->float_num);
return None_Flt32();
}
#include "../../../gen/l1/OptionVecU64.h"
OptionVecU64 Json_try_as_arr_of_u64(const Json* self) {
if (self->variant != Json_arr)
return None_VecU64();
VecU64 res = VecU64_new_zeroinit(self->arr.len);
for (size_t i = 0; i < self->arr.len; i++) {
const Json* el = &self->arr.buf[i];
if (el->variant != Json_integer || el->integer < 0) {
VecU64_drop(res);
return None_VecU64();
}
res.buf[i] = (U64)el->integer;
}
return Some_VecU64(res);
}
#include "../../../gen/l1/VecAndSpan_Flt32.h"
/* true=ok, false=err */
bool Json_try_as_MutSpanFlt32(const Json* self, MutSpanFlt32 ret) {
if (self->variant != Json_arr)
return false;
size_t n = ret.len;
if (self->arr.len != n)
return false;
for (size_t i = 0; i < n; i++) {
const Json* el = &self->arr.buf[i];
OptionFlt32 opt = Json_try_as_float(el);
if (opt.variant != Option_Some)
return false;
ret.data[i] = opt.some;
}
return true;
}
OptionU64 Json_dict_field_try_as_u64(const Json* self, SpanU8 key) {
const Json* el = Json_dict_at(self, key);
if (!el)
return None_U64();
return Json_try_as_u64(el);
}
OptionSpanU8 Json_dict_field_try_as_str(const Json* self, SpanU8 key) {
const Json* el = Json_dict_at(self, key);
if (!el || el->variant != Json_str)
return None_SpanU8();
return Some_SpanU8(VecU8_to_span(&el->str));
}
OptionFlt32 Json_dict_field_try_as_float(const Json* self, SpanU8 key) {
const Json* el = Json_dict_at(self, key);
if (!el)
return None_Flt32();
if (el->variant == Json_integer)
return Some_Flt32((float)el->integer);
if (el->variant == Json_float)
return Some_Flt32((float)el->float_num);
return None_Flt32();
}

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,