if (heapSize < 20000000) then
	heapSize = 200000000
fname = getOpenFileName \
caption:"Open .gr2 from Mesh folder" \
types:"SWTOR (*.gr2)|*.gr2" \
historyCategory:"SWTORObjectPresets"
f = fopen fname "rb"


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
)	

clearlistener()

struct weight_data
(
   boneids,weights
)
struct mesh_info_struct
(
BCount,FaceCount,VertCount,VertPos,FacePos,BonePos,VSize
)

clearlistener()

Mesh_InfoArray=#()

fseek f 0x8 #seek_set
Pos=ftell f
fseek f 0x14 #seek_set
unk_1=readlong f
MeshCount=readshort f
TexCount=readshort f
fseek f 0x34 #seek_cur
UnkOff=readlong f
MeshInfoOff=readlong f
NamesOff=readlong f
fseek f 0x14 #seek_cur
MeshNameOff=readlong f
fseek f (Pos+MeshInfoOff) #seek_set
Print ("Mesh Info @ 0x"+((bit.intAsHex(ftell f))as string))	
for i=1 to MeshCount do (
meshcount2=readshort f
BCount=readshort f
unk=readshort f	
VSize=readshort f
VertCount=readlong f
FaceCount=readlong f
VertPos=readlong f	
unk1=readlong f
FacePos=readlong f
BonePos=readlong f
unk2=readlong f
unk3=readlong f	
append Mesh_InfoArray (mesh_info_struct BCount:BCount FaceCount:FaceCount VertCount:VertCount VertPos:VertPos FacePos:FacePos BonePos:BonePos VSize:VSize)	
)

print Mesh_InfoArray

for i=1 to MeshCount do (
	
fseek f Mesh_InfoArray[i].VertPos #seek_set
	
Print ("Vertex Start @ 0x"+((bit.intAsHex(ftell f))as string))	
	
BNArr = #()
vertArray=#()
faceArray =#()
UVarray=#()
Weight_array=#()
BoneNamesArray=#()	

if (Mesh_InfoArray[i].VSize)==12 then
for x =1 to Mesh_InfoArray[i].VertCount do (
getPos = ftell f + (Mesh_InfoArray[i].VSize)		
vx = readFloat f
vy = readFloat f
vz = readFloat f	
fseek f getPos #seek_set	
append vertArray ([vx,vy,vz]*1000)	
append UVarray [tu,tv,0]		
)	
if (Mesh_InfoArray[i].VSize)==24 then
for x =1 to Mesh_InfoArray[i].VertCount do (
getPos = ftell f + (Mesh_InfoArray[i].VSize)		
vx = readFloat f
vy = readFloat f
vz = readFloat f	
unk1 = readFloat f
unk2 = readFloat f		
tu = readHalfFloat f
tv = readHalfFloat f*-1	
fseek f getPos #seek_set		
append vertArray ([vx,vy,vz]*1000)	
append UVarray [tu,tv,0]		
)
if (Mesh_InfoArray[i].VSize)==32 then
for x =1 to Mesh_InfoArray[i].VertCount do (
getPos = ftell f + (Mesh_InfoArray[i].VSize)		
vx = readFloat f
vy = readFloat f
vz = readFloat f	
weight1 = readbyte f #unsigned
weight2 = readbyte f #unsigned
weight3 = readbyte f #unsigned
weight4 =readbyte f #unsigned	
bone1 = readbyte f #unsigned
bone2 = readbyte f #unsigned
bone3 = readbyte f #unsigned
bone4 = readbyte f #unsigned
unk1 = readFloat f
unk2 = readFloat f		
tu = readHalfFloat f
tv = readHalfFloat 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 / 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,vy,vz]*1000)	
append UVarray [tu,tv,0]		
)
Print ("Vertex End @ 0x"+((bit.intAsHex(ftell f))as string))	

fseek f Mesh_InfoArray[i].FacePos #seek_set	
	
for x = 1 to (Mesh_InfoArray[i].FaceCount)/3 do (
fa=readshort f + 1
fb=readshort f + 1
fc=readshort f + 1
append faceArray [fa,fb,fc] 	
)	

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

fseek f Mesh_InfoArray[i].BonePos #seek_set
	
BonePos=ftell f	
for a = 1 to Mesh_InfoArray[i].BCount do (
getPos = ftell f + 28	
fseek f getPos #seek_set		
)	

MeshName=#()
if TexCount!=0 then
for x=1 to 1 do (	
fseek f (MeshNameOff) #seek_set
append MeshName (readstring f)
fseek f (NamesOff) #seek_set
NameStart=readlong f
fseek f (NameStart) #seek_set
for x=1 to TexCount do (
MatInfo=readstring f
)
for a = 1 to Mesh_InfoArray[i].BCount do (
BoneName=readstring f
append BoneNamesArray BoneName	
)	
)

if TexCount==0 then
fseek f (MeshNameOff) #seek_set
append MeshName (readstring f)
for a = 1 to Mesh_InfoArray[i].BCount do (
BoneName=readstring f
append BoneNamesArray BoneName	
)	

Print ("Bone Name End @ 0x"+((bit.intAsHex(ftell f))as string))	
	
msh = mesh vertices:vertArray faces:faceArray
msh.name=MeshName[i]
msh.numTVerts = UVarray.count
buildTVFaces msh
for j = 1 to UVarray.count do setTVert msh j UVarray[j]
for j = 1 to faceArray.count do setTVFace msh j faceArray[j]

try(
max modify mode
select msh
skinMod = skin ()
addModifier msh skinMod
for i = 1 to Mesh_InfoArray[i].BCount do
(
	maxbone = getnodebyname BoneNamesArray[i]
	if i != BNArr.count then 
		skinOps.addBone skinMod maxbone 0
	else
		skinOps.addBone skinMod maxbone 1
)
modPanel.setCurrentObject skinMod
for i = 1 to Mesh_InfoArray[i].VertCount 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