Minors data fix #1

Merged
JackCarterSmith merged 5 commits from develop into master 2022-07-28 17:26:56 +02:00
7 changed files with 2774 additions and 2667 deletions

View File

@ -7,6 +7,8 @@ The collection consist of few independants modules, each of them deals with spec
All modules are independants. This is the **'MODEL'** module. All modules are independants. This is the **'MODEL'** module.
[![Build Status](https://ci.jcsmith.fr/job/JCS-Prod/job/RSE-Model/job/master/badge/icon)](https://ci.jcsmith.fr/job/JCS-Prod/job/RSE-Model/job/master/)
## MODEL MODULE ## MODEL MODULE
It's extract texture datas from Rogue Squadron 3D (PC) game models files (HOB). It's extract texture datas from Rogue Squadron 3D (PC) game models files (HOB).

File diff suppressed because it is too large Load Diff

View File

@ -104,7 +104,7 @@ static unsigned int mainProcess(int args_cnt, char *args_value[]) {
} }
static int checkInputArgs(int arg_nbr, char *args[]) { static int checkInputArgs(int arg_nbr, char *args[]) {
int _o = 0x0002; // Default options parameters int _o = (OUTPUT_DIR | EXPORT_MTL); // Default options parameters
char test[256]; char test[256];
int i; int i;
@ -120,7 +120,10 @@ static int checkInputArgs(int arg_nbr, char *args[]) {
printf("[OPTN] Verbose enabled.\n"); printf("[OPTN] Verbose enabled.\n");
} else if (strcmp(args[i], "-no-subdir") == 0) { } else if (strcmp(args[i], "-no-subdir") == 0) {
_o &= ~OUTPUT_DIR; _o &= ~OUTPUT_DIR;
printf("[OPTN] Extract to current directory.\n"); printf("[OPTN] Export to current directory.\n");
} else if (strcmp(args[i], "-mtl") == 0) {
_o &= ~EXPORT_MTL;
printf("[OPTN] No materials datas.\n");
} else { } else {
printf("[ERR] Unknown option: %s\n", args[i]); printf("[ERR] Unknown option: %s\n", args[i]);
} }
@ -150,11 +153,11 @@ static void cleanUpMemory(T_HOB* hobStruct) {
for ( i=0; i<hobStruct->obj_count; i++ ) { for ( i=0; i<hobStruct->obj_count; i++ ) {
for ( j=0; j<hobStruct->objects[i].face_group_count; j++ ) { for ( j=0; j<hobStruct->objects[i].face_group_count; j++ ) {
free(hobStruct->objects[i].face_groups[j].faces); free(hobStruct->objects[i].object_parts[j].faces);
free(hobStruct->objects[i].face_groups[j].vertices); free(hobStruct->objects[i].object_parts[j].vertices);
} }
free(hobStruct->objects[i].face_groups); free(hobStruct->objects[i].object_parts);
} }
free(hobStruct->objects); free(hobStruct->objects);
@ -163,7 +166,10 @@ static void cleanUpMemory(T_HOB* hobStruct) {
static inline void dispHelp() { static inline void dispHelp() {
printf("\n"); printf("\n");
printf("Options:\n -h Print this message\n -v Activate verbose console output\n -no-subdir Extract textures inside current folder\n"); printf("Options:\n -h Print this message\n");
printf(" -v Activate verbose console output\n");
printf(" -no-subdir Export models inside current folder\n");
printf(" -no-mtl Disable materials datas export with model\n");
printf("\n"); printf("\n");
printf("Usage: RSE-Model_%s [options] <hob files...>\n", VERSION); printf("Usage: RSE-Model_%s [options] <hob files...>\n", VERSION);
printf("\n"); printf("\n");

View File

@ -60,10 +60,10 @@ unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct) {
+ sizeof(T_HOBFILE_HEADER) + sizeof(T_HOBFILE_HEADER)
+ sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->facegroup_offset; + sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->facegroup_offset;
if (_options & VERBOSE_ENABLED) printf("[DBG] > Face group offset: 0x%X\n", hob_struct->objects[i].face_group_offset); if (_options & VERBOSE_ENABLED) printf("[DBG] > Face group offset: 0x%X\n", hob_struct->objects[i].face_group_offset);
hob_struct->objects[i].face_group_header_offset = ((T_HOBFILE_OBJ_DESCRIPTOR *)(memFile hob_struct->objects[i].object_part_header_offset = ((T_HOBFILE_OBJ_DESCRIPTOR *)(memFile
+ sizeof(T_HOBFILE_HEADER) + sizeof(T_HOBFILE_HEADER)
+ sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->object_parts_offset; + sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->object_parts_offset;
if (_options & VERBOSE_ENABLED) printf("[DBG] > Face group header/object parts offset: 0x%X\n", hob_struct->objects[i].face_group_header_offset); if (_options & VERBOSE_ENABLED) 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_header2_offset = ((T_HOBFILE_OBJ_DESCRIPTOR *)(memFile hob_struct->objects[i].face_group_header2_offset = ((T_HOBFILE_OBJ_DESCRIPTOR *)(memFile
+ sizeof(T_HOBFILE_HEADER) + sizeof(T_HOBFILE_HEADER)
+ sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->facegroup_header_2_offset; + sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->facegroup_header_2_offset;
@ -71,85 +71,104 @@ unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct) {
// Get count and offsets from the facegroup header // Get count and offsets from the facegroup header
hob_struct->objects[i].face_group_count = ((T_HOBFILE_FACEGROUP_HEADER *)(memFile hob_struct->objects[i].face_group_count = ((T_HOBFILE_FACEGROUP_HEADER *)(memFile
+ hob_struct->objects[i].face_group_header_offset))->facegroup_count; + hob_struct->objects[i].object_part_header_offset))->facegroup_count;
if (_options & VERBOSE_ENABLED) printf("[DBG] > Face group count: %d\n", hob_struct->objects[i].face_group_count); if (_options & VERBOSE_ENABLED) printf("[DBG] > Face group count: %d\n", hob_struct->objects[i].face_group_count);
hob_struct->objects[i].face_group_count0 = ((T_HOBFILE_FACEGROUP_HEADER *)(memFile hob_struct->objects[i].face_group_count0 = ((T_HOBFILE_FACEGROUP_HEADER *)(memFile
+ hob_struct->objects[i].face_group_header_offset))->facegroup_count0; + hob_struct->objects[i].object_part_header_offset))->facegroup_count0;
if (_options & VERBOSE_ENABLED) printf("[DBG] > Face group count0: %d\n", hob_struct->objects[i].face_group_count0); if (_options & VERBOSE_ENABLED) printf("[DBG] > Face group count0: %d\n", hob_struct->objects[i].face_group_count0);
if (hob_struct->objects[i].face_group_count != hob_struct->objects[i].face_group_count0 && (_options & VERBOSE_ENABLED)) printf("[DBG] > Facegroup count are different!\n"); if (hob_struct->objects[i].face_group_count != hob_struct->objects[i].face_group_count0 && (_options & VERBOSE_ENABLED)) printf("[DBG] > Facegroup count are different!\n");
// Get facegroup datas // Get facegroup datas
offset_index = calloc(hob_struct->objects[i].face_group_count, sizeof(int)); offset_index = calloc(hob_struct->objects[i].face_group_count, sizeof(int));
hob_struct->objects[i].face_groups = calloc(hob_struct->objects[i].face_group_count, sizeof(T_HOB_FACE_GROUP)); hob_struct->objects[i].object_parts = calloc(hob_struct->objects[i].face_group_count, sizeof(T_HOB_FACE_GROUP));
for ( j = 0; j < hob_struct->objects[i].face_group_count; j++ ) { for ( j = 0; j < hob_struct->objects[i].face_group_count; j++ ) {
offset_index[j] = ((T_HOBFILE_FACEGROUP_OFFSET *)(memFile + hob_struct->objects[i].face_group_header_offset 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_HEADER)
+ sizeof(T_HOBFILE_FACEGROUP_OFFSET) * j))->facegroup_offset; + sizeof(T_HOBFILE_FACEGROUP_OFFSET) * j))->facegroup_offset;
if (_options & VERBOSE_ENABLED) printf("\n[DBG] > Face group meshdef0 offset: 0x%X\n", offset_index[j]); if (_options & VERBOSE_ENABLED) printf("\n[DBG] > Face group meshdef0 offset: 0x%X\n", offset_index[j]);
// Get meshdef1 (mesh descriptor) offset // Get meshdef0 datas
hob_struct->objects[i].face_groups[j].meshdef1_offset = ((T_HOBFILE_MESHDEF0_0 *)(memFile if (_options & VERBOSE_ENABLED) printf("\n[DBG] > Next meshdef0 offset: 0x%X",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->next_meshdef0_offset);
+ offset_index[j]))->meshdef1_offset_plus_4; if (_options & VERBOSE_ENABLED) printf("\n[DBG] > Prev meshdef0 offset: 0x%X",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->prev_meshdef0_offset);
if (_options & VERBOSE_ENABLED) printf("[DBG] > Face group meshdef1 offset: 0x%X\n", hob_struct->objects[i].face_groups[j].meshdef1_offset); hob_struct->objects[i].object_parts[j].id = ((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->object_id;
if (_options & VERBOSE_ENABLED) printf("\n[DBG] > Facegroup/object ID: %d\n", hob_struct->objects[i].object_parts[j].id);
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 (_options & VERBOSE_ENABLED) 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 (hob_struct->objects[i].face_groups[j].meshdef1_offset > 0) { // 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 (_options & VERBOSE_ENABLED) printf("[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 (_options & VERBOSE_ENABLED) printf("[DBG] > Face group meshdef0: no 0!\n");
}
if (hob_struct->objects[i].object_parts[j].meshdef1_offset > 0) {
// Read meshdef1 datas // Read meshdef1 datas
hob_struct->objects[i].face_groups[j].face_block_end_offset = ((T_HOBFILE_MESHDEF1 *)(memFile hob_struct->objects[i].object_parts[j].face_block_end_offset = ((T_HOBFILE_MESHDEF1 *)(memFile
+ hob_struct->objects[i].face_groups[j].meshdef1_offset - 4))->facedef_end_offset; + hob_struct->objects[i].object_parts[j].meshdef1_offset - 4))->facedef_end_offset;
hob_struct->objects[i].face_groups[j].vertex_count = ((T_HOBFILE_MESHDEF1 *)(memFile hob_struct->objects[i].object_parts[j].vertex_count = ((T_HOBFILE_MESHDEF1 *)(memFile
+ hob_struct->objects[i].face_groups[j].meshdef1_offset - 4))->vertex_count; + hob_struct->objects[i].object_parts[j].meshdef1_offset - 4))->vertex_count;
hob_struct->objects[i].face_groups[j].face_block_offset = ((T_HOBFILE_MESHDEF1 *)(memFile hob_struct->objects[i].object_parts[j].face_block_offset = ((T_HOBFILE_MESHDEF1 *)(memFile
+ hob_struct->objects[i].face_groups[j].meshdef1_offset - 4))->faceblock_offset; + hob_struct->objects[i].object_parts[j].meshdef1_offset - 4))->faceblock_offset;
if (_options & VERBOSE_ENABLED) printf("[DBG] > Faces offset: 0x%X\n", hob_struct->objects[i].face_groups[j].face_block_offset); if (_options & VERBOSE_ENABLED) printf("[DBG] > Faces offset: 0x%X\n", hob_struct->objects[i].object_parts[j].face_block_offset);
hob_struct->objects[i].face_groups[j].vertex_block_offset = ((T_HOBFILE_MESHDEF1 *)(memFile hob_struct->objects[i].object_parts[j].vertex_block_offset = ((T_HOBFILE_MESHDEF1 *)(memFile
+ hob_struct->objects[i].face_groups[j].meshdef1_offset - 4))->vertexblocks_offset; + hob_struct->objects[i].object_parts[j].meshdef1_offset - 4))->vertexblocks_offset;
if (_options & VERBOSE_ENABLED) printf("[DBG] > Vertex offset: 0x%X\n\n", hob_struct->objects[i].face_groups[j].vertex_block_offset); if (_options & VERBOSE_ENABLED) printf("[DBG] > Vertex offset: 0x%X\n\n", hob_struct->objects[i].object_parts[j].vertex_block_offset);
// Get face datas // Get face datas
if( ((T_HOBFILE_FACEBLOCK *)(memFile + hob_struct->objects[i].face_groups[j].face_block_offset))->reserved1 != 0 || 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].face_groups[j].face_block_offset))->reserved2 != 0 ) { ((T_HOBFILE_FACEBLOCK *)(memFile + hob_struct->objects[i].object_parts[j].face_block_offset))->reserved2 != 0 ) {
if (_options & VERBOSE_ENABLED) printf("[DBG] > Face block: uncommon zero header!\n"); if (_options & VERBOSE_ENABLED) printf("[DBG] > Face block: uncommon zero header!\n");
} }
if ( ((T_HOBFILE_FACEBLOCK *)(memFile + hob_struct->objects[i].face_groups[j].face_block_offset))->facesOffset != if ( ((T_HOBFILE_FACEBLOCK *)(memFile + hob_struct->objects[i].object_parts[j].face_block_offset))->facesOffset !=
hob_struct->objects[i].face_groups[j].face_block_offset + sizeof(T_HOBFILE_FACEBLOCK)) { hob_struct->objects[i].object_parts[j].face_block_offset + sizeof(T_HOBFILE_FACEBLOCK)) {
if (_options & VERBOSE_ENABLED) printf("[DBG] > Face block: uncommon face data offset position!\n"); if (_options & VERBOSE_ENABLED) printf("[DBG] > Face block: uncommon face data offset position!\n");
} }
hob_struct->objects[i].face_groups[j].face_count = ((T_HOBFILE_FACEBLOCK *)(memFile hob_struct->objects[i].object_parts[j].face_count = ((T_HOBFILE_FACEBLOCK *)(memFile
+ hob_struct->objects[i].face_groups[j].face_block_offset))->faceCounts; + hob_struct->objects[i].object_parts[j].face_block_offset))->faceCounts;
hob_struct->objects[i].face_groups[j].faces = calloc(hob_struct->objects[i].face_groups[j].face_count, sizeof(T_HOB_FACE)); hob_struct->objects[i].object_parts[j].faces = calloc(hob_struct->objects[i].object_parts[j].face_count, sizeof(T_HOB_FACE));
facesExtraOffset = 0; facesExtraOffset = 0;
for ( k = 0; k < hob_struct->objects[i].face_groups[j].face_count; k++ ) { for ( k = 0; k < hob_struct->objects[i].object_parts[j].face_count; k++ ) {
// Get flags // Get flags
hob_struct->objects[i].face_groups[j].faces[k].flags = ((T_HOBFILE_FACES_HEADER *)(memFile hob_struct->objects[i].object_parts[j].faces[k].flags = ((T_HOBFILE_FACES_HEADER *)(memFile
+ hob_struct->objects[i].face_groups[j].face_block_offset + hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) * k + sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->flags; + facesExtraOffset))->flags;
// Get unknown bytes // Get unknown bytes
hob_struct->objects[i].face_groups[j].faces[k].b1 = ((T_HOBFILE_FACES_HEADER *)(memFile hob_struct->objects[i].object_parts[j].faces[k].b1 = ((T_HOBFILE_FACES_HEADER *)(memFile
+ hob_struct->objects[i].face_groups[j].face_block_offset + hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) * k + sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->b1; + facesExtraOffset))->b1;
hob_struct->objects[i].face_groups[j].faces[k].b2 = ((T_HOBFILE_FACES_HEADER *)(memFile hob_struct->objects[i].object_parts[j].faces[k].b2 = ((T_HOBFILE_FACES_HEADER *)(memFile
+ hob_struct->objects[i].face_groups[j].face_block_offset + hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) * k + sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->b2; + facesExtraOffset))->b2;
hob_struct->objects[i].face_groups[j].faces[k].b3 = ((T_HOBFILE_FACES_HEADER *)(memFile hob_struct->objects[i].object_parts[j].faces[k].b3 = ((T_HOBFILE_FACES_HEADER *)(memFile
+ hob_struct->objects[i].face_groups[j].face_block_offset + hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) * k + sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->b3; + facesExtraOffset))->b3;
hob_struct->objects[i].face_groups[j].faces[k].bsize = ((T_HOBFILE_FACES_HEADER *)(memFile hob_struct->objects[i].object_parts[j].faces[k].bsize = ((T_HOBFILE_FACES_HEADER *)(memFile
+ hob_struct->objects[i].face_groups[j].face_block_offset + hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) * k + sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->faceBlockIntSize * 4; // Multiply by 4 to get the bytes exact number + facesExtraOffset))->faceBlockIntSize * 4; // Multiply by 4 to get the bytes exact number
if (((T_HOBFILE_FACES_HEADER *)(memFile if (((T_HOBFILE_FACES_HEADER *)(memFile
+ hob_struct->objects[i].face_groups[j].face_block_offset + hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) * k + sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->headerSeparator != 0) { + facesExtraOffset))->headerSeparator != 0) {
@ -157,48 +176,48 @@ unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct) {
} }
// Get materials index // Get materials index
hob_struct->objects[i].face_groups[j].faces[k].material_index = ((T_HOBFILE_FACES_HEADER *)(memFile hob_struct->objects[i].object_parts[j].faces[k].material_index = ((T_HOBFILE_FACES_HEADER *)(memFile
+ hob_struct->objects[i].face_groups[j].face_block_offset + hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) * k + sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->materialIndex; + facesExtraOffset))->materialIndex;
// Get vertex indices // Get vertex indices
memcpy(hob_struct->objects[i].face_groups[j].faces[k].indices, memcpy(hob_struct->objects[i].object_parts[j].faces[k].indices,
((T_HOBFILE_FACES_HEADER *)(memFile ((T_HOBFILE_FACES_HEADER *)(memFile
+ hob_struct->objects[i].face_groups[j].face_block_offset + hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) * k + sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->vertexIndices, + facesExtraOffset))->vertexIndices,
sizeof(unsigned short) * 4); sizeof(unsigned short) * 4);
// Recalculate the dynamic extra bytes offset size - if present // Recalculate the dynamic extra bytes offset size - if present
if (hob_struct->objects[i].face_groups[j].faces[k].flags_bits.fHasExtraBytesBeforeColor) facesExtraOffset += 8; if (hob_struct->objects[i].object_parts[j].faces[k].flags_bits.fHasExtraBytesBeforeColor) facesExtraOffset += 8;
// Get vertex color - if present // Get vertex color - if present
if (hob_struct->objects[i].face_groups[j].faces[k].flags_bits.fHasColor) { if (hob_struct->objects[i].object_parts[j].faces[k].flags_bits.fHasColor) {
if (hob_struct->objects[i].face_groups[j].faces[k].flags_bits.fSeparateColorVertex) { if (hob_struct->objects[i].object_parts[j].faces[k].flags_bits.fSeparateColorVertex) {
hob_struct->objects[i].face_groups[j].faces[k].vertex_colors[0] = ((T_HOBFILE_FACES_VERTEX_COLOR *)(memFile hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[0] = ((T_HOBFILE_FACES_VERTEX_COLOR *)(memFile
+ hob_struct->objects[i].face_groups[j].face_block_offset + hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) + sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k + sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->v1_rgba; + facesExtraOffset))->v1_rgba;
hob_struct->objects[i].face_groups[j].faces[k].vertex_colors[1] = ((T_HOBFILE_FACES_VERTEX_COLOR *)(memFile hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[1] = ((T_HOBFILE_FACES_VERTEX_COLOR *)(memFile
+ hob_struct->objects[i].face_groups[j].face_block_offset + hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) + sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k + sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->v2_rgba; + facesExtraOffset))->v2_rgba;
hob_struct->objects[i].face_groups[j].faces[k].vertex_colors[2] = ((T_HOBFILE_FACES_VERTEX_COLOR *)(memFile hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[2] = ((T_HOBFILE_FACES_VERTEX_COLOR *)(memFile
+ hob_struct->objects[i].face_groups[j].face_block_offset + hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) + sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k + sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->v3_rgba; + facesExtraOffset))->v3_rgba;
if (hob_struct->objects[i].face_groups[j].faces[k].flags_bits.fIsQuad) { if (hob_struct->objects[i].object_parts[j].faces[k].flags_bits.fIsQuad) {
hob_struct->objects[i].face_groups[j].faces[k].vertex_colors[3] = ((T_HOBFILE_FACES_VERTEX_COLOR *)(memFile hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[3] = ((T_HOBFILE_FACES_VERTEX_COLOR *)(memFile
+ hob_struct->objects[i].face_groups[j].face_block_offset + hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) + sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k + sizeof(T_HOBFILE_FACES_HEADER) * k
@ -208,26 +227,26 @@ unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct) {
facesExtraOffset += sizeof(T_HOBFILE_FACES_VERTEX_COLOR) - sizeof(T_RGBA); facesExtraOffset += sizeof(T_HOBFILE_FACES_VERTEX_COLOR) - sizeof(T_RGBA);
} }
} else { } else {
hob_struct->objects[i].face_groups[j].faces[k].vertex_colors[0] = ((T_HOBFILE_FACES_COLOR *)(memFile hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[0] = ((T_HOBFILE_FACES_COLOR *)(memFile
+ hob_struct->objects[i].face_groups[j].face_block_offset + hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) + sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k + sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->rgba; + facesExtraOffset))->rgba;
hob_struct->objects[i].face_groups[j].faces[k].vertex_colors[1] = ((T_HOBFILE_FACES_COLOR *)(memFile hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[1] = ((T_HOBFILE_FACES_COLOR *)(memFile
+ hob_struct->objects[i].face_groups[j].face_block_offset + hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) + sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k + sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->rgba; + facesExtraOffset))->rgba;
hob_struct->objects[i].face_groups[j].faces[k].vertex_colors[2] = ((T_HOBFILE_FACES_COLOR *)(memFile hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[2] = ((T_HOBFILE_FACES_COLOR *)(memFile
+ hob_struct->objects[i].face_groups[j].face_block_offset + hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) + sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k + sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->rgba; + facesExtraOffset))->rgba;
hob_struct->objects[i].face_groups[j].faces[k].vertex_colors[3] = ((T_HOBFILE_FACES_COLOR *)(memFile hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[3] = ((T_HOBFILE_FACES_COLOR *)(memFile
+ hob_struct->objects[i].face_groups[j].face_block_offset + hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) + sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k + sizeof(T_HOBFILE_FACES_HEADER) * k
@ -237,28 +256,28 @@ unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct) {
} }
// Get UV map - if present // Get UV map - if present
if (hob_struct->objects[i].face_groups[j].faces[k].flags_bits.fHasTexture) { if (hob_struct->objects[i].object_parts[j].faces[k].flags_bits.fHasTexture) {
hob_struct->objects[i].face_groups[j].faces[k].tex_coords[0] = ((T_HOBFILE_FACES_VERTEX_TEXTURE *)(memFile hob_struct->objects[i].object_parts[j].faces[k].tex_coords[0] = ((T_HOBFILE_FACES_VERTEX_TEXTURE *)(memFile
+ hob_struct->objects[i].face_groups[j].face_block_offset + hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) + sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k + sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->v1_texcoord; + facesExtraOffset))->v1_texcoord;
hob_struct->objects[i].face_groups[j].faces[k].tex_coords[1] = ((T_HOBFILE_FACES_VERTEX_TEXTURE *)(memFile hob_struct->objects[i].object_parts[j].faces[k].tex_coords[1] = ((T_HOBFILE_FACES_VERTEX_TEXTURE *)(memFile
+ hob_struct->objects[i].face_groups[j].face_block_offset + hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) + sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k + sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->v2_texcoord; + facesExtraOffset))->v2_texcoord;
hob_struct->objects[i].face_groups[j].faces[k].tex_coords[2] = ((T_HOBFILE_FACES_VERTEX_TEXTURE *)(memFile hob_struct->objects[i].object_parts[j].faces[k].tex_coords[2] = ((T_HOBFILE_FACES_VERTEX_TEXTURE *)(memFile
+ hob_struct->objects[i].face_groups[j].face_block_offset + hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) + sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k + sizeof(T_HOBFILE_FACES_HEADER) * k
+ facesExtraOffset))->v3_texcoord; + facesExtraOffset))->v3_texcoord;
if (hob_struct->objects[i].face_groups[j].faces[k].flags_bits.fIsQuad) { if (hob_struct->objects[i].object_parts[j].faces[k].flags_bits.fIsQuad) {
hob_struct->objects[i].face_groups[j].faces[k].tex_coords[3] = ((T_HOBFILE_FACES_VERTEX_TEXTURE *)(memFile hob_struct->objects[i].object_parts[j].faces[k].tex_coords[3] = ((T_HOBFILE_FACES_VERTEX_TEXTURE *)(memFile
+ hob_struct->objects[i].face_groups[j].face_block_offset + hob_struct->objects[i].object_parts[j].face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) + sizeof(T_HOBFILE_FACES_HEADER)
+ sizeof(T_HOBFILE_FACES_HEADER) * k + sizeof(T_HOBFILE_FACES_HEADER) * k
@ -271,78 +290,78 @@ unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct) {
if (_options & VERBOSE_ENABLED) { if (_options & VERBOSE_ENABLED) {
printf("[DBG] > Face %d details: 0x%X, %d, %d, %d, %d\n", k, printf("[DBG] > Face %d details: 0x%X, %d, %d, %d, %d\n", k,
hob_struct->objects[i].face_groups[j].faces[k].flags, hob_struct->objects[i].object_parts[j].faces[k].flags,
hob_struct->objects[i].face_groups[j].faces[k].b1, hob_struct->objects[i].object_parts[j].faces[k].b1,
hob_struct->objects[i].face_groups[j].faces[k].b2, hob_struct->objects[i].object_parts[j].faces[k].b2,
hob_struct->objects[i].face_groups[j].faces[k].b3, hob_struct->objects[i].object_parts[j].faces[k].b3,
hob_struct->objects[i].face_groups[j].faces[k].bsize hob_struct->objects[i].object_parts[j].faces[k].bsize
); );
printf("[DBG] - Type is Quad: %d\n", hob_struct->objects[i].face_groups[j].faces[k].flags_bits.fIsQuad); 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].face_groups[j].faces[k].material_index); 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", printf("[DBG] - Vertex indices: %d, %d, %d, %d\n",
hob_struct->objects[i].face_groups[j].faces[k].indices[0], hob_struct->objects[i].object_parts[j].faces[k].indices[0],
hob_struct->objects[i].face_groups[j].faces[k].indices[1], hob_struct->objects[i].object_parts[j].faces[k].indices[1],
hob_struct->objects[i].face_groups[j].faces[k].indices[2], hob_struct->objects[i].object_parts[j].faces[k].indices[2],
hob_struct->objects[i].face_groups[j].faces[k].indices[3] hob_struct->objects[i].object_parts[j].faces[k].indices[3]
); );
printf("[DBG] - Vertex colors: 0x%X, 0x%X, 0x%X, 0x%X\n", printf("[DBG] - Vertex colors: 0x%X, 0x%X, 0x%X, 0x%X\n",
hob_struct->objects[i].face_groups[j].faces[k].vertex_colors[0], hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[0],
hob_struct->objects[i].face_groups[j].faces[k].vertex_colors[1], hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[1],
hob_struct->objects[i].face_groups[j].faces[k].vertex_colors[2], hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[2],
hob_struct->objects[i].face_groups[j].faces[k].vertex_colors[3] hob_struct->objects[i].object_parts[j].faces[k].vertex_colors[3]
); );
printf("[DBG] - Vertex UV coord (divided by 4096):\n"); printf("[DBG] - Vertex UV coord (divided by 4096):\n");
printf("[DBG] > %.8f(%d), %.8f(%d)\n", printf("[DBG] > %.8f(%d), %.8f(%d)\n",
((double) 1/4096) * hob_struct->objects[i].face_groups[j].faces[k].tex_coords[0].u, ((double) 1/4096) * hob_struct->objects[i].object_parts[j].faces[k].tex_coords[0].u,
hob_struct->objects[i].face_groups[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].face_groups[j].faces[k].tex_coords[0].v, ((double) 1/4096) * hob_struct->objects[i].object_parts[j].faces[k].tex_coords[0].v,
hob_struct->objects[i].face_groups[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", printf("[DBG] > %.8f(%d), %.8f(%d)\n",
((double) 1/4096) * hob_struct->objects[i].face_groups[j].faces[k].tex_coords[1].u, ((double) 1/4096) * hob_struct->objects[i].object_parts[j].faces[k].tex_coords[1].u,
hob_struct->objects[i].face_groups[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].face_groups[j].faces[k].tex_coords[1].v, ((double) 1/4096) * hob_struct->objects[i].object_parts[j].faces[k].tex_coords[1].v,
hob_struct->objects[i].face_groups[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", printf("[DBG] > %.8f(%d), %.8f(%d)\n",
((double) 1/4096) * hob_struct->objects[i].face_groups[j].faces[k].tex_coords[2].u, ((double) 1/4096) * hob_struct->objects[i].object_parts[j].faces[k].tex_coords[2].u,
hob_struct->objects[i].face_groups[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].face_groups[j].faces[k].tex_coords[2].v, ((double) 1/4096) * hob_struct->objects[i].object_parts[j].faces[k].tex_coords[2].v,
hob_struct->objects[i].face_groups[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", printf("[DBG] > %.8f(%d), %.8f(%d)\n",
((double) 1/4096) * hob_struct->objects[i].face_groups[j].faces[k].tex_coords[3].u, ((double) 1/4096) * hob_struct->objects[i].object_parts[j].faces[k].tex_coords[3].u,
hob_struct->objects[i].face_groups[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].face_groups[j].faces[k].tex_coords[3].v, ((double) 1/4096) * hob_struct->objects[i].object_parts[j].faces[k].tex_coords[3].v,
hob_struct->objects[i].face_groups[j].faces[k].tex_coords[3].v hob_struct->objects[i].object_parts[j].faces[k].tex_coords[3].v
); );
printf("\n"); printf("\n");
} }
} }
// Get vertex datas // Get vertex datas
hob_struct->objects[i].face_groups[j].vertices = calloc(hob_struct->objects[i].face_groups[j].vertex_count, sizeof(T_VERTEX)); 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].face_groups[j].vertex_count; k++ ) { for ( k = 0; k < hob_struct->objects[i].object_parts[j].vertex_count; k++ ) {
hob_struct->objects[i].face_groups[j].vertices[k].x = ((T_HOBFILE_VERTEX *)(memFile hob_struct->objects[i].object_parts[j].vertices[k].x = ((T_HOBFILE_VERTEX *)(memFile
+ hob_struct->objects[i].face_groups[j].vertex_block_offset + hob_struct->objects[i].object_parts[j].vertex_block_offset
+ sizeof(T_VERTEX) * k))->x; + sizeof(T_VERTEX) * k))->x;
hob_struct->objects[i].face_groups[j].vertices[k].y = ((T_HOBFILE_VERTEX *)(memFile hob_struct->objects[i].object_parts[j].vertices[k].y = ((T_HOBFILE_VERTEX *)(memFile
+ hob_struct->objects[i].face_groups[j].vertex_block_offset + hob_struct->objects[i].object_parts[j].vertex_block_offset
+ sizeof(T_VERTEX) * k))->y; + sizeof(T_VERTEX) * k))->y;
hob_struct->objects[i].face_groups[j].vertices[k].z = ((T_HOBFILE_VERTEX *)(memFile hob_struct->objects[i].object_parts[j].vertices[k].z = ((T_HOBFILE_VERTEX *)(memFile
+ hob_struct->objects[i].face_groups[j].vertex_block_offset + hob_struct->objects[i].object_parts[j].vertex_block_offset
+ sizeof(T_VERTEX) * k))->z; + sizeof(T_VERTEX) * k))->z;
hob_struct->objects[i].face_groups[j].vertices[k].w = ((T_HOBFILE_VERTEX *)(memFile hob_struct->objects[i].object_parts[j].vertices[k].w = ((T_HOBFILE_VERTEX *)(memFile
+ hob_struct->objects[i].face_groups[j].vertex_block_offset + hob_struct->objects[i].object_parts[j].vertex_block_offset
+ sizeof(T_VERTEX) * k))->w; // Always 0??? + sizeof(T_VERTEX) * k))->w; // Always 0???
if (_options & VERBOSE_ENABLED) printf("[DBG] > Found vertex %d: (%d, %d, %d)\n", k, if (_options & VERBOSE_ENABLED) printf("[DBG] > Found vertex %d: (%d, %d, %d)\n", k,
hob_struct->objects[i].face_groups[j].vertices[k].x, hob_struct->objects[i].object_parts[j].vertices[k].x,
hob_struct->objects[i].face_groups[j].vertices[k].y, hob_struct->objects[i].object_parts[j].vertices[k].y,
hob_struct->objects[i].face_groups[j].vertices[k].z hob_struct->objects[i].object_parts[j].vertices[k].z
); );
} }
} }

View File

@ -22,6 +22,8 @@
typedef unsigned int T_RGBA; typedef unsigned int T_RGBA;
typedef struct vector3 { float x,y,z; } T_VECTOR3;
typedef struct vertex { short x,y,z,w; } T_VERTEX; typedef struct vertex { short x,y,z,w; } T_VERTEX;
typedef struct tex_coord { unsigned short u,v; } T_TEXCOORD; typedef struct tex_coord { unsigned short u,v; } T_TEXCOORD;
@ -64,6 +66,9 @@ typedef struct hob_face_group {
unsigned int face_block_offset; unsigned int face_block_offset;
unsigned int vertex_block_offset; unsigned int vertex_block_offset;
unsigned int id;
T_VECTOR3 transform;
unsigned int face_count; unsigned int face_count;
T_HOB_FACE* faces; T_HOB_FACE* faces;
@ -74,13 +79,13 @@ typedef struct hob_face_group {
typedef struct hob_object { typedef struct hob_object {
char name[16]; char name[16];
unsigned int face_group_offset; unsigned int face_group_offset;
unsigned int face_group_header_offset; unsigned int object_part_header_offset;
unsigned int face_group_header2_offset; unsigned int face_group_header2_offset;
unsigned int face_group_count; unsigned int face_group_count;
unsigned int face_group_count0; unsigned int face_group_count0;
T_HOB_FACE_GROUP* face_groups; T_HOB_FACE_GROUP* object_parts;
} T_HOB_OBJECT; } T_HOB_OBJECT;
/** /**
@ -147,45 +152,53 @@ typedef struct __attribute__((packed)) hobfile_facegroup_offset {
unsigned int facegroup_offset; unsigned int facegroup_offset;
} T_HOBFILE_FACEGROUP_OFFSET; } T_HOBFILE_FACEGROUP_OFFSET;
typedef struct __attribute__((packed)) hobfile_meshdef0_0 { typedef struct __attribute__((packed)) hobfile_meshdef0 {
unsigned int next_meshdef0_offset; unsigned int next_meshdef0_offset;
unsigned int prev_meshdef0_offset_unsure; unsigned int unknown1;
unsigned int offset_beginning_if_not_first; unsigned int unknown2;
unsigned int offset_end_if_next_equal_0; unsigned int prev_meshdef0_offset;
unsigned int meshdef1_offset_plus_4; unsigned int meshdef1_offset_plus_4;
unsigned int reserved1; // 8B of zeros unsigned int reserved1; // 8B of zeros
unsigned int reserved2; unsigned int reserved2;
} T_HOBFILE_MESHDEF0_0;
typedef struct __attribute__((packed)) hobfile_meshdef0_1 {
float unknown1;
unsigned int reserved1; // 12B of zeros
unsigned int reserved2;
unsigned int reserved3;
} T_HOBFILE_MESHDEF0_1;
typedef struct __attribute__((packed)) hobfile_meshdef0_2 {
unsigned int Unknown1;
float unknown2; // Can be a vector???
float unknown3; float unknown3;
unsigned int reserved3; // 12B of zeros
unsigned int reserved4;
unsigned int reserved5;
float unknown4; float unknown4;
float unknown5; // Can be a vector??? unsigned int reserved6; // 12B of zeros
float unknown6; unsigned int reserved7;
float unknown7; unsigned int reserved8;
float unknown8; // Can be a matrix??? float unknown5;
float unknown9;
float unknown10; unsigned int reserved9; // 12B of zeros
float unknown11; unsigned int reserved10;
unsigned int reserved11;
unsigned int object_id;
float unknown12; // Can be a vector??? float unknown12; // Can be a vector???
float unknown13; float unknown13;
float unknown14; float unknown14;
} T_HOBFILE_MESHDEF0_2;
float unknown15; // Can be a vector???
float unknown16;
float unknown17;
float unknown18; // Can be a matrix???
float unknown19;
float unknown20;
float unknown21;
float transform_x;
float transform_y;
float transform_z;
} T_HOBFILE_MESHDEF0;
typedef struct __attribute__((packed)) hobfile_meshdef1 { typedef struct __attribute__((packed)) hobfile_meshdef1 {
unsigned int facedef_end_offset; unsigned int facedef_end_offset;

View File

@ -15,12 +15,15 @@
#include "obj_exporter.h" #include "obj_exporter.h"
static void mtlPathPatch(const char* out_file, const char* obj_name) ;
unsigned char exportOBJModel(T_HOB_OBJECT* hob_objects, const char *out_path) { unsigned char exportOBJModel(T_HOB_OBJECT* hob_objects, const char *out_path) {
char objExport_path[128]; char objExport_path[128];
char mtlExport_path[128]; char mtlExport_path[128];
obj* objConstruct = NULL; obj* objConstruct = NULL;
unsigned int i,j; unsigned int i,j;
int surfID = 0, materialID = 0, tmpVertex = 0, tmpIndex = 0; int surfID = 0, materialID = 0, tmpVertex = 0, tmpIndex = 0;
int indexOffset = 0; // Used to compensate reset of indices between face group
float vertexBuff[3] = {0}, textureBuff[2] = {0}; float vertexBuff[3] = {0}, textureBuff[2] = {0};
int indicesBuff[3] = {0}; int indicesBuff[3] = {0};
@ -39,8 +42,8 @@ unsigned char exportOBJModel(T_HOB_OBJECT* hob_objects, const char *out_path) {
strcpy(objExport_path, hob_objects->name); strcpy(objExport_path, hob_objects->name);
} }
strcpy(mtlExport_path, objExport_path); strcpy(mtlExport_path, objExport_path);
strcat(objExport_path, ".obj"); strcat(objExport_path, ".obj\0");
strcat(mtlExport_path, ".mtl"); strcat(mtlExport_path, ".mtl\0");
objConstruct = obj_create(NULL); objConstruct = obj_create(NULL);
@ -50,45 +53,108 @@ unsigned char exportOBJModel(T_HOB_OBJECT* hob_objects, const char *out_path) {
materialID = obj_add_mtrl(objConstruct); materialID = obj_add_mtrl(objConstruct);
// Build vertex container // Build vertex container
for ( j = 0; j < hob_objects->face_groups[i].vertex_count; j++ ) { for ( j = 0; j < hob_objects->object_parts[i].vertex_count; j++ ) {
tmpVertex = obj_add_vert(objConstruct); tmpVertex = obj_add_vert(objConstruct);
vertexBuff[0] = ((float)1/1024) * -hob_objects->face_groups[i].vertices[j].x; // Invert X to fix mirror display vertexBuff[0] = ((float)1/1024) * -hob_objects->object_parts[i].vertices[j].x; // Invert X to fix mirror display
vertexBuff[1] = ((float)1/1024) * -hob_objects->face_groups[i].vertices[j].y; // Invert Y to render upside up vertexBuff[1] = ((float)1/1024) * -hob_objects->object_parts[i].vertices[j].y; // Invert Y to render upside up
vertexBuff[2] = ((float)1/1024) * hob_objects->face_groups[i].vertices[j].z; vertexBuff[2] = ((float)1/1024) * hob_objects->object_parts[i].vertices[j].z;
obj_set_vert_v(objConstruct, tmpVertex, vertexBuff); obj_set_vert_v(objConstruct, tmpVertex, vertexBuff);
//textureBuff[0] = ((float)1/1) * hob_objects->face_groups[i].
//obj_set_vert_t(objConstruct, tmpVertex, textureBuff);
} }
// Build indices container // Build indices container and UV mapping
for ( j = 0; j < hob_objects->face_groups[i].face_count; j++ ) { for ( j = 0; j < hob_objects->object_parts[i].face_count; j++ ) {
tmpIndex = obj_add_poly(objConstruct, surfID); tmpIndex = obj_add_poly(objConstruct, surfID);
indicesBuff[0] = (int)hob_objects->face_groups[i].faces[j].indices[0]; indicesBuff[0] = indexOffset + (int)hob_objects->object_parts[i].faces[j].indices[0];
indicesBuff[1] = (int)hob_objects->face_groups[i].faces[j].indices[1]; indicesBuff[1] = indexOffset + (int)hob_objects->object_parts[i].faces[j].indices[1];
indicesBuff[2] = (int)hob_objects->face_groups[i].faces[j].indices[2]; indicesBuff[2] = indexOffset + (int)hob_objects->object_parts[i].faces[j].indices[2];
obj_set_poly(objConstruct, surfID, tmpIndex, indicesBuff); obj_set_poly(objConstruct, surfID, tmpIndex, indicesBuff);
if (hob_objects->object_parts[i].faces[j].flags_bits.fHasTexture) {
textureBuff[0] = ((float)1/4096) * hob_objects->object_parts[i].faces[j].tex_coords[0].u;
textureBuff[1] = ((float)1/4096) * hob_objects->object_parts[i].faces[j].tex_coords[0].v;
obj_set_vert_t(objConstruct, indexOffset + (int)hob_objects->object_parts[i].faces[j].indices[0], textureBuff);
textureBuff[0] = ((float)1/4096) * hob_objects->object_parts[i].faces[j].tex_coords[1].u;
textureBuff[1] = ((float)1/4096) * hob_objects->object_parts[i].faces[j].tex_coords[1].v;
obj_set_vert_t(objConstruct, indexOffset + (int)hob_objects->object_parts[i].faces[j].indices[1], textureBuff);
textureBuff[0] = ((float)1/4096) * hob_objects->object_parts[i].faces[j].tex_coords[2].u;
textureBuff[1] = ((float)1/4096) * hob_objects->object_parts[i].faces[j].tex_coords[2].v;
obj_set_vert_t(objConstruct, indexOffset + (int)hob_objects->object_parts[i].faces[j].indices[2], textureBuff);
}
// Process 2 triangles if face is Quad // Process 2 triangles if face is Quad
if (hob_objects->face_groups[i].faces[j].flags_bits.fIsQuad) { if (hob_objects->object_parts[i].faces[j].flags_bits.fIsQuad) {
tmpIndex = obj_add_poly(objConstruct, surfID); tmpIndex = obj_add_poly(objConstruct, surfID);
indicesBuff[0] = (int)hob_objects->face_groups[i].faces[j].indices[0]; indicesBuff[0] = indexOffset + (int)hob_objects->object_parts[i].faces[j].indices[0];
indicesBuff[1] = (int)hob_objects->face_groups[i].faces[j].indices[2]; indicesBuff[1] = indexOffset + (int)hob_objects->object_parts[i].faces[j].indices[2];
indicesBuff[2] = (int)hob_objects->face_groups[i].faces[j].indices[3]; indicesBuff[2] = indexOffset + (int)hob_objects->object_parts[i].faces[j].indices[3];
obj_set_poly(objConstruct, surfID, tmpIndex, indicesBuff); obj_set_poly(objConstruct, surfID, tmpIndex, indicesBuff);
if (hob_objects->object_parts[i].faces[j].flags_bits.fHasTexture) {
textureBuff[0] = ((float)1/4096) * hob_objects->object_parts[i].faces[j].tex_coords[3].u;
textureBuff[1] = ((float)1/4096) * hob_objects->object_parts[i].faces[j].tex_coords[3].v;
obj_set_vert_t(objConstruct, indexOffset + (int)hob_objects->object_parts[i].faces[j].indices[3], textureBuff);
}
} }
} }
indexOffset = obj_num_vert(objConstruct);
} }
obj_write(objConstruct, objExport_path, NULL, 8); if (_options & EXPORT_MTL) {
obj_write(objConstruct, objExport_path, mtlExport_path, 8);
if (_options & OUTPUT_DIR) mtlPathPatch(objExport_path, hob_objects->name);
} else obj_write(objConstruct, objExport_path, NULL, 8);
obj_delete(objConstruct); obj_delete(objConstruct);
return NO_ERROR; return NO_ERROR;
} }
static void mtlPathPatch(const char* out_file, const char* obj_name) {
FILE* obj = NULL;
char* memFile = NULL;
long fileSize,i,pos = 0,lines;
char _path[128],b;
obj = fopen(out_file, "r");
if ( obj != NULL ) {
fseek(obj, 0, SEEK_END);
fileSize = ftell(obj);
fseek(obj, 0, SEEK_SET);
// Find the end of first line
for ( i = 0; i < fileSize + 1; i++) {
b = (char)fgetc(obj);
if (b == '\n') {
if (pos == 0) pos = i;
lines++;
}
}
// Prepare mtl path for output
strcpy(_path, obj_name);
strcat(_path, ".mtl");
memFile = malloc(fileSize - (pos + lines));
if ( memFile != NULL ) {
// Read the rest of file in memory
fseek(obj, pos, SEEK_SET);
fread(memFile, fileSize - (pos + lines), 1, obj);
fclose(obj);
// Begin rewrite file
obj = fopen(out_file, "w");
fprintf(obj, "mtllib %s", _path);
fwrite(memFile, fileSize - (pos + lines), 1, obj);
free(memFile);
}
fclose(obj);
}
}

View File

@ -2,7 +2,8 @@
#define OPTIONS_H_ #define OPTIONS_H_
#define VERBOSE_ENABLED 0x0001 #define VERBOSE_ENABLED 0x0001
#define OUTPUT_DIR 0x0002 #define OUTPUT_DIR 0x0002
#define EXPORT_MTL 0x0004
extern int _options; extern int _options;