Tried, still the same. I shortened the param list because that's the root bone, with no parent(it doesn't even have a name), I saw some plugins with shortened param lists so i thought it might work this way xd
Code: Select all
from inc_noesis import *
import noesis
import rapi
def registerNoesisTypes():
handle = noesis.register("The iDOLM@STER One For All Model", ".pmd")
noesis.setHandlerTypeCheck(handle, pmdCheckType)
noesis.setHandlerLoadModel(handle, pmdLoadModel)
handle = noesis.register("The iDOLM@STER One For All Texture", ".pta")
noesis.setHandlerTypeCheck(handle, ptaCheckType)
noesis.setHandlerLoadRGBA(handle, ptaLoadRGBA)
noesis.logPopup()
return 1
NOEPY_HEADER = "PMD"
def ptaCheckType(data):
bs = NoeBitStream(data)
return 1
def pmdCheckType(data):
bs = NoeBitStream(data)
if len(data) < 3:
return 0
if bs.readBytes(3).decode("ASCII") != NOEPY_HEADER:
return 0
return 1
def ptaLoadRGBA(data, texList):
bs = NoeBitStream(data, NOE_BIGENDIAN)
Header = bs.readBytes(3).decode("ASCII")
print(Header)
bs.seek(0x5, NOESEEK_REL)
FileCount=bs.readInt()
print(FileCount)
bs.seek(0x4, NOESEEK_REL)
TextureOffsets = []
for i in range(0, FileCount):
TextureOffsets.append (bs.readInt())
print(TextureOffsets)
print(FileCount % 4)
if(FileCount % 4 != 0):
bs.seek((4 - FileCount % 4)*4, NOESEEK_REL)
TextureNames = []
Files = []
for i in range(0, FileCount):
TextureNames.append(bs.readBytes(128).decode("UTF-8").rstrip("\0"))
bs = NoeBitStream(data)
bs.setEndian(NOE_BIGENDIAN)
bs.seek(TextureOffsets[0], NOESEEK_ABS)
for i in range(0, FileCount):
bs.seek(TextureOffsets[i], NOESEEK_ABS)
bs.seek(0x6, NOESEEK_REL)
FMT = bs.readBytes(1)
bs.seek(0x11, NOESEEK_REL)
NRML = bs.readBytes(1)
print(FMT)
print(NRML)
bs.seek(0x7, NOESEEK_REL)
imgWidth = bs.readShort()
imgHeight = bs.readShort()
print(imgWidth, "x", imgHeight)
bs.seek(0x5C, NOESEEK_REL)
if FMT == b'\x80':
data = bs.readBytes(imgWidth*imgHeight)
texFmt = noesis.NOESISTEX_DXT1
texList.append(NoeTexture(TextureNames[i], imgWidth, imgHeight, data, texFmt))
if FMT == b'\x40':
data = bs.readBytes(imgWidth*imgHeight)
texFmt = noesis.NOESISTEX_DXT3
texList.append(NoeTexture(TextureNames[i], imgWidth, imgHeight, data, texFmt))
if FMT == b'\00':
data = bs.readBytes(imgWidth*imgHeight)
texFmt = noesis.NOESISTEX_DXT5
texList.append(NoeTexture(TextureNames[i], imgWidth, imgHeight, data, texFmt))
if FMT == b'\00' and NRML == b'\85':
data = bs.readBytes(imgWidth*imgHeight*4)
data = rapi.imageDecodeRaw(data, imgWidth[0], imgHeight[0], "a8r8g8b8")
texFmt = noesis.NOESISTEX_RGB16
texList.append(NoeTexture(TextureNames[i], imgWidth, imgHeight, data, texFmt))
if FMT == b'\04':
data = bs.readBytes(imgWidth*imgHeight*4)
texFmt = noesis.NOESISTEX_DXT5
texList.append(NoeTexture(TextureNames[i], imgWidth, imgHeight, data, texFmt))
if FMT == b'\x10':
data = bs.readBytes(imgWidth*imgHeight)
texFmt = noesis.NOESISTEX_DXT5
texList.append(NoeTexture(TextureNames[i], imgWidth, imgHeight, data, texFmt))
print(TextureNames)
return 1
def pmdLoadModel(data, mdlList):
global boneList, texList, texNameList
boneList = []
texList = []
texNameList = []
baseName = rapi.getExtensionlessName(rapi.getLocalFileName(rapi.getLastCheckedName()))
texName = baseName
if baseName.endswith("glamour"):
texName = baseName[:-8]
elif baseName.endswith("slender"):
texName = baseName[:-8]
bs = NoeBitStream(data, NOE_BIGENDIAN)
bs.seek(0x10, NOESEEK_ABS) #PTR - Bone block
BoneBlock=bs.readBytes(3).decode("UTF-8")
print(BoneBlock)
bs.seek(0x05, NOESEEK_REL)
BoneCountOffset=bs.readInt()
print(BoneCountOffset)
BoneBlockSize = bs.readInt()
print(BoneBlockSize)
bs.seek(BoneCountOffset, NOESEEK_ABS)
BoneCount=bs.readInt()
print(BoneCount)
bs.seek(0xE, NOESEEK_REL)
bs.seek(8*BoneCount+42, NOESEEK_REL)
BoneNames = []
for i in range(0, BoneCount):
if(i == 0):
BoneNames.append ("ROOT")
bs.seek(0x20, NOESEEK_REL)
BoneParent=bs.readInt()
BoneChild=bs.readInt()
BoneUNK=bs.readInt()
BoneNULL=bs.readInt()
POS = NoeVec3.fromBytes(bs.readBytes(0xC))
bs.seek(0x4, NOESEEK_REL)
ROT = NoeAngles.fromBytes(bs.readBytes(0xC))
bs.seek(0x4, NOESEEK_REL)
SCL = NoeVec3.fromBytes(bs.readBytes(0xC))
bs.seek(0x4, NOESEEK_REL)
MTRX = ROT.toMat43()
MTRX[3] = POS;
MTRX[0][0] = SCL[0]
MTRX[1][1] = SCL[1]
MTRX[2][2] = SCL[2]
Bone = NoeBone(i, BoneNames[i], MTRX, BoneParent, -1)
boneList.append(Bone)
bs.seek(0x9C, NOESEEK_REL)
else:
BoneNames.append (bs.readBytes(32).decode("UTF-8").rstrip("\0"))
BoneParent=bs.readInt()
BoneChild=bs.readInt()
BoneUNK=bs.readInt()
BoneNULL=bs.readInt()
POS = NoeVec3.fromBytes(bs.readBytes(0xC))
bs.seek(0x4, NOESEEK_REL)
ROT = NoeAngles.fromBytes(bs.readBytes(0xC))
bs.seek(0x4, NOESEEK_REL)
SCL = NoeVec3.fromBytes(bs.readBytes(0xC))
bs.seek(0x4, NOESEEK_REL)
MTRX = ROT.toMat43()
MTRX[3] = POS;
MTRX[0][0] = SCL[0]
MTRX[1][1] = SCL[1]
MTRX[2][2] = SCL[2]
Bone = NoeBone(i, BoneNames[i], MTRX, BoneParent, -1)
boneList.append(Bone)
if(i == BoneCount-1): #last bone is C bytes shorter
bs.seek(0xB0, NOESEEK_REL)
else:
bs.seek(0xBC, NOESEEK_REL)
print(BoneNames)
MeshBlock=bs.readBytes(3).decode("UTF-8")
print(MeshBlock)
bs.seek(0xD, NOESEEK_REL)
MeshCount=bs.readInt()
print(MeshCount)
bs.seek(MeshCount*8+8, NOESEEK_REL)
ctx = rapi.rpgCreateContext()
rapi.rpgSetOption(noesis.RPGOPT_BIGENDIAN, 1)
MeshNames = []
MaterialInfo = []
for i in range(0, MeshCount):
bs.seek(0x10, NOESEEK_REL)
MeshNames.append (noeStrFromBytes(bs.readBytes(0x20), "UTF8"))
bs.seek(0x18, NOESEEK_REL)
VertCount = bs.readInt()
bs.seek(4, NOESEEK_REL)
VertSize = bs.readInt()
FaceSize = VertSize // VertCount
FaceIndexCount = bs.readInt()
bs.seek(4, NOESEEK_REL)
FaceIndexSize = bs.readInt()
IndexSize = FaceIndexSize // FaceIndexCount
bs.seek(0x58, NOESEEK_REL)
MeshOffset = bs.readInt()
bs.seek(0x84, NOESEEK_REL)
MeshOffset += bs.tell()
VData = bs.readBytes(VertSize)
IndexData = bs.readBytes(FaceIndexSize)
rapi.rpgSetName(MeshNames[i])
rapi.rpgBindPositionBuffer(VData, noesis.RPGEODATA_FLOAT, FaceSize)
rapi.rpgBindNormalBufferOfs(VData, noesis.RPGEODATA_SHORT, FaceSize, 0x10)
rapi.rpgBindUV1BufferOfs(VData, noesis.RPGEODATA_HALFFLOAT, FaceSize, 0x18)
if IndexSize == 1:
idxType = noesis.RPGEODATA_UBYTE
elif IndexSize == 2:
idxType = noesis.RPGEODATA_USHORT
else:
idxType = noesis.RPGEODATA_INT
rapi.rpgCommitTriangles(IndexData, idxType, FaceIndexCount, noesis.RPGEO_TRIANGLE_STRIP, 1)
rapi.rpgClearBufferBinds()
bs.seek(MeshOffset, NOESEEK_ABS)
print(MeshNames)
bs.seek(0x04, NOESEEK_REL)
MaterialBlock=noeStrFromBytes(bs.readBytes(3), "UTF8")
print(MaterialBlock)
bs.seek(0x09, NOESEEK_REL)
MaterialOffset=bs.readInt()
print(MaterialOffset)
MaterialCount=bs.readInt()
print(MaterialCount)
bs.seek(0xF, NOESEEK_REL)
bs.seek(MaterialCount*8+10, NOESEEK_REL)
bs.seek(MaterialOffset-13, NOESEEK_REL)
TextureBlock=noeStrFromBytes(bs.readBytes(3), "UTF8")
print(TextureBlock)
bs.seek(0xD, NOESEEK_REL)
TextureCount=bs.readInt()
print(TextureCount)
bs.seek(0xF, NOESEEK_REL)
bs.seek(TextureCount*8+41, NOESEEK_REL)
#textures are .gtf in a .pta file container with the same name as the model minus _glamour or _slender, no idea how to have Noesis open that file together with the model
TextureNames = []
for i in range(0, TextureCount):
TextureNames.append (noeStrFromBytes(bs.readBytes(40), "UTF8") + ".gtf")
bs.seek(0x148, NOESEEK_REL)
print(TextureNames)
if( rapi.checkFileExists( rapi.getDirForFilePath( rapi.getLastCheckedName() ) + texName + ".pta" ) ):
data = rapi.loadIntoByteArray( rapi.getDirForFilePath( rapi.getLastCheckedName() ) + texName + ".pta" )
ptaLoadRGBA(data, texList)
mdl = rapi.rpgConstructModel()
mdlList.append(mdl)
return 1