mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-04-05 04:33:51 +00:00
refactor: name ADT vertex constants, add BLP decompression comments
- adt_loader: replace magic 145 with kMCVTVertexCount and 17 with kMCVTRowStride — MCVT height grid is 9 outer + 8 inner vertices per row across 9 rows - adt_loader: replace 999999.0f sentinels with numeric_limits - blp_loader: add why-comments on RGB565→RGB888 bit layout (R=bits[15:11], G=[10:5], B=[4:0]) - blp_loader: explain DXT3 4-bit alpha scaling (n * 255 / 15) - blp_loader: explain palette 4-bit alpha multiply-by-17 trick (equivalent to n * 255 / 15, exact for all 16 values)
This commit is contained in:
parent
683e171fd1
commit
1151785381
2 changed files with 21 additions and 18 deletions
|
|
@ -3,23 +3,25 @@
|
|||
#include <cstring>
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
namespace wowee {
|
||||
namespace pipeline {
|
||||
|
||||
// MCVT height grid: 9 outer + 8 inner vertices per row, 9 rows = 145 total.
|
||||
// Each row is 17 entries: 9 outer corner vertices then 8 inner midpoints.
|
||||
static constexpr int kMCVTVertexCount = 145;
|
||||
static constexpr int kMCVTRowStride = 17; // 9 outer + 8 inner per row
|
||||
|
||||
// HeightMap implementation
|
||||
float HeightMap::getHeight(int x, int y) const {
|
||||
if (x < 0 || x > 8 || y < 0 || y > 8) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
// MCVT heights are stored in interleaved 9x17 row-major layout:
|
||||
// Row 0: 9 outer (indices 0-8), then 8 inner (indices 9-16)
|
||||
// Row 1: 9 outer (indices 17-25), then 8 inner (indices 26-33)
|
||||
// ...
|
||||
// Outer vertex (x, y) is at index: y * 17 + x
|
||||
int index = y * 17 + x;
|
||||
if (index < 0 || index >= 145) return 0.0f;
|
||||
// Outer vertex (x, y) in the interleaved grid
|
||||
int index = y * kMCVTRowStride + x;
|
||||
if (index < 0 || index >= kMCVTVertexCount) return 0.0f;
|
||||
|
||||
return heights[index];
|
||||
}
|
||||
|
|
@ -355,16 +357,15 @@ void ADTLoader::parseMCNK(const uint8_t* data, size_t size, int chunkIndex, ADTT
|
|||
}
|
||||
|
||||
void ADTLoader::parseMCVT(const uint8_t* data, size_t size, MapChunk& chunk) {
|
||||
// MCVT contains 145 height values (floats)
|
||||
if (size < 145 * sizeof(float)) {
|
||||
if (size < kMCVTVertexCount * sizeof(float)) {
|
||||
LOG_WARNING("MCVT chunk too small: ", size, " bytes");
|
||||
return;
|
||||
}
|
||||
|
||||
float minHeight = 999999.0f;
|
||||
float maxHeight = -999999.0f;
|
||||
float minHeight = std::numeric_limits<float>::max();
|
||||
float maxHeight = std::numeric_limits<float>::lowest();
|
||||
|
||||
for (int i = 0; i < 145; i++) {
|
||||
for (int i = 0; i < kMCVTVertexCount; i++) {
|
||||
float height = readFloat(data, i * sizeof(float));
|
||||
chunk.heightMap.heights[i] = height;
|
||||
|
||||
|
|
@ -386,13 +387,13 @@ void ADTLoader::parseMCVT(const uint8_t* data, size_t size, MapChunk& chunk) {
|
|||
}
|
||||
|
||||
void ADTLoader::parseMCNR(const uint8_t* data, size_t size, MapChunk& chunk) {
|
||||
// MCNR contains 145 normals (3 bytes each, signed)
|
||||
if (size < 145 * 3) {
|
||||
// MCNR: one signed XYZ normal per vertex (3 bytes each)
|
||||
if (size < kMCVTVertexCount * 3) {
|
||||
LOG_WARNING("MCNR chunk too small: ", size, " bytes");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 145 * 3; i++) {
|
||||
for (int i = 0; i < kMCVTVertexCount * 3; i++) {
|
||||
chunk.normals[i] = static_cast<int8_t>(data[i]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -209,7 +209,8 @@ void BLPLoader::decompressDXT1(const uint8_t* src, uint8_t* dst, int width, int
|
|||
uint16_t c0 = block[0] | (block[1] << 8);
|
||||
uint16_t c1 = block[2] | (block[3] << 8);
|
||||
|
||||
// Convert RGB565 to RGB888
|
||||
// Convert RGB565 to RGB888: extract 5/6/5-bit channels and scale to [0..255].
|
||||
// R = bits[15:11] (5-bit, /31), G = bits[10:5] (6-bit, /63), B = bits[4:0] (5-bit, /31)
|
||||
uint8_t r0 = ((c0 >> 11) & 0x1F) * 255 / 31;
|
||||
uint8_t g0 = ((c0 >> 5) & 0x3F) * 255 / 63;
|
||||
uint8_t b0 = (c0 & 0x1F) * 255 / 31;
|
||||
|
|
@ -303,7 +304,7 @@ void BLPLoader::decompressDXT3(const uint8_t* src, uint8_t* dst, int width, int
|
|||
case 3: pixel[0] = (r0 + 2*r1) / 3; pixel[1] = (g0 + 2*g1) / 3; pixel[2] = (b0 + 2*b1) / 3; break;
|
||||
}
|
||||
|
||||
// Apply 4-bit alpha
|
||||
// Apply 4-bit alpha: scale [0..15] → [0..255] via (n * 255 / 15)
|
||||
int alphaIndex = py * 4 + px;
|
||||
uint8_t alpha4 = (alphaBlock >> (alphaIndex * 4)) & 0xF;
|
||||
pixel[3] = alpha4 * 255 / 15;
|
||||
|
|
@ -416,7 +417,8 @@ void BLPLoader::decompressPalette(const uint8_t* src, uint8_t* dst, const uint32
|
|||
if (alphaDepth == 8) {
|
||||
dst[i * 4 + 3] = alphaData[i];
|
||||
} else if (alphaDepth == 4) {
|
||||
// 4-bit alpha: 2 pixels per byte
|
||||
// 4-bit alpha: 2 pixels packed per byte (low nibble first).
|
||||
// Multiply by 17 to scale [0..15] → [0..255] (equivalent to n * 255 / 15).
|
||||
uint8_t alphaByte = alphaData[i / 2];
|
||||
dst[i * 4 + 3] = (i % 2 == 0) ? ((alphaByte & 0x0F) * 17) : ((alphaByte >> 4) * 17);
|
||||
} else if (alphaDepth == 1) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue