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 .mesh from Mesh folder" \
types:"RE2 Models (*.mes;*.mesh;*.*)|*.mes;*.mesh;*.*" \
historyCategory:"RE2ObjectPresets"
f = fopen fname "rb"

clearlistener()

fn readBElong fstream = (bit.swapBytes (bit.swapBytes (readlong fstream #unsigned) 1 4) 2 3)
	
fn readBEfloat fstream = (bit.intAsFloat (bit.swapBytes (bit.swapBytes (readlong fstream #unsigned) 1 4) 2 3))	
	
fn readBEword fstream = (
short = readshort fstream #unsigned
short = bit.swapBytes short 1 2
return short
)	

fn ReadBEHalfFloat fstream = 
	(
	hf=readBEword fstream
	sign = bit.get hf 16
	exponent = (bit.shift (bit.and hf (bit.hexasint "7C00")) -10) as integer - 16
	fraction = bit.and hf (bit.hexasint "03FF")
	if sign==true then sign = 1 else sign = 0
	exponentF = exponent + 127
	outputAsFloat = bit.or (bit.or (bit.shift fraction 13) \
	(bit.shift exponentF 23)) (bit.shift sign 31)
	return bit.intasfloat outputasfloat*2
)	

fn ReadHalfFloat fstream = 
	(
	hf=readshort fstream
	sign = bit.get hf 16
	exponent = (bit.shift (bit.and hf (bit.hexasint "7C00")) -10) as integer - 16
	fraction = bit.and hf (bit.hexasint "03FF")
	if sign==true then sign = 1 else sign = 0
	exponentF = exponent + 127
	outputAsFloat = bit.or (bit.or (bit.shift fraction 13) \
	(bit.shift exponentF 23)) (bit.shift sign 31)
	return bit.intasfloat outputasfloat*2
)

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 Bone_Info_Struct
(
	Bone1,Bone2,Bone3,Bone4
)
struct Weight_Info_Struct
(
	Weight1,Weight2,Weight3,Weight4
)
struct Mesh_Info_Struct
(
    DataOff,DataSize,DataCount
)	
struct Mesh_Info_Struct_2 
(
    DataOff2,DataSize2,DataCount2
)	
clearlistener()

BNArr=#()	
BNameArray=#()

fseek f (0x0) #seek_set
Magic=readlong f
if Magic!=1213416781 then fclose f
if Magic==1213416781 then (
unk=readbyte f
vertSize=readbyte f
UnkCount=readbyte f
MatCount=readbyte f	
FileSize=readlong f
readlong f	
SkelMapCount=readshort f
UnkMeshCount=readbyte f	
MMeshCount=readbyte f+1
GBBOff=readlong f
Print ("Start @ 0x"+((bit.intAsHex(ftell f))as string))		
DatOffFirst=readlong f		
fseek f (0x14) #seek_cur	
DatOff=readlong f	
fseek f (0x14) #seek_cur		
BBOff=readlong f
readlong f
MeshStartOff=readlong f
fseek f (0xC) #seek_cur		
BoneEnd=readlong f
readlong f	
BoneMapOff=readlong f	
fseek f (0xC) #seek_cur		
MatNameOff=readlong f	
	
fseek f (0x78) #seek_set	
NameOff=readlong f		
		
Print ("End @ 0x"+((bit.intAsHex(ftell f))as string))		

print ("Bone Related Section End "+BoneEnd as string)
	
print ("MeshInfo Related Section End "+DatOff as string)	

fseek f (DatOffFirst) #seek_set
UCount1=readbyte f	
UCount2=readbyte f	
VType=readbyte f
FType=readbyte f		

BMapArray=#()	
if DatOff!=0 then (	
fseek f (DatOff) #seek_set
BCount=readlong f
BMapCount=readlong f	
	
Print ("Bone Count @ 0x"+((bit.intAsHex(ftell f))as string))		
	
fseek f (8) #seek_cur	

Print ("Bone and Map Offsets @ 0x"+((bit.intAsHex(ftell f))as string))		
	
BParOff=readlong f	
readlong f
BOff=readlong f		
	
fseek f (20) #seek_cur	

Print ("BoneMap Start @ 0x"+((bit.intAsHex(ftell f))as string))	
	
for i=1 to BMapCount do (
BMap=readshort f #usigned+1
append BMapArray BMap	
)	
	
Print ("BoneMap End @ 0x"+((bit.intAsHex(ftell f))as string))	
	
fseek f (BParOff) #seek_set		
	
Print ("Bone Parent Start @ 0x"+((bit.intAsHex(ftell f))as string))	
	
BParArray=#()		
for i=1 to BCount do (
getPos = ftell f + 16
BoneId=readshort f #usigned+1
BPar=readshort f #usigned	
fseek f getPos #seek_set	
append BParArray BPar 	
)	
	
Print ("Bone Parent End @ 0x"+((bit.intAsHex(ftell f))as string))		
	
print ("This is Bones Count: "+BCount as string)	
print ("This is Bones Offset: "+BOff as string)	
	
fseek f (BOff) #seek_set	
	
Print ("Bone Start 1 @ 0x"+((bit.intAsHex(ftell f))as string))	

for i=1 to BCount do (	
getPos = ftell f + 64
fseek f getPos #seek_set									  
)		
	
for i=1 to BCount do (	
getPos = ftell f + 64
fseek f getPos #seek_set									  
)	

BonesStartMain=ftell f

for i=1 to BCount do (	
getPos = ftell f + 64
fseek f getPos #seek_set									  
)	

Print ("Bone/Mat Order Start @ 0x"+((bit.intAsHex(ftell f))as string))	
	
fseek f 16 #seek_cur

for i=1 to BCount do (
readshort f #usigned
)	
	
fseek f NameOff #seek_set	

Print ("Bone/Mat Order End @ 0x"+((bit.intAsHex(ftell f))as string))	

for i=1 to UCount2 do (
getPos = ftell f + 8
fseek f getPos #seek_set		
)	

Print ("Bone Name Offsets Start @ 0x"+((bit.intAsHex(ftell f))as string))	
	
for i=1 to BCount do (
getPos = ftell f + 8
BNameOff=readlong f
readlong f	
BnamePos=ftell f
fseek f BNameOff #seek_set	
BName=readstring f
fseek f BnamePos #seek_set		
fseek f getPos #seek_set	
append BNameArray BName	
)	

Print ("Bone Name Offsets End @ 0x"+((bit.intAsHex(ftell f))as string))	

fseek f BonesStartMain #seek_set	

Print ("Bone Start Main @ 0x"+((bit.intAsHex(ftell f))as string))	

for a=1 to BCount do (	
getPos = ftell f + 64
c11=readfloat f;c12=readfloat f;c13=readfloat f;c14=readfloat f
c21=readfloat f;c22=readfloat f;c23=readfloat f;c24=readfloat f
c31=readfloat f;c32=readfloat f;c33=readfloat f;c34=readfloat f
c41=readfloat f;c42=readfloat f;c43=readfloat f;c44=readfloat f	
fseek f getPos #seek_set	
	
tfm = matrix3 [c11,c12,c13] [c21,c22,c23] [c31,c32,c33] ([c41,c42,c43]*100)	
	
if isvalidnode (getNodeByName BNameArray[a]) != true then (
newBone = bonesys.createbone    \
                                      tfm.row4      \
                                      (tfm.row4 + 0.01 * (normalize tfm.row1)) \
                                      (normalize tfm.row3)
                            newBone.width  = 0.01
                            newBone.height = 0.01
							newBone.name = BNameArray[a]								  
                            newBone.transform = inverse tfm
                            newBone.setBoneEnable false 0
                            newBone.wirecolor = yellow
                            newbone.showlinks = true
                            newBone.pos.controller      = TCB_position ()
                            newBone.rotation.controller = TCB_rotation () 		
						    if (BParArray[a]!= -1) then
							newBone.parent = BNArr[(BParArray[a]+1)]					 
)	
if isvalidnode (getNodeByName BNameArray[a]) == true then (
newBone = getNodeByName BNameArray[a]
)
append BNArr newBone  									  
)	

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

VertexCountArray=#() 
FaceCountArray=#()
FaceStrideArray=#()
VertStrideArray=#()
MeshSubCountArray=#()
IdOffArray=#()
BMapCountArray=#()
VEnd1=#()	
FEnd1=#()	

fseek f (DatOffFirst) #seek_set
for i=1 to 1 do (
UCount1=readbyte f	
UCount2=readbyte f	
VType=readbyte f
FType=readbyte f	
IdCheck=readlong f
if i==1 then fseek f (0x38) #seek_cur	
if i!=1 then fseek f (0x8) #seek_cur	
OffOne=readlong f	
fseek f (OffOne) #seek_set	
OffTwo=readlong f	
fseek f (OffTwo) #seek_set
for i=1 to 1 do (
MeshCountTrue=readshort f
BMapCount=readBEword f
UnkLong=readlong f
MeshOff=readlong f
readlong f

append BMapCountArray BMapCount	
		
print 	(MeshCountTrue as string)
	
fseek f (MeshOff) #seek_set	
	
Print ("Mesh Offset @ 0x"+((bit.intAsHex(ftell f))as string))		
	
MeshOffArray=#()	
for i=1 to MeshCountTrue do (	
MeshOffStart=readlong f
Null=readlong f		
append MeshOffArray MeshOffStart
)	
	
for i=1 to MeshOffArray.count do (
fseek f (MeshOffArray[i]) #seek_set	
Print ("Mesh Info Start @ 0x"+((bit.intAsHex(ftell f))as string))		
MeshId=readbyte f+1
MeshStart=readbyte f
readshort f
readlong f
VertexCount=readlong f
FaceCount2=readlong f

print (MeshStart as string)	
for a=1 to MeshStart do (	
IdOff=readlong f	
FaceCount=readlong f	
FaceStride=readlong f	
VertStride=readlong f
append FaceStrideArray FaceStride
append VertStrideArray VertStride	
append FaceCountArray FaceCount	
append IdOffArray IdOff	
)
append MeshSubCountArray MeshStart
append VertexCountArray VertexCount 
print (VertexCountArray[i] as string)
print (FaceCountArray[i]  as string)
print (FaceStrideArray[i]  as string)
print (VertStrideArray[i]  as string)
)	

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

fseek f (MeshStartOff) #seek_set

Print ("MeshStartOff @ 0x"+((bit.intAsHex(ftell f))as string))	
	
fseek f (16) #seek_cur	
FaceOffset=readlong f	
readlong f	
TotalVBuffSize=readlong f
TotalFBuffSize=readlong f	
Buff1Count=readshort f
Buff2Count=readshort f	
fseek f (12) #seek_cur		
VBuff1Id=readshort f	
VBuff1Size=readshort f	
VBuffOff1=readlong f		
VBuff2Id=readshort f	
VBuff2Size=readshort f	
VBuffOff2=readlong f	
VBuff3Id=readshort f	
VBuff3Size=readshort f	
VBuffOff3=readlong f	
VBuff4Id=readshort f	
VBuff4Size=readshort f		
VBuffOff4=readlong f	
if Buff1Count==4 then fseek f (0) #seek_cur	
if Buff1Count!=4 then (
VBuff5Id=readshort f
VBuff5Size=readshort f	
VBuffOff5=readlong f		
)	

VertOffset=ftell f

print ("This is Vertex Size: "+VBuff1Size as string)

Print ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! @ 0x"+((bit.intAsHex(ftell f))as string))	

Vert1=#()
for i=1 to IdOffArray.count do (	
Face_array_Vert=#()		
fseek f (FaceOffset+(FaceStrideArray[i]*2)) #seek_set	
	
for x = 1 to FaceCountArray[i] do (
Vert=readshort f #unsigned + 1
append Face_array_Vert Vert
)	
sort Face_array_Vert
Vertex=(Face_array_Vert[FaceCountArray[i]])
append Vert1 (Vertex as integer)
)	
	
for i=1 to IdOffArray.count do (
		
Vert_array=#()
Face_array=#()
UV_array=#()	
UV_array2=#()	
Weight_array=#()	
	
fseek f (VertOffset+(VertStrideArray[i]*VBuff1Size)) #seek_set
	
Print ("Vertex Start @ 0x"+((bit.intAsHex(ftell f))as string))	
	
if VBuff1Size==12 then 	
for x =1 to Vert1[i] do (
getPos = ftell f + 12
	
vx = readFloat f
vy = readFloat f
vz = readFloat f	
	
fseek f getPos #seek_set			
append Vert_array ([vx,vy,vz]*100)	
)		

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

fseek f ((VertOffset+VBuffOff3)+(VertStrideArray[i]*VBuff3Size)) #seek_set	
	
Print ("Uv's Start @ 0x"+((bit.intAsHex(ftell f))as string))	
	
if VBuff3Size==4 then 	
for x =1 to Vert1[i] do (
getPos = ftell f + 4
	
tu=readHalfFloat f
tv=readHalfFloat f	
	
fseek f getPos #seek_set			
append UV_array [tu,(1.0-tv),0] 	
)		

Print ("Uv's End @ 0x"+((bit.intAsHex(ftell f))as string))
	
fseek f ((VertOffset+VBuffOff4)+(VertStrideArray[i]*VBuff4Size)) #seek_set	
	
Print ("Second Uv's Start @ 0x"+((bit.intAsHex(ftell f))as string))	
	
if VBuff4Size==4 then 	
for x =1 to Vert1[i] do (
getPos = ftell f + 4
	
tu2=readHalfFloat f
tv2=readHalfFloat f	
	
fseek f getPos #seek_set			
append UV_array2 [tu2,(1.0-tv2),0] 	
)		

Print ("Second Uv's End @ 0x"+((bit.intAsHex(ftell f))as string))	
	
if Buff1Count!=4 then (	
fseek f ((VertOffset+VBuffOff5)+(VertStrideArray[i]*VBuff5Size)) #seek_set	
	
Print ("Weights Start @ 0x"+((bit.intAsHex(ftell f))as string))	
	
if VBuff5Size==16 then 	
for x =1 to Vert1[i] do (
getPos = ftell f + 16
	
bone1 = readbyte f #unsigned	
bone2 = readbyte f #unsigned	
bone3 = readbyte f #unsigned	
bone4 = readbyte f #unsigned
bone5 = readbyte f #unsigned	
bone6 = readbyte f #unsigned	
bone7 = readbyte f #unsigned	
bone8 = readbyte f #unsigned	

weight1 = readbyte f #unsigned	
weight2 = readbyte f #unsigned	
weight3 = readbyte f #unsigned	
weight4 = readbyte f #unsigned		
weight5 = readbyte f #unsigned	
weight6 = readbyte f #unsigned	
weight7 = readbyte f #unsigned	
weight8 = readbyte f #unsigned	
	
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(weight5 != 0) then
   maxweight = maxweight + weight5
if(weight6 != 0) then
   maxweight = maxweight + weight6
if(weight7 != 0) then
   maxweight = maxweight + weight7
if(weight8 != 0) then
   maxweight = maxweight + weight8	


if(maxweight != 0) then (
      if(weight1 != 0) then (
         w1 = weight1 as float
         append w.boneids (bone1 + 1)
         append w.weights (w1/255.0)
      )
      if(weight2 != 0) then (
         w2 = weight2 as float
         append w.boneids (bone2 + 1)
         append w.weights (w2/255.0)
      )
      if(weight3 != 0) then (
         w3 = weight3 as float
         append w.boneids (bone3 + 1)
         append w.weights (w3/255.0)
      )
      if(weight4 != 0) then (
         w4 = weight4 as float
         append w.boneids (bone4 + 1)
        append w.weights (w4/255.0)
      )   
      if(weight5 != 0) then (
         w5 = weight5 as float
         append w.boneids (bone5 + 1)
         append w.weights (w5/255.0)
      )
      if(weight6 != 0) then (
         w6 = weight6 as float
         append w.boneids (bone6 + 1)
         append w.weights (w6/255.0)
      )
      if(weight7 != 0) then (
         w7 = weight7 as float
         append w.boneids (bone7 + 1)
         append w.weights (w7/255.0)
      )
      if(weight8 != 0) then (
         w8 = weight8 as float
         append w.boneids (bone8 + 1)
        append w.weights (w8/255.0)
      )   	  
   )		
fseek f getPos #seek_set	
append Weight_array w	   
)		

Print ("Weights End @ 0x"+((bit.intAsHex(ftell f))as string))		
)	
fseek f (FaceOffset+(FaceStrideArray[i]*2)) #seek_set	

Print ("Face Start @ 0x"+((bit.intAsHex(ftell f))as string))		
	
for x = 1 to FaceCountArray[i]/3 do (
fa=readshort f #unsigned + 1
fb=readshort f #unsigned+ 1
fc=readshort f #unsigned+ 1
append Face_array [fa,fb,fc] 	
)	

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

FaceEnd1=ftell f	

append VEnd1 VertexEnd1	
append FEnd1 FaceEnd1 	

try(	
msh = mesh vertices:Vert_array faces:Face_array
msh.numTVerts = UV_array.count
msh.name="Resident Evil 7: "+i as string
buildTVFaces msh
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]
	
max modify mode
select msh
skinMod = skin ()
addModifier msh skinMod
for i = 1 to BMapArray.count do
(
	maxbone = BNArr[BMapArray[i]]
	if i != BMapArray.count then 
		skinOps.addBone skinMod maxbone 0
	else
		skinOps.addBone skinMod maxbone 1
)
modPanel.setCurrentObject skinMod
for i = 1 to vert_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
)
)catch(format "Wrong Skeleton!!!\n")
)
------------------------------------------------------------------------------------------------------------------------------
)

fclose f 