Created
February 13, 2022 16:48
-
-
Save warmist/f06b553621dd2d516b0f8d91f6da1e53 to your computer and use it in GitHub Desktop.
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
local fname="mp_forwardbase_kodai.ain" | |
local print_stuff=true | |
local save_nodes=true | |
local save_links=true | |
--[[ current struct layouts ]] | |
local MAX_HULLS=5 | |
local ain_file={ | |
{"u32","magic"}, | |
{"u32","mapver"}, | |
{"u32","crc"}, | |
{"u32","nodecount"}, | |
{"CAI_NodeDisk","nodes","nodecount"}, | |
{"u32","linkcount"}, | |
{"AINLink","links","linkcount"}, | |
{"u32","unk0","nodecount"}, | |
{"u16","unk1"}, | |
{"UnkStruct0","unk2","unk1"}, | |
{"UnkStruct1","unk3",MAX_HULLS}, | |
--[[ | |
{"u32","unk4"}, | |
{"UnkStruct3","unk5","unk4"}, | |
{"u32","unk6"}, | |
{"UnkStruct4","unk7","unk6"}, | |
{"u32","unk8"}, | |
{"u32","scriptnodecount"}, | |
{"AINScriptNode","scriptnodes","scriptnodecount"}, | |
{"u32","hintcount"}, | |
{"AINHint","hints","hintcount"}, | |
--]] | |
} | |
local ain_node={ | |
{"float","x"}, | |
{"float","y"}, | |
{"float","z"}, | |
{"float","yaw"}, | |
{"float","hulls",MAX_HULLS}, | |
{"s8","unk0"}, | |
{"u32","unk1"}, | |
{"u16","unk2",MAX_HULLS}, | |
{"s8","unk3",MAX_HULLS}, | |
{"u16","unk4"}, | |
{"u16","unk5"}, | |
{"s8","unk6",8}, | |
} | |
local ain_link={ | |
{"u16","srcID"}; | |
{"u16","destID"}; | |
{"u8","unk0",6}; | |
} | |
local unk0={ | |
{"u8","unk0",20} | |
} | |
local unk1={ | |
{"u32","unk0"}, | |
{"u16","unk1"}, | |
{"u16","unk2"}, | |
{"u32","unk3","unk2"},--originally u8 of unk2*4 | |
} | |
local typenames={ | |
CAI_NodeDisk=ain_node, | |
AINLink=ain_link, | |
UnkStruct0=unk0, | |
UnkStruct1=unk1, | |
} | |
local type_transforms={ | |
u32="I4", | |
u16="I2", | |
u8="I1", | |
s32="i4", | |
s16="i2", | |
s8="i1", | |
float="f", | |
double="d", | |
} | |
function opt_print( ... ) | |
if print_stuff then | |
print(...) | |
end | |
end | |
function byte_array_tohex( barr ) | |
local ret="" | |
for i=1,#barr do | |
ret=ret..string.format("%02x",barr[i]) | |
end | |
return ret | |
end | |
--prints typename | |
function print_tname( struct,tname,fname ) | |
if type(tname)=="string" then | |
opt_print(string.format("\t%20s\t%s",fname or "",tostring(struct))) | |
return | |
end | |
for i,v in ipairs(tname) do | |
opt_print(string.format("\t%20s\t%s",v[2],tostring(struct[v[2]]))) | |
end | |
end | |
--loads typename from a string | |
function load_typename(s,cp,tname) | |
--print("D:",cp/#s) | |
local ret={} | |
if type(tname)=="string" then | |
local tformat=type_transforms[tname] | |
if tformat~=nil then | |
ret,cp=string.unpack(tformat,s,cp) | |
return ret,cp | |
else | |
tformat=typenames[tname] | |
return load_typename(s,cp,tformat) | |
end | |
end | |
for i,v in ipairs(tname) do | |
--print(i,v,v[1],v[2],v[3]) | |
local tformat=type_transforms[v[1]] | |
local count=v[3] | |
if type(count)=="string" then | |
count=ret[count] | |
end | |
if count~=nil then | |
--if tformat==nil then tformat=typenames[v[1]] end | |
ret[v[2]],cp=load_array(s,cp,v[1],count) | |
else | |
if tformat~=nil then | |
ret[v[2]],cp=string.unpack(tformat,s,cp) | |
else | |
tformat=typenames[tname] | |
ret[v[2]],cp=load_typename(s,cp,tformat) | |
end | |
end | |
end | |
return ret,cp | |
end | |
--loads array of typename from a string | |
function load_array( s,cp,tname,count ) | |
--print(tname,count) | |
local ret={} | |
for i=1,count do | |
ret[i],cp=load_typename(s,cp,tname) | |
end | |
return ret,cp | |
end | |
function load_file( fname,typename ) | |
print(string.format("Loading:\t%20s\t=========================================",fname)) | |
local f=io.open(fname,"rb") | |
local s=f:read("a") | |
f:close() | |
local cp=1 | |
local loaded_file | |
loaded_file,cp=load_typename(s,cp,typename) | |
--assert(cp==#s) | |
return loaded_file | |
end | |
function cross_prod(a,b) | |
local ret={ | |
a[2]*b[3]-a[3]*b[2], | |
a[3]*b[1]-a[1]*b[3], | |
a[1]*b[2]-a[2]*b[1] | |
} | |
return ret | |
end | |
function length( v ) | |
return math.sqrt(v[1]*v[1]+v[2]*v[2]+v[3]*v[3]) | |
end | |
function normalize( v ) | |
local l=length(v) | |
return {v[1]/l,v[2]/l,v[3]/l} | |
end | |
function add_pt(a,b) | |
return {a[1]+b[1],a[2]+b[2],a[3]+b[3]} | |
end | |
function mult_pt( a,scalar) | |
return {a[1]*scalar,a[2]*scalar,a[3]*scalar} | |
end | |
function add_tube( out_verts,out_tris,pt_start,pt_end,radius ) | |
local dx={-1,-1,1,1} | |
local dz={1,-1,-1,1} | |
local s_pt={pt_start.x,pt_start.y,pt_start.z} | |
local e_pt={pt_end.x,pt_end.y,pt_end.z} | |
local con_d=add_pt(s_pt,mult_pt(e_pt,-1)) | |
local cd=normalize(con_d) | |
local ovec1=cross_prod(cd,{0,0,1}) | |
local ovec2=cross_prod(cd,ovec1) | |
local rad=radius | |
local vert_count_start=#out_verts | |
for i=1,4 do | |
local v=add_pt(s_pt,add_pt(mult_pt(ovec1,dx[i]*rad),mult_pt(ovec2,dz[i]*rad))) | |
table.insert(out_verts,string.format("%g %g %g\n",v[1],v[2],v[3])) | |
end | |
for i=1,4 do | |
local v=add_pt(e_pt,add_pt(mult_pt(ovec1,dx[i]*rad),mult_pt(ovec2,dz[i]*rad))) | |
table.insert(out_verts,string.format("%g %g %g\n",v[1],v[2],v[3])) | |
end | |
local tris={ | |
{0,1,5}, | |
{0,5,4}, | |
{1,2,5}, | |
{2,6,5}, | |
{3,2,6}, | |
{3,6,7}, | |
{0,3,4}, | |
{3,7,4} | |
} | |
for i,v in ipairs(tris) do | |
table.insert(out_tris,string.format("3 %d %d %d\n",v[1]+vert_count_start,v[2]+vert_count_start,v[3]+vert_count_start)) | |
end | |
end | |
function add_box( out_verts,out_tris,pt,radius ) | |
local dx={-1, 1, 1,-1,-1, 1, 1,-1} | |
local dy={-1,-1, 1, 1,-1,-1, 1, 1} | |
local dz={-1,-1,-1,-1, 1, 1, 1, 1} | |
local s_pt={pt.x,pt.y,pt.z} | |
local rad=radius | |
local vert_count_start=#out_verts | |
for i=1,8 do | |
local v=add_pt(s_pt,mult_pt({dx[i],dy[i],dz[i]},rad)) | |
table.insert(out_verts,string.format("%g %g %g\n",v[1],v[2],v[3])) | |
end | |
local tris={ | |
{0,1,5}, | |
{0,5,4}, | |
{1,2,5}, | |
{2,6,5}, | |
{3,6,2}, | |
{3,7,6}, | |
{0,4,3}, | |
{3,4,7}, | |
{2,1,0}, | |
{3,2,0}, | |
{6,4,5}, | |
{7,4,6}, | |
} | |
for i,v in ipairs(tris) do | |
table.insert(out_tris,string.format("3 %d %d %d\n",v[1]+vert_count_start,v[2]+vert_count_start,v[3]+vert_count_start)) | |
end | |
end | |
function print_recurse( t,tabs ) | |
tabs=tabs or 0 | |
if type(t)=="table" then | |
for k,v in pairs(t) do | |
print(string.rep("\t",tabs)..k) | |
print_recurse(v,tabs+1) | |
end | |
else | |
print(string.rep("\t",tabs)..t) | |
end | |
end | |
function save_ply(verts,tris,fname ) | |
print(string.format("Writing:\t%20s\t=========================================",fname)) | |
local ply_header= | |
[[ | |
ply | |
format ascii 1.0 | |
element vertex %d | |
property float x | |
property float y | |
property float z | |
element face %d | |
property list uchar int vertex_index | |
end_header | |
]] | |
local ply_data=ply_header:format(#verts,#tris)..table.concat(verts)..table.concat(tris) | |
local f_out=io.open (fname,"w") | |
f_out:write(ply_data) | |
f_out:close() | |
end | |
local lf=load_file(fname,ain_file) | |
--print_recurse(lf.unk3) | |
local verts={} | |
local tris={} | |
function add_nodes(node_file,verts,tris ) | |
for i,v in ipairs(node_file.nodes) do | |
add_box(verts,tris,v,16) | |
end | |
end | |
function fingerprint(tbl ) | |
local ret=0 | |
for i=1,6 do | |
ret=bit32.bor(ret,bit32.lshift(tbl[i],(i-1)*4)) | |
end | |
return ret | |
end | |
local fprints={} | |
local fprints_idx={ | |
"000404000404", | |
"000404040400", | |
"000000010001", | |
"000101000100", | |
"000100000000", | |
"000000000101", | |
"000101010101", | |
"000404040404", | |
"000100000100", | |
"000000010000", | |
"000100000101", | |
"000404000400", | |
"000000000100", | |
"000100010101", | |
"000101000101", | |
"000000000001", | |
"000100010100", | |
"000400000400", | |
} | |
function add_links(node_file,verts,tris,l) | |
local count_added=0 | |
for j,v in ipairs(node_file.links) do | |
local need_add=true | |
local s=node_file.nodes[v.srcID+1] | |
local e=node_file.nodes[v.destID+1] | |
--[[for i=1,6 do | |
if v.unk0[i]~=0 and v.unk0[i]~=1 then | |
need_add=false | |
end | |
end--]] | |
--print(fingerprint(v.unk0)) | |
--local ff=fingerprint(v.unk0) | |
local ff=byte_array_tohex(v.unk0) | |
if fprints[ff]==nil then | |
fprints[ff]=1 | |
else | |
fprints[ff]=fprints[ff]+1 | |
end | |
if l~=nil then | |
need_add=(ff==l) | |
end | |
if need_add then | |
add_tube(verts,tris,s,e,1) | |
count_added=count_added+1 | |
end | |
end | |
print("Added",count_added,"links") | |
for k,v in pairs(fprints) do | |
print("0x"..k,v) | |
end | |
end | |
if save_links then | |
add_nodes(lf,verts,tris) | |
end | |
-- [[ | |
--for i,v in ipairs(fprints_idx) do | |
--local verts={} | |
--local tris={} | |
if save_links then | |
add_links(lf,verts,tris,v) | |
end | |
if save_links or save_nodes then | |
save_ply(verts,tris,fname..".ply") | |
end | |
--end | |
--]] | |
--[[ | |
local new_nodes={ | |
} | |
for i,v in ipairs(new_nodes) do | |
add_box(verts,tris,{x=v[1],y=v[2],z=v[3]},16) | |
end | |
save_ply(verts,tris,"mp_wargames_loged.ply") | |
--]] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment