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:" (*.msh)|*.msh" \
historyCategory:"ISObjectPresets"
f = fopen fname "rb"

clearlistener()

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 Mesh_Info_Struct
(
VertexCount, VertexStart, FaceCount, FaceStart, VertexId, UsedBones, UsedBonesStart, VertexEnd
)		

clearlistener()

fseek f 0x24 #seek_set
BoneCount=readlong f

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

BNArr=#()	
for a = 1 to BoneCount do (
getPos = ftell f + 56	
BoneHash = readlong f #unsigned
Unk=readlong f	
BoneParent	= readlong f 
a11 = Readfloat f; a12 = Readfloat f; a13 = Readfloat f
a21 = Readfloat f; a22 = Readfloat f; a23 = Readfloat f; a24 = Readfloat f	
fseek f getPos #seek_set	
	
tfm = (quat a21 a22 a23 a24) as matrix3
tfm.row4 = (([a11,a12,a13]))
     		
	newBone = bonesys.createbone	\
				  tfm.row4	\
				  (tfm.row4 + 0.01 * (normalize tfm.row1)) \
				  (normalize tfm.row3)
			newBone.name = a as string
			newBone.width  = 0.01
			newBone.height = 0.01
			newBone.transform = tfm		  
			newBone.setBoneEnable false 0
			newBone.wirecolor = white
			newbone.showlinks = true
			newBone.pos.controller      = TCB_position ()
			newBone.rotation.controller = TCB_rotation ()
if (boneparent != -1) then
 newBone.parent = BNArr[(boneparent + 1)]							  
append BNArr newBone
)	

Print ("Bones End @ 0x"+((bit.intAsHex(ftell f))as string))	
	
rootRT = dummy name:"Main_Root" boxsize:[.1,.1,.1]
for b in BNArr where b.parent==undefined do b.parent = rootRT
rootRT.transform = (matrix3 [-1,0,0] [0,0,1] [0,-1,0] [0,0,0])		

readlong f
readlong f
readlong f
MeshCount=readlong f
MatCount=readlong f	
	
for i=1 to MeshCount do (
	
readlong f
readlong f
WShift=readlong f
VSecSize=readlong f
	
vertArray = #()
Facearray = #()	
UV_array = #()
Weight_array=#()
	
if WShift==2 then 	
for x = 1 to VSecSize/28 do (
getPos = ftell f + 28
vx = ReadFloat f
vy = ReadFloat f
vz = ReadFloat f
	
tu=ReadShort f	
tv=1.0-ReadShort f	
	
weight1 = 1.0
	
bone1 = 0
	
w = (weight_data boneids:#() weights:#())
maxweight = 0
	
if(weight1 != 0) then
   maxweight = maxweight + weight1

if(maxweight != 0) then (
      if(weight1 != 0) then (
         w1 = weight1 as float
         append w.boneids (bone1 + 1)
         append w.weights (w1 / 255.0)
      )
   )
append Weight_array w 	
fseek f getPos #seek_set		
append vertArray [-vx,-vz,vy]
append UV_array ([tu,tv,0]/1024.0)		
)		

if WShift==3 then 	
for x = 1 to VSecSize/32 do (
getPos = ftell f + 32
vx = ReadFloat f
vy = ReadFloat f
vz = ReadFloat f
	
tu=ReadShort f	
tv=1.0-ReadShort f	

fseek f 0x8 #seek_cur
	
weight3 = readbyte f #unsigned
weight2 = readbyte f #unsigned
weight1 = readbyte f #unsigned	
weight4 =readbyte f #unsigned	
	
bone1 = (readbyte f #unsigned)/WShift
bone2 = (readbyte f #unsigned)/WShift
bone3 = (readbyte f #unsigned)/WShift
bone4 = (readbyte f #unsigned)/WShift
	
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 / 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)
      )      
   )
append Weight_array w 	
fseek f getPos #seek_set		
append vertArray [-vx,-vz,vy]
append UV_array ([tu,tv,0]/1024.0)		
)	

Print ("Face Start @ 0x"+((bit.intAsHex(ftell f))as string))	
	
FSecSize=readlong f

for x=1 to 	(FSecSize/6) do (	
fa=readshort f #unsigned +1
fb=readshort f #unsigned +1
fc=readshort f #unsigned +1
append faceArray [fc,fb,fa]	
)	

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

msh = mesh vertices:vertArray faces:faceArray
msh.numTVerts = UV_array.count
msh.name=("IronSight MMO mesh: "+i as string)	
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]
	
max modify mode
select msh
skinMod = skin ()
addModifier msh skinMod
for i = 1 to BNArr.count do
(  
	maxbone = BNArr[i]
	if i != BNArr.count then 
		skinOps.addBone skinMod maxbone 0
	else
		skinOps.addBone skinMod maxbone 1
)
modPanel.setCurrentObject skinMod
for i = 1 to (vertArray.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
   
)
)

fclose f
