home *** CD-ROM | disk | FTP | other *** search
- #Base Model Class
-
- from inc_noesis import *
-
- def registerNoesisTypes():
- handle = noesis.register("Enchanted Arms MDL", ".mdl")
- noesis.setHandlerTypeCheck(handle, earmsCheckType)
- noesis.setHandlerLoadModel(handle, earmsLoadModel)
- #noesis.logPopup()
-
- handle = noesis.register("Enchanted Arms TBND", ".tbnd")
- noesis.setHandlerTypeCheck(handle, tbndCheckType)
- noesis.setHandlerLoadRGBA(handle, tbndLoadRGBA)
-
- return 1
-
-
- def tbndCheckType(data):
- td = NoeBitStream(data)
- Magic = td.readUInt()
- if Magic != 0x33444E42:
- return 0
- return 1
-
- def earmsCheckType(data):
- bs = NoeBitStream(data)
- Magic = bs.readUInt()
- if Magic != 0x344C444D:
- return 0
- return 1
-
- def tbndLoadRGBA(data, texList):
- td = NoeBitStream(data, NOE_BIGENDIAN)
- td.seek(0x10, NOESEEK_ABS)
- texCount = td.readUInt(); td.seek(0x20, NOESEEK_ABS)
- texOff = []
- for i in range(0, texCount):
- texOff.append(td.read(">" + 4 * "i"))
- for i in range(0, texCount):
- td.seek(texOff[i][2], NOESEEK_ABS)
- tpfinfo = td.read(">" + 6 * "i")
- tpfinfo2 = td.read(">" + 4 * "h")
- td.seek(0x10, NOESEEK_REL)
- texName = td.readBytes(0x50).decode("ASCII").rstrip("\0")
- texData = td.readBytes(tpfinfo[5])
- texFmt = noesis.NOESISTEX_DXT1
- if tpfinfo2[0] == 0:
- texFmt = noesis.NOESISTEX_DXT1
- elif tpfinfo2[0] == 1:
- texFmt = noesis.NOESISTEX_DXT1
- elif tpfinfo2[0] == 768:
- texFmt = noesis.NOESISTEX_DXT3
- if tpfinfo2[0] == 1280:
- texFmt = noesis.NOESISTEX_DXT5
- texList.append(NoeTexture(texName, tpfinfo2[2], tpfinfo2[3], texData, texFmt))
- return 1
-
- class EnchArms(object):
-
- def __init__(self, data):
- self.inFile = NoeBitStream(data, NOE_BIGENDIAN)
- rapi.rpgSetOption(noesis.RPGOPT_BIGENDIAN, 1)
- rapi.rpgSetOption(noesis.RPGOPT_TRIWINDBACKWARD, 1)
- rapi.setPreviewOption("setAngOfs", "0 90 90")
- rapi.setPreviewOption("setAnimSpeed", "2.0")
- #all morphs that we provide are relative to the base positions,
- #so we just leave these options on.
- #(otherwise, they affect things only at CommitMorphFrame time,
- #and can be toggled on and off as needed)
- rapi.rpgSetOption(noesis.RPGOPT_MORPH_RELATIVEPOSITIONS, 1)
- rapi.rpgSetOption(noesis.RPGOPT_MORPH_RELATIVENORMALS, 1)
- self.texList = []
- self.matList = []
- self.boneList = []
- self.boneMap = []
- self.meshOffsets = []
-
- def alignPosition(self, bs, alignment):
- alignment = alignment - 1
- bs.seek(((bs.tell() + alignment) & ~alignment), NOESEEK_ABS)
-
- def loadHeader(self, bs):
- magic = bs.readBytes(4).decode("ASCII").rstrip("\0")
- mdlVersion, mdlSubVersion = bs.read(">" + 2 * "H")
- self.dataOffset, self.dataSize, self.count1, self.materialCount, \
- self.boneCount, self.meshCount, self.meshCount2 \
- = bs.read(">" + 7 * "i")
- self.bbMin = NoeVec3( (bs.readFloat(), bs.readFloat(), bs.readFloat()) )
- self.bbMax = NoeVec3( (bs.readFloat(), bs.readFloat(), bs.readFloat()) )
- self.totalVertCount, self.totalFaceCount = bs.read(">" + 2 * "i")
- bs.seek(0x80, NOESEEK_ABS)
- #print("Data Offset:", self.dataOffset, " Data Size:", self.dataSize, " Count 1:", self.count1, \
- #" Material Count:", self.materialCount, " Bone Count:", self.boneCount, " Mesh Count:", \
- #self.meshCount, " Mesh Count 2:", self.meshCount2)
- #print("Bounding Box Min:", self.bbMin, " Bounding Box Max:", self.bbMax)
- #print("Vertex Count:", self.totalVertCount, " Face Count:", self.totalFaceCount)
-
- def loadSection1(self, bs):
- #print("Section1 Start:", bs.tell())
- bs.seek(0x30 * self.count1, NOESEEK_REL)
-
-
- def loadMaterials(self, bs):
- #print("Material Info Start:", bs.tell())
- for i in range(0, self.materialCount):
- matStart = bs.tell()
- try:
- materialName = bs.readBytes(0x1F).decode("ASCII").rstrip("\0")
- except:
- print("WARNING: Non-ASCII string data:")
- materialName = "material_" + str(i)
- #materialName = bs.readBytes(0x1F).decode("ASCII").rstrip("\0")
- shaderName = bs.readBytes(0x1F).decode("ASCII").rstrip("\0")
- material = NoeMaterial(materialName, "")
- modelID = bs.readUByte()
- shaderCount = bs.readUByte()
- for a in range(0, shaderCount):
- valueType = bs.readUByte()
- valueName = bs.readBytes(0x1F).decode("ASCII").rstrip("\0")
- if valueName in testMaterialLoaderDict:
- testMaterialLoaderDict[valueName](material, bs)
- else:
- print(bs.tell())
- print("New Material Found:",valueName)
- bs.seek(0x20, NOESEEK_REL)
- self.matList.append(material)
- bs.seek(0x840 + matStart, NOESEEK_ABS)
-
- def loadBones(self, bs):
- #print("Bone Info Start:", bs.tell())
- for i in range(0, self.boneCount):
- try:
- boneName = bs.readBytes(0x20).decode("ASCII").rstrip("\0")
- except:
- print("WARNING: Non-ASCII string data:")
- boneName = "bone_" + str(i)
- pos = NoeVec3.fromBytes(bs.readBytes(12), NOE_BIGENDIAN)
- boneMtx = NoeAngles.fromBytes(bs.readBytes(12), NOE_BIGENDIAN).toDegrees().toMat43_XYZ()
- boneMtx[3] = pos
- bs.seek(0x24, NOESEEK_REL)
- bInfo = bs.read(">" + 4 * "h")
- bs.seek(0x2C, NOESEEK_REL)
- newBone = NoeBone(i, boneName, boneMtx, None, bInfo[0])
- self.boneList.append(newBone)
- self.boneList = rapi.multiplyBones(self.boneList)
-
-
- def loadModelInfo(self, bs):
- #print("Model Info Start:", bs.tell())
- for i in range(0, self.meshCount):
- morphInfo = []
- bonePallet = []
- #print(bs.tell())
- flags = bs.read(4 * "b")
- faceCount, unk = bs.read(">" + 2 * "h")
- for a in range(0, 28):
- boneID = bs.readShort()
- if boneID != -1:
- bonePallet.append(boneID)
- faceSize, faceStart, vertSize, vertStart = bs.read(">" + 4 * "i")
- if flags[0] == 2:
- for a in range(0, 16):
- morphSize, morphOffset = bs.read(">" + 2 * "i")
- if morphSize != 0:
- morphInfo.append([morphSize, morphOffset])
- self.meshOffsets.append([faceSize, faceStart, vertSize, vertStart, flags[0], flags[1], faceCount, morphInfo])
- self.boneMap.append(bonePallet)
- #print(flags)
- #print((self.dataOffset + faceStart), (self.dataOffset + vertStart), vertSize)
- #print(faceSize, faceStart, vertSize, vertStart)
-
-
-
- def loadMesh(self, bs):
- bs.seek(self.dataOffset, NOESEEK_ABS)
- #print("Mesh Start:", bs.tell())
- for i in range(0, self.meshCount):
- #print(self.meshOffsets[i][4])
- bs.seek(self.dataOffset + self.meshOffsets[i][1], NOESEEK_ABS)
- faceBuff = bs.readBytes(self.meshOffsets[i][0])
- bs.seek(self.dataOffset + self.meshOffsets[i][3], NOESEEK_ABS)
- vertBuff = bs.readBytes(self.meshOffsets[i][2])
- rapi.rpgSetBoneMap(self.boneMap[i])
- #rapi.rpgSetName(str(i))
- rapi.rpgSetMaterial(self.matList[self.meshOffsets[i][5]].name)
- if self.meshOffsets[i][4] == 0:
- rapi.rpgSetPosScaleBias(None, None)
- rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 0x40, 0)
- rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, 0x40, 24, 4)
- rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 0x40, 28)
- rapi.rpgBindUV2BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 0x40, 44)
- #rapi.rpgBindBoneIndexBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, 0x40, 20, 4)
- #rapi.rpgBindBoneWeightBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, 0x40, 60, 4)
- rapi.rpgCommitTriangles(faceBuff, noesis.RPGEODATA_SHORT, self.meshOffsets[i][6], noesis.RPGEO_TRIANGLE_STRIP, 1)
- elif self.meshOffsets[i][4] == 1:
- rapi.rpgSetPosScaleBias(None, None)
- rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 0x54, 0)
- #rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, 0x54, 24, 4)
- rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 0x54, 28)
- rapi.rpgBindUV2BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 0x54, 44)
- rapi.rpgBindBoneIndexBufferOfs(vertBuff, noesis.RPGEODATA_SHORT, 0x54, 60, 4)
- rapi.rpgBindBoneWeightBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 0x54, 68, 4)
- rapi.rpgCommitTriangles(faceBuff, noesis.RPGEODATA_SHORT, self.meshOffsets[i][6], noesis.RPGEO_TRIANGLE_STRIP, 1)
- elif self.meshOffsets[i][4] == 2:
- rapi.rpgSetPosScaleBias((328.0,328.0,328.0),(0,0,0))
- #print(self.meshOffsets[i][7][0])
- bs.seek(self.dataOffset + self.meshOffsets[i][7][0][1], NOESEEK_ABS)
- posBuff = bs.readBytes(self.meshOffsets[i][7][0][0])
- rapi.rpgBindPositionBufferOfs(posBuff, noesis.RPGEODATA_SHORT, 16, 0)
- #rapi.rpgBindColorBufferOfs(vertBuff, noesis.RPGEODATA_UBYTE, 0x3C, 0, 4)
- rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 0x3C, 4)
- rapi.rpgBindUV2BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 0x3C, 20)
- rapi.rpgBindBoneIndexBufferOfs(vertBuff, noesis.RPGEODATA_SHORT, 0x3C, 36, 4)
- rapi.rpgBindBoneWeightBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 0x3C, 44, 4)
- for a in range(1, len(self.meshOffsets[i][7])):
- bs.seek(self.dataOffset + self.meshOffsets[i][7][a][1], NOESEEK_ABS)
- morphBuff = bs.readBytes(self.meshOffsets[i][7][a][0])
- rapi.rpgFeedMorphTargetPositionsOfs(morphBuff, noesis.RPGEODATA_SHORT, 16, 0)
- rapi.rpgCommitMorphFrame(self.meshOffsets[i][7][a][0] // 16)
- rapi.rpgCommitMorphFrameSet()
- rapi.rpgCommitTriangles(faceBuff, noesis.RPGEODATA_SHORT, self.meshOffsets[i][6], noesis.RPGEO_TRIANGLE_STRIP, 1)
-
- rapi.rpgClearBufferBinds()
- def load_tex(self):
- folderName = rapi.getDirForFilePath(rapi.getInputName())
- baseName = rapi.getExtensionlessName(rapi.getLocalFileName(rapi.getInputName()))
- texFile = folderName + baseName + ".tbnd"
- if (rapi.checkFileExists(texFile)):
- #print(texFile)
- texData = rapi.loadIntoByteArray(texFile)
- tbndLoadRGBA(texData, self.texList)
-
-
- def parse_file(self):
- bs = self.inFile
- self.loadHeader(bs)
- self.load_tex()
- self.loadSection1(bs)
- self.loadMaterials(bs)
- self.loadBones(bs)
- self.loadModelInfo(bs)
- self.loadMesh(bs)
- return 1
-
-
- #Noesis blends:
- #0 - "None"
- #1 - "GL_ZERO"
- #2 - "GL_ONE"
- #3 - "GL_SRC_COLOR"
- #4 - "GL_ONE_MINUS_SRC_COLOR"
- #5 - "GL_SRC_ALPHA"
- #6 - "GL_ONE_MINUS_SRC_ALPHA"
- #7 - "GL_DST_ALPHA"
- #8 - "GL_ONE_MINUS_DST_ALPHA"
- #9 - "GL_DST_COLOR"
- #10 - "GL_ONE_MINUS_DST_COLOR"
- #11 - "GL_SRC_ALPHA_SATURATE"
-
- class Material:
- def _init_(self):
- texColorExpr = "abs(mtl_diffuse_a, 0, 12)"
- self.setExpr_texidx(texColorExpr)
- pass
- #self.setBlendMode("None", "None")
-
- def load_g_MatAlphaBlend(self, bs):
- AlphaBlend = bs.readUInt()
- bs.seek(0x1C, NOESEEK_REL)
-
- def load_g_MatAlphaRef(self, bs):
- AlphaRef = bs.readUInt()
- self.setDefaultBlend(0)
- #if AlphaRef:
- # self.setBlendMode("GL_ONE_MINUS_SRC_COLOR", "None")
- bs.seek(0x1C, NOESEEK_REL)
-
- def load_g_MatSelfIllumeCol(self, bs):
- #self.setAmbientColor(NoeVec4.fromBytes(bs.readBytes(16), NOE_BIGENDIAN))
- bs.seek(0x20, NOESEEK_REL)
-
- def load_g_MatSelfIllumeCoef(self, bs):
- bs.seek(0x20, NOESEEK_REL)
-
- def load_g_MatDiffCol(self, bs):
- #self.setDiffuseColor(NoeVec4.fromBytes(bs.readBytes(16), NOE_BIGENDIAN))
- bs.seek(0x20, NOESEEK_REL)
-
- def load_g_MatDiffCoef(self, bs):
- bs.seek(0x20, NOESEEK_REL)
-
- def load_g_MatDiffRough(self, bs):
- bs.seek(0x20, NOESEEK_REL)
-
- def load_g_MatSpecCol(self, bs):
- #self.setSpecularColor(NoeVec4.fromBytes(bs.readBytes(16), NOE_BIGENDIAN))
- bs.seek(0x20, NOESEEK_REL)
-
- def load_g_MatSpecCoef(self, bs):
- bs.seek(0x20, NOESEEK_REL)
-
- def load_g_MatSpecPower(self, bs):
- bs.seek(0x20, NOESEEK_REL)
-
- def load_g_MatEnvmapFresnelScale(self, bs):
- bs.seek(0x20, NOESEEK_REL)
-
- def load_g_MatEnvmapFresnelBias(self, bs):
- bs.seek(0x20, NOESEEK_REL)
-
- def load_g_DiffuseTexture(self, bs):
- self.setTexture(bs.readBytes(0x20).decode("ASCII").rstrip("\0"))
-
-
- def load_g_DiffuseTexture2(self, bs):
- bs.seek(0x20, NOESEEK_REL)
-
-
- def load_g_AlphamapTexture(self, bs):
- bs.seek(0x20, NOESEEK_REL)
- #self.setOpacityTexture(bs.readBytes(0x20).decode("ASCII").rstrip("\0"))
-
- def load_g_LightmapTexture(self, bs):
- bs.seek(0x20, NOESEEK_REL)
- #self.setOpacityTexture(bs.readBytes(0x20).decode("ASCII").rstrip("\0"))
-
- def load_g_CubeEnvmapTexture(self, bs):
- bs.seek(0x20, NOESEEK_REL)
-
- def load_g_EnvmapMaskTexture(self, bs):
- bs.seek(0x20, NOESEEK_REL)
- #self.setEnvTexture(bs.readBytes(0x20).decode("ASCII").rstrip("\0"))
-
- def load_g_BumpmapTexture(self, bs):
- #bs.seek(0x20, NOESEEK_REL)
- self.setBumpTexture(bs.readBytes(0x20).decode("ASCII").rstrip("\0"))
-
- def load_g_MatParallaxOffset(self, bs):
- bs.seek(0x20, NOESEEK_REL)
-
- def load_g_EnchantMapTexture(self, bs):
- bs.seek(0x20, NOESEEK_REL)
- #self.setBumpTexture(bs.readBytes(0x20).decode("ASCII").rstrip("\0"))
-
- def load_g_MatEnchantMapParamID(self, bs):
- MatEnchantMapParamID = bs.readUInt()
- bs.seek(0x1C, NOESEEK_REL)
-
- def load_g_MatDiffLerpExp(self, bs):
- bs.seek(0x20, NOESEEK_REL)
-
- testmaterialTypeDict = {
-
- }
-
-
-
- testMaterialLoaderDict = {
- "g_MatAlphaBlend" : Material.load_g_MatAlphaBlend,
- "g_MatAlphaRef" : Material.load_g_MatAlphaRef,
- "g_MatSelfIllumeCol" : Material.load_g_MatSelfIllumeCol,
- "g_MatSelfIllumeCoef" : Material.load_g_MatSelfIllumeCoef,
- "g_MatDiffCol" : Material.load_g_MatDiffCol,
- "g_MatDiffCoef" : Material.load_g_MatDiffCoef,
- "g_MatDiffRough" : Material.load_g_MatDiffRough,
- "g_MatSpecCol" : Material.load_g_MatSpecCol,
- "g_MatSpecCoef" : Material.load_g_MatSpecCoef,
- "g_MatSpecPower" : Material.load_g_MatSpecPower,
- "g_MatEnvmapFresnelScale" : Material.load_g_MatEnvmapFresnelScale,
- "g_MatEnvmapFresnelBias" : Material.load_g_MatEnvmapFresnelBias,
- "g_DiffuseTexture" : Material.load_g_DiffuseTexture,
- "g_DiffuseTexture2" : Material.load_g_DiffuseTexture2,
- "g_AlphamapTexture" : Material.load_g_AlphamapTexture,
- "g_LightmapTexture" : Material.load_g_LightmapTexture,
- "g_CubeEnvmapTexture" : Material.load_g_CubeEnvmapTexture,
- "g_EnvmapMaskTexture" : Material.load_g_EnvmapMaskTexture,
- "g_BumpmapTexture" : Material.load_g_BumpmapTexture,
- "g_MatParallaxOffset" : Material.load_g_MatParallaxOffset,
- "g_EnchantMapTexture" : Material.load_g_EnchantMapTexture,
- "g_MatEnchantMapParamID" : Material.load_g_MatEnchantMapParamID,
- "g_MatDiffLerpExp" : Material.load_g_MatDiffLerpExp
-
- }
-
-
-
- def earmsLoadModel(data, mdlList):
- ctx = rapi.rpgCreateContext()
- parser = EnchArms(data)
- parser.parse_file()
- #rapi.rpgSmoothNormals()
- #rapi.rpgSmoothTangents()
- #rapi.rpgUnifyBinormals(1)
- try:
- mdl = rapi.rpgConstructModel()
- except:
- mdl = NoeModel()
- mdl.setModelMaterials(NoeModelMaterials(parser.texList, parser.matList))
- mdlList.append(mdl); mdl.setBones(parser.boneList)
- return 1