скайбоксы, рендер воды, документация
This commit is contained in:
@@ -180,6 +180,7 @@ Ref<Image> BLPLoader::parse(const uint8_t *data, size_t len) {
|
||||
const size_t palette_ofs = sizeof(BLP2Header);
|
||||
if (palette_ofs + 256*4 > len) return Ref<Image>();
|
||||
const uint8_t *palette = data + palette_ofs;
|
||||
const uint8_t *alpha = mip + (size_t)w * (size_t)h;
|
||||
|
||||
rgba.resize(w * h * 4);
|
||||
for (uint32_t i = 0; i < w * h && i < mip_size; ++i) {
|
||||
@@ -187,7 +188,23 @@ Ref<Image> BLPLoader::parse(const uint8_t *data, size_t len) {
|
||||
rgba[i*4+0] = palette[idx*4+2]; // R (from BGR)
|
||||
rgba[i*4+1] = palette[idx*4+1]; // G
|
||||
rgba[i*4+2] = palette[idx*4+0]; // B
|
||||
rgba[i*4+3] = (hdr.alphaDepth == 0) ? 255 : mip[w*h + i];
|
||||
uint8_t a = 255;
|
||||
if (hdr.alphaDepth == 8) {
|
||||
size_t alpha_pos = (size_t)w * (size_t)h + i;
|
||||
a = alpha_pos < mip_size ? mip[alpha_pos] : 255;
|
||||
} else if (hdr.alphaDepth == 4) {
|
||||
size_t byte_pos = i >> 1;
|
||||
if ((size_t)w * (size_t)h + byte_pos < mip_size) {
|
||||
uint8_t nibble = (i & 1) ? (alpha[byte_pos] >> 4) : (alpha[byte_pos] & 0x0F);
|
||||
a = (uint8_t)(nibble * 17);
|
||||
}
|
||||
} else if (hdr.alphaDepth == 1) {
|
||||
size_t byte_pos = i >> 3;
|
||||
if ((size_t)w * (size_t)h + byte_pos < mip_size) {
|
||||
a = (alpha[byte_pos] & (1 << (i & 7))) ? 255 : 0;
|
||||
}
|
||||
}
|
||||
rgba[i*4+3] = a;
|
||||
}
|
||||
|
||||
} else if (hdr.encoding == 3) {
|
||||
|
||||
@@ -199,6 +199,8 @@ Dictionary M2Loader::parse_m2(const std::vector<uint8_t> &buf, const std::string
|
||||
|
||||
// ── Textures ─────────────────────────────────────────────────────────────
|
||||
PackedStringArray textures;
|
||||
PackedInt32Array texture_types;
|
||||
PackedInt32Array texture_flags;
|
||||
const auto *tex_arr = safe_array<M2Texture>(buf, hdr.ofsTextures, hdr.nTextures);
|
||||
if (tex_arr) {
|
||||
for (uint32_t i = 0; i < hdr.nTextures; ++i) {
|
||||
@@ -217,6 +219,8 @@ Dictionary M2Loader::parse_m2(const std::vector<uint8_t> &buf, const std::string
|
||||
}
|
||||
}
|
||||
textures.push_back(to_godot(fname));
|
||||
texture_types.push_back((int)t.type);
|
||||
texture_flags.push_back((int)t.flags);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,8 +317,11 @@ Dictionary M2Loader::parse_m2(const std::vector<uint8_t> &buf, const std::string
|
||||
|
||||
Dictionary result;
|
||||
result["textures"] = textures;
|
||||
result["texture_types"] = texture_types;
|
||||
result["texture_flags"] = texture_flags;
|
||||
result["materials"] = materials;
|
||||
result["texture_combos"] = texture_combos;
|
||||
result["model_path"] = to_godot(path);
|
||||
result["vertices"] = vertices;
|
||||
result["normals"] = normals;
|
||||
result["uvs"] = uvs;
|
||||
|
||||
@@ -24,8 +24,11 @@ namespace godot {
|
||||
// Return Dictionary:
|
||||
// {
|
||||
// "textures": PackedStringArray, # .blp texture paths (may be empty for replaceable)
|
||||
// "texture_types": PackedInt32Array, # M2Texture.type per texture slot
|
||||
// "texture_flags": PackedInt32Array, # M2Texture.flags per texture slot
|
||||
// "materials": Array[Dictionary], # [{flags, blend_mode}]
|
||||
// "texture_combos": PackedInt32Array, # textureCombos[i] = index into textures
|
||||
// "model_path": String, # absolute source .m2 path
|
||||
// "vertices": PackedVector3Array, # Godot-space positions
|
||||
// "normals": PackedVector3Array,
|
||||
// "uvs": PackedVector2Array,
|
||||
|
||||
@@ -313,7 +313,7 @@ Dictionary WMOLoader::parse_group(const std::vector<uint8_t> &buf) {
|
||||
auto *v = sc.array<MOTVEntry>();
|
||||
uvs.resize(n);
|
||||
for (uint32_t i = 0; i < n; ++i)
|
||||
uvs[i] = Vector2(v[i].u, 1.0f - v[i].v);
|
||||
uvs[i] = Vector2(v[i].u, v[i].v);
|
||||
|
||||
} else if (sc.is("MOVI")) {
|
||||
uint32_t n = sc.size / 2;
|
||||
|
||||
Reference in New Issue
Block a user