Working on it... But struggling with decompression via noesis. You need to use BMS first to decompress *.XMD. Or maybe i'll figure out. EDiT: Figured out. Now you don't need to decompress model... Here we go... # Script by h3x3r
from inc_noesis import *
import noesis
import rapi
import os
def registerNoesisTypes():
handle = noesis.register("Deadly Premonition - XMD Mesh", ".xmd")
noesis.setHandlerTypeCheck(handle, noepyCheckType)
noesis.setHandlerLoadModel(handle, noepyLoadModel)
noesis.logPopup()
return 1
def noepyCheckType(data):
bs = NoeBitStream(data)
bs.read(8)
CSize = bs.readUInt()
Size = bs.readUInt()
Buffer = bs.read(CSize)
data = rapi.decompInflate(Buffer,Size)
bs = NoeBitStream(data)
if len(data) < 20:
return 0
if bs.readUInt() != 0x33444D58:
return 0
return 1
def noepyLoadModel(data, mdlList):
bs = NoeBitStream(data)
bs.read(8)
CSize = bs.readUInt()
Size = bs.readUInt()
Buffer = bs.read(CSize)
data = rapi.decompInflate(Buffer,Size)
bs = NoeBitStream(data)
baseName = rapi.getExtensionlessName(rapi.getLocalFileName(rapi.getInputName()))
ctx = rapi.rpgCreateContext()
Underline = "_"
# Main Info
Sign = bs.read(4)
ResourceSize = bs.readUInt()
TotalIndexCount = bs.readUInt()
TotalElementCount = bs.readUInt()
Unknown_2 = bs.readUInt()
Reserved0 = bs.read(20)
Unknown_3 = bs.readUShort()
BoneCount = bs.readUShort()
ShapeCount = bs.readUInt()
Unknown_4 = bs.readUInt()
Unknown_5 = bs.readUByte()
Unknown_6 = bs.readUByte()
Unknown_7 = bs.readUByte()
Unknown_8 = bs.readUByte()
Unknown_9 = bs.readUByte()
ElementStride = bs.readUByte()
NormalSkinStride = bs.readUByte()
Unknown_12 = bs.readUByte()
Reserved1 = bs.readUInt()
BBoxMin = bs.read(12)
BBoxMax = bs.read(12)
Unknown_13 = bs.readUShort()
Unknown_14_Count = bs.readUShort()
Unknown_15 = bs.readUInt()
Unknown_16 = bs.readUInt()
MaterialDefOffset = bs.readUInt()
BoneDefOffset = bs.readUInt()
ShapeDefOffset = bs.readUInt()
Unknown_17 = bs.readUInt()
Unknown_18 = bs.readUInt()
UnknownDefOffset = bs.readUInt()
Reserved2 = bs.read(16)
IndexBufferBaseOffset = bs.readUInt()
ElementBufferBaseOffset = bs.readUInt()
NormalSkinBufferBaseOffset = bs.readUInt()
Reserved3 = bs.read(16)
Unknown_14_Offset = bs.readUInt()
print("Element Stride >",ElementStride,"NormalSkin Stride >",NormalSkinStride)
# Material Info
bs.seek(MaterialDefOffset, NOESEEK_ABS)
MaterialName = bs.readString()
rapi.rpgSetMaterial(MaterialName)
# Shape Info
bs.seek(ShapeDefOffset, NOESEEK_ABS)
for i in range(0, ShapeCount):
StrPos = bs.tell()
ShapeName = bs.readString()
bs.seek(StrPos, NOESEEK_ABS)
bs.read(16)
Unknown_0 = bs.readShort()
BoneId = bs.readShort()
Unknown_2 = bs.readUInt()
Unknown_3 = bs.readUInt()
BBoxMin = bs.read(12)
BBoxMax = bs.read(12)
IndexCount = bs.readUInt()
ElementCount = bs.readUInt()
IndexOffset = bs.readUInt() * 2
ElementOffset = bs.readUInt()
Unknown_4 = bs.readUInt()
Reserved = bs.read(8)
cPos = bs.tell()
bs.seek(ElementBufferBaseOffset + (ElementOffset * ElementStride), NOESEEK_ABS)
ElementBuffer = bs.read(ElementCount * ElementStride)
if ElementStride == 20:
rapi.rpgBindPositionBufferOfs(ElementBuffer, noesis.RPGEODATA_HALFFLOAT, 20, 0)
rapi.rpgBindUV1BufferOfs(ElementBuffer, noesis.RPGEODATA_HALFFLOAT, 20, 8)
elif ElementStride == 24:
rapi.rpgBindPositionBufferOfs(ElementBuffer, noesis.RPGEODATA_FLOAT, 24, 0)
rapi.rpgBindUV1BufferOfs(ElementBuffer, noesis.RPGEODATA_HALFFLOAT, 24, 12)
bs.seek(NormalSkinBufferBaseOffset + (ElementOffset * NormalSkinStride), NOESEEK_ABS)
NormalSkinBuffer = bs.read(ElementCount * NormalSkinStride)
if NormalSkinStride == 12:
rapi.rpgBindNormalBufferOfs(NormalSkinBuffer, noesis.RPGEODATA_HALFFLOAT, 12, 0)
rapi.rpgBindBoneWeightBufferOfs(NormalSkinBuffer, noesis.RPGEODATA_HALFFLOAT, 12, 6, 3)
elif NormalSkinStride == 16:
rapi.rpgBindNormalBufferOfs(NormalSkinBuffer, noesis.RPGEODATA_HALFFLOAT, 16, 0)
rapi.rpgBindBoneWeightBufferOfs(NormalSkinBuffer, noesis.RPGEODATA_HALFFLOAT, 16, 8, 3)
bs.seek(IndexBufferBaseOffset + IndexOffset, NOESEEK_ABS)
IndexBuffer = bs.read(IndexCount * 2)
rapi.rpgSetStripEnder(0xFFFF)
rapi.rpgSetName(ShapeName)
rapi.rpgCommitTriangles(IndexBuffer, noesis.RPGEODATA_USHORT, IndexCount, noesis.RPGEO_TRIANGLE_STRIP)
bs.seek(cPos, NOESEEK_ABS)
mdl = rapi.rpgConstructModel()
mdlList.append(mdl)
return 1No skin/bones/skeleton. Could be done later...