TMB Blender Importer

Status
Not open for further replies.
Joined
Aug 27, 2006
Messages
223
Reaction score
189
This came about by a request from archonus months ago. I had a few hours of free time today and voila. Importing of textures and armatures is still outstanding and will have to wait until time permits.

Installation:
  1. Download and install Blender 2.46+ from Blender.org
  2. Download and install Python 2.5.x from (Windows Users)
  3. Unzip contents of tmb_import.zip
  4. Copy tmb_import.py into your Blender scripts directory.

Usage:
  1. Click File > Import > Tantra Online (*.tmb)...
  2. Select *.tmb file
  3. Click Ok

License:

​

Source:
Copy and save as tmb_import.py​

Code:
#!BPY

# Copyright (c) 2008-2012 AJ
# 
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# 
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
# 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.


"""
Name: 'Tantra Online (*.tmb)...'
Blender: 246
Group: 'Import'
Tooltip: 'Import Tantra Online *.tmb game files'
"""

__author__ = 'AJ'
__email__ = ''
__url__ = ('blender', 'elysiun', 'Project homepage, http://www.ragezone.com/')
__version__ = '0.0.1'
__bpydoc__ = """ \
This script imports Tantra Online *.tmb game files
"""


import Blender
import struct


def tmb_read_mesh(file_object, revision):
    data_chunk = file_object.read(256) # Read mesh name
    
    name = data_chunk[0:data_chunk.find('\0', 0)]
#    
#    print "mesh %s start 0x%x" % (name, file_object.tell() - 256)
    
    data_chunk = file_object.read(4) # Read vertex count
    
    vertex_count = struct.unpack('<I', data_chunk)[0]
    
    print "\tvertex count %d" % vertex_count
    
    mesh_object = Blender.Object.New('Mesh', name)
    
    mesh = mesh_object.getData(mesh = True)
    
    if mesh is None:
        mesh = Blender.Mesh.New(name)
        
        mesh_object.link(mesh)
    
    mesh.vertexUV = True
    
    data_chunk = file_object.read(vertex_count * 12) # Read vertex positions
    
    for x in xrange(vertex_count): # Build point list
        #data_chunk = file_object.read(12)
        
        position = Blender.Mathutils.Vector(struct.unpack_from('<3f', data_chunk, x * 12))
        
        mesh.verts.extend(position)
    
    for x in xrange(vertex_count): # Read vertex normals
        data_chunk = file_object.read(12)
        
        normal = Blender.Mathutils.Vector(struct.unpack('<3f', data_chunk))
        
        vertex = mesh.verts[x]
        
        vertex.no = normal
    
    for x in xrange(vertex_count): # Read texture coordinates
        data_chunk = file_object.read(8)
        
        uv_coordinates = Blender.Mathutils.Vector(struct.unpack('<2f', data_chunk))
        
        vertex = mesh.verts[x]
        
        vertex.uvco = uv_coordinates
    
    data_chunk = file_object.read(4)
    
    matrix_count = struct.unpack('<I', data_chunk)[0]
#    
#    print "\tmatrix count %d" % matrix_count
    
    if matrix_count > 1:
        data_chunk = file_object.read(4 * (matrix_count - 1))
    
    for x in xrange(matrix_count):
        data_chunk = file_object.read(64) # Read matrix
    
    data_chunk = file_object.read(12)
    
    x_count, face_count = struct.unpack_from('<2I', data_chunk, 4)
    
    if matrix_count > 1:
        data_chunk = file_object.read(4 * (matrix_count - 1))
#    
#    print "\tface count %d, %d" % (x_count, face_count)
    
    for x in xrange(face_count):
        data_chunk = file_object.read(12)
        
        face_vertices = [mesh.verts[y] for y in struct.unpack('<3I', data_chunk)]
        
        mesh.faces.extend(face_vertices)
        
        face = mesh.faces[-1]
        
        face.uv = [vertex.uvco for vertex in face_vertices]
    
    for x in xrange(matrix_count):
        data_chunk = file_object.read(256) # Read texture file name
        
        texture_file_name = data_chunk[0:data_chunk.find('\0', 0)]
#        
#        print "\ttexture %d: %s" % (x, texture_file_name)
    
    data_chunk = file_object.read(40)
    
    if revision == 2:
        data_chunk = file_object.read(8)
        
        bone_count, rename_me_0 = struct.unpack('<2I', data_chunk) # Read bone count
#        
#        print "\tbone count %d" % bone_count
        
        bones = []
        
        for x in xrange(bone_count):
            data_chunk = file_object.read(256)
            
            bone_name = data_chunk[0:data_chunk.find('\0', 0)]
            
            bones.append(bone_name)
            
            mesh.addVertGroup(bone_name)
#            
#            print "\t\tbone %s" % bone_name
        
        rename_me_1 = []
        
        total = 0
        totalx = 0
        
        for x in xrange(rename_me_0):
            data_chunk = file_object.read(4)
            
            y = struct.unpack('<I', data_chunk)[0]
            
            totalx = totalx + y
            
            rename_me_1.append(y)
            
            total = total + 1
        
        print "total = %d, totalx = %d" % (total, totalx)
        
        bone_influences = []
        
        for rename_me in rename_me_1:
            for x in xrange(rename_me):
                data_chunk = file_object.read(8)
                
                bone_index, bone_weight = struct.unpack('<If', data_chunk)
                
                bone_influences.append((bone_index, bone_weight))
#                
#                print "\t\tbone index %d, bone weight %f" % (bone_index, bone_weight)
        
        data_chunk = file_object.read(4) # rename_me_0
        
        rename_me_2 =  struct.unpack('<I', data_chunk)[0]
        
        rename_me_3 = []
        
        total = 0
        totalx = 0
        
        for x in xrange(rename_me_2): # vertice count
            data_chunk = file_object.read(4)
            
            y = struct.unpack('<I', data_chunk)[0]
            
            totalx = totalx + y
            
            rename_me_3.append(y)
            
            total = total + 1
        
        print "total = %d, totalx = %d" % (total, totalx)
        
        i = 0
        
        for rename_me in rename_me_3:
            for x in xrange(rename_me):
                data_chunk = file_object.read(4)
                
                vertex_index = struct.unpack('<I', data_chunk)[0]
                
                bone_index, bone_weight = bone_influences[i]
#                
#                print "%s: %d %f" % (bones[bone_index], vertex_index, bone_weight)
                
                mesh.assignVertsToGroup(bones[bone_index], \
                                        [vertex_index],
                                        bone_weight,
                                        Blender.Mesh.AssignModes.ADD)
                
#                i = i + 1
#                
#                print "\t\tvertex index %d" % vertex_index
        
        for x in xrange(vertex_count):
            data_chunk = file_object.read(12)
#            
#            print struct.unpack('<3f', data_chunk)
#    
#    print "mesh %s end 0x%x" % (name, file_object.tell())
    
    return mesh_object


def tmb_read(file_path):
    file_object = None
    
    try:
        file_object = open(file_path, 'rb')
        
        data_chunk = file_object.read(12) # Read header chunk
        
        version, revision, mesh_count = struct.unpack('<3I', data_chunk)
#        
#        print "mesh count %d" % mesh_count
        
        mesh_objects = []
        
        for x in xrange(mesh_count):
            mesh_objects.append(tmb_read_mesh(file_object, revision))
        
        scene = Blender.Scene.GetCurrent()
        
        for mesh_object in mesh_objects:
            scene.objects.link(mesh_object)
    except IOError, (errno, strerror):
        Blender.Draw.PupMenu("Error%%t|I/O error(%d): %s." % (errno, strerror))
    except Exception, err:
        Blender.Draw.PupMenu("Error%%t|.%s" % err)
    finally:
        if file_object is not None:
            file_object.close()


def main():
    def tmb_file_selector(file_path):
        if file_path and not Blender.sys.exists(file_path):
            Blender.Draw.PupMenu("Error%%t|The file %s does not exist." % file_path)
        else:
            tmb_read(file_path)
    
    Blender.Window.FileSelector(tmb_file_selector, 'Ok', Blender.sys.makename(ext='.tmb'))


if __name__ == "__main__":
    main()
 
Last edited:
Thank you very much Phantom*, and thanks master_unknown for reuploading. It works. It imports all levels of detail of the TMB mesh into Blender. But it crashes when importing character parts...

Phantom*, i have some experience with Blender scripting, maybe I can help you somehow...
 
Blender importer uploaded to mediafire


^_^
 
Last edited by a moderator:
why is this.... when i extract my tmb_import.py ito blender directory and when i go to file - import--- i can't see the tantraonline (.tmb)???????

how to extract the tmb_import.py?????

i use blender 2.46

and python 2.5.4
 
just quit using blender even you can import the tmb files still you cant save them. you need tmb_export.py inorder for you to save your own data.
 
Has anyone had any luck with the export script in blender???????? i have it but, when i save it as tmb format and try to start the game the htlauncher crashes. abnormal - TMB Blender Importer - RaGEZONE Forums
 
Status
Not open for further replies.
Back