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");
|
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");*/
|
//WMOData test_WMOdata = load_wmo_data(hMPQ, "World\\wmo\\PvP\\Buildings\\CTF\\CTFOrc_A.wmo");*/
|
||||||
// "World\\wmo\\Dungeon\\MD_Caveden\\MD_VrykulDen.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\\Dungeon\\MD_Caveden\\MD_VrykulDen.wmo";
|
||||||
//char *wmoFileName = "World\\wmo\\Test\\test_petes_wmo_rotation_test.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);
|
WMOData test_WMOdata = load_wmo_data(&manager, wmoFileName);
|
||||||
|
|
||||||
const char *log_file_name = "wmo_geometry_export.obj.log";
|
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
|
//glFrontFace(GL_CW); // GL_CCW for counter clock-wise
|
||||||
glDisable(GL_CULL_FACE);
|
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 last_position = 0.0f;
|
||||||
float cam_speed = 30.0f; // 1 unit per sec
|
float cam_speed = 30.0f; // 1 unit per sec
|
||||||
float cam_yaw_speed = 1.0f; // 3.5 degrees per second
|
float cam_yaw_speed = 1.0f; // 3.5 degrees per second
|
||||||
@@ -597,19 +597,16 @@ void init() {
|
|||||||
yaw_rad = TO_RAD(cam_yaw);
|
yaw_rad = TO_RAD(cam_yaw);
|
||||||
pitch_rad = TO_RAD(cam_pitch);
|
pitch_rad = TO_RAD(cam_pitch);
|
||||||
|
|
||||||
vec3_t cam_front;
|
|
||||||
cam_front.x = cosf(yaw_rad) * cosf(pitch_rad);
|
cam_front.x = cosf(yaw_rad) * cosf(pitch_rad);
|
||||||
cam_front.y = sinf(pitch_rad);
|
cam_front.y = sinf(pitch_rad);
|
||||||
cam_front.z = sinf(yaw_rad) * cosf(pitch_rad);
|
cam_front.z = sinf(yaw_rad) * cosf(pitch_rad);
|
||||||
|
|
||||||
vec3_normalize(&cam_front);
|
vec3_normalize(&cam_front);
|
||||||
|
cam_right = vec3_cross(cam_front, world_up);
|
||||||
vec3_t world_up = { 0.0f, 1.0f, 0.0f };
|
|
||||||
|
|
||||||
vec3_t cam_right = vec3_cross(cam_front, world_up);
|
|
||||||
vec3_normalize(&cam_right);
|
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);
|
vec3_normalize(&cam_up);
|
||||||
|
|
||||||
float move_dist = cam_speed * elapsed_seconds;
|
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 C3Vector* normals = (const C3Vector*)group->monr_data_ptr;
|
||||||
const C2Vector* texCoords = (const C2Vector*)group->motv_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++) {
|
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 wx = positions[i].x;
|
||||||
float wy = positions[i].y;
|
float wy = positions[i].y;
|
||||||
float wz = positions[i].z;
|
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 < minZ) minZ = vertices[k].position.z;
|
||||||
if (vertices[k].position.z > maxZ) maxZ = 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) {
|
if (group->moba_data_ptr && group->moba_size > 0) {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ typedef struct {
|
|||||||
C3Vector position;
|
C3Vector position;
|
||||||
C3Vector normal;
|
C3Vector normal;
|
||||||
C2Vector texCoord;
|
C2Vector texCoord;
|
||||||
|
CImVector colour;
|
||||||
} Vertex;
|
} Vertex;
|
||||||
|
|
||||||
typedef struct {
|
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,
|
log_info("Portal reference %zu: portalIndex: %u, groupIndex: %u, side: %d", i, portal_ref.portalIndex,
|
||||||
portal_ref.groupIndex, portal_ref.side);
|
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) {
|
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) {
|
void parse_mogp_sub_chunks(const char *mogp_data_buffer, DWORD mogp_data_size, WMOGroupData *out_group_data) {
|
||||||
if (mogp_data_size < sizeof(SMOGroupHeader)) {
|
if (mogp_data_size < sizeof(SMOGroupHeader)) {
|
||||||
log_error("MOGP chunk size is too small for 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 MOBN:
|
||||||
case MOBR:
|
case MOBR:
|
||||||
case MOCV:
|
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 MOC2:
|
||||||
case MLIQ:
|
case MLIQ:
|
||||||
case MORI:
|
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) {
|
void extract_wmo_geometry(const WMORootData *wmo_root_data, FILE *output_file) {
|
||||||
if (wmo_root_data->groups == NULL || wmo_root_data->group_count == 0) {
|
if (wmo_root_data->groups == NULL || wmo_root_data->group_count == 0) {
|
||||||
log_error("No WMO group data found to extract geometry from");
|
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;
|
size_t cumulative_vertex_count = 0;
|
||||||
|
|
||||||
|
|
||||||
for (size_t i = 0; i < wmo_root_data->group_count; i++) {
|
for (size_t i = 0; i < wmo_root_data->group_count; i++) {
|
||||||
const WMOGroupData *group = &wmo_root_data->groups[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, "\n# -------------------\n");
|
||||||
fprintf(output_file, "g Group_%zu\n", i);
|
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);
|
size_t num_vertices = group->movt_size / sizeof(C3Vector);
|
||||||
const C3Vector *vertices = (const C3Vector *)group->movt_data_ptr;
|
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);
|
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++) {
|
for (size_t j = 0; j < num_vertices; j++) {
|
||||||
// A. Vertices (v) - Apply offset and coordinate swap
|
// A. Vertices (v) - Apply offset and coordinate swap
|
||||||
float x_wmo = vertices[j].x + offset_x;
|
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);
|
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 uint16_t *all_indices = (const uint16_t *)group->movi_data_ptr;
|
||||||
const SMOBatch *batches = (const SMOBatch *)group->moba_data_ptr;
|
const SMOBatch *batches = (const SMOBatch *)group->moba_data_ptr;
|
||||||
size_t num_batches = group->moba_size / sizeof(SMOBatch);
|
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");
|
log_info("Geometry data written to output file");
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// isTransFace: triangles flagged as TRANSITION. They blend lighting from exterior to interior
|
// isTransFace: triangles flagged as TRANSITION. They blend lighting from exterior to interior
|
||||||
char smopoly_is_trans_face(SMOPolyFlags flags) {
|
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_mopv_chunk(const WMORootData *wmo_root_data);
|
||||||
void parse_mopt_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_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);
|
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);
|
WMOGroupData parse_wmo_group_file(ArchiveManager *archives, const char *group_file_path);
|
||||||
void extract_wmo_geometry(const WMORootData *wmo_root_data, FILE *output_file);
|
void extract_wmo_geometry(const WMORootData *wmo_root_data, FILE *output_file);
|
||||||
|
|||||||
@@ -37,6 +37,14 @@ typedef union {
|
|||||||
} components;
|
} components;
|
||||||
} CArgb;
|
} 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
|
// Axis-aligned bounding box
|
||||||
typedef struct {
|
typedef struct {
|
||||||
float min[3];
|
float min[3];
|
||||||
@@ -242,6 +250,8 @@ typedef struct {
|
|||||||
DWORD moqg_size;
|
DWORD moqg_size;
|
||||||
const char *molr_data_ptr;
|
const char *molr_data_ptr;
|
||||||
DWORD molr_size;
|
DWORD molr_size;
|
||||||
|
const char *mocv_data_ptr; // Vertex colours
|
||||||
|
DWORD mocv_size;
|
||||||
// TODO: chunks dependent on flag, need to add their ptr's
|
// TODO: chunks dependent on flag, need to add their ptr's
|
||||||
} WMOGroupData;
|
} WMOGroupData;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user