diff --git a/src/main.c b/src/main.c index 00f6962..759e3d3 100644 --- a/src/main.c +++ b/src/main.c @@ -265,10 +265,10 @@ void init() { log_info("Getting (CTFNightelf_A.wmo) for WMO data test"); //WMOData test_WMOdata = load_wmo_data(hMPQ, "World\\wmo\\PvP\\Buildings\\CTF\\CTFOrc_A.wmo");*/ // "World\\wmo\\Dungeon\\MD_Caveden\\MD_VrykulDen.wmo" - //char *wmoFileName = "World\\wmo\\PvP\\Buildings\\CTF\\CTFNightelf_A.wmo"; + char *wmoFileName = "World\\wmo\\PvP\\Buildings\\CTF\\CTFNightelf_A.wmo"; //char *wmoFileName = "World\\wmo\\Dungeon\\MD_Caveden\\MD_VrykulDen.wmo"; //char *wmoFileName = "World\\wmo\\Test\\test_petes_wmo_rotation_test.wmo"; - char *wmoFileName = "World\\wmo\\Dungeon\\Ulduar\\Ulduar_Raid.wmo"; + //char *wmoFileName = "World\\wmo\\Dungeon\\Ulduar\\Ulduar_Raid.wmo"; WMOData test_WMOdata = load_wmo_data(&manager, wmoFileName); const char *log_file_name = "wmo_geometry_export.obj.log"; @@ -472,7 +472,7 @@ void init() { //glFrontFace(GL_CW); // GL_CCW for counter clock-wise glDisable(GL_CULL_FACE); - float speed = 10.0f; // 1 unit per second + float speed = 30.0f; // 1 unit per second float last_position = 0.0f; float cam_speed = 30.0f; // 1 unit per sec float cam_yaw_speed = 1.0f; // 3.5 degrees per second @@ -597,19 +597,16 @@ void init() { yaw_rad = TO_RAD(cam_yaw); pitch_rad = TO_RAD(cam_pitch); - vec3_t cam_front; + cam_front.x = cosf(yaw_rad) * cosf(pitch_rad); cam_front.y = sinf(pitch_rad); cam_front.z = sinf(yaw_rad) * cosf(pitch_rad); vec3_normalize(&cam_front); - - vec3_t world_up = { 0.0f, 1.0f, 0.0f }; - - vec3_t cam_right = vec3_cross(cam_front, world_up); + cam_right = vec3_cross(cam_front, world_up); vec3_normalize(&cam_right); - vec3_t cam_up = vec3_cross(cam_right, cam_front); + cam_up = vec3_cross(cam_right, cam_front); vec3_normalize(&cam_up); float move_dist = cam_speed * elapsed_seconds; diff --git a/src/renderer/mesh.c b/src/renderer/mesh.c index 7d6aa3c..39757ee 100644 --- a/src/renderer/mesh.c +++ b/src/renderer/mesh.c @@ -27,16 +27,7 @@ GroupMesh create_mesh_from_group(const WMOGroupData* group, const WMORootData* r const C3Vector* normals = (const C3Vector*)group->monr_data_ptr; const C2Vector* texCoords = (const C2Vector*)group->motv_data_ptr; - // TODO: double check if we need the offset here, I believe its - GLfloat offset_x = group->header.boundingBox.min[0]; - GLfloat offset_y = group->header.boundingBox.min[1]; - GLfloat offset_z = group->header.boundingBox.min[2]; - for (size_t i = 0; i < num_vertices; i++) { - //float wx = positions[i].x + offset_x; - //float wy = positions[i].y + offset_y; - //float wz = positions[i].z + offset_z; - float wx = positions[i].x; float wy = positions[i].y; float wz = positions[i].z; @@ -75,11 +66,6 @@ GroupMesh create_mesh_from_group(const WMOGroupData* group, const WMORootData* r if (vertices[k].position.z < minZ) minZ = vertices[k].position.z; if (vertices[k].position.z > maxZ) maxZ = vertices[k].position.z; } - - log_info("MESH DEBUG: Group has %zu vertices", num_vertices); - // This is the critical line. It tells us where the mesh actually IS. - log_info("BOUNDS: X[%.1f to %.1f] Y[%.1f to %.1f] Z[%.1f to %.1f]", - minX, maxX, minY, maxY, minZ, maxZ); } if (group->moba_data_ptr && group->moba_size > 0) { diff --git a/src/renderer/mesh.h b/src/renderer/mesh.h index 679bf81..23dee6f 100644 --- a/src/renderer/mesh.h +++ b/src/renderer/mesh.h @@ -14,6 +14,7 @@ typedef struct { C3Vector position; C3Vector normal; C2Vector texCoord; + CImVector colour; } Vertex; typedef struct { diff --git a/src/wmo/wmo.c b/src/wmo/wmo.c index 0afc050..af7770e 100644 --- a/src/wmo/wmo.c +++ b/src/wmo/wmo.c @@ -200,8 +200,6 @@ void parse_mopr_chunk(const WMORootData *wmo_root_data) { log_info("Portal reference %zu: portalIndex: %u, groupIndex: %u, side: %d", i, portal_ref.portalIndex, portal_ref.groupIndex, portal_ref.side); } - - // TODO - DOES THE CALLER OR THE FUNCTION FREE MALLOC()? } WMOGroupData parse_wmo_group_file(ArchiveManager *archives, const char *group_file_path) { @@ -385,6 +383,44 @@ void parse_movi_chunk(const WMOGroupData *wmo_group_data) { } +void parse_mocv_chunk(const WMOGroupData *wmo_group_data) { + if (wmo_group_data->mocv_data_ptr == NULL || wmo_group_data->mocv_size == 0) { + log_error("Could not find valid MOCV chunk inside WMO Group File"); + return; + } + + //uint32_t expected_count = wmo_group_data->movt_size / sizeof(C3Vector); + uint32_t actual_colour_count = wmo_group_data->mocv_size / sizeof(uint32_t); + + /* + if (expected_count != actual_colour_count) { + log_warn("We have %d vertices but %d colours", expected_count, actual_colour_count); + } else { + log_info("1:1 vertex to colour mapping confirmed"); + }*/ + + const CImVector* colourVertexList = (const CImVector*)wmo_group_data->mocv_data_ptr; + log_info("Total MOCV Bytes (%lu) / 4 = %lu", wmo_group_data->mocv_size, (wmo_group_data->mocv_size) / sizeof(uint32_t)); + + // TODO: store data in a new packed vertex array + for (size_t i = 0; i < actual_colour_count; i++) { + uint32_t expected_count = wmo_group_data->movt_size / sizeof(C3Vector); + + if (expected_count != actual_colour_count) { + log_warn("We have %d vertices but %d colours", expected_count, actual_colour_count); + } else { + log_info("1:1 vertex to colour mapping confirmed"); + } + + uint8_t b = colourVertexList[i].b; + uint8_t g = colourVertexList[i].g; + uint8_t r = colourVertexList[i].r; + uint8_t a = colourVertexList[i].a; + + log_info("Vertex %zu has colours: (B: %u, G: %u, R: %u, A: %u)", i, b, g, r, a); + } +} + void parse_mogp_sub_chunks(const char *mogp_data_buffer, DWORD mogp_data_size, WMOGroupData *out_group_data) { if (mogp_data_size < sizeof(SMOGroupHeader)) { log_error("MOGP chunk size is too small for SMOGroupHeader"); @@ -470,6 +506,11 @@ void parse_mogp_sub_chunks(const char *mogp_data_buffer, DWORD mogp_data_size, W case MOBN: case MOBR: case MOCV: + out_group_data->mocv_data_ptr = data_start; + out_group_data->mocv_size = header->chunk_size; + log_info(" -> MOCV Chunk found at offset %td", out_group_data->mocv_data_ptr - mogp_data_buffer); + parse_mocv_chunk(out_group_data); + break; case MOC2: case MLIQ: case MORI: @@ -486,6 +527,7 @@ void parse_mogp_sub_chunks(const char *mogp_data_buffer, DWORD mogp_data_size, W } } +/* void extract_wmo_geometry(const WMORootData *wmo_root_data, FILE *output_file) { if (wmo_root_data->groups == NULL || wmo_root_data->group_count == 0) { log_error("No WMO group data found to extract geometry from"); @@ -517,6 +559,7 @@ void extract_wmo_geometry(const WMORootData *wmo_root_data, FILE *output_file) { size_t cumulative_vertex_count = 0; + for (size_t i = 0; i < wmo_root_data->group_count; i++) { const WMOGroupData *group = &wmo_root_data->groups[i]; @@ -529,9 +572,9 @@ void extract_wmo_geometry(const WMORootData *wmo_root_data, FILE *output_file) { fprintf(output_file, "\n# -------------------\n"); fprintf(output_file, "g Group_%zu\n", i); - /* ----------------------------------------------------------------- - 1. SETUP ALL CHUNKS AND OFFSETS - ----------------------------------------------------------------- */ + // ----------------------------------------------------------------- + // 1. SETUP ALL CHUNKS AND OFFSETS + // ----------------------------------------------------------------- size_t num_vertices = group->movt_size / sizeof(C3Vector); const C3Vector *vertices = (const C3Vector *)group->movt_data_ptr; @@ -546,9 +589,9 @@ void extract_wmo_geometry(const WMORootData *wmo_root_data, FILE *output_file) { fprintf(output_file, "# Found %zu vertices (MOVT), normals (MONR), and texcoords (MOTV)\n", num_vertices); - /* ----------------------------------------------------------------- - 2. VERTICES, NORMALS, AND TEXCOORDS (MOVT, MONR, MOTV) - ONE LOOP - ----------------------------------------------------------------- */ + // ----------------------------------------------------------------- + // 2. VERTICES, NORMALS, AND TEXCOORDS (MOVT, MONR, MOTV) - ONE LOOP + // ----------------------------------------------------------------- for (size_t j = 0; j < num_vertices; j++) { // A. Vertices (v) - Apply offset and coordinate swap float x_wmo = vertices[j].x + offset_x; @@ -586,9 +629,9 @@ void extract_wmo_geometry(const WMORootData *wmo_root_data, FILE *output_file) { fprintf(output_file, "vn %.6f %.6f %.6f\n", nx_obj, ny_obj, nz_obj); } - /* ----------------------------------------------------------------- - 3. FACES (MOVI & MOBA) - Second Loop - ----------------------------------------------------------------- */ + // ----------------------------------------------------------------- + // 3. FACES (MOVI & MOBA) - Second Loop + // ----------------------------------------------------------------- const uint16_t *all_indices = (const uint16_t *)group->movi_data_ptr; const SMOBatch *batches = (const SMOBatch *)group->moba_data_ptr; size_t num_batches = group->moba_size / sizeof(SMOBatch); @@ -636,6 +679,7 @@ void extract_wmo_geometry(const WMORootData *wmo_root_data, FILE *output_file) { log_info("Geometry data written to output file"); } +*/ // isTransFace: triangles flagged as TRANSITION. They blend lighting from exterior to interior char smopoly_is_trans_face(SMOPolyFlags flags) { diff --git a/src/wmo/wmo.h b/src/wmo/wmo.h index 62441d8..69c715b 100644 --- a/src/wmo/wmo.h +++ b/src/wmo/wmo.h @@ -13,6 +13,7 @@ void parse_mohd_chunk(const WMORootData *wmo_root_data); void parse_mopv_chunk(const WMORootData *wmo_root_data); void parse_mopt_chunk(const WMORootData *wmo_root_data); void parse_mopr_chunk(const WMORootData *wmo_root_data); +void parse_mocv_chunk(const WMOGroupData *wmo_group_data); void parse_mogp_sub_chunks(const char *mogp_data_buffer, DWORD mogp_data_size, WMOGroupData *out_group_data); WMOGroupData parse_wmo_group_file(ArchiveManager *archives, const char *group_file_path); void extract_wmo_geometry(const WMORootData *wmo_root_data, FILE *output_file); diff --git a/src/wmo/wmo_structs.h b/src/wmo/wmo_structs.h index 567e4dc..4fbaef2 100644 --- a/src/wmo/wmo_structs.h +++ b/src/wmo/wmo_structs.h @@ -37,6 +37,14 @@ typedef union { } components; } CArgb; +// a color given in values of blue, green, red and alpha +typedef union { + uint32_t raw_value; + struct { + uint8_t r, g, b, a; + }; +} CImVector; + // Axis-aligned bounding box typedef struct { float min[3]; @@ -242,6 +250,8 @@ typedef struct { DWORD moqg_size; const char *molr_data_ptr; DWORD molr_size; + const char *mocv_data_ptr; // Vertex colours + DWORD mocv_size; // TODO: chunks dependent on flag, need to add their ptr's } WMOGroupData;