Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- """
- Megaman Legends 2 Noesis Addon
- Copyright 2017, 2018 Satoh
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- """
- #MML2 PC DAT models.
- #step one: load an extracted X01 file
- #step two: discover and load X01s inside a DAT
- #step three: discover and load texture and palette data inside a DAT
- #step four: apply textures to loaded models
- #Current Step: One
- from inc_noesis import *
- import noesis
- #rapi methods should only be used during handler callbacks
- import rapi
- #registerNoesisTypes is called by Noesis to allow the script to register formats.
- #Do not implement this function in script files unless you want them to be dedicated format modules!
- def registerNoesisTypes():
- handle = noesis.register("MML2PC Dat(X1C)", ".x01")
- noesis.setHandlerTypeCheck(handle, mml2CheckType)
- noesis.setHandlerLoadModel(handle, mml2LoadModel)
- #noesis.logPopup()
- #print("The log can be useful for catching debug prints from preview loads.\nBut don't leave it on when you release your script, or it will probably annoy people.")
- return 1
- #check if it's this type based on the data
- def mml2CheckType(data):
- #bs = NoeBitStream(data)
- # if len(data) < 16:
- # return 0
- # if bs.readUInt()&0xFF < 1:
- # return 0
- #print("check pass")
- return 1
- #load the model
- def mml2LoadModel(data, mdlList):
- ctx = rapi.rpgCreateContext()
- bs = NoeBitStream(data)
- x01start = bs.tell()
- #ofs(bs,"Start")
- mdl = checkType0(bs, x01start)
- if(mdl!=None):
- mdlList.append(mdl)
- rapi.rpgReset()
- loadx01(bs, x01start, mdlList)
- return 1
- def checkType0(bs, x01start):
- checkOfs = bs.readUShort()
- checkType = bs.readUShort()
- mdl = None
- x40 = 0
- while(checkType > 0xFF):
- here = bs.tell()-4
- #p("here",hex(here))
- if (checkType == 0x4000):
- tcnt = bs.readUByte()
- qcnt = bs.readUByte()
- vcnt = bs.readUByte()
- scale = bs.readUByte()
- tloc = bs.readUInt()
- qloc = bs.readUInt()
- vloc = bs.readUInt()
- tcol = bs.readUInt()
- qcol = bs.readUInt()
- rapi.rpgSetName("Model_40_Mesh_"+str(hex(x40)))
- rapi.rpgSetPosScaleBias(NoeVec3((1.0*(2 ** scale)/256, 1.0*(2 ** scale)/256, 1.0*(2 ** scale)/256)),
- NoeVec3((0, 0, 0 )) )
- #seek for the vertices
- #p(hex(x01start + hi_hdr[part][VERTOFS]))
- bs.seek(x01start + vloc,NOESEEK_ABS)
- #ofs(bs,"v",part, mdlidx)
- vtx = []
- for v in range(0,vcnt):
- x,y,z = decode10bit(bs.read("I")[0])
- vtx.append(x)#+boneposlist[bonecompat[part]][0])
- vtx.append(y)#+boneposlist[bonecompat[part]][1])
- vtx.append(z)#+boneposlist[bonecompat[part]][2])
- #p(vtx)
- #p(mdlidx, part, vtx)
- cols = []
- bs.seek(tcol,NOESEEK_ABS)
- for v in range(0,vcnt):
- cols.append(bs.readUInt())
- colofs = bs.tell()
- #p(len(cols),hi_hdr[part][VERTCNT])
- newverts = []
- newtris = []
- newuvs = []
- newcols = []
- uvs = []
- tris = []
- for uv in range(0,vcnt):
- uvs.append(0)
- #seek to Solo
- #uv2 = []
- bid = []
- bs.seek(x01start + tloc,NOESEEK_ABS)
- #ofs(bs,"t",part, mdlidx)
- for tri in range(0,tcnt):
- uv2 = []
- uv2.append(bs.readUShort())
- uv2.append(bs.readUShort())
- uv2.append(bs.readUShort())
- bs.readBytes(2)
- #the order is 1 3 2, 4 2 3
- a,b,c,d = decodefaces(bs.readUInt())
- tris.append(a)
- tris.append(b)
- tris.append(c)
- uvs[a] = uv2[0]
- uvs[b] = uv2[1]
- uvs[c] = uv2[2]
- newverts.append(vtx[a*3+0])
- newverts.append(vtx[a*3+1])
- newverts.append(vtx[a*3+2])
- newverts.append(vtx[b*3+0])
- newverts.append(vtx[b*3+1])
- newverts.append(vtx[b*3+2])
- newverts.append(vtx[c*3+0])
- newverts.append(vtx[c*3+1])
- newverts.append(vtx[c*3+2])
- newcols.append(cols[a])
- newcols.append(cols[b])
- newcols.append(cols[c])
- newtris.append(tri*3+0)
- newtris.append(tri*3+2)
- newtris.append(tri*3+1)
- newuvs.append(uv2[0])
- newuvs.append(uv2[1])
- newuvs.append(uv2[2])
- #seek to dual
- bs.seek(x01start + qloc,NOESEEK_ABS)
- #ofs(bs,"q",part, mdlidx)
- for quad in range(0,qcnt):
- uv2 = []
- uv2.append(bs.readUShort())
- uv2.append(bs.readUShort())
- uv2.append(bs.readUShort())
- uv2.append(bs.readUShort())
- #the order is 1 3 2, 4 2 3
- a,b,c,d = decodefaces(bs.readUInt())
- tris.append(a)
- tris.append(c)
- tris.append(b)
- tris.append(d)
- tris.append(b)
- tris.append(c)
- uvs[a] = uv2[0]
- uvs[b] = uv2[1]
- uvs[c] = uv2[2]
- uvs[d] = uv2[3]
- newverts.append(vtx[a*3+0])
- newverts.append(vtx[a*3+1])
- newverts.append(vtx[a*3+2])
- newverts.append(vtx[b*3+0])
- newverts.append(vtx[b*3+1])
- newverts.append(vtx[b*3+2])
- newverts.append(vtx[c*3+0])
- newverts.append(vtx[c*3+1])
- newverts.append(vtx[c*3+2])
- newverts.append(vtx[d*3+0])
- newverts.append(vtx[d*3+1])
- newverts.append(vtx[d*3+2])
- newcols.append(cols[a])
- newcols.append(cols[b])
- newcols.append(cols[c])
- newcols.append(cols[d])
- newtris.append(quad*4+0+(tcnt*3))
- newtris.append(quad*4+2+(tcnt*3))
- newtris.append(quad*4+1+(tcnt*3))
- newtris.append(quad*4+3+(tcnt*3))
- newtris.append(quad*4+1+(tcnt*3))
- newtris.append(quad*4+2+(tcnt*3))
- newuvs.append(uv2[0])
- newuvs.append(uv2[1])
- newuvs.append(uv2[2])
- newuvs.append(uv2[3])
- #for u in range(0,len(uvs)):
- # print(u,(uvs[u]&0xFF)/256,(uvs[u]>>8&0xFF)/256)
- #verts = struct.pack("f"*len(vtx),*vtx)
- #uvbuffer = struct.pack("H"*len(uvs),*uvs)
- #tribuffer = struct.pack("H"*len(tris),*tris)
- #bwt = []
- #print(len(newcols)==(len(newverts)//3))
- #beginmerge = []
- #endmerge = []
- #for v in range(0,len(newverts)//3):
- # if(newcols[v] >> 30 & 0x01 == 0x01):
- #endmerge.append([v,newcols[v] >> 24 & 0x03])
- # bid.append(boneparent[part])
- # else:
- # bid.append(part)
- # bwt.append(1.0)
- #p(len(newcols),len(bid),len(newverts)//3)
- #for v in range(0,len(bid)):
- #this is complicated. vertices belong to the parent bone when...
- #their corresponding vertex color's alpha byte is greater than 00...
- #and there may be some flags at play that determine exactly how...
- #the game merges these vertices.
- #so, we have to modify the existing bone weights and potentially positions
- #so far, best I can tell, 0x80 is a flag for which vert to merge to, and...
- # flag 0xC0 is for which vertex to merge from.
- # However, I have seen 0xD0 and 0xE0, meaning there could be a 6 bit
- # integer after the initial two bit flag
- # if(newcols[v] > 0xFFFFFF):
- # bid[v] = boneparent[part]
- #idxData = struct.pack("i"*len(bid),*bid)
- #valData = struct.pack("f"*len(bwt),*bwt)
- #rapi.rpgBindBoneIndexBuffer(idxData, noesis.RPGEODATA_INT, 4, 1)
- #rapi.rpgBindBoneWeightBuffer(valData, noesis.RPGEODATA_FLOAT, 4, 1)
- colbuffer = struct.pack("I"*len(newcols),*newcols)
- verts = struct.pack("f"*len(newverts),*newverts)
- uvbuffer = struct.pack("H"*len(newuvs),*newuvs)
- tribuffer = struct.pack("H"*len(newtris),*newtris)
- #p(len(newcols),len(newverts))
- #print(len(list(uvbuffer)))
- rapi.rpgBindPositionBuffer(verts, noesis.RPGEODATA_FLOAT, 12)
- rapi.rpgBindUV1Buffer(uvbuffer, noesis.RPGEODATA_UBYTE, 2)
- #rapi.rpgBindColorBuffer(colbuffer, noesis.RPGEODATA_UBYTE, 4, 3)
- rapi.rpgCommitTriangles(tribuffer, noesis.RPGEODATA_USHORT, len(tris), noesis.RPGEO_TRIANGLE, 1)
- #rapi.rpgCommitTriangles(None, noesis.RPGEODATA_USHORT, len(vtx)//3, noesis.RPGEO_POINTS, 1)
- #rapi.rpgOptimize()
- x40 += 1
- mdl = rapi.rpgConstructModel()
- #bonelist = rapi.multiplyBones(bonelist)
- #mdl.setBones(bonelist)
- bs.seek(here,NOESEEK_ABS)
- #ofs(bs)
- bs.seek(checkOfs,NOESEEK_REL)
- #ofs(bs)
- checkOfs = bs.readUShort()
- checkType = bs.readUShort()
- #if(checkOfs % 4 != 0):
- # p("error in offset reading")
- # break
- bs.seek(-4,NOESEEK_REL)
- return mdl
- def loadx1c(bs, mdlidx, x01start, offset):
- #info for our x1c headers
- #Sections
- HI = 0 #High Res
- MED = 1 #Medium Res
- LO = 2 #Low Res
- BONEPOS = 3 #Bone positioning list
- BONEPNT = 4 #Bone parent list
- MAT = 5 #Material texture and palette info
- HILT = 7 #Vertex color/lighting for High
- MEDLT = 8 #Vertex color/lighting for Medium
- LOLT = 9 #Vertex color/lighting for Low
- ############################################
- #info for HI headers
- SOLOCNT = 0 #Tri count
- DUALCNT = 1 #Quad count
- VERTCNT = 2 #this is definitely the vertex count.
- SCALE = 3 #Scale factor as a power of two
- SOLOOFS = 4 #offset for solo
- DUALOFS = 5 #offset for dual
- VERTOFS = 6 #offset for verts
- ############################################
- #go to the beginning of this model
- bs.seek(x01start+offset, NOESEEK_ABS)
- #ofs(bs)
- #Read the parts count for each LOD
- #Note that parts are separate meshes that belong to the same model
- #This can also be understood as a bone count, since there is one part per bone
- hicnt = bs.readUByte()
- medcnt = bs.readUByte()
- lowcnt = bs.readUByte()
- #I THINK this is the texture count.
- texcnt = bs.readUByte()
- x1c_hdr = []
- hi_hdr = []
- bonepart = []
- boneparent = []
- bonecompat = []
- boneflags = []
- PARTID = 0 #The bone ID
- PARENT = 1 #The Parent's ID
- COMPAT = 2 #The ID of the bone this is an alternate of, used for held items for turning on and off.
- #and the last one is ?? Some kind of flag I'm sure. Might be scale
- boneposlist = []
- bonelist = []
- for h in range(0,10):
- x1c_hdr.append(bs.readUInt())
- bs.seek(x01start+x1c_hdr[HI])
- for hdr in range(0,hicnt):
- hi_hdr.append([bs.readUByte(),bs.readUByte(),
- bs.readUByte(),bs.readUByte(),
- bs.readUInt(),bs.readUInt(),
- bs.readUInt()])
- colofs = x01start+x1c_hdr[HILT]
- #p(colofs)
- #read parent infos
- bs.seek(x01start + x1c_hdr[BONEPNT],NOESEEK_ABS)
- for part in range(0,hicnt):
- #p(hex(hi_hdr[part][VERTCNT]))
- bonepart.append(bs.readByte())
- boneparent.append(bs.readByte())
- bonecompat.append(bs.readByte())
- boneflags.append(bs.readByte())
- #p(bonepart)
- #read pos modifiers
- bs.seek(x01start + x1c_hdr[BONEPOS],NOESEEK_ABS)
- for part in range(0,hicnt):
- boneposlist.append([bs.readShort(),-bs.readShort(),-bs.readShort()])
- for part in range(0,hicnt):
- #p(hex(hi_hdr[part][VERTCNT]))
- pp = part#bonepart.index(part)
- b = NoeBone(part,"Bone_"+str(part),
- NoeMat43(( NoeVec3((1.0, 0.0, 0.0)),
- NoeVec3((0.0, 1.0, 0.0)),
- NoeVec3((0.0, 0.0, 1.0)),
- NoeVec3((0.0, 0.0, 0.0 )) ) ))
- if(boneparent[pp] == max(boneparent)):
- b.parentIndex = 0
- else:
- b.parentIndex = boneparent[pp]
- b.setMatrix(NoeMat43(( NoeVec3((1.0, 0.0, 0.0)),
- NoeVec3((0.0, 1.0, 0.0)),
- NoeVec3((0.0, 0.0, 1.0)),
- NoeVec3((boneposlist[bonecompat[part]][0]/256,
- boneposlist[bonecompat[part]][1]/256,
- boneposlist[bonecompat[part]][2]/256 )) ) ))
- if(bonecompat[part] != part):
- b.parentIndex = bonecompat[part]
- b.setMatrix(NoeMat43(( NoeVec3((1.0, 0.0, 0.0)),
- NoeVec3((0.0, 1.0, 0.0)),
- NoeVec3((0.0, 0.0, 1.0)),
- NoeVec3((0, 0, 0 )) ) ))
- bonelist.append(b)
- rapi.rpgSetName("Model_"+str(mdlidx)+"_Mesh_"+str(hex(part)))
- xm = boneposlist[bonecompat[part]][0]/256
- ym = boneposlist[bonecompat[part]][1]/256
- zm = boneposlist[bonecompat[part]][2]/256
- while(boneparent[pp] != max(boneparent)):
- pp = boneparent[pp]
- xm += boneposlist[bonecompat[pp]][0]/256
- ym += boneposlist[bonecompat[pp]][1]/256
- zm += boneposlist[bonecompat[pp]][2]/256
- #rapi.rpgSetPosScaleBias(NoeVec3((1.0, 1.0, 1.0)),
- # NoeVec3((boneposlist[bonecompat[part]][0],
- # boneposlist[bonecompat[part]][1],
- # boneposlist[bonecompat[part]][2] )) )
- rapi.rpgSetPosScaleBias(NoeVec3((1.0*(2 ** hi_hdr[part][SCALE])/256, 1.0*(2 ** hi_hdr[part][SCALE])/256, 1.0*(2 ** hi_hdr[part][SCALE])/256)),
- NoeVec3((xm, ym, zm )) )
- #seek for the vertices
- #p(hex(x01start + hi_hdr[part][VERTOFS]))
- bs.seek(x01start + hi_hdr[part][VERTOFS],NOESEEK_ABS)
- #ofs(bs,"v",part, mdlidx)
- vtx = []
- for v in range(0,hi_hdr[part][VERTCNT]):
- x,y,z = decode10bit(bs.read("I")[0])
- vtx.append(x)#+boneposlist[bonecompat[part]][0])
- vtx.append(y)#+boneposlist[bonecompat[part]][1])
- vtx.append(z)#+boneposlist[bonecompat[part]][2])
- #p(vtx)
- #p(mdlidx, part, vtx)
- cols = []
- bs.seek(colofs,NOESEEK_ABS)
- for v in range(0,hi_hdr[part][VERTCNT]):
- cols.append(bs.readUInt())
- colofs = bs.tell()
- #p(len(cols),hi_hdr[part][VERTCNT])
- newverts = []
- newtris = []
- newuvs = []
- newcols = []
- uvs = []
- tris = []
- for uv in range(0,hi_hdr[part][VERTCNT]):
- uvs.append(0)
- #seek to Solo
- #uv2 = []
- bid = []
- bs.seek(x01start + hi_hdr[part][SOLOOFS],NOESEEK_ABS)
- #ofs(bs,"t",part, mdlidx)
- for tri in range(0,hi_hdr[part][SOLOCNT]):
- uv2 = []
- uv2.append(bs.readUShort())
- uv2.append(bs.readUShort())
- uv2.append(bs.readUShort())
- bs.readBytes(2)
- #the order is 1 3 2, 4 2 3
- a,b,c,d = decodefaces(bs.readUInt())
- tris.append(a)
- tris.append(b)
- tris.append(c)
- uvs[a] = uv2[0]
- uvs[b] = uv2[1]
- uvs[c] = uv2[2]
- # vct1 = hi_hdr[part][VERTCNT] - 1
- # vct2 = vct1 - 1
- # vct3 = vct2 - 1
- # vct4 = vct3 - 1
- # if((a == vct1 or a == vct4 or a == vct2 or a == vct3) and
- # boneflags[part] & 0x40 == 0x40 and
- # boneflags[boneparent[bonecompat[part]]] & 0x40 == 0x40):
- # bid.append(boneparent[part])
- # else:
- # bid.append(part)
- # if((b == vct4 or b == vct1 or b == vct2 or b == vct3) and
- # boneflags[part] & 0x40 == 0x40 and
- # boneflags[boneparent[bonecompat[part]]] & 0x40 == 0x40):
- # bid.append(boneparent[part])
- # else:
- # bid.append(part)
- # if((c == vct4 or c == vct1 or c == vct2 or c == vct3) and
- # boneflags[part] & 0x40 == 0x40 and
- # boneflags[boneparent[bonecompat[part]]] & 0x40 == 0x40):
- # bid.append(boneparent[part])
- # else:
- # bid.append(part)
- #print ((uv2[0]&0xFF)/256,(uv2[0]>>8&0xFF)/256)
- #print ((uv2[1]&0xFF)/256,(uv2[1]>>8&0xFF)/256)
- #print ((uv2[2]&0xFF)/256,(uv2[2]>>8&0xFF)/256)
- newverts.append(vtx[a*3+0])
- newverts.append(vtx[a*3+1])
- newverts.append(vtx[a*3+2])
- newverts.append(vtx[b*3+0])
- newverts.append(vtx[b*3+1])
- newverts.append(vtx[b*3+2])
- newverts.append(vtx[c*3+0])
- newverts.append(vtx[c*3+1])
- newverts.append(vtx[c*3+2])
- newcols.append(cols[a])
- newcols.append(cols[b])
- newcols.append(cols[c])
- # newcols.append(cols[b])
- # newcols.append(cols[b])
- # newcols.append(cols[b])
- # newcols.append(cols[c])
- # newcols.append(cols[c])
- # newcols.append(cols[c])
- newtris.append(tri*3+0)
- newtris.append(tri*3+2)
- newtris.append(tri*3+1)
- newuvs.append(uv2[0])
- newuvs.append(uv2[1])
- newuvs.append(uv2[2])
- #seek to dual
- bs.seek(x01start + hi_hdr[part][DUALOFS],NOESEEK_ABS)
- #ofs(bs,"q",part, mdlidx)
- for quad in range(0,hi_hdr[part][DUALCNT]):
- uv2 = []
- uv2.append(bs.readUShort())
- uv2.append(bs.readUShort())
- uv2.append(bs.readUShort())
- uv2.append(bs.readUShort())
- #the order is 1 3 2, 4 2 3
- a,b,c,d = decodefaces(bs.readUInt())
- tris.append(a)
- tris.append(c)
- tris.append(b)
- tris.append(d)
- tris.append(b)
- tris.append(c)
- uvs[a] = uv2[0]
- uvs[b] = uv2[1]
- uvs[c] = uv2[2]
- uvs[d] = uv2[3]
- # vct1 = hi_hdr[part][VERTCNT] - 1
- # vct2 = vct1 - 1
- # vct3 = vct2 - 1
- # vct4 = vct3 - 1
- # if((a == vct1 or a == vct4 or a == vct2 or a == vct3) and
- # boneflags[part] & 0x40 == 0x40 and
- # boneflags[boneparent[bonecompat[part]]] & 0x40 == 0x40):
- # bid.append(boneparent[part])
- # else:
- # bid.append(part)
- # if((b == vct4 or b == vct1 or b == vct2 or b == vct3) and
- # boneflags[part] & 0x40 == 0x40 and
- # boneflags[boneparent[bonecompat[part]]] & 0x40 == 0x40):
- # bid.append(boneparent[part])
- # else:
- # bid.append(part)
- # if((c == vct4 or c == vct1 or c == vct2 or c == vct3) and
- # boneflags[part] & 0x40 == 0x40 and
- # boneflags[boneparent[bonecompat[part]]] & 0x40 == 0x40):
- # bid.append(boneparent[part])
- # else:
- # bid.append(part)
- # if((d == vct4 or d == vct1 or d == vct2 or d == vct3) and
- # boneflags[part] & 0x40 == 0x40 and
- # boneflags[boneparent[bonecompat[part]]] & 0x40 == 0x40):
- # bid.append(boneparent[part])
- # else:
- # bid.append(part)
- #print ((uv2[0]&0xFF)/256,(uv2[0]>>8&0xFF)/256)
- #print ((uv2[1]&0xFF)/256,(uv2[1]>>8&0xFF)/256)
- #print ((uv2[2]&0xFF)/256,(uv2[2]>>8&0xFF)/256)
- #print ((uv2[3]&0xFF)/256,(uv2[3]>>8&0xFF)/256)
- newverts.append(vtx[a*3+0])
- newverts.append(vtx[a*3+1])
- newverts.append(vtx[a*3+2])
- newverts.append(vtx[b*3+0])
- newverts.append(vtx[b*3+1])
- newverts.append(vtx[b*3+2])
- newverts.append(vtx[c*3+0])
- newverts.append(vtx[c*3+1])
- newverts.append(vtx[c*3+2])
- newverts.append(vtx[d*3+0])
- newverts.append(vtx[d*3+1])
- newverts.append(vtx[d*3+2])
- newcols.append(cols[a])
- newcols.append(cols[b])
- newcols.append(cols[c])
- newcols.append(cols[d])
- # newcols.append(cols[a])
- # newcols.append(cols[b])
- # newcols.append(cols[c])
- # newcols.append(cols[d])
- # newcols.append(cols[a])
- # newcols.append(cols[b])
- # newcols.append(cols[c])
- # newcols.append(cols[d])
- newtris.append(quad*4+0+(hi_hdr[part][SOLOCNT]*3))
- newtris.append(quad*4+2+(hi_hdr[part][SOLOCNT]*3))
- newtris.append(quad*4+1+(hi_hdr[part][SOLOCNT]*3))
- newtris.append(quad*4+3+(hi_hdr[part][SOLOCNT]*3))
- newtris.append(quad*4+1+(hi_hdr[part][SOLOCNT]*3))
- newtris.append(quad*4+2+(hi_hdr[part][SOLOCNT]*3))
- newuvs.append(uv2[0])
- newuvs.append(uv2[1])
- newuvs.append(uv2[2])
- newuvs.append(uv2[3])
- #for u in range(0,len(uvs)):
- # print(u,(uvs[u]&0xFF)/256,(uvs[u]>>8&0xFF)/256)
- #verts = struct.pack("f"*len(vtx),*vtx)
- #uvbuffer = struct.pack("H"*len(uvs),*uvs)
- #tribuffer = struct.pack("H"*len(tris),*tris)
- bwt = []
- #print(len(newcols)==(len(newverts)//3))
- beginmerge = []
- endmerge = []
- for v in range(0,len(newverts)//3):
- if(newcols[v] >> 30 & 0x01 == 0x01):
- #endmerge.append([v,newcols[v] >> 24 & 0x03])
- bid.append(boneparent[part])
- else:
- bid.append(part)
- bwt.append(1.0)
- #p(len(newcols),len(bid),len(newverts)//3)
- #for v in range(0,len(bid)):
- #this is complicated. vertices belong to the parent bone when...
- #their corresponding vertex color's alpha byte is greater than 00...
- #and there may be some flags at play that determine exactly how...
- #the game merges these vertices.
- #so, we have to modify the existing bone weights and potentially positions
- #so far, best I can tell, 0x80 is a flag for which vert to merge to, and...
- # flag 0xC0 is for which vertex to merge from.
- # However, I have seen 0xD0 and 0xE0, meaning there could be a 6 bit
- # integer after the initial two bit flag
- # if(newcols[v] > 0xFFFFFF):
- # bid[v] = boneparent[part]
- idxData = struct.pack("i"*len(bid),*bid)
- valData = struct.pack("f"*len(bwt),*bwt)
- rapi.rpgBindBoneIndexBuffer(idxData, noesis.RPGEODATA_INT, 4, 1)
- rapi.rpgBindBoneWeightBuffer(valData, noesis.RPGEODATA_FLOAT, 4, 1)
- colbuffer = struct.pack("I"*len(newcols),*newcols)
- verts = struct.pack("f"*len(newverts),*newverts)
- uvbuffer = struct.pack("H"*len(newuvs),*newuvs)
- tribuffer = struct.pack("H"*len(newtris),*newtris)
- #p(len(newcols),len(newverts))
- #print(len(list(uvbuffer)))
- rapi.rpgBindPositionBuffer(verts, noesis.RPGEODATA_FLOAT, 12)
- rapi.rpgBindUV1Buffer(uvbuffer, noesis.RPGEODATA_UBYTE, 2)
- rapi.rpgBindColorBuffer(colbuffer, noesis.RPGEODATA_UBYTE, 4, 3)
- rapi.rpgCommitTriangles(tribuffer, noesis.RPGEODATA_USHORT, len(tris), noesis.RPGEO_TRIANGLE, 1)
- #rapi.rpgCommitTriangles(None, noesis.RPGEODATA_USHORT, len(vtx)//3, noesis.RPGEO_POINTS, 1)
- #rapi.rpgOptimize()
- mdl = rapi.rpgConstructModel()
- bonelist = rapi.multiplyBones(bonelist)
- mdl.setBones(bonelist)
- return mdl
- def loadx01(bs, x01start, mdlList):
- UNKSHORT1 = 0
- UNKSHORT2 = 1
- OFFSET = 2 #where in the x01 file
- UNKINT1 = 3
- UNKINT2 = 4
- #I don't know what all of it is yet, but I know which one is the offset.
- x01_hdr = []
- #memorize our X01 start position since each file inside references this, rather than the DAT start
- x01start = bs.tell()
- #ofs(bs,"x01hdr")
- mdlcount = bs.readUInt() #first thing in the x01
- for i in range(0,mdlcount):
- x01_hdr.append([bs.readUShort(),bs.readUShort(),bs.readUInt(),bs.readUInt(),bs.readUInt()])
- for i in range(0, mdlcount):
- mdlList.append(loadx1c(bs, i, x01start , x01_hdr[i][OFFSET]))
- rapi.rpgReset()
- #rapi.rpgClearBufferBinds()
- #def multiplyparts(part,):
- def decode10bit(_uint):
- w = (_uint >> 30 & 0x0003)
- tx = (_uint >> 0 & 0x03FF)
- tz = (_uint >> 10 & 0x03FF)
- ty = (_uint >> 20 & 0x03FF)
- if (tx & 0x200 > 0):
- x = tx ^ 0x3FF * -1
- else:
- x = tx
- if (ty & 0x200 > 0):
- y = ty ^ 0x3FF * -1
- else:
- y = ty
- if (tz & 0x200 > 0):
- z = tz ^ 0x3FF * -1
- else:
- z = tz
- return [x,-z,-y]
- def decodefaces(_uint):
- a = _uint >> 0 & 0x7F
- b = _uint >> 7 & 0x7F
- c = _uint >> 14 & 0x7F
- d = _uint >> 21 & 0x7F
- tex_info = _uint >> 28 &0x0F
- return [a,b,c,d]
- #debugging helper functions
- def p(*args):
- noesis.logPopup()
- print(args)
- def ofs(bs,*args):
- p(hex(bs.tell()),*args)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement