Going well so far. Could I get some help with the Rigs?
As far as I can see there are 7 offsets listed at the bottom of the header. The second and third one seem to be some kind of parenting information. But I can't tell which one contains position information. Any help would be great.
I also updated the script. The locations where the vertex and index counts are defined are different for every model, so I just added a place to put the TSBS locations to grab the counts and "s" defines which submesh to load. Also some rig experiments. Clearly, its very messy. It is also currently set up for the mesh in this post.
Code: Select all
#Noesis Python model import+export test module, imports/exports some data from/to a made-up format
from inc_noesis import *
import noesis
#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("Brutal Legend", ".MeshFix")
noesis.setHandlerTypeCheck(handle, noepyCheckType)
noesis.setHandlerLoadModel(handle, noepyLoadModel) #see also noepyLoadModelRPG
#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 = "hsem"
#check if it's this type based on the data
def noepyCheckType(data):
bs = NoeBitStream(data)
if len(data) > 16:
return 1
#if bs.readBytes(32).decode("ASCII").rstrip("\0") != NOEPY_HEADER:
# return 0
#return 1
#load the model
def noepyLoadModel(data, mdlList):
ctx = rapi.rpgCreateContext()
bs = NoeBitStream(data)
#bs.seek(0x54, NOESEEK_ABS) #Seek to header info
#Manual Entery Required!
MatCountLOC = (84)
tsbsLOC = [592, 696, 814, 915, 1046, 1177, 1277, 1391, 1491, 1617, 1729, 1829, 1930, 2031, ]
MeshStart = [2135]
bs.seek(MatCountLOC, NOESEEK_ABS)
MatCount = bs.read("L")
MatNames = []
#Do GETMATNAMES - Static
for i in range(0, MatCount[0]):
pos = bs.tell()
print(pos)
MatCharCount = bs.readUInt()#Materials are in Model Order
MatNames.append (bs.readBytes(MatCharCount).decode("ASCII").rstrip("\0"))
print(MatNames)
VertCount = []
FaceCount = []
FaceType = []
VertType = []
MatID = []
MeshCount = bs.read("I")
print(MeshCount)
for i in range(0, MeshCount[0]):
bs.seek(tsbsLOC[i], NOESEEK_ABS)
ReadSBST = bs.readUInt()
MatID.append (bs.readUInt())
MeshID = bs.readUInt()
BVXD = bs.readUInt()
#if VertBuffSig != CorrectVertBuffSig
#noesis.doException("VertSig Incorrect" + repr(VertBuffSig))
#pos = bs.tell()
#print("Got Vert From", pos)
VertCount.append (bs.readUInt())
VertType.append (bs.readUInt())
bs.seek(2, NOESEEK_REL)
BIXD = bs.readUInt()
Nothing = bs.readUInt()
pos = bs.tell()
print("Got Face From", pos)
FaceCount.append (bs.readUInt())
FaceType.append (bs.readUInt())
print("Vert Count:", VertCount)
print("Vert Type:", VertType)
print("Face Count:", FaceCount)
print("Face Type:", FaceType)
pos = bs.tell()
print(pos)
#Do Bones We rig. Now
if VertType[0] == 1024:
rigFile = rapi.loadPairedFile("Brutal Legend", ".RigHeader")
rig = NoeBitStream(rigFile)
boneList = []
Blank2 = rig.readUInt()
Float1 = rig.readHalfFloat()
Float2 = rig.readHalfFloat()
Float3 = rig.readHalfFloat()
Float4 = rig.readHalfFloat()
BoneNameSize = rig.readUInt()
BoneCount = rig.read("L")
UNK3 = rig.readUInt()
UNK4 = rig.readUInt()
UNK5 = rig.readUInt()
UNK6 = rig.readUInt()
UNK7 = rig.readUInt()
UNK8 = rig.readUInt()
UNK9 = rig.readUInt()
UNK10 = rig.readUInt()
UNK11 = rig.readUInt()
Float6 = rig.readFloat()
UNK12 = rig.readUInt()
UNK13 = rig.readUInt()
UNK14 = rig.readUInt()
rig.seek(76, NOESEEK_ABS)
Offset1 = rig.readUInt()
Offset2 = rig.readUInt()
Offset3 = rig.readUInt()
Offset4 = rig.readUInt()
Offset5 = rig.readUInt()
Offset6 = rig.readUInt()
Offset7 = rig.readUInt()
Blank2 = rig.readUInt()
pos = rig.tell()
print("I am At", pos, "For RigSig")
print(BoneCount)
RigSig = rig.readUInt()
print("The Rig Sig is", RigSig)
print("RigNameSizeIs", BoneNameSize)
rigSource = rapi.loadPairedFile("Brutal Legend", ".RigFix")
rigsource = NoeBitStream(rigSource)
BoneNames = []
BoneNames.append (rigsource.readBytes(BoneNameSize).decode("ASCII").rstrip("\0"))
print("Bone Names", BoneNames)
print(Offset1)
rigsource.seek(Offset5, NOESEEK_ABS)
BoneID = []
boneList2 = list(boneList)
pos = rigsource.tell()
print("First", pos)
for i in range(0, BoneCount[0]):
#rigsource.seek(2, NOESEEK_REL)
#pos = rigsource.tell()
#print("First1", pos)
#Gibber = rigsource.readUInt()
BONE_XPOS = rigsource.readHalfFloat()
BONE_YPOS = rigsource.readHalfFloat()
BONE_ZPOS = rigsource.readHalfFloat()
#pos = rigsource.tell()
#print("First2", pos)
BoneID.append (i)
quat = NoeQuat([0, 0, 0, 1])
mat = quat.toMat43()
mat[3] = [BONE_XPOS, BONE_YPOS, BONE_ZPOS]
boneList2.append(NoeBone(i, "bone%03i"%i, mat, None, BoneID[i]))
boneList = rapi.multiplyBones(boneList2)
#pos = rigsource.tell()
#print("First3", pos)
bs.seek(MeshStart[0], NOESEEK_ABS)
VertBuff = []
FaceBuff = []
BoneBuff = []
s = int(3)
if VertType[s] == 512:
for i in range(0, MeshCount[0]):
pos = bs.tell()
print("Where Am I?", pos)
VertBuff.append (bs.readBytes(VertCount[i] * 40))
pos = bs.tell()
print("VertDone, Where Am I?", pos)
FaceBuff.append (bs.readBytes(FaceCount[i] * 0x02))
pos = bs.tell()
print("FaceDone, Where Am I?", pos)
if VertType[s] == 1024:
for i in range(0, MeshCount[0]):
pos = bs.tell()
print("Where Am I?", pos)
#BlockUNK1 = bs.readUInt()
#BlockUNK2 = bs.readUInt()
pos = bs.tell()
print("VertBegin, Where Am I?", pos)
VertBuff.append (bs.readBytes(VertCount[i] * 48))
pos = bs.tell()
print("VertDone, FaceBegin, Where Am I?", pos)
FaceBuff.append (bs.readBytes(FaceCount[i] * 0x02))
pos = bs.tell()
print("FaceDone, Where Am I?", pos)
if VertType[s] == 512:
rapi.rpgBindPositionBufferOfs(VertBuff[s], noesis.RPGEODATA_HALFFLOAT, 40, 0)
rapi.rpgBindNormalBufferOfs(VertBuff[s], noesis.RPGEODATA_HALFFLOAT, 40, 16)
#rapi.rpgBindColorBuffer(VertBuff[s], noesis.RPGEODATA_HALFFLOAT, 40, 20, 3)
rapi.rpgBindUV1BufferOfs(VertBuff[s], noesis.RPGEODATA_HALFFLOAT, 40, 24)
rapi.rpgBindUV2BufferOfs(VertBuff[s], noesis.RPGEODATA_HALFFLOAT, 40, 32)
print("Buffered")
#VertBuff = None
#bs.seek(-216, NOESEEK_REL)
#VertBlockFix = bs.read(FirstVertBlock * 40)
#bs.seek(FirstVertBlock)
#rapi.rpgCommitTriangles(None, noesis.RPGEODATA_USHORT, VertCount[i], noesis.RPGEO_POINTS, 1)
if VertType[s] == 1024:
print("Buffering")
rapi.rpgBindPositionBufferOfs(VertBuff[s], noesis.RPGEODATA_HALFFLOAT, 48, 8)
rapi.rpgBindNormalBufferOfs(VertBuff[s], noesis.RPGEODATA_HALFFLOAT, 48, 32)
rapi.rpgBindUV1BufferOfs(VertBuff[s], noesis.RPGEODATA_HALFFLOAT, 48, 16)
rapi.rpgBindUV2BufferOfs(VertBuff[s], noesis.RPGEODATA_HALFFLOAT, 48, 24)
#VertBuff = None
#bs.seek(-216, NOESEEK_REL)
#VertBlockFix = bs.read(FirstVertBlock * 40)
#bs.seek(FirstVertBlock)
#rapi.rpgCommitTriangles(None, noesis.RPGEODATA_USHORT, VertCount[i], noesis.RPGEO_POINTS, 1)
if FaceType[s] == 2:
rapi.rpgCommitTriangles(FaceBuff[s], noesis.RPGEODATA_USHORT, FaceCount[s], noesis.RPGEO_TRIANGLE, 1)
else:
rapi.rpgCommitTriangles(FaceBuff[s], noesis.RPGEODATA_USHORT, FaceCount[s], noesis.RPGEO_TRIANGLE_STRIP, 1)
mdl = rapi.rpgConstructModel()
mdlList.append(mdl) #important, don't forget to put your loaded model in the mdlList
mdl.setBones(boneList)
rapi.rpgClearBufferBinds()
rapi.rpgSetMaterial(MatNames[0])
material = NoeMaterial(MatNames, "")
material.setTexture(MatNames[0])
MatNames.append(material)
#print(MatCharCount)
rapi.rpgClearBufferBinds()
return 1