266 auto const len = parse_xac_any_binary<uint32_t>(&start, end, err);
271 auto const len = parse_xac_any_binary<uint32_t>(&start, end, err);
272 out.resize(
size_t(len),
'\0');
273 std::memcpy(&out[0], start,
size_t(len));
279 auto const mh = parse_xac_any_binary<xac_metadata_chunk_header>(&start, end, err);
281 std::printf(
"program-name=%s\n", start + 4);
285 std::printf(
"workspace-folder-name=%s\n", start + 4);
289 std::printf(
"edition-or-creation-date=%s\n", start + 4);
293 std::printf(
"name-of-the-model=%s\n", start + 4);
300 auto const mh = parse_xac_any_binary<xac_material_block_v1_chunk_header>(&start, end, err);
302 std::printf(
"NumStd=%u,NumFx=%u\n", mh.num_standard_materials, mh.num_fx_materials);
310 auto const mh = parse_xac_any_binary<xac_material_v2_chunk_header>(&start, end, err);
311 std::string name =
"";
323 mat.
shine = mh.shine;
328 for(
uint8_t i = 0; i < mh.num_layers; ++i) {
329 auto const mlh = parse_xac_any_binary<xac_material_layer_v2_header>(&start, end, err);
330 std::string layer_name =
"";
336 layer.
amount = mlh.amount;
345 mat.
layers.push_back(layer);
357 auto const ch = parse_xac_any_binary<xac_node_hierachy_v1_chunk_header>(&start, end, err);
358 if(int32_t(ch.num_nodes) <= 0) {
362 if(int32_t(ch.num_root_nodes) <= 0) {
366 for(
uint32_t i = 0; i < ch.num_nodes; i++) {
367 auto const mh = parse_xac_any_binary<xac_node_hierachy_v1_node_header>(&start, end, err);
368 std::string name =
"";
371 std::printf(
">(Id=%u),Name=%s,IIBC=%x,Imp=%f,ParentId=%i,NumChild=%u,Unk=%x,%x\n", i, name.c_str(), mh.include_in_bounds_calc, mh.importance_factor, mh.parent_id, mh.num_children, mh.unknown[0], mh.unknown[1]);
378 node.
scale = mh.scale;
381 if(mh.parent_id == -1) {
384 if(
size_t(mh.parent_id) >= context.
nodes.size()) {
389 context.
nodes.push_back(node);
395 auto const cd = parse_xac_any_binary<xac_mesh_v1_chunk_header>(&start, end, err);
396 if(cd.node_id >= int32_t(context.
nodes.size())) {
401 std::printf(
"N-AttribLayers=%u\n", cd.num_attribute_layers);
402 std::printf(
"IsCollision=%u,Pad=%u,%u,%u\n", cd.is_collision_mesh, cd.unused[0], cd.unused[1], cd.unused[2]);
407 obj.influence_counts.resize(
size_t(cd.num_influence_ranges), 0);
408 for(
uint32_t i = 0; i < cd.num_attribute_layers; ++i) {
409 auto const vbh = parse_xac_any_binary<xac_vertex_block_v1_header>(&start, end, err);
411 std::printf(
"T=%u,AttribSize=%u,NumVertices=%u,IsKeep=%u,IsScale=%u\n", vbh.ident, vbh.size, cd.num_vertices, vbh.keep_original, vbh.is_scale_factor);
413 for(
uint32_t j = 0; j < cd.num_vertices; ++j) {
420 auto const normal = parse_xac_any_binary<xac_vector3f>(&start, end, err);
421 obj.normals.push_back(
normal);
429 auto const vertex = parse_xac_any_binary<xac_vector3f>(&start, end, err);
430 obj.vertices.push_back(
vertex);
438 auto const texcoord = parse_xac_any_binary<xac_vector2f>(&start, end, err);
447 auto const weight = parse_xac_any_binary<xac_vector4f>(&start, end, err);
448 obj.weights.push_back(
weight);
456 auto const influence_index = parse_xac_any_binary<uint32_t>(&start, end, err);
457 obj.influence_indices.push_back(influence_index);
468 for(
uint32_t i = 0; i < cd.num_sub_meshes; i++) {
469 auto const smh = parse_xac_any_binary<xac_submesh_v1_header>(&start, end, err);
471 std::printf(
"SubObj,NumInd=%u,NumVert=%u,NumBone=%u\n", smh.num_indices, smh.num_vertices, smh.num_bones);
473 if((int32_t(smh.num_indices) % 3) != 0) {
476 if(int32_t(smh.num_indices) < 0) {
479 if(int32_t(smh.num_bones) < 0) {
483 sub.material_id = smh.material_id;
484 sub.num_vertices = smh.num_vertices;
485 sub.vertex_offset = vertex_offset;
486 for(
uint32_t j = 0; j < smh.num_indices; j++) {
487 auto index = parse_xac_any_binary<uint32_t>(&start, end, err);
488 if(index >= smh.num_vertices) {
491 sub.indices.push_back(index);
493 for(
uint32_t j = 0; j < smh.num_bones; j++) {
494 auto index = parse_xac_any_binary<uint32_t>(&start, end, err);
495 sub.bone_ids.push_back(index);
497 obj.submeshes.push_back(sub);
498 vertex_offset += smh.num_vertices;
500 auto& node = context.
nodes[cd.node_id];
501 if(cd.is_collision_mesh) {
502 if(node.collision_mesh >= 0)
505 node.collision_mesh = int32_t(node.meshes.size());
507 if(node.visual_mesh >= 0)
510 node.visual_mesh = int32_t(node.meshes.size());
513 if(vertex_offset != cd.num_vertices) {
514 err.
accumulated_warnings +=
"Object total meshes doesn't add up to subojects " + std::to_string(vertex_offset) +
" != " + std::to_string(cd.num_vertices) +
" (" + err.
file_name +
")\n";
516 node.meshes.push_back(obj);
521 auto const sh = parse_xac_any_binary<xac_skinning_v3_chunk_header>(&start, end, err);
523 std::printf(
"NInfluences=%u\n", sh.num_influences);
525 std::vector<xac_skinning_v3_influence_entry> influence_data;
526 for(
uint32_t i = 0; i < sh.num_influences; i++) {
527 auto const influence = parse_xac_any_binary<xac_skinning_v3_influence_entry>(&start, end, err);
528 influence_data.push_back(influence);
530 if(sh.node_id >= int32_t(context.
nodes.size())) {
533 }
else if(sh.node_id < 0) {
538 auto& node = context.
nodes[sh.node_id];
539 if(sh.is_for_collision_mesh) {
540 if(node.collision_mesh >= 0) {
541 auto& obj = node.meshes[node.collision_mesh];
542 for(
const auto& influence : influence_data) {
544 bone_influence.
weight = influence.weight;
545 bone_influence.bone_id = influence.bone_id;
546 obj.influences.push_back(bone_influence);
549 auto const range = parse_xac_any_binary<xac_skinning_v3_influence_range>(&start, end, err);
550 obj.influence_starts[i] = range.first_influence_index;
551 obj.influence_counts[i] = range.num_influences;
558 if(node.visual_mesh >= 0) {
559 auto& obj = node.meshes[node.visual_mesh];
560 for(
const auto& influence : influence_data) {
562 bone_influence.
weight = influence.weight;
563 bone_influence.bone_id = influence.bone_id;
564 obj.influences.push_back(bone_influence);
567 auto const range = parse_xac_any_binary<xac_skinning_v3_influence_range>(&start, end, err);
568 obj.influence_starts[i] = range.first_influence_index;
569 obj.influence_counts[i] = range.num_influences;
580 const char* file_start = start;
581 auto const h = parse_xac_any_binary<xac_header>(&start, end, err);
587 std::printf(
"XacFile-> version %u.%u, totalSize=%u\n", h.major_version, h.minor_version,
uint32_t(end - start));
590 auto const ch = parse_xac_any_binary<xac_chunk_header>(&start, end, err);
592 std::printf(
">>> Id=%u,ChunkVersion=%u(Len=%u)\n", ch.ident, ch.version, ch.len);
595 const char* expected = start + ch.len;
598 if(ch.version == 1) {
605 if(ch.version == 2) {
612 if(ch.version == 1) {
619 if(ch.version == 2) {
627 if(ch.version == 1) {
634 if(ch.version == 3) {
643 std::printf(
"CT,Unknown-(%i)\n", int16_t(ch.ident));
645 err.
accumulated_warnings +=
"Unknown chunk block type " + std::to_string(int32_t(ch.ident)) +
" (size " + std::to_string(ch.len) +
" @ offset " + std::to_string(
uint32_t(start - file_start)) +
") on " + err.
file_name +
"\n";
650 err.
accumulated_errors +=
"Incorrect parsing for chunk ident " + std::to_string(int32_t(ch.ident)) +
" (difference from expected " + std::to_string(int32_t(expected - start)) +
") on " + err.
file_name +
"\n";
655 for(
const auto& node : context.
nodes) {
656 std::printf(
"Node: %s\n", node.name.c_str());
657 std::printf(
"* Meshes: %zu\n", node.meshes.size());
658 for(
const auto& o : node.meshes) {
659 std::printf(
"\tMesh\n");
660 std::printf(
"\t* vertices: %zu\n", o.vertices.size());
661 std::printf(
"\t* normals: %zu\n", o.normals.size());
662 std::printf(
"\t* texcoords: %zu\n", o.texcoords.size());
673 for(
auto& node : context.
nodes) {
674 for(
auto& o : node.meshes) {
677 2.f * (q.
x * q.
x + q.
y * q.
y) - 1.f,
678 2.f * (q.
y * q.
z - q.
x * q.
w),
679 2.f * (q.
y * q.
w + q.
x * q.
z),
681 2.f * (q.
y * q.
z + q.
x * q.
w),
682 2.f * (q.
x * q.
x + q.
z * q.
z) - 1.f,
683 2.f * (q.
z * q.
w - q.
x * q.
y),
685 2.f * (q.
y * q.
w - q.
x * q.
z),
686 2.f * (q.
z * q.
w + q.
x * q.
y),
687 2.f * (q.
x * q.
x + q.
w * q.
w) - 1.f,
691 qm.
m[0 * 4 + 0] * node.scale.x,
692 qm.m[0 * 4 + 1] * node.scale.y,
693 qm.m[0 * 4 + 2] * node.scale.z,
695 qm.m[1 * 4 + 0] * node.scale.x,
696 qm.m[1 * 4 + 1] * node.scale.y,
697 qm.m[1 * 4 + 2] * node.scale.z,
699 qm.m[2 * 4 + 0] * node.scale.x,
700 qm.m[2 * 4 + 1] * node.scale.y,
701 qm.m[2 * 4 + 2] * node.scale.z,
704 for(
uint32_t i = 0; i < o.vertices.size(); i++) {
706 v.
x = tm.m[0 * 4 + 0] * v.
x + tm.m[0 * 4 + 1] * v.
y + tm.m[0 * 4 + 2] * v.
z + tm.m[0 * 4 + 3] * 1.f;
707 v.
y = tm.m[1 * 4 + 0] * v.
x + tm.m[1 * 4 + 1] * v.
y + tm.m[1 * 4 + 2] * v.
z + tm.m[1 * 4 + 3] * 1.f;
708 v.
z = tm.m[2 * 4 + 0] * v.
x + tm.m[2 * 4 + 1] * v.
y + tm.m[2 * 4 + 2] * v.
z + tm.m[2 * 4 + 3] * 1.f;
std::string accumulated_errors
std::string accumulated_warnings
const char * parse_xac_metadata_v2(xac_context &context, const char *start, const char *end, parsers::error_handler &err)
void parse_xac(xac_context &context, const char *start, const char *end, parsers::error_handler &err)
const char * parse_xac_node_hierachy_v1(xac_context &context, const char *start, const char *end, parsers::error_handler &err)
const char * parse_xac_material_v2(xac_context &context, const char *start, const char *end, parsers::error_handler &err)
const char * parse_xac_material_block_v1(xac_context &context, const char *start, const char *end, parsers::error_handler &err)
const char * parse_xac_skinning_v3(xac_context &context, const char *start, const char *end, parsers::error_handler &err)
const char * parse_xac_cstring(const char *start, const char *end, parsers::error_handler &err)
void finish(xac_context &context)
const char * parse_xac_cstring_nodiscard(std::string &out, const char *start, const char *end, parsers::error_handler &err)
const char * parse_xac_mesh_v1(xac_context &context, const char *start, const char *end, parsers::error_handler &err)
uint32_t max_standard_materials
std::vector< xac_pp_actor_material > materials
std::vector< xac_pp_actor_node > root_nodes
uint32_t max_fx_materials
std::vector< xac_pp_actor_node > nodes
xac_pp_material_map_type map_type
std::vector< xac_pp_actor_material_layer > layers
xac_color_rgba emissive_color
xac_color_rgba specular_color
xac_color_rgba ambient_color
xac_color_rgba diffuse_color
std::vector< uint32_t > influence_starts
xac_vector4f scale_rotation