Last active
November 19, 2019 22:00
-
-
Save fusspawn/2f819938b19f12869952eb00fe63345b to your computer and use it in GitHub Desktop.
MMTile lua parser. Works inside of wow. requires: https://github.com/iryont/lua-struct
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- fixed invalid mmap_uses_liquid check | |
local file = GetHackDirectory() .. "\mmaps\\0002239.mmtile" | |
function pack(...) | |
return {...} | |
end | |
function ToStream(byte_array) | |
byte_array.index = 0 | |
byte_array.read_bytes = function(self, len) | |
local ret = {} | |
for i = 1, len, 1 do | |
ret[i] = self[self.index + i] | |
end | |
self.index = self.index + len | |
return ret | |
end | |
byte_array.read_bytes_str = function(self, len) | |
local ret = {} | |
for i = 1, len, 1 do | |
ret[i] = self[self.index + i] | |
end | |
self.index = self.index + len | |
return bytestostring(ret) | |
end | |
return byte_array | |
end | |
function bytestostring(bytes) | |
s = "" | |
for i = 1, getn(bytes) do | |
s = s .. string.char(bytes[i]) -- Fixme: '..' creates new string. Expensive and shit! | |
end | |
return s | |
end | |
dtAlign4 = function(x) | |
return bit.band((x+3), bit.bnot(3)) | |
end | |
function DumpNavMeshFile(filename) | |
if #GetDirectoryFiles(filename) == 0 then | |
DEBUG("No file found..: " .. filename) | |
return | |
end | |
print("reading file: " .. filename) | |
local bytes = ReadFile(filename, true) | |
print("loaded " .. #bytes .. " of navmesh") | |
local byte_stream = ToStream(bytes) | |
local magic_header = byte_stream:read_bytes_str(4) | |
if magic_header ~= "PAMM" then | |
print("Found invalid magic header. stopping") | |
return | |
end | |
print("magic header was... ok!") | |
local dt_version_num = struct.unpack("<I", byte_stream:read_bytes_str(4)) | |
if dt_version_num ~= 7 then | |
print("invalid dt version num. expected 7 got: " .. dt_version_num) | |
end | |
print("detour version was... ok!") | |
local mmap_version_num = struct.unpack("<I", byte_stream:read_bytes_str(4)) | |
print("mmap version was... " .. mmap_version_num) | |
local mmap_data_size = struct.unpack("<I", byte_stream:read_bytes_str(4)) | |
print("mmap data size was... " .. mmap_data_size) | |
local mmap_uses_liquid = struct.unpack("<i", byte_stream:read_bytes_str(4)) == 1 or false | |
print("mmap uses liquid: " .. tostring(mmap_uses_liquid)) | |
local data_start_index = byte_stream.index | |
local t_magic = struct.unpack("<i", byte_stream:read_bytes_str(4)) | |
local t_version = struct.unpack("<i", byte_stream:read_bytes_str(4)) | |
local t_x = struct.unpack("<i", byte_stream:read_bytes_str(4)) | |
local t_y = struct.unpack("<i", byte_stream:read_bytes_str(4)) | |
local t_layer = struct.unpack("<i", byte_stream:read_bytes_str(4)) | |
local t_userId = struct.unpack("<I", byte_stream:read_bytes_str(4)) | |
local t_polyCount = struct.unpack("<i", byte_stream:read_bytes_str(4)) | |
local t_vertCount = struct.unpack("<i", byte_stream:read_bytes_str(4)) | |
local t_maxLinkCount = struct.unpack("<i", byte_stream:read_bytes_str(4)) | |
local t_detailMeshCount = struct.unpack("<i", byte_stream:read_bytes_str(4)) | |
local t_detailVertCount = struct.unpack("<i", byte_stream:read_bytes_str(4)) | |
local t_detailTriCount = struct.unpack("<i", byte_stream:read_bytes_str(4)) | |
local t_bvNodeCount = struct.unpack("<i", byte_stream:read_bytes_str(4)) | |
local t_offMeshConCount = struct.unpack("<i", byte_stream:read_bytes_str(4)) | |
local t_offMeshBase = struct.unpack("<i", byte_stream:read_bytes_str(4)) | |
local t_walkableHeight = struct.unpack("<f", byte_stream:read_bytes_str(4)) | |
local t_walkableRadius = struct.unpack("<f", byte_stream:read_bytes_str(4)) | |
local t_walkableClimb = struct.unpack("<f", byte_stream:read_bytes_str(4)) | |
local t_bMinX = struct.unpack("<f", byte_stream:read_bytes_str(4)) | |
local t_bMinY = struct.unpack("<f", byte_stream:read_bytes_str(4)) | |
local t_bMinZ = struct.unpack("<f", byte_stream:read_bytes_str(4)) | |
local t_bMaxX = struct.unpack("<f", byte_stream:read_bytes_str(4)) | |
local t_bMaxY = struct.unpack("<f", byte_stream:read_bytes_str(4)) | |
local t_bMaxZ = struct.unpack("<f", byte_stream:read_bytes_str(4)) | |
local t_bvQuantFactor = struct.unpack("<f", byte_stream:read_bytes_str(4)) | |
print("found nav tile: Pos: (".. t_x .. "/" .. t_y.. " - layer: ".. t_layer ..") WalkableHeight: " .. t_walkableHeight .. " WalkableRadius: " .. t_walkableRadius .. " WalkableClimb: " .. t_walkableClimb) | |
print("Tile BoundingBox: ") | |
print("Min: ") | |
print("X: " .. t_bMinX) | |
print("Y: " .. t_bMinY) | |
print("Z: " .. t_bMinZ) | |
print("Max: ") | |
print("X: " .. t_bMaxX) | |
print("Y: " .. t_bMaxY) | |
print("Z: " .. t_bMaxZ) | |
local headerSize = dtAlign4(100); | |
local vertsSize = dtAlign4(4 * 3 * t_vertCount); | |
local polysSize = dtAlign4(34 * t_polyCount); | |
local linksSize = dtAlign4(16 * t_maxLinkCount); | |
local detailMeshesSize = dtAlign4(10 * t_detailMeshCount); | |
local detailVertsSize = dtAlign4(4*3*t_detailVertCount); | |
local detailTrisSize = dtAlign4(4*t_detailTriCount); | |
local bvtreeSize = dtAlign4(8*t_bvNodeCount); | |
local offMeshLinksSize = dtAlign4(36*t_offMeshConCount); | |
local data_index = data_start_index + headerSize | |
byte_stream.index = data_index | |
local vertex_data = pack(struct.unpack("<" .. string.rep("f", t_vertCount), byte_stream:read_bytes_str(4 * t_vertCount))) | |
print("Read " .. #vertex_data .. " vertices") | |
data_index = data_start_index + headerSize + vertsSize; | |
byte_stream.index = data_index | |
local poly_data = {} | |
for poly_index = 1, t_polyCount, 1 do | |
local poly = pack(struct.unpack("<IHHHHHHHHHHHHHBB", byte_stream:read_bytes_str(34))) | |
poly_data[poly_index] = poly | |
end | |
print("read: " .. #poly_data .. " polygons expected: " .. t_polyCount) | |
data_index = data_start_index + headerSize + vertsSize + polysSize; | |
byte_stream.index = data_index | |
local link_data = {} | |
for link_index = 1, t_maxLinkCount, 1 do | |
local link = pack(struct.unpack("<LIBBBB", byte_stream:read_bytes_str(16))) | |
--print("link_index: " .. link_index .. " / " .. link[1]) | |
link_data[link_index] = link | |
end | |
print("read: " .. #link_data .. " links expected: " .. t_maxLinkCount) | |
data_index = data_start_index + headerSize + vertsSize + polysSize + linksSize; | |
byte_stream.index = data_index | |
local detail_mesh_data = {} | |
for link_index = 1, t_detailMeshCount, 1 do | |
local link = pack(struct.unpack("<IIBB", byte_stream:read_bytes_str(10))) | |
detail_mesh_data[link_index] = link | |
end | |
print("read: " .. #detail_mesh_data .. " detail meshes expected: " .. t_detailMeshCount) | |
data_index = data_start_index + headerSize + vertsSize + polysSize + linksSize + detailMeshesSize; | |
byte_stream.index = data_index | |
local detail_mesh_verts = {} | |
for link_index = 1, t_detailVertCount, 1 do | |
local link = pack(struct.unpack("<FFF", byte_stream:read_bytes_str(12))) | |
detail_mesh_verts[link_index] = link | |
end | |
print("read: " .. #detail_mesh_verts .. " detail mesh vert expected: " .. t_detailVertCount) | |
data_index = data_start_index + headerSize + vertsSize + polysSize + linksSize + detailMeshesSize + detailVertsSize; | |
byte_stream.index = data_index | |
local detail_mesh_tris = {} | |
for link_index = 1, t_detailTriCount, 1 do | |
local link = pack(struct.unpack("<B", byte_stream:read_bytes_str(1))) | |
detail_mesh_tris[link_index] = link | |
end | |
print("read: " .. #detail_mesh_tris .. " detail mesh tri expected: " .. t_detailTriCount) | |
local mmtile = { | |
header = { | |
magic = t_magic, | |
version = t_version, | |
x = t_x, | |
y = t_y, | |
layer = t_layer, | |
userId = t_userId, | |
polyCount = t_polyCount, | |
vertCount = t_vertCount, | |
maxLinkCount = t_maxLinkCount, | |
detailMeshCount = t_detailMeshCount, | |
detailVertCount = t_detailVertCount, | |
detailTriCount = t_detailTriCount, | |
bvNodeCount = t_bvNodeCount, | |
offMeshConCount = t_offMeshConCount, | |
offMeshBase = t_offMeshBase, | |
walkableHeight = t_walkableHeight, | |
walkableRadius = t_walkableRadius, | |
walkableClimb = t_walkableClimb, | |
BBox= { | |
Min = { | |
X = t_bMinX, | |
Y = t_bMinY, | |
Z = t_bMinZ | |
}, | |
Max = { | |
X = t_bMaxX, | |
Y = t_bMaxY, | |
Z = t_bMaxZ | |
} | |
}, | |
bvQuantFactor = t_bvQuantFactor | |
}, | |
verticies = vertex_data, | |
polys =poly_data, | |
links =link_data, | |
detailMeshs =detail_mesh_data, | |
detailMeshVerts = detail_mesh_verts, | |
detailMeshTris = detail_mesh_tris | |
} | |
return mmtile; | |
end | |
DumpNavMeshFile(file) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment