Sonic Generations Model ripping problems - Printable Version +- The VG Resource (https://www.vg-resource.com) +-- Forum: The Resources (https://www.vg-resource.com/forum-109.html) +--- Forum: The Models Resource (https://www.vg-resource.com/forum-111.html) +---- Forum: Ripping Help (https://www.vg-resource.com/forum-115.html) +---- Thread: Sonic Generations Model ripping problems (/thread-28292.html) |
Sonic Generations Model ripping problems - Yarcaz - 12-04-2015 I can't seem to open only one file now, and that is the time eater (final boss main model, when I do, I get this) I am using the Sonic GLvl export/import script for Autodesk 3ds max, as apparently the boss models of the game cooperate more when using 3ds max.
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 |