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 .ski from Mesh folder" \
types:"SKI Mesh (*.ski)|*.ski" \
historyCategory:"SKIObjectPresets"
f = fopen fname "rb"

clearlistener()
fn readHalfFloat fstream = (
    hf=readshort fstream #unsigned
    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()
	
BoneNamesArray = #()	
fseek f 0x0 #seek_set
MOXBIKSA=readFixedString f 8
Version = ReadLong f
numSkinObjext = ReadLong f
numStaticObject = ReadLong f
Unk1 = ReadLong f
Unk2 = ReadLong f
numTexture = ReadLong f
numMaterial = ReadLong f
numUsedBones = ReadLong f
Unk3 = ReadLong f
numSkeletonBones = ReadLong f
fseek f 0x3C #seek_cur
if Version==8 then fseek f 0x0 #seek_cur	
if Version!=8 then	
for a = 1 to numUsedBones Do (
BoneNameSize = ReadLong f
BName = readFixedString f BoneNameSize
append BoneNamesArray BName	
)

	for i = 1 to numTexture do (
		texture_name_size = (readlong f)
		texture_name = readFixedString f texture_name_size
		)
		
if 	numMaterial==1 then 
if Version==9 then	
(	
Pos=ftell f		
Check=readlong f
if Check<100 then
(
fseek f Pos #seek_set	
fseek f 0x63 #seek_cur	
)
if Check>100 then
(	
fseek f Pos #seek_set		
(
		MtlName = readFixedString f 11
		fseek f 0x45 #seek_cur
)
)
)

if 	numMaterial==1 then
if Version==10 then 
(		
MatId = readlong f	
if MatId ==3 then
(		fseek f 0x5F #seek_cur
)		
if MatId ==7 then
(	
		fseek f 0x67 #seek_cur
		TexPathSize=readlong f
		TexPath = readFixedString f TexPathSize
		FF=readlong f
	    NSize = readlong f
	    Nname = readFixedString f NSize	
        fseek f 0x4 #seek_cur
		TexPathSize=readlong f
		TexPath = readFixedString f TexPathSize
		fseek f 0x8 #seek_cur	
)
if MatId ==8 then
(	
		fseek f 0x67 #seek_cur
		TexPathSize=readlong f
		TexPath = readFixedString f TexPathSize
		FF=readlong f
	    NSize = readlong f
	    Nname = readFixedString f NSize	
        fseek f 0x4 #seek_cur
		TexPathSize=readlong f
		TexPath = readFixedString f TexPathSize
		fseek f 0x9 #seek_cur	
)
if MatId ==12 then
(
		fseek f 0x67 #seek_cur
		TexPathSize=readlong f
		TexPath = readFixedString f TexPathSize
		FF=readlong f
	    NSize = readlong f
	    Nname = readFixedString f NSize	
        fseek f 0x2A #seek_cur
		TexPathSize=readlong f
		TexPath = readFixedString f TexPathSize
	     fseek f 0x3D #seek_cur	
)
if MatId ==14 then
(
		fseek f 0x67 #seek_cur
		TexPathSize=readlong f
		TexPath = readFixedString f TexPathSize
		if TexPathSize!=0 then (			
		FF=readlong f
	    NSize = readlong f
	    Nname = readFixedString f NSize	
        fseek f 0x2A #seek_cur
		TexPathSize2=readlong f
		TexPath = readFixedString f TexPathSize2
	    if TexPathSize2==0 then 			
		(
         fseek f 0x46 #seek_cur			
		TexPathSize3=readlong f
		TexPath = readFixedString f TexPathSize3		
		)	
	    if TexPathSize2!=0 then fseek f 0x4A #seek_cur
        )
		if TexPathSize==0 then (			
		FF=readlong f
	    NSize = readlong f
	    Nname = readFixedString f NSize	
        fseek f 0x2A #seek_cur
		TexPathSize2=readlong f
		TexPath = readFixedString f TexPathSize2
        fseek f 0x39 #seek_cur	
		TexPathSize3=readlong f
		TexPath = readFixedString f TexPathSize3
        fseek f 0xD #seek_cur			
)
)
if MatId ==15 then
(
		fseek f 0x67 #seek_cur
		TexPathSize=readlong f
		TexPath = readFixedString f TexPathSize
		if TexPathSize!=0 then (			
		FF=readlong f
	    NSize = readlong f
	    Nname = readFixedString f NSize	
        fseek f 0x2A #seek_cur
		TexPathSize2=readlong f
		TexPath = readFixedString f TexPathSize2
	    if TexPathSize2==0 then 			
		(
         fseek f 0x46 #seek_cur			
		TexPathSize3=readlong f
		TexPath = readFixedString f TexPathSize3
        fseek f 0x4 #seek_cur			
		)	
	    if TexPathSize2!=0 then fseek f 0x4E #seek_cur
        )
		if TexPathSize==0 then (			
		FF=readlong f
	    NSize = readlong f
	    Nname = readFixedString f NSize	
        fseek f 0x2A #seek_cur
		TexPathSize2=readlong f
		TexPath = readFixedString f TexPathSize2
        fseek f 0x39 #seek_cur	
		TexPathSize3=readlong f
		TexPath = readFixedString f TexPathSize3
        fseek f 0x11 #seek_cur			
)
)
if MatId ==16 then
(
		fseek f 0x67 #seek_cur
		TexPathSize=readlong f
		TexPath = readFixedString f TexPathSize
		if TexPathSize==0 then (			
		FF=readlong f
	    NSize = readlong f
	    Nname = readFixedString f NSize	
        fseek f 0x2A #seek_cur
		TexPathSize2=readlong f
		TexPath = readFixedString f TexPathSize2
        fseek f 0x39 #seek_cur	
		TexPathSize3=readlong f
		TexPath = readFixedString f TexPathSize3
        fseek f 0x21 #seek_cur			
)
       if TexPathSize!=0 then (		
		FF=readlong f
	    NSize = readlong f
	    Nname = readFixedString f NSize	
	    if NSize==0 then 
		(
		fseek f 0x4 #seek_cur
		TexPathSize=readlong f
		TexPath = readFixedString f TexPathSize
		fseek f 0x22 #seek_cur	
		TexPathSize3=readlong f	
		TexPath = readFixedString f TexPathSize3
		if TexPathSize3==0 then 
		(
		fseek f 0x46 #seek_cur	
		TexPathSize4=readlong f	
		TexPath = readFixedString f TexPathSize4	
		fseek f 0x14 #seek_cur	        			
		)	
		if TexPathSize3!=0 then  fseek f 0x5E #seek_cur		
		)	
)
)
if MatId ==19 then
(
		fseek f 0x7E #seek_cur
		TexPathSize=readlong f
		TexPath = readFixedString f TexPathSize
		FF=readlong f
	    NSize = readlong f
	    Nname = readFixedString f NSize	
        fseek f 0x2A #seek_cur
		TexPathSize=readlong f
		TexPath = readFixedString f TexPathSize
	     fseek f 0x37 #seek_cur	
)
)

if 	numMaterial!=1 then
if Version==10 then		
for i = 1 to numMaterial do (
MatId = readlong f
if MatId ==3 then
(		fseek f 0x5F #seek_cur
)	
if MatId ==7 then
(	
		fseek f 0x67 #seek_cur
		TexPathSize=readlong f
		TexPath = readFixedString f TexPathSize
		FF=readlong f
	    NSize = readlong f
	    Nname = readFixedString f NSize	
        fseek f 0x4 #seek_cur
		TexPathSize=readlong f
		TexPath = readFixedString f TexPathSize
		fseek f 0x8 #seek_cur	
)
if MatId ==8 then
(	
		fseek f 0x67 #seek_cur
		TexPathSize=readlong f
		TexPath = readFixedString f TexPathSize
		FF=readlong f
	    NSize = readlong f
	    Nname = readFixedString f NSize	
        fseek f 0x4 #seek_cur
		TexPathSize=readlong f
		TexPath = readFixedString f TexPathSize
		fseek f 0x9 #seek_cur	
)
if MatId ==12 then
(
		fseek f 0x67 #seek_cur
		TexPathSize=readlong f
		TexPath = readFixedString f TexPathSize
		FF=readlong f
	    NSize = readlong f
	    Nname = readFixedString f NSize	
        fseek f 0x2A #seek_cur
		TexPathSize=readlong f
		TexPath = readFixedString f TexPathSize
	     fseek f 0x3D #seek_cur	
)
if MatId ==14 then
(
		fseek f 0x67 #seek_cur
		TexPathSize=readlong f
		TexPath = readFixedString f TexPathSize
		if TexPathSize!=0 then (			
		FF=readlong f
	    NSize = readlong f
	    Nname = readFixedString f NSize	
        fseek f 0x2A #seek_cur
		TexPathSize2=readlong f
		TexPath = readFixedString f TexPathSize2
	    if TexPathSize2==0 then 			
		(
         fseek f 0x46 #seek_cur			
		TexPathSize3=readlong f
		TexPath = readFixedString f TexPathSize3		
		)	
	    if TexPathSize2!=0 then fseek f 0x4A #seek_cur
        )
		if TexPathSize==0 then (			
		FF=readlong f
	    NSize = readlong f
	    Nname = readFixedString f NSize	
        fseek f 0x2A #seek_cur
		TexPathSize2=readlong f
		TexPath = readFixedString f TexPathSize2
        fseek f 0x39 #seek_cur	
		TexPathSize3=readlong f
		TexPath = readFixedString f TexPathSize3
        fseek f 0xD #seek_cur			
)
)
if MatId ==15 then
(
		fseek f 0x67 #seek_cur
		TexPathSize=readlong f
		TexPath = readFixedString f TexPathSize
		if TexPathSize!=0 then (			
		FF=readlong f
	    NSize = readlong f
	    Nname = readFixedString f NSize	
        fseek f 0x2A #seek_cur
		TexPathSize2=readlong f
		TexPath = readFixedString f TexPathSize2
	    if TexPathSize2==0 then 	(
         fseek f 0x46 #seek_cur			
		TexPathSize3=readlong f
		TexPath = readFixedString f TexPathSize3
        fseek f 0x4 #seek_cur			
		)	
	    if TexPathSize2!=0 then fseek f 0x4E #seek_cur
        )
		if TexPathSize==0 then (			
		FF=readlong f
	    NSize = readlong f
	    Nname = readFixedString f NSize	
        fseek f 0x2A #seek_cur
		TexPathSize2=readlong f
		TexPath = readFixedString f TexPathSize2
        fseek f 0x39 #seek_cur	
		TexPathSize3=readlong f
		TexPath = readFixedString f TexPathSize3
        fseek f 0x11 #seek_cur			
)
)
if MatId ==16 then
(
		fseek f 0x67 #seek_cur
		TexPathSize=readlong f
		TexPath = readFixedString f TexPathSize
		if TexPathSize==0 then (			
		FF=readlong f
	    NSize = readlong f
	    Nname = readFixedString f NSize	
        fseek f 0x2A #seek_cur
		TexPathSize2=readlong f
		TexPath = readFixedString f TexPathSize2
        fseek f 0x39 #seek_cur	
		TexPathSize3=readlong f
		TexPath = readFixedString f TexPathSize3
        fseek f 0x21 #seek_cur			
)
       if TexPathSize!=0 then (		
		FF=readlong f
	    NSize = readlong f
	    Nname = readFixedString f NSize	
	    if NSize==0 then 
		(
		fseek f 0x4 #seek_cur
		TexPathSize=readlong f
		TexPath = readFixedString f TexPathSize
		fseek f 0x22 #seek_cur	
		TexPathSize3=readlong f	
		TexPath = readFixedString f TexPathSize3
		if TexPathSize3==0 then 
		(
		fseek f 0x46 #seek_cur	
		TexPathSize4=readlong f	
		TexPath = readFixedString f TexPathSize4	
		fseek f 0x14 #seek_cur	        			
		)	
		if TexPathSize3!=0 then  fseek f 0x5E #seek_cur		
		)	
)
)
if MatId ==19 then
(
		fseek f 0x7E #seek_cur
		TexPathSize=readlong f
		TexPath = readFixedString f TexPathSize
		FF=readlong f
	    NSize = readlong f
	    Nname = readFixedString f NSize	
        fseek f 0x2A #seek_cur
		TexPathSize=readlong f
		TexPath = readFixedString f TexPathSize
	     fseek f 0x37 #seek_cur	
)
)
		
Print ("Mat End @ 0x"+((bit.intAsHex(ftell f))as string))	

		
for a = 1 to numSkinObjext Do (
	
ModelNameSize = ReadLong f
ModelName = readFixedString f ModelNameSize
TextureID = ReadLong f
MatlID = ReadLong f
numVerts = ReadLong f
numFaces = ReadLong f
	
vertArray = #()
Facearray = #()	
UV_array = #()
Weight_array =#()
	
Print ("Vertex Start @ 0x"+((bit.intAsHex(ftell f))as string))		
	
if Version==9 then		
for x = 1 to numVerts Do (
vx = Readfloat f
vy = Readfloat f
vz = Readfloat f
	
weight1 = Readfloat f
weight2 = Readfloat f
weight3 = Readfloat f
weight4 = 0
	
bone1 = readbyte f #unsigned	
bone2 = readbyte f #unsigned	
bone3 = readbyte f #unsigned	
bone4 = readbyte f #unsigned	
	
n1= Readfloat f
n2 = Readfloat f
n3 = Readfloat f	
	
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,-vz,vy]*100)
append UV_array [tu,tv,0]	 
)		
	
if Version==10 then		
for x = 1 to numVerts Do (
vx = Readfloat f
vy = Readfloat f
vz = Readfloat f
	
weight1 = Readfloat f
weight2 = Readfloat f
weight3 = Readfloat f
weight4 = 0
	
bone1 = readbyte f #unsigned	
bone2 = readbyte f #unsigned	
bone3 = readbyte f #unsigned	
bone4 = readbyte f #unsigned	
	
n1= Readfloat f
n2 = Readfloat f
n3 = Readfloat f	
	
tu=ReadFloat f	
tv=ReadFloat f*-1

Unk1 = Readfloat f	

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,-vz,vy]*100)
append UV_array [tu,tv,0]	 
)	

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

for x = 1 to (numFaces/3) do 
(
f1 = (Readshort f #unsigned + 1) 
f2 = (Readshort f #unsigned + 1) 
f3 = (Readshort f #unsigned + 1) 
append Facearray [f3,f2,f1]
)

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

msh = mesh vertices:vertArray faces:faceArray
msh.numTVerts = UV_array.count
msh.name=ModelName
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 = true
msh.wirecolor = (color 230 200 210)

if Version==8 then
(				
try(
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 (numVerts) 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 "Failed - New VertType!!!\n")
)

if Version!=8 then
(	
try(
max modify mode
select msh
skinMod = skin ()
addModifier msh skinMod	
for i = 1 to numUsedBones do
(
	maxbone = getnodebyname BoneNamesArray[i] 
	if i != numUsedBones then 
		skinOps.addBone skinMod maxbone 0
	else
		skinOps.addBone skinMod maxbone 1
)
modPanel.setCurrentObject skinMod
for i = 1 to (numVerts) 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 "Failed - New VertType!!!\n")
)
)
  
for a = 1 to numStaticObject Do (
	
ModelNameSize = ReadLong f
ModelName = readFixedString f ModelNameSize
Unk1 = ReadLong f	
TextureID = ReadLong f
MatlID = ReadLong f
numVerts = ReadLong f
numFaces = ReadLong f
	
vertArray = #()
Facearray = #()	
UV_array = #()
	
Print ("Vertex Start @ 0x"+((bit.intAsHex(ftell f))as string))	

if Version==9 then	
for x = 1 to numVerts Do (
	
vx = Readfloat f
vy = Readfloat f
vz = Readfloat f
	
n1= Readfloat f
n2 = Readfloat f
n3 = Readfloat f	

tu=ReadFloat f	
tv=ReadFloat f*-1	
	
append vertArray ([-vx,-vz,vy]*100)
append UV_array [tu,tv,0]	 
)	
	
if Version==10 then	
for x = 1 to numVerts Do (
	
vx = Readfloat f
vy = Readfloat f
vz = Readfloat f
	
n1= Readfloat f
n2 = Readfloat f
n3 = Readfloat f	

tu=ReadFloat f	
tv=ReadFloat f*-1	
	
Unk1=ReadFloat f		
	
append vertArray ([-vx,-vz,vy]*100)
append UV_array [tu,tv,0]	 
)	

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

for x = 1 to (numFaces/3) do 
(
f1 = (Readshort f #unsigned + 1) 
f2 = (Readshort f #unsigned + 1) 
f3 = (Readshort f #unsigned + 1) 
append Facearray [f3,f2,f1]
)

try(
msh = mesh vertices:vertArray faces:faceArray
msh.numTVerts = UV_array.count
msh.name=ModelName	
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 = true
msh.wirecolor = (color 230 200 210)

)catch(format "Failed - Static Mesh Error!!!\n")
)

fclose f
