added MOCV chunk parsing for vertex colours
This commit is contained in:
15
src/main.c
15
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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -14,6 +14,7 @@ typedef struct {
|
||||
C3Vector position;
|
||||
C3Vector normal;
|
||||
C2Vector texCoord;
|
||||
CImVector colour;
|
||||
} Vertex;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user