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:"Azera (*.model)|*.model" \
historyCategory:"AzeraObjectPresets"
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
)

clearlistener()

fseek f (0x20) #seek_set
ID=readlong f
fseek f (0x2C) #seek_set
VertSize=readshort f
fseek f (0x60) #seek_set
WVertexCount=readlong f

vertArray = #()
faceArray = #()
UV_array = #()
Weight_array=#()	
fseek f (0x10) #seek_set
SecEnd=readlong f

fseek f (SecEnd) #seek_set
fseek f (0x24) #seek_cur
Sec2Size=readlong f
Pos=ftell f
fseek f (0x12) #seek_cur
MeshNameSize=readlong f
MeshName=readFixedString f MeshNameSize
Print ("Mesh Name End @ 0x"+((bit.intAsHex(ftell f))as string))	
fseek f (Pos) #seek_set
fseek f (Sec2Size) #seek_cur	
fseek f (0x10) #seek_cur	
Sec3Size=readlong f
fseek f (Sec3Size) #seek_cur
fseek f (0x10) #seek_cur
Sec4Size=readlong f
fseek f (Sec4Size+12) #seek_cur

SKEL==readFixedString f 4
SKELSize=readlong f
Null=readshort f
BoneCount=readshort f

tarr = #()
rarr = #()
Barr = #()
Parr = #()	

for i=1 to BoneCount do (
	
BoneNameSize=readlong f
BoneName=(readFixedString f BoneNameSize)
BoneParent=readshort f+1	

getPos = ftell f + 56
	
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

fseek f getPos #seek_set	
			
tfm = (quat c33 c34 c41 c42) as matrix3
bvx=c24
bvy=c31
bvz=c32
	
append tarr [bvx,bvy,bvz]
append rarr tfm
append Barr BoneName		
append Parr BoneParent	
)	

BNArr = #()
for i = 1 to BoneCount Do (
if isvalidnode (getNodeByName Barr[i]) != true then (
tfm = rarr[i]
tfm.row4 = tarr[i]
newBone = bonesys.createbone   \
              tfm.row4   \
              (tfm.row4 + 0.01 * (normalize tfm.row1)) \
              (normalize tfm.row3)
         newBone.name = Barr[i]
         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 ()
if Parr[i]!=0 then (
newBone.parent=BNArr[(Parr[i])]	
newBone.transform *= newBone.parent.transform	
)					  
)
if isvalidnode (getNodeByName Barr[i]) == true then (
newBone = getNodeByName Barr[i]
)
append BNArr newBone
)
	
Print ("Bone End @ 0x"+((bit.intAsHex(ftell f))as string))	

fseek f (0xE) #seek_cur
WGHT=readFixedString f 4
WGHTSize=readlong f	
WGHTId=readlong f

for i=1 to WVertexCount do (
	
Bone1 = -1
Bone2 = -1
Bone3 = -1
Bone4 = -1
weight1 = 0
weight2 = 0
weight3 = 0
weight4 = 0	
	
WeightCount=readshort f		
	
if WeightCount == 1 then (
Bone1 = readshort f	
weight1 = readshort f #unsigned/65535.00	
)
if WeightCount == 2 then (
Bone1 = readshort f	
weight1 = readshort f #unsigned/65535.00	
Bone2 = readshort f	
weight2 = readshort f #unsigned/65535.00	
)
if WeightCount == 3 then (
Bone1 = readshort f	
weight1 = readshort f #unsigned/65535.00	
Bone2 = readshort f	
weight2 = readshort f #unsigned/65535.00	
Bone3 = readshort f	
weight3 = readshort f #unsigned/65535.00			
)
if WeightCount == 4 then (
Bone1 = readshort f	
weight1 = readshort f #unsigned/65535.00	
Bone2 = readshort f	
weight2 = readshort f #unsigned/65535.00	
Bone3 = readshort f	
weight3 = readshort f #unsigned/65535.00		
Bone4 = readshort f	
weight4 = readshort f #unsigned/65535.00				
)
w = (weight_data boneids:#() weights:#())
maxweight = 0
if(Bone1 != -1) then
	maxweight = maxweight + weight1
if(Bone2 != -1) then
	maxweight = maxweight + weight2
if(Bone3 != -1) then
	maxweight = maxweight + weight3
if(Bone4 != -1) then
	maxweight = maxweight + weight4

if(maxweight != 0) then (
		if(Bone1 != -1) then (
			w1 = weight1 as float
			append w.boneids (bone1 + 1)
			append w.weights w1
		)
		if(Bone2 != -1) then (
			w2 = weight2 as float
			append w.boneids (bone2 + 1)
			append w.weights w2
		)
		if(Bone3 != -1) then (
			w3 = weight3 as float
			append w.boneids (bone3 + 1)
			append w.weights w3
		)
		if(Bone4 != -1) then (
			w4 = weight4 as float
			append w.boneids (bone4 + 1)
			append w.weights w4
		)		
	)
append Weight_array w
)

-- print Weight_array
	
fseek f (0x2C) #seek_set
VertSize=readshort f
fseek f (0x60) #seek_set
VertexCount=readlong f
if Id==1 then (
fseek f (0xC) #seek_cur
readbyte f	
)	
if Id!=1 then (
fseek f (0x10) #seek_cur
readbyte f
)
Print ("Face Count @ 0x"+((bit.intAsHex(ftell f))as string))	
FaceCount=readlong f

if Id==1 then fseek f (0x80) #seek_set	
if Id!=1 then fseek f (0x86) #seek_set
	
Print ("Vert Start @ 0x"+((bit.intAsHex(ftell f))as string))	

if VertSize==44 then
for x=1 to VertexCount do (
getPos = ftell f + VertSize
vx = ReadFloat f
vy = ReadFloat f
vz = ReadFloat f
	
nx = ReadFloat f
ny = ReadFloat f
nz = ReadFloat f
	
tu =	ReadFloat f
tv =  ReadFloat f*-1		

tx = ReadFloat f
ty = ReadFloat f
tz = ReadFloat f
	
fseek f getPos #seek_set	
append vertArray ([vx,vy,vz])	
append UV_array ([tu,tv,0])		
)	
	
if VertSize==48 then
for x=1 to VertexCount do (
getPos = ftell f + VertSize
vx = ReadFloat f
vy = ReadFloat f
vz = ReadFloat f

nx = ReadFloat f
ny = ReadFloat f
nz = ReadFloat f

Null=readfloat f

tu =	ReadFloat f
tv =  ReadFloat f*-1	
	
tx = ReadFloat f
ty = ReadFloat f
tz = ReadFloat f	
	
fseek f getPos #seek_set	
append vertArray ([vx,vy,vz])	
append UV_array ([tu,tv,0])		
)

if VertSize==52 then
for x=1 to VertexCount do (
getPos = ftell f + VertSize
vx = ReadFloat f
vy = ReadFloat f
vz = ReadFloat f
	
nx = ReadFloat f
ny = ReadFloat f
nz = ReadFloat f

tu =	ReadFloat f
tv =  ReadFloat f*-1	
	
Null=readfloat f	
Null=readfloat f	
	
tx = ReadFloat f
ty = ReadFloat f
tz = ReadFloat f	
	
fseek f getPos #seek_set	
append vertArray ([vx,vy,vz])	
append UV_array ([tu,tv,0])		
)

if VertSize==56 then
for x=1 to VertexCount do (
getPos = ftell f + VertSize
vx = ReadFloat f
vy = ReadFloat f
vz = ReadFloat f

nx = ReadFloat f
ny = ReadFloat f
nz = ReadFloat f

Null=readfloat f

tu =	ReadFloat f
tv =  ReadFloat f*-1	
	
Null=readfloat f
Null=readfloat f

tx = ReadFloat f
ty = ReadFloat f
tz = ReadFloat f	
	
fseek f getPos #seek_set	
append vertArray ([vx,vy,vz])	
append UV_array ([tu,tv,0])		
)

if VertSize==60 then
for x=1 to VertexCount do (
getPos = ftell f + VertSize
vx = ReadFloat f
vy = ReadFloat f
vz = ReadFloat f

nx = ReadFloat f
ny = ReadFloat f
nz = ReadFloat f

Null=readfloat f

tu =	ReadFloat f
tv =  ReadFloat f*-1	
	
Null=readfloat f
Null=readfloat f

tx = ReadFloat f
ty = ReadFloat f
tz = ReadFloat f	
	
fseek f getPos #seek_set	
append vertArray ([vx,vy,vz])	
append UV_array ([tu,tv,0])		
)

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

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

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

try (	
msh = mesh vertices:vertArray faces:faceArray
msh.name = (MeshName) 
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 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
)	
)catch(format "Wrong Skel or Messed Bones!!\n")
	
fclose f