BMS Script
Code: Select all
endian big
get name FILENAME
string name + ".dec"
get lzo long
get version long
get subversion long
get files long
get TotalUncompSize long
get unk long
goto 0x20
comtype LZO1X
for i = 1 to files
get memoffset long
get size long
get zsize long
savepos offset
if size == zsize
append
log MEMORY_FILE offset zsize
append
else
append
clog MEMORY_FILE offset zsize size
append
endif
math offset + zsize
goto offset
Padding 0x10000
next i
log NAME 0 TotalUncompSize MEMORY_FILE
This is a great import with bones and materials.
Code: Select all
if (heapSize < 200000) then
heapSize = 30000000 -- allow ~ 40 MB instead of just 7.5 MB. Prevents "Runtime Error: Out of scripter memory"
fname = getOpenFileName \
caption:"NIER Model File" \
types:"NIER Model File(*.mdv)|*.mdv" \
historyCategory:"NIERObjectPresets"
f = fopen fname "rb"
fname2 = ((getFilenamePath fname) + (getFilenameFile fname)) + ".MDP.dec"
g = fopen fname2 "rb"
fn ReadBEShort fstream = (
short = readshort fstream #unsigned
short = bit.swapBytes short 2 1
b = (bit.get short 16)
for i = 17 to 32 do short = bit.set short i b
return short
)
fn PrintOffset Var =
(
local Var = Var
print ("This is the offset 0x" + (bit.intAsHex Var) as string)
Var
)
fn floatSwap2 f =
(
i = bit.floatAsInt f
h = bit.intashex i
while h.count < 8 do h = "0" + h
s = (substring h 7 2) + (substring h 5 2) + (substring h 3 2) + (substring h 1 2)
bit.intAsFloat (bit.hexasint s)
)
fn ReadBEword fstream = (
return (bit.swapBytes (readshort fstream #unsigned) 1 2)
)
fn convertTo32 input16 = (
inputAsInt = input16
sign = bit.get inputAsInt 16
exponent = (bit.shift (bit.and inputAsInt (bit.hexasint "7C00")) -10) as integer - 16
fraction = bit.and inputAsInt (bit.hexasint "03FF")
if sign==true then sign = 1 else sign = 0
exponentF = exponent + 127
--Ouput 32 bit integer representing a 32 bit float
outputAsFloat = bit.or (bit.or (bit.shift fraction 13) (bit.shift exponentF 23)) (bit.shift sign 31)
--Output Check
return bit.intasfloat outputasfloat
)
fn ReadBEHalfFloat fstream = (
return convertTo32(ReadBEword fstream)
)
fn ReadBElong fstream = (
long = readlong fstream
long = bit.swapBytes long 1 4
long = bit.swapBytes long 2 3
return long
)
fn ReadBEfloat fstream = (
return floatSwap2(readfloat fstream)
)
fn ReadFixedString bstream fixedLen =
(
local str = ""
for i = 1 to fixedLen do
(
str += bit.intAsChar (ReadByte bstream #unsigned)
)
str
)
struct weight_data
(
boneids,weights
)
--0x20 size is an lod can delete them
fseek f 0x10#seek_set
BoneOff = ReadBElong f + 0x80
fseek f 0x110#seek_set
NODToff = ReadBElong f + 0x100
heapoff = ReadBElong f + 0x100
fseek f 0x180#seek_set
MESH1 = ReadFixedString f 4
MESH1Size = ReadBElong f
MESH1Off = (ftell f) + MESH1Size
REM0 = ReadFixedString f 4
REM0Size = ReadBElong f
REM0Name = ReadFixedString f REM0Size
STRB = ReadFixedString f 4
STRBSize = ReadBElong f
STRBOff = (ftell f) + STRBSize
STRBCount = ReadBElong f
STRL = ReadFixedString f 4
STRLSize = ReadBElong f
Name2_Array = #()
for a = 1 to STRBCount Do (
Name2 = readstring f
append Name2_Array Name2
)
print Name2_Array
fseek f STRBOff#seek_set
meditMaterials[1] = Multimaterial ()
MatID_array = #()
MatSlotTexID = #()
While (ftell f) != MESH1Off Do (
Name1 = ReadFixedString f 4
print Name1
Name1Size = ReadBElong f
if Name1 == "DSNA" Do (
fseek f Name1Size#seek_cur
)
if Name1 == "TRSP" Do (
fseek f Name1Size#seek_cur
)
if Name1 == "EFFE" Do (
fseek f 0x10#seek_cur
)
if Name1 == "TPAS" Do (
fseek f Name1Size#seek_cur
)
if Name1 == "CSTS" Do (
fseek f 0x4#seek_cur
)
if Name1 == "CSTV" Do (
fseek f Name1Size#seek_cur
)
if Name1 == "SAMP" Do (
MatID = ReadBElong f + 1
append MatID_array MatID
print ("This is the material info for slot " + MatID as string)
)
if Name1 == "SSTV" Do (
MatSlot = ReadBElong f
TexID = ReadBElong f + 1
MatNameID = ReadBElong f
if MatSlot == 29 Do (
print ("The Diffuse Texture is " + Name2_Array[TexID])
meditMaterials[1].materialList[MatID_array.count].diffuseMap = Bitmaptexture fileName:((getFilenamePath fname) + (Name2_Array[TexID] + ".tga"))
meditMaterials[1].materialList[MatID_array.count].opacityMap = Bitmaptexture fileName:((getFilenamePath fname) + (Name2_Array[TexID] + ".tga"))
meditMaterials[1].materialList[MatID_array.count].opacityMap.monoOutput = 1
meditMaterials[1].materialList[MatID_array.count].opacityMapEnable = on
meditMaterials[1].materialList[MatID_array.count].diffuseMap.alphaSource = 2
)
if MatSlot == 32 Do (
print ("The Normal Texture is " + Name2_Array[TexID])
meditMaterials[1].materialList[MatID_array.count].bumpMap = Normal_Bump ()
meditMaterials[1].materialList[MatID_array.count].bumpMap.normal_map = Bitmaptexture fileName:((getFilenamePath fname) + (Name2_Array[TexID] + ".tga"))
meditMaterials[1].materialList[MatID_array.count].bumpMap.normal_map.Output.Invert = true
)
if MatSlot == 35 Do (
print ("The Specular Texture is " + Name2_Array[TexID])
meditMaterials[1].materialList[MatID_array.count].specularLevelMap = Bitmaptexture fileName:((getFilenamePath fname) + (Name2_Array[TexID] + ".tga"))
meditMaterials[1].materialList[MatID_array.count].specularLevelMapEnable = off
)
if MatSlot == 44 Do (
print ("The 2nd Normal Texture is " + Name2_Array[TexID])
meditMaterials[1].materialList[MatID_array.count].specularMap = Bitmaptexture fileName:((getFilenamePath fname) + (Name2_Array[TexID] + ".tga"))
meditMaterials[1].materialList[MatID_array.count].specularMapEnable = off
)
)
if Name1 == "MATE" Do (
MatSlotID = ReadBElong f + 1
MatSlotN1 = ReadBElong f + 1
MatSlotN2 = ReadBElong f + 1
MatSlotID2 = ReadBElong f
MatSlotTexID1 = ReadBElong f + 1
MatSlotN = ReadBElong f
MatSlotN = ReadBElong f
MatSlotTexID2 = ReadBElong f + 1
meditMaterials[1].names[MatSlotID] = Name2_Array[MatSlotN1]
meditMaterials[1][MatSlotID].name = Name2_Array[MatSlotN2]
)
if Name1 == "VARI" Do (
fseek f 0x10#seek_cur
)
if Name1 == "PRIM" Do (
MshSlotID = ReadBElong f
MshSlotID = ReadBElong f
MshSlotID = ReadBElong f
MshSlotID = ReadBElong f
MshSlotID = ReadBElong f
MshMatID = ReadBElong f + 1
MshSlotID = ReadBElong f
append MatSlotTexID MshMatID
)
if Name1 == "BONE" Do (
fseek f 0x4#seek_cur
)
if Name1 == "BOIF" Do (
fseek f Name1Size#seek_cur
)
if Name1 == "IMTX" Do (
fseek f Name1Size#seek_cur
)
if Name1 == "" Do (
)
)
fseek f BoneOff#seek_set
CJF = ReadFixedString f 4
RigName = ReadFixedString f 0x20
BoneCount = ReadBElong f
Unk01Count = ReadBElong f
BoneNameStart = ReadBElong f + BoneOff
Unk01Start = ReadBElong f + BoneOff
BoneParentStart = ReadBElong f + BoneOff
BoneMatrixStart = ReadBElong f + BoneOff
BoneInvMatrixStart = ReadBElong f + BoneOff
Bone_Name_Array = #()
Bone_Parent_Array = #()
struct Bone_Info_Struct
(
BonePID01,BonePID02,BonePID03
)
fseek f BoneNameStart#seek_set
with undo off with redraw off for a = 1 to BoneCount Do (
Unk01 = ReadBElong f
BoneName = ReadFixedString f 0x20
append Bone_Name_Array BoneName
)
print Bone_Name_Array
fseek f BoneParentStart#seek_set
with undo off with redraw off for a = 1 to BoneCount Do (
BonePID01 = ReadBEword f + 1
append Bone_Parent_Array BonePID01
)
print Bone_Parent_Array
fseek f BoneMatrixStart#seek_set
BNArr = #()
with undo off with redraw off for a = 1 to BoneCount Do (
m11 = ReadBEFloat f; m12 = ReadBEFloat f; m13 = ReadBEFloat f; m14 = ReadBEFloat f
m21 = ReadBEFloat f; m22 = ReadBEFloat f; m23 = ReadBEFloat f; m24 = ReadBEFloat f
m31 = ReadBEFloat f; m32 = ReadBEFloat f; m33 = ReadBEFloat f; m34 = ReadBEFloat f
m41 = ReadBEFloat f; m42 = ReadBEFloat f; m43 = ReadBEFloat f; m44 = ReadBEFloat f
tfm = matrix3 [m11,m12,m13] [m21,m22,m23] [m31,m32,m33] [m41,m42,m43]
newBone = bonesys.createbone \
tfm.row4 \
(tfm.row4 + 0.01 * (normalize tfm.row1)) \
(normalize tfm.row3)
newBone.name = Bone_Name_Array[a]
newBone.width = 0.01
newBone.height = 0.01
newBone.transform = tfm
newBone.setBoneEnable false 0
newBone.wirecolor = yellow
newbone.showlinks = true
newBone.pos.controller = TCB_position ()
newBone.rotation.controller = TCB_rotation ()
append BNArr newBone
)
with undo off with redraw off for a = 1 to BoneCount Do (
select BNArr[a]
if (Bone_Parent_Array[a] != 0) then
$.parent = BNArr[(Bone_Parent_Array[a])]
)
fseek f heapoff#seek_set
HEAP = ReadFixedString f 4
Null1= ReadBElong f
SectSize= ReadBElong f
Heap1Size= ReadBElong f
Count1= ReadBElong f
NameSize= ReadBElong f
Null1= ReadBElong f
HeapCount= ReadBElong f
myoff = (ftell f)
fseek f (heapoff + Heap1Size)#seek_set
Mesh_Name_array = #()
while (ftell f) <= (heapoff + Count1) do (
Mesh_Name = readstring f
if Mesh_Name != "" do (
append Mesh_Name_array Mesh_Name
)
)
print Mesh_Name_array
fseek f myoff#seek_set
IXBF_array = #()
VXBF_array = #()
VXST_array = #()
struct Mesh_Info_Struct
(
HEAPID,Size,Offset,TotalSize
)
for a = 1 to HeapCount do (
HEAPID = ReadFixedString f 4
print HEAPID
fseek f 0x1C#seek_cur
if HEAPID == "IXBF" do (
fseek f -0x10#seek_cur
Size = ReadBElong f
Offset = ReadBElong f
TotalSize = ReadBElong f
Null1 = ReadBElong f
append IXBF_array (Mesh_Info_Struct HEAPID:HEAPID Size:Size Offset:Offset TotalSize:TotalSize)
)
if HEAPID == "VXBF" do (
fseek f -0x10#seek_cur
Size = ReadBElong f
Offset = ReadBElong f
TotalSize = ReadBElong f
Null1 = ReadBElong f
append VXBF_array (Mesh_Info_Struct HEAPID:HEAPID Size:Size Offset:Offset TotalSize:TotalSize)
)
if HEAPID == "VXST" do (
fseek f -0x14#seek_cur
Offset = (ReadBElong f) + ((Count1 + heapoff) + 0x30)
print Offset
fseek f 0x10#seek_cur
append VXST_array Offset
)
)
print IXBF_array
print VXBF_array
print VXST_array
vsize_array = #()
for a = 1 to VXST_array.count do (
fseek f VXST_array[a]#seek_set
vertsize = ReadBElong f
append vsize_array vertsize
)
print vsize_array
with undo off with redraw off for a = 1 to IXBF_array.count Do (
Vert_array = #()
Normal_array = #()
UV_array = #()
Face_array = #()
used_id_array =#()
Weight_array = #()
fseek g IXBF_array[a].offset#seek_set
FaceEnd = (IXBF_array[a].offset + (IXBF_array[a].TotalSize))
StartDirection = -1
f1 = ReadBEword g + 1
f2 = ReadBEword g + 1
IndexCounter = 2
FaceDirection = StartDirection
do (
f3 = ReadBEword g
IndexCounter += 1
if (f3==0xFFFF) then (
f1 = ReadBEword g + 1
f2 = ReadBEword g + 1
IndexCounter += 2
FaceDirection = StartDirection
) else (
f3 += 1
FaceDirection *= -1
if (f1!=f2)AND(f2!=f3)AND(f3!=f1) then (
if FaceDirection > 0 then append Face_array [(f1),(f2),(f3)]
else append Face_array [(f1),(f3),(f2)]
)
f1 = f2
f2 = f3
)
)while (ftell g) <= FaceEnd
printoffset (ftell g)
fseek g VXBF_array[a].offset#seek_set
VertCount = (VXBF_array[a].TotalSize / vsize_array[a])
for b = 1 to VertCount Do (
if vsize_array[a] == 12 do (
vx = ReadBEfloat g
vy = ReadBEfloat g
vz = ReadBEfloat g
tu =0
tv = 0
weight1 = 0
weight2 = 0
weight3 = 0
weight4 = 0
bone1 = 1
bone2 = 1
bone3 = 1
bone4 = 1
)
if vsize_array[a] == 20 do (
vx = ReadBEfloat g
vy = ReadBEfloat g
vz = ReadBEfloat g
tu = 0
tv = 0
weight1 = readbyte g#unsigned
weight2 = readbyte g#unsigned
weight3 = readbyte g#unsigned
weight4 = readbyte g#unsigned
bone1 = readbyte g#unsigned
bone2 = readbyte g#unsigned
bone3 = readbyte g#unsigned
bone4 = readbyte g#unsigned
)
if vsize_array[a] == 24 do (
vx = ReadBEfloat g
vy = ReadBEfloat g
vz = ReadBEfloat g
weight1 = readbyte g#unsigned
weight2 = readbyte g#unsigned
weight3 = readbyte g#unsigned
weight4 = readbyte g#unsigned
bone1 = readbyte g#unsigned
bone2 = readbyte g#unsigned
bone3 = readbyte g#unsigned
bone4 = readbyte g#unsigned
tu = ReadBEHalfFloat g * 2
tv = ReadBEHalfFloat g * -2
)
if vsize_array[a] == 28 do (
vx = ReadBEfloat g
vy = ReadBEfloat g
vz = ReadBEfloat g
vx = ReadBEfloat g
vy = ReadBEfloat g
vz = ReadBEfloat g
weight1 = readbyte g#unsigned
weight2 = readbyte g#unsigned
weight3 = readbyte g#unsigned
weight4 = readbyte g#unsigned
bone1 = readbyte g#unsigned
bone2 = readbyte g#unsigned
bone3 = readbyte g#unsigned
bone4 = readbyte g#unsigned
tu = ReadBEHalfFloat g * 2
tv = ReadBEHalfFloat g * -2
unk24 = ReadBEfloat g
)
if vsize_array[a] == 32 do (
vx = ReadBEfloat g
vy = ReadBEfloat g
vz = ReadBEfloat g
weight1 = readbyte g#unsigned
weight2 = readbyte g#unsigned
weight3 = readbyte g#unsigned
weight4 = readbyte g#unsigned
bone1 = readbyte g#unsigned
bone2 = readbyte g#unsigned
bone3 = readbyte g#unsigned
bone4 = readbyte g#unsigned
nz = ReadBEfloat g
tu = ReadBEHalfFloat g * 2
tv = ReadBEHalfFloat g * -2
unk24 = ReadBEfloat g
)
if vsize_array[a] == 36 do (
vx = ReadBEfloat g
vy = ReadBEfloat g
vz = ReadBEfloat g
weight1 = readbyte g#unsigned
weight2 = readbyte g#unsigned
weight3 = readbyte g#unsigned
weight4 = readbyte g#unsigned
bone1 = readbyte g#unsigned
bone2 = readbyte g#unsigned
bone3 = readbyte g#unsigned
bone4 = readbyte g#unsigned
nz = ReadBEfloat g
tu = ReadBEHalfFloat g * 2
tv = ReadBEHalfFloat g * -2
unk24 = ReadBEfloat g
unk24 = ReadBEfloat g
)
if vsize_array[a] == 40 do (
vx = ReadBEfloat g
vy = ReadBEfloat g
vz = ReadBEfloat g
weight1 = readbyte g#unsigned
weight2 = readbyte g#unsigned
weight3 = readbyte g#unsigned
weight4 = readbyte g#unsigned
bone1 = readbyte g#unsigned
bone2 = readbyte g#unsigned
bone3 = readbyte g#unsigned
bone4 = readbyte g#unsigned
nz = ReadBEfloat g
tu = ReadBEHalfFloat g * 2
tv = ReadBEHalfFloat g * -2
unk24 = ReadBEfloat g
unk24 = ReadBEfloat g
unk24 = ReadBEfloat g
)
if vsize_array[a] == 44 do (
vx = ReadBEfloat g
vy = ReadBEfloat g
vz = ReadBEfloat g
weight1 = readbyte g#unsigned
weight2 = readbyte g#unsigned
weight3 = readbyte g#unsigned
weight4 = readbyte g#unsigned
bone1 = readbyte g#unsigned
bone2 = readbyte g#unsigned
bone3 = readbyte g#unsigned
bone4 = readbyte g#unsigned
nz = ReadBEfloat g
tu = ReadBEHalfFloat g * 2
tv = ReadBEHalfFloat g * -2
unk24 = ReadBEfloat g
unk24 = ReadBEfloat g
unk24 = ReadBEfloat g
unk24 = ReadBEfloat g
)
if vsize_array[a] == 48 do (
vx = ReadBEfloat g
vy = ReadBEfloat g
vz = ReadBEfloat g
weight1 = readbyte g#unsigned
weight2 = readbyte g#unsigned
weight3 = readbyte g#unsigned
weight4 = readbyte g#unsigned
bone1 = readbyte g#unsigned
bone2 = readbyte g#unsigned
bone3 = readbyte g#unsigned
bone4 = readbyte g#unsigned
nz = ReadBEfloat g
tu = ReadBEHalfFloat g * 2
tv = ReadBEHalfFloat g * -2
unk24 = ReadBEfloat g
unk24 = ReadBEfloat g
unk24 = ReadBEfloat g
unk24 = ReadBEfloat g
unk24 = ReadBEfloat g
)
w = (weight_data boneids:#() weights:#())
maxweight = 0
if(weight1 != 0) then
maxweight = maxweight + weight1
if(weight2 != 0) then
maxweight = maxweight + weight2
if(weight3 != 0) then
maxweight = maxweight + weight3
if(weight4 != 0) then
maxweight = maxweight + weight4
if(maxweight != 0) then
(
if(weight1 != 0) then
(
w1 = weight1 as float
append w.boneids (bone1 + 2)
append w.weights (w1 / 100)
append used_id_array (bone1)
)
if(weight2 != 0) then
(
w2 = weight2 as float
append w.boneids (bone2 + 2)
append w.weights (w2 / 100)
append used_id_array (bone2 )
)
if(weight3 != 0) then
(
w3 = weight3 as float
append w.boneids (bone3 + 2)
append w.weights (w3 / 100)
append used_id_array (bone3)
)
if(weight4 != 0) then
(
w4 = weight4 as float
append w.boneids (bone4 + 2)
append w.weights (w4 / 100)
append used_id_array (bone4)
)
)
append Weight_array w
append Vert_array [vx,vy,vz]
--append Normal_array [nx,ny,nz]
append UV_array [tu,tv,0]
)
msh = mesh vertices:Vert_array faces:Face_array
msh.numTVerts = UV_array.count
buildTVFaces msh
msh.name = Mesh_Name_array[a]
msh.material = meditMaterials[1].materialList[(MatSlotTexID[a])]
for j = 1 to UV_array.count do setTVert msh j UV_array[j]
for j = 1 to Face_array.count do setTVFace msh j Face_array[j]
for j = 1 to Normal_array.count do setNormal msh j Normal_array[j]
max modify mode
select msh
skinMod = skin ()
addModifier msh skinMod
for i = 1 to BNArr.count do
(
maxbone = getnodebyname BNArr[i].name
if i != BNArr.count then
skinOps.addBone skinMod maxbone 0
else
skinOps.addBone skinMod maxbone 1
)
modPanel.setCurrentObject skinMod
for i = 1 to Weight_array.count do (
w = Weight_array[i]
bi = #() --bone index array
wv = #() --weight value array
for j = 1 to w.boneids.count do
(
boneid = w.boneids[j]
weight = w.weights[j]
append bi boneid
append wv weight
)
skinOps.ReplaceVertexWeights skinMod i bi wv
)
max create mode
)
actionMan.executeAction 0 "63508" -- Views: Standard Display with Maps
fclose f
fclose g
if you have problems please tell me the file name