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()