#include "global.h" i32 util_encode_mesh_data_size(mesh_data_t_array_t *datas) { if (datas == NULL) { return 0; } i32 size = 0; for (i32 i = 0; i < datas->length; ++i) { for (i32 j = 0; j < datas->buffer[i]->vertex_arrays->length; ++j) { size += datas->buffer[i]->vertex_arrays->buffer[j]->values->length * 2; } size += datas->buffer[i]->index_array->length * 4; } return size; } void util_encode_mesh_datas(mesh_data_t_array_t *datas) { armpack_encode_string("mesh_datas"); if (datas == NULL) { armpack_encode_null(); return; } armpack_encode_array(datas->length); for (i32 i = 0; i < datas->length; ++i) { armpack_encode_map(5); armpack_encode_string("name"); armpack_encode_string(datas->buffer[i]->name); armpack_encode_string("scale_pos"); armpack_encode_f32(datas->buffer[i]->scale_pos); armpack_encode_string("scale_tex"); armpack_encode_f32(datas->buffer[i]->scale_tex); armpack_encode_string("vertex_arrays"); armpack_encode_array(datas->buffer[i]->vertex_arrays->length); for (i32 j = 0; j < datas->buffer[i]->vertex_arrays->length; ++j) { armpack_encode_map(3); armpack_encode_string("attrib"); armpack_encode_string(datas->buffer[i]->vertex_arrays->buffer[j]->attrib); armpack_encode_string("data"); armpack_encode_string(datas->buffer[i]->vertex_arrays->buffer[j]->data); armpack_encode_string("values"); armpack_encode_array_i16(datas->buffer[i]->vertex_arrays->buffer[j]->values); } armpack_encode_string("index_array"); armpack_encode_array_i32(datas->buffer[i]->index_array); } } buffer_t *util_encode_scene(scene_t *raw) { i32 size = 8 * 1024 * 1024 + util_encode_mesh_data_size(raw->mesh_datas); buffer_t *encoded = buffer_create(size); armpack_encode_start(encoded->buffer); armpack_encode_map(13); armpack_encode_string("name"); armpack_encode_null(); armpack_encode_string("objects"); armpack_encode_null(); util_encode_mesh_datas(raw->mesh_datas); armpack_encode_string("camera_datas"); armpack_encode_null(); armpack_encode_string("camera_ref"); armpack_encode_null(); armpack_encode_string("material_datas"); armpack_encode_null(); armpack_encode_string("shader_datas"); armpack_encode_null(); armpack_encode_string("world_datas"); armpack_encode_null(); armpack_encode_string("world_ref"); armpack_encode_null(); armpack_encode_string("speaker_datas"); // TODO: deprecated armpack_encode_null(); armpack_encode_string("embedded_datas"); armpack_encode_null(); i32 ei = armpack_encode_end(); encoded->length = ei; return encoded; } void util_encode_node_canvas(ui_node_canvas_t *c) { ui_node_canvas_encode(c); } i32 util_encode_packed_assets_size(packed_asset_t_array_t *assets) { if (assets == NULL) { return 0; } i32 size = 0; for (i32 i = 0; i < assets->length; ++i) { packed_asset_t *asset = assets->buffer[i]; buffer_t *bytes = asset->bytes; size += bytes->length; } return size; } i32 util_encode_buffers_size(buffer_t_array_t *buffers) { if (buffers == NULL) { return 0; } i32 size = 0; for (i32 i = 0; i < buffers->length; ++i) { size += buffers->buffer[i]->length; } return size; } i32 util_encode_f32_arrays_size(f32_array_t_array_t *arrays) { if (arrays == NULL) { return 0; } i32 size = 0; for (i32 i = 0; i < arrays->length; ++i) { size += arrays->buffer[i]->length * 4; } return size; } i32 util_encode_layer_data_size(layer_data_t_array_t *datas) { if (datas == NULL) { return 0; } i32 size = 0; for (i32 i = 0; i < datas->length; ++i) { buffer_t *tp = datas->buffer[i]->texpaint; if (tp != NULL) { size += tp->length; } buffer_t *tp_nor = datas->buffer[i]->texpaint_nor; if (tp_nor != NULL) { size += tp_nor->length; } buffer_t *tp_pack = datas->buffer[i]->texpaint_pack; if (tp_pack != NULL) { size += tp_pack->length; } } return size; } buffer_t *util_encode_project(project_t *raw) { i32 size = 32 * 1024 * 1024 + util_encode_layer_data_size(raw->layer_datas) + util_encode_mesh_data_size(raw->mesh_datas) + util_encode_packed_assets_size(raw->packed_assets) + util_encode_buffers_size(raw->brush_icons) + util_encode_buffers_size(raw->material_icons) + util_encode_buffers_size(raw->mesh_icons) + util_encode_f32_arrays_size(raw->mesh_transforms); buffer_t *encoded = buffer_create(size); armpack_encode_start(encoded->buffer); armpack_encode_map(26); armpack_encode_string("version"); armpack_encode_string(raw->version); armpack_encode_string("assets"); armpack_encode_array_string(raw->assets); armpack_encode_string("is_bgra"); armpack_encode_bool(raw->is_bgra); armpack_encode_string("packed_assets"); if (raw->packed_assets != NULL) { armpack_encode_array(raw->packed_assets->length); for (i32 i = 0; i < raw->packed_assets->length; ++i) { armpack_encode_map(2); armpack_encode_string("name"); armpack_encode_string(raw->packed_assets->buffer[i]->name); armpack_encode_string("bytes"); armpack_encode_array_u8(raw->packed_assets->buffer[i]->bytes); } } else { armpack_encode_null(); } armpack_encode_string("envmap"); armpack_encode_string(raw->envmap); armpack_encode_string("envmap_strength"); armpack_encode_f32(raw->envmap_strength); armpack_encode_string("envmap_angle"); armpack_encode_f32(raw->envmap_angle); armpack_encode_string("envmap_blur"); armpack_encode_bool(raw->envmap_blur); armpack_encode_string("camera_world"); armpack_encode_array_f32(raw->camera_world); armpack_encode_string("camera_origin"); armpack_encode_array_f32(raw->camera_origin); armpack_encode_string("camera_fov"); armpack_encode_f32(raw->camera_fov); armpack_encode_string("swatches"); if (raw->swatches != NULL) { armpack_encode_array(raw->swatches->length); for (i32 i = 0; i < raw->swatches->length; ++i) { armpack_encode_map(9); armpack_encode_string("base"); armpack_encode_i32(raw->swatches->buffer[i]->base); armpack_encode_string("opacity"); armpack_encode_f32(raw->swatches->buffer[i]->opacity); armpack_encode_string("occlusion"); armpack_encode_f32(raw->swatches->buffer[i]->occlusion); armpack_encode_string("roughness"); armpack_encode_f32(raw->swatches->buffer[i]->roughness); armpack_encode_string("metallic"); armpack_encode_f32(raw->swatches->buffer[i]->metallic); armpack_encode_string("normal"); armpack_encode_i32(raw->swatches->buffer[i]->normal); armpack_encode_string("emission"); armpack_encode_f32(raw->swatches->buffer[i]->emission); armpack_encode_string("height"); armpack_encode_f32(raw->swatches->buffer[i]->height); armpack_encode_string("subsurface"); armpack_encode_f32(raw->swatches->buffer[i]->subsurface); } } else { armpack_encode_null(); } armpack_encode_string("brush_nodes"); if (raw->brush_nodes != NULL) { armpack_encode_array(raw->brush_nodes->length); for (i32 i = 0; i < raw->brush_nodes->length; ++i) { util_encode_node_canvas(raw->brush_nodes->buffer[i]); } } else { armpack_encode_null(); } armpack_encode_string("brush_icons"); if (raw->brush_icons != NULL) { armpack_encode_array(raw->brush_icons->length); for (i32 i = 0; i < raw->brush_icons->length; ++i) { armpack_encode_array_u8(raw->brush_icons->buffer[i]); } } else { armpack_encode_null(); } armpack_encode_string("material_nodes"); if (raw->material_nodes != NULL) { armpack_encode_array(raw->material_nodes->length); for (i32 i = 0; i < raw->material_nodes->length; ++i) { util_encode_node_canvas(raw->material_nodes->buffer[i]); } } else { armpack_encode_null(); } armpack_encode_string("material_groups"); if (raw->material_groups != NULL) { armpack_encode_array(raw->material_groups->length); for (i32 i = 0; i < raw->material_groups->length; ++i) { util_encode_node_canvas(raw->material_groups->buffer[i]); } } else { armpack_encode_null(); } armpack_encode_string("material_icons"); if (raw->material_icons != NULL) { armpack_encode_array(raw->material_icons->length); for (i32 i = 0; i < raw->material_icons->length; ++i) { armpack_encode_array_u8(raw->material_icons->buffer[i]); } } else { armpack_encode_null(); } armpack_encode_string("font_assets"); armpack_encode_array_string(raw->font_assets); armpack_encode_string("layer_datas"); if (raw->layer_datas != NULL) { armpack_encode_array(raw->layer_datas->length); for (i32 i = 0; i < raw->layer_datas->length; ++i) { armpack_encode_map(28); armpack_encode_string("name"); armpack_encode_string(raw->layer_datas->buffer[i]->name); armpack_encode_string("res"); armpack_encode_i32(raw->layer_datas->buffer[i]->res); armpack_encode_string("bpp"); armpack_encode_i32(raw->layer_datas->buffer[i]->bpp); armpack_encode_string("texpaint"); armpack_encode_array_u8(raw->layer_datas->buffer[i]->texpaint); armpack_encode_string("uv_scale"); armpack_encode_f32(raw->layer_datas->buffer[i]->uv_scale); armpack_encode_string("uv_rot"); armpack_encode_f32(raw->layer_datas->buffer[i]->uv_rot); armpack_encode_string("uv_type"); armpack_encode_i32(raw->layer_datas->buffer[i]->uv_type); armpack_encode_string("decal_mat"); armpack_encode_array_f32(raw->layer_datas->buffer[i]->decal_mat); armpack_encode_string("opacity_mask"); armpack_encode_f32(raw->layer_datas->buffer[i]->opacity_mask); armpack_encode_string("fill_layer"); armpack_encode_i32(raw->layer_datas->buffer[i]->fill_layer); armpack_encode_string("object_mask"); armpack_encode_i32(raw->layer_datas->buffer[i]->object_mask); armpack_encode_string("blending"); armpack_encode_i32(raw->layer_datas->buffer[i]->blending); armpack_encode_string("parent"); armpack_encode_i32(raw->layer_datas->buffer[i]->parent); armpack_encode_string("visible"); armpack_encode_bool(raw->layer_datas->buffer[i]->visible); armpack_encode_string("texpaint_nor"); armpack_encode_array_u8(raw->layer_datas->buffer[i]->texpaint_nor); armpack_encode_string("texpaint_pack"); armpack_encode_array_u8(raw->layer_datas->buffer[i]->texpaint_pack); armpack_encode_string("paint_base"); armpack_encode_bool(raw->layer_datas->buffer[i]->paint_base); armpack_encode_string("paint_opac"); armpack_encode_bool(raw->layer_datas->buffer[i]->paint_opac); armpack_encode_string("paint_occ"); armpack_encode_bool(raw->layer_datas->buffer[i]->paint_occ); armpack_encode_string("paint_rough"); armpack_encode_bool(raw->layer_datas->buffer[i]->paint_rough); armpack_encode_string("paint_met"); armpack_encode_bool(raw->layer_datas->buffer[i]->paint_met); armpack_encode_string("paint_nor"); armpack_encode_bool(raw->layer_datas->buffer[i]->paint_nor); armpack_encode_string("paint_nor_blend"); armpack_encode_bool(raw->layer_datas->buffer[i]->paint_nor_blend); armpack_encode_string("paint_height"); armpack_encode_bool(raw->layer_datas->buffer[i]->paint_height); armpack_encode_string("paint_height_blend"); armpack_encode_bool(raw->layer_datas->buffer[i]->paint_height_blend); armpack_encode_string("paint_emis"); armpack_encode_bool(raw->layer_datas->buffer[i]->paint_emis); armpack_encode_string("paint_subs"); armpack_encode_bool(raw->layer_datas->buffer[i]->paint_subs); armpack_encode_string("uv_map"); armpack_encode_i32(raw->layer_datas->buffer[i]->uv_map); } } else { armpack_encode_null(); } util_encode_mesh_datas(raw->mesh_datas); armpack_encode_string("mesh_assets"); armpack_encode_array_string(raw->mesh_assets); armpack_encode_string("mesh_icons"); if (raw->mesh_icons != NULL) { armpack_encode_array(raw->mesh_icons->length); for (i32 i = 0; i < raw->mesh_icons->length; ++i) { armpack_encode_array_u8(raw->mesh_icons->buffer[i]); } } else { armpack_encode_null(); } armpack_encode_string("mesh_transforms"); if (raw->mesh_transforms != NULL) { armpack_encode_array(raw->mesh_transforms->length); for (i32 i = 0; i < raw->mesh_transforms->length; ++i) { armpack_encode_array_f32(raw->mesh_transforms->buffer[i]); } } else { armpack_encode_null(); } armpack_encode_string("atlas_objects"); armpack_encode_array_i32(raw->atlas_objects); armpack_encode_string("atlas_names"); armpack_encode_array_string(raw->atlas_names); armpack_encode_string("script_datas"); armpack_encode_array_string(raw->script_datas); i32 ei = armpack_encode_end(); encoded->length = ei; return encoded; }