RSE-Model/RSPModelLib/hob_parser.c

423 lines
24 KiB
C

/**
* \file hob_parser.c
* \date 26/07/2022
* \author JackCarterSmith
* \copyright GPL-v3.0
* \brief Decode HOB file structure.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "errors_types.h"
#include "options.h"
#include "hob_struct.h"
#include "hob_parser.h"
unsigned char RSP_ModelLib_ParseHOBFile(const char* fileName, T_HOB* hob_struct, T_PROG_OPTIONS* p_opts) {
unsigned char err = NO_ERROR;
long fileSize;
FILE* fStream = NULL;
char* memFile = NULL;
unsigned int i,j,k;
unsigned int facesExtraOffset;
int* offset_index = NULL;
if (hob_struct != NULL && fileName != NULL) {
// Open file
fStream = fopen(fileName, "rb");
if (fStream != NULL) {
// Determine file size in bytes
fseek(fStream, 0, SEEK_END);
fileSize = ftell(fStream);
fseek(fStream, 0, SEEK_SET);
if (p_opts->verbose_mode) printf("[DBG] > Input file size: %ld bytes\n", fileSize);
memFile = malloc(fileSize + 1);
if (memFile != NULL) {
// Copy file in RAM
fread(memFile, fileSize, 1, fStream);
fclose(fStream);
// Retrieve object count from the header
hob_struct->obj_count = ((T_HOBFILE_HEADER *)memFile)->obj_count;
printf("[INFO] - Object(s) quantity: %d\n", hob_struct->obj_count);
if (hob_struct->obj_count > 0) {
// Populate HOB structure with object descriptor
hob_struct->objects = calloc(hob_struct->obj_count, sizeof(T_HOB_OBJECT));
for ( i = 0; i < hob_struct->obj_count; i++ ) {
if (p_opts->debug_mode) printf("\n-=====================-Begin of Object part-======================-\n");
// Get object name
memcpy(hob_struct->objects[i].name, ((T_HOBFILE_OBJ_DESCRIPTOR *)(memFile
+ sizeof(T_HOBFILE_HEADER)
+ sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->object_name, 16);
if (p_opts->verbose_mode) printf("\n");
printf("[INFO] - Process %s object...\n", hob_struct->objects[i].name);
// Get offsets
hob_struct->objects[i].face_group_offset = ((T_HOBFILE_OBJ_DESCRIPTOR *)(memFile
+ sizeof(T_HOBFILE_HEADER)
+ sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->facegroup_offset;
if (p_opts->verbose_mode) printf("[DBG] > Face group offset: 0x%X\n", hob_struct->objects[i].face_group_offset);
hob_struct->objects[i].object_part_header_offset = ((T_HOBFILE_OBJ_DESCRIPTOR *)(memFile
+ sizeof(T_HOBFILE_HEADER)
+ sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->object_parts_offset;
if (p_opts->verbose_mode) printf("[DBG] > Face group header/object parts offset: 0x%X\n", hob_struct->objects[i].object_part_header_offset);
hob_struct->objects[i].face_group_header_offset = ((T_HOBFILE_OBJ_DESCRIPTOR *)(memFile
+ sizeof(T_HOBFILE_HEADER)
+ sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->facegroup_header_2_offset;
if (p_opts->verbose_mode) printf("[DBG] > Face group header2 offset: 0x%X\n", hob_struct->objects[i].face_group_header_offset);
if (p_opts->god_mode) {
printf("[DBG] > Face group unknown1: %d\n",((T_HOBFILE_OBJ_DESCRIPTOR *)(memFile + sizeof(T_HOBFILE_HEADER) + sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->unknownOffset1);
printf("[DBG] > Face group unknown2: %d\n",((T_HOBFILE_OBJ_DESCRIPTOR *)(memFile + sizeof(T_HOBFILE_HEADER) + sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->unknownOffset2);
printf("[DBG] > Face group unknown3: %d\n",((T_HOBFILE_OBJ_DESCRIPTOR *)(memFile + sizeof(T_HOBFILE_HEADER) + sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->unknownOffset3);
printf("[DBG] > Face group unknown4: %.8f\n",((T_HOBFILE_OBJ_DESCRIPTOR *)(memFile + sizeof(T_HOBFILE_HEADER) + sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->unknown4);
}
// Get count and offsets from the facegroup header
hob_struct->objects[i].object_part_count = ((T_HOBFILE_FACEGROUP_HEADER *)(memFile
+ hob_struct->objects[i].object_part_header_offset))->object_part_count;
if (p_opts->verbose_mode) printf("[DBG] > Object parts count: %d\n", hob_struct->objects[i].object_part_count);
hob_struct->objects[i].face_group_count = ((T_HOBFILE_FACEGROUP_HEADER *)(memFile
+ hob_struct->objects[i].object_part_header_offset))->facegroup_count;
if (p_opts->verbose_mode) printf("[DBG] > Face groups count: %d\n", hob_struct->objects[i].face_group_count);
if (hob_struct->objects[i].object_part_count != hob_struct->objects[i].face_group_count && (p_opts->verbose_mode)) printf("[DBG] > Object parts / facegroup count are different!\n");
// Get facegroup datas
offset_index = calloc(hob_struct->objects[i].object_part_count, sizeof(int));
hob_struct->objects[i].object_parts = calloc(hob_struct->objects[i].object_part_count, sizeof(T_HOB_FACE_GROUP));
for ( j = 0; j < hob_struct->objects[i].object_part_count; j++ ) {
if (p_opts->debug_mode) printf("\n-----------------------Begin of Mesh part-------------------------\n");
offset_index[j] = ((T_HOBFILE_FACEGROUP_OFFSET *)(memFile + hob_struct->objects[i].object_part_header_offset
+ sizeof(T_HOBFILE_FACEGROUP_HEADER)
+ sizeof(T_HOBFILE_FACEGROUP_OFFSET) * j))->facegroup_offset;
if (p_opts->verbose_mode) printf("\n[DBG] > Face group meshdef0 offset: 0x%X\n", offset_index[j]);
// Get meshdef0 datas
if (p_opts->god_mode) printf("[DBG] > meshdef0 offset1: 0x%X\n",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->offset1);
if (p_opts->god_mode) printf("[DBG] > meshdef0 offset2: 0x%X\n",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->offset2);
if (p_opts->verbose_mode) printf("[DBG] > Prev meshdef0 offset: 0x%X\n",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->prev_meshdef0_offset);
if (p_opts->verbose_mode) printf("[DBG] > Next meshdef0 offset: 0x%X\n",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->next_meshdef0_offset);
if (p_opts->god_mode) printf("[DBG] > meshdef0 unknown3: %.8f\n",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->unknown3);
if (p_opts->god_mode) printf("[DBG] > meshdef0 unknown4: %.8f\n",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->unknown4);
if (p_opts->god_mode) printf("[DBG] > meshdef0 unknown5: %.8f\n",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->unknown5);
// Get meshdef1 (mesh descriptor) offset
hob_struct->objects[i].object_parts[j].meshdef1_offset = ((T_HOBFILE_MESHDEF0 *)(memFile
+ offset_index[j]))->meshdef1_offset_plus_4;
if (p_opts->verbose_mode) printf("\n[DBG] > Face group meshdef1 offset: 0x%X\n", hob_struct->objects[i].object_parts[j].meshdef1_offset);
if( ((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->reserved1 != 0 ||
((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->reserved2 != 0 ) {
if (p_opts->god_mode) printf("[DBG] > Face group meshdef0: no 0!\n");
}
if (hob_struct->objects[i].object_parts[j].meshdef1_offset > 0) {
// Read meshdef1 datas
hob_struct->objects[i].object_parts[j].face_block_end_offset = ((T_HOBFILE_MESHDEF1 *)(memFile
+ hob_struct->objects[i].object_parts[j].meshdef1_offset - 4))->facedef_end_offset;
hob_struct->objects[i].object_parts[j].vertex_count = ((T_HOBFILE_MESHDEF1 *)(memFile
+ hob_struct->objects[i].object_parts[j].meshdef1_offset - 4))->vertex_count;
hob_struct->objects[i].object_parts[j].face_block_offset = ((T_HOBFILE_MESHDEF1 *)(memFile
+ hob_struct->objects[i].object_parts[j].meshdef1_offset - 4))->faceblock_offset;
if (p_opts->verbose_mode) printf("[DBG] > Faces offset: 0x%X\n", hob_struct->objects[i].object_parts[j].face_block_offset);
hob_struct->objects[i].object_parts[j].vertex_block_offset = ((T_HOBFILE_MESHDEF1 *)(memFile
+ hob_struct->objects[i].object_parts[j].meshdef1_offset - 4))->vertexblocks_offset;
if (p_opts->verbose_mode) printf("[DBG] > Vertex offset: 0x%X\n\n", hob_struct->objects[i].object_parts[j].vertex_block_offset);
// Get face datas
if( ((T_HOBFILE_FACEBLOCK *)(memFile + hob_struct->objects[i].object_parts[j].face_block_offset))->reserved1 != 0 ||
((T_HOBFILE_FACEBLOCK *)(memFile + hob_struct->objects[i].object_parts[j].face_block_offset))->reserved2 != 0 ) {
if (p_opts->god_mode) printf("[DBG] > Face block: uncommon zero header!\n");
}
if ( ((T_HOBFILE_FACEBLOCK *)(memFile + hob_struct->objects[i].object_parts[j].face_block_offset))->facesOffset !=
hob_struct->objects[i].object_parts[j].face_block_offset + sizeof(T_HOBFILE_FACEBLOCK)) {
if (p_opts->god_mode) printf("[DBG] > Face block: uncommon face data offset position!\n");
}
hob_struct->objects[i].object_parts[j].face_count = ((T_HOBFILE_FACEBLOCK *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset))->faceCounts;
hob_struct->objects[i].object_parts[j].faces = calloc(hob_struct->objects[i].object_parts[j].face_count, sizeof(T_HOB_FACE));
facesExtraOffset = 0;
for ( k = 0; k < hob_struct->objects[i].object_parts[j].face_count; k++ ) {
if (p_opts->debug_mode) printf("\n----------------------Begin of FaceGroup part----------------------\n");
// Get flags
hob_struct->objects[i].object_parts[j].faces[k].flags = ((T_HOBFILE_FACES_HEADER *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->flags;
// Get unknown bytes
hob_struct->objects[i].object_parts[j].faces[k].b1 = ((T_HOBFILE_FACES_HEADER *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->b1;
hob_struct->objects[i].object_parts[j].faces[k].b2 = ((T_HOBFILE_FACES_HEADER *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->b2;
hob_struct->objects[i].object_parts[j].faces[k].b3 = ((T_HOBFILE_FACES_HEADER *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->b3;
hob_struct->objects[i].object_parts[j].faces[k].bsize = ((T_HOBFILE_FACES_HEADER *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->faceBlockIntSize * 4; // Multiply by 4 to get the bytes exact number
if (((T_HOBFILE_FACES_HEADER *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->headerSeparator != 0) {
if (p_opts->god_mode) printf("[DBG] > Face header: uncommon separator!\n");
}
// Get materials index
hob_struct->objects[i].object_parts[j].faces[k].material_index = ((T_HOBFILE_FACES_HEADER *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->materialIndex;
// Get vertex indices
memcpy(hob_struct->objects[i].object_parts[j].faces[k].indices,
((T_HOBFILE_FACES_HEADER *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->vertexIndices,
sizeof(unsigned short) * 4);
// Recalculate the dynamic extra bytes offset size - if present
if (hob_struct->objects[i].object_parts[j].faces[k].flags_bits.fHasExtraBytesBeforeColor) facesExtraOffset += 8;
// Get vertex color - if present
if (hob_struct->objects[i].object_parts[j].faces[k].flags_bits.fHasColor) {
if (hob_struct->objects[i].object_parts[j].faces[k].flags_bits.fSeparateColorVertex) {
hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[0] = ((T_HOBFILE_FACES_VERTEX_COLOR *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->v1_rgba;
hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[1] = ((T_HOBFILE_FACES_VERTEX_COLOR *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->v2_rgba;
hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[2] = ((T_HOBFILE_FACES_VERTEX_COLOR *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->v3_rgba;
if (hob_struct->objects[i].object_parts[j].faces[k].flags_bits.fIsQuad) {
hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[3] = ((T_HOBFILE_FACES_VERTEX_COLOR *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->v4_rgba;
facesExtraOffset += sizeof(T_HOBFILE_FACES_VERTEX_COLOR);
} else {
facesExtraOffset += sizeof(T_HOBFILE_FACES_VERTEX_COLOR) - sizeof(T_RGBA);
}
} else {
hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[0] = ((T_HOBFILE_FACES_COLOR *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->rgba;
hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[1] = ((T_HOBFILE_FACES_COLOR *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->rgba;
hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[2] = ((T_HOBFILE_FACES_COLOR *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->rgba;
hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[3] = ((T_HOBFILE_FACES_COLOR *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->rgba;
facesExtraOffset += sizeof(T_HOBFILE_FACES_COLOR);
}
}
// Get UV map - if present
if (hob_struct->objects[i].object_parts[j].faces[k].flags_bits.fHasTexture) {
hob_struct->objects[i].object_parts[j].faces[k].tex_coords[0] = ((T_HOBFILE_FACES_VERTEX_TEXTURE *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->v1_texcoord;
hob_struct->objects[i].object_parts[j].faces[k].tex_coords[1] = ((T_HOBFILE_FACES_VERTEX_TEXTURE *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->v2_texcoord;
hob_struct->objects[i].object_parts[j].faces[k].tex_coords[2] = ((T_HOBFILE_FACES_VERTEX_TEXTURE *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->v3_texcoord;
if (hob_struct->objects[i].object_parts[j].faces[k].flags_bits.fIsQuad) {
hob_struct->objects[i].object_parts[j].faces[k].tex_coords[3] = ((T_HOBFILE_FACES_VERTEX_TEXTURE *)(memFile
+ hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->v4_texcoord;
facesExtraOffset += sizeof(T_HOBFILE_FACES_VERTEX_TEXTURE);
} else {
facesExtraOffset += sizeof(T_HOBFILE_FACES_VERTEX_TEXTURE) - sizeof(T_TEXCOORD);
}
}
if (p_opts->debug_mode) {
printf("[DBG] > Face %d details: flags:0x%X b1:%d b2:%d b3%d bsize:%d\n", k,
hob_struct->objects[i].object_parts[j].faces[k].flags,
hob_struct->objects[i].object_parts[j].faces[k].b1,
hob_struct->objects[i].object_parts[j].faces[k].b2,
hob_struct->objects[i].object_parts[j].faces[k].b3,
hob_struct->objects[i].object_parts[j].faces[k].bsize
);
printf("[DBG] - Type is Quad: %d\n", hob_struct->objects[i].object_parts[j].faces[k].flags_bits.fIsQuad);
printf("[DBG] - Material offset: 0x%X\n", hob_struct->objects[i].object_parts[j].faces[k].material_index);
printf("[DBG] - Vertex indices: %d, %d, %d, %d\n",
hob_struct->objects[i].object_parts[j].faces[k].indices[0],
hob_struct->objects[i].object_parts[j].faces[k].indices[1],
hob_struct->objects[i].object_parts[j].faces[k].indices[2],
hob_struct->objects[i].object_parts[j].faces[k].indices[3]
);
printf("[DBG] - Vertex colors: 0x%X, 0x%X, 0x%X, 0x%X\n",
hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[0],
hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[1],
hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[2],
hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[3]
);
printf("[DBG] - Vertex UV coord (divided by 4096):\n");
printf("[DBG] > %.8f(%d), %.8f(%d)\n",
((double) 1/4096) * hob_struct->objects[i].object_parts[j].faces[k].tex_coords[0].u,
hob_struct->objects[i].object_parts[j].faces[k].tex_coords[0].u,
((double) 1/4096) * hob_struct->objects[i].object_parts[j].faces[k].tex_coords[0].v,
hob_struct->objects[i].object_parts[j].faces[k].tex_coords[0].v
);
printf("[DBG] > %.8f(%d), %.8f(%d)\n",
((double) 1/4096) * hob_struct->objects[i].object_parts[j].faces[k].tex_coords[1].u,
hob_struct->objects[i].object_parts[j].faces[k].tex_coords[1].u,
((double) 1/4096) * hob_struct->objects[i].object_parts[j].faces[k].tex_coords[1].v,
hob_struct->objects[i].object_parts[j].faces[k].tex_coords[1].v
);
printf("[DBG] > %.8f(%d), %.8f(%d)\n",
((double) 1/4096) * hob_struct->objects[i].object_parts[j].faces[k].tex_coords[2].u,
hob_struct->objects[i].object_parts[j].faces[k].tex_coords[2].u,
((double) 1/4096) * hob_struct->objects[i].object_parts[j].faces[k].tex_coords[2].v,
hob_struct->objects[i].object_parts[j].faces[k].tex_coords[2].v
);
printf("[DBG] > %.8f(%d), %.8f(%d)\n",
((double) 1/4096) * hob_struct->objects[i].object_parts[j].faces[k].tex_coords[3].u,
hob_struct->objects[i].object_parts[j].faces[k].tex_coords[3].u,
((double) 1/4096) * hob_struct->objects[i].object_parts[j].faces[k].tex_coords[3].v,
hob_struct->objects[i].object_parts[j].faces[k].tex_coords[3].v
);
printf("\n");
}
if (p_opts->debug_mode) printf("\n-----------------------End of FaceGroup part-----------------------\n");
}
// Get vertex datas
hob_struct->objects[i].object_parts[j].vertices = calloc(hob_struct->objects[i].object_parts[j].vertex_count, sizeof(T_VERTEX));
for ( k = 0; k < hob_struct->objects[i].object_parts[j].vertex_count; k++ ) {
hob_struct->objects[i].object_parts[j].vertices[k].x = ((T_HOBFILE_VERTEX *)(memFile
+ hob_struct->objects[i].object_parts[j].vertex_block_offset
+ sizeof(T_VERTEX) * k))->x;
hob_struct->objects[i].object_parts[j].vertices[k].y = ((T_HOBFILE_VERTEX *)(memFile
+ hob_struct->objects[i].object_parts[j].vertex_block_offset
+ sizeof(T_VERTEX) * k))->y;
hob_struct->objects[i].object_parts[j].vertices[k].z = ((T_HOBFILE_VERTEX *)(memFile
+ hob_struct->objects[i].object_parts[j].vertex_block_offset
+ sizeof(T_VERTEX) * k))->z;
hob_struct->objects[i].object_parts[j].vertices[k].w = ((T_HOBFILE_VERTEX *)(memFile
+ hob_struct->objects[i].object_parts[j].vertex_block_offset
+ sizeof(T_VERTEX) * k))->w; // Always 0???
if (p_opts->debug_mode) printf("[DBG] > Found vertex %d: (%d, %d, %d)\n", k,
hob_struct->objects[i].object_parts[j].vertices[k].x,
hob_struct->objects[i].object_parts[j].vertices[k].y,
hob_struct->objects[i].object_parts[j].vertices[k].z
);
}
}
// Get object part ID, used by animation? bones?
hob_struct->objects[i].object_parts[j].id = ((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->object_id;
if (p_opts->verbose_mode) printf("\n[DBG] > Facegroup/object ID: %d\n", hob_struct->objects[i].object_parts[j].id);
// Get the transform matrix, used by at-st and at-at (at this time)
hob_struct->objects[i].object_parts[j].transform.x = ((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->transform_x;
hob_struct->objects[i].object_parts[j].transform.y = ((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->transform_y;
hob_struct->objects[i].object_parts[j].transform.z = ((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->transform_z;
if (p_opts->god_mode) printf("\n[DBG] > Facegroup/object transform matrix: [%.8f %.8f %.8f]\n",
hob_struct->objects[i].object_parts[j].transform.x,
hob_struct->objects[i].object_parts[j].transform.y,
hob_struct->objects[i].object_parts[j].transform.z
);
if (p_opts->debug_mode) printf("\n-----------------------End of Mesh part---------------------------\n");
}
if (p_opts->debug_mode) printf("\n-=====================-End of Object part-========================-\n");
}
free(offset_index);
} else {
err = ERROR_GENERIC;
printf("[INFO] Can't process empty file!\n");
}
free(memFile);
} else {
fclose(fStream);
err = ERROR_MEMORY;
if (p_opts->verbose_mode) printf("[ERR] Can't allocate enough memory for file processing!\n");
}
} else {
err = ERROR_IO;
if (p_opts->verbose_mode) printf("[ERR] Input file %s not found!\n", fileName);
}
} else err = ERROR_ARGS_NULL;
return err;
}