Deconstruct mega-parser in sub parts
All checks were successful
JCS-Prod/RSE-Model/pipeline/pr-master This commit looks good

This commit is contained in:
JackCarterSmith 2022-08-18 21:47:54 +02:00
parent 6d3beabb5e
commit be31c972c4
Signed by: JackCarterSmith
GPG Key ID: 832E52F4E23F8F24
4 changed files with 356 additions and 34 deletions

View File

@ -55,9 +55,9 @@ typedef struct hob_face {
unsigned short indices[4];
T_RGBA vertex_colors[4]; //TODO: convert in R:8_G:8_B:8_A:8 format? Caution with BE/LE conversion
T_TEXCOORD tex_coords[4];
} T_HOB_FACE;
} T_RSPMODEL_FACE;
typedef struct hob_face_group {
typedef struct rspmodel_obj_parts {
unsigned int meshdef1_offset;
unsigned int face_block_end_offset;
@ -68,11 +68,11 @@ typedef struct hob_face_group {
T_VECTOR3 transform;
unsigned int face_count;
T_HOB_FACE* faces;
T_RSPMODEL_FACE* faces;
unsigned int vertex_count;
T_VERTEX* vertices;
} T_HOB_FACE_GROUP;
} T_RSPMODEL_OBJ_PARTS;
typedef struct rspmodel_object {
char name[16];
@ -83,7 +83,7 @@ typedef struct rspmodel_object {
unsigned int object_part_count;
unsigned int face_group_count;
T_HOB_FACE_GROUP* object_parts;
T_RSPMODEL_OBJ_PARTS* object_parts;
} T_RSPMODEL_OBJECT;
/**

View File

@ -26,6 +26,8 @@ unsigned short RSPModel_processHOBFile( T_RSPMODEL_HOB* hob, const char* const f
T_PROG_OPTIONS canard;
canard.god_mode = 1;
canard.debug_mode = 1;
canard.verbose_mode = 1;
RSP_ModelLib_ParseHOBFile(filePath, hob, &canard);
return RSPLIB_SUCCESS;

View File

@ -17,14 +17,17 @@
#include "hob_parser.h"
static unsigned int ExtractObjects(T_RSPMODEL_HOB*, const MEMFILE, const unsigned char);
static unsigned int ExtractObjParts(T_RSPMODEL_OBJECT*, const MEMFILE, const unsigned char);
static unsigned int ExtractObjParts_faces(T_RSPMODEL_OBJ_PARTS*, const MEMFILE, const unsigned char);
static inline unsigned int ExtractObjpart_Face_Colors(T_RSPMODEL_FACE*, const char*);
static inline unsigned int ExtractObjpart_Face_UVMaps(T_RSPMODEL_FACE*, const char*);
unsigned char RSP_ModelLib_ParseHOBFile(const char* fileName, T_RSPMODEL_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;
MEMFILE memFile = NULL;
if (hob_struct != NULL && fileName != NULL) {
// Open file
@ -43,6 +46,11 @@ unsigned char RSP_ModelLib_ParseHOBFile(const char* fileName, T_RSPMODEL_HOB* ho
fread(memFile, fileSize, 1, fStream);
fclose(fStream);
// Do the magic!
ExtractObjects(hob_struct, memFile, p_opts->verbose_mode + p_opts->debug_mode + p_opts->god_mode);
/*
// 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);
@ -88,7 +96,8 @@ unsigned char RSP_ModelLib_ParseHOBFile(const char* fileName, T_RSPMODEL_HOB* ho
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");
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));
@ -354,30 +363,7 @@ unsigned char RSP_ModelLib_ParseHOBFile(const char* fileName, T_RSPMODEL_HOB* ho
}
// 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
);
}
ExtractObjpartVertices(&hob_struct->objects[i].object_parts[j], memFile, p_opts->debug_mode);
}
// Get object part ID, used by animation? bones?
@ -406,6 +392,7 @@ unsigned char RSP_ModelLib_ParseHOBFile(const char* fileName, T_RSPMODEL_HOB* ho
err = RSPLIB_ERROR_GENERIC;
printf("[INFO] Can't process empty file!\n");
}
*/
free(memFile);
@ -422,3 +409,334 @@ unsigned char RSP_ModelLib_ParseHOBFile(const char* fileName, T_RSPMODEL_HOB* ho
return err;
}
/**
* Count objects and extract datas from them.
*
* @param[in|out] pHobStruct Take root hob structure to get the T_RSPMODEL_OBJECT buffer and header datas.
* @param[in] pMemfile
* @param[in] verbose
*
* @return Error code, RSPLIB_SUCCESS when no error.
*/
static unsigned int ExtractObjects(T_RSPMODEL_HOB* pHobStruct, const MEMFILE pMemfile, const unsigned char verbose) {
unsigned int i;
if (pHobStruct == NULL || pMemfile == NULL) return RSPLIB_ERROR_ARGS_NULL;
// Retrieve object count from the header
pHobStruct->obj_count = ((T_HOBFILE_HEADER *)pMemfile)->obj_count;
printf("[INFO] - Object(s) quantity: %d\n", pHobStruct->obj_count);
if (pHobStruct->obj_count <= 0) {
printf("[INFO] Can't process empty file!\n");
return RSPLIB_ERROR_GENERIC;
}
// Populate HOB structure with object descriptor
pHobStruct->objects = calloc(pHobStruct->obj_count, sizeof(T_RSPMODEL_OBJECT));
if (pHobStruct->objects == NULL) return RSPLIB_ERROR_MEMORY;
for ( i = 0; i < pHobStruct->obj_count; i++ ) {
if (verbose == 2) printf("\n-=====================-Begin of Object part-======================-\n");
// Get object name
memcpy(pHobStruct->objects[i].name, ((T_HOBFILE_OBJ_DESCRIPTOR *)(pMemfile + sizeof(T_HOBFILE_HEADER)
+ sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->object_name, 16);
if (verbose == 1) printf("\n");
printf("[INFO] - Process %s object...\n", pHobStruct->objects[i].name);
// Get offsets
pHobStruct->objects[i].face_group_offset = ((T_HOBFILE_OBJ_DESCRIPTOR *)(pMemfile + sizeof(T_HOBFILE_HEADER)
+ sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->facegroup_offset;
if (verbose == 1) printf("[DBG] > Face group offset: 0x%X\n", pHobStruct->objects[i].face_group_offset);
pHobStruct->objects[i].object_part_header_offset = ((T_HOBFILE_OBJ_DESCRIPTOR *)(pMemfile + sizeof(T_HOBFILE_HEADER)
+ sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->object_parts_offset;
if (verbose == 1) printf("[DBG] > Face group header/object parts offset: 0x%X\n", pHobStruct->objects[i].object_part_header_offset);
pHobStruct->objects[i].face_group_header_offset = ((T_HOBFILE_OBJ_DESCRIPTOR *)(pMemfile + sizeof(T_HOBFILE_HEADER)
+ sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->facegroup_header_2_offset;
if (verbose == 1) printf("[DBG] > Face group header2 offset: 0x%X\n", pHobStruct->objects[i].face_group_header_offset);
if (verbose == 3) {
printf("[DBG] > Face group unknown1: %d\n",((T_HOBFILE_OBJ_DESCRIPTOR *)(pMemfile + sizeof(T_HOBFILE_HEADER) + sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->unknownOffset1);
printf("[DBG] > Face group unknown2: %d\n",((T_HOBFILE_OBJ_DESCRIPTOR *)(pMemfile + sizeof(T_HOBFILE_HEADER) + sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->unknownOffset2);
printf("[DBG] > Face group unknown3: %d\n",((T_HOBFILE_OBJ_DESCRIPTOR *)(pMemfile + sizeof(T_HOBFILE_HEADER) + sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->unknownOffset3);
printf("[DBG] > Face group unknown4: %.8f\n",((T_HOBFILE_OBJ_DESCRIPTOR *)(pMemfile + sizeof(T_HOBFILE_HEADER) + sizeof(T_HOBFILE_OBJ_DESCRIPTOR) * i))->unknown4);
}
// Get count and offsets from the facegroup header
pHobStruct->objects[i].object_part_count = ((T_HOBFILE_FACEGROUP_HEADER *)(pMemfile
+ pHobStruct->objects[i].object_part_header_offset))->object_part_count;
if (verbose == 1) printf("[DBG] > Object parts count: %d\n", pHobStruct->objects[i].object_part_count);
pHobStruct->objects[i].face_group_count = ((T_HOBFILE_FACEGROUP_HEADER *)(pMemfile
+ pHobStruct->objects[i].object_part_header_offset))->facegroup_count;
if (verbose == 1) printf("[DBG] > Face groups count: %d\n", pHobStruct->objects[i].face_group_count);
if (pHobStruct->objects[i].object_part_count != pHobStruct->objects[i].face_group_count && (verbose == 1))
printf("[DBG] > Object parts / facegroup count are different!\n");
// Get facegroup datas
ExtractObjParts(&pHobStruct->objects[i], pMemfile, verbose);
}
return RSPLIB_SUCCESS;
}
/**
* Count object's sub-part and extract datas from them.
*
* @param[in|out] pObject Take object structure to get the T_RSPMODEL_OBJ_PARTS buffer and object datas.
* @param[in] pMemfile
* @param[in] verbose
*
* @return Error code, RSPLIB_SUCCESS when no error.
*/
static unsigned int ExtractObjParts(T_RSPMODEL_OBJECT* pObject, const MEMFILE pMemfile, const unsigned char verbose) {
unsigned int i, subpart_offset = 0;
if (pObject == NULL || pMemfile == NULL) return RSPLIB_ERROR_ARGS_NULL;
pObject->object_parts = calloc(pObject->object_part_count, sizeof(T_RSPMODEL_OBJ_PARTS));
if (pObject->object_parts == NULL) return RSPLIB_ERROR_MEMORY;
for ( i = 0; i < pObject->object_part_count; i++ ) {
if (verbose == 2) printf("\n-----------------------Begin of Mesh part-------------------------\n");
subpart_offset = ((T_HOBFILE_FACEGROUP_OFFSET *)(pMemfile + pObject->object_part_header_offset
+ sizeof(T_HOBFILE_FACEGROUP_HEADER) + sizeof(T_HOBFILE_FACEGROUP_OFFSET) * i))->facegroup_offset;
if (verbose == 1) printf("\n[DBG] > Face group meshdef0 offset: 0x%X\n", subpart_offset);
// Get meshdef0 datas
if (verbose == 3) printf("[DBG] > meshdef0 offset1: 0x%X\n",((T_HOBFILE_MESHDEF0 *)(pMemfile + subpart_offset))->offset1);
if (verbose == 3) printf("[DBG] > meshdef0 offset2: 0x%X\n",((T_HOBFILE_MESHDEF0 *)(pMemfile + subpart_offset))->offset2);
if (verbose == 1) printf("[DBG] > Prev meshdef0 offset: 0x%X\n",((T_HOBFILE_MESHDEF0 *)(pMemfile + subpart_offset))->prev_meshdef0_offset);
if (verbose == 1) printf("[DBG] > Next meshdef0 offset: 0x%X\n",((T_HOBFILE_MESHDEF0 *)(pMemfile + subpart_offset))->next_meshdef0_offset);
if (verbose == 3) printf("[DBG] > meshdef0 unknown3: %.8f\n",((T_HOBFILE_MESHDEF0 *)(pMemfile + subpart_offset))->unknown3);
if (verbose == 3) printf("[DBG] > meshdef0 unknown4: %.8f\n",((T_HOBFILE_MESHDEF0 *)(pMemfile + subpart_offset))->unknown4);
if (verbose == 3) printf("[DBG] > meshdef0 unknown5: %.8f\n",((T_HOBFILE_MESHDEF0 *)(pMemfile + subpart_offset))->unknown5);
// Get meshdef1 (mesh descriptor) offset
pObject->object_parts[i].meshdef1_offset = ((T_HOBFILE_MESHDEF0 *)(pMemfile + subpart_offset))->meshdef1_offset_plus_4;
if (verbose == 1) printf("\n[DBG] > Face group meshdef1 offset: 0x%X\n", pObject->object_parts[i].meshdef1_offset);
if( ((T_HOBFILE_MESHDEF0 *)(pMemfile + subpart_offset))->reserved1 != 0 ||
((T_HOBFILE_MESHDEF0 *)(pMemfile + subpart_offset))->reserved2 != 0 ) {
if (verbose == 3) printf("[DBG] > Face group meshdef0: no 0!\n");
}
if (pObject->object_parts[i].meshdef1_offset > 0) {
// Read meshdef1 datas
pObject->object_parts[i].face_block_end_offset = ((T_HOBFILE_MESHDEF1 *)(pMemfile
+ pObject->object_parts[i].meshdef1_offset - 4))->facedef_end_offset;
pObject->object_parts[i].vertex_count = ((T_HOBFILE_MESHDEF1 *)(pMemfile
+ pObject->object_parts[i].meshdef1_offset - 4))->vertex_count;
pObject->object_parts[i].face_block_offset = ((T_HOBFILE_MESHDEF1 *)(pMemfile
+ pObject->object_parts[i].meshdef1_offset - 4))->faceblock_offset;
if (verbose == 1) printf("[DBG] > Faces offset: 0x%X\n", pObject->object_parts[i].face_block_offset);
pObject->object_parts[i].vertex_block_offset = ((T_HOBFILE_MESHDEF1 *)(pMemfile
+ pObject->object_parts[i].meshdef1_offset - 4))->vertexblocks_offset;
if (verbose == 1) printf("[DBG] > Vertex offset: 0x%X\n\n", pObject->object_parts[i].vertex_block_offset);
// Get faces datas
ExtractObjParts_faces(&pObject->object_parts[i], pMemfile, verbose);
}
// Get object part ID, used by animation? bones?
pObject->object_parts[i].id = ((T_HOBFILE_MESHDEF0 *)(pMemfile + subpart_offset))->object_id;
if (verbose == 1) printf("\n[DBG] > Facegroup/object ID: %d\n", pObject->object_parts[i].id);
// Get the transform matrix, used by at-st and at-at (at this time)
pObject->object_parts[i].transform.x = ((T_HOBFILE_MESHDEF0 *)(pMemfile + subpart_offset))->transform_x;
pObject->object_parts[i].transform.y = ((T_HOBFILE_MESHDEF0 *)(pMemfile + subpart_offset))->transform_y;
pObject->object_parts[i].transform.z = ((T_HOBFILE_MESHDEF0 *)(pMemfile + subpart_offset))->transform_z;
if (verbose == 3) printf("\n[DBG] > Facegroup/object transform matrix: [%.8f %.8f %.8f]\n",
pObject->object_parts[i].transform.x,
pObject->object_parts[i].transform.y,
pObject->object_parts[i].transform.z
);
if (verbose == 2) printf("\n-----------------------End of Mesh part---------------------------\n");
}
if (verbose == 2) printf("\n-=====================-End of Object part-========================-\n");
return RSPLIB_SUCCESS;
}
/**
* Extract datas from faces in object sub-part.
*
* @param[in|out] pObjParts
* @param[in] pMemfile
* @param[in] verbose
*
* @return Error code, RSPLIB_SUCCESS when no error.
*/
static unsigned int ExtractObjParts_faces(T_RSPMODEL_OBJ_PARTS* pObjParts, const MEMFILE pMemfile, const unsigned char verbose) {
unsigned int i, facesExtraOffset = 0;
if (pObjParts == NULL || pMemfile == NULL) return RSPLIB_ERROR_ARGS_NULL;
if( ((T_HOBFILE_FACEBLOCK *)(pMemfile + pObjParts->face_block_offset))->reserved1 != 0 ||
((T_HOBFILE_FACEBLOCK *)(pMemfile + pObjParts->face_block_offset))->reserved2 != 0 ) {
if (verbose == 3) printf("[DBG] > Face block: uncommon zero header!\n");
}
if ( ((T_HOBFILE_FACEBLOCK *)(pMemfile + pObjParts->face_block_offset))->facesOffset !=
pObjParts->face_block_offset + sizeof(T_HOBFILE_FACEBLOCK)) {
if (verbose == 3) printf("[DBG] > Face block: uncommon face data offset position!\n");
}
pObjParts->face_count = ((T_HOBFILE_FACEBLOCK *)(pMemfile + pObjParts->face_block_offset))->faceCounts;
pObjParts->faces = calloc(pObjParts->face_count, sizeof(T_RSPMODEL_FACE));
for ( i = 0; i < pObjParts->face_count; i++ ) {
if (verbose == 2) printf("\n----------------------Begin of FaceGroup part----------------------\n");
// Get flags
pObjParts->faces[i].flags = ((T_HOBFILE_FACES_HEADER *)(pMemfile + pObjParts->face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACES_HEADER) * i + facesExtraOffset))->flags;
// Get unknown bytes
pObjParts->faces[i].b1 = ((T_HOBFILE_FACES_HEADER *)(pMemfile + pObjParts->face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACES_HEADER) * i + facesExtraOffset))->b1;
pObjParts->faces[i].b2 = ((T_HOBFILE_FACES_HEADER *)(pMemfile + pObjParts->face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACES_HEADER) * i + facesExtraOffset))->b2;
pObjParts->faces[i].b3 = ((T_HOBFILE_FACES_HEADER *)(pMemfile + pObjParts->face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACES_HEADER) * i + facesExtraOffset))->b3;
pObjParts->faces[i].bsize = ((T_HOBFILE_FACES_HEADER *)(pMemfile + pObjParts->face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACES_HEADER) * i + facesExtraOffset))->faceBlockIntSize * 4; // Multiply by 4 to get the bytes exact number
if (((T_HOBFILE_FACES_HEADER *)(pMemfile + pObjParts->face_block_offset + sizeof(T_HOBFILE_FACEBLOCK)
+ sizeof(T_HOBFILE_FACES_HEADER) * i + facesExtraOffset))->headerSeparator != 0) {
if (verbose == 3) printf("[DBG] > Face header: uncommon separator!\n");
}
// Get materials index
pObjParts->faces[i].material_index = ((T_HOBFILE_FACES_HEADER *)(pMemfile + pObjParts->face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACES_HEADER) * i + facesExtraOffset))->materialIndex;
// Get vertex indices
memcpy(pObjParts->faces[i].indices, ((T_HOBFILE_FACES_HEADER *)(pMemfile + pObjParts->face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACES_HEADER) * i + facesExtraOffset))->vertexIndices,
sizeof(unsigned short) * 4);
// Recalculate the dynamic extra bytes offset size - if present
if (pObjParts->faces[i].flags_bits.fHasExtraBytesBeforeColor) facesExtraOffset += 8;
// Get vertex color - if present
if (pObjParts->faces[i].flags_bits.fHasColor) {
facesExtraOffset += ExtractObjpart_Face_Colors(&pObjParts->faces[i], pMemfile + pObjParts->face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACES_HEADER) + sizeof(T_HOBFILE_FACES_HEADER) * i
+ facesExtraOffset);
}
// Get UV map - if present
if (pObjParts->faces[i].flags_bits.fHasTexture) {
facesExtraOffset += ExtractObjpart_Face_UVMaps(&pObjParts->faces[i], pMemfile + pObjParts->face_block_offset
+ sizeof(T_HOBFILE_FACEBLOCK) + sizeof(T_HOBFILE_FACES_HEADER) + sizeof(T_HOBFILE_FACES_HEADER) * i
+ facesExtraOffset);
}
if (verbose == 2) {
printf("[DBG] > Face %d details: flags:0x%X b1:%d b2:%d b3%d bsize:%d\n", i, pObjParts->faces[i].flags,
pObjParts->faces[i].b1, pObjParts->faces[i].b2, pObjParts->faces[i].b3, pObjParts->faces[i].bsize);
printf("[DBG] - Type is Quad: %d\n", pObjParts->faces[i].flags_bits.fIsQuad);
printf("[DBG] - Material offset: 0x%X\n", pObjParts->faces[i].material_index);
printf("[DBG] - Vertex indices: %d, %d, %d, %d\n", pObjParts->faces[i].indices[0], pObjParts->faces[i].indices[1],
pObjParts->faces[i].indices[2], pObjParts->faces[i].indices[3]);
printf("[DBG] - Vertex colors: 0x%X, 0x%X, 0x%X, 0x%X\n", pObjParts->faces[i].vertex_colors[0],
pObjParts->faces[i].vertex_colors[1], pObjParts->faces[i].vertex_colors[2], pObjParts->faces[i].vertex_colors[3]);
printf("[DBG] - Vertex UV coord (divided by 4096):\n");
printf("[DBG] > %.8f(%d), %.8f(%d)\n",
((double) 1/4096) * pObjParts->faces[i].tex_coords[0].u,
pObjParts->faces[i].tex_coords[0].u,
((double) 1/4096) * pObjParts->faces[i].tex_coords[0].v,
pObjParts->faces[i].tex_coords[0].v
);
printf("[DBG] > %.8f(%d), %.8f(%d)\n",
((double) 1/4096) * pObjParts->faces[i].tex_coords[1].u,
pObjParts->faces[i].tex_coords[1].u,
((double) 1/4096) * pObjParts->faces[i].tex_coords[1].v,
pObjParts->faces[i].tex_coords[1].v
);
printf("[DBG] > %.8f(%d), %.8f(%d)\n",
((double) 1/4096) * pObjParts->faces[i].tex_coords[2].u,
pObjParts->faces[i].tex_coords[2].u,
((double) 1/4096) * pObjParts->faces[i].tex_coords[2].v,
pObjParts->faces[i].tex_coords[2].v
);
printf("[DBG] > %.8f(%d), %.8f(%d)\n",
((double) 1/4096) * pObjParts->faces[i].tex_coords[3].u,
pObjParts->faces[i].tex_coords[3].u,
((double) 1/4096) * pObjParts->faces[i].tex_coords[3].v,
pObjParts->faces[i].tex_coords[3].v
);
printf("\n");
}
if (verbose == 2) printf("\n-----------------------End of FaceGroup part-----------------------\n");
}
// Get vertex datas
pObjParts->vertices = calloc(pObjParts->vertex_count, sizeof(T_VERTEX));
if (pObjParts->vertices == NULL) return RSPLIB_ERROR_MEMORY;
for ( i = 0; i < pObjParts->vertex_count; i++ ) {
pObjParts->vertices[i].x =
((T_HOBFILE_VERTEX *)(pMemfile + pObjParts->vertex_block_offset + sizeof(T_VERTEX) * i))->x;
pObjParts->vertices[i].y =
((T_HOBFILE_VERTEX *)(pMemfile + pObjParts->vertex_block_offset + sizeof(T_VERTEX) * i))->y;
pObjParts->vertices[i].z =
((T_HOBFILE_VERTEX *)(pMemfile + pObjParts->vertex_block_offset + sizeof(T_VERTEX) * i))->z;
pObjParts->vertices[i].w =
((T_HOBFILE_VERTEX *)(pMemfile + pObjParts->vertex_block_offset + sizeof(T_VERTEX) * i))->w; // Always 0???
if (verbose == 2) printf("[DBG] > Found vertex %d: (%d, %d, %d)\n", i,
pObjParts->vertices[i].x, pObjParts->vertices[i].y, pObjParts->vertices[i].z
);
}
return RSPLIB_SUCCESS;
}
static inline unsigned int ExtractObjpart_Face_Colors(T_RSPMODEL_FACE* pFace, const char* pFaceMemFileOffset) {
unsigned int dynOffset = 0;
if (pFace->flags_bits.fSeparateColorVertex) {
pFace->vertex_colors[0] = ((T_HOBFILE_FACES_VERTEX_COLOR *)(pFaceMemFileOffset))->v1_rgba;
pFace->vertex_colors[1] = ((T_HOBFILE_FACES_VERTEX_COLOR *)(pFaceMemFileOffset))->v2_rgba;
pFace->vertex_colors[2] = ((T_HOBFILE_FACES_VERTEX_COLOR *)(pFaceMemFileOffset))->v3_rgba;
if (pFace->flags_bits.fIsQuad) {
pFace->vertex_colors[3] = ((T_HOBFILE_FACES_VERTEX_COLOR *)(pFaceMemFileOffset))->v4_rgba;
dynOffset += sizeof(T_HOBFILE_FACES_VERTEX_COLOR);
} else {
dynOffset += sizeof(T_HOBFILE_FACES_VERTEX_COLOR) - sizeof(T_RGBA);
}
} else {
pFace->vertex_colors[0] = ((T_HOBFILE_FACES_COLOR *)(pFaceMemFileOffset))->rgba;
pFace->vertex_colors[1] = ((T_HOBFILE_FACES_COLOR *)(pFaceMemFileOffset))->rgba;
pFace->vertex_colors[2] = ((T_HOBFILE_FACES_COLOR *)(pFaceMemFileOffset))->rgba;
pFace->vertex_colors[3] = ((T_HOBFILE_FACES_COLOR *)(pFaceMemFileOffset))->rgba;
dynOffset += sizeof(T_HOBFILE_FACES_COLOR);
}
return dynOffset;
}
static inline unsigned int ExtractObjpart_Face_UVMaps(T_RSPMODEL_FACE* pFace, const char* pFaceMemFileOffset) {
unsigned int dynOffset = 0;
pFace->tex_coords[0] = ((T_HOBFILE_FACES_VERTEX_TEXTURE *)(pFaceMemFileOffset))->v1_texcoord;
pFace->tex_coords[1] = ((T_HOBFILE_FACES_VERTEX_TEXTURE *)(pFaceMemFileOffset))->v2_texcoord;
pFace->tex_coords[2] = ((T_HOBFILE_FACES_VERTEX_TEXTURE *)(pFaceMemFileOffset))->v3_texcoord;
if (pFace->flags_bits.fIsQuad) {
pFace->tex_coords[3] = ((T_HOBFILE_FACES_VERTEX_TEXTURE *)(pFaceMemFileOffset))->v4_texcoord;
dynOffset += sizeof(T_HOBFILE_FACES_VERTEX_TEXTURE);
} else {
dynOffset += sizeof(T_HOBFILE_FACES_VERTEX_TEXTURE) - sizeof(T_TEXCOORD);
}
return dynOffset;
}

View File

@ -14,6 +14,8 @@
#ifndef SRC_HOB_PARSER_H_
#define SRC_HOB_PARSER_H_
typedef char* MEMFILE;
unsigned char RSP_ModelLib_ParseHOBFile(const char* fileName, T_RSPMODEL_HOB* hob_struct, T_PROG_OPTIONS* p_opts);
#endif /* SRC_HOB_PARSER_H_ */