if (heapSize < 200000) then
        heapSize = 2000000 -- allow ~ 40 MB instead of just 7.5 MB. Prevents "Runtime Error: Out of scripter memory"

fname = getOpenFileName \
caption:"Open .flver from Mesh folder" \
types:"Dark Souls (*.flver)|*.flver" \
historyCategory:"DarkSoulsObjectPresets"
f = fopen fname "rb"

clearlistener()

fn readFixedString bstream fixedLen = (
local str = ""
for i = 1 to fixedLen do (
str += bit.intAsChar (ReadByte bstream #unsigned))
str
)

struct weight_data
(
	boneids,weights
)
struct Vertex_Info_Struct
(
VertexType, VertexSize,VertexCount,VertexOffset
)
struct Face_Info_Struct
(
FaceCount, FaceOffset,FaceSecSize
)


clearlistener()

fseek f 0x6 #seek_set
Endian = ReadShort f
VersionMajor=Readshort f
VersionMinor=Readshort f
dataOffset = Readlong f	
print (dataOffset as string)
dataSize = Readlong f	
count = Readlong f
numMat = Readlong f	
BoneCount = Readlong f		
numParts = Readlong f	
numMesh = Readlong f	

fseek f 0x54  #seek_set
SkipCount1 = readlong f	
SkipCount2 = readlong f	

fseek f 0x80  #seek_set
for a = 1 to count  do (
getPos = ftell f + 64
fseek f getPos #seek_set	
)		
for a = 1 to numMat do (
getPos = ftell f + 32
fseek f getPos #seek_set	
)	

Print ("Bone Start @ 0x"+((bit.intAsHex(ftell f))as string))
	
BNArr = #()
Vertex_Info	= #()
Face_Info = #()	
LodCount_Array = #()	
Bone_Names_Array = #()	
BoneMapCount_Array = #()
BoneMapOff_Array = #()	
BoneNameSizeArray = #()	
Trans_array = #()	
Rotation_array = #()	
Scale_array = #()	

BonePos=ftell f
	
for a = 1 to BoneCount/2 do (

fseek f 0xC #seek_cur
BoneNameSize1 = Readlong f	
fseek f 0x70 #seek_cur
Pos2=ftell f	
fseek f 0xC #seek_cur
BoneNameSize2 = Readlong f	
fseek f 0x70 #seek_cur		
	
fseek f Pos2 #seek_set	

fseek f 0xC #seek_cur
BoneNameSize3 = Readlong f	
fseek f 0x70 #seek_cur
Pos1=ftell f			
fseek f 0xC #seek_cur
BoneNameSize4 = Readlong f		
fseek f Pos1 #seek_set		

BoneNameSize_1=(BoneNameSize2-BoneNameSize1)
BoneNameSize_2=(BoneNameSize4-BoneNameSize3)	

append BoneNameSizeArray [BoneNameSize_1, BoneNameSize_2]
)

print BoneNameSizeArray

fseek f BonePos #seek_set

for a = 1 to BoneCount do (

fseek f 0xC #seek_cur

BPos=ftell f
BoneNameOff = Readlong f	
fseek f BoneNameOff #seek_set
BoneName=readFixedString f 12
fseek f BPos #seek_set
	
fseek f 0x74 #seek_cur
append Bone_Names_Array BoneName		
)

fseek f BonePos #seek_set

  for a = 1 to BoneCount do (
   getPos = ftell f + 128 
   px = readFloat f
   py = readFloat f
   pz = readFloat f
   BPosition = [px,py,pz]
   BoneNameOff = readlong f
   rx = readFloat f 
   ry = readFloat f 
   rz = readFloat f 
   BoneRotation = ((eulerAngles (RadToDeg (rx)) (RadToDeg (ry)) (RadToDeg (rz))) as quat)
   BoneParent = readShort f
   Unknown01 = readShort f
   sx = readFloat f
   sy = readFloat f
   sz = readFloat f
   BScale = [sx,sy,sz]
   Unk02 = readShort f
   Unk03 = readShort f
   fseek f getPos #seek_set 
	  
   bne = dummy showLinks:true showLinksOnly:true
   bne.scale = BScale
   bne.rotation =  conjugate BoneRotation
   bne.pos = BPosition
   append BNArr bne
   if BoneParent!=-1 then (
    bne.parent = BNArr[(BoneParent+1)]
    bne.transform *= bne.parent.transform   
   )
  )

Print ("Bone End @ 0x"+((bit.intAsHex(ftell f))as string))
	
for a = 1 to numParts do (
getPos = ftell f + 48	
fseek f 0x14 #seek_cur	
BoneMapCount= readlong f
Null = readlong f	
BoneMapOff = readlong f		
LodCount= readlong f	
fseek f 0xC #seek_cur		
fseek f getPos #seek_set	
append LodCount_Array LodCount
append BoneMapCount_Array BoneMapCount	
append BoneMapOff_Array	BoneMapOff 
)		

print BoneMapCount_Array

for a = 1 to numParts do (
if LodCount_Array[a]==1 then
(
LodId= Readlong f
Unk1= readbyte f	
Unk2= readbyte f
Unk3= readbyte f	
Unk4= readbyte f	
FaceCount= Readlong f	
FaceOffset= Readlong f	
FaceSecSize= Readlong f		
null= Readlong f	
null2= Readlong f
null3= Readlong f	
append Face_Info (Face_Info_Struct FaceCount:FaceCount FaceOffset:FaceOffset FaceSecSize:FaceSecSize )				
)
if LodCount_Array[a]>1 then
(
LodId= Readlong f
Unk1= readbyte f	
Unk2= readbyte f
Unk3= readbyte f	
Unk4= readbyte f	
FaceCount= Readlong f	
FaceOffset= Readlong f	
FaceSecSize= Readlong f		
null= Readlong f	
null2= Readlong f
null3= Readlong f	
append Face_Info (Face_Info_Struct FaceCount:FaceCount FaceOffset:FaceOffset FaceSecSize:FaceSecSize )					
for i = 1 to (LodCount_Array[a]-1) do (	
getPos = ftell f + 32			
fseek f getPos #seek_set	
)	
)

)	

Print ("Face Info End @ 0x"+((bit.intAsHex(ftell f))as string))

print Face_Info
	
for a = 1 to numParts do (
LodCount= Readlong f	
if LodCount==1 then fseek f 0x20 #seek_cur	
if LodCount==0 then fseek f 0x0 #seek_cur		
VertexType= Readlong f	
VertexSize= Readlong f	
VertexCount= Readlong f	
Unk1= Readlong f	
Unk2= Readlong f	
VertexSecSize= Readlong f	
VertexOffset= Readlong f	
append Vertex_Info (Vertex_Info_Struct VertexType:VertexType VertexSize:VertexSize VertexCount:VertexCount VertexOffset:VertexOffset)			
)	

print Vertex_Info

Print ("Vertex Info End @ 0x"+((bit.intAsHex(ftell f))as string))

for a = 1 to SkipCount1 do (
getPos = ftell f + 16		
fseek f getPos #seek_set	
)		
for a = 1 to SkipCount2 do (
getPos = ftell f + 32		
fseek f getPos #seek_set	
)	
	
for i = 1 to numParts do (
	
vertArray = #()
Facearray = #()	
UV_array = #()
Weight_array=#()
BoneMapIdArray	= #()	

BoneMapStart = BoneMapOff_Array[i]	
	
fseek f BoneMapStart #seek_set 
	
for i = 1 to BoneMapCount_Array[i] do (
BoneMapIds = readlong f	
append BoneMapIdArray (BoneMapIds+1)	
)

print BoneMapIdArray

FaceOffset=(dataOffset+(Face_Info[i].FaceOffset))		
fseek f (dataOffset+(Face_Info[i].FaceOffset)) #seek_set	
	
Print ("Face Start @ 0x"+((bit.intAsHex(ftell f))as string))	

StartDirection = 1
f1 = ((Readshort f) + 1) 
f2 = ((Readshort f) + 1) 
FaceDirection = StartDirection
while ((ftell f) < (FaceOffset + (Face_Info[i].FaceSecSize))) Do (
f3 = (Readshort f)
if (f3==0xFFFF) then (
f1 = ((Readshort f) + 1) 
f2 = ((Readshort f) + 1) 
FaceDirection = StartDirection 
) else (
f3 += 1
FaceDirection *= -1
if (f1!=f2)AND(f2!=f3)AND(f3!=f1) then (
if FaceDirection > 0 then append Facearray [f1,f2,f3]
else append Facearray [f1,f3,f2]
)
f1 = f2
f2 = f3
) 
) 
	
VertOffset=(dataOffset+(Vertex_Info[i].VertexOffset))	
fseek f (dataOffset+(Vertex_Info[i].VertexOffset))	 #seek_set	

Print ("Vertex Start @ 0x"+((bit.intAsHex(ftell f))as string))		
if Vertex_Info[i].VertexSize==48 then
for x = 1 to Vertex_Info[i].VertexCount do (
vx = Readfloat f
vy = Readfloat f
vz = Readfloat f
		
bone1 = readbyte f #unsigned	
bone2 = readbyte f #unsigned	
bone3 = readbyte f #unsigned	
bone4 = readbyte f #unsigned
	
weight1 = (readshort f /32767.00) 	
weight2 = (readshort f /32767.00) 
weight3 = (readshort f /32767.00)
weight4 = (readshort f /32767.00) 
	
fseek f 0x10 #seek_cur
	
tu=Readfloat f	
tv=Readfloat f*-1

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 + 1)
         append w.weights (w1)
      )
      if(weight2 != 0) then (
         w2 = weight2 as float
         append w.boneids (bone2 + 1)
         append w.weights (w2)
      )
      if(weight3 != 0) then (
         w3 = weight3 as float
         append w.boneids (bone3 + 1)
         append w.weights (w3)
      )
      if(weight4 != 0) then (
         w4 = weight4 as float
         append w.boneids (bone4 + 1)
        append w.weights (w4)
      )      
   )
append Weight_array w	
append vertArray [vx,vy,vz]
append UV_array [tu,tv,0]	
)	
if Vertex_Info[i].VertexSize==40 then
for x = 1 to Vertex_Info[i].VertexCount do (

vx = Readfloat f
vy = Readfloat f
vz = Readfloat f
		
bone1 = readbyte f #unsigned	
bone2 = readbyte f #unsigned	
bone3 = readbyte f #unsigned	
bone4 = readbyte f #unsigned
	
weight1 = (readshort f /32767.00) 	
weight2 = (readshort f /32767.00) 
weight3 = (readshort f /32767.00)
weight4 = (readshort f /32767.00) 
	
fseek f 0xC #seek_cur
	
tu=Readshort f/1024.00	
tv=(Readshort f/1024.00)*-1	

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 + 1)
         append w.weights (w1)
      )
      if(weight2 != 0) then (
         w2 = weight2 as float
         append w.boneids (bone2 + 1)
         append w.weights (w2)
      )
      if(weight3 != 0) then (
         w3 = weight3 as float
         append w.boneids (bone3 + 1)
         append w.weights (w3)
      )
      if(weight4 != 0) then (
         w4 = weight4 as float
         append w.boneids (bone4 + 1)
        append w.weights (w4)
      )      
   )
append Weight_array w	
append vertArray [vx,vy,vz]
append UV_array [tu,tv,0]	
)	
if Vertex_Info[i].VertexSize==36 then
for x = 1 to Vertex_Info[i].VertexCount do (

vx = Readfloat f
vy = Readfloat f
vz = Readfloat f
		
bone1 = readbyte f #unsigned	
bone2 = readbyte f #unsigned	
bone3 = readbyte f #unsigned	
bone4 = readbyte f #unsigned
	
weight1 = (readshort f /32767.00) 	
weight2 = (readshort f /32767.00) 
weight3 = (readshort f /32767.00)
weight4 = (readshort f /32767.00) 
	
fseek f 0x8 #seek_cur
	
tu=Readshort f/1024.00	
tv=(Readshort f/1024.00)*-1	

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 + 1)
         append w.weights (w1)
      )
      if(weight2 != 0) then (
         w2 = weight2 as float
         append w.boneids (bone2 + 1)
         append w.weights (w2)
      )
      if(weight3 != 0) then (
         w3 = weight3 as float
         append w.boneids (bone3 + 1)
         append w.weights (w3)
      )
      if(weight4 != 0) then (
         w4 = weight4 as float
         append w.boneids (bone4 + 1)
        append w.weights (w4)
      )      
   )
append Weight_array w	
append vertArray [vx,vy,vz]
append UV_array [tu,tv,0]	
)	

try(
msh = mesh vertices:vertArray faces:faceArray
msh.numTVerts = UV_array.count
buildTVFaces msh
for j = 1 to UV_array.count do setTVert msh j UV_array[j]
for j = 1 to faceArray.count do setTVFace msh j faceArray[j]
msh.displayByLayer = false
msh.backfacecull = false
msh.wirecolor = (color 230 200 210)

max modify mode
select msh
skinMod = skin ()
addModifier msh skinMod
for i = 1 to BoneMapIdArray.count do
(
	maxbone = BNArr[(BoneMapIdArray[i])] 
	if i != BoneMapIdArray.count then 
		skinOps.addBone skinMod maxbone 0
	else
		skinOps.addBone skinMod maxbone 1
)
modPanel.setCurrentObject skinMod
for i = 1 to (Vertex_Info[i].VertexCount) 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
   
)
)catch(format "Error!!!\n")
)

fclose f