diff --git a/src/Model-Extractor.c b/src/Model-Extractor.c index 76b4aa7..078e2ab 100644 --- a/src/Model-Extractor.c +++ b/src/Model-Extractor.c @@ -150,11 +150,11 @@ static void cleanUpMemory(T_HOB* hobStruct) { for ( i=0; iobj_count; i++ ) { for ( j=0; jobjects[i].face_group_count; j++ ) { - free(hobStruct->objects[i].face_groups[j].faces); - free(hobStruct->objects[i].face_groups[j].vertices); + free(hobStruct->objects[i].object_parts[j].faces); + free(hobStruct->objects[i].object_parts[j].vertices); } - free(hobStruct->objects[i].face_groups); + free(hobStruct->objects[i].object_parts); } free(hobStruct->objects); diff --git a/src/hob_parser.c b/src/hob_parser.c index aaf1254..0108257 100644 --- a/src/hob_parser.c +++ b/src/hob_parser.c @@ -60,10 +60,10 @@ unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct) { + sizeof(T_HOBFILE_HEADER) + 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); - 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_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 + sizeof(T_HOBFILE_HEADER) + 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 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); 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 (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 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++ ) { - 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_OFFSET) * j))->facegroup_offset; if (_options & VERBOSE_ENABLED) printf("\n[DBG] > Face group meshdef0 offset: 0x%X\n", offset_index[j]); - // Get meshdef1 (mesh descriptor) offset - hob_struct->objects[i].face_groups[j].meshdef1_offset = ((T_HOBFILE_MESHDEF0_0 *)(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].face_groups[j].meshdef1_offset); + // Get meshdef0 datas + if (_options & VERBOSE_ENABLED) printf("\n[DBG] > Next meshdef0 offset: 0x%X",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->next_meshdef0_offset); + if (_options & VERBOSE_ENABLED) printf("\n[DBG] > Prev meshdef0 offset: 0x%X",((T_HOBFILE_MESHDEF0 *)(memFile + offset_index[j]))->prev_meshdef0_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 - hob_struct->objects[i].face_groups[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].face_groups[j].vertex_count = ((T_HOBFILE_MESHDEF1 *)(memFile - + hob_struct->objects[i].face_groups[j].meshdef1_offset - 4))->vertex_count; - hob_struct->objects[i].face_groups[j].face_block_offset = ((T_HOBFILE_MESHDEF1 *)(memFile - + hob_struct->objects[i].face_groups[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); - hob_struct->objects[i].face_groups[j].vertex_block_offset = ((T_HOBFILE_MESHDEF1 *)(memFile - + hob_struct->objects[i].face_groups[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); + 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 (_options & VERBOSE_ENABLED) 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 (_options & VERBOSE_ENABLED) 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].face_groups[j].face_block_offset))->reserved1 != 0 || - ((T_HOBFILE_FACEBLOCK *)(memFile + hob_struct->objects[i].face_groups[j].face_block_offset))->reserved2 != 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].object_parts[j].face_block_offset))->reserved2 != 0 ) { 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 != - hob_struct->objects[i].face_groups[j].face_block_offset + sizeof(T_HOBFILE_FACEBLOCK)) { + 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 (_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].face_groups[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].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].face_groups[j].face_count; k++ ) { + for ( k = 0; k < hob_struct->objects[i].object_parts[j].face_count; k++ ) { // Get flags - hob_struct->objects[i].face_groups[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].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].face_groups[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].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].face_groups[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].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].face_groups[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].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].face_groups[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].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].face_groups[j].face_block_offset + + hob_struct->objects[i].object_parts[j].face_block_offset + sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACES_HEADER) * k + facesExtraOffset))->headerSeparator != 0) { @@ -157,48 +176,48 @@ unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct) { } // Get materials index - hob_struct->objects[i].face_groups[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].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].face_groups[j].faces[k].indices, + memcpy(hob_struct->objects[i].object_parts[j].faces[k].indices, ((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_FACES_HEADER) * k + facesExtraOffset))->vertexIndices, sizeof(unsigned short) * 4); // 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 - if (hob_struct->objects[i].face_groups[j].faces[k].flags_bits.fHasColor) { - if (hob_struct->objects[i].face_groups[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].face_groups[j].face_block_offset + 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].face_groups[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].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].face_groups[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].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].face_groups[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].face_groups[j].face_block_offset + 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 @@ -208,26 +227,26 @@ unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct) { facesExtraOffset += sizeof(T_HOBFILE_FACES_VERTEX_COLOR) - sizeof(T_RGBA); } } else { - hob_struct->objects[i].face_groups[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].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].face_groups[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].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].face_groups[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].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].face_groups[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].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 @@ -237,28 +256,28 @@ unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct) { } // Get UV map - if present - if (hob_struct->objects[i].face_groups[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].face_groups[j].face_block_offset + 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].face_groups[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].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].face_groups[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].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].face_groups[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].face_groups[j].face_block_offset + 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 @@ -271,78 +290,78 @@ unsigned char parseHOBFile(const char* fileName, T_HOB* hob_struct) { if (_options & VERBOSE_ENABLED) { 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].face_groups[j].faces[k].b1, - hob_struct->objects[i].face_groups[j].faces[k].b2, - hob_struct->objects[i].face_groups[j].faces[k].b3, - hob_struct->objects[i].face_groups[j].faces[k].bsize + 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].face_groups[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] - 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].face_groups[j].faces[k].indices[0], - hob_struct->objects[i].face_groups[j].faces[k].indices[1], - hob_struct->objects[i].face_groups[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[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].face_groups[j].faces[k].vertex_colors[0], - hob_struct->objects[i].face_groups[j].faces[k].vertex_colors[1], - hob_struct->objects[i].face_groups[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[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].face_groups[j].faces[k].tex_coords[0].u, - hob_struct->objects[i].face_groups[j].faces[k].tex_coords[0].u, - ((double) 1/4096) * hob_struct->objects[i].face_groups[j].faces[k].tex_coords[0].v, - 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].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].face_groups[j].faces[k].tex_coords[1].u, - hob_struct->objects[i].face_groups[j].faces[k].tex_coords[1].u, - ((double) 1/4096) * hob_struct->objects[i].face_groups[j].faces[k].tex_coords[1].v, - 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].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].face_groups[j].faces[k].tex_coords[2].u, - hob_struct->objects[i].face_groups[j].faces[k].tex_coords[2].u, - ((double) 1/4096) * hob_struct->objects[i].face_groups[j].faces[k].tex_coords[2].v, - 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].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].face_groups[j].faces[k].tex_coords[3].u, - hob_struct->objects[i].face_groups[j].faces[k].tex_coords[3].u, - ((double) 1/4096) * hob_struct->objects[i].face_groups[j].faces[k].tex_coords[3].v, - 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].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"); } } // Get vertex datas - hob_struct->objects[i].face_groups[j].vertices = calloc(hob_struct->objects[i].face_groups[j].vertex_count, sizeof(T_VERTEX)); - for ( k = 0; k < hob_struct->objects[i].face_groups[j].vertex_count; k++ ) { - hob_struct->objects[i].face_groups[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].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].face_groups[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].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].face_groups[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].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].face_groups[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].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 (_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].face_groups[j].vertices[k].y, - hob_struct->objects[i].face_groups[j].vertices[k].z + 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 ); } } diff --git a/src/hob_struct.h b/src/hob_struct.h index 55b1697..c3bc733 100644 --- a/src/hob_struct.h +++ b/src/hob_struct.h @@ -22,6 +22,8 @@ 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 tex_coord { unsigned short u,v; } T_TEXCOORD; @@ -64,6 +66,9 @@ typedef struct hob_face_group { unsigned int face_block_offset; unsigned int vertex_block_offset; + unsigned int id; + T_VECTOR3 transform; + unsigned int face_count; T_HOB_FACE* faces; @@ -74,13 +79,13 @@ typedef struct hob_face_group { typedef struct hob_object { char name[16]; 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_count; unsigned int face_group_count0; - T_HOB_FACE_GROUP* face_groups; + T_HOB_FACE_GROUP* object_parts; } T_HOB_OBJECT; /** @@ -147,45 +152,53 @@ typedef struct __attribute__((packed)) hobfile_facegroup_offset { unsigned int 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 prev_meshdef0_offset_unsure; - unsigned int offset_beginning_if_not_first; - unsigned int offset_end_if_next_equal_0; + unsigned int unknown1; + unsigned int unknown2; + unsigned int prev_meshdef0_offset; unsigned int meshdef1_offset_plus_4; unsigned int reserved1; // 8B of zeros 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; + + unsigned int reserved3; // 12B of zeros + unsigned int reserved4; + unsigned int reserved5; + float unknown4; - float unknown5; // Can be a vector??? - float unknown6; - float unknown7; + unsigned int reserved6; // 12B of zeros + unsigned int reserved7; + unsigned int reserved8; - float unknown8; // Can be a matrix??? - float unknown9; - float unknown10; - float unknown11; + float unknown5; + + unsigned int reserved9; // 12B of zeros + unsigned int reserved10; + unsigned int reserved11; + + unsigned int object_id; float unknown12; // Can be a vector??? float unknown13; 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 { unsigned int facedef_end_offset; diff --git a/src/obj_exporter.c b/src/obj_exporter.c index c5eb52b..6a88f6b 100644 --- a/src/obj_exporter.c +++ b/src/obj_exporter.c @@ -51,12 +51,12 @@ unsigned char exportOBJModel(T_HOB_OBJECT* hob_objects, const char *out_path) { materialID = obj_add_mtrl(objConstruct); // 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); - vertexBuff[0] = ((float)1/1024) * -hob_objects->face_groups[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[2] = ((float)1/1024) * hob_objects->face_groups[i].vertices[j].z; + 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->object_parts[i].vertices[j].y; // Invert Y to render upside up + vertexBuff[2] = ((float)1/1024) * hob_objects->object_parts[i].vertices[j].z; obj_set_vert_v(objConstruct, tmpVertex, vertexBuff); @@ -66,22 +66,22 @@ unsigned char exportOBJModel(T_HOB_OBJECT* hob_objects, const char *out_path) { } // Build indices container - 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); - indicesBuff[0] = indexOffset + (int)hob_objects->face_groups[i].faces[j].indices[0]; - indicesBuff[1] = indexOffset + (int)hob_objects->face_groups[i].faces[j].indices[1]; - indicesBuff[2] = indexOffset + (int)hob_objects->face_groups[i].faces[j].indices[2]; + indicesBuff[0] = indexOffset + (int)hob_objects->object_parts[i].faces[j].indices[0]; + indicesBuff[1] = indexOffset + (int)hob_objects->object_parts[i].faces[j].indices[1]; + indicesBuff[2] = indexOffset + (int)hob_objects->object_parts[i].faces[j].indices[2]; obj_set_poly(objConstruct, surfID, tmpIndex, indicesBuff); // 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); - indicesBuff[0] = indexOffset + (int)hob_objects->face_groups[i].faces[j].indices[0]; - indicesBuff[1] = indexOffset + (int)hob_objects->face_groups[i].faces[j].indices[2]; - indicesBuff[2] = indexOffset + (int)hob_objects->face_groups[i].faces[j].indices[3]; + indicesBuff[0] = indexOffset + (int)hob_objects->object_parts[i].faces[j].indices[0]; + indicesBuff[1] = indexOffset + (int)hob_objects->object_parts[i].faces[j].indices[2]; + indicesBuff[2] = indexOffset + (int)hob_objects->object_parts[i].faces[j].indices[3]; obj_set_poly(objConstruct, surfID, tmpIndex, indicesBuff); }