mirror of
https://github.com/WerWolv/ImHex-Patterns.git
synced 2026-03-27 23:37:04 -05:00
patterns: Added new WebP and VGM patterns (#294)
* README: fix square bracket * patterns: add WebP pattern * patterns/dds: add x-dds mimetype * patterns: add vgm pattern * patterns/vgm: remove old pointer * patterns/protobuf: fix field number handling * patterns/protobuf: add .pb file extension * patterns/uf2: updating the family IDs again * patterns/png: add cHRM and tIME chunks * patterns/png: whoops, old description snuck back in * new quantized-mesh pattern * add quantized-mesh to README, implement oct16 decoding
This commit is contained in:
169
patterns/quantized-mesh.hexpat
Normal file
169
patterns/quantized-mesh.hexpat
Normal file
@@ -0,0 +1,169 @@
|
||||
#pragma author applecuckoo
|
||||
#pragma description Cesium quantized-mesh terrain
|
||||
#pragma endian little
|
||||
|
||||
// based on https://github.com/CesiumGS/quantized-mesh
|
||||
// potential improvements: figure out high water mark encoding for indices
|
||||
|
||||
import std.math;
|
||||
import std.io;
|
||||
|
||||
u8 extensionCount;
|
||||
extensionCount = 0; // NOTE: set this to the amount of extensions in your terrain.
|
||||
|
||||
// ZigZag decoder based on protobuf.hexpat by WerWolv
|
||||
|
||||
struct ZigZag16 {
|
||||
u16 value;
|
||||
} [[sealed, format("format_zigzag16")]];
|
||||
|
||||
fn format_zigzag16(ZigZag16 zigzag) {
|
||||
return s16((s16(zigzag.value) << 1) ^ (s16(zigzag.value) >> 15));
|
||||
};
|
||||
|
||||
struct QuantizedMeshHeader {
|
||||
double CenterX;
|
||||
double CenterY;
|
||||
double CenterZ;
|
||||
|
||||
float MinimumHeight;
|
||||
float MaximumHeight;
|
||||
|
||||
double BoundingSphereCenterX;
|
||||
double BoundingSphereCenterY;
|
||||
double BoundingSphereCenterZ;
|
||||
double BoundingSphereRadius;
|
||||
|
||||
double HorizonOcclusionPointX;
|
||||
double HorizonOcclusionPointY;
|
||||
double HorizonOcclusionPointZ;
|
||||
};
|
||||
|
||||
struct VertexData {
|
||||
u32 vertexCount;
|
||||
ZigZag16 u[vertexCount];
|
||||
ZigZag16 v[vertexCount];
|
||||
ZigZag16 height[vertexCount];
|
||||
};
|
||||
|
||||
struct IndexData16 {
|
||||
u32 triangleCount;
|
||||
u16 indices[triangleCount * 3];
|
||||
};
|
||||
|
||||
struct IndexData32 {
|
||||
u32 triangleCount;
|
||||
u32 indices[triangleCount * 3];
|
||||
};
|
||||
|
||||
struct EdgeIndices16 {
|
||||
u32 westVertexCount;
|
||||
u16 westIndices[westVertexCount];
|
||||
|
||||
u32 southVertexCount;
|
||||
u16 southIndices[southVertexCount];
|
||||
|
||||
u32 eastVertexCount;
|
||||
u16 eastIndices[eastVertexCount];
|
||||
|
||||
u32 northVertexCount;
|
||||
u16 northIndices[northVertexCount];
|
||||
};
|
||||
|
||||
struct EdgeIndices32 {
|
||||
u32 westVertexCount;
|
||||
u32 westIndices[westVertexCount];
|
||||
|
||||
u32 southVertexCount;
|
||||
u32 southIndices[southVertexCount];
|
||||
|
||||
u32 eastVertexCount;
|
||||
u32 eastIndices[eastVertexCount];
|
||||
|
||||
u32 northVertexCount;
|
||||
u32 northIndices[northVertexCount];
|
||||
};
|
||||
|
||||
enum ExtensionTypes : u8 {
|
||||
OctEncodedVertexNormals = 0x1,
|
||||
WaterMask,
|
||||
Metadata = 0x4,
|
||||
};
|
||||
|
||||
// Oct16 decode based on https://github.com/loicgasser/quantized-mesh-tile/blob/master/quantized_mesh_tile/utils.py
|
||||
|
||||
fn signNotZero(float v) {
|
||||
if (v < 0.0)
|
||||
return -1.0;
|
||||
else
|
||||
return 1.0;
|
||||
};
|
||||
|
||||
fn fromSnorm(u8 value) {
|
||||
return float(std::math::clamp(value, 0.0, 255.0) / 255.0 * 2.0 - 1.0);
|
||||
};
|
||||
|
||||
struct Oct16 {
|
||||
u8 x;
|
||||
u8 y;
|
||||
}[[sealed, format("format_oct16")]];
|
||||
|
||||
fn format_oct16(Oct16 oct) {
|
||||
float xOut;
|
||||
float yOut;
|
||||
float zOut;
|
||||
|
||||
xOut = fromSnorm(oct.x);
|
||||
yOut = fromSnorm(oct.y);
|
||||
zOut = 1.0 - (std::math::abs(xOut) + std::math::abs(yOut));
|
||||
|
||||
if (zOut < 0.0) {
|
||||
float oldX;
|
||||
|
||||
oldX = xOut;
|
||||
xOut = (1.0 - std::math::abs(yOut)) * signNotZero(oldX);
|
||||
yOut = (1.0 - std::math::abs(oldX)) * signNotZero(yOut);
|
||||
}
|
||||
|
||||
return std::format("{}, {}, {}", xOut, yOut, zOut);
|
||||
};
|
||||
|
||||
struct OctEncodedVertexNormals {
|
||||
Oct16 xy[parent.parent.vertdata.vertexCount];
|
||||
};
|
||||
|
||||
struct WaterMask {
|
||||
u8 mask[parent.extensionLength];
|
||||
};
|
||||
|
||||
struct Metadata {
|
||||
u32 jsonLength;
|
||||
char json[jsonLength];
|
||||
};
|
||||
|
||||
struct ExtensionHeader {
|
||||
u8 extensionId;
|
||||
u32 extensionLength;
|
||||
match (extensionId) {
|
||||
(ExtensionTypes::OctEncodedVertexNormals): OctEncodedVertexNormals octVertNormals;
|
||||
(ExtensionTypes::WaterMask): WaterMask maskData;
|
||||
(ExtensionTypes::Metadata): Metadata metadata;
|
||||
}
|
||||
};
|
||||
|
||||
struct QuantizedMesh {
|
||||
QuantizedMeshHeader header;
|
||||
VertexData vertdata;
|
||||
|
||||
if (vertdata.vertexCount > 65536) {
|
||||
IndexData32 indexdata;
|
||||
EdgeIndices32 edgeindices;
|
||||
} else {
|
||||
IndexData16 indexdata;
|
||||
EdgeIndices16 edgeindices;
|
||||
}
|
||||
|
||||
ExtensionHeader extensions[extensionCount];
|
||||
};
|
||||
|
||||
QuantizedMesh mesh @ 0x00;
|
||||
Reference in New Issue
Block a user