Skip to content
View in the app

A better way to browse. Learn more.

ResHax

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.
Help us keep the site running.

Problem with boneMatrix

Featured Replies

Solved by shak-otay

  • Supporter
  • Solution

First: wrong sub forum! That's not a graphic's format problem.

2nd: So this is Durik's script which you seem to have patched wrongly? (Since Durik's script usually work like a charm...)

---------------------------------

To get rid of this annoying "RuntimeError: Invalid type provided for bone matrix"

I made these changes (without knowing what I did exactly):

            elif ntype == 10:
                bs.seek(80, NOESEEK_REL);
                trfm = NoeMat44.fromBytes(bs.readBytes(0x40)).toMat43()
                #trfm = NoeMat44.fromBytes(bs.readBytes(64))
                bs.seek(80, NOESEEK_REL)
                print("trfm:", trfm)
                #bone = NoeBone(pidx, trfm, bonename)
                bone = NoeBone(len(bones), bonename, trfm, "dummy", -1)
                bones.append(bone)

(Be sure to replace the string "dummy" by a parent bonename variable, btw.)

Result:

 

PorkyPigSkel.png

Edited by shak-otay

  • Author

Ok thanks the parent variable is pidx but dont worry i rename but thanks 

  • Supporter

I don't understand why you clone topics (and from different accounts).

*( I already wrote to you that it is worth indicating the original author, even if you edit the original plugin)

having the complete structure that I researched and provided to you, you still did it your way and incorrectly

I made some minor edits (in reading nodes and creating bones), creating one model with a skeleton and meshes (and not all as separate models).

Spoiler

 

# edited plugin
# orig researcher Durik256 
# orig topic https://reshax.com/topic/959-looney-tunes-dash/?do=findComment&comment=4845
from inc_noesis import *

def registerNoesisTypes():
    handle = noesis.register("3d looney tunes dash", ".fmlb")
    noesis.setHandlerTypeCheck(handle, noepyCheckType)
    noesis.setHandlerLoadModel(handle, noepyLoadModel)
    
    noesis.logPopup()
    return 1

def noepyCheckType(data):
    bs = NoeBitStream(data)
    if noeAsciiFromBytes(bs.readBytes(4)) != '_FML':
        return 0
    return 1   

def noepyLoadModel(data, mdlList):
    bs = NoeBitStream(data)
    bs.seek(16)  # _FML + ver?
    count = bs.readInt()
    data_offset = bs.readInt()
    unk = bs.readInt()
    bs.seek(20, NOESEEK_REL)  # END> + 16bytes unk

    print("count:", count, "offset:", data_offset, "unk:", unk)

    skeletons = []
    subMeshes = []

    for x in range(count):
        type = bs.readUByte()
        bs.seek(11, NOESEEK_REL)
        name = searchString(bs)
        bs.seek(19 - len(name), NOESEEK_REL)
        bs.seek(44, NOESEEK_REL)
        offset = bs.readInt() + data_offset
        bs.seek(8, NOESEEK_REL)
        print("type", type, name, offset)
        if type == 102:
            skeletons.append(Skeleton(name, offset))
        elif type == 107:
            subMeshes.append(SubMesh(name, offset))

    mdl = NoeModel()

    #if not len(skeletons):
    #    print("Dont have skeleton")
    #    return 0

    for skel in skeletons:
        bs.seek(skel.offset)
        print(bs.getOffset())
        name = searchString(bs)
        bs.seek(63 - len(name), NOESEEK_REL)
        ndCount = bs.readInt()
        bs.seek(156, NOESEEK_REL)
        print(name, "ndcount:", ndCount)

        bones = []

        for _ in range(ndCount):
            ntype = bs.readInt()
            bonename = bs.read(64).split(b'\x00')[0].decode()#searchString(bs)
            #bs.seek(63 - len(bonename), NOESEEK_REL)
            bs.seek(16 + 28 + 16 + 4, NOESEEK_REL) #+ 2
            #pidx = bs.readShort()
            #tag = bs.readShort()
            #bs.seek(2 + 4, NOESEEK_REL)

            index = bs.readShort()
            dep = bs.readShort()
            strLen = bs.readShort()
            strLen2 = bs.readShort()
            unk = bs.readUInt()

            print("ntype:", ntype, "bonename:", bonename, "index:", index, "dep:", dep)

            if ntype == 1:
                #bs.seek(80 + tag, NOESEEK_REL)
                bs.seek(64 + 16 + strLen, 1)
            elif ntype == 2:
                #bs.seek(144, NOESEEK_REL)
                bs.seek(64 + 16 + 64, 1)
            elif ntype == 3:
                #bs.seek(208 + tag, NOESEEK_REL)
                bs.seek(64 + 144 + strLen, 1)
            elif ntype == 3:
                bs.seek(strLen, 1)
            elif ntype == 5:
                bs.seek(4, 1)
                ccou = bs.readInt()
                for _ in range(ccou):
                    bs.seek(16, 1)
            elif ntype == 6:
                bs.seek(64+strLen2, 1)
            elif ntype == 7:
                bs.seek(strLen, 1)
            elif ntype == 8:
                bs.seek(strLen + 64 + 16 + 64, 1)
            elif ntype == 9:
                bs.seek(16+24, NOESEEK_REL)
            elif ntype == 10:
                bs.seek(80, NOESEEK_REL)
                trfm = NoeMat44.fromBytes(bs.readBytes(64)).toMat43()
                bs.seek(80, NOESEEK_REL)
                print("trfm:", trfm)
                #bone = NoeBone(pidx, trfm, bonename)
                bone = NoeBone(index, bonename, trfm)
                bones.append(bone)
            elif ntype == 12:
                bs.seek(strLen, 1)
            elif ntype == 13:
                bs.seek(64+64+4+4, 1)
            elif ntype == 14:
                bs.seek(strLen + 64+16, 1)

        if bones:
            #mdl = NoeModel()
            mdl.setBones(bones)
            #mdlList.append(mdl)

    #if not len(subMeshes):
    #    print("Dont have mesh")
    #    return 0

    meshes = []
    for sm in subMeshes:
        bs.seek(sm.offset)
        print(bs.getOffset())
        name = searchString(bs)
        bs.seek(69 - len(name), NOESEEK_REL)
        iCount = bs.readInt()
        vCount = bs.readInt()
        unk1 = bs.readInt()
        unk2 = bs.readInt()
        bs.seek(126, NOESEEK_REL)
        print(name, "iCount", iCount, "vCount", vCount, unk1, unk2)

        indices = [bs.readUShort() for _ in range(iCount)]
        vert = []

        if bs.readShort() != 0:
            bs.seek(-2, NOESEEK_REL)

        for _ in range(vCount):
            vert.append(NoeVec3.fromBytes(bs.readBytes(12)))

        mesh = NoeMesh(indices, vert, name)#, "mat_0")
        #mdl = NoeModel([mesh])
        #mdlList.append(mdl)
        meshes.append(mesh)
        
    
    mdlList.append(mdl)
    mdl.setMeshes(meshes)
    print(bs.getOffset())
    return 1

def searchString(bs):
    bytes = []
    byte = None
    while byte != 0:
        byte = bs.readUByte()
        bytes.append(byte)
    return noeAsciiFromBytes(bytes)

class SubMesh:
    def __init__(self, name, offset):
        self.name = name
        self.offset = offset

class Skeleton:
    def __init__(self, name, offset):
        self.name = name
        self.offset = offset

as I wrote earlier. the game has a text analogue of fmlb, in fml format. looking inside it you can understand the structure in more detail. for example, the parameter "dep" (which you removed in the plugin) is responsible for the depth of the node, on its basis you can specify the parents of the bones by building the correct hierarchy

image.png

*(I think that's enough info for now. So this is the last message regarding fmlb.)

Edited by Durik256

  • Author

Ok ok but you finally implemented support for skeletons and thats if suficient for the moment very thanks and i prommes this is the last post about fmlb files starting now every new request related to fmlb files i going to post here forever

  • Supporter
On 7/14/2025 at 7:00 PM, Arfanu said:

I can load skeletons but i have problems loading bone weights

1. you are constructing the skeleton hierarchy incorrectly

2.you constantly ignore the structure that I provided you (see message above). if you look into it, you will see that there are 4 bytes for indexes "wi-vec4(ubyte)"

3. the error says in plain text: "unwanted object". look in  "inc_noeis.py" >> "class NoeVertWeight:"

 

fast fix u code: (without checking for functionality)

Spoiler
        bs.seek(idoffs)
        boneIndices = [[
            #NoeVec3((
                bs.readUByte(),
                bs.readUByte(),
                bs.readUByte() + bs.readUByte() * 0 # read and skip 4 indx
            #)) for _ in range(vCount)
            ] for _ in range(vCount)
        ]
        print(boneIndices)
        bs.seek(woffs)
        boneWeights = [[
            #NoeVec3((
                bs.readHalfFloat(),
                bs.readHalfFloat(),
                bs.readHalfFloat()
            #)) for _ in range(vCount)
            ] for _ in range(vCount)
        ]
        
        #combine indices and weights
        NoeVertWeightList = []
        for x in range(vCount):
            NoeVertWeightList.append(NoeVertWeight(boneIndices[x], boneWeights[x]))

 

*(and you need to build a bone map for bone indices)

 

Edited by Durik256

  • Supporter

@Durik256: without you, we would be lost. Thanks for your support and patience!

btw, I saw two lines

            elif ntype == 3:

in your fmlb code. Shouldn't the 2nd one compare to '4'?

Edited by shak-otay

  • Supporter
13 hours ago, shak-otay said:

in your fmlb code. Shouldn't the 2nd one compare to '4'?

yes you are right, it is a mistake) but these are quick edits of the topic author's code, that is, not the final version, he should have written his code based on this, and noticed what you noticed

  • Author

Here is the updated script (uncompleted) by #Durik256,every updated or news can be sended in this post

fmt_fmlb.zip

Create an account or sign in to comment

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.