|
Post by bluearms on Feb 10, 2015 1:51:15 GMT 10
{Spoiler}
--RER mod tool v0.2 by maliwei777 --Edited By mariokart64n June 11, 2013 -> Added version switch for RER and Re6 --v0.21 - Edited by Sectus. Fixed material ID (was a byte, but should be a short) --v1.1 - Modified version for HD Remastered. --v1.2 - Edited by Bluearms for dummy same material assignment.
-- 50MB if (heapSize < 50000000) then heapSize = 50000000
--XNA "Microsoft.Xna.Framework.dll" Path --dotnet.loadassembly @"C:\Program Files (x86)\Common Files\microsoft shared\XNA\DeployableRuntimes\Zune\3.1.10527.0\Microsoft.Xna.Framework.dll" --dotnet.loadassembly @"C:\Program Files (x86)\Common Files\microsoft shared\XNA\DeployableRuntimes\Zune\3.1.10527.100\Microsoft.Xna.Framework.dll"
global mod_ver = 0,ReHDModTool
struct Header ( BoneCount, MeshCount, MatCount, VertCount, TriangleCount, VertexIds, VertexBufferSize, Padding, -- 0 BoneMapCount, ptr_Bone, ptr_BoneMap, ptr_MatID, ptr_Mesh, ptr_vertex, ptr_triangle, EndSize )
fn ReadHeader bstream = ( local H = Header () H.BoneCount = ReadShort bstream #unsigned H.MeshCount = ReadShort bstream #unsigned H.MatCount = ReadShort bstream #unsigned H.VertCount = ReadLong bstream #unsigned H.TriangleCount = ReadLong bstream #unsigned H.VertexIds = ReadLong bstream #unsigned --?? H.VertexBufferSize = ReadLong bstream #unsigned H.Padding = ReadLong bstream #unsigned H.BoneMapCount = ReadLong bstream #unsigned H.ptr_Bone = ReadLong bstream #unsigned H.ptr_BoneMap = ReadLong bstream #unsigned H.ptr_MatID = ReadLong bstream #unsigned H.ptr_Mesh = ReadLong bstream #unsigned H.ptr_vertex = ReadLong bstream #unsigned H.ptr_triangle = ReadLong bstream #unsigned H.EndSize = ReadLong bstream #unsigned H )
struct BoneInfo ( ID, --cId; Parent, --cParent; // -1 means no parents Child, --cChild; // child id uk1, --cUnknown; physic ? uk2, --fData[2]; physic ? col uk3, --fData[2]; physic ? Trans --vTrans; )
fn ReadBoneInfo bstream = ( local Info = BoneInfo() Info.ID = ReadByte bstream #unsigned Info.Parent = ReadByte bstream Info.Child = ReadByte bstream Info.uk1 = ReadByte bstream Info.uk2 = ReadFloat bstream Info.uk3 = ReadFloat bstream Info.Trans = [(ReadFloat bstream),(ReadFloat bstream),(ReadFloat bstream)] Info )
struct MeshHeader ( meshtype, vertCount, unk01, MatId, lodLevel, unk04 , vertFlag, vertStride, unk05, vertStart, vertBase, fvfInfo, faceStart, faceCount, faceBase, bonemapindex, weightmaps, unk07, unk08, min_index, max_index, unk09 )
fn ReadMeshHeader bstream = ( local M = MeshHeader () M.meshtype = ReadShort bstream #unsigned --mesh type M.vertCount = ReadShort bstream #unsigned --vertex count M.unk01 = ReadByte bstream #unsigned --byte or 12bits M.MatId = ReadShort bstream #unsigned --mat index must be divided by 16 M.lodLevel = ReadByte bstream #unsigned --Lod level M.unk04 = ReadByte bstream #unsigned M.vertFlag = ReadByte bstream #unsigned M.vertStride = ReadByte bstream #unsigned --vertex size used for stride M.unk05 = ReadByte bstream #unsigned --? M.vertStart = ReadLong bstream #unsigned -- vertex List Start M.vertBase = ReadLong bstream #unsigned -- vertexoffset M.fvfInfo = ReadLong bstream #unsigned --vertexformat
M.faceStart = ReadLong bstream #unsigned --face list M.faceCount = ReadLong bstream #unsigned --face M.faceBase = ReadLong bstream #unsigned
M.bonemapindex = ReadByte bstream #unsigned -- byte *2 M.weightmaps = ReadByte bstream #unsigned M.unk07 = ReadByte bstream #unsigned M.unk08 = ReadByte bstream #unsigned M.min_index = ReadShort bstream #unsigned M.max_index = ReadShort bstream #unsigned M.unk09 = ReadLong bstream #unsigned --?? M )
--fn FShort fValue = --( -- ft = dotnetobject "Microsoft.Xna.Framework.Graphics.PackedVector.HalfSingle" fValue -- ft.packedvalue --)
fn FShort fValue = ( Src = bit.floatasint fValue Sign=exponent=Mantissa=0 Sign = bit.shift Src -31 exponent = (bit.shift (bit.and Src 0x7F800000) -23) - 127 + 15 Mantissa = bit.and Src 0x007FFFFF if (exponent >= 0) and (exponent <= 30) then ( Result = bit.or (bit.shift Sign 15) (bit.or (bit.shift exponent 10) \ (bit.shift (Mantissa + 0x00001000) -13)) ) else ( if Src == 0 then ( Result = 0 ) else ( if exponent <= 0 then ( if exponent <= -10 then ( Result = 0 ) else ( Mantissa = bit.shift (bit.or Mantissa 0x00800000) -(1 - exponent) if (bit.or Mantissa 0x00001000) >= 0 do ( Mantissa = Mantissa + 0x00002000 Result = bit.or (bit.shift Sign 15) (bit.shift Mantissa -13) ) ) ) else ( if exponent = 255 - 127 + 15 then ( if Mantissa = 0 then ( Result = (bit.shift Sign 15) or 0x7C00 ) else ( Result = bit.or (bit.shift Sign 15) (bit.or 0x7C00 (bit.shift Mantissa -13)) ) ) else ( if (bit.and Mantissa 0x00001000) >= 0 then ( Mantissa = Mantissa + 0x00002000 if (bit.and Mantissa 0x00800000) >= 0 then ( Mantissa = 0 exponent = exponent + 1 ) ) if exponent >= 30 then ( Result = (bit.shift Sign 15) or 0x7C00 ) else ( Result = bit.or (bit.shift Sign 15) (bit.or (bit.shift exponent 10) (bit.shift Mantissa -13)) ) ) ) ) ) Result )
fn ReadFloat16 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.0 )
fn ToFloat16 hf = ( 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.0 )
fn ReadFixedString bstream fixedLen = ( local str = "" local length = 0 local finished = false for i = 1 to fixedLen do ( local c = ReadByte bstream #unsigned if c == 0 then finished = true if finished then continue str += bit.intAsChar(c) if c != 32 then length = i ) substring str 1 length )
struct BoneMapListA ( ID, -- unk, --0xCDCDCDCD x 3 ?? v4 ) --BoneMaplist2 struct BoneMapListB ( ID, -- unk, --0xCDCDCDCD x 3 ?? v1,v2,v3,v4,v5,v6,v7,v8 )
fn PadString len instring = ( instring=instring as string local str="" if instring.count <=len then ( for i = 1 to (len-instring.count) do ( str+="0" ) str = (str+instring) ) else ( for i = 1 to len do ( str+="0";str[i]=instring[i] ) ) str )
fn ReadVertexPos bstream = ( local vp = [0,0,0] vp.x = (readshort bstream)/32767.0 vp.z = (readshort bstream)/32767.0 vp.y = -(readshort bstream)/32767.0 vp )
fn ReadMatrix bstream = ( local Mat = Matrix3 1 Mat.row1 = [(ReadFloat bstream),(ReadFloat bstream),(ReadFloat bstream),(ReadFloat bstream)] Mat.row2 = [(ReadFloat bstream),(ReadFloat bstream),(ReadFloat bstream),(ReadFloat bstream)] Mat.row3 = [(ReadFloat bstream),(ReadFloat bstream),(ReadFloat bstream),(ReadFloat bstream)] tYZ = [-(ReadFloat bstream),-(ReadFloat bstream),(ReadFloat bstream)] Mat.row4 = [tYZ.x,tYZ.z,tYZ.y,(ReadFloat bstream)] Mat )
fn ReadFace bstream = ( local F F = [(ReadShort bstream),(ReadShort bstream),(ReadShort bstream)] F )
Global OriginalBoneScale = 1 Global FWeightMin = 0.0001
fn getUniqueArray2 b1 b2 w1 w2 = ( if (w1 < FWeightMin) then return #(#(b2),#(w2),1) if (w2 < FWeightMin) then return #(#(b1),#(w1),1) if (b1==b2) then return #(#(b1),#(1.0),1) return #(#(b1,b2),#(w1,w2),2) )
fn getUniqueArray4 b1 b2 b3 b4 w1 w2 w3 w4 = ( local bi, bw, idx, n
bi = #(b1) bw = #(w1) n = 1
-- if w1==0???? -- assume at least one of w?'s is not zero -- if w1==0 then b1 is not eliminated with this method. -- (too many checks make execution slow. need some certainty with the format. then we can eliminate unnecessary check) -- weights must be positive, if zero or negative remove
idx = findItem bi b2 if (idx==0) then (if (w2 >= FWeightMin) then (append bi b2; append bw w2; n=n+1)) idx = findItem bi b3 if (idx==0) then (if (w3 >= FWeightMin) then (append bi b3; append bw w3; n=n+1)) idx = findItem bi b4 if (idx==0) then (if (w4 >= FWeightMin) then (append bi b4; append bw w4; n=n+1)) if (n==1) then (bw[1]=1.0) return #(bi, bw, n) )
fn findIndex a b = ( local ai, ac
ac = a.count for ai=1 to ac do ( if a[ai][1]==b then return ai ) return 0 )
fn compareIndexedArray a b = ( local d = a[1] - b[1] case of ( (d < 0.): -1 (d > 0.): 1 default: 0 ) )
fn compareByWeight a b = ( local d = a[2] - b[2] case of ( (d < 0.): -1 (d > 0.): 1 default: 0 ) )
fn getUniqueArray6 b1 b2 b3 b4 b5 b6 w1 w2 w3 w4 w5 w6 = ( local sb, bi, bw, idx, n, ni
sb = #(#(b1, w1)) n = 1
idx = findIndex sb b2 if (idx==0) then (if (w2 >= FWeightMin) then (append sb #(b2, w2); n=n+1)) idx = findIndex sb b3 if (idx==0) then (if (w3 >= FWeightMin) then (append sb #(b3, w3); n=n+1)) idx = findIndex sb b4 if (idx==0) then (if (w4 >= FWeightMin) then (append sb #(b4, w4); n=n+1)) idx = findIndex sb b5 if (idx==0) then (if (w5 >= FWeightMin) then (append sb #(b5, w5); n=n+1)) idx = findIndex sb b6 if (idx==0) then (if (w6 >= FWeightMin) then (append sb #(b6, w6); n=n+1))
qsort sb compareByWeight
if (sb[1][2]==0) then ( -- if weight is zero then remove deleteItem sb 1 n=n-1 ) -- now all weights are non zero if (n==0) then ( -- this can not happen, but in case w1==0.0 print "All Weights Zero Anomaly Happened!" return #(b1, 1.0, 1) ) -- now reverse and split to make major weights are in the front -- because if n>4 we need major 4 weights. -- Currently export routine considers only 4 weights but max can handle many weghts. so delay until export and use like this bi = #() bw = #() bi.count = n bw.count = n
for ni=1 to n do ( bi[ni]=sb[n-ni+1][1] bw[ni]=sb[n-ni+1][2] )
if (n==1) then (bw[1]=1.0) return #(bi, bw, n) )
fn doImport f = ( --"MOD"
if (f==undefined) then (return())
Type = ReadFixedString f 4 if Type != "MOD" do ( messageBox "It is not Mod file" return() ) mod_ver = readshort f #unsigned print ("mod ver : "+(bit.intAsHex mod_ver)) hdr = ReadHeader f print hdr --Bounding Sphere & Box fn GetBound bstream = ([(ReadFloat bstream),(ReadFloat bstream),(ReadFloat bstream),(ReadFloat bstream)]) BoundingSphere = GetBound f ;BoundingBoxMin = GetBound f ;BoundingBoxMax = GetBound f BoundSphere = Sphere radius: BoundingSphere[4] BoundSphere.pos = [BoundingSphere[1],BoundingSphere[2],BoundingSphere[3]] BoundSphere.name = "BoundSphere" BoundBoxMin = Point Size:10.0 BoundBoxMin.name = "BoundBoxMin" BoundBoxMin.pos = [BoundingBoxMin[1],BoundingBoxMin[2],BoundingBoxMin[3]] BoundBoxMax = Point Size:10.0 BoundBoxMax.name = "BoundBoxMax" BoundBoxMax.pos = [BoundingBoxMax[1],BoundingBoxMax[2],BoundingBoxMax[3]] freeze BoundSphere ;Hide BoundSphere ;freeze BoundBoxMin ;Hide BoundBoxMin ;freeze BoundBoxMax ;Hide BoundBoxMax
fseek f 16 #seek_cur -- HD Remasterd Version == 0x00D2 if mod_ver==0x00D2 do (fseek f 4 #seek_cur)
--Bones bCount = hdr.BoneCount BoneArray=#()
print "Bone Index" for i=1 to bCount do ( bInfo = ReadBoneInfo f cBone = Dummy size:1.0 cBone.showLinks = true cBone.showLinksOnly = true cBone.name = "b_" + (bInfo.Parent+1)as string +"_"+ i as string Append BoneArray cBone print ("Bone "+(i as string)+":"+cBone.name) )
--for i=1 to bCount do --Local or physical --( -- BoneLocalMatrix = ReadMatrix f --cBone = boneSys.createBone BoneLocalMatrix.row4 [0, 0, 0] [0, 0, 0] --cBone.showLinks = true --cBone.showLinksOnly = true --cBone.transform = BoneLocalMatrix --print BoneWorldMatrix --)
LocalMatrixSize = 16*4*bCount fseek f LocalMatrixSize #seek_cur
--print ("bCount:"+(bCount as string))
if (bCount >= 1) then ( BoneWorldMatrix = ReadMatrix f BoneArray[1].transform = BoneWorldMatrix MeshScale = BoneArray[1].scale ) else ( MeshScale = [1.0, 1.0, 1.0] )
for i=2 to bCount do --World ( BoneWorldMatrix = ReadMatrix f BoneArray[i].transform = BoneWorldMatrix if (OriginalBoneScale!=1) then (BoneArray[i].scale = [1.0,1.0,1.0]) ParentID = filterString BoneArray[i].name "_" pID = execute ParentID[2] if pid<0 then pid = pid + 256 if pID != 0 then BoneArray[i].Parent = BoneArray[pID] )
print ("Position After Bone Array: "+ (bit.intasHex (ftell f)))
-----------------------------------------------------------------------------------------------------------------
--BoneMaplist1 ?? unknow fseek f 256 #seek_cur
fn ReadBoneMapListA bstream = ( local LA = BoneMapListA () LA.ID = ReadLong bstream #unsigned LA.unk = [(ReadLong bstream #unsigned),(ReadLong bstream #unsigned),(ReadLong bstream #unsigned)] LA.v4 = [(Readfloat bstream),(Readfloat bstream),(Readfloat bstream),(Readfloat bstream)] LA )
lac = hdr.BoneMapCount MeshBoneMapListA_array = #() MeshBoneMapListA_array.count = lac
for i=1 to lac do ( mla = ReadBoneMapListA f MeshBoneMapListA_array[i]=#(mla.ID,mla.v4) --print MeshBoneMapListA_array[i] )
--mat id list print ("Position Before Mat: "+ (bit.intasHex (ftell f)))
MatCount = hdr.MatCount if (mod_ver==0x00D2) then (MatCount = (MatCount * 32)) MeshMatID_array = #() MeshMatID_array.count = MatCount
for i=1 to MatCount do ( matID = ReadLong f MeshMatID_array[i]=matID ) --this is required to know which material is which in mrl editor -- bluearms fn swapEndian num = ( n = num n = bit.swapBytes n 1 4 n = bit.swapBytes n 2 3 return n )
if (mod_ver==0x00D2) then ( local t = MatCount/32 print ("MatCount:32*"+(t as string)) for i=1 to t do ( for j=1 to 32 do ( local t t = MeshMatID_array[(i-1)*32+j] -- just to print as little endian style.. -- number 0x12345678 prints as 12345678 but stored in 78 56 34 12 which is showed in mrl editor t = swapEndian t print ((i as string)+":"+(j as string)+":0x"+(bit.intasHex t)) ) ) ) else ( print ("MatCount:"+(MatCount as string)) print ("MeshMatID:"+(MeshMatID_array as string)) for i=1 to MatCount do ( local t t = MeshMatID_array[i] -- just to print as little endian style.. -- number 0x12345678 prints as 12345678 but stored in 78 56 34 12 which is showed in mrl editor t = swapEndian t print ((i as string)+":0x"+(bit.intasHex t)) ) )
print ("Position After Mat: "+ (bit.intasHex (ftell f)))
----------------------------------------------------------------------------------------------------------------- --Mesh Info fseek f hdr.ptr_Mesh #seek_Set
print ("Position Mesh Header: "+ (bit.intasHex (ftell f)))
--mesh info mc = hdr.MeshCount MeshInfo_array = #() MeshInfo_array.count = mc
for i=1 to mc do ( mhdr = ReadMeshHeader f MeshInfo_array[i] = #(mhdr.vertCount,mhdr.vertStride,mhdr.vertStart,mhdr.vertBase,mhdr.faceStart,mhdr.faceCount,mhdr.faceBase,mhdr.lodLevel,mhdr.fvfInfo,mhdr.matId,mhdr.unk01,mhdr.unk05) )
------------------------------- -- vertex MeshVertex_array = #() MeshVertex_array.count = mc MeshUV_array = #() MeshUV_array.count = mc MeshBoneID_array = #() MeshBoneID_array.count = mc MeshBoneWeight_array = #() MeshBoneWeight_array.count = mc MeshBoneLimit = #() MeshBoneLimit.count = mc
print ("Total Mesh Count : "+(mc as string))
for i=1 to mc do ( fseek f (hdr.ptr_vertex + MeshInfo_array[i][4]) #seek_Set -- check vertex, weight structure size is correct.. eash end position must match with next skipped to position --print ("start i="+(i as string)+":"+(bit.intasHex (ftell f))) fseek f (MeshInfo_array[i][2]*MeshInfo_array[i][3]) #seek_cur --print ("skipped to i="+(i as string)+":"+(bit.intasHex (ftell f)))
vc = MeshInfo_array[i][1] --if (vc==0) then (print "vc==0 at "+(i as string)) VertexPos_array = #() VertexPos_array.count = vc UV_array = #() UV_array.count = vc BoneID_array = #() BoneID_array.count = vc BoneWeight_array = #() BoneWeight_array.count = vc print ("mesh "+(i as string)+":"+(vc as string)+":"+(bit.intashex MeshInfo_array[i][9]))
case MeshInfo_array[i][9] of ( --12 x y z w nx ny nz nw (bit.hexasint "0xB0983013"): ( -- usually spline shape object so ignore it for c=1 to vc do ( VertexPos_array[c] = ReadVertexPos f fseek f 6 #seek_cur UV_array[c]=[0,0,0] ) ) (bit.hexasint "0xDB7DA014"): ( -- used in REHDRE -- usually spline shape object so ignore it for c=1 to vc do ( VertexPos_array[c] = ReadVertexPos f fseek f 6 #seek_cur -- 4 bytes to read -- fseek f 4 #seek_cur u1 = readShort f #unsigned; u1s=bit.intashex u1 -- ?? 0x80 u2 = readShort f #unsigned; u2s=bit.intashex u2 -- ?? 0x80 --vUV = [(ReadFloat16 f),(ReadFloat16 f)*-1.0 + 1.0,0.0] u3 = ToFloat16 u1 u4 = ToFloat16 u2 if (((abs u3)>1.0) or ((abs u4)>1.0)) then (print (#(u1s,u2s,u3,u4) as string)) --print (vUV as string) --UV_array[c]=vUV -- usually [0,1,0] UV_array[c]=[0,0,0] ) ) (bit.hexasint "0xB6681034"): ( print ("Position 0x"+(bit.intasHex (ftell f))) for c=1 to vc do ( VertexPos_array[c] = ReadVertexPos f fseek f 10 #seek_cur UV_array[c]=[0,0,0] ) print ("Not Exported Case 0xB6681034 at "+(i as string)) ) --20 (bit.hexasint "0x0CB68015"): ( -- used in REHDRE -- usually spline shape object so ignore it -- But it seems exported with zero values -> I corrected to export only positions. print ("Position 0x"+(bit.intasHex (ftell f))) for c=1 to vc do ( VertexPos_array[c] = ReadVertexPos f
-- maybe spline related data follows u1 = readByte f #unsigned -- 0 or negative u2 = readByte f -- 0
-- 8 bytes to read --fseek f 8 #seek_cur u3 = readByte f #unsigned u4 = readByte f #unsigned u5 = readByte f #unsigned u6 = readByte f #unsigned u7 = readByte f #unsigned u8 = readByte f #unsigned u9 = readByte f #unsigned u10 = readByte f #unsigned
-- 4 bytes to read fseek f 4 #seek_cur --c1 = readByte f #unsigned --c2 = readByte f #unsigned --c3 = readByte f #unsigned --c4 = readByte f #unsigned -- large values near 255
if (u1!=0 or u2!=0 or u4!=1 or u5!=1 or u6!=0 or u8!=0 or u9!=0 or u10!=0) then ( print (#(u1,u2,u3,u4,u5,u6,u7,u8,u9,u10) as string) ) UV_array[c]=[0,0,0] ) print ("Alert: Case 0x0CB68015 at "+(i as string)) ) (bit.hexasint "0xA8FAB018"): ( for c=1 to vc do ( --withskin x y z b1 w1 nx ny nz nw tx ty tz tw tu tv VertexPos_array[c] = ReadVertexPos f b1 = readByte f #unsigned b1 += 1 w1 = readByte f -- this seems always 0 fseek f 8 #seek_cur vUV = [(ReadFloat16 f),(ReadFloat16 f)*-1.0 + 1.0,0.0] if (w1!=0) then print ((c as string)+":"+(#(b1,w1) as string)) UV_array[c]=vUV BoneID_array[c] = #(b1) BoneWeight_array[c] = #(1.0) ) MeshBoneLimit[i] = 1 ) (bit.hexasint "0xA7D7D036"): ( print ("Position 0x"+(bit.intasHex (ftell f))) for c=1 to vc do ( VertexPos_array[c] = ReadVertexPos f fseek f 14 #seek_cur UV_array[c]=[0,0,0] ) print ("Not Exported Case 0xA7D7D036 at "+(i as string)) ) --24 (bit.hexasint "0xC31F201C"): ( for c=1 to vc do ( --withskin x y z w nx ny nz nw tx ty tz tw tu tv b1 b2 (b1 b2 half float) VertexPos_array[c] = ReadVertexPos f w1 = (readshort f)/32767.0 w2 = 1.0 - w1 fseek f 8 #seek_cur vUV = [(ReadFloat16 f),(ReadFloat16 f)*-1.0 + 1.0,0.0] b1 = int(ReadFloat16 f) b1 += 1 b2 = int(ReadFloat16 f) b2 += 1
UV_array[c]=vUV ba = getUniqueArray2 b1 b2 w1 w2 BoneID_array[c] = ba[1] BoneWeight_array[c] = ba[2] ) MeshBoneLimit[i] = 2 ) (bit.hexasint "0xCBF6C01A"): ( print ("Position 0x"+(bit.intasHex (ftell f))) for c=1 to vc do ( --withskin x y z bf bi nx ny nz nw tx ty tz tw tu tv 21 22 23 24 VertexPos_array[c] = ReadVertexPos f fseek f 10 #seek_cur vUV = [(ReadFloat16 f),(ReadFloat16 f)*-1.0 + 1.0,0.0] fseek f 4 #seek_cur UV_array[c]=[0,0,0] ) print ("Not Exported Case 0xCBF6C01A at "+(i as string)) MeshBoneLimit[i] = 1 ) (bit.hexasint "0x207D6037"): ( print ("Position 0x"+(bit.intasHex (ftell f))) for c=1 to vc do ( VertexPos_array[c] = ReadVertexPos f fseek f 10 #seek_cur vUV = [(ReadFloat16 f),(ReadFloat16 f)*-1.0 + 1.0,0.0] fseek f 4 #seek_cur UV_array[c]=vUV ) print ("Not Exported Case 0x207D6037 at "+(i as string)) ) (bit.hexasint "0xD1A47038"): ( print ("Position 0x"+(bit.intasHex (ftell f))) for c=1 to vc do ( VertexPos_array[c] = ReadVertexPos f fseek f 18 #seek_cur UV_array[c]=[0,0,0] ) print ("Not Exported Case 0xD1A47038 at "+(i as string)) ) (bit.hexasint "0xD8297028"): ( print ("Position 0x"+(bit.intasHex (ftell f))) for c=1 to vc do ( VertexPos_array[c] = ReadVertexPos f fseek f 18 #seek_cur UV_array[c]=[0,0,0] ) print ("Not Exported Case 0xD8297028 at "+(i as string)) ) (bit.hexasint "0x667B1019"): ( print ("Position 0x"+(bit.intasHex (ftell f))) for c=1 to vc do ( --withskin x y z bf bi nx ny nz nw tx ty tz tw tu tv lu lv VertexPos_array[c] = ReadVertexPos f fseek f 10 #seek_cur vUV = [(ReadFloat16 f),(ReadFloat16 f)*-1.0 + 1.0,0.0] fseek f 4 #seek_cur UV_array[c]=[0,0,0] ) print ("Not Exported Case 667B1019 at "+(i as string)) MeshBoneLimit[i] = 1 )
--28 (bit.hexasint "0x2BE814D4"): ( print ("Position 0x"+(bit.intasHex (ftell f))) for c=1 to vc do ( VertexPos_array[c] = ReadVertexPos f fseek f 22 #seek_cur UV_array[c]=[0,0,0] ) print ("Not Exported Case 2BE814D4 at "+(i as string)) ) (bit.hexasint "0x7CD414D4"): ( print ("Position 0x"+(bit.intasHex (ftell f))) for c=1 to vc do ( VertexPos_array[c] = ReadVertexPos f fseek f 22 #seek_cur UV_array[c]=[0,0,0] ) print ("Not Exported Case 7CD414D4 at "+(i as string)) ) (bit.hexasint "0x14D40020"): ( for c=1 to vc do ( --withskin x y z w1 nx ny nz nw tx ty tz tw b1 b2 b3 b4 tu tv w2 w3 VertexPos_array[c] = ReadVertexPos f w1 = (readshort f #unsigned)/32767.0 fseek f 8 #seek_cur b1 = readbyte f b2 = readbyte f b3 = readbyte f b4 = readbyte f b1 += 1 b2 += 1 b3 += 1 b4 += 1 vUV = [(ReadFloat16 f),(ReadFloat16 f)*-1.0 + 1.0,0.0] w2 = ReadFloat16 f w3 = ReadFloat16 f w4 = 1.0 - w1 - w2 - w3
UV_array[c]=vUV ba = getUniqueArray4 b1 b2 b3 b4 w1 w2 w3 w4 BoneID_array[c] = ba[1] BoneWeight_array[c] = ba[2] ) MeshBoneLimit[i] = 4 ) (bit.hexasint "0xA320C016"): ( -- used in REHDRE -- usually spline shape object so ignore it print ("Position 0x"+(bit.intasHex (ftell f))) for c=1 to vc do ( VertexPos_array[c] = ReadVertexPos f fseek f 22 #seek_cur UV_array[c]=[0,0,0] ) print ("Not Exported Case 0xA320C016 at "+(i as string)) ) (bit.hexasint "0x49B4F029"): ( print ("Position 0x"+(bit.intasHex (ftell f))) for c=1 to vc do ( VertexPos_array[c] = ReadVertexPos f fseek f 22 #seek_cur UV_array[c]=[0,0,0] ) print ("Not Exported Case 0x49B4F029 at "+(i as string)) ) (bit.hexasint "0x5E7F202C"): ( print ("Position 0x"+(bit.intasHex (ftell f))) for c=1 to vc do ( VertexPos_array[c] = ReadVertexPos f; fseek f 22 #seek_cur;UV_array[c]=[0,0,0] ) print ("Not Exported Case 0x5E7F202C at "+(i as string)) ) (bit.hexasint "0x0D9E801D"): ( print ("Position 0x"+(bit.intasHex (ftell f))) for c=1 to vc do ( --withskin x y z w nx ny nz nw tx ty tz tw tu tv b1 b2 tu2 tv2 VertexPos_array[c] = ReadVertexPos f; fseek f 22 #seek_cur;UV_array[c]=[0,0,0] ) print ("Not Exported Case 0x0D9E801D at "+(i as string)) MeshBoneLimit[i] = 2 ) (bit.hexasint "0xA013501E"): ( print ("Position 0x"+(bit.intasHex (ftell f))) for c=1 to vc do ( --withskin x y z w nx ny nz nw tx ty tz tw tu tv b1 b2 r g b a VertexPos_array[c] = ReadVertexPos f; fseek f 22 #seek_cur;UV_array[c]=[0,0,0] ) print ("Not Exported Case 0xA013501E at "+(i as string)) MeshBoneLimit[i] = 2 ) --32 (bit.hexasint "0xD877801B"): ( for c=1 to vc do ( --withskin x y z bf bi nx ny nz nw tx ty tz tw tu tv 12byte VertexPos_array[c] = ReadVertexPos f b1 = readByte f b1 += 1 w1 = readByte f BoneID_array[c] = #(b1) BoneWeight_array[c] = #(1.0) fseek f 16 #seek_cur vUV = [(ReadFloat16 f),(ReadFloat16 f)*-1.0 + 1.0,0.0] fseek f 4 #seek_cur UV_array[c]=vUV -- something seems missing ) print ("Case 0xD877801B at "+(i as string)) MeshBoneLimit[i] = 1 ) (bit.hexasint "0xB86DE02A"): ( print ("Position 0x"+(bit.intasHex (ftell f))) for c=1 to vc do ( VertexPos_array[c] = ReadVertexPos f; fseek f 26 #seek_cur;UV_array[c]=[0,0,0] ) print ("Not Exported Case 0xB86DE02A at "+(i as string)) ) (bit.hexasint "0x926FD02E"): ( print ("Position 0x"+(bit.intasHex (ftell f))) for c=1 to vc do ( VertexPos_array[c] = ReadVertexPos f; fseek f 26 #seek_cur;UV_array[c]=[0,0,0] ) print ("Not Exported Case 0x926FD02E at "+(i as string)) ) (bit.hexasint "0xA14E003C"): ( print ("Position 0x"+(bit.intasHex (ftell f))) for c=1 to vc do ( VertexPos_array[c] = ReadVertexPos f; fseek f 26 #seek_cur;UV_array[c]=[0,0,0] ) print ("Not Exported Case 0xA14E003C at "+(i as string)) ) (bit.hexasint "0xDA55A021"): ( print ("Position 0x"+(bit.intasHex (ftell f))) for c=1 to vc do ( --withskin x y z w nx ny nz nw tx ty tz tw b1 b2 b3 b4 tu tv w2 w3 short short VertexPos_array[c] = ReadVertexPos f; fseek f 26 #seek_cur;UV_array[c]=[0,0,0] ) print ("Not Exported Case 0xDA55A021 at "+(i as string)) ) (bit.hexasint "0x77D87022"): ( print ("Position 0x"+(bit.intasHex (ftell f))) for c=1 to vc do ( --withskin x y z w nx ny nz nw tx ty tz tw b1 b2 b3 b4 tu tv w2 w3 byte byte byte byte VertexPos_array[c] = ReadVertexPos f; fseek f 26 #seek_cur;UV_array[c]=[0,0,0] ) print ("Not Exported Case 0x77D87022 at "+(i as string)) )
--36 (bit.hexasint "0xB392101F"): ( print ("Position 0x"+(bit.intasHex (ftell f))) for c=1 to vc do (--withskin x y z w1 nx ny nz nw tx ty tz tw i1 i2 tu1 tv1 tu2 tv2 long long VertexPos_array[c] = ReadVertexPos f; fseek f 30 #seek_cur;UV_array[c]=[0,0,0] ) print ("Not Exported Case 0xB392101F at "+(i as string)) ) (bit.hexasint "0xBB424024"): ( n=4 for c=1 to vc do ( --withskin x y z w1 nx ny nz nw w2 w3 w4 w5 b1 b2 b3 b4 b5 b6 b7 b8 tu tv u3 u4 u5 u6 r g b a -- Need more Check!
-- Example Data ep04.mod --55 2b 09 4d 86 0a -- x,y,z --d1 51 -- w1 --d1 53 d5 fe -- nx,ny,nz,nw --45 0c 04 04 -- w2~w5 --21 19 1a 04 10 23 00 00 -- b1~b6,u1,u2 --37 38 dc 38 -- vUV --06 22 00 00 -- wb6,b7,wb7,b8 --d6 73 24 fe -- ?? (not weight, too large)
--ad 2a 7f 4a fe 07 -- x,y,z --4b 4c -- w1 --ce 61 dd fe -- nx,ny,nz,nw --67 00 00 00 -- w2~w5 --03 04 04 04 04 04 00 00 -- b1~b6,u1,u2 --04 38 3d 3a -- vUV --00 00 00 00 -- wb6,b7,wb7,b8 --df 7d 2d f3 -- ??
VertexPos_array[c] = ReadVertexPos f w1 = (readshort f #unsigned)/32767.0 fseek f 4 #seek_cur -- skip normal w2 = (readbyte f #unsigned)/255.0 w3 = (readbyte f #unsigned)/255.0 w4 = (readbyte f #unsigned)/255.0 w5 = (readbyte f #unsigned)/255.0
b1 = readbyte f b2 = readbyte f b3 = readbyte f b4 = readbyte f b5 = readbyte f b6 = readbyte f
u1 = readbyte f -- unknown, known values 0,4,22,18,41,45 u2 = readbyte f -- unknown, known values 0
b1 += 1; b2 += 1; b3 += 1; b4 += 1; b5 += 1; b6 += 1 u1 += 1; -- seems like a bone index, but b7 or b8 that's not clear -- u2 += 1; -- I have not seen this is not zero
vUV = [(ReadFloat16 f),(ReadFloat16 f)*-1.0 + 1.0,0.0]
-- <-This is just test wb6 = readbyte f -- known values 0,6,-124 b7 = readbyte f -- known values 43,38,40 b7 += 1 wb7 = readbyte f -- unknown, known values 0,7 b8 = readbyte f -- unknown, known values 0,39 b8 += 1
if (false) then ( -- don't use until it it certain if (wb6>=0) then (w6=wb6/510.0) else (w6=wb6+128; w6=w6/128.0) if (wb7>=0) then (w7=wb7/510.0) else (w7=wb7+128; w7=w7/128.0) wa = w1+w2+w3+w4+w5+w6+w7; w8 = 1.0-wa ) else ( wa = w1+w2+w3+w4+w5; w6 = 1.0-wa if (wb6>=0) then (ww6=wb6/510.0) else (ww6=wb6+128; ww6=ww6/128.0) if (wb7>=0) then (ww7=wb7/510.0) else (ww7=wb7+128; ww7=ww7/128.0) w7 = 0.0 w8 = 0.0 ) -- Until here, this is just test -->
fseek f 4 #seek_cur -- not weights, vertex color or tangent, write routines uses vTan, just skip now
UV_array[c]=vUV
if (false) then ( if ((abs w8) > FWeightMin) then ( print ((c as string)+":"+(#(b1,b2,b3,b4,b5,":",b6,b7,b8) as string)) print ((c as string)+":"+(#(w1,w2,w3,w4,w5,":",w6,w7,w8) as string)) ) ) else ( if ((abs w6) > FWeightMin) then ( print ((c as string)+":"+(#(b1,b2,b3,b4,b5,":",b6,b7,b8) as string)) print ((c as string)+":"+(#(w1,w2,w3,w4,w5,":",w6,ww6,ww7) as string)) ) )
if ((u1!=1 and u1!=5) or u2!=0 or b7!=1 or b8!=1 or wb6!=0 or wb7!=0) then ( if ((abs w6)<FWeightMin) then (w6=0.0) if ((abs w8)<FWeightMin) then (w8=0.0) print ("Alert:"+(c as string)+":"+(#(b1,b2,b3,b4,b5,":",b6,b7,b8) as string)) print ("Alert:"+(c as string)+":"+(#(u1,u2,wb6,b7,wb7,b8) as string)) print ("Alert:"+(c as string)+":"+(#(w1,w2,w3,w4,w5,":",w6,w7,w8) as string)) ) ba = getUniqueArray6 b1 b2 b3 b4 b5 b6 w1 w2 w3 w4 w5 w6 if (ba[3]>n) then (n=ba[3]) if (ba[3]>4) then ( if ((abs w6)<FWeightMin) then (w6=0.0) if ((abs w8)<FWeightMin) then (w8=0.0) print ("N>4:"+(c as string)+":"+(#(b1,b2,b3,b4,b5,":",b6,b7,b8) as string)) print ("N>4:"+(c as string)+":"+(#(u1,u2,wb6,b7,wb7,b8) as string)) print ("N>4:"+(c as string)+":"+(#(w1,w2,w3,w4,w5,":",w6,w7,w8) as string)) ) BoneID_array[c] = ba[1] BoneWeight_array[c] = ba[2] ) print ("Bones larger than 4 assigned: "+(n as string)) MeshBoneLimit[i] = n )
(bit.hexasint "0x63B6C02F"): ( print ("Position 0x"+(bit.intasHex (ftell f))) for c=1 to vc do ( VertexPos_array[c] = ReadVertexPos f; fseek f 30 #seek_cur;UV_array[c]=[0,0,0] ) print ("Not Exported Case 0x63B6C02F at "+(i as string)) )
--40 (bit.hexasint "0x64593023"): ( for c=1 to vc do ( --withskin x y z w1 nx ny nz nw tx ty tz tw i1 i2 i3 i4 tu tv w2 w3 short short tu2 tv2 short short VertexPos_array[c] = ReadVertexPos f w1 = (readshort f)/32767.0 fseek f 8 #seek_cur b1 = readbyte f b2 = readbyte f b3 = readbyte f b4 = readbyte f b1 += 1 b2 += 1 b3 += 1 b4 += 1 vUV = [(ReadFloat16 f),(ReadFloat16 f)*-1.0 + 1.0,0.0] w2 = ReadFloat16 f w3 = ReadFloat16 f w4 = 1.0 - w1 - w2 - w3
fseek f 4 #seek_cur vUV2 = [(ReadFloat16 f),(ReadFloat16 f)*-1.0 + 1.0,0.0] fseek f 4 #seek_cur
UV_array[c]=vUV ba = getUniqueArray4 b1 b2 b3 b4 w1 w2 w3 w4 BoneID_array[c] = ba[1] BoneWeight_array[c] = ba[2] ) MeshBoneLimit[i] = 4 ) (bit.hexasint "0x75C3E025"): ( print ("Position 0x"+(bit.intasHex (ftell f))) for c=1 to vc do ( --withskin x y z w1 nx ny nz nw w2 w3 w4 w5 i1 i2 i3 i4 i5 i6 i7 i8 tu tv w6 w7 r g b a tu2 tv2 VertexPos_array[c] = ReadVertexPos f; fseek f 14 #seek_cur; vUV = [(ReadFloat16 f),(ReadFloat16 f)*-1.0 + 1.0,0.0]; fseek f 16 #seek_cur;UV_array[c]=vUV ) print ("Not Exported Case 0x75C3E025 at "+(i as string)) ) (bit.hexasint "0xD84E3026"): ( print ("Position 0x"+(bit.intasHex (ftell f))) for c=1 to vc do ( --withskin x y z w1 nx ny nz nw w2 w3 w4 w5 i1 i2 i3 i4 i5 byte byte byte tv tu short shot v4 v4 VertexPos_array[c] = ReadVertexPos f; fseek f 14 #seek_cur; vUV = [(ReadFloat16 f),(ReadFloat16 f)*-1.0 + 1.0,0.0]; fseek f 16 #seek_cur;UV_array[c]=vUV ) print ("Not Exported Case 0xD84E3026 at "+(i as string)) ) --48 (bit.hexasint "0xCBCF7027"): ( print ("Position 0x"+(bit.intasHex (ftell f))) for c=1 to vc do ( --withskin x y z w1 nx ny nz nw w2 w3 w4 w5 i1 i2 i3 i4 i5 i6 i7 i8 tu tv w6 w7 tx ty tz tw long tu tv long VertexPos_array[c] = ReadVertexPos f; fseek f 14 #seek_cur; vUV = [(ReadFloat16 f),(ReadFloat16 f)*-1.0 + 1.0,0.0]; fseek f 16 #seek_cur;UV_array[c]=vUV ) print ("Not Exported Case 0xCBCF7027 at "+(i as string)) ) --64 (bit.hexasint "0x2F55C03D"): ( for c=1 to vc do ( --withskin x y z w1 nx ny nz nw tx ty tz tw b1 b2 b3 b4 tu tv w2 w3 long long long long long long long long long VertexPos_array[c] = ReadVertexPos f; w1 = (readshort f)/32767.0; fseek f 4 #seek_cur; --normal as signed bytes *4 fseek f 4 #seek_cur;-- tangeants as signed bytes *4
b1 = readbyte f b2 = readbyte f b3 = readbyte f b4 = readbyte f b1 += 1;b2 += 1;b3 += 1;b4 += 1 --bone id's vUV = [(ReadFloat16 f),(ReadFloat16 f)*-1.0 + 1.0,0.0] w2 = ReadFloat16 f w3 = ReadFloat16 f w4 = 1.0 - w1 - w2 - w3
fseek f 24 #seek_cur -- seems color or tangent -- A or W part large fseek f 12 #seek_cur
UV_array[c]=vUV ba = getUniqueArray4 b1 b2 b3 b4 w1 w2 w3 w4 BoneID_array[c] = ba[1] BoneWeight_array[c] = ba[2] ) --print ("Case 0x2F55C03D at "+(i as string)) MeshBoneLimit[i] = 4 ) default: ( print ("Position 0x"+(bit.intasHex (ftell f))) for c=1 to vc do ( VertexPos_array[c] = ReadVertexPos f fseek f 6 #seek_cur fseek f (MeshInfo_array[i][2] - 20) #seek_cur vUV = [(ReadFloat16 f),(ReadFloat16 f)*-1.0 + 1.0,0.0] fseek f 4 #seek_cur UV_array[c]=vUV ) print ("Unknown Case at"+(i as string)) ) )
-- check vertex, weight structure size is correct.. eash end position must match with next skipped to position --print ("end i="+(i as string)+":"+(bit.intasHex (ftell f)))
MeshVertex_array[i] = VertexPos_array MeshUV_array[i] = UV_array MeshBoneID_array[i] = BoneID_array MeshBoneWeight_array[i] = BoneWeight_array ) --build mesh fseek f hdr.ptr_triangle #seek_Set MeshFace_array = #() MeshFace_array.count = mc MatID_array = #() Mat_array = #() Mat_Carray = #()
for i=1 to mc do ( Face_array = #() fc = MeshInfo_array[i][6]/3 Face_array.count = fc vstart = MeshInfo_array[i][3] --print ("i:vstart="+(i as string)+":"+(vstart as string)) for c=1 to fc do ( fi = ReadFace f Face_array[c] = fi - [vstart-1,vstart-1,vstart-1] ) MeshFace_array[i] = Face_array )
--build mat
for i=1 to mc do ( matid = MeshInfo_array[i][10] idx = findItem MatID_array matid if (idx == 0) then ( append MatID_array matid sm = standardmaterial() sm.name = "#"+(matid as string) sm.shaderType = 5 -- 5 phong -- make color unique do ( co = random white black coidx = findItem Mat_Carray co ) while (coidx != 0) append Mat_Carray co sm.diffuse = co -- specular -- just for import/export compatibility sm.specular = (color 51 51 51) -- cinema 4d : default value 20% specular height sm.specularLevel = 20 -- cinema 4d : goes to specular width sm.soften = 0.1 append Mat_array sm ) )
--build mesh --Lod Packet Lod1 = Dummy size:10.0 Lod1.name = "LodGroup_1" Lod2 = Dummy size:10.0 Lod2.name = "LodGroup_2" Lod3 = Dummy size:10.0 Lod3.name = "LodGroup_3" Lod255 = Dummy size:10.0 Lod255.name = "LodGroup_255" Lod252 = Dummy size:10.0 Lod252.name = "LodGroup_252" OtherMesh = Dummy size:10.0 OtherMesh.name = "OtherMesh"
for i=1 to mc do ( new_mesh = mesh vertices:MeshVertex_array[i] faces:MeshFace_array[i] new_mesh.name = ( "Mesh_"+ (PadString 3 (i as string)) +"_"+ \ (PadString 8 ((bit.intashex MeshInfo_array[i][9]) as string)) +"_LODx"+ \ MeshInfo_array[i][8] as string + "_MatID:" + MeshInfo_array[i][10] as string + \ "_Group:" + MeshInfo_array[i][11] as string + "_DisplayMode:" + \ MeshInfo_array[i][12] as string ) new_mesh.scale = MeshScale
vc = MeshInfo_array[i][1] fc = MeshInfo_array[i][6]/3 --build UV setNumTVerts new_mesh vc for c=1 to vc do ( setTVert new_mesh c MeshUV_array[i][c] ) -- Even spline like object has faces if (fc==0) then (print "Vertex Only Object at:"+(i as string)) buildTVFaces new_mesh false for f=1 to fc do ( setTVFace new_mesh f MeshFace_array[i][f] ) --Skin if MeshBoneID_array[i][1] != undefined then ( addModifier new_mesh (skin()) theSkin = new_mesh.modifiers[#skin] theSkin.bone_Limit = MeshBoneLimit[i] max modify mode select new_mesh for b = 1 to bCount do ( skinOps.addBone theSkin BoneArray[b] b ) subobjectLevel = 1 if MeshInfo_array[i][8] == 1 then new_mesh.Parent = Lod1 if MeshInfo_array[i][8] == 2 then new_mesh.Parent = Lod2 if MeshInfo_array[i][8] == 3 then new_mesh.Parent = Lod3 if MeshInfo_array[i][8] == 255 then new_mesh.Parent = Lod255 if MeshInfo_array[i][8] == 252 then new_mesh.Parent = Lod252
for c=1 to vc do ( local bi, bw
--b1 = MeshBoneID_array[i][c][1] --b2 = MeshBoneID_array[i][c][2] --b3 = MeshBoneID_array[i][c][3] --b4 = MeshBoneID_array[i][c][4] --w1 = MeshBoneWeight_array[i][c][1] --w2 = MeshBoneWeight_array[i][c][2] --w3 = MeshBoneWeight_array[i][c][3] --w4 = MeshBoneWeight_array[i][c][4] -- don't use copy use deepcopy, copy just gives Ok in this case. Anyway I don't think deepcopy is required. bi = MeshBoneID_array[i][c] bw = MeshBoneWeight_array[i][c]
skinOps.unNormalizeVertex theSkin c true --skinOps.ReplaceVertexWeights theSkin c #(b1,b2,b3,b4) #(w1,w2,w3,w4) skinOps.ReplaceVertexWeights theSkin c bi bw skinOps.unNormalizeVertex theSkin c false
)
update new_mesh subobjectLevel = 0 ) else ( new_mesh.Parent = OtherMesh ) -- material matid = MeshInfo_array[i][10] idx = findItem MatID_array matid if (idx != 0) then ( new_mesh.material = Mat_array[idx] ) )
)
fn doExport f fsource = ( Type = ReadFixedString f 4 if Type != "MOD" do ( messageBox "It is not Mod file" return() )
nf = fopen (fsource +".NewMOD") "wb" WriteString nf "MOD" --MOD fseek f 4 #seek_Set;mod_ver = readshort f #unsigned WriteShort nf mod_ver BoneCount = readshort f WriteShort nf BoneCount MeshCount = readshort f WriteShort nf MeshCount MatCount = readshort f WriteShort nf MatCount OrgVertexCount = readlong f WriteLong nf OrgVertexCount OrgFaceCount = readlong f WriteLong nf OrgFaceCount OrgVertexIds = readlong f WriteLong nf OrgVertexIds OrgVertexSize = readlong f WriteLong nf OrgVertexSize ReadTemp = readlong f WriteLong nf ReadTemp --padding BoneMapCount = readlong f WriteLong nf BoneMapCount --BoneMapCount ptr_Bone = readlong f WriteLong nf ptr_Bone --ptr_Bone ptr_BoneMap = readlong f WriteLong nf ptr_BoneMap --ptr_BoneMap ptr_MatID = readlong f WriteLong nf ptr_MatID --ptr_MatID ptr_Mesh = readlong f WriteLong nf ptr_Mesh --ptr_Mesh ptr_vertex = readlong f WriteLong nf ptr_vertex --ptr_vertex OrgPtr_triangle = readlong f WriteLong nf OrgPtr_triangle OrgEndSize = readlong f WriteLong nf OrgEndSize
ReadTemp = readlong f WriteLong nf ReadTemp --? X ReadTemp = readlong f WriteLong nf ReadTemp --? Y ReadTemp = readlong f WriteLong nf ReadTemp --? Z ReadTemp = readlong f WriteLong nf ReadTemp --? R BoundMin = $BoundBoxMin.pos -- Bound box min Writefloat nf BoundMin.x Writefloat nf BoundMin.y Writefloat nf BoundMin.z Writefloat nf 0.0 BoundMax = $BoundBoxMax.pos -- Bound box max Writefloat nf BoundMax.x Writefloat nf BoundMax.y Writefloat nf BoundMax.z Writefloat nf 0.0 --unknow fseek f 32 #seek_cur ReadTemp = readlong f WriteLong nf ReadTemp ReadTemp = readlong f WriteLong nf ReadTemp ReadTemp = readlong f WriteLong nf ReadTemp ReadTemp = readlong f WriteLong nf ReadTemp if mod_ver==0x00D2 do ( ReadTemp = readlong f ukCount = ReadTemp WriteLong nf ReadTemp ) -- BoneInfo for i=1 to BoneCount do ( BInfo = ReadBoneInfo f WriteByte nf BInfo.ID WriteByte nf BInfo.Parent WriteByte nf BInfo.Child WriteByte nf BInfo.uk1 WriteFloat nf BInfo.uk2 WriteFloat nf BInfo.uk3 WriteFloat nf BInfo.Trans.x WriteFloat nf BInfo.Trans.y WriteFloat nf BInfo.Trans.z
) -- Local & World bone Matrix (16+16=32) for i=1 to BoneCount do ( for j=1 to 32 do ( ReadTemp = readlong f WriteLong nf ReadTemp ) ) --unknown for i=1 to 256 do ( ReadTemp = readByte f WriteByte nf ReadTemp )
-- BoneMapListA for i=1 to BoneMapCount do ( for j=1 to 8 do ( ReadTemp = readlong f WriteLong nf ReadTemp ) )
-- Mat ID array for i=1 to MatCount do ( cnt = 1 if mod_ver==0x00D2 do (cnt=32) for j=1 to cnt do ( ReadTemp = readlong f WriteLong nf ReadTemp ) )
SelectMeshInfo = #() SelectMeshInfo2 = #() SelectMeshInfo.count = selection.count SelectMeshInfo2.count = selection.count -- selection.count is checeked before the call for i=1 to selection.count do ( sName = filterString selection[i].name "_" SelectMeshInfo[i] = #(selection[i],sName[2],sName[3],i) --#(Mesh, MeshIndex, VertexType) if (sName.count == 7) then ( -- old script naming scheme, but how can it be possible? by import? mshHdr_matid = execute ((filterString sName[5] ":")[2]) mshHdr_grp = execute ((filterString sName[6] ":")[2]) mshHdr_mde = execute ((filterString sName[7] ":")[2]) mshHdr_lod = execute ((filterString sName[4] "x")[2]) SelectMeshInfo2[i] = #(mshHdr_matid,mshHdr_grp,mshHdr_mde,mshHdr_lod) ) else ( -- for mixed messed up case SelectMeshInfo2[i] = #(-1,-1,-1,-1) ) ) --print SelectMeshInfo NewMeshInfo = #() NewMeshInfo.count = MeshCount for i=1 to MeshCount do ( bMeshSame = false sc = 0 OrgMeshInfo = ReadMeshHeader f OrgMeshInfo_Array for j=1 to selection.count do ( ind = execute SelectMeshInfo[j][2] if ind == i then ( bMeshSame = true sc = j break ) ) if (bMeshSame == true) then ( writeshort nf OrgMeshInfo.meshtype vc = getNumVerts SelectMeshInfo[sc][1] writeshort nf vc
if (SelectMeshInfo2[sc][1]!=-1) then ( writebyte nf SelectMeshInfo2[sc][2] writeshort nf SelectMeshInfo2[sc][1] --Is this valid? writebyte nf SelectMeshInfo2[sc][4] writebyte nf OrgMeshInfo.unk04 writebyte nf OrgMeshInfo.vertFlag writebyte nf OrgMeshInfo.vertStride writebyte nf SelectMeshInfo2[sc][3] ) else ( writebyte nf OrgMeshInfo.unk01 writeshort nf OrgMeshInfo.MatId writebyte nf OrgMeshInfo.lodLevel writebyte nf OrgMeshInfo.unk04 writebyte nf OrgMeshInfo.vertFlag writebyte nf OrgMeshInfo.vertStride writebyte nf OrgMeshInfo.unk05 ) writelong nf OrgMeshInfo.vertStart writelong nf OrgMeshInfo.vertBase writelong nf OrgMeshInfo.fvfInfo writelong nf OrgMeshInfo.faceStart fc = getNumFaces SelectMeshInfo[sc][1] ifc = fc *= 3 writelong nf ifc writelong nf OrgMeshInfo.faceBase writebyte nf OrgMeshInfo.bonemapindex writebyte nf OrgMeshInfo.weightmaps writebyte nf OrgMeshInfo.unk07 writebyte nf OrgMeshInfo.unk08 writeshort nf OrgMeshInfo.min_index writeshort nf OrgMeshInfo.max_index writelong nf OrgMeshInfo.unk09 NewMeshInfo[i] = #(true,OrgMeshInfo.fvfInfo,OrgMeshInfo.vertStride,vc,fc,sc,OrgMeshInfo.min_index,OrgMeshInfo.vertBase) ) else ( writeshort nf OrgMeshInfo.meshtype writeshort nf OrgMeshInfo.vertCount vc = OrgMeshInfo.vertCount writebyte nf OrgMeshInfo.unk01 writeshort nf OrgMeshInfo.MatId writebyte nf OrgMeshInfo.lodLevel writebyte nf OrgMeshInfo.unk04 writebyte nf OrgMeshInfo.vertFlag writebyte nf OrgMeshInfo.vertStride writebyte nf OrgMeshInfo.unk05 writelong nf OrgMeshInfo.vertStart writelong nf OrgMeshInfo.vertBase writelong nf OrgMeshInfo.fvfInfo writelong nf OrgMeshInfo.faceStart writelong nf OrgMeshInfo.faceCount writelong nf OrgMeshInfo.faceBase fc = OrgMeshInfo.faceCount writebyte nf OrgMeshInfo.bonemapindex writebyte nf OrgMeshInfo.weightmaps writebyte nf OrgMeshInfo.unk07 writebyte nf OrgMeshInfo.unk08 writeshort nf OrgMeshInfo.min_index writeshort nf OrgMeshInfo.max_index writelong nf OrgMeshInfo.unk09 NewMeshInfo[i] = #(false,OrgMeshInfo.fvfInfo,OrgMeshInfo.vertStride,vc,fc,0,OrgMeshInfo.min_index,OrgMeshInfo.vertBase) ) NewMeshInfo[i][10] = OrgMeshInfo.vertCount*OrgMeshInfo.vertStride NewMeshInfo[i][11] = OrgMeshInfo.faceCount )
if mod_ver!=0x00D2 do ( ukCount = readlong f WriteLong nf ukCount ) for i=1 to ukCount do ( for j=1 to 36 do ( ReadTemp = readlong f WriteLong nf ReadTemp ) ) --vertex for i=1 to MeshCount do ( vc = NewMeshInfo[i][4] vs = NewMeshInfo[i][3] if NewMeshInfo[i][1] == false then ( vs /= 4 for v=1 to vc do ( for s=1 to vs do ( ReadTemp = readlong f WriteLong nf ReadTemp ) ) ) else ( vcs = NewMeshInfo[i][10];fseek f vcs #seek_cur si = NewMeshInfo[i][6] OutMesh = SelectMeshInfo[si][1] max modify mode select OutMesh theSkin = OutMesh.modifiers[#skin] theNorm = OutMesh.modifiers["Edit Normals"] NormArray = #() NormArray.count = vc if theNorm != undefined then ( modPanel.setCurrentObject theNorm vnt = #{} for i=1 to vc do ( vct = #{i} theNorm.ConvertVertexSelection vct vnt vnf = vnt as array N = theNorm.GetNormal vnf[1] NormArray[i] = [N.x,N.z,-N.y] ) ) else ( for i=1 to vc do ( nodn = getNormal OutMesh i NormArray[i] = [nodn.x,nodn.z,-nodn.y] ) ) if theSkin != undefined then modPanel.setCurrentObject theSkin local b1,b2,b3,b4,b5,b6,w1,w2,w3,w4,w5,w6 --bone weight MeshScale = 32768/($b_0_1.scale) case NewMeshInfo[i][2] of ( --12 x y z w nx ny nz nw (bit.hexasint "0xB0983013"): for c=1 to vc do ( vPos = (getVert OutMesh c)*MeshScale vPos = [vPos.x,vPos.z,-vPos.y] vNorm = NormArray[c]; vTan = Cross [1,0,0] vNorm vNorm *= 127.0; vNorm += 127 WriteShort nf vPos.x; WriteShort nf vPos.y; WriteShort nf vPos.z; WriteShort nf 26470 WriteByte nf vNorm.x; WriteByte nf vNorm.y; WriteByte nf vNorm.z; WriteByte nf 254 --WriteShort nf 0; WriteShort nf 0; WriteShort nf 0; WriteShort nf 0 --WriteByte nf 0; WriteByte nf 0; WriteByte nf 0; WriteByte nf 0 ) --16 (bit.hexasint "0xDB7DA014"): for c=1 to vc do ( vPos = (getVert OutMesh c)*MeshScale vPos = [vPos.x,vPos.z,-vPos.y] vNorm = NormArray[c] vNorm *= 127.0; vNorm += 127 uvw = getTVert OutMesh c uvw.y = 1.0 - uvw.y vTan = Normalize( vPos/uvw.y) vTan *= 127.0; vTan += 127 WriteShort nf vPos.x; WriteShort nf vPos.y; WriteShort nf vPos.z; WriteShort nf 26470 WriteByte nf vNorm.x; WriteByte nf vNorm.y; WriteByte nf vNorm.z; WriteByte nf 254
WriteShort nf (FShort uvw.x) WriteShort nf (FShort uvw.y) ) --20 (bit.hexasint "0x0CB68015"): for c=1 to vc do --withskin x y z bi bf nx ny nz nw tx ty tz tw tu tv ( vPos = (getVert OutMesh c)*MeshScale vPos = [vPos.x,vPos.z,-vPos.y] /*vNorm = NormArray[c] vNorm *= 127.0; vNorm += 127
uvw = getTVert OutMesh c uvw.y = 1.0 - uvw.y vTan = Normalize( vPos/uvw.y) vTan *= 127.0; vTan += 127
b1 = skinOps.GetVertexWeightBoneID theSkin c 1 b1 -= 1 w1 = 254 */
WriteShort nf vPos.x; WriteShort nf vPos.y; WriteShort nf vPos.z -- other stuff is not clear WriteShort nf 0 WriteLong nf 0; WriteLong nf 0; WriteLong nf 0 ) (bit.hexasint "0xA8FAB018"): for c=1 to vc do --withskin x y z bi bf nx ny nz nw tx ty tz tw tu tv ( vPos = (getVert OutMesh c)*MeshScale vPos = [vPos.x,vPos.z,-vPos.y] vNorm = NormArray[c] vNorm *= 127.0; vNorm += 127 uvw = getTVert OutMesh c uvw.y = 1.0 - uvw.y vTan = Normalize( vPos/uvw.y) vTan *= 127.0; vTan += 127 b1 = skinOps.GetVertexWeightBoneID theSkin c 1 b1 -= 1 w1 = 254 WriteShort nf vPos.x; WriteShort nf vPos.y; WriteShort nf vPos.z WriteByte nf b1 WriteByte nf w1 WriteByte nf vNorm.x; WriteByte nf vNorm.y; WriteByte nf vNorm.z; WriteByte nf 254 WriteByte nf vTan.x; WriteByte nf vTan.y; WriteByte nf vTan.z; WriteByte nf 254 WriteShort nf (FShort uvw.x) WriteShort nf (FShort uvw.y) ) --24 (bit.hexasint "0xC31F201C"): for c=1 to vc do --withskin x y z w nx ny nz nw tx ty tz tw tu tv b1 b2 (b1 b2 half float) ( vPos = (getVert OutMesh c)*MeshScale vPos = [vPos.x,vPos.z,-vPos.y] vNorm = NormArray[c] vNorm *= 127.0; vNorm += 127 uvw = getTVert OutMesh c uvw.y = 1.0 - uvw.y vTan = Normalize( vPos/uvw.y) vTan *= 127.0; vTan += 127 bc = skinOps.getVertexWeightCount theSkin c if (bc>2) then (bc=2) -- if you have modified if bc == 1 then ( b1 = skinOps.GetVertexWeightBoneID theSkin c 1 b1 -= 1 b2=b1 w1 = 254 ) if bc == 2 then ( b1 = skinOps.GetVertexWeightBoneID theSkin c 1;b2 = skinOps.GetVertexWeightBoneID theSkin c 2 b1 -= 1 b2 -= 1 w1 = skinOps.getVertexWeight theSkin c 1 ) WriteShort nf vPos.x; WriteShort nf vPos.y; WriteShort nf vPos.z WriteShort nf (w1*32767) WriteByte nf vNorm.x; WriteByte nf vNorm.y; WriteByte nf vNorm.z; WriteByte nf 254 WriteByte nf vTan.x; WriteByte nf vTan.y; WriteByte nf vTan.z; WriteByte nf 254 WriteShort nf (FShort uvw.x) WriteShort nf (FShort uvw.y) WriteShort nf (FShort b1) WriteShort nf (FShort b2) ) --28 (bit.hexasint "0x14D40020"): for c=1 to vc do ( vPos = (getVert OutMesh c)*MeshScale vPos = [vPos.x,vPos.z,-vPos.y] vNorm = NormArray[c] vNorm *= 127.0; vNorm += 127 uvw = getTVert OutMesh c uvw.y = 1.0 - uvw.y vTan = Normalize( vPos/uvw.y) vTan *= 127.0; vTan += 127
bc = skinOps.getVertexWeightCount theSkin c case bc of ( 0: ( b1=0 b2=b1;b3=b1;b4=b1 w1=1.0 w2=0.0;w3=0.0;w4=0.0 ) 1: ( b1 = skinOps.GetVertexWeightBoneID theSkin c 1 b1 -= 1 b2=b1;b3=b1;b4=b1 w1 = skinOps.getVertexWeight theSkin c 1 w2=0.0;w3=0.0;w4=0.0 ) 2: ( b1 = skinOps.GetVertexWeightBoneID theSkin c 1 b2 = skinOps.GetVertexWeightBoneID theSkin c 2 b1 -= 1 b2 -= 1 b3=b1;b4=b1 w1 = skinOps.getVertexWeight theSkin c 1; w2 = skinOps.getVertexWeight theSkin c 2; w3=0.0;w4=0.0 ) 3: ( b1 = skinOps.GetVertexWeightBoneID theSkin c 1 b2 = skinOps.GetVertexWeightBoneID theSkin c 2 b3 = skinOps.GetVertexWeightBoneID theSkin c 3 b1 -= 1 b2 -= 1 b3 -= 1 b4=b1 w1 = skinOps.getVertexWeight theSkin c 1; w2 = skinOps.getVertexWeight theSkin c 2; w3 = skinOps.getVertexWeight theSkin c 3; w4=0.0 ) default: ( -- >= 4 b1 = skinOps.GetVertexWeightBoneID theSkin c 1 b2 = skinOps.GetVertexWeightBoneID theSkin c 2 b3 = skinOps.GetVertexWeightBoneID theSkin c 3 b4 = skinOps.GetVertexWeightBoneID theSkin c 4 b1 -= 1;b2 -= 1;b3 -= 1;b4 -=1 w1 = skinOps.getVertexWeight theSkin c 1 w2 = skinOps.getVertexWeight theSkin c 2 w3 = skinOps.getVertexWeight theSkin c 3 w4 = skinOps.getVertexWeight theSkin c 4 ) ) -- in fact w4 is assumed 1-w1-w2-w3 and not used WriteShort nf vPos.x WriteShort nf vPos.y WriteShort nf vPos.z WriteShort nf (w1*32767) WriteByte nf vNorm.x; WriteByte nf vNorm.y; WriteByte nf vNorm.z; WriteByte nf 254 WriteByte nf vTan.x; WriteByte nf vTan.y; WriteByte nf vTan.z; WriteByte nf 254 WriteByte nf b1 WriteByte nf b2 WriteByte nf b3 WriteByte nf b4 WriteShort nf (FShort uvw.x) WriteShort nf (FShort uvw.y) WriteShort nf (FShort w2) WriteShort nf (FShort w3) ) --32 (bit.hexasint "0xD877801B"): for c=1 to vc do --withskin x y z bf bi nx ny nz nw tx ty tz tw tu tv 12byte 只有一根骨??重 ( vPos = (getVert OutMesh c)*MeshScale vPos = [vPos.x,vPos.z,-vPos.y] vNorm = NormArray[c] vNorm *= 127.0; vNorm += 127 uvw = getTVert OutMesh c uvw.y = 1.0 - uvw.y vTan = Normalize( vPos/uvw.y) vTan *= 127.0; vTan += 127 b1 = skinOps.GetVertexWeightBoneID theSkin c 1 b1 -= 1 w1 = 254 WriteShort nf vPos.x; WriteShort nf vPos.y; WriteShort nf vPos.z WriteByte nf b1 WriteByte nf w1 WriteByte nf vNorm.x; WriteByte nf vNorm.y; WriteByte nf vNorm.z; WriteByte nf 254 WriteByte nf vTan.x; WriteByte nf vTan.y; WriteByte nf vTan.z; WriteByte nf 254 WriteLong nf 0 WriteLong nf 0 WriteShort nf (FShort uvw.x) WriteShort nf (FShort uvw.y) WriteLong nf 0 ) --36 --for c=1 to vc do --withskin x y z w1 nx ny nz nw w2 w3 w4 w5 b1 b2 b3 b4 b5 b6 u1 u2 tu tv short short r g b a (bit.hexasint "0xBB424024"): for c=1 to vc do ( -- Need more Check vPos = (getVert OutMesh c)*MeshScale vPos = [vPos.x,vPos.z,-vPos.y] vNorm = NormArray[c] vNorm *= 127.0; vNorm += 127 uvw = getTVert OutMesh c uvw.y = 1.0 - uvw.y vTan = Normalize( vPos/uvw.y) vTan *= 127.0; vTan += 127
bc = skinOps.getVertexWeightCount theSkin c
-- this case occures in RE HD remaster and use 4 (head b_4_5) as bone index default DBI = 4 -- Default Bone Index (of head)
case bc of ( 0: ( b1=DBI;b2=b1;b3=b1;b4=b1;b5=b1;b6=b1 w1=1.0 w2=0.0;w3=0.0;w4=0.0;w5=0.0;w6=0.0 ) 1: ( b1 = skinOps.GetVertexWeightBoneID theSkin c 1 b1 -= 1 b2=DBI;b3=b2;b4=b2;b5=b2;b6=b2 --w1 = skinOps.getVertexWeight theSkin c 1 w1=1.0 w2=0.0;w3=0.0;w4=0.0;w5=0.0;w6=0.0 ) 2: ( b1 = skinOps.GetVertexWeightBoneID theSkin c 1 b2 = skinOps.GetVertexWeightBoneID theSkin c 2 b1 -= 1 b2 -= 1 b3=DBI;b4=b3;b5=b3;b6=b3 w1 = skinOps.getVertexWeight theSkin c 1; w2 = skinOps.getVertexWeight theSkin c 2; w3=0.0;w4=0.0;w5=0.0;w6=0.0 --Assume all weights normalized --wa = w1+w2; wd=1.0-wa; --if ((abs wd) >= FWeightMin) then (w1+=(wd/2.0);w2+=(wd/2.0)) ) 3: ( b1 = skinOps.GetVertexWeightBoneID theSkin c 1 b2 = skinOps.GetVertexWeightBoneID theSkin c 2 b3 = skinOps.GetVertexWeightBoneID theSkin c 3 b1 -= 1 b2 -= 1 b3 -= 1 b4=DBI;b5=b4;b6=b4 w1 = skinOps.getVertexWeight theSkin c 1; w2 = skinOps.getVertexWeight theSkin c 2; w3 = skinOps.getVertexWeight theSkin c 3; w4=0.0;w5=0.0;w6=0.0 --wa = w1+w2+w3; wd=1.0-wa; --if ((abs wd) >= FWeightMin) then (w1+=(wd/3.0);w2+=(wd/3.0);w3+=(wd/3.0)) ) 4: ( b1 = skinOps.GetVertexWeightBoneID theSkin c 1 b2 = skinOps.GetVertexWeightBoneID theSkin c 2 b3 = skinOps.GetVertexWeightBoneID theSkin c 3 b4 = skinOps.GetVertexWeightBoneID theSkin c 4 b1 -= 1 b2 -= 1 b3 -= 1 b4 -= 1 b5=DBI;b6=b1 w1 = skinOps.getVertexWeight theSkin c 1; w2 = skinOps.getVertexWeight theSkin c 2; w3 = skinOps.getVertexWeight theSkin c 3; w4 = skinOps.getVertexWeight theSkin c 3; w5=0.0;w6=0.0 --wa = w1+w2+w3+w4; wd=1.0-wa; --if ((abs wd) >= FWeightMin) then (w1+=(wd/4.0);w2+=(wd/4.0);w3+=(wd/4.0);w4+=(wd/4.0)) ) 5: ( b1 = skinOps.GetVertexWeightBoneID theSkin c 1 b2 = skinOps.GetVertexWeightBoneID theSkin c 2 b3 = skinOps.GetVertexWeightBoneID theSkin c 3 b4 = skinOps.GetVertexWeightBoneID theSkin c 4 b5 = skinOps.GetVertexWeightBoneID theSkin c 5 b1 -= 1;b2 -= 1;b3 -= 1;b4 -= 1;b5 -= 1 b6 = DBI w1 = skinOps.getVertexWeight theSkin c 1 w2 = skinOps.getVertexWeight theSkin c 2 w3 = skinOps.getVertexWeight theSkin c 3 w4 = skinOps.getVertexWeight theSkin c 4 w5 = skinOps.getVertexWeight theSkin c 5 w6 = 0.0 --wa = w1+w2+w3+w4+w5; wd=1.0-wa; --if ((abs wd) >= FWeightMin) then (w1+=(wd/5.0);w2+=(wd/5.0);w3+=(wd/5.0);w4+=(w5/5.0);w5+=(wd/5.0)) ) default: ( -- >= 6 -- b6 and w6 is not guaranteed correct so eliminate it. -- weights are assumed sorted already b1 = skinOps.GetVertexWeightBoneID theSkin c 1 b2 = skinOps.GetVertexWeightBoneID theSkin c 2 b3 = skinOps.GetVertexWeightBoneID theSkin c 3 b4 = skinOps.GetVertexWeightBoneID theSkin c 4 b5 = skinOps.GetVertexWeightBoneID theSkin c 5 b6 = skinOps.GetVertexWeightBoneID theSkin c 5 b1 -= 1;b2 -= 1;b3 -= 1;b4 -= 1;b5 -= 1;b6 -= 1 w1 = skinOps.getVertexWeight theSkin c 1 w2 = skinOps.getVertexWeight theSkin c 2 w3 = skinOps.getVertexWeight theSkin c 3 w4 = skinOps.getVertexWeight theSkin c 4 w5 = skinOps.getVertexWeight theSkin c 5 w6 = skinOps.getVertexWeight theSkin c 6 wa = w1+w2+w3+w4+w5; wd=1.0-wa; -- eliminate w6 etc if ((abs wd) >= FWeightMin) then ( w1+=(wd/5.0);w2+=(wd/5.0);w3+=(wd/5.0);w4+=(w5/5.0);w5+=(wd/5.0);w6=0.0 ) else ( w6=0.0 ) ) )
WriteShort nf vPos.x; WriteShort nf vPos.y; WriteShort nf vPos.z WriteShort nf (w1*32767) WriteByte nf vNorm.x; WriteByte nf vNorm.y; WriteByte nf vNorm.z; WriteByte nf 254 --WriteByte nf vTan.x; WriteByte nf vTan.y; WriteByte nf vTan.z; WriteByte nf 254 WriteByte nf (w2*255) WriteByte nf (w3*255) WriteByte nf (w4*255) WriteByte nf (w5*255) WriteByte nf b1 WriteByte nf b2 WriteByte nf b3 WriteByte nf b4 WriteByte nf b5 WriteByte nf DBI -- remove b6..in fact, this can be different value WriteByte nf 0 -- mystery bone index WriteByte nf 0 -- seems always 0 WriteShort nf (FShort uvw.x) WriteShort nf (FShort uvw.y) WriteByte nf 0 -- w6 ? WriteByte nf 0 -- b7 ? WriteByte nf 0 -- w7 ? WriteByte nf 0 -- b8 ?
WriteByte nf vTan.x; WriteByte nf vTan.y; WriteByte nf vTan.z; WriteByte nf 254 -- correct? ) --40 (bit.hexasint "0x64593023"): for c=1 to vc do --withskin x y z w1 nx ny nz nw tx ty tz tw i1 i2 i3 i4 tu tv w2 w3 short short tu2 tv2 short short ( vPos = (getVert OutMesh c)*MeshScale vPos = [vPos.x,vPos.z,-vPos.y] vNorm = NormArray[c] vNorm *= 127.0; vNorm += 127 uvw = getTVert OutMesh c uvw.y = 1.0 - uvw.y vTan = Normalize( vPos/uvw.y) vTan *= 127.0; vTan += 127 bc = skinOps.getVertexWeightCount theSkin c case bc of ( 0: ( b1=0 b2=b1;b3=b1;b4=b1 w1=1.0 w2=0.0;w3=0.0;w4=0.0 ) 1: ( b1 = skinOps.GetVertexWeightBoneID theSkin c 1 b1 -= 1 b2=b1;b3=b1;b4=b1 w1 = skinOps.getVertexWeight theSkin c 1 w2=0.0;w3=0.0;w4=0.0 ) 2: ( b1 = skinOps.GetVertexWeightBoneID theSkin c 1 b2 = skinOps.GetVertexWeightBoneID theSkin c 2 b1 -= 1 b2 -= 1 b3=b1;b4=b1 w1 = skinOps.getVertexWeight theSkin c 1; w2 = skinOps.getVertexWeight theSkin c 2; w3=0.0;w4=0.0 ) 3: ( b1 = skinOps.GetVertexWeightBoneID theSkin c 1 b2 = skinOps.GetVertexWeightBoneID theSkin c 2 b3 = skinOps.GetVertexWeightBoneID theSkin c 3 b1 -= 1 b2 -= 1 b3 -= 1 b4=b1 w1 = skinOps.getVertexWeight theSkin c 1; w2 = skinOps.getVertexWeight theSkin c 2; w3 = skinOps.getVertexWeight theSkin c 3; w4=0.0 ) default: ( -- >= 4 b1 = skinOps.GetVertexWeightBoneID theSkin c 1 b2 = skinOps.GetVertexWeightBoneID theSkin c 2 b3 = skinOps.GetVertexWeightBoneID theSkin c 3 b4 = skinOps.GetVertexWeightBoneID theSkin c 4 b1 -= 1;b2 -= 1;b3 -= 1;b4 -=1 w1 = skinOps.getVertexWeight theSkin c 1 w2 = skinOps.getVertexWeight theSkin c 2 w3 = skinOps.getVertexWeight theSkin c 3 w4 = skinOps.getVertexWeight theSkin c 4 ) ) -- in fact w4 is assumed 1-w1-w2-w3 and not used WriteShort nf vPos.x; WriteShort nf vPos.y; WriteShort nf vPos.z WriteShort nf (w1*32767) WriteByte nf vNorm.x; WriteByte nf vNorm.y; WriteByte nf vNorm.z; WriteByte nf 255 WriteByte nf vTan.x; WriteByte nf vTan.y; WriteByte nf vTan.z; WriteByte nf 254 WriteByte nf b1 WriteByte nf b2 WriteByte nf b3 WriteByte nf b4 WriteShort nf (FShort uvw.x) WriteShort nf (FShort uvw.y) WriteShort nf (FShort w2) WriteShort nf (FShort w3) WriteLong nf 0 WriteShort nf (FShort uvw.x) WriteShort nf (FShort uvw.y) WriteLong nf 0 --for t=1 to 3 do WriteLong nf 0 --pidding )
--64 (bit.hexasint "0x2F55C03D"): for c=1 to vc do ( vPos = (getVert OutMesh c)*MeshScale vPos = [vPos.x,vPos.z,-vPos.y] vNorm = NormArray[c] vNorm *= 127.0; vNorm += 127 uvw = getTVert OutMesh c uvw.y = 1.0 - uvw.y vTan = Normalize( vPos/uvw.y) vTan *= 127.0; vTan += 127 bc = skinOps.getVertexWeightCount theSkin c
case bc of ( 0: ( b1=0 b2=b1;b3=b1;b4=b1 w1=1.0 w2=0.0;w3=0.0;w4=0.0 ) 1: ( b1 = skinOps.GetVertexWeightBoneID theSkin c 1 b1 -= 1 b2=b1;b3=b1;b4=b1 w1 = skinOps.getVertexWeight theSkin c 1 w2=0.0;w3=0.0;w4=0.0 ) 2: ( b1 = skinOps.GetVertexWeightBoneID theSkin c 1 b2 = skinOps.GetVertexWeightBoneID theSkin c 2 b1 -= 1 b2 -= 1 b3=b1;b4=b1 w1 = skinOps.getVertexWeight theSkin c 1; w2 = skinOps.getVertexWeight theSkin c 2; w3=0.0;w4=0.0 ) 3: ( b1 = skinOps.GetVertexWeightBoneID theSkin c 1 b2 = skinOps.GetVertexWeightBoneID theSkin c 2 b3 = skinOps.GetVertexWeightBoneID theSkin c 3 b1 -= 1 b2 -= 1 b3 -= 1 b4=b1 w1 = skinOps.getVertexWeight theSkin c 1; w2 = skinOps.getVertexWeight theSkin c 2; w3 = skinOps.getVertexWeight theSkin c 3; w4=0.0 ) default: ( -- >= 4 b1 = skinOps.GetVertexWeightBoneID theSkin c 1 b2 = skinOps.GetVertexWeightBoneID theSkin c 2 b3 = skinOps.GetVertexWeightBoneID theSkin c 3 b4 = skinOps.GetVertexWeightBoneID theSkin c 4 b1 -= 1;b2 -= 1;b3 -= 1;b4 -=1 w1 = skinOps.getVertexWeight theSkin c 1 w2 = skinOps.getVertexWeight theSkin c 2 w3 = skinOps.getVertexWeight theSkin c 3 w4 = skinOps.getVertexWeight theSkin c 4 ) ) -- in fact w4 is assumed 1-w1-w2-w3 and not used WriteShort nf vPos.x WriteShort nf vPos.y WriteShort nf vPos.z WriteShort nf (w1*32767) WriteByte nf vNorm.x; WriteByte nf vNorm.y; WriteByte nf vNorm.z; WriteByte nf 255 WriteByte nf vTan.x; WriteByte nf vTan.y; WriteByte nf vTan.z; WriteByte nf 254 WriteByte nf b1 WriteByte nf b2 WriteByte nf b3 WriteByte nf b4 WriteShort nf (FShort uvw.x) WriteShort nf (FShort uvw.y) WriteShort nf (FShort w2) WriteShort nf (FShort w3) --WriteShort nf (FShort w4) -- 0 never used --WriteShort nf 0 for t=1 to 6 do WriteLong nf 0 -- could be binormal or anything else --rgba color coded on 12 bytes ! 3 bytes for each component --r=0xB275F2 --g=0xB275F2 --b=0xB275F2 --a=0 always zero --color rgba 12 byte rgb+a this is a test WriteLong nf -1292733006 WriteLong nf 1974661749 WriteLong nf 242 ) ) ) NewMeshInfo[i][9] = (ftell nf) - ptr_vertex ) --print NewMeshInfo PtrFace = ftell nf --Mesh header fseek nf ptr_Mesh #seek_set local vertStart =0 local faceStart =0 local vmin =0 local vmax =0 local svc = 0 local svptr = 0 for i=1 to MeshCount do ( fseek nf 12 #seek_cur if NewMeshInfo[i][8] == 0 then ( Writelong nf svc NewMeshInfo[i][12] = svc Writelong nf 0 svc += NewMeshInfo[i][4] )else ( vptr = NewMeshInfo[i-1][9] if NewMeshInfo[i][8] == NewMeshInfo[i-1][8] then ( svc += NewMeshInfo[i-1][4] Writelong nf svc NewMeshInfo[i][12] = svc Writelong nf svptr )else ( svc = 0 Writelong nf 0 NewMeshInfo[i][12] = 0 Writelong nf vptr svptr = vptr ) ) fseek nf 4 #seek_cur Writelong nf faceStart faceStart += NewMeshInfo[i][5] fseek nf 12 #seek_cur if NewMeshInfo[i][7] == 0 then ( vmin = 0 Writeshort nf vmin vmax = vmin + NewMeshInfo[i][4] - 1 Writeshort nf vmax vmin += NewMeshInfo[i][4] )else ( Writeshort nf vmin vmax = vmin + NewMeshInfo[i][4] - 1 Writeshort nf vmax vmin += NewMeshInfo[i][4] ) fseek nf 4 #seek_cur ) --Face fseek nf PtrFace #seek_set for i=1 to MeshCount do ( fc = NewMeshInfo[i][5] if NewMeshInfo[i][1] == false then ( for c=1 to fc do ( ReadTemp = readshort f Writeshort nf ReadTemp ) )else ( wfc = NewMeshInfo[i][11]*2 fseek f wfc #seek_cur --print wfc si = NewMeshInfo[i][6] OutMesh = SelectMeshInfo[si][1] fvc = fc/3 --print fvc for c=1 to fvc do ( fv = getFace OutMesh c --Writeshort nf (fv.x - 1 + NewMeshInfo[i][4]/4) --Writeshort nf (fv.y - 1 + NewMeshInfo[i][4]/4) --Writeshort nf (fv.z - 1 + NewMeshInfo[i][4]/4) Writeshort nf (fv.x - 1 + NewMeshInfo[i][12]) Writeshort nf (fv.y - 1 + NewMeshInfo[i][12]) Writeshort nf (fv.z - 1 + NewMeshInfo[i][12]) ) -- print NewMeshInfo[i][4] ) )
EndSize = ftell nf if EndSize > int(EndSize/4)*4 then ( Writeshort nf 0 EndSize += 2 ) Writelong nf 0
local avc =0 local afc =0 local avs =0 for i=1 to MeshCount do ( avc += NewMeshInfo[i][4] afc += NewMeshInfo[i][5] avs += NewMeshInfo[i][4]*NewMeshInfo[i][3] ) fseek nf 12 #seek_set Writelong nf avc --vertex count Writelong nf afc --face count fseek nf 24 #seek_set Writelong nf avs --size of all vertex fseek nf 56 #seek_set Writelong nf PtrFace Writelong nf EndSize fclose nf
)
try(destroydialog ReHDModTool)catch() rollout ReHDModTool "RE HD Mod Script v0.11" ( editText edt1 "" pos:[25,10] width:200 height:18 button ImportButton "ImportMod" pos:[36,40] width:180 height:25 button ExportButton "ExportToMod" pos:[36,75] width:180 height:25 groupBox grp1 "Mesh Rename" pos:[10,110] width:230 height:180 label lbl1 "Value" pos:[20,130] width:30 height:18 editText edt4 "" pos:[55,130] width:170 height:18 radioButtons rdo2 "Replace" pos:[90,160] width:80 height:80 columns:1 labels:#("LOD", "MAT", "Group", "Display") button RenameButton "Rename Selected" pos:[36,250] width:180 height:25
on ImportButton pressed do ( clearlistener() fsource = GetOpenFileName \ caption:"Select *.mod File" \ types: "RE HD Remastered Model(*.mod)|*.mod|All files (*.*)|*.*|"
if fsource != undefined then ( edt1.text = (filenameFromPath fsource) f = fopen fsource "rb" if f != undefined then ( doImport f fclose f ) ) ) on ExportButton pressed do ( clearlistener() fsource = GetOpenFileName \ caption:"Select *.mod File" \ types: "RE HD Remastered Model(*.mod)|*.mod|All files (*.*)|*.*|"
if fsource != undefined and selection.count!=0 then ( f = fopen fsource "rb" if f != undefined then ( doExport f fsource fclose f messageBox ("Export Complete to :\n\n" + fsource +".NewMOD") as string ) ) else ( if selection.count == 0 do (messagebox "ACTION ABORTED\n\nSelect a mesh first!") ) ) on RenameButton pressed do ( if edt4.text!=undefined AND edt4.text!="" do ( for i = 1 to selection.count do ( sName = filterString selection[i].name "_" if sName[1]=="Mesh" do ( --SelectMeshInfo[i] = #(selection[i],sName[2],sName[3],i) --#(Mesh, MeshIndex, VertexType) mshHdr_matid = mshHdr_grp = mshHdr_mde = mshHdr_lod = 0 if sName.count == 7 do ( mshHdr_matid = execute ((filterString sName[5] ":")[2]) mshHdr_grp = execute ((filterString sName[6] ":")[2]) mshHdr_mde = execute ((filterString sName[7] ":")[2]) mshHdr_lod = execute ((filterString sName[4] "x")[2]) ) case rdo2.state of ( 1:(mshHdr_lod = execute edt4.text) 2:(mshHdr_matid = execute edt4.text) 3:(mshHdr_grp = execute edt4.text) 4:(mshHdr_mde = execute edt4.text)
) selection[i].name = "Mesh_"+ sName[2] +"_"+ sName[3] +"_LODx"+ mshHdr_lod as string + "_MatID:" + mshHdr_matid as string + "_Group:" + mshHdr_grp as string + "_DisplayMode:" + mshHdr_mde as string
) ) messagebox "Done." ) ) )-- rollout end createDialog ReHDModTool width:250 height:300
I fixed missing weight issues, some code rearragement, test routines etc etc etc.. Export routines are nearly same and nearly not changed. (except some dummy value changes etc..) I will not work anymore so have fun~. Editing or fixing free.. All yours. I need more case related info to do more and it seems not happen soon. -- I fixed using spoiler. Click spoiler to see the code.
|
|