Last active
February 16, 2019 21:29
-
-
Save hhrhhr/0969a85afce034015b8cd02ac2544477 to your computer and use it in GitHub Desktop.
Subnautica Below Zero: map export
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
@echo off | |
rem edit paths (input and output) | |
set MESH_DIR=b:\sub | |
set WORK_DIR=d:\tmp\subnautica\zero_work | |
set LUA=E:\devel\lua_x64\lua.exe | |
set LUA_DIR=%~dp0% | |
:convert | |
if exist %WORK_DIR%\obj rmdir /q /s %WORK_DIR%\obj | |
mkdir %WORK_DIR%\obj | |
pushd %WORK_DIR%\obj | |
for /r %MESH_DIR% %%i in (*.dat) do ( | |
%LUA% "%LUA_DIR%\mesh2obj.lua" "%%i" | |
) | |
popd | |
:merge | |
if exist %WORK_DIR%\level rmdir /q /s %WORK_DIR%\level | |
mkdir %WORK_DIR%\level | |
pushd %WORK_DIR%\level | |
for /l %%i in (0 1 24) do ( | |
echo %%i | |
copy /y "%WORK_DIR%\obj\*-%%i-*.obj" level-%%i.obj | |
) | |
popd | |
:eof | |
pause |
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
assert(_VERSION == "Lua 5.3") | |
local function convert(fn) | |
local r | |
local su = string.unpack | |
local function uint16() | |
local res, _ = su("H", r:read(2)) | |
return res | |
end | |
local function uint32() | |
local res, _ = su("I4", r:read(4)) | |
return res | |
end | |
local function str(len) | |
return r:read(len) | |
end | |
local function float() | |
local res, _ = su("f", r:read(4)) | |
if res ~= res then res = 0.0 end | |
return res | |
end | |
r = assert(io.open(fn, "rb")) | |
local point = {} | |
local normal = {} | |
local face = {} | |
local sz = uint32() | |
local name = str(sz) | |
local tail = sz % 4 | |
if tail > 0 then r:read(4 - tail) end | |
r:read(8) -- 1, 0 | |
local idxs = uint32() | |
r:read(12) -- 0, 0, 0 | |
local points = uint32() | |
-- local center = { float(), float(), float() } | |
-- local extent = { float(), float(), float() } | |
r:read(60) | |
print(("%s\t%d indices, %d points"):format(name, idxs, points)) | |
-- print(("center: %s\nextent: %s"):format(table.concat(center, ", "), table.concat(extent, ", "))) | |
sz = uint32() | |
local faces = sz // 6 | |
-- print(("%d faces"):format(faces)) | |
for i = 1, faces do | |
local f1, f2, f3 = points-uint16(), points-uint16(), points-uint16() | |
table.insert(face, { f1, f3, f2 }) | |
end | |
r:read(64) | |
sz = uint32() | |
assert(points == sz // 24, "\n\n" .. points .. " != " .. sz // 24 .. "\n\n") | |
local X, Y, Z | |
for _x, _y, _z in name:gmatch("-(.+)-(.+)-(.+)") do | |
X = _x * 32.0 | |
Y = _y * 32.0 | |
Z = _z * -32.0 | |
end | |
for i = 1, points do | |
local x, y, z = float() + X, float() + Y, Z - float() | |
table.insert(point, { x, y, z }) | |
table.insert(normal, { float(), float(), -float() }) | |
end | |
r:read(16*10+4) | |
local center2 = { float(), float(), float() } | |
local extent2 = { float(), float(), float() } | |
--print(("center: %s\nextent: %s"):format(table.concat(center2, ", "), table.concat(extent2, ", "))) | |
r:read(4*3) | |
r:close() | |
--[[ write OBJ ]]-- | |
fn = name:sub(7) .. ".obj" | |
local w = assert(io.open(fn, "w+b")) | |
local fmt = { | |
head = "#o n_%s\n# %d points, %d faces\n", | |
point = "v %f %f %f\n", | |
normal = "vn %f %f %f\n", | |
group = "g g_%s\ns 1\n", | |
face = "f -%d//-%d -%d//-%d -%d//-%d\n" | |
} | |
w:write(fmt.head:format(name, points, faces)) | |
for i = 1, points do | |
local p = point[i] | |
w:write(fmt.point:format(p[1], p[2], p[3])) | |
end | |
-- don't export normals, recalculate it the Meshlab | |
--[[ | |
for i = 1, points do | |
local n = normal[i] | |
w:write(fmt.normal:format(n[1], n[2], n[3])) | |
end | |
]] | |
w:write(fmt.group:format(name)) | |
for i = 1, #face do | |
local f = face[i] | |
w:write(fmt.face:format(f[1], f[1], f[2], f[2], f[3], f[3])) | |
end | |
w:close() | |
end | |
convert(arg[1]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment