Ejemplo n.º 1
0
 def Textures(self):
     self.data.seek(4,1)
     numShader = self.data.readUInt()
     for i in range( numShader):
         name    = noeStrFromBytes(self.data.readBytes(self.data.readUInt()))
         numTex  = self.data.readUInt()
         material = NoeMaterial(name, "")
         for n in range( numTex):
             typeName    = noeStrFromBytes(self.data.readBytes(self.data.readUInt()))
             typeID      = self.data.readUInt()
             if typeID ==7: #BaseTexture, Bump
                 if MODPATH == None:texName = noeStrFromBytes(self.data.readBytes(self.data.readUInt())).split('\\')[-1]
                 else: texName = noeStrFromBytes(self.data.readBytes(self.data.readUInt()))
                 if typeName == 'baseTexture':
                     tex = LoadTexture(texName, self)
                     if tex != None: material.setTexture(tex.name)
                 elif typeName == 'bumpTexture':
                     tex = LoadTexture(texName, self)
                     if tex != None: material.setNormalTexture(tex.name)
                     
             elif typeID ==8:
                 self.data.read('2f')
             elif typeID ==9: #Color (specular, ..)
                 temp = self.data.read('3f')
                 if typeName == 'specularColor':
                     material.setSpecularColor((temp[0], temp[1], temp[2], 8.0))
                     
             elif typeID ==10: #Power, Effects, ...
                 self.data.read('f')
         self.matList.append(material)
         
     for draw in self.drawCallInfo:
         idxBuff = self.idxBuffer[ draw['faceStart'] * 6 : ]
         numIdx  = draw['faceCount']
         rapi.rpgSetMaterial(self.matList[draw['matID']].name)
         if len(self.boneList) >0:
                 rapi.rpgSetBoneMap( draw['boneMap'])
                 rapi.rpgBindBoneIndexBufferOfs  (self.vertBuff, noesis.RPGEODATA_UBYTE, self.vertLength, self.boneIndexOffset, 4)
                 rapi.rpgBindBoneWeightBufferOfs (self.vertBuff, noesis.RPGEODATA_FLOAT, self.vertLength, self.boneWeightOffset, 4)
         rapi.rpgSetOption(noesis.RPGOPT_TRIWINDBACKWARD, 1)
         rapi.rpgCommitTriangles(idxBuff, noesis.RPGEODATA_USHORT, numIdx*3, noesis.RPGEO_TRIANGLE, 1)
         
     return
Ejemplo n.º 2
0
def noepyLoadModel(data, mdlList):
    bs = NoeBitStream(data)
    if bs.readInt() != NOEPY_HEADER:
        return 0
    if bs.readInt() != NOEPY_VERSION:
        return 0

    #no need to explicitly free the context (created contexts are auto-freed after the handler), but DO NOT hold any references to it outside of this method
    ctx = rapi.rpgCreateContext()

    numMeshes = bs.readInt()
    for i in range(0, numMeshes):
        meshName = bs.readString()
        meshMat = bs.readString()
        numIdx = bs.readInt()
        numPos = bs.readInt()
        numNrm = bs.readInt()
        numUVs = bs.readInt()
        numTan = bs.readInt()
        numClr = bs.readInt()
        numWeights = bs.readInt()
        numBoneRefs = bs.readInt()
        if numBoneRefs > 0:
            boneMap = bs.read("i" * numBoneRefs)
            rapi.rpgSetBoneMap(boneMap)  #set the bone map

        rapi.rpgSetName(meshName)
        rapi.rpgSetMaterial(meshMat)

        triangles = bs.readBytes(numIdx * 4)
        positions = bs.readBytes(numPos * 12)
        normals = bs.readBytes(numPos * 12) if numNrm == numPos else None
        uvs = bs.readBytes(numPos * 12) if numUVs == numPos else None
        tans = bs.readBytes(numPos * 48) if numTan == numPos else None
        colors = bs.readBytes(numPos * 16) if numClr == numPos else None

        rapi.rpgBindPositionBuffer(positions, noesis.RPGEODATA_FLOAT, 12)
        rapi.rpgBindNormalBuffer(normals, noesis.RPGEODATA_FLOAT, 12)
        rapi.rpgBindUV1Buffer(uvs, noesis.RPGEODATA_FLOAT, 12)
        rapi.rpgBindColorBuffer(colors, noesis.RPGEODATA_FLOAT, 16, 4)
        if numWeights > 0:
            vwList = []
            for j in range(0, numWeights):
                vwNum = bs.readInt()
                bidx = []
                bwgt = []
                for k in range(0, vwNum):
                    bidx.append(bs.readInt())
                for k in range(0, vwNum):
                    bwgt.append(bs.readFloat())
                vwList.append(NoeVertWeight(bidx, bwgt))
            fw = NoeFlatWeights(vwList)
            rapi.rpgBindBoneIndexBuffer(fw.flatW[:fw.weightValOfs],
                                        noesis.RPGEODATA_INT,
                                        4 * fw.weightsPerVert,
                                        fw.weightsPerVert)
            rapi.rpgBindBoneWeightBuffer(fw.flatW[fw.weightValOfs:],
                                         noesis.RPGEODATA_FLOAT,
                                         4 * fw.weightsPerVert,
                                         fw.weightsPerVert)
        numMorphFrames = bs.readInt()
        for j in range(0, numMorphFrames):
            numMFPos = bs.readInt()
            numMFNrm = bs.readInt()
            morphPosAr = bs.readBytes(numMFPos * 12)
            rapi.rpgFeedMorphTargetPositions(morphPosAr,
                                             noesis.RPGEODATA_FLOAT, 12)
            if numMFNrm > 0:
                morphNrmAr = bs.readBytes(numMFNrm * 12)
                rapi.rpgFeedMorphTargetNormals(morphNrmAr,
                                               noesis.RPGEODATA_FLOAT, 12)
            rapi.rpgCommitMorphFrame(numMFPos)
        rapi.rpgCommitMorphFrameSet()

        rapi.rpgCommitTriangles(triangles, noesis.RPGEODATA_INT, numIdx,
                                noesis.RPGEO_TRIANGLE, 1)
        rapi.rpgClearBufferBinds(
        )  #reset in case a subsequent mesh doesn't have the same components

    mdl = rapi.rpgConstructModel()

    bones = []
    numBones = bs.readInt()
    for i in range(0, numBones):
        bone = noepyReadBone(bs)
        bones.append(bone)

    anims = []
    numAnims = bs.readInt()
    for i in range(0, numAnims):
        animName = bs.readString()
        numAnimBones = bs.readInt()
        animBones = []
        for j in range(0, numAnimBones):
            animBone = noepyReadBone(bs)
            animBones.append(animBone)
        animNumFrames = bs.readInt()
        animFrameRate = bs.readFloat()
        numFrameMats = bs.readInt()
        animFrameMats = []
        for j in range(0, numFrameMats):
            frameMat = NoeMat43.fromBytes(bs.readBytes(48))
            animFrameMats.append(frameMat)
        anim = NoeAnim(animName, animBones, animNumFrames, animFrameMats,
                       animFrameRate)
        anims.append(anim)

    mdl.setBones(bones)
    mdl.setAnims(anims)
    mdlList.append(
        mdl)  #important, don't forget to put your loaded model in the mdlList
    return 1
Ejemplo n.º 3
0
def noepyLoadModel(data, mdlList):
    LOADANIM = 0
    ExportSkin = 1
    VertexBool = 0  #Vertex Bool = 1 is Vertex Tint Channel Vertex Bool = 0 is Material Layers
    #Remember Vertex Colors are BGRA
    ctx = rapi.rpgCreateContext()
    bs = NoeBitStream(data)
    rapi.rpgSetOption(noesis.RPGOPT_MORPH_RELATIVEPOSITIONS, 1)
    rapi.rpgSetOption(noesis.RPGOPT_MORPH_RELATIVENORMALS, 1)
    #IDSig = bs.readUInt()
    #Blank1 = bs.readUInt()
    #BSphereX = bs.readFloat()
    #BSphereY = bs.readFloat()
    #BSphereZ = bs.readFloat()
    #BSphereThing = bs.readFloat()
    #UNK1 = bs.readFloat()
    #BBoxX1 = bs.readFloat()
    #BBoxY1 = bs.readFloat()
    #BBoxZ1 = bs.readFloat()
    #BBoxX2 = bs.readFloat()
    #BBoxY2 = bs.readFloat()
    #BBoxZ2 = bs.readFloat()
    #BBoxScaleX1 = bs.readFloat()
    #BBoxScaleY1 = bs.readFloat()
    #BBoxScaleZ1 = bs.readFloat()
    #BBoxScaleX2 = bs.readFloat()
    #BBoxScaleY2 = bs.readFloat()
    #BBoxScaleZ2 = bs.readFloat()
    #MipConstantUV0 = bs.readFloat()
    #MipConstantUV1 = bs.readFloat()
    bs.seek(84, NOESEEK_ABS)
    posAli = 0

    #MTRL STUFF
    #MatSig = bs.readUInt()
    MatCount = bs.read("L")
    MatNames = []
    pos = bs.tell()
    print(MatCount, pos)
    #MTRL LOOP
    for i in range(0, MatCount[0]):
        #MatCharCount = bs.readUInt()
        #print(MatCharCount)
        #MatNames.append (bs.readBytes(MatCharCount).decode("ASCII").rstrip("\0"))
        bs.seek(4, NOESEEK_REL)
        MatNames.append(bs.readString())

#STBS LOOP
    print(MatNames)
    subMeshCount = bs.readUInt()
    print(subMeshCount)
    MatID = []
    VertCount = []
    VertBuffType = []
    FaceCount = []
    FaceType = []
    BoneIDS = []
    BIXD = []
    BoneIDLOC = []
    BoneIDS = []

    mdl = []
    VertID = []
    MorphVertPOS = []
    MorphVertNorm = []
    MorphFrameCountID = []
    MDLWritten = rapi.getInputName()
    MDLWrite = NoeBitStream()
    topname = rapi.getExtensionlessName(
        rapi.getExtensionlessName(rapi.getInputName()))
    for i in range(0, subMeshCount):
        BoneIDSPre = []
        print("Sub Mesh", i)
        tsbsSig = bs.readUInt()
        print(tsbsSig)
        MatID.append(bs.readUInt())
        Blank2 = bs.readUInt()
        BVXD = bs.readUInt()
        VertCount.append(bs.readUInt())
        VertBuffType.append(bs.readUShort())
        print(VertBuffType[i])
        MorphFrameCount = bs.readUInt()
        MorphFrameCountID.append(MorphFrameCount)
        if MorphFrameCount is 0:
            print(MorphFrameCount, "Morph Frame Count is 0")

        if MorphFrameCount is not 0:
            print(MorphFrameCount, "Morph Frame Count is not 0")
            n = 0
            MorphVertCountList = []
            FrameLOC = []
            FrameOrder = []
            for m in range(0, MorphFrameCount):
                pos = bs.tell()
                FrameLOC.append(pos)
                MorphVertCount = bs.readUInt()
                MorphVertCountList.append(MorphVertCount)
                #print("MorphVertCount", MorphVertCount)
                #n = 0
                FrameName = ("Frame_" + str(n))
                n = (n + 1)
                Frame = []
                for mv in range(0, MorphVertCount):
                    VertID.append(bs.readUInt())
                    VertX = bs.readUShort()
                    #pos = bs.tell()
                    #VertX = (VertX / 32767)
                    VertY = bs.readUShort()
                    #pos = bs.tell()
                    #VertY = (VertY / 32767)
                    VertZ = bs.readUShort()
                    #pos = bs.tell()
                    #VertZ = (VertZ / 32767)
                    VertNormX = bs.readUShort()
                    VertNormY = bs.readUShort()
                    VertNormZ = bs.readUShort()
                    bs.seek(8, NOESEEK_REL)
                    #pos = bs.tell()
            for mc in range(0, MorphFrameCount):
                FrameOrder.append(bs.readUShort())
            FinalMorphCount = bs.readUShort()
            MorphCharCount = bs.readUInt()
            MorphName = bs.readString()
            print(MorphName)

        if VertBuffType[i] == int(768) or VertBuffType[i] == int(256):
            bs.seek(3, NOESEEK_REL)
        pos = bs.tell()
        BIXD.append(pos)
        BIXDSig = bs.readUInt()
        Blank2 = bs.readUInt()
        FaceCount.append(bs.readUInt())
        FaceType.append(bs.readUInt())
        pos = bs.tell()
        BoneIDLOC.append(pos)
        BoneIDCount = bs.readUByte()
        for bi in range(0, BoneIDCount):
            BoneIDSPre.append(bs.readUByte())
        BoneIDS.append(BoneIDSPre)
        bs.seek(56, NOESEEK_REL)
        if VertBuffType[i] == (1280, ):
            crap = bs.readUShort()
            VertBuffType[i] = (1024, )
    print("MaterialIDS", MatID)
    #RigStuff
    if VertBuffType[0] == int(1024) or VertBuffType[0] == int(768):
        boneReList = RigStuff(VertBuffType, topname)


#MDLSourceStuff
    MeshExists = rapi.checkFileExists(topname + str(".Mesh"))
    if MeshExists:
        MDLFile = rapi.loadIntoByteArray(topname + str(".Mesh"))
    else:
        MDLFile = rapi.loadPairedFile("Brutal Legend", ".Mesh")
    MDL = NoeBitStream(MDLFile)
    MeshStarts = []
    MeshFaceStarts = []
    BONINDBUFF = []

    #print("MeshStarts", MeshStarts, "MeshFaceStarts", MeshFaceStarts)
    print("MDL AT ", MDL.tell())
    for s in range(0, subMeshCount):
        Face = []

        POS, NORM, TAN, UV1, UV2, COL1, COL2, BI, BW = VertStuff(
            MDL, VertCount[s], VertBuffType[s])
        POS = struct.pack('B' * len(POS), *POS)
        NORM = struct.pack('B' * len(NORM), *NORM)
        TAN = struct.pack('B' * len(TAN), *TAN)
        UV1 = struct.pack('B' * len(UV1), *UV1)
        UV2 = struct.pack('B' * len(UV2), *UV2)
        if VertBuffType[s] == int(1024) or VertBuffType[s] == int(512):
            rapi.rpgBindPositionBuffer(POS, noesis.RPGEODATA_HALFFLOAT, 8)
            rapi.rpgBindNormalBuffer(NORM, noesis.RPGEODATA_HALFFLOAT, 8)
            rapi.rpgBindTangentBuffer(TAN, noesis.RPGEODATA_HALFFLOAT, 8)
            rapi.rpgBindUV1Buffer(UV1, noesis.RPGEODATA_HALFFLOAT, 4)
            rapi.rpgBindUV2Buffer(UV2, noesis.RPGEODATA_HALFFLOAT, 4)
        if VertBuffType[s] == int(768) or VertBuffType[s] == int(256):
            rapi.rpgBindPositionBuffer(POS, noesis.RPGEODATA_FLOAT, 12)
            rapi.rpgBindNormalBuffer(NORM, noesis.RPGEODATA_FLOAT, 12)
            #rapi.rpgBindTangentBuffer(TAN, noesis.RPGEODATA_FLOAT, 16)
            rapi.rpgBindUV1Buffer(UV1, noesis.RPGEODATA_FLOAT, 8)
            rapi.rpgBindUV2Buffer(UV2, noesis.RPGEODATA_FLOAT, 8)
        if VertexBool:
            COL = COL2
        else:
            COL = COL1
        COL = struct.pack('B' * len(COL), *COL)
        #VertColor = BGRA
        rapi.rpgBindColorBuffer(COL, noesis.RPGEODATA_UBYTE, 4, 4)
        if VertBuffType[s] == int(1024) or VertBuffType[s] == int(768):
            rapi.rpgSetBoneMap(BoneIDS[s])
            IDS = struct.pack('B' * len(BI), *BI)
            WEIGHTS = struct.pack('B' * len(BW), *BW)
            if ExportSkin:
                print("Bind Skin")
                rapi.rpgBindBoneIndexBuffer(IDS, noesis.RPGEODATA_BYTE, 4, 4)
                rapi.rpgBindBoneWeightBuffer(WEIGHTS, noesis.RPGEODATA_UBYTE,
                                             4, 4)
        FaceBuff = MDL.readBytes(FaceCount[s] * 2)
        # FaceBuff = struct.pack('H'*len(Face), *Face)
        if MorphFrameCountID[s] is not 0:
            ##            RETURN = bs.tell()
            for mf in range(0, MorphFrameCountID[s]):

                bs.seek(FrameLOC[mf], NOESEEK_ABS)
                # print(FrameLOC[mf], FlexNames[FrameOrder[mf]])
                MorphVertCount = bs.readUInt()
                FramePOS = []
                FrameNorm = []
                FrameTan = []
                FrameIDS = []
                MorphPOS = []
                MorphNorm = []
                MorphTan = []
                for mm in range(0, MorphVertCount):
                    FrameIDS.append(bs.readUInt())
                    MPOSX = (((bs.readShort() / 32767) * 2))
                    MPOSY = (((bs.readShort() / 32767) * 2))
                    MPOSZ = (((bs.readShort() / 32767) * 2))
                    MNORMX = (((bs.readShort() / 32767) * 2))
                    MNORMY = (((bs.readShort() / 32767) * 2))
                    MNORMZ = (((bs.readShort() / 32767) * 2))
                    MTANX = (((bs.readShort() / 32767) * 2))
                    MTANY = (((bs.readShort() / 32767) * 2))
                    MTANZ = (((bs.readShort() / 32767) * 2))
                    MTANW = (((bs.readShort() / 32767) * 2))
                    FramePOS.append((float(MPOSX), float(MPOSY), float(MPOSZ)))
                    FrameNorm.append(
                        (float(MNORMX), float(MNORMY), float(MNORMZ)))
                    FrameTan.append((float(MTANX), float(MTANY), float(MTANZ),
                                     float(MTANW)))
                for mv in range(0, VertCount[s]):
                    if mv in FrameIDS:
                        ID = FrameIDS.index(mv)
                        MorphPOS.append(FramePOS[ID])
                        MorphNorm.append(FrameNorm[ID])
                        MorphTan.append(FrameTan[ID])
                    else:
                        MorphPOS.append((float(0.0), float(0.0), float(0.0)))
                        MorphNorm.append((float(0.0), float(0.0), float(0.0)))
                        MorphTan.append(
                            (float(0.0), float(0.0), float(0.0), float(0.0)))
                MPOSBUFF3 = list(itertools.chain.from_iterable(MorphPOS))
                MNORMBUFF = list(itertools.chain.from_iterable(MorphNorm))
                MTANBUFF = list(itertools.chain.from_iterable(MorphTan))
                #rapi.rpgSetName(MeshName)
                MPOS = struct.pack('f' * len(MPOSBUFF3), *MPOSBUFF3)
                MNORM = struct.pack('f' * len(MNORMBUFF), *MNORMBUFF)
                MTAN = struct.pack('f' * len(MTANBUFF), *MTANBUFF)
                rapi.rpgFeedMorphTargetPositions(MPOS, noesis.RPGEODATA_FLOAT,
                                                 12)
                rapi.rpgFeedMorphTargetNormals(MNORM, noesis.RPGEODATA_FLOAT,
                                               12)
                rapi.rpgCommitMorphFrame(VertCount[s])
                MPOSBUFF = []
                MNORMBUFF = []
                MTANBUFF = []
                MPOS = None
                MNORM = None
                MTAN = None
            rapi.rpgCommitMorphFrameSet()
        Mesh = ("Mesh_" + str(s))
        MeshName = str(Mesh)
        rapi.rpgSetName(MeshName)
        print(MatNames[MatID[s]])
        CurrentMaterial = MatNames[MatID[s]]
        CurrentMaterial = CurrentMaterial.replace('/', '_')
        rapi.rpgSetMaterial(CurrentMaterial)
        rapi.rpgSmoothTangents()
        if FaceType[s] == 2:
            rapi.rpgCommitTriangles(FaceBuff, noesis.RPGEODATA_USHORT,
                                    FaceCount[s], noesis.RPGEO_TRIANGLE, 1)
        else:
            rapi.rpgCommitTriangles(FaceBuff, noesis.RPGEODATA_USHORT,
                                    FaceCount[s], noesis.RPGEO_TRIANGLE_STRIP,
                                    1)
        rapi.rpgClearBufferBinds()

    mdl = rapi.rpgConstructModel()

    if LOADANIM == (0):
        print("No Anim")
        if VertBuffType[0] == int(1024) or VertBuffType[0] == int(768):
            mdl.setBones(boneReList)
        mdlList.append(
            mdl
        )  #important, don't forget to put your loaded model in the mdlList

    return 1
def noepyLoadModel(data, mdlList):
	bs = NoeBitStream(data)
	if bs.readInt() != NOEPY_HEADER:
		return 0
	if bs.readInt() != NOEPY_VERSION:
		return 0

	#no need to explicitly free the context (created contexts are auto-freed after the handler), but DO NOT hold any references to it outside of this method
	ctx = rapi.rpgCreateContext()

	numMeshes = bs.readInt()
	for i in range(0, numMeshes):
		meshName = bs.readString()
		meshMat = bs.readString()
		numIdx = bs.readInt()
		numPos = bs.readInt()
		numNrm = bs.readInt()
		numUVs = bs.readInt()
		numTan = bs.readInt()
		numClr = bs.readInt()
		numWeights = bs.readInt()
		numBoneRefs = bs.readInt()
		if numBoneRefs > 0:
			boneMap = bs.read("i"*numBoneRefs)
			rapi.rpgSetBoneMap(boneMap) #set the bone map

		rapi.rpgSetName(meshName)
		rapi.rpgSetMaterial(meshMat)

		triangles = bs.readBytes(numIdx * 4)
		positions = bs.readBytes(numPos * 12)
		normals = bs.readBytes(numPos * 12) if numNrm == numPos else None
		uvs = bs.readBytes(numPos * 12) if numUVs == numPos else None
		tans = bs.readBytes(numPos * 48) if numTan == numPos else None
		colors = bs.readBytes(numPos * 16) if numClr == numPos else None

		rapi.rpgBindPositionBuffer(positions, noesis.RPGEODATA_FLOAT, 12)
		rapi.rpgBindNormalBuffer(normals, noesis.RPGEODATA_FLOAT, 12)
		rapi.rpgBindUV1Buffer(uvs, noesis.RPGEODATA_FLOAT, 12)
		rapi.rpgBindColorBuffer(colors, noesis.RPGEODATA_FLOAT, 16, 4)
		if numWeights > 0:
			vwList = []
			for j in range(0, numWeights):
				vwNum = bs.readInt()
				bidx = []
				bwgt = []
				for k in range(0, vwNum):
					bidx.append(bs.readInt())
				for k in range(0, vwNum):
					bwgt.append(bs.readFloat())
				vwList.append(NoeVertWeight(bidx, bwgt))
			fw = NoeFlatWeights(vwList)
			rapi.rpgBindBoneIndexBuffer(fw.flatW[:fw.weightValOfs], noesis.RPGEODATA_INT, 4*fw.weightsPerVert, fw.weightsPerVert)
			rapi.rpgBindBoneWeightBuffer(fw.flatW[fw.weightValOfs:], noesis.RPGEODATA_FLOAT, 4*fw.weightsPerVert, fw.weightsPerVert)
		numMorphFrames = bs.readInt()
		for j in range(0, numMorphFrames):
			numMFPos = bs.readInt()
			numMFNrm = bs.readInt()
			morphPosAr = bs.readBytes(numMFPos * 12)
			rapi.rpgFeedMorphTargetPositions(morphPosAr, noesis.RPGEODATA_FLOAT, 12)
			if numMFNrm > 0:
				morphNrmAr = bs.readBytes(numMFNrm * 12)
				rapi.rpgFeedMorphTargetNormals(morphNrmAr, noesis.RPGEODATA_FLOAT, 12)
			rapi.rpgCommitMorphFrame(numMFPos)
		rapi.rpgCommitMorphFrameSet()

		rapi.rpgCommitTriangles(triangles, noesis.RPGEODATA_INT, numIdx, noesis.RPGEO_TRIANGLE, 1)
		rapi.rpgClearBufferBinds() #reset in case a subsequent mesh doesn't have the same components

	mdl = rapi.rpgConstructModel()

	bones = []
	numBones = bs.readInt()
	for i in range(0, numBones):
		bone = noepyReadBone(bs)
		bones.append(bone)

	anims = []
	numAnims = bs.readInt()
	for i in range(0, numAnims):
		animName = bs.readString()
		numAnimBones = bs.readInt()
		animBones = []
		for j in range(0, numAnimBones):
			animBone = noepyReadBone(bs)
			animBones.append(animBone)
		animNumFrames = bs.readInt()
		animFrameRate = bs.readFloat()
		numFrameMats = bs.readInt()
		animFrameMats = []
		for j in range(0, numFrameMats):
			frameMat = NoeMat43.fromBytes(bs.readBytes(48))
			animFrameMats.append(frameMat)
		anim = NoeAnim(animName, animBones, animNumFrames, animFrameMats, animFrameRate)
		anims.append(anim)

	mdl.setBones(bones)
	mdl.setAnims(anims)
	mdlList.append(mdl)			#important, don't forget to put your loaded model in the mdlList
	return 1
Ejemplo n.º 5
0
    def __init__(self, data):

        self.meshInfo = []
        self.bufferInfo = []
        self.vertexBuffer = []
        self.indexBuffer = []
        self.matList = []
        self.texList = []
        self.lightMapList = {}

        self.data = NoeBitStream(data)
        self.findMODL()
        self.parseMaterials()

        self.findGEOM()
        self.header = ANetPfChunkHeader(self.data)
        self.numMesh = self.data.readUInt()
        if self.numMesh == 0: print("numMesh = 0, animation file")
        meshInfoOffsetTableOffset = self.data.readUInt()
        self.data.seek(meshInfoOffsetTableOffset - 4, 1)
        meshInfoOffsetTable = self.data.read('%di' % self.numMesh)

        for i in range(self.numMesh):
            self.meshInfo.append(ANetModelMeshInfo(self.data))
        for mesh in self.meshInfo:
            self.data.seek(mesh.pos + mesh.bufferInfoOffset)
            self.bufferInfo.append(ANetModelBufferInfo(self.data))

            self.data.seek(mesh.matpos + mesh.materialNameOffset)
            self.bufferInfo[-1].materialName = self.data.readString()
            self.bufferInfo[-1].materialIndex = mesh.materialIndex
        for buffer in self.bufferInfo:

            Format = self.vertexSize(buffer)
            LOGGING = 0
            if LOGGING == 1:
                print("[*] Mesh")
                for var in vars(Format):
                    val = getattr(Format, var)
                    if val != -1: print("  %s: %d" % (var, val))

            self.data.seek(buffer.vertexPos + buffer.vertexBufferOffset)
            vertexBuffer = self.data.readBytes(buffer.vertexBufferSize)

            self.data.seek(buffer.indexPos + buffer.indexBufferOffset)
            indexBuffer = self.data.readBytes(buffer.indexCount * 2)

            self.data.seek(buffer.boneMapPos + buffer.boneMapOffset)
            boneMap = self.data.read('%di' % buffer.boneMapCount)
            try:
                material = self.matList[buffer.materialIndex]
            except:
                print(buffer.materialIndex)
                raise
            material.name = buffer.materialName
            rapi.rpgSetMaterial(buffer.materialName)
            self.matList[buffer.materialIndex] = material
            if buffer.materialIndex in self.lightMapList:
                material = self.lightMapList[buffer.materialIndex]
                material.name = buffer.materialName + "_LM"
                rapi.rpgSetLightmap(material.name)
                self.matList.append(material)
            if Format.position != -1:
                rapi.rpgBindPositionBufferOfs(vertexBuffer,
                                              noesis.RPGEODATA_FLOAT,
                                              Format.vertexSize,
                                              Format.position)
            if Format.uv32Mask != -1:
                rapi.rpgBindUV1BufferOfs(vertexBuffer, noesis.RPGEODATA_FLOAT,
                                         Format.vertexSize, Format.uv32Mask)
            if Format.uv16Mask != -1:
                rapi.rpgBindUV1BufferOfs(vertexBuffer,
                                         noesis.RPGEODATA_HALFFLOAT,
                                         Format.vertexSize, Format.uv16Mask)
                if Format.uv16Count >= 3:
                    rapi.rpgBindUV2BufferOfs(vertexBuffer,
                                             noesis.RPGEODATA_HALFFLOAT,
                                             Format.vertexSize,
                                             Format.uv16Mask + 8)
            rapi.rpgBindBoneIndexBufferOfs(vertexBuffer,
                                           noesis.RPGEODATA_UBYTE,
                                           Format.vertexSize, Format.group, 4)
            rapi.rpgBindBoneWeightBufferOfs(vertexBuffer,
                                            noesis.RPGEODATA_UBYTE,
                                            Format.vertexSize, Format.weights,
                                            4)
            rapi.rpgSetBoneMap(boneMap)
            rapi.rpgCommitTriangles(indexBuffer, noesis.RPGEODATA_USHORT,
                                    buffer.indexCount, noesis.RPGEO_TRIANGLE,
                                    1)
        self.Bones = []
        self.ParseBones()
Ejemplo n.º 6
0
def noepyLoadFMOD(data, mdlList):
    bs = NoeBitStream(data)
    if bs.readInt() != FMOD_HEADER:
        return 0
    if bs.readInt() != FMOD_VERSION:
        return 0

    pos = 0
    
    filesize = bs.readUInt() # total
    
    typeBlock = bs.readInt()
    countBlock = bs.readInt()
    sizeBlock = bs.readInt()
    processBlock(typeBlock, countBlock, sizeBlock, bs)
    
    while pos < filesize:
        for i in range(countBlock):
            pos = bs.tell()
            if pos < filesize:
                typeBlock = bs.readInt()
                countBlock = bs.readInt()
                sizeBlock = bs.readInt()
                processBlock(typeBlock, countBlock, sizeBlock, bs)

    ctx = rapi.rpgCreateContext()
    global textureOff, textureCount, materialOff, materialCount
    texList, matList = createMaterialTexList(bs,textureOff,textureCount,materialOff,materialCount)
    for meshi in range(objectcount):
        # Add vertices
        bs.seek(vertexoffsets[meshi])
        vertexbuffer = bs.readBytes(vertexcounts[meshi] * 12)
        rapi.rpgBindPositionBufferOfs(vertexbuffer, noesis.RPGEODATA_FLOAT, 12, 0)
        
        # Add normals
        global normalsoffsets
        bs.seek(normalsoffsets[meshi] - 8)
        normalscount = bs.readInt()
        bs.readInt() # skip
        normalsbuffer = bs.readBytes(normalscount * 12)
        rapi.rpgBindNormalBufferOfs(normalsbuffer, noesis.RPGEODATA_FLOAT, 12, 0)
        
        # Add tangents (is it necessary?)
        global tanoffsets
        if len(tanoffsets) > 0:
            bs.seek(tanoffsets[meshi] - 8)
            tangentcount = bs.readInt()
            bs.readInt() #blocksize
            tangentbuffer = bs.readBytes(tangentcount*16)
            rapi.rpgBindTangentBuffer(tangentbuffer, noesis.RPGEODATA_FLOAT, 16)

        # Add UVs
        bs.seek(uvoffsets[meshi] - 8)
        uvcount = bs.readInt()
        bs.readInt() # skip
        uvbuffer = bs.readBytes(uvcount * 8)
        rapi.rpgBindUV1BufferOfs(uvbuffer, noesis.RPGEODATA_FLOAT, 8, 0)

        # Add Vertex Color (possible)
        global coloroffsets
        bs.seek(coloroffsets[meshi] - 8)
        colorcount = bs.readUInt()
        bs.readUInt() #blocksize
        colorbuffer = bs.readBytes(colorcount*16)
        rapi.rpgBindColorBuffer(colorbuffer, noesis.RPGEODATA_FLOAT, 16, 4)

        # Add Bone Remap
        global boneoffsets
        if(len(boneoffsets) > 0):
            bs.seek(boneoffsets[meshi] - 8)
            boneCount = bs.readInt()
            bs.readInt() #blockSize
            bones = list()
            for i in range(boneCount):
                bone = bs.readInt()
                bones.append(bone)
            rapi.rpgSetBoneMap(bones)
        else:
            #there's no bone remap
            dummy = 1+1 #just to please noesis
            
        
        # Add Weights
        global weightoffsets
        if len(weightoffsets) > 0:
            weightValues = bytes()
            weightBones = bytes()
            bs.seek(weightoffsets[meshi] - 8)
            weightcount = bs.readInt()
            bs.readInt() #blocksize
            for i in range(weightcount):
                paircount = bs.readInt()
                for j in range(paircount):
                    weightBone = bs.readUInt()
                    weightValue = bs.readFloat()
                    weightBones += noePack("i", weightBone)
                    weightValues += noePack("f", weightValue/100)
                for k in range(4-paircount):
                    weightBone = 0
                    weightValue = 0.0
                    weightBones += noePack("i", weightBone)
                    weightValues += noePack("f", weightValue)
            rapi.rpgBindBoneIndexBufferOfs(weightBones,noesis.RPGEODATA_UINT, 16, 0, 4)
            rapi.rpgBindBoneWeightBufferOfs(weightValues,noesis.RPGEODATA_FLOAT, 16, 0, 4)
        
        # Add skeleton
        bins = []
        for root, dirnames, filenames in os.walk(noesis.getSelectedDirectory()):
            for filename in fnmatch.filter(filenames, '*.fskl'):
                bins.append(os.path.join(root, filename))
        
        boneList = []
        if len(bins) > 0:
            dataSkl = []
            with open(bins[0], mode='rb') as file:
                dataSkl = file.read()
                bsSkl = NoeBitStream(dataSkl)
                if bsSkl.readUInt() == FSKL_HEADER:
                    # slightly adapted from https://github.com/m2jean/mhfu-ios-pmo-plugin
                    blockCount = bsSkl.readUInt() - 1
                    #print("Skeleton file with {} sections found.".format(blockCount))
                    filesizeSkl = bsSkl.readUInt()
                    
                    blockType = bsSkl.readUInt()
                    blockCount1 = bsSkl.readUInt()
                    blockLen = bsSkl.readUInt()
                    for i in range(blockCount1):
                        dummy = bsSkl.readUInt()
                    
                    
                    
                    sklidxList = []
                    posList = []
                    for i in range(blockCount):
                        blockTyp = bsSkl.readUInt()
                        assert blockTyp == 0x40000001 or 0x40000002
                        assert bsSkl.readUInt() == 0x1
                        assert bsSkl.readUInt() == 0x10C
                        nodei = bsSkl.readInt()
                        parent = bsSkl.readInt()
                        lchild = bsSkl.readInt()
                        rsibling = bsSkl.readInt()

                        bsSkl.readBytes(4*8)
                        mat43 = []
                        for _ in range(3):
                            mat43.append(bsSkl.readFloat())
                        bsSkl.readFloat()
                        bsSkl.readBytes(16*12)

                        if parent == -1:
                            pos = (0,0,0)
                        else:
                            pos = posList[parent].vec3
                            sklidxList += (nodei, parent, parent)
                        
                        transform = list(pos)
                        transform[0] += mat43[0]
                        transform[1] += mat43[1]
                        transform[2] += mat43[2]
                        #print(mat43, transform)
                        posList.append(NoeVec3(transform))
                        
                        finMatrix = NoeQuat().toMat43()
                        finMatrix[3] = NoeVec3(transform)
                        boneList.append(NoeBone(i, "Bone.%03i"%i, finMatrix, None, parent))

        #create material remap and material map
        global materialoffsets, matmapoffsets
        bs.seek(materialoffsets[meshi]-8)
        matRemap = []
        remapCount = bs.readUInt()
        bs.readUInt()
        for _ in range(remapCount):
            matRemap.append(bs.readUInt())

        matMap = []
        bs.seek(matmapoffsets[meshi]-8)
        stripCount = bs.readUInt()
        bs.readUInt()
        for _ in range(stripCount):
            matMap.append(matRemap[bs.readUInt()])


        # Add faces
        bs.seek(faceoffsets[meshi])
        stripIndex = 0
        for j in range(faceblockcounts[meshi]):
            faceblocktype = bs.readInt()
            facesubblockcount = bs.readInt()
            blocksize = bs.readInt()
            
            for i in range(facesubblockcount):
                rapi.rpgSetMaterial("Material.%03i"%matMap[stripIndex])
                facecount = bs.readUInt()
                # not sure what's up with these counts i.e. wf521, em098
                if facecount > 0x80000000:
                    #print("WARNING: Face count is abnormal with {}. Fake adjusted.".format(facecount))
                    facecount = facecount - 0x80000000
                #print("Mesh {} face index {} block count: {} at offset 0x{:X}".format(meshi, i, facecount, bs.tell()))
                facebuffer = bs.readBytes(facecount * 4)
                rapi.rpgCommitTriangles(facebuffer, noesis.RPGEODATA_UINT, facecount, noesis.RPGEO_TRIANGLE_STRIP, 1)
                stripIndex += 1
        
        matRemap = []
        matMap = []
    mdl = rapi.rpgConstructModel()
    mdl.setModelMaterials(NoeModelMaterials(texList, matList))
    mdl.setBones(boneList)
    mdlList.append(mdl)
    rapi.rpgReset()
    
    rapi.rpgClearBufferBinds()
    # reset global variables
    rapi.rpgOptimize()
    global objectcount
    global vertexoffsets; global vertexcounts
    global faceoffsets; global faceblocksubcounts; global faceblockcounts
    global uvoffsets; global tanoffsets
    objectcount = 0
    vertexoffsets = list(); vertexcounts = list()
    faceoffsets = list(); faceblockcounts = list(); faceblocksubcounts = list()
    uvoffsets = list(); normalsoffsets = list(); tanoffsets = list()
    weightoffsets = list(); boneoffsets = list()
    materialoffsets =list(); matmapoffsets = list()
    matoffsets = list(); texoffsets = list()
    coloroffsets = list()
    materialOff = 0
    materialCount = 0
    textureOff = 0
    textureCount = 0
    
    return 1
Ejemplo n.º 7
0
def pso2LoadModel(data, mdlList):
	ctx = rapi.rpgCreateContext()
	bs = NoeBitStream(data)
	Bones = []
	Bone_Pallet = []
	Bone_Matrix = []
	Bone_Name = []
	Bone_Parent = []
	vertSize = []
	vertCount = []
	vtxeOffset = []
	vtxlOffset = []
	psetOffset = []

	boneFileName = rapi.getDirForFilePath(rapi.getInputName()) + rapi.getLocalFileName(rapi.getInputName()).rstrip(".aqo") + ".aqn"
	if (rapi.checkFileExists(boneFileName)):
		boneData = rapi.loadIntoByteArray(boneFileName)
		if boneData is not None:
			bd = NoeBitStream(boneData)
		bd.seek(0xC, NOESEEK_ABS)
		start = bd.readInt()
		bd.seek(start + 0x10, NOESEEK_ABS)
		while not bd.checkEOF():
			chunkStart = bd.tell()
			chunkType = bd.readBytes(4).decode("ASCII")
			chunkSize = bd.readInt()
			subChunkType = bd.readBytes(4).decode("ASCII")
			#print([chunkType,chunkSize,subChunkType])

			for case in switch(subChunkType):
				if case('AQGF'):
					bd.seek(chunkStart + chunkSize, NOESEEK_ABS)
					break
				if case('ROOT'):
					bd.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS)
					break
				if case('NODE'):
					bd.seek(6, NOESEEK_REL)
					while bd.tell() < chunkStart + 8 + chunkSize:
						nodeChunkStart = bd.tell()
						nodeChunkType = bd.readUShort()
						#print([nodeChunkType,nodeChunkStart])
						for case in switch(nodeChunkType):
							if case(0x903):
								nodeTest1 = bd.readInt()
								break
							if case(0x804):
								BoneParent = bd.readInt()
								Bone_Parent.append(BoneParent)
								break
							if case(0x80F):
								nodeTest1 = bd.readInt()
								break
							if case(0x805):
								nodeTest1 = bd.readInt()
								break
							if case(0x806):
								nodeTest1 = bd.readInt()
								break
							if case(0x4A07):
								bd.seek(0xD, NOESEEK_REL)
								break
							if case(0x4A08):
								bd.seek(0xD, NOESEEK_REL)
								break
							if case(0x4A09):
								bd.seek(0xD, NOESEEK_REL)
								break
							if case(0xCA0A):
								bd.seek(0x2, NOESEEK_REL)
								BoneMatrix = NoeMat44.fromBytes(bd.readBytes(64)).toMat43()
								Bone_Matrix.append(BoneMatrix.inverse())
								break
							if case(0x90B):
								nodeTest1 = bd.readInt()
								break
							if case(0x90C):
								nodeTest1 = bd.readInt()
								break
							if case(0x20D):
								nSize = bd.readUByte()
								boneName = bd.readBytes(nSize).decode("ASCII")
								Bone_Name.append(boneName)
								break
							if case(0xFD):
								break
					break
				if case('NODO'):
					bd.seek(bd.getSize(), NOESEEK_ABS)
					break
				if case(): # default, could also just omit condition or 'if True'
					bd.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS)
					# No need to break here, it'll stop anyway
		for a in range(0, len(Bone_Matrix)):
			bn = NoeBone(a, Bone_Name[a], Bone_Matrix[a], None, Bone_Parent[a])
			Bones.append(bn)
	aqoMagic = bs.readInt()
	while not bs.checkEOF():
		chunkStart = bs.tell()
		chunkType = bs.readBytes(4).decode("ASCII")
		chunkSize = bs.readInt()
		subChunkType = bs.readBytes(4).decode("ASCII")
		#print([chunkType,chunkSize,subChunkType])

		for case in switch(subChunkType):
			if case('AQGF'):
				bs.seek(chunkStart + chunkSize, NOESEEK_ABS)
				break
			if case('ROOT'):
				bs.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS)
				break
			if case('OBJC'):
				bs.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS)
				break
			if case('VSET'):
				while bs.tell() < chunkStart + 8 + chunkSize:
					vsetChunkStart = bs.tell()
					vsetChunkType = bs.readUShort()
					#print([vsetChunkStart,vsetChunkType])
					for case in switch(vsetChunkType):
						if case(0x9B6):
							vsetVertSize = bs.readInt()
							vertSize.append(vsetVertSize)
							#print([vsetChunkType,vsetVertSize])
							break
						if case(0x9BF):
							vsetUnk01 = bs.readInt()
							break
						if case(0x9B9):
							vsetVertCount = bs.readInt()
							vertCount.append(vsetVertCount)
							#print([vsetChunkType,vsetVertCount])
							break
						if case(0x9C4):
							vsetUnk01 = bs.readInt()
							break
						if case(0x9BD):
							vsetUnk01 = bs.readInt()
							if vsetUnk01 == 0:
								Bone_Pallet.append(())
							break
						if case(0x86BE):
							test = bs.readByte()
							test = bs.readUByte()
							BonePallet = bs.read("H"*(test + 1))
							Bone_Pallet.append(BonePallet)
							break
						if case(0x6BE):
							test = bs.readByte()
							test = bs.readUByte()
							Bone_Pallet.append(())
							break
						if case(0x9C8):
							vsetUnk01 = bs.readInt()
							break
						if case(0x9CC):
							vsetUnk01 = bs.readInt()
							break
						if case(0x9C9):
							vsetUnk01 = bs.readInt()
							break
						if case(0xFD):
							break

				bs.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS)
				break
			if case('VTXE'):
				vtxeOffset.append([chunkStart,chunkSize])
				bs.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS)
				break
			if case('MESH'):
				bs.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS)
				break
			if case('REND'):
				bs.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS)
				break
			if case('SHAD'):
				bs.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS)
				break
			if case('SHAP'):
				bs.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS)
				break
			if case('TSTA'):
				bs.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS)
				break
			if case('TSET'):
				bs.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS)
				break
			if case('VTXL'):
				vtxlOffset.append([chunkStart,chunkSize])
				bs.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS)
				break
			if case('TEXF'):
				bs.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS)
				break
			if case('PSET'):
				psetOffset.append(chunkStart)
				bs.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS)
				break
			if case(): # default, could also just omit condition or 'if True'
				bs.seek(chunkStart + 8 + chunkSize, NOESEEK_ABS)
				# No need to break here, it'll stop anyway
		
	#bs.readBytes(8).decode("ASCII").rstrip("\0")
	FaceOff = psetOffset[0] + 18
	rapi.rpgSetUVScaleBias(NoeVec3 ((1.0, -1.0, 1.0)), NoeVec3 ((1.0, 1.0, 1.0)))
	for i in range(0, len(vertSize)):
		bs.seek(vtxlOffset[i][0] + 18, NOESEEK_ABS)
		test = bs.readByte()
		if test == 8:
			test = bs.readUByte()
			VertBuff = bs.readBytes(vtxlOffset[i][1] - 12)
		elif test == 24:
			test = bs.readInt()
			VertBuff = bs.readBytes(vtxlOffset[i][1] - 15)
		else:
			test = bs.readUShort()
			VertBuff = bs.readBytes(vtxlOffset[i][1] - 13)
		bs.seek(vtxeOffset[i][0] + 18, NOESEEK_ABS)
		for j in range(0, (vtxeOffset[i][1] - 10) // 26):
			vtxeChunkTypeid = bs.readUShort()
			vtxeChunkType = bs.readInt()
			vtxeChunkType2id = bs.readUShort()
			vtxeChunkType2 = bs.readInt()
			vtxeChunkPosId = bs.readUShort()
			vtxeChunkPos = bs.readInt()
			vtxeChunkUnkid = bs.readUShort()
			vtxeChunkUnk = bs.readInt()
			vtxeChunkTerm = bs.readUShort()
			if vtxeChunkType == 0:
				rapi.rpgBindPositionBufferOfs(VertBuff, noesis.RPGEODATA_FLOAT, vertSize[i], vtxeChunkPos)
			elif vtxeChunkType == 1:
				rapi.rpgBindBoneWeightBufferOfs(VertBuff, noesis.RPGEODATA_FLOAT, vertSize[i], vtxeChunkPos, 4)
			elif vtxeChunkType == 2:
				#rapi.rpgBindNormalBufferOfs(VertBuff, noesis.RPGEODATA_FLOAT, vertSize[i], vtxeChunkPos)
				pass
			elif vtxeChunkType == 3:
				rapi.rpgBindColorBufferOfs(VertBuff, noesis.RPGEODATA_UBYTE, vertSize[i], vtxeChunkPos, 4)
			elif vtxeChunkType == 4:
				pass#4 bytes as floats 2nd vertex color?
			elif vtxeChunkType == 11:
				rapi.rpgBindBoneIndexBufferOfs(VertBuff, noesis.RPGEODATA_UBYTE, vertSize[i], vtxeChunkPos, 4)
			elif vtxeChunkType == 16:
				rapi.rpgBindUV1BufferOfs(VertBuff, noesis.RPGEODATA_FLOAT, vertSize[i], vtxeChunkPos)
			elif vtxeChunkType == 17:
				rapi.rpgBindUV2BufferOfs(VertBuff, noesis.RPGEODATA_FLOAT, vertSize[i], vtxeChunkPos)
			elif vtxeChunkType == 32:
				pass#tangents?
			elif vtxeChunkType == 33:
				pass#binormals/tangents?
			else:
				print(vtxeChunkType)
		bs.seek(FaceOff, NOESEEK_ABS)
		bs.seek(0x1A, NOESEEK_REL)
		test = bs.readByte()
		if test == 8:
			FaceCount = bs.readUByte()
			FaceBuff = bs.readBytes((FaceCount + 1) * 2)
		elif test == 16:
			FaceCount = bs.readUShort()
			FaceBuff = bs.readBytes((FaceCount + 1) * 2)
		else:
			FaceCount = bs.readInt()
			FaceBuff = bs.readBytes((FaceCount + 1) * 2)
		bs.seek(0x8, NOESEEK_REL)
		FaceOff = bs.tell()
		rapi.rpgSetName(str(i))
		rapi.rpgSetMaterial(str(i))
		material = NoeMaterial((str(i)), "")
		if len(Bone_Pallet) > 0:
			if len(Bone_Pallet[i]) > 0:
				rapi.rpgSetBoneMap(Bone_Pallet[i])
		
		rapi.rpgCommitTriangles(FaceBuff, noesis.RPGEODATA_USHORT, FaceCount + 1, noesis.RPGEO_TRIANGLE_STRIP, 1)
	mdl = rapi.rpgConstructModel()
	mdl.setBones(Bones)
	mdlList.append(mdl)
	rapi.rpgClearBufferBinds()	
	return 1
    def __init__(self,data):
        
        self.meshInfo     = []
        self.bufferInfo   = []
        self.vertexBuffer = []
        self.indexBuffer  = []
        self.matList      = []
        self.texList      = []
        self.lightMapList = {}
        
        self.data = NoeBitStream(data)
        self.findMODL()
        self.parseMaterials()
        
        self.findGEOM()
        self.header               = ANetPfChunkHeader(self.data)
        self.numMesh              = self.data.readUInt()
        if self.numMesh == 0:print("numMesh = 0, animation file")
        meshInfoOffsetTableOffset = self.data.readUInt()
        self.data.seek(meshInfoOffsetTableOffset-4,1)
        meshInfoOffsetTable       = self.data.read('%di'%self.numMesh)
        
        for i in range(self.numMesh): self.meshInfo.append(ANetModelMeshInfo(self.data))
        for mesh in self.meshInfo:
            self.data.seek(mesh.pos+mesh.bufferInfoOffset)
            self.bufferInfo.append(ANetModelBufferInfo(self.data))

            self.data.seek(mesh.matpos+mesh.materialNameOffset)
            self.bufferInfo[-1].materialName = self.data.readString()
            self.bufferInfo[-1].materialIndex= mesh.materialIndex
        for buffer in self.bufferInfo:
            
            Format = self.vertexSize(buffer)
            LOGGING = 0
            if LOGGING == 1:
                print("[*] Mesh")
                for var in vars(Format):
                    val = getattr(Format,var)
                    if val != -1:print("  %s: %d"%(var,val))

            self.data.seek(buffer.vertexPos + buffer.vertexBufferOffset)
            vertexBuffer = self.data.readBytes(buffer.vertexBufferSize)
            
            self.data.seek(buffer.indexPos + buffer.indexBufferOffset)
            indexBuffer = self.data.readBytes(buffer.indexCount*2)

            self.data.seek(buffer.boneMapPos + buffer.boneMapOffset)
            boneMap = self.data.read('%di'%buffer.boneMapCount)
            try:material = self.matList[buffer.materialIndex]
            except:
                print(buffer.materialIndex)
                raise
            material.name = buffer.materialName
            rapi.rpgSetMaterial(buffer.materialName)
            self.matList[buffer.materialIndex] = material
            if buffer.materialIndex in self.lightMapList:
                material = self.lightMapList[buffer.materialIndex]
                material.name = buffer.materialName + "_LM"
                rapi.rpgSetLightmap(material.name)
                self.matList.append(material)
            if Format.position != -1: rapi.rpgBindPositionBufferOfs(vertexBuffer, noesis.RPGEODATA_FLOAT, Format.vertexSize, Format.position)
            if Format.uv32Mask != -1: rapi.rpgBindUV1BufferOfs(vertexBuffer, noesis.RPGEODATA_FLOAT, Format.vertexSize, Format.uv32Mask)
            if Format.uv16Mask != -1:
                rapi.rpgBindUV1BufferOfs(vertexBuffer, noesis.RPGEODATA_HALFFLOAT, Format.vertexSize, Format.uv16Mask)
                if Format.uv16Count >=3: rapi.rpgBindUV2BufferOfs(vertexBuffer, noesis.RPGEODATA_HALFFLOAT, Format.vertexSize, Format.uv16Mask+8)
            rapi.rpgBindBoneIndexBufferOfs(vertexBuffer, noesis.RPGEODATA_UBYTE, Format.vertexSize ,Format.group, 4)
            rapi.rpgBindBoneWeightBufferOfs(vertexBuffer, noesis.RPGEODATA_UBYTE, Format.vertexSize, Format.weights, 4)
            rapi.rpgSetBoneMap(boneMap)
            rapi.rpgCommitTriangles(indexBuffer, noesis.RPGEODATA_USHORT, buffer.indexCount, noesis.RPGEO_TRIANGLE, 1)
        self.Bones = []
        self.ParseBones()