home *** CD-ROM | disk | FTP | other *** search
Wrap
#Noesis Python model import+export test module, imports/exports some data from/to a made-up format from inc_noesis import * import noesis import struct #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("Persona 4: Dancing All Night", ".gmd") noesis.setHandlerTypeCheck(handle, noepyCheckType) noesis.setHandlerLoadModel(handle, noepyLoadModel) #see also noepyLoadModelRPG handle = noesis.register("Persona 4: Dancing All Night", ".GFS") noesis.setHandlerTypeCheck(handle, noepyCheckType) noesis.setHandlerLoadModel(handle, noepyLoadModel) #noesis.setHandlerWriteModel(handle, noepyWriteModel) #noesis.setHandlerWriteAnim(handle, noepyWriteAnim) ## 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 NOEPY_HEADER = "GFS0" #check if it's this type based on the data def noepyCheckType(data): bs = NoeBitStream(data) if len(data) < 16: return 0 if bs.readBytes(4).decode("ASCII").rstrip("\0") != NOEPY_HEADER: return 0 return 1 #load the model def noepyLoadModel(data, mdlList): ctx = rapi.rpgCreateContext() bs = NoeBitStream(data, 1) sb = NoeBitStream(data) ## bs.setByteEndianForBits(NOE_BIGENDIAN) bs.setEndian(NOE_BIGENDIAN) rapi.rpgSetOption(noesis.RPGOPT_BIGENDIAN, 1) DDSSpitOut = 0 SkipMaterials = 0 Skin = 1 Optimize = 0 EXPMorph = 1 MATDEBUG = 0 MESHDEBUG = 0 EmergencyNameDump = 0 BoneOverride = 0 if BoneOverride: Skin = 0 SkipNodes = 1 else: SkipNodes = 0 BL = None MAGIC = bs.readBytes(4) TOPID = bs.readUInt() TOPTYPE = bs.readUInt() BLANK = bs.readUInt() CHUNKID = bs.readUInt() CHUNKTYPE = bs.readUInt() CHUNKSIZE = ((bs.readUInt()) - 8) BLANK = bs.readUInt() ContentCOUNT = bs.readUInt() DDSNames = [] DDSContent = [] print(bs.tell()) texList = [] texIndex = [] for D in range(0, ContentCOUNT): NameCharCount = bs.readUShort() if MATDEBUG: print("NameCharCount", NameCharCount, bs.tell()) DDSName = bs.readBytes(NameCharCount).decode("ASCII").rstrip("\0") texIndex.append(DDSName) TextureFormat = bs.readUShort() TextureSize = bs.readUInt() if MATDEBUG: print("TextureSize", TextureSize) Return = bs.tell() bs.seek(12, NOESEEK_REL) z = bs.tell() sb.seek(z, NOESEEK_ABS) DDSHeight = sb.readUInt() DDSWidth = sb.readUInt() bs.seek(72, NOESEEK_REL) DDSFormat = bs.readBytes(4).decode("ASCII").rstrip("\0") print(DDSFormat, bs.tell()) bs.seek(Return, NOESEEK_ABS) bs.seek(128, NOESEEK_REL) Content = (TextureSize - 128) DDSContent2 = bs.readBytes(Content) bs.seek(Return, NOESEEK_ABS) DDSContent = bs.readBytes(TextureSize) DDSFooter = bs.readUInt() if DDSFormat == ("DXT5"): DDSFormat2 = noesis.NOESISTEX_DXT5 if DDSFormat == ("DXT1"): DDSFormat2 = noesis.NOESISTEX_DXT1 if DDSFormat == ("DXT3"): DDSFormat2 = noesis.NOESISTEX_DXT3 texList.append(NoeTexture(DDSName, DDSWidth, DDSHeight, DDSContent2, DDSFormat2)) if DDSSpitOut == 1: dds = NoeBitStream() dds.writeBytes(DDSContent) ExportDDSName = (noesis.getSelectedDirectory() + DDSName) if MATDEBUG: print("Writing", ExportDDSName) o = open(ExportDDSName, 'wb') o.write(dds.getBuffer()) o.close() if MATDEBUG: print("DDSEND", bs.tell()) print(DDSName) MaterialStart = (bs.tell()) print(MaterialStart) ChunkID = bs.readUInt() ChunkType = bs.readUInt() ChunkSize = (bs.readUInt()) Blank = bs.readUInt() ContentCount = bs.readUInt() if SkipMaterials == 1: bs.seek(ChunkSize - 20, NOESEEK_REL) else: matList = [] matNames = [] for M in range(0, ContentCount): if MATDEBUG: print("Reading MATS", bs.tell()) MaterialNameChar = bs.readUShort() MaterialName = bs.readBytes(MaterialNameChar).decode("ASCII").rstrip("\0") shit = bs.readUInt() MaterialName = MaterialName.replace(':', '_') Material = NoeMaterial(MaterialName, "") MatType = bs.readUShort() MatBS = bs.readUShort() if MATDEBUG: print("MATTYPE", MatType) if MatType == int(0): Diffuse = NoeVec4([0.0, 0.0, 0.0, 0.0]) Material.setDiffuseColor(Diffuse) bs.seek(102, NOESEEK_REL) if MatType == int(17): AmbX = bs.readFloat() AmbY = bs.readFloat() AmbZ = bs.readFloat() Amb = NoeVec4([AmbX, AmbY, AmbZ, 1.0]) blank = bs.readUInt() RimC = NoeVec3.fromBytes(bs.readBytes(12)) Material.setRimLighting(RimC) Spec = NoeVec4([0.0, 0.0, 0.0, 0.0,]) Material.setSpecularColor(Spec) bs.seek(74, NOESEEK_REL) CurrentCount = bs.readUShort() CurrentTex = bs.readBytes(CurrentCount).decode("ASCII").rstrip("\0") Material.setTexture(CurrentTex) Material.setAmbientColor(Amb) bs.seek(124, NOESEEK_REL) if MatType == int(16): bs.seek(102, NOESEEK_REL) CurrentCount = bs.readUShort() CurrentTex = bs.readBytes(CurrentCount).decode("ASCII").rstrip("\0") Material.setTexture(CurrentTex) bs.seek(76, NOESEEK_REL) if MatType == int(145): AmbX = bs.readFloat() AmbY = bs.readFloat() AmbZ = bs.readFloat() Amb = NoeVec4([AmbX, AmbY, AmbZ, 1.0]) blank = bs.readUInt() RimC = NoeVec3.fromBytes(bs.readBytes(12)) Material.setRimLighting(RimC) Spec = NoeVec4([0.0, 0.0, 0.0, 0.0,]) Material.setSpecularColor(Spec) bs.seek(50, NOESEEK_REL) Four = bs.readUInt() Byte = bs.readUByte() print(Byte) Count = bs.readUByte() Two = bs.readUInt() bs.seek(14, NOESEEK_REL) for TC in range(0, 2): CurrentCount = bs.readUShort() CurrentTex = bs.readBytes(CurrentCount).decode("ASCII").rstrip("\0") if TC == 0: Material.setTexture(CurrentTex) if TC == 1: Material.setSpecularTexture(CurrentTex) bs.seek(76, NOESEEK_REL) if MATDEBUG: print("Tex ", TC, " Done", bs.tell()) bs.seek(48, NOESEEK_REL) if MATDEBUG: print("LoopDone", bs.tell()) Material.setAmbientColor(Amb) matList.append(Material) matNames.append(MaterialName) Material = None ## MESHES ChunkID = bs.readUInt() ChunkType = bs.readUInt() ChunkSize = bs.readUInt() Blank = bs.readUInt() MeshType = bs.readUInt() ##MeshTypes: 7 = Skinned Mesh; 3 = Static Mesh; 11 = Morphed Mesh; 30 = World Mesh B = None NameList = [] BoneMats = [] BoneName = [] if MeshType == 7: BoneCount = bs.readUInt() BoneList = [] BoneParents = [] for B in range(0, BoneCount): boneMat44 = NoeMat44.fromBytes(bs.readBytes(64), NOE_BIGENDIAN) boneMat43 = boneMat44.toMat43() BoneMats.append(boneMat43.inverse()) ## BoneList.append(NoeBone(B, "bone_"+str(B), boneMat43, None, 0)) for BP in range(0, BoneCount): BoneParents.append(bs.readUShort()) BBOXSHIT = bs.readBytes(40) if MeshType == 11: BBOXSHIT = bs.readBytes(40) BoneList = [] BoneParents = [] if MeshType == 3: Shit = bs.readBytes(40) Other = [] Extra = [] BS2 = [] BSC = 0 BSP = [] NM = 0 BPP = [-1] BB = -1 BSBoneList = [] RigMatrix = [] Mesh = 0 Bone = 0 MeshCount = 0 RootNodeChar = bs.readUShort() RootNodeName = bs.readBytes(RootNodeChar).decode("ASCII").rstrip("\0") RootHash = bs.readUInt() POSX = bs.readFloat() POSY = bs.readFloat() POSZ = bs.readFloat() ROTX = bs.readFloat() ROTY = bs.readFloat() ROTZ = bs.readFloat() SCAX = bs.readFloat() SCAY = bs.readFloat() SCAZ = bs.readFloat() Scale = bs.readFloat() Matrix0 = NoeVec3((ROTX, ROTY, ROTZ)) Matrix1 = Matrix0.toAnglesDirect() Matrix = Matrix1.toMat43() Matrix.__setitem__(3,(POSX,POSY,POSZ)) BS2.append(NoeBone(BSC, RootNodeName, Matrix, None, -1)) Blank = bs.readUInt() Byte = bs.readUByte() Scale = bs.readFloat() Test2 = bs.readUInt() if Test2 > 0: for T in range(0, (Test2)): BSP.append(BSC) SuperTest = int(0) while (SuperTest != int(272)): NM = (NM + 1) NodeChar = bs.readUShort() NodeName = bs.readBytes(NodeChar).decode("ASCII").rstrip("\0") if MESHDEBUG: print(NodeName) NodeHash = bs.readUInt() POSX = bs.readFloat() POSY = bs.readFloat() POSZ = bs.readFloat() ROTX = bs.readFloat() ROTY = bs.readFloat() ROTZ = bs.readFloat() SCAX = bs.readFloat() SCAY = bs.readFloat() SCAZ = bs.readFloat() Scale = bs.readFloat() Matrix0 = NoeVec3((ROTX,ROTY,-ROTZ)) Matrix1 = Matrix0.toAnglesDirect() Matrix = Matrix1.toMat43() Matrix.__setitem__(3,(POSX,POSY,POSZ)) if MeshType == 11 or BoneOverride: if BoneOverride: print("BONEOVERRIDE", NodeName) Remember = BSP[-1] BSP.pop(-1) if NodeName == "root": Remember = -1 BS2.append(NoeBone(NM, NodeName, Matrix, None, Remember)) Test = bs.readUInt() ModelType = 0 if MESHDEBUG: print("Set Bone", BB, bs.tell()) if Test != int(0): if MESHDEBUG: print("A Mesh", NM) Mesh = 1 Bone = 0 SubMeshCount = Test if MeshType == 11: if SubMeshCount > 1: SubMeshCount = (SubMeshCount - 1) MeshName = NodeName ## print("SubMesh", SubMeshCount, bs.tell()) for SC in range(0, SubMeshCount): print(bs.tell(), SC, SubMeshCount) Four = bs.readUInt() if Four == 9: if MESHDEBUG: print("Mesh ", BB, " Has Morphs") MorphThing1 = bs.readUInt() if MorphThing1 == 15: if MESHDEBUG: print("Morph Thing is 15") shit = bs.readBytes(60) elif MorphThing1 == 6: shit = bs.readBytes(24) MorphSetNameChar = bs.readUShort() MorphSetName = bs.readBytes(MorphSetNameChar).decode("ASCII").rstrip("\0") MorphSetID = bs.readUInt() FourAgain = bs.readUInt() Thing = bs.readUShort() ModelType = bs.readUShort() if ModelType == 94: if MESHDEBUG: print("Morph Enabled", SC) Morph = 1 else: Morph = 0 Stride = bs.readUInt() if MESHDEBUG: print("Stride", SC, Stride, bs.tell()) if Stride == int(18): VertStride = 44 UVStride = None NormOff = 12 IAmStatic = 0 if Stride == int(82): if Morph == 1: VertStride = 28 UVStride = None IAmStatic = 1 elif ModelType == 30: VertStride = 28 UVStride = None IAmStatic = 1 else: VertStride = 48 UVStride = None IAmStatic = 0 elif Stride == int(274): if ModelType == 30: VertStride = 32 UVStride = 24 NormOff = 12 IAmStatic = 1 else: VertStride = 52 UVStride = 24 NormOff = 12 IAmStatic = 0 elif Stride == int(338): if Morph == 1: VertStride = 36 UVStride = 28 IAmStatic = 1 else: VertStride = 56 UVStride = 28 IAmStatic = 0 UVType = noesis.RPGEODATA_FLOAT NormOff = 12 if ModelType == 30 or ModelType == 1310: VertStride = 36 UVStride = 28 IAmStatic = 1 FaceBuffSize = (bs.readUInt() * 6) FaceCount = (FaceBuffSize / 2) FaceCount = int(FaceCount) One = bs.readUShort() if MESHDEBUG: print("VertAT", bs.tell()) VertCount = bs.readUInt() Blank = bs.readUInt() VPOS = [] VPOS2 = [] NORM = [] UV = [] Weights = [] Indexs = [] print(Stride, VertStride, VertCount) for VS in range(0, VertCount): VPOSX = bs.readFloat() VPOSY = bs.readFloat() VPOSZ = bs.readFloat() VPOS.append(VPOSX) VPOS.append(VPOSY) VPOS.append(VPOSZ) VPOS2.append((VPOSX, VPOSY, VPOSZ)) NormX = bs.readFloat() NormY = bs.readFloat() NormZ = bs.readFloat() NORM.append(NormX) NORM.append(NormY) NORM.append(NormZ) if (Stride == int(338)) or (Stride == int(82)): Negative1 = bs.readUInt() if UVStride != None: U = bs.readFloat() V = bs.readFloat() UV.append(U) UV.append(V) if UVStride == None: U = float(0.0) V = float(0.0) UV.append(U) UV.append(V) if MeshType == 7: if IAmStatic == 0: Weight4 = bs.readFloat() Weight3 = bs.readFloat() Weight2 = bs.readFloat() Weight1 = bs.readFloat() Index1 = bs.readByte() Index2 = bs.readByte() Index3 = bs.readByte() Index4 = bs.readByte() Weights.append(Weight4) Weights.append(Weight3) Weights.append(Weight2) Weights.append(Weight1) Indexs.append(Index4) Indexs.append(Index3) Indexs.append(Index2) Indexs.append(Index1) POSBUFF = struct.pack('>' + 'f'*len(VPOS), *VPOS) UVBUFF = struct.pack('>' + 'f'*len(UV), *UV) NORMBUFF = struct.pack('>' + 'f'*len(NORM), *NORM) if MeshType == 7: if ModelType != 30: WeightBuff = struct.pack('>' + 'f'*len(Weights), *Weights) IndexBuff = struct.pack('>' + 'b'*len(Indexs), *Indexs) if Morph == 1: if MESHDEBUG: print("Doing Morph Things", SC) MorphThing1 = bs.readUInt() MorphCount = bs.readUInt() MPOS = [] MPOS2 = [] MFrame = [] for MBS in range(0, MorphCount): MorphThing2 = bs.readUInt() MorphVertCount = bs.readUInt() ## print(bs.tell()) if MorphVertCount != VertCount: print("PANIC", MorphVertCount, VertCount, MBS) for MVS in range(0, MorphVertCount): X = VPOS2[MVS] XX = X[0] XXX = X[1] XXXX = X[2] MPOSX = (bs.readFloat() + XX) MPOSY = (bs.readFloat() + XXX) MPOSZ = (bs.readFloat() + XXXX) MPOS.append(MPOSX) MPOS.append(MPOSY) MPOS.append(MPOSZ) MORPHBUFF = struct.pack('>' + 'f'*len(MPOS), *MPOS) MFrame.append(MORPHBUFF) MPOS = [] MBS = 0 MVS = 0 MVVS = 0 if MESHDEBUG: print("VertDone", bs.tell()) FaceBuff = bs.readBytes(FaceBuffSize) if MESHDEBUG: print("FaceBuff Done", bs.tell()) MaterialChar = bs.readUShort() CurrentMaterial = bs.readBytes(MaterialChar).decode("ASCII").rstrip("\0") CurrentMaterial = CurrentMaterial.replace(':', '_') if SubMeshCount > 1: MeshName = (MeshName + "_sub_" + str(SC)) if EXPMorph == 1: if Morph == 1: rapi.rpgBindPositionBuffer(POSBUFF, noesis.RPGEODATA_FLOAT, 12) rapi.rpgSetName(MeshName) rapi.rpgBindNormalBuffer(NORMBUFF, noesis.RPGEODATA_FLOAT, 12) rapi.rpgBindUV1Buffer(UVBUFF, noesis.RPGEODATA_FLOAT, 8) rapi.rpgSetMaterial(CurrentMaterial) rapi.rpgCommitTriangles(FaceBuff, noesis.RPGEODATA_USHORT, FaceCount, noesis.RPGEO_TRIANGLE, 1) rapi.rpgClearBufferBinds() for Frame1 in range(0, MorphCount): rapi.rpgBindPositionBuffer(MFrame[Frame1], noesis.RPGEODATA_FLOAT, 12) rapi.rpgSetName(MeshName + "_Morph" + str(Frame1)) rapi.rpgBindNormalBuffer(NORMBUFF, noesis.RPGEODATA_FLOAT, 12) rapi.rpgBindUV1Buffer(UVBUFF, noesis.RPGEODATA_FLOAT, 8) rapi.rpgSetMaterial(CurrentMaterial) rapi.rpgCommitTriangles(FaceBuff, noesis.RPGEODATA_USHORT, FaceCount, noesis.RPGEO_TRIANGLE, 1) rapi.rpgClearBufferBinds() else: rapi.rpgBindPositionBuffer(POSBUFF, noesis.RPGEODATA_FLOAT, 12) rapi.rpgBindNormalBuffer(NORMBUFF, noesis.RPGEODATA_FLOAT, 12) rapi.rpgBindUV1Buffer(UVBUFF, noesis.RPGEODATA_FLOAT, 8) rapi.rpgSetName(MeshName) rapi.rpgSetMaterial(CurrentMaterial) if MeshType == 7: if ModelType == 31: if Skin == 1: rapi.rpgBindBoneWeightBuffer(WeightBuff, noesis.RPGEODATA_FLOAT, 16, 4) rapi.rpgBindBoneIndexBuffer(IndexBuff, noesis.RPGEODATA_BYTE, 4, 4) rapi.rpgCommitTriangles(FaceBuff, noesis.RPGEODATA_USHORT, FaceCount, noesis.RPGEO_TRIANGLE, 1) if Optimize: rapi.rpgOptimize() rapi.rpgClearBufferBinds() MFrame = [] MeshCount = (MeshCount + 1) MaterialID = bs.readUInt() BBOXSHIT = bs.readBytes(40) MeshName = NodeName NameList.append(MeshName) print(SC, " Done ", bs.tell()) Byte = bs.readUByte() if Byte == int(1): if Mesh != 1: Bone = 1 Mesh = 0 BB = (BB + 1) Prop2 = bs.readUInt() if MESHDEBUG: print("Extra Params Start", bs.tell(), "0", "Count", Prop2) for BSProp in range(0, Prop2): Thing = bs.readUInt() propchar = bs.readUShort() propname = bs.readBytes(propchar).decode("ASCII").rstrip("\0") prophash = bs.readUInt() Type2 = bs.readUInt() ## if prophash == int(1882726475) or int(1253562415): ## Type2 = (Type2 - 1) if Thing == int(4): Type2 = (Type2 - 1) PropData = bs.seek(Type2, NOESEEK_REL) if MESHDEBUG: print(BSProp, bs.tell()) if MESHDEBUG: print("Extra Params End", bs.tell(), "1") Float = bs.readFloat() Test2 = bs.readUInt() if Test2 != 0: for T2 in range(0, Test2): if ModelType == 30: BSP.append(NM) else: BSP.append(NM) if Bone: BPP.append(BB) if Bone: BoneName.append(NodeName) RigMatrix.append(Matrix) SuperTest = bs.readUShort() if SuperTest != int(272): bs.seek(-2, NOESEEK_REL) if MESHDEBUG: print("Complete", bs.tell()) Mesh = 0 mdl = rapi.rpgConstructModel() if MeshType == 7: if not BoneOverride: if MESHDEBUG: print("Setting Bones") MaxBoneList = max(BoneParents) print("BoneParentListMax ", MaxBoneList) print(len(BPP), BPP) print(len(BoneName), BoneName) print(BoneCount) Diff = (MaxBoneList - BoneCount) for BD in range(0, BoneCount): CBP = BoneParents[BD] print(BD, CBP) CBP = (CBP - 1) BoneList.append(NoeBone(BD, "bone_"+str(BD), BoneMats[BD], None, 0)) mdl.setBones(BoneList) if MeshType == 11 or MeshType == 3 or BoneOverride: if MESHDEBUG: print("Setting Bones") BS2 = rapi.multiplyBones(BS2) mdl.setBones(BS2) mdl.setModelMaterials(NoeModelMaterials(texList, matList)) if EmergencyNameDump: print(NameList) mdlList.append(mdl) rapi.rpgClearBufferBinds() return 1