The Forum is up for sale: XeNTaX Forum looking for new owner

Tron 2.0 Noesis Conversion not working

Post questions about game models here, or help out others!
Post Reply
photojoe
beginner
Posts: 23
Joined: Tue Jan 26, 2016 11:49 pm
Has thanked: 5 times
Been thanked: 1 time

Tron 2.0 Noesis Conversion not working

Post by photojoe »

I keep getting a failed to construct RPGEO Context in line 35, it's a call to noepyloadmodel. I attached the meshes that it won't view/convert.


Code: Select all

from inc_noesis import *
import noesis
import rapi
import os

def registerNoesisTypes():
    '''Register the plugin'''
    
    handle = noesis.register("Zu Online", ".ltb")
    noesis.setHandlerTypeCheck(handle, noepyCheckType)
    noesis.setHandlerLoadModel(handle, noepyLoadModel) #see also noepyLoadModelRPG
    return 1

def noepyCheckType(data):
    '''Verify that the format is supported by this plugin.'''
    
    if len(data) < 9:
        return 0
    try:
        bs = NoeBitStream(data)
        ver1 = bs.readShort()
        ver2 = bs.readShort()
        if ver1 != 1 or ver2 != 9:
            return 0
        return 1
    except:
        return 0

def noepyLoadModel(data, mdlList):
    '''Load the model'''
    
    ctx = rapi.rpgCreateContext()
    parser = ZuOnline_LTB(data)
    parser.parse_file()
    mdl = rapi.rpgConstructModel()
    mdlList.append(mdl)
    mdl.setModelMaterials(NoeModelMaterials(parser.texList, parser.matList))
    mdlList.append(mdl)
    return 1

class ZuOnline_LTB(object):
    
    def __init__(self, data):    
        self.inFile = NoeBitStream(data)
        self.animList = []
        self.texList = []
        self.matList = []
        self.boneList = []
        self.dirpath = rapi.getDirForFilePath(rapi.getInputName())
        self.texpath = self.dirpath + "texture\\"
        
    def basename(self):
        '''Returns the filename without extension'''
        
        filename = rapi.getLocalFileName(rapi.getInputName())
        basename, ext = os.path.splitext(filename)
        return basename    
        
    def read_name(self):
        
        string = self.inFile.readBytes(self.inFile.readUShort())
        try:
            return noeStrFromBytes(string)
        except:
            return string
            
    def parse_vertices(self, numVerts, meshType):
        
        print (self.inFile.tell())
        if meshType == 1:
            vertBuff = self.inFile.readBytes(numVerts * 32)
            rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 32, 0)
            rapi.rpgBindNormalBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 32, 12)
            rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 32, 24)
        elif meshType == 2:
            vertBuff = self.inFile.readBytes(numVerts * 36)
            rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 36, 0)
            rapi.rpgBindNormalBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 36, 16)
            rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 36, 28)
        elif meshType == 3:
            vertBuff = self.inFile.readBytes(numVerts * 40)
            rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 40, 0)
            rapi.rpgBindNormalBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 40, 20)
            rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 40, 32)
        elif meshType == 4:
            vertBuff = self.inFile.readBytes(numVerts * 44)
            rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 44, 0)
            rapi.rpgBindNormalBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 44, 24)
            rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 44, 36)
        else:
            print("unknown meshType: %d" %meshType)        

    def parse_faces(self, numIdx):
        
        return self.inFile.readBytes(numIdx * 2)
    
    def parse_unk(self):
        
        count = self.inFile.readUInt()
        self.inFile.seek(count*12, 1)
        
    def create_material(self, matNum):
        
        matName = "material[%d]" %matNum
        if matNum == 1:
            texName = self.texpath + self.basename() + ".dtx"
        elif matNum == 2:
            texName = self.texpath + self.basename() + "_a.dtx" 
        elif matNum == 3:
            texName = self.texpath + self.basename() + "_b.dtx"
        elif matNum == 4:
            texName = self.texpath + self.basename() + "_c.dtx"
        elif matNum == 5:
            texName = self.texpath + self.basename() + "_a.dtx"
        elif matNum == 6:
            texName = self.texpath + self.basename() + "_a.dtx"
        else:
            print(matNum)
            texName = ""
        
        material = NoeMaterial(matName, texName)
        self.matList.append(material)
        return matName
    
    def parse_submesh(self, numSubmesh):
        
        print (self.inFile.tell())
        for i in range(numSubmesh):
            self.inFile.readUInt()
            matNum = self.inFile.readUInt()
            self.inFile.read('4L')
            self.inFile.readByte()
            unk1 = self.inFile.readUInt()
            sectionSize = self.inFile.readUInt()
            
            #sectionSize could be 0
            if sectionSize:
                start = self.inFile.tell()
                numVerts = self.inFile.readUInt()
                numIdx = self.inFile.readUInt() * 3
                meshType = self.inFile.readUInt()
                self.inFile.read('5L')
       
                if unk1 == 4:
                    self.inFile.readUInt()
                elif unk1 == 5:
                    self.inFile.readUShort()
                
                self.parse_vertices(numVerts, meshType)
                idxBuff = self.parse_faces(numIdx)
                
                #just seeking past unknowns rather than parse the unknown
                curr = self.inFile.tell() - start
                remain = sectionSize - curr
                self.inFile.seek(remain, 1)
    
                unk2 = self.inFile.readByte()
                self.inFile.seek(unk2, 1)
                
                
                matName = self.create_material(matNum)
                #rapi.rpgSetMaterial(matName)
                #rapi.rpgCommitTriangles(idxBuff, noesis.RPGEODATA_USHORT, numIdx, noesis.RPGEO_TRIANGLE, 1)
    
    def parse_mesh(self, numMesh):
        
        for i in range(numMesh):
            meshName = self.read_name()
            numSubmesh = self.inFile.readUInt()
            for j in range(numSubmesh):
                self.inFile.readFloat()
            self.inFile.read('2L')
            self.parse_submesh(numSubmesh)
            
    def parse_file(self):
        
        self.inFile.read('2H')
        self.inFile.read('4L')
        version = self.inFile.readUInt()
        self.inFile.read('2L')
        numBones = self.inFile.readUInt()
        self.inFile.read('10L')
        self.inFile.read('2H') #large number
        self.inFile.readUInt()
        self.read_name()
        self.inFile.readFloat()
        self.inFile.readUInt()
        numMesh = self.inFile.readUInt()
        self.parse_mesh(numMesh)
You do not have the required permissions to view the files attached to this post.
User avatar
shakotay2
MEGAVETERAN
MEGAVETERAN
Posts: 4231
Joined: Fri Apr 20, 2012 9:24 am
Location: Nexus, searching for Jim Kirk
Has thanked: 1139 times
Been thanked: 2222 times

Re: Tron 2.0 Noesis Conversion not working

Post by shakotay2 »

Why do you think this script could load Tron 2.0 .ltb files? (Try search "Lithtech" ltb, maybe you'll get some valid info.)
For both ltbs you provided the numMesh count is 0 with this script.

Use script from here:
mariokart64n wrote: Sun Jun 21, 2020 7:09 pm
Will load the seeker at least.

(For Kernel_Death.ltb we get an error, as the name tells. :D )
Tuts: a) Bigchillghost, viewtopic.php?f=29&t=17889
b) Extracting simple models: http://forum.xentax.com/viewtopic.php?f=29&t=10894
"Quoting the whole thing. Would u ever stop this nonsense?"
photojoe
beginner
Posts: 23
Joined: Tue Jan 26, 2016 11:49 pm
Has thanked: 5 times
Been thanked: 1 time

Re: Tron 2.0 Noesis Conversion not working

Post by photojoe »

Because it works on all but those post meshes, the LTB files are Lilthtech Game engine mesh files.
However I do not understand why it glitches out on some but not all.

Tried this script and did the same thing, threw the error on the files in that zip I posted, but everything else works.

Code: Select all

from inc_noesis import *
import noesis
import rapi
import os

def registerNoesisTypes():
    '''Register the plugin'''

    handle = noesis.register("Zu Online", ".ltb")
    noesis.setHandlerTypeCheck(handle, noepyCheckType)
    noesis.setHandlerLoadModel(handle, noepyLoadModel) #see also noepyLoadModelRPG
    return 1

def noepyCheckType(data):
    '''Verify that the format is supported by this plugin.'''
    
    if len(data) < 9:
        return 0
    try:
        bs = NoeBitStream(data)
        ver1 = bs.readShort()
        ver2 = bs.readShort()
        if ver1 != 1 or ver2 != 9:
            return 0
        return 1
    except:
        return 0

def noepyLoadModel(data, mdlList):
    '''Load the model'''
    
    ctx = rapi.rpgCreateContext()
    parser = ZuOnline_LTB(data)
    parser.parse_file()
    mdl = rapi.rpgConstructModel()
    mdlList.append(mdl)
    mdl.setModelMaterials(NoeModelMaterials(parser.texList, parser.matList))
    mdlList.append(mdl)
    return 1

class ZuOnline_LTB(object):
    
    def __init__(self, data):    
        self.inFile = NoeBitStream(data)
        self.animList = []
        self.texList = []
        self.matList = []
        self.boneList = []
        self.dirpath = rapi.getDirForFilePath(rapi.getInputName())
        self.texpath = self.dirpath + "texture\\"
        
    def basename(self):
        '''Returns the filename without extension'''
        
        filename = rapi.getLocalFileName(rapi.getInputName())
        basename, ext = os.path.splitext(filename)
        return basename    
        
    def read_name(self):
        
        string = self.inFile.readBytes(self.inFile.readUShort())
        try:
            return noeStrFromBytes(string)
        except:
            return string
            
    def parse_vertices(self, numVerts, meshType):
        
        print (self.inFile.tell())
        if meshType == 1:
            vertBuff = self.inFile.readBytes(numVerts * 32)
            rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 32, 0)
            rapi.rpgBindNormalBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 32, 12)
            rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 32, 24)
        elif meshType == 2:
            vertBuff = self.inFile.readBytes(numVerts * 36)
            rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 36, 0)
            rapi.rpgBindNormalBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 36, 16)
            rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 36, 28)
        elif meshType == 3:
            vertBuff = self.inFile.readBytes(numVerts * 40)
            rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 40, 0)
            rapi.rpgBindNormalBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 40, 20)
            rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 40, 32)
        elif meshType == 4:
            vertBuff = self.inFile.readBytes(numVerts * 44)
            rapi.rpgBindPositionBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 44, 0)
            rapi.rpgBindNormalBufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 44, 24)
            rapi.rpgBindUV1BufferOfs(vertBuff, noesis.RPGEODATA_FLOAT, 44, 36)
        else:
            print("unknown meshType: %d" %meshType)        

    def parse_faces(self, numIdx):
        
        return self.inFile.readBytes(numIdx * 2)
    
    def parse_unk(self):
        
        count = self.inFile.readUInt()
        self.inFile.seek(count*12, 1)
        
    def create_material(self, matNum):
        
        matName = "material[%d]" %matNum
        if matNum == 1:
            texName = self.texpath + self.basename() + ".dtx"
        elif matNum == 2:
            texName = self.texpath + self.basename() + "_a.dtx" 
        elif matNum == 3:
            texName = self.texpath + self.basename() + "_b.dtx"
        elif matNum == 4:
            texName = self.texpath + self.basename() + "_c.dtx"
        elif matNum == 5:
            texName = self.texpath + self.basename() + "_a.dtx"
        elif matNum == 6:
            texName = self.texpath + self.basename() + "_a.dtx"
        else:
            print(matNum)
            texName = ""
        
        material = NoeMaterial(matName, texName)
        self.matList.append(material)
        return matName
    
    def parse_submesh(self, numSubmesh):
        
        print (self.inFile.tell())
        for i in range(numSubmesh):
            self.inFile.readUInt()
            matNum = self.inFile.readUInt()
            self.inFile.read('4L')
            self.inFile.readByte()
            unk1 = self.inFile.readUInt()
            sectionSize = self.inFile.readUInt()
            
            #sectionSize could be 0
            if sectionSize:
                start = self.inFile.tell()
                numVerts = self.inFile.readUInt()
                numIdx = self.inFile.readUInt() * 3
                meshType = self.inFile.readUInt()
                self.inFile.read('5L')
       
                if unk1 == 4:
                    self.inFile.readUInt()
                elif unk1 == 5:
                    self.inFile.readUShort()
                
                self.parse_vertices(numVerts, meshType)
                idxBuff = self.parse_faces(numIdx)
                
                #just seeking past unknowns rather than parse the unknown
                curr = self.inFile.tell() - start
                remain = sectionSize - curr
                self.inFile.seek(remain, 1)
    
                unk2 = self.inFile.readByte()
                self.inFile.seek(unk2, 1)
                
                
                matName = self.create_material(matNum)
                #rapi.rpgSetMaterial(matName)
                #rapi.rpgCommitTriangles(idxBuff, noesis.RPGEODATA_USHORT, numIdx, noesis.RPGEO_TRIANGLE, 1)
    
    def parse_mesh(self, numMesh):
        
        for i in range(numMesh):
            meshName = self.read_name()
            numSubmesh = self.inFile.readUInt()
            for j in range(numSubmesh):
                self.inFile.readFloat()
            self.inFile.read('2L')
            self.parse_submesh(numSubmesh)
            
    def parse_file(self):
        
        self.inFile.read('2H')
        self.inFile.read('4L')
        version = self.inFile.readUInt()
        self.inFile.read('2L')
        numBones = self.inFile.readUInt()
        self.inFile.read('10L')
        self.inFile.read('2H') #large number
        self.inFile.readUInt()
        self.read_name()
        self.inFile.readFloat()
        self.inFile.readUInt()
        numMesh = self.inFile.readUInt()
        self.parse_mesh(numMesh)
User avatar
shakotay2
MEGAVETERAN
MEGAVETERAN
Posts: 4231
Joined: Fri Apr 20, 2012 9:24 am
Location: Nexus, searching for Jim Kirk
Has thanked: 1139 times
Been thanked: 2222 times

Re: Tron 2.0 Noesis Conversion not working

Post by shakotay2 »

why do you post the same script again?
Tuts: a) Bigchillghost, viewtopic.php?f=29&t=17889
b) Extracting simple models: http://forum.xentax.com/viewtopic.php?f=29&t=10894
"Quoting the whole thing. Would u ever stop this nonsense?"
photojoe
beginner
Posts: 23
Joined: Tue Jan 26, 2016 11:49 pm
Has thanked: 5 times
Been thanked: 1 time

Re: Tron 2.0 Noesis Conversion not working

Post by photojoe »

One was dedicated to Lilithtech, this one was Zu-Online script for ltb files, their identical but I thought maybe I missed something that you could point out.

There is no difference i can see between the two, and you ask if the ZuOnline could handle it. When you said the Seeker would load for you, I was surprised as that file didn't work on my side
User avatar
shakotay2
MEGAVETERAN
MEGAVETERAN
Posts: 4231
Joined: Fri Apr 20, 2012 9:24 am
Location: Nexus, searching for Jim Kirk
Has thanked: 1139 times
Been thanked: 2222 times

Re: Tron 2.0 Noesis Conversion not working

Post by shakotay2 »

photojoe wrote: Sat May 15, 2021 10:17 pmWhen you said the Seeker would load for you, I was surprised as that file didn't work on my side
The Seeker is loaded by the script from mariokart64n whose post I linked to. [roll]
In this post, click on the up-arrow.
shakotay2 wrote: Sat May 15, 2021 9:15 pm
.
Seeker.png
You do not have the required permissions to view the files attached to this post.
Tuts: a) Bigchillghost, viewtopic.php?f=29&t=17889
b) Extracting simple models: http://forum.xentax.com/viewtopic.php?f=29&t=10894
"Quoting the whole thing. Would u ever stop this nonsense?"
photojoe
beginner
Posts: 23
Joined: Tue Jan 26, 2016 11:49 pm
Has thanked: 5 times
Been thanked: 1 time

Re: Tron 2.0 Noesis Conversion not working

Post by photojoe »

Got it, didn't see the link originally must of blew past it. Thanks.

I have the seeker, but the Mesh files still throw an error.
Post Reply