Announcements

Between mid-October and November, the content on AREA will be relocated to the Autodesk Community M&E Hub and the Autodesk Community Gallery. Learn more HERE.

Combining two scripts...

Combining two scripts...

Anonymous
Not applicable
394 Views
0 Replies
Message 1 of 1

Combining two scripts...

Anonymous
Not applicable

So I could really use some help.  I'm trying to import some models into Max with a script custom-made for this file type.  The models are intended for use with .kf (havok) animations.  There are two versions of this script around the web, and each has faults.  The original imports the model really nice and clean, but animations make the character's bone positions 90 degrees around the origin from where they should be, while maintaining original bone rotations.  So the model looks horribly disfigured.
  The edited script seems to work perfectly with animations; they're all upright and beautiful.  Unfortunately it also splits the mesh into many different pieces, when I only need it in one piece.


I've done a few small edits to the scripts but this seems way over my head.  Can anyone help me figure out where the scripts are going wrong?

 

Spoiler
Spoiler
Spoiler
clearlistener()

mdlScale = 1.0

if (heapSize < 20000000) then
heapSize = 200000000 -- allow ~ 40 MB instead of just 7.5 MB. Prevents "Runtime Error: Out of scripter memory"

struct weight_data
(
boneids,weights
)

struct VertexDeclarationEntry
(
DataOffset, DataType, EntryType, SubId
)

struct BoneDData (
BoneID, BoneNameOffset, BoneName, BoneParentID
)

fn existFile fname = (getfiles fname).count != 0

fn PrintOffset Var =
(
local Var = Var
print ("This is the offset 0x" + (bit.intAsHex Var) as string)
Var
)
y = 180
PrintOffset y
x = 200
print ("This is the number 0x" + (bit.intAsHex x) as string)

fn floatSwap2 f =
(
I = bit.floatAsInt f
h = bit.intashex I
while h.count < 8 do h = "0" + h

s = (substring h 7 2) + (substring h 5 2) + (substring h 3 2) + (substring h 1 2)
bit.intAsFloat (bit.hexasint s)
)

fn ReadBEword fstream = (
return (bit.swapBytes (readshort fstream #unsigned) 1 2)
)

fn ReadBEHalfFloat Fstream = (
local BH = readByte Fstream #unsigned
local BL = readByte Fstream #unsigned
local N = BH*256 + BL
local S = floor((mod N 65536) / 32768)
local Ef = floor((mod N 32768) / 1024)
local M = mod N 1024
if (Ef==0)AND(M==0) then return ( (-1.0)^S * 0.0 )
if (Ef==0)AND(M!=0) then return ( (-1.0)^S * 2.0^-14 * (M / 2.0^10) )
if (Ef>0)AND(Ef<31) then return ( (-1.0)^S * 2.0^(Ef-15) * (1 + M/2.0^10) )
if (Ef==31)AND(M==0) then return ( (-1.0)^S * 1/0.0 )
if (Ef==31)AND(M!=0) then return 0 --hack-- should be #inf
)--end fn ReadBEHalfFloat

fn ReadBElong fstream = (
long = readlong fstream
long = bit.swapBytes long 1 4
long = bit.swapBytes long 2 3
return long
)

fn ImportTextureGenerations mm index texfilename filepath = (
matdata = fopen (filepath + texfilename + ".material") "rb"

fseek matdata 0x04 #seek_set
texcount = ReadBElong matdata

fseek matdata 0x24 #seek_set
--PrintOffset (ftell matdata)
DataBegin = ReadBElong matdata
fseek matdata (DataBegin + 0x18) #seek_set
--PrintOffset (ftell matdata)
DataBegin2 = ReadBElong matdata
fseek matdata (DataBegin2 + 0x18) #seek_set
--PrintOffset (ftell matdata)
TexBegin = ReadBElong matdata
fseek matdata (TexBegin + 0x18) #seek_set
--PrintOffset (ftell matdata)

--mat = standardMaterial()
mat = mm.materialList[index]
mat.name = texfilename
mat.showinviewport = true
mat.twosided = false

--print("Material has " + (texcount as string) + " maps!")

for I = 1 to texcount do (

ddsfile = readstring matdata
ddsdata = readstring matdata

--print("Map " + (I as string) + " is " + ddsdata + " map: " + (ddsfile) + ".dds")

pos = ftell matdata
pos = pos + 0x0C
ex = mod pos 4

if(ex != 0) then (
pos = pos + (4 - ex)
)

fseek matdata pos #seek_set

--print ddsdata
tm = Bitmaptexture filename:(filepath + ddsfile + ".dds")
tm.alphasource = 2
case ddsdata of
(
"diffuse": mat.diffuseMap = tm
"displacement": (
mat.bumpMap = tm
mat.bumpMapAmount = 40
)
"normal": (
mat.bumpMap = tm
mat.bumpMapAmount = 40
)
"specular": mat.specularMap = tm
"gloss": mat.specularMap = tm
"reflection": mat.reflectionMap = tm
default: ( )
)
)

fclose matdata

--msh.material = mat
)


fn ImportTexture mm index texfilename filepath = (
if(not existFile(filepath + texfilename + ".texset")) then (
ImportTextureGenerations mm index texfilename filepath
return true
)
texdesc = fopen (filepath + texfilename + ".texset") "rb"

fseek texdesc 0x18 #seek_set
texcount = ReadBElong texdesc

textfiles = #()
fseek texdesc (0x20 + texcount * 4) #seek_set
for I = 1 to texcount do (
textfiles[I] = readstring texdesc
--print (textfiles[I])
)

fclose texdesc

mat = mm.materialList[index]
mat.name = texfilename
mat.showinviewport = true
mat.twosided = false

for I = 1 to texcount do (
mapdata = fopen (filepath + textfiles[I] + ".texture") "rb"
fseek mapdata 0x24 #seek_set
ddsfile = readstring mapdata
ddsdata = readstring mapdata

fclose mapdata

--print ddsdata
tm = Bitmaptexture filename:(filepath + ddsfile + ".dds")
tm.alphasource = 2
case ddsdata of
(
"diffuse": mat.diffuseMap = tm
"displacement": (
mat.bumpMap = tm
mat.bumpMapAmount = 40
)
"normal": (
mat.bumpMap = tm
mat.bumpMapAmount = 40
)
"specular": mat.specularMap = tm
"gloss": mat.specularMap = tm
"reflection": mat.reflectionMap = tm
default: ( )
)
)
--msh.material = mat
)

fn ImportTextureGenerationsMesh msh texfilename filepath = (
matdata = fopen (filepath + texfilename + ".material") "rb"

fseek matdata 0x04 #seek_set
texcount = ReadBElong matdata

fseek matdata 0x24 #seek_set
--PrintOffset (ftell matdata)
DataBegin = ReadBElong matdata
fseek matdata (DataBegin + 0x18) #seek_set
--PrintOffset (ftell matdata)
DataBegin2 = ReadBElong matdata
fseek matdata (DataBegin2 + 0x18) #seek_set
--PrintOffset (ftell matdata)
TexBegin = ReadBElong matdata
fseek matdata (TexBegin + 0x18) #seek_set
--PrintOffset (ftell matdata)

mat = standardMaterial()
mat.showinviewport = true
mat.twosided = false

--print("Material has " + (texcount as string) + " maps!")

for I = 1 to texcount do (

ddsfile = readstring matdata
ddsdata = readstring matdata

--print("Map " + (I as string) + " is " + ddsdata + " map: " + (ddsfile) + ".dds")

pos = ftell matdata
pos = pos + 0x0C
ex = mod pos 4

if(ex != 0) then (
pos = pos + (4 - ex)
)

fseek matdata pos #seek_set

--print ddsdata
tm = Bitmaptexture filename:(filepath + ddsfile + ".dds")
tm.alphasource = 2
case ddsdata of
(
"diffuse": mat.diffuseMap = tm
"displacement": (
mat.bumpMap = tm
mat.bumpMapAmount = 40
)
"normal": (
mat.bumpMap = tm
mat.bumpMapAmount = 40
)
"specular": mat.specularMap = tm
"gloss": mat.specularMap = tm
"reflection": mat.reflectionMap = tm
default: ( )
)
)

fclose matdata

msh.material = mat
)


fn ImportTextureMesh msh texfilename filepath = (
if(not existFile(filepath + texfilename + ".texset")) then (
ImportTextureGenerationsMesh msh texfilename filepath
return true
)
texdesc = fopen (filepath + texfilename + ".texset") "rb"

fseek texdesc 0x18 #seek_set
texcount = ReadBElong texdesc

textfiles = #()
fseek texdesc (0x20 + texcount * 4) #seek_set
for I = 1 to texcount do (
textfiles[I] = readstring texdesc
--print (textfiles[I])
)

fclose texdesc

mat = StandardMaterial()
mat.showinviewport = true
mat.twosided = false

for I = 1 to texcount do (
mapdata = fopen (filepath + textfiles[I] + ".texture") "rb"
fseek mapdata 0x24 #seek_set
ddsfile = readstring mapdata
ddsdata = readstring mapdata

fclose mapdata

--print ddsdata
tm = Bitmaptexture filename:(filepath + ddsfile + ".dds")
tm.alphasource = 2
case ddsdata of
(
"diffuse": mat.diffuseMap = tm
"displacement": (
mat.bumpMap = tm
mat.bumpMapAmount = 40
)
"normal": (
mat.bumpMap = tm
mat.bumpMapAmount = 40
)
"specular": mat.specularMap = tm
"gloss": mat.specularMap = tm
"reflection": mat.reflectionMap = tm
default: ( )
)
)
msh.material = mat
)

fn ReadBEfloat fstream = (
return floatSwap2(readfloat fstream)
)

fname = GetOpenFileName caption:"Open Sonic Model File" types:"Sonic Model File(*.model)|*.model"
if (fname!=undefined) and ((doesFileExist fname)==true) then (

f = fopen fname "rb" --open file in read only format
filepath = GetFilenamePath fname

fseek f 0x04 #seek_set
MeshType = ReadBElong f

CinematicMesh = 0
MorphTargetTable = 0
BoneCount = 0
BoneTableOffset = 0
BoneTableOffset2 = 0
BoneTableOffset3 = 0
ModelType = 0
Extra_Mesh_Area = #()
VertexDataBegin = 0x68

if(MeshType == 2) Then (
print "MeshType 2"
fseek f 0x30 #seek_set
BoneCount = ReadBElong f
BoneTableOffset = ReadBElong f + 0x18
BoneTableOffset2 = ReadBElong f + 0x18
BoneTableOffset3 = ReadBElong f + 0x18
VertexDataBegin = 0x40

fseek f 0x18 #seek_set
)
else if(MeshType == 4) Then (
print "MeshType 4"
fseek f 0x38 #seek_set
BoneCount = ReadBElong f
BoneTableOffset = ReadBElong f + 0x18
BoneTableOffset2 = ReadBElong f + 0x18
BoneTableOffset3 = ReadBElong f + 0x18
VertexDataBegin = 0x48

fseek f 0x18 #seek_set
) else if(MeshType == 5) Then (
print "MeshType 5"
fseek f 0x20 #seek_set
CinematicMesh = ReadBElong f
MorphTargetTable = ReadBElong f + 0x18
BoneCount = ReadBElong f
BoneTableOffset = ReadBElong f + 0x18
BoneTableOffset2 = ReadBElong f + 0x18
BoneTableOffset3 = ReadBElong f + 0x18
ModelType = ReadBElong f
VertexDataBegin = 0x68
) else if(MeshType == 2005) Then (
print "MeshType 2005"
fseek f 0x28 #seek_set
BoneCount = ReadBElong f
BoneTableOffset = ReadBElong f + 0x18
BoneTableOffset2 = ReadBElong f + 0x18
BoneTableOffset3 = ReadBElong f + 0x18
ModelType = ReadBElong f
VertexDataBegin = 0x68

fseek f 0x44 #seek_set
)
else (
throw "Unknown format!"
fclose f
)

MeshDataOffset = 0
if(ModelType > 0x34) then (
MeshDataOffset = (ModelType - 0x34)
MeshDataOffset = MeshDataOffset - (mod MeshDataOffset 4)
)

ExtraMeshAreaCount = MeshDataOffset / 4
for I = 1 to ExtraMeshAreaCount Do (
append Extra_Mesh_Area (ReadBELong f + 0x18)
)


BeforeExtra = ftell f
ExtraMeshCount = 0
Extra_Meshes = #()
for I = 1 to ExtraMeshAreaCount Do (
fseek f Extra_Mesh_Area[I] #seek_set
ThisAreaExtra = (ReadBELong f)
ExtraMeshCount = ExtraMeshCount + ThisAreaExtra
ThisAreaHead = ReadBELong f + 0x18
for j = 1 To ThisAreaExtra Do (
append Extra_Meshes (ThisAreaHead + (j-1) * 4)
)
)
fseek f BeforeExtra #seek_set

MeshCount = ReadBElong f
UnkCount2 = ReadBElong f
AddMeshCount = ReadBElong f
AddMeshBegin =ReadBElong f + 0x18
ExtraMeshCount = ExtraMeshCount + AddMeshCount
for I = 1 to AddMeshCount Do (
append Extra_Meshes (AddMeshBegin + (I-1) * 4)
)
AlphaMeshCount = ReadBElong f
AlphaMeshBegin = ReadBElong f + 0x18
ExtraMeshCount = ExtraMeshCount + AlphaMeshCount
for I = 1 to AlphaMeshCount Do (
append Extra_Meshes (AlphaMeshBegin + (I-1) * 4)
)

fseek f BoneTableOffset#seek_set
struct BoneOffset (
BoneTOffset
)
Bone_Offset_array = #()
for I = 1 to BoneCount Do (
BoneTOffset = ReadBElong f + 0x18
append Bone_Offset_array (BoneOffset BoneTOffset:BoneTOffset)
)
print Bone_Offset_array

Bone_Data_array = #()
BoneID = -1
for k in Bone_Offset_array Do (
fseek f k.BoneTOffset#seek_set
BoneID += 1
BoneParentID = ReadBElong f
BoneNameOffset = ReadBElong f
BoneName = readstring f
append Bone_Data_array ( BoneDData BoneID:BoneID BoneNameOffset:BoneNameOffset BoneName:BoneName BoneParentID:BoneParentID )
)
print Bone_Data_array
fseek f BoneTableOffset2 #seek_set
--if CinematicMesh == 1 Do (
--fseek f 0x1#seek_cur
--)
BNArr = #()

enableSceneRedraw()
--disableSceneRedraw()

Bone_root_array = #()
for I = 1 to BoneCount Do (
m11 = ReadBEfloat f; m12 = ReadBEfloat f; m13 = ReadBEfloat f; m14 = ReadBEfloat f
m21 = ReadBEfloat f; m22 = ReadBEfloat f; m23 = ReadBEfloat f; m24 = ReadBEfloat f
m31 = ReadBEfloat f; m32 = ReadBEfloat f; m33 = ReadBEfloat f; m34 = ReadBEfloat f
m41 = ReadBEfloat f; m42 = ReadBEfloat f; m43 = ReadBEfloat f; m44 = ReadBEfloat f
tfm = matrix3 [m11,m12,m13] [m21,m22,m23] [m31,m32,m33] [m41,m42,m43]

newBone = bonesys.createbone \
tfm.row4 \
(tfm.row4 + 0.01 * (normalize tfm.row1)) \
(normalize tfm.row3)
newBone.name = Bone_Data_array[I].BoneName

newBone.width = 0.01
newBone.height = 0.01
newBone.transform = tfm

pos = (-1) * [m14,m24,m34]
pos = pos * tfm

--if(newbone.name == "Brow1_L") then
--newBone.pos = [0.045,0.84,0.148]
--else if(newbone.name == "Brow2_L") then
--newBone.pos = [0.096,0.911,0.108]
--else if(newbone.name == "Brow3_L") then
--newBone.pos = [0.138,0.854,0.05]
--else if(newbone.name == "Brow_C") then
--newBone.pos = [0.0, 0.8, 0.05]
--else
--(
newBone.pos.x = pos.x * mdlScale
newBone.pos.y = pos.z * (-1) * mdlScale
newBone.pos.z = pos.y * mdlScale
--)

newBone.setBoneEnable false 0
newBone.pos.controller = TCB_position ()
newBone.rotation.controller = TCB_rotation ()


if (Bone_Data_array[I].BoneParentID != -1) then
newBone.parent = BNArr[Bone_Data_array[I].BoneParentID+1]

BNArr[I] = newBone
if I == 1 do (
append Bone_root_array newBone
)

)
MorphArr = #()
MorphArr2 = #()
Morph_Face_array = #()
Morph_Name_array = #()

print "Bones done"

if CinematicMesh == 1 Then (
fseek f MorphTargetTable #seek_set

print "Cinematic mesh"
PrintOffset (ftell f)

MorphVertCountOffset = ReadBElong f + 0x18
MorphVertCount = ReadBElong f
MorphTableEnd = ReadBElong f + 0x18
MorphUnkCount1 = ReadBElong f
MorphCount = ReadBElong f
MorphTableStart = ReadBElong f + 0x18
MorphTableNameStart = ReadBElong f + 0x18
MorphFaceSetsCount = ReadBElong f
MorphFaceTableStart = ReadBElong f + 0x18
Null = readlong f
MorphFaceTableEnd = ReadBElong f + 0x18
Texture = ""

Bone_ids1 = #()

fseek f MorphFaceTableStart#seek_set
PrintOffset (ftell f)
MorphFaceSets = #()
MorphVertSize = 0x68
DataTable = #()

for I = 1 to MorphFaceSetsCount Do
(
FaceSetStart = ReadBElong f + 0x18
append MorphFaceSets FaceSetStart
)

for I = 1 to MorphFaceSetsCount Do
(
fseek f MorphFaceSets[I] #seek_set
PrintOffset (ftell f)
TextureOffset = ReadBElong f + 0x18
MorphFaceCount = ReadBElong f
MorphFaceOffset = ReadBElong f + 0x18
--ReadBElong f
--MorphVertSize = ReadBElong f
--MorphDataTable = ReadBElong f + 0x18
if ( I == 1) then
(
BackJump = ftell f
fseek f TextureOffset #seek_set
Texture = readstring f
fseek f BackJump #seek_set

fseek f 0x10 #seek_cur
boneidcount = ReadBElong f
boneidstart = (ReadBElong f) + 0x18

fseek f boneidstart #seek_set
for j=1 to boneidcount do
(
addboneid = (ReadByte f #unsigned)
append Bone_ids1 (addboneid + 1)
)
)

--Read data table
/*
CoordinatesFound = false
UVDataFound = false
BoneIndicesFound = false
BoneWeightsFound = false
DataTableEnd = false
fseek f MorphDataTable #seek_set
PrintOffset(MorphDataTable)
while(not DataTableEnd) do (
DataOffset = ReadBElong f
DataType = ReadBElong f
EntryType = ReadBEword f
SubId = ReadByte f
Padding = ReadByte f

if(DataType != -1) then (
append DataTable (VertexDeclarationEntry DataOffset: DataOffset DataType: DataType EntryType: EntryType SubId: SubId)
if(EntryType == 0) then CoordinatesFound = true
if(EntryType == 1) then BoneWeightsFound = true
if(EntryType == 2) then BoneIndicesFound = true
if(EntryType == 5) then UVDataFound = true
) else (
DataTableEnd = true
)
)
if((not CoordinatesFound) or (not BoneWeightsFound) or (not BoneIndicesFound) or (not UVDataFound)) then (
throw "NOOOOO!"
)*/

fseek f MorphFaceOffset#seek_set
StartDirection = 1
f1 = (ReadBEword f) + 1
f2 = (ReadBEword f) + 1
FaceDirection = StartDirection
Do (
f3 = (ReadBEword f)
if (f3==0xFFFF) then (
f1 = (ReadBEword f) + 1
f2 = (ReadBEword f) + 1
FaceDirection = StartDirection
) else (
f3 += 1
FaceDirection *= -1
if (f1!=f2)AND(f2!=f3)AND(f3!=f1) then (
if FaceDirection > 0 then append Morph_Face_array [f1,f2,f3]
else append Morph_Face_array [f1,f3,f2]
)
f1 = f2
f2 = f3
)
) while ((ftell f) != (MorphFaceOffset + (MorphFaceCount * 2)))
)

fseek f MorphTableEnd #seek_set

Vert_array1 = #() --define arrays for verts, normals, UV and Faces
--Normal_array1 = #()
UV_array1 = #()
Weight_array1 = #()



for k = 1 to MorphVertCount Do (
--Ignoring data table for speed reasons!
vx = ReadBEfloat f --read xyz coordinates
vy = ReadBEfloat f
vz = ReadBEfloat f
fseek f 0x24#seek_cur
tu = ReadBEFloat f --read UV float value
tv = ReadBEFloat f * -1
fseek f 0x28#seek_cur

bone1 = readbyte f#unsigned
bone2 = readbyte f#unsigned
bone3 = readbyte f#unsigned
bone4 = readbyte f#unsigned
weight1 = readbyte f#unsigned
weight2 = readbyte f#unsigned
weight3 = readbyte f#unsigned
weight4 = readbyte f#unsigned

w = (weight_data boneids:#() weights:#())

maxweight = 0

if(bone1 != 0xFF) then
maxweight = maxweight + weight1
if(bone2 != 0xFF) then
maxweight = maxweight + weight2
if(bone3 != 0xFF) then
maxweight = maxweight + weight3
if(bone4 != 0xFF) then
maxweight = maxweight + weight4

if(maxweight != 0) then
(
mxw = 255.0
if(bone1 != 0xFF) then
(
w1 = weight1 as float
append w.boneids (Bone_ids1[bone1+1])
append w.weights (w1 / mxw)
)
if(bone2 != 0xFF) then
(
w2 = weight2 as float
append w.boneids (Bone_ids1[bone2+1])
append w.weights (w2 / mxw)
)
if(bone3 != 0xFF) then
(
w3 = weight3 as float
append w.boneids (Bone_ids1[bone3+1])
append w.weights (w3 / mxw)
)
if(bone4 != 0xFF) then
(
w4 = weight4 as float
append w.boneids (Bone_ids1[bone4+1])
append w.weights (w4 / mxw)
)
)

append Vert_array1 [vx*mdlScale,(-1)*vz*mdlScale,vy*mdlScale]
append UV_array1 [tu,tv,0] --save UVs to UV_array
append Weight_array1 w
)
msh = mesh vertices:Vert_array1 faces:Morph_Face_array --build mesh
msh.numTVerts = UV_array1.count
buildTVFaces msh
ImportTextureMesh msh Texture filepath
msh.name = "Mouth"
for j = 1 to UV_array1.count do setTVert msh j UV_array1[j]
for j = 1 to Morph_Face_array.count do setTVFace msh j Morph_Face_array[j]
--for j = 1 to Normal_array1.count do setNormal msh j Normal_array1[j]
select $Mouth
MorphMod = morpher ()
addModifier $Mouth MorphMod
$Mouth.morpher.Autoload_of_targets = 1
--$Mouth.parent = $Neck

fseek f MorphTableStart#seek_set
for I = 1 to MorphCount Do (
append MorphArr (ReadBElong f + 0x18)
)
for I = 1 to MorphCount Do (
append MorphArr2 (ReadBElong f + 0x18)
)
for I = 1 to MorphCount Do (
fseek f MorphArr[I]#seek_set
MorphName = readstring f
fseek f MorphArr2[I]#seek_set
Morph_Vert_array = #()
Morph_UV_array = #()
--Morph_Normal_array = #()
for k = 1 to MorphVertCount Do (
vx = ((ReadBEfloat f) ) + Vert_array1[k].x / mdlScale
vy = ((ReadBEfloat f) ) + Vert_array1[k].z / mdlScale
vz = ((ReadBEfloat f) ) + (-1) * Vert_array1[k].y / mdlScale
append Morph_Vert_array [vx * mdlScale,-vz * mdlScale,vy * mdlScale]
)

msh = mesh vertices:Morph_Vert_array faces:Morph_Face_array --build mesh
msh.numTVerts = UV_array1.count
buildTVFaces msh
msh.name = MorphName
for j = 1 to UV_array1.count do setTVert msh j UV_array1[j]
for j = 1 to Morph_Face_array.count do setTVFace msh j Morph_Face_array[j]
--for j = 1 to Morph_Normal_array.count do setNormal msh j Morph_Normal_array[j]
append Morph_Name_array msh
)

max modify mode
select $mouth
skinMod = skin ()
addModifier $mouth skinMod
for I = 1 to BNArr.count do
(
maxbone = getnodebyname BNArr[I].name
if I != BNArr.count then
skinOps.addBone skinMod maxbone 0
else
skinOps.addBone skinMod maxbone 1

)
modPanel.setCurrentObject skinMod

for I = 1 to Weight_array1.count do
(
w = Weight_array1[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
)

vwld = Vertex_Weld()
vwld.enabledInRenders = true
vwld.enabledInViews = false
vwld.threshold = 0.002
addModifier $mouth vwld

max create mode

)
for b = 1 to Morph_Name_array.count Do (
WM3_MC_BuildFromNode $Mouth.morpher b Morph_Name_array[b]
hide Morph_Name_array[b]
)


All_Vert_array = #()
All_UV_array = #()
All_Mat_Face_array = #()
All_Face_array = #()
All_Weight_array = #()
AllVertexCount = 0
MultiMat = MultiMaterial()
MultiMat.numsubs = MeshCount+ExtraMeshCount

if(MeshType == 5) Then
fseek f (VertexDataBegin + MeshDataOffset) #seek_set
else
fseek f VertexDataBegin #seek_set

for c = 1 to MeshCount+ExtraMeshCount Do (

CExtra = false
if(c > MeshCount) then (
--Extra mesh!
CExtra = true
extraIndex = c - MeshCount
fseek f (Extra_Meshes[extraIndex]) #seek_set
print("Extra Mesh " + (extraIndex as string))
)

--print ("Mesh: " + c as string)
--PrintOffset (ftell f)

Vert_array = #()
Normal_array = #()
UV_array = #()
Face_array = #()
Weight_array = #()
BoneID_array = #()

offsetstart = (ReadBElong f) + 0x18
tablestart = ftell f
fseek f offsetstart#seek_set

PrintOffset (ftell f)

TextureOffset = ReadBElong f + 0x18

BackJump = ftell f

fseek f TextureOffset #seek_set
Texture = readstring f
--print (Texture)
fseek f BackJump #seek_set

FaceCount = ReadBElong f
FaceStart = ReadBElong f + 0x18
VertCount = ReadBElong f
VertSize = ReadBElong f
VertStart = ReadBElong f + 0x18
DataTableStart = ReadBElong f + 0x18
SecBoneCount = ReadBElong f
SecBoneIDs = (ReadBElong f) + 0x18

BackJump = ftell f

fseek f SecBoneIDs #seek_set
for I = 1 to SecBoneCount do
(
addboneid = (ReadByte f #unsigned)
append BoneID_array (addboneid + 1)
)

fseek f BackJump #seek_set

Count10 = ReadBElong f
Count11 = ReadBElong f
FaceStart = ftell f
VerStart = (FaceCount * 2) + FaceStart

--Read data table
BackJump = ftell f
CoordinatesFound = false
UVDataFound = false
BoneIndicesFound = false
BoneWeightsFound = false
DataTableEnd = false
DataTable = #()
fseek f DataTableStart #seek_set
while(not DataTableEnd) do (
DataOffset = ReadBElong f
DataType = ReadBElong f
EntryType = ReadBEword f
SubId = ReadByte f
Padding = ReadByte f

if(DataType != -1) then (
append DataTable (VertexDeclarationEntry DataOffset: DataOffset DataType: DataType EntryType: EntryType SubId: SubId)
if(EntryType == 0) then CoordinatesFound = true
if(EntryType == 1) then BoneWeightsFound = true
if(EntryType == 2) then BoneIndicesFound = true
if(EntryType == 5) then UVDataFound = true
) else (
DataTableEnd = true
)
)
if((not CoordinatesFound) or (not BoneWeightsFound) or (not BoneIndicesFound) or (not UVDataFound)) then (
throw "NOOOOO!"
)

fseek f BackJump #seek_set
--end read data table

StartDirection = 1
f1 = (ReadBEword f) + 1
f2 = (ReadBEword f) + 1
FaceDirection = StartDirection
Do (
f3 = (ReadBEword f)
if (f3==0xFFFF) then (
f1 = (ReadBEword f) + 1
f2 = (ReadBEword f) + 1
FaceDirection = StartDirection
) else (
f3 += 1
FaceDirection *= -1
if (f1!=f2)AND(f2!=f3)AND(f3!=f1) then (
if FaceDirection > 0 then append Face_array [f1,f2,f3]
else append Face_array [f1,f3,f2]
)
f1 = f2
f2 = f3
)
) while ((ftell f) != (VerStart))
fseek f VerStart#seek_set
test = readshort f
if test != 0x0000 Do (
fseek f -2 #seek_cur
)
fseek f VertStart#seek_set

for v = 1 to VertCount Do (
vx = 0
vy = 0
vz = 0
tu = 0
tv = 0
bone1 = 0xFF
bone2 = 0xFF
bone3 = 0xFF
bone4 = 0xFF
weight1 = 0
weight2 = 0
weight3 = 0
weight4 = 0

UVSubZeroFound = false
UVFound = false
VertexDataStart = ftell f
for x = 1 to DataTable.count Do (
Entry = DataTable[x]
fseek f Entry.DataOffset #seek_cur
if(Entry.EntryType == 0) Then (
vx = ReadBEfloat f
vy = ReadBEfloat f
vz = ReadBEfloat f
)
if(Entry.EntryType == 1) Then (
weight1 = readbyte f#unsigned
weight2 = readbyte f#unsigned
weight3 = readbyte f#unsigned
weight4 = readbyte f#unsigned
)
if(Entry.EntryType == 2) Then (
bone1 = readbyte f#unsigned
bone2 = readbyte f#unsigned
bone3 = readbyte f#unsigned
bone4 = readbyte f#unsigned
)
if(Entry.EntryType == 5) Then (
SubId = Entry.SubId
ReadThisUV = (not UVFound) or (not UVSubZeroFound and SubId == 0)
if(ReadThisUV) then (
UVFound = true
if(SubId == 0) then
UVSubZeroFound = true

if(Entry.DataType == 2892709) then (
tu = ReadBEfloat f
tv = ReadBEfloat f
) else (
tu = ReadBEHalfFloat f
tv = ReadBEHalfFloat f
)
tv = tv * (-1)
)
)
fseek f VertexDataStart #seek_set
)
fseek f VertSize #seek_cur

w = (weight_data boneids:#() weights:#())

maxweight = 0
if(bone1 != 0xFF) then
maxweight = maxweight + weight1
if(bone2 != 0xFF) then
maxweight = maxweight + weight2
if(bone3 != 0xFF) then
maxweight = maxweight + weight3
if(bone4 != 0xFF) then
maxweight = maxweight + weight4

if(maxweight != 0) then
(
mxw = 255.0
if(bone1 != 0xFF) then
(
w1 = weight1 as float
append w.boneids (BoneID_array[bone1+1])
append w.weights (w1 / mxw)
)
if(bone2 != 0xFF) then
(
w2 = weight2 as float
append w.boneids (BoneID_array[bone2+1])
append w.weights (w2 / mxw)
)
if(bone3 != 0xFF) then
(
w3 = weight3 as float
append w.boneids (BoneID_array[bone3+1])
append w.weights (w3 / mxw)
)
if(bone4 != 0xFF) then
(
w4 = weight4 as float
append w.boneids (BoneID_array[bone4+1])
append w.weights (w4 / mxw)
)
)

append Vert_array [vx * mdlScale,(-1)*vz * mdlScale,vy * mdlScale] --save verts to Vert_array
--append Normal_array [nx,ny,nz] --save normals to Normal_array
append UV_array [tu,tv,0] --save UVs to UV_array
append Weight_array w

)
fseek f tablestart#seek_set

for I = 1 to Face_array.count do (
vertices = Face_array[I]
append All_Face_array [vertices[1] + AllVertexCount, vertices[2] + AllVertexCount, vertices[3] + AllVertexCount]
append All_Mat_Face_array c
)

AllVertexCount = AllVertexCount + Vert_array.count

for I = 1 to Vert_array.count do (
append All_Vert_array vert_array[I]
append All_UV_array UV_array[I]
append All_Weight_array Weight_array[I]
)

importTexture MultiMat c Texture filepath

/*msh = mesh vertices:Vert_array faces:Face_array --build mesh
msh.numTVerts = UV_array.count

importTexture msh Texture filepath

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]
--for j = 1 to Normal_array.count do setNormal msh j Normal_array[j]

max modify mode
select msh
skinMod = skin ()
addModifier msh skinMod
for I = 1 to BNArr.count do
(
maxbone = getnodebyname BNArr[I].name
if I != BNArr.count then
skinOps.addBone skinMod maxbone 0
else
skinOps.addBone skinMod maxbone 1

)

modPanel.setCurrentObject skinMod

for I = 1 to Weight_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
)


max create mode*/

)

max create mode

msh = mesh vertices:All_Vert_array faces:All_Face_array --build mesh
msh.numTVerts = All_UV_array.count
if (BNArr.count >= 1) then msh.name = BNArr[1].name

buildTVFaces msh
for j = 1 to All_UV_array.count do setTVert msh j All_UV_array[j]
for j = 1 to All_Face_array.count do (
setTVFace msh j All_Face_array[j]
setFaceMatID msh j All_Mat_Face_array[j]
)

max modify mode

select msh
skinMod = skin ()
addModifier msh skinMod
for I = 1 to BNArr.count do
(
maxbone = getnodebyname BNArr[I].name
if I != BNArr.count then
skinOps.addBone skinMod maxbone 0
else
skinOps.addBone skinMod maxbone 1

)

modPanel.setCurrentObject skinMod

for I = 1 to All_Weight_array.count do
(
w = All_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
)

msh.material = MultiMat

max modify mode

--enableSceneRedraw()

fclose f

)

/*select Bone_root_array[1]
scale $ [36.0,36.0,36.0]
rotate $ (angleaxis 90 [1,0,0])*/
--actionMan.executeAction 0 "311" -- Tools: Zoom Extents All Selected

 

Spoiler
clearlistener()
	-- Script originally written by chroxx, Link, and Kentalin. Modified by Brooks (ItsEasyActually) for Generations :D

struct weight_data
(
	boneids,weights
)

struct BoneOffset (
BoneTOffset
)

struct BoneDataStruc (
BoneID, BoneNameOffset, BoneName, BoneParentID
)

fn PrintOffset Var =
(
	local Var = Var
print ("This is the offset 0x" + (bit.intAsHex Var) as string)
	Var
)
y = 180
PrintOffset y
x = 200
print ("This is the number 0x" + (bit.intAsHex x) as string)

fn floatSwap2 f = 
(
	i = bit.floatAsInt f
	h = bit.intashex i
	while h.count < 8 do h = "0" + h
	
	s = (substring h 7 2) + (substring h 5 2) + (substring h 3 2) + (substring h 1 2)
	bit.intAsFloat (bit.hexasint s)
)	

fn ReadBEword fstream = (
return (bit.swapBytes (readshort fstream #unsigned) 1 2)
)

 fn ReadBEHalfFloat Fstream = (
  local BH  = readByte Fstream #unsigned
  local BL  = readByte Fstream #unsigned
  local N = BH*256 + BL
  local S = floor((mod N 65536) / 32768)
  local Ef = floor((mod N 32768) / 1024)
  local M = mod N 1024
  if (Ef==0)AND(M==0) then return ( (-1.0)^S * 0.0 )
  if (Ef==0)AND(M!=0) then return ( (-1.0)^S * 2.0^-14 * (M / 2.0^10) )
  if (Ef>0)AND(Ef<31) then return ( (-1.0)^S * 2.0^(Ef-15) * (1 + M/2.0^10) )
  if (Ef==31)AND(M==0) then return ( (-1.0)^S * 1/0.0 )
  if (Ef==31)AND(M!=0) then return 0	--hack-- should be #inf   
 )--end fn ReadBEHalfFloat

fn ReadBElong fstream = (
long = readlong fstream
long = bit.swapBytes long 1 4
long = bit.swapBytes long 2 3
return long
)

fn ReadBEfloat fstream = (
return floatSwap2(readfloat fstream)
)

if (heapSize < 20000000) then
	heapSize = 200000000 -- allow ~ 40 MB instead of just 7.5 MB. Prevents "Runtime Error: Out of scripter memory"

-- TexDir = getSavePath caption:"Select texture path" initialDir:"C:\Users\Experience\Desktop\Emulators\Games\360\Sonic Generations Demo\disk\bb\Packed\ghz100\TexPack"
-- Textures = getFiles (TexDir+"/*.dds")
-- Materials = getFiles (TexDir+"/*.material")

fname = GetOpenFileName caption:"Open Sonic Model File" types:"Sonic Model File(*.model)|*.model"
f = fopen fname "rb"   --open file in read only format

filepath = GetFilenamePath fname

fseek f 0x18#seek_set
MeshHeaderTotal = ReadBELong f
OffsetMHLoc = ReadBELong f + 0x18
CinematicMesh = ReadBElong f
MorphTargetTable = ReadBElong f + 0x18
BoneCount = ReadBElong f
BoneTableOffset = ReadBElong f + 0x18
BoneTableOffset2 = ReadBElong f + 0x18
BoneTableOffset3 = ReadBElong f + 0x18


fseek f BoneTableOffset#seek_set
Bone_Offset_array = #()
for i = 1 to BoneCount Do (
BoneTOffset = ReadBElong f + 0x18
append Bone_Offset_array (BoneOffset BoneTOffset:BoneTOffset)
)
print Bone_Offset_array
Bone_Data_array = #()
BoneID = -1
for k in Bone_Offset_array Do (
fseek f k.BoneTOffset#seek_set
BoneID += 1
BoneParentID = ReadBElong f
BoneNameOffset = ReadBElong f
BoneName = readstring f
append Bone_Data_array ( BoneDataStruc BoneID:BoneID BoneNameOffset:BoneNameOffset BoneName:BoneName BoneParentID:BoneParentID )
)
print Bone_Data_array
fseek f BoneTableOffset2 #seek_set
--if CinematicMesh == 1 Do (
--fseek f 0x1#seek_cur
--)
BNArr = #()
disableSceneRedraw()
Bone_root_array = #()
for i = 1 to BoneCount Do (
m11 = ReadBEfloat f; m12 = ReadBEfloat f; m13 = ReadBEfloat f; m14 = ReadBEfloat f
m21 = ReadBEfloat f; m22 = ReadBEfloat f; m23 = ReadBEfloat f; m24 = ReadBEfloat f
m31 = ReadBEfloat f; m32 = ReadBEfloat f; m33 = ReadBEfloat f; m34 = ReadBEfloat f
m41 = ReadBEfloat f; m42 = ReadBEfloat f; m43 = ReadBEfloat f; m44 = ReadBEfloat f
tfm = matrix3 [m11,m12,m13] [m21,m22,m23] [m31,m32,m33] [m41,m42,m43]
	
newBone = bonesys.createbone	\
				  tfm.row4	\
				  (tfm.row4 + 0.01 * (normalize tfm.row1)) \
				  (normalize tfm.row3)
			newBone.name   = Bone_Data_array[i].BoneName

    	    newBone.width  = 0.01
			newBone.height = 0.01
			newBone.transform = tfm
			newBone.wirecolor = yellow
			newbone.showlinks = true
					  
			pos = [m14,m24,m34]
			pos = pos * tfm
 
			newBone.pos.x = (-1)*pos.x
			newBone.pos.y = (-1)*pos.y
			newBone.pos.z = (-1)*pos.z

			newBone.setBoneEnable false 0
			newBone.pos.controller      = TCB_position ()
			newBone.rotation.controller = TCB_rotation ()

			
			if (Bone_Data_array[i].BoneParentID != -1) then
					  newBone.parent = BNArr[Bone_Data_array[i].BoneParentID+1]

			BNArr[i] = newBone
			if i == 1 do (
				append Bone_root_array newBone
			)
			
				  )
MorphArr = #()
MorphArr2 = #()
Morph_Face_array = #()
Morph_Name_array = #()

print "Bones done"

if CinematicMesh == 1 Then (
fseek f MorphTargetTable #seek_set
MorphVertCountOffset = ReadBElong f	+ 0x18
MorphVertCount = ReadBElong f	
MorphTableEnd = ReadBElong f + 0x18
MorphUnkCount1 = ReadBElong f
MorphCount = ReadBElong f
MorphTableStart = ReadBElong f + 0x18
MorphTableNameStart = ReadBElong f + 0x18
MorphFaceSetsCount = ReadBElong f
MorphFaceTableStart = ReadBElong f + 0x18
Null = readlong f
MorphFaceTableEnd = ReadBElong f + 0x18

Bone_ids1 = #()

fseek f MorphFaceTableStart#seek_set
PrintOffset (ftell f)
MorphFaceSets = #()
for i = 1 to MorphFaceSetsCount Do
(
	FaceSetStart = ReadBElong f	+ 0x18
	append MorphFaceSets FaceSetStart
)
for i = 1 to MorphFaceSetsCount Do
(
fseek f MorphFaceSets[i] #seek_set
Offset1 = ReadBElong f	+ 0x18
MorphFaceCount = ReadBElong f
MorphFaceOffset = ReadBElong f + 0x18
if ( i == 1) then
(
	fseek f 0x10 #seek_cur
	boneidcount = ReadBElong f
	boneidstart = (ReadBElong f) + 0x18
			
	fseek f boneidstart #seek_set
	for j=1 to boneidcount do
	(
		addboneid = (ReadByte f #unsigned)
		append Bone_ids1 (addboneid + 1)
	)
)	
fseek f MorphFaceOffset#seek_set
StartDirection = 1
f1 = (ReadBEword f) + 1
f2 = (ReadBEword f) + 1  
FaceDirection = StartDirection
Do (
f3 = (ReadBEword f)
if (f3==0xFFFF) then (
f1 = (ReadBEword f) + 1
f2 = (ReadBEword f) + 1
FaceDirection = StartDirection 
) else (
f3 += 1
FaceDirection *= -1
if (f1!=f2)AND(f2!=f3)AND(f3!=f1) then (
if FaceDirection > 0 then append Morph_Face_array [f1,f2,f3]
else append Morph_Face_array [f1,f3,f2]
)
f1 = f2
f2 = f3
) 
) while ((ftell f) != (MorphFaceOffset + (MorphFaceCount * 2)))
)

fseek f MorphTableEnd #seek_set

Vert_array1 = #() --define arrays for verts, normals, UV and Faces
Normal_array1 = #()
UV_array1 = #()
Weight_array1 = #()



for k = 1 to MorphVertCount Do (
vx = ReadBEfloat f  --read xyz coordinates
vy = ReadBEfloat f
vz = ReadBEfloat f
fseek f 0x24#seek_cur
tu = ReadBEFloat f   --read UV float value
tv = ReadBEFloat f * -1
fseek f 0x28#seek_cur

bone1 = readbyte f#unsigned
bone2 = readbyte f#unsigned
bone3 = readbyte f#unsigned
bone4 = readbyte f#unsigned
weight1 = readbyte f#unsigned
weight2 = readbyte f#unsigned
weight3 = readbyte f#unsigned
weight4 = readbyte f#unsigned

w = (weight_data boneids:#() weights:#())

maxweight = 0
	
if(bone1 != 0xFF) then
	maxweight = maxweight + weight1
if(bone2 != 0xFF) then
	maxweight = maxweight + weight2
if(bone3 != 0xFF) then
	maxweight = maxweight + weight3
if(bone4 != 0xFF) then
	maxweight = maxweight + weight4

if(maxweight != 0) then
	(
		mxw = maxweight as float
		if(bone1 != 0xFF) then
		(
			w1 = weight1 as float
			append w.boneids (Bone_ids1[bone1+1])
			append w.weights (w1 / mxw)
		)
		if(bone2 != 0xFF) then
		(
			w2 = weight2 as float
			append w.boneids (Bone_ids1[bone2+1])
			append w.weights (w2 / mxw)
		)
		if(bone3 != 0xFF) then
		(
			w3 = weight3 as float
			append w.boneids (Bone_ids1[bone3+1])
			append w.weights (w3 / mxw)
		)
		if(bone4 != 0xFF) then
		(
			w4 = weight4 as float
			append w.boneids (Bone_ids1[bone4+1])
			append w.weights (w4 / mxw)
		)		
	)

append Vert_array1 [vx,vy,vz]
append UV_array1 [tu,tv,0]  --save UVs to UV_array
append Weight_array1 w
)
msh = mesh vertices:Vert_array1 faces:Morph_Face_array --build mesh
msh.numTVerts = UV_array1.count
buildTVFaces msh
msh.name =  "Mouth"
for j = 1 to UV_array1.count do setTVert msh j UV_array1[j]
for j = 1 to Morph_Face_array.count do setTVFace msh j Morph_Face_array[j]
for j = 1 to Normal_array1.count do setNormal msh j Normal_array1[j]
select $Mouth
MorphMod = morpher ()
addModifier $Mouth MorphMod
$Mouth.morpher.Autoload_of_targets = 1
--$Mouth.parent = $Neck

fseek f MorphTableStart#seek_set
for i = 1 to MorphCount Do (
append MorphArr (ReadBElong f + 0x18)
)
for i = 1 to MorphCount Do (
append MorphArr2 (ReadBElong f + 0x18)
)	
for i = 1 to MorphCount Do (
fseek f MorphArr[i]#seek_set
MorphName = readstring f
fseek f MorphArr2[i]#seek_set
Morph_Vert_array = #()
Morph_UV_array = #()
Morph_Normal_array = #()
for k = 1 to MorphVertCount Do (
vx = ((ReadBEfloat f) ) + Vert_array1[k].x
vy = ((ReadBEfloat f) ) + Vert_array1[k].y
vz = ((ReadBEfloat f) ) + Vert_array1[k].z
append Morph_Vert_array [vx,vy,vz]
)

msh = mesh vertices:Morph_Vert_array faces:Morph_Face_array   --build mesh
msh.numTVerts = UV_array1.count
buildTVFaces msh
msh.name =  MorphName
for j = 1 to UV_array1.count  do setTVert msh j UV_array1[j]
for j = 1 to Morph_Face_array.count  do setTVFace msh j Morph_Face_array[j]
for j = 1 to Morph_Normal_array.count do setNormal msh j Morph_Normal_array[j]
append Morph_Name_array msh
)

max modify mode
select $mouth
skinMod = skin ()
addModifier $mouth skinMod
for i = 1 to BNArr.count do
(
	maxbone = getnodebyname BNArr[i].name
	if i != BNArr.count then
		skinOps.addBone skinMod maxbone 0
	else
		skinOps.addBone skinMod maxbone 1
	
)

modPanel.setCurrentObject skinMod

for i = 1 to Weight_array1.count do
(
	w = Weight_array1[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
)

max create mode

)
for b = 1 to Morph_Name_array.count Do (
	WM3_MC_BuildFromNode $Mouth.morpher b Morph_Name_array[b]
	hide Morph_Name_array[b]
)

fseek f OffsetMHLoc#seek_set

for m = 1 to MeshHeaderTotal Do (
MeshHeader = ReadBELong f + 0x18
	NextHeader = ftell f
	

fseek f MeshHeader#seek_set
MeshCount = ReadBElong f
MshLoc = ReadBElong f + 0x18
AddMeshCount = ReadBElong f
AddMeshBegin = ReadBElong f + 0x18
AlphaMeshCount = ReadBELong f
AlphaMeshBegin = ReadBELong f + 0x18

fseek f 0x4#seek_cur
TestByte = ReadByte f#unsigned
if TestByte != 0xFF Do (
	fseek f -0x5#seek_cur
	OpaqueCount = ReadBELong f
	OpaqueOffset = ReadBELong f + 0x1C
	fseek f OpaqueOffset#seek_set
	OpOff = ReadBELong f + 0x18
	OpaqueMeshBegin = ReadBELong f + 0x18	
	fseek f OpOff#seek_set
	OpaqueMeshCount = ReadBELong f
)

if TestByte == 0xFF Do (
	OpaqueMeshCount = 0
)

fseek f MshLoc#seek_set
for c = 1 to MeshCount+AddMeshCount+AlphaMeshCount+OpaqueMeshCount Do (

if(c == MeshCount + 1) then (
	fseek f AddMeshBegin #seek_set
)	

if(c == (MeshCount+AddMeshCount) + 1) then (
	fseek f AlphaMeshBegin #seek_set
)	

if(c == (MeshCount+AddMeshCount+AlphaMeshCount) + 1) then (
	fseek f OpaqueMeshBegin #seek_set
)	

	Vert_array = #()
	Normal_array = #()
	UV_array = #()
	Face_array = #()
	Weight_array = #()
	BoneID_array = #()
	
offsetstart = (ReadBElong f) + 0x18
tablestart = ftell f
	fseek f offsetstart#seek_set
TexNameOff = ReadBElong f + 0x18
FaceCount = ReadBElong f	
FaceStart = ReadBElong f 	+ 0x18
VertCount = ReadBElong f	
VertSize = ReadBElong f	
VertStart = ReadBElong f + 0x18
VertEnd = ReadBElong f + 0x18
SecBoneCount = ReadBElong f	
SecBoneIDs = (ReadBElong f) + 0x18
MaterialCount = ReadBElong f	
MaterialCountOffset = ReadBElong f

BackJump = ftell f
	
fseek f SecBoneIDs #seek_set
for i = 1 to SecBoneCount do
(
	addboneid = (ReadByte f #unsigned)
	append BoneID_array (addboneid + 1)
)
	
fseek f BackJump #seek_set
	
FaceStart = ftell f	
VerStart = (FaceCount * 2) + FaceStart


StartDirection = 1
f1 = (ReadBEword f) + 1
f2 = (ReadBEword f) + 1  
FaceDirection = StartDirection
Do (
f3 = (ReadBEword f)
if (f3==0xFFFF) then (
f1 = (ReadBEword f) + 1
f2 = (ReadBEword f) + 1
FaceDirection = StartDirection 
) else (
f3 += 1
FaceDirection *= -1
if (f1!=f2)AND(f2!=f3)AND(f3!=f1) then (
if FaceDirection > 0 then append Face_array [f1,f2,f3]
else append Face_array [f1,f3,f2]
)
f1 = f2
f2 = f3
) 
) while ((ftell f) != (VerStart))
fseek f VerStart#seek_set
 test = readshort f
 if test != 0x0000 Do (
         fseek f -2 #seek_cur
)
fseek f VertStart#seek_set
for v = 1 to VertCount Do (
if VertSize == 0x24 Do (
vx = ReadBEfloat f  --read xyz coordinates
vy = ReadBEfloat f
vz = ReadBEfloat f
bone1 = readbyte f#unsigned
bone2 = readbyte f#unsigned
bone3 = readbyte f#unsigned
bone4 = readbyte f#unsigned
weight1 = readbyte f#unsigned
weight2 = readbyte f#unsigned
weight3 = readbyte f#unsigned
weight4 = readbyte f#unsigned
fseek f 0x8#seek_cur
tu = ReadBEHalfFloat f   --read UV float value
tv = ReadBEHalfFloat f * -1
fseek f 0x4#seek_cur
)
if VertSize == 0x28 Do (
vx = ReadBEfloat f  --read xyz coordinates
vy = ReadBEfloat f
vz = ReadBEfloat f
fseek f 0xC#seek_cur
tu = ReadBEHalfFloat f   --read UV float value
tv = ReadBEHalfFloat f * -1
fseek f 0x4#seek_cur

bone1 = readbyte f#unsigned
bone2 = readbyte f#unsigned
bone3 = readbyte f#unsigned
bone4 = readbyte f#unsigned
weight1 = readbyte f#unsigned
weight2 = readbyte f#unsigned
weight3 = readbyte f#unsigned
weight4 = readbyte f#unsigned
)
if VertSize == 0x2C Do (
vx = ReadBEfloat f  --read xyz coordinates
vy = ReadBEfloat f
vz = ReadBEfloat f
fseek f 0x10#seek_cur
tu = ReadBEHalfFloat f   --read UV float value
tv = ReadBEHalfFloat f * -1
fseek f 0x4#seek_cur
	
bone1 = readbyte f#unsigned
bone2 = readbyte f#unsigned
bone3 = readbyte f#unsigned
bone4 = readbyte f#unsigned
weight1 = readbyte f#unsigned
weight2 = readbyte f#unsigned
weight3 = readbyte f#unsigned
weight4 = readbyte f#unsigned
)

if VertSize == 0x30 Do(
vx = ReadBEFloat f
vy = ReadBEFloat f
vz = ReadBEFloat f
fseek f 0xC#seek_cur
tu = ReadBEHalfFloat f
tv = ReadBEHalfFloat f * -1
fseek f 0xC#seek_cur
bone1 = readbyte f#unsigned
bone2 = readbyte f#unsigned
bone3 = readbyte f#unsigned
bone4 = readbyte f#unsigned
weight1 = readbyte f#unsigned
weight2 = readbyte f#unsigned
weight3 = readbyte f#unsigned
weight4 = readbyte f#unsigned
)

if VertSize == 0x34 Do (
vx = ReadBEFloat f
vy = ReadBEFloat f
vz = ReadBEFloat f
fseek f 0x10#seek_cur
tu = ReadBEHalfFloat f
tv = ReadBEHalfFloat f * -1
fseek f 0xC#seek_cur
bone1 = readbyte f#unsigned
bone2 = readbyte f#unsigned
bone3 = readbyte f#unsigned
bone4 = readbyte f#unsigned
weight1 = readbyte f#unsigned
weight2 = readbyte f#unsigned
weight3 = readbyte f#unsigned
weight4 = readbyte f#unsigned
)

if VertSize == 0x68 Do (
vx = ReadBEfloat f  --read xyz coordinates
vy = ReadBEfloat f
vz = ReadBEfloat f
fseek f 0x24#seek_cur
tu = ReadBEFloat f   --read UV float value
tv = ReadBEFloat f * -1
fseek f 0x28#seek_cur
	
bone1 = readbyte f#unsigned
bone2 = readbyte f#unsigned
bone3 = readbyte f#unsigned
bone4 = readbyte f#unsigned
weight1 = readbyte f#unsigned
weight2 = readbyte f#unsigned
weight3 = readbyte f#unsigned
weight4 = readbyte f#unsigned
)

w = (weight_data boneids:#() weights:#())

maxweight = 0
	
if(bone1 != 0xFF) then
	maxweight = maxweight + weight1
if(bone2 != 0xFF) then
	maxweight = maxweight + weight2
if(bone3 != 0xFF) then
	maxweight = maxweight + weight3
if(bone4 != 0xFF) then
	maxweight = maxweight + weight4

if(maxweight != 0) then
	(
		mxw = maxweight as float
		if(bone1 != 0xFF) then
		(
			w1 = weight1 as float
			append w.boneids (BoneID_array[bone1+1])
			append w.weights (w1 / mxw)
		)
		if(bone2 != 0xFF) then
		(
			w2 = weight2 as float
			append w.boneids (BoneID_array[bone2+1])
			append w.weights (w2 / mxw)
		)
		if(bone3 != 0xFF) then
		(
			w3 = weight3 as float
			append w.boneids (BoneID_array[bone3+1])
			append w.weights (w3 / mxw)
		)
		if(bone4 != 0xFF) then
		(
			w4 = weight4 as float
			append w.boneids (BoneID_array[bone4+1])
			append w.weights (w4 / mxw)
		)		
	)

append Vert_array [vx,vy,vz] --save verts to Vert_array
--append Normal_array [nx,ny,nz] --save normals to Normal_array
append UV_array [tu,tv,0]  --save UVs to UV_array
append Weight_array w

)
fseek f TexNameOff#seek_set
TexName = ReadString f
print TexName

fseek f tablestart#seek_set

MaterialFile = (filepath+"/")+(TexName+".material")

msh = mesh vertices:Vert_array faces:Face_array --build mesh
msh.numTVerts = UV_array.count
buildTVFaces msh    
msh.name = TexName
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]
for j = 1 to Normal_array.count do setNormal msh j Normal_array[j]
	
max modify mode
select msh
skinMod = skin ()
addModifier msh skinMod
for i = 1 to BNArr.count do
(
	maxbone = getnodebyname BNArr[i].name
	if i != BNArr.count then (
		skinOps.addBone skinMod maxbone 0
	)else(
		skinOps.addBone skinMod maxbone 1
	)
)

modPanel.setCurrentObject skinMod

for i = 1 to Weight_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
)

mf = fopen MaterialFile "rb"

fseek mf 0x24#seek_set
TextureTable = ReadBELong mf +0x18
fseek mf 0x6#seek_cur
TextureTotal = ReadBEWord mf

-- DiffArr = #()
-- BumpArr = #()
-- SpecArr = #()

fseek mf TextureTable#seek_set
	m = standardMaterial()
for tex = 1 to 1 Do (

	TextureNameOff = ReadBELong mf +0x18
	NextTex = ftell mf
	
	fseek mf TextureNameOff#seek_set
	fseek mf 0xC#seek_cur
	TextureName = ReadString mf +".dds"
	TexType = ReadString mf as name
	
	TextureFile = filepath+"/"+TextureName
	
-- 	print "TextureType ="
-- 	print TexType
-- 	
-- 	if TexType == "diffuse" Do (
-- 		bt = BitmapTexture()
-- 		bt.FileName = TextureFile
-- 		m.DiffuseMap = bt
-- 	)
-- 	
-- 	if TexType == "normal" Do (
-- 		nt = BitmapTexture()
-- 		nt.FileName = TextureFile
-- 		append BumpArr[nt]
-- 	)
-- 	
-- 	if TexType == "specular" Do (
-- 		st = BitmapTexture()
-- 		st.FileName = TextureFile
-- 		append SpecArr[st]
-- 	)
-- 	
-- 	if TexType == "opacity" Do (
-- 		ot = BitmapTexture()
-- 		ot.FileName = TextureFile
-- 	)
-- 	
-- 	if TexType == "reflection" Do (
-- 		rt = BitmapTexture()
-- 		rt.FileName = TextureFile
-- 	)
-- 	
-- 	if TexType == "displacement" Do (
-- 		dt = BitmapTexture()
-- 		dt.FileName = TextureFile
-- 	)
-- 	
-- 	if TexType == "gloss" Do (
-- 		gt = BitmapTexture()
-- 		gt.FileName = TextureFile
-- 	)
	
	bt = BitmapTexture()
	bt.FileName = TextureFile
	m.DiffuseMap = bt
	print bt
	)
	
-- 	fseek mf NextTex#seek_set

-- m.DiffuseMap = bt
-- m.BumpMap = nt
-- m.SpecularMap = st
-- m.OpacityMap = ot
-- m.ReflectionMap = rt
-- m.DisplacementMap = dt
-- m.GlossinessMap = gt

m.showInViewport = true
$.material = m


max create mode
)
fseek f NextHeader#seek_set
)

enableSceneRedraw()
select Bone_root_array[1]
scale $ [36.0,36.0,36.0]
rotate $ (angleaxis 90 [1,0,0])


fclose mf
fclose f
clearSelection()
actionMan.executeAction 0 "311"  -- Tools: Zoom Extents All Selected

 

 

 

 

 

 

 

0 Likes
395 Views
0 Replies
Replies (0)