Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

[Help] Bad Number Version

Status
Not open for further replies.
Joined
May 16, 2011
Messages
650
Reaction score
327
File "C:\blabla\blabla\gunz_import.py", line 444, in elu_import
raise VersionError, "Bad version number %d" % version
__main__.VersionError: Bad version number 20495

Gentlemen, It seems we have hit a pine-cone in the middle of the GunZ 2 Development Road..

Ideas? Solutions?
 
DRGunZ 2 Creator
Loyal Member
Joined
Jan 21, 2007
Messages
4,493
Reaction score
161
I can upload some ELU files for you Phantom.

EDIT: I don't know if the .elus in the other files are the same or not, but here is the .elus from SFX.mrf. I included all of them so you can test of those if needed.

 
Last edited:
Joined
Apr 23, 2008
Messages
1,178
Reaction score
97
I can upload some ELU files for you Phantom.

EDIT: I don't know if the .elus in the other files are the same or not, but here is the .elus from SFX.mrf. I included all of them so you can test of those if needed.


Upload one from the Character.mrf
I would but at school and on my Mac and then Ima be gone till about 12so I wont be able to upload
 
DRGunZ 2 Creator
Loyal Member
Joined
Jan 21, 2007
Messages
4,493
Reaction score
161
Alright, but the files that are in Character.mrf are mostly .dds files.
 
Experienced Elementalist
Joined
Apr 18, 2009
Messages
271
Reaction score
142
I think he's talking about an actual character model and not Character.mrf, so I just uploaded Assassin_Male_01.elu and a weapon: flame_thrower.elu


 
Joined
May 16, 2011
Messages
650
Reaction score
327
Need some elus to investigate but for now I will assume that nothing changed from version 20487 :p Good luck..

Code:
#!BPY
# Copyright (c) 2008-2011 Peter S. Stevens
# 
# 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: 'GUNZ (*.elu, *.ani)...'
Blender: 246
Group: 'Import'
Tooltip: 'Import GUNZ *.elu and/or *.ani game files'
"""
__author__ = 'Peter S. Stevens'
__email__ = 'pstevens:cryptomail*org'
__url__ = ('blender', 'elysiun', 'Project homepage, [URL]http://www.ragezone.com/'[/URL])
__version__ = '09.12.00'
__bpydoc__ = """ \
This script imports GUNZ *.elu and/or *.ani game files.
"""
 
import Blender
import bpy
import struct
 
LEFT_TO_RIGHT = Blender.Mathutils.Matrix([-1.0, 0.0, 0.0, 0.0],
                                         [0.0, 0.0, 1.0, 0.0],
                                         [0.0, 1.0, 0.0, 0.0],
                                         [0.0, 0.0, 0.0, 1.0])
ELU_VERSIONS = (0x5004, 0x5005, 0x5006, 0x5007, 0x500F)
ANI_VERSIONS = (0x1001, 0x1003)
DOT_DDS = '.dds'
MAX_INFLUENCES = 4
 
class MagicError(ValueError):
    pass
 
class VersionError(ValueError):
    pass
 
def elu_to_blender_name(name):
    if name.startswith('Bip01 L ') == True:
        return "%s %s.L" % ('Bip01', name[8:])
 
    if name.startswith('Bip01 R ') == True:
        return "%s %s.R" % ('Bip01', name[8:])
 
    return name
 
def elu_read_material(file_object):
    data_chunk = file_object.read(64)
 
    high_index, \
    low_index = struct.unpack_from('<2I', data_chunk)
    diffuse_color = struct.unpack_from('<4f', data_chunk, 8)
    ambient_color = struct.unpack_from('<4f', data_chunk, 24)
    specular_color = struct.unpack_from('<4f', data_chunk, 40)
    specular_power, \
    emissive = struct.unpack_from('<2f', data_chunk, 56)
 
    material = Blender.Material.New()
 
    material.setRGBCol(diffuse_color[0:3])
    material.setAlpha(diffuse_color[3])
    material.setMirCol(ambient_color[0:3])
    material.setAmb(ambient_color[3])
    material.setSpecCol(specular_color[0:3])
    material.setSpec(specular_power)
    material.setEmit(emissive)
 
    return material
 
def elu_read_texture(file_object, version):
    texture_name_1 = ''
    texture_name_2 = ''
 
    if version == 0x5004 or version == 0x5005:
        texture_name_1 = file_object.read(40)
        texture_name_2 = file_object.read(40)
    elif version == 0x5006 or version == 0x5007 or version == 0x500F:
        texture_name_1 = file_object.read(256)
        texture_name_2 = file_object.read(256)
 
    texture_name_1 = texture_name_1[0:texture_name_1.find('\0')]
 
    texture = None
 
    try:
        texture = Blender.Texture.Get(texture_name_1)
    except:
        texture = Blender.Texture.New(texture_name_1)
 
        texture.setType('Image')
 
        image = None
 
        try:
            image = Blender.Image.Get(texture_name_1 + DOT_DDS)
        except:
            search_paths = [Blender.sys.dirname(file_object.name), Blender.Get('texturesdir')]
 
            for search_path in search_paths:
                if search_path is not None and len(search_path) > 0:
                    image_file = Blender.sys.join(search_path, texture_name_1 + DOT_DDS)
 
                    if Blender.sys.exists(image_file):
                        try:
                            image = Blender.Image.Load(image_file)
                        except:
                            Blender.Draw.PupMenu("Warning%%t|Could not load %s." % image_file)
 
                        break
        finally:
            if image is not None:
                texture.setImage(image)
            else:
                Blender.Draw.PupMenu("Warning%%t|Could not locate %s." % texture_name_1 + DOT_DDS)
 
    double_sided, unknown_1 = struct.unpack('<2I', file_object.read(8))
 
    alpha_percentage = 0
 
    if version == 0x5007 or version == 0x500F:
        alpha_percentage = struct.unpack('<I', file_object.read(4))
 
    if texture is not None and alpha_percentage > 0:
        texture.useAlpha = 1
 
    return texture
 
def elu_read_mesh(file_object, materials, version):
    def boolean_xor(a, b):
     return (not a) != (not b)
 
    mesh_name = file_object.read(40)
    parent_mesh_name = file_object.read(40)
 
    mesh_name = mesh_name[0:mesh_name.find('\0')]
    parent_mesh_name = parent_mesh_name[0:parent_mesh_name.find('\0')]
 
    mesh_name = elu_to_blender_name(mesh_name)
    parent_mesh_name = elu_to_blender_name(parent_mesh_name)
 
    print "mesh %s start 0x%x" % (mesh_name, file_object.tell() - 80)
 
    mesh_object = Blender.Object.New('Mesh', mesh_name)
 
    mesh = mesh_object.getData(mesh = True)
 
    if mesh is None:
        if mesh_name.startswith('Bip') == True:
            mesh = Blender.Mesh.New(mesh_name + "~tmp")
        else:
            mesh = Blender.Mesh.New(mesh_name)
 
        mesh_object.link(mesh)
    else:
        if mesh_name.startswith('Bip') == True:
            mesh.name = mesh_name + "~tmp"
        else:
            mesh.name = mesh_name
 
    world_matrix = Blender.Mathutils.Matrix(struct.unpack('<4f', file_object.read(16)), \
                                            struct.unpack('<4f', file_object.read(16)), \
                                            struct.unpack('<4f', file_object.read(16)), \
                                            struct.unpack('<4f', file_object.read(16)))
 
    unknown_0 = struct.unpack('<11f', file_object.read(44))
 
    local_matrix = Blender.Mathutils.Matrix(struct.unpack('<4f', file_object.read(16)), \
                                            struct.unpack('<4f', file_object.read(16)), \
                                            struct.unpack('<4f', file_object.read(16)), \
                                            struct.unpack('<4f', file_object.read(16)))
 
    vertex_position_count = struct.unpack('<I', file_object.read(4))[0]
 
#    print "\tvertex position count %d" % vertex_position_count
 
    for x in xrange(vertex_position_count):
        position = Blender.Mathutils.Vector(struct.unpack('<3f', file_object.read(12)))
 
        mesh.verts.extend(position)
 
    face_count = struct.unpack('<I', file_object.read(4))[0]
 
#    print "\tface count %d" % face_count
 
    for x in xrange(face_count):
        mesh.faces.extend([mesh.verts[y] for y in struct.unpack('<3I', file_object.read(12))])
 
        face = mesh.faces[-1]
 
        face_uvs = []
 
        for y in xrange(len(face.verts)):
            uv = Blender.Mathutils.Vector(struct.unpack('<2f', file_object.read(8)))
            uv.y = float(1.0 - uv.y)
 
            face_uvs.append(uv)
 
            file_object.seek(4, 1)
 
        face.uv = tuple(face_uvs)
 
        file_object.seek(8, 1)
 
    material_index = 0
 
    if (version >= 0x5005 and version <= 0x5007) or version == 0x500F:
        # This is an assumption that these values are normals
        for face in mesh.faces:
            face_unknown_0 = Blender.Mathutils.Vector(struct.unpack('<3f', file_object.read(12)))
 
            for vertex in face.verts:
                vertex.no = Blender.Mathutils.Vector(struct.unpack('<3f', file_object.read(12)))
 
        temp_fix = face_count - len(mesh.faces)
 
        for x in xrange(temp_fix):
            file_object.seek(48, 1)
 
        vertex_color_count = struct.unpack('<I', file_object.read(4))[0]
 
#        print "\tvertex color count %d" % vertex_color_count
 
        vertex_colors = []
 
        for x in xrange(vertex_color_count):
            vertex_color = struct.unpack('<3f', file_object.read(12))
 
            vertex_colors.append([int(y * 255.0) for y in vertex_color])
 
        if vertex_color_count > 0:
            mesh.vertexColors = True
 
            for face in mesh.faces:
                for i, vertex in enumerate(face):
                    vertex_color = vertex_colors[vertex.index]
 
                    face_color = face.col[i]
                    face_color.r = vertex_color[0]
                    face_color.g = vertex_color[1]
                    face_color.b = vertex_color[2]
 
        material_index = struct.unpack('<I', file_object.read(4))[0]
 
#        print "\tmaterial index %d" % material_index
 
        bone_influence_count = struct.unpack('<I', file_object.read(4))[0]
 
#        print "\tbone influence count %d" % bone_influence_count
 
        for x in xrange(bone_influence_count):
            bone_influence_names = []
 
            for y in xrange(MAX_INFLUENCES):
                bone_influence_name = file_object.read(40)
                bone_influence_name = bone_influence_name[0:bone_influence_name.find('\0')]
 
                if len(bone_influence_name) > 0:
                    bone_influence_name = elu_to_blender_name(bone_influence_name)
 
                    bone_influence_names.append(bone_influence_name)
 
            bone_influence_weights = [y for y in struct.unpack('<8f', file_object.read(32)) if y > 0]
 
            # doesn't seem to be reliable... what might be needed is verifying if
            # the sum of the weights is 1.0 just to be safe
            count = struct.unpack('<I', file_object.read(4))[0]
 
            for y in xrange(len(bone_influence_weights)):
                mesh.addVertGroup(bone_influence_names[y])
 
                mesh.assignVertsToGroup(bone_influence_names[y], \
                                        [x],
                                        bone_influence_weights[y],
                                        Blender.Mesh.AssignModes.ADD)
 
            for y in xrange(MAX_INFLUENCES):
                a, b, c = struct.unpack('<3f', file_object.read(12))
#                print "\t\t%f, %f, %f" % (a, b, c)
    else:
        file_object.seek(4, 1)
        material_index = struct.unpack('<I', file_object.read(4))[0]
 
    if material_index < len(materials):
        material = materials[material_index]
 
        mesh.materials = [material]
 
        textures = material.getTextures()
 
        if len(textures) > 0:
            texture = textures[0].tex
 
            image = texture.getImage()
 
            for face in mesh.faces:
                face.mode = Blender.Mesh.FaceModes.TEX + Blender.Mesh.FaceModes.TWOSIDE
                face.image = image
        else:
            Blender.Draw.PupMenu("Warning%%t|Could not set material for %s mesh." % mesh_name)
 
    mesh_object.setMatrix(world_matrix * LEFT_TO_RIGHT)
 
    if len(parent_mesh_name) > 0:
        bip_check = boolean_xor(mesh_name.startswith('Bip'), parent_mesh_name.startswith('Bip'))
 
        if bip_check == False:
            parent_mesh_object = Blender.Object.Get(parent_mesh_name)
            parent_mesh_object.makeParent([mesh_object])
 
    print "mesh %s end 0x%x" % (mesh_name, file_object.tell())
 
    return mesh_object
 
def ani_read_mesh_transformations(file_object, armature_object):
    key_frames = {}
 
    armature_pose = armature_object.getPose()
 
    armature_pose_bones = armature_pose.bones
 
    unknown_0 = struct.unpack('<I', file_object.read(4))[0]
 
    mesh_name = file_object.read(40)
 
    mesh_name = mesh_name[0:mesh_name.find('\0')]
 
    mesh_name = elu_to_blender_name(mesh_name)
 
    print "transform %s start 0x%x" % (mesh_name, file_object.tell() - 80)
 
    pose_matrix = Blender.Mathutils.Matrix(struct.unpack('<4f', file_object.read(16)), \
                                           struct.unpack('<4f', file_object.read(16)), \
                                           struct.unpack('<4f', file_object.read(16)), \
                                           struct.unpack('<4f', file_object.read(16)))
 
    translation_count = struct.unpack('<I', file_object.read(4))[0]
 
#    print "translation count %d" % translation_count
 
    for y in xrange(translation_count):
        translation = Blender.Mathutils.Vector(struct.unpack('<3f', file_object.read(12)))
 
        key_frame_second = int(struct.unpack('<I', file_object.read(4))[0] / 60)
 
        key_frames[key_frame_second] = Blender.Mathutils.TranslationMatrix(translation)
 
    rotation_count = struct.unpack('<I', file_object.read(4))[0]
 
#    print "rotation count %d" % rotation_count
 
    for y in xrange(rotation_count):
        x, y, z, w = struct.unpack('<4f', file_object.read(16))
 
        rotation = Blender.Mathutils.Quaternion(w, x, y, z)
 
        key_frame_second = int(struct.unpack('<I', file_object.read(4))[0] / 60)
 
        if key_frame_second in key_frames:
            key_frames[key_frame_second] = rotation.toMatrix().resize4x4() * key_frames[key_frame_second]
        else:
            inverse_parent_pose_matrix = Blender.Mathutils.Matrix()
            inverse_parent_pose_matrix.identity()
 
            if mesh_name in armature_pose_bones.keys():
                if armature_pose_bones[mesh_name].parent is not None:
                    inverse_parent_pose_matrix = armature_pose_bones[mesh_name].parent.poseMatrix.copy() * LEFT_TO_RIGHT
 
            inverse_parent_pose_matrix.invert()
 
            key_frames[key_frame_second] = rotation.toMatrix().resize4x4() * Blender.Mathutils.TranslationMatrix((pose_matrix * inverse_parent_pose_matrix).translationPart())
 
    if mesh_name in armature_pose_bones.keys():
        if len(key_frames) > 0:
            for key_frame_second, key_frame_transformation in key_frames.iteritems():
                if armature_pose_bones[mesh_name].parent is not None:
                    key_frame_transformation *= (armature_pose_bones[mesh_name].parent.poseMatrix.copy() * LEFT_TO_RIGHT)
 
                armature_pose_bones[mesh_name].poseMatrix = key_frame_transformation * LEFT_TO_RIGHT
                armature_pose.update()
                armature_pose_bones[mesh_name].insertKey(armature_object, key_frame_second + 1)
 
            armature_pose_bones[mesh_name].poseMatrix = pose_matrix * LEFT_TO_RIGHT
            armature_pose.update()
        else:
            armature_pose_bones[mesh_name].poseMatrix = pose_matrix * LEFT_TO_RIGHT
            armature_pose.update()
            armature_pose_bones[mesh_name].insertKey(armature_object, 1)
 
    print "transform %s end 0x%x" % (mesh_name, file_object.tell())
 
def elu_import(file_path):
    file_object = None
 
    try:
        file_object = open(file_path, 'rb')
 
        data_chunk = file_object.read(16)
 
        magic, \
        version, \
        material_count, \
        mesh_count = struct.unpack('<4I', data_chunk)
 
        if magic != 0x0107F060:
            raise MagicError, "Bad magic number, %x" % magic
 
        print "version %d" % version
 
        if version not in ELU_VERSIONS and version not in ANI_VERSIONS:
            raise VersionError, "Bad version number %d" % version
 
        if version in ELU_VERSIONS:
            materials = []
 
            for x in xrange(material_count):
                material = elu_read_material(file_object)
 
                texture = elu_read_texture(file_object, version)
 
                if texture is not None:
                    material.setTexture(0, texture, Blender.Texture.TexCo.UV)
 
                    if texture.useAlpha == 1:
                        material.setMode(Blender.Material.Modes.TEXFACE + Blender.Material.Modes.TEXFACE_ALPHA)
                    else:
                        material.setMode(Blender.Material.Modes.TEXFACE)
 
                materials.append(material)
 
            mesh_objects = []
 
            for x in xrange(mesh_count):
                mesh_objects.append(elu_read_mesh(file_object, materials, version))
        elif version in ANI_VERSIONS:
            try:
                armature_object = Blender.Object.Get('Armature')
            except ValueError:
                Blender.Draw.PupMenu("Error%%t|The scene does not contain an armature.")
            else:
                scene = Blender.Scene.GetCurrent()
 
                action_name = Blender.sys.basename(file_object.name)
                action_name = action_name[0:action_name.find('.')]
 
                action = Blender.Armature.NLA.NewAction(action_name)
                action.setActive(armature_object)
 
                for x in xrange(mesh_count):
                    ani_read_mesh_transformations(file_object, armature_object)
 
                scene.update(0)
    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)
    else:
        scene = Blender.Scene.GetCurrent()
 
        if version in ELU_VERSIONS:
            armature_object = Blender.Object.New('Armature')
 
            armature_object.drawMode = Blender.Object.DrawModes.XRAY
 
            armature = armature_object.getData()
 
            if armature is None:
                armature = Blender.Armature.New('Armature')
                armature_object.link(armature)
 
            armature.drawType = Blender.Armature.STICK
            armature.envelopes = False
            armature.vertexGroups = True
 
            armature.makeEditable()
 
            for mesh_object in mesh_objects:
                mesh = mesh_object.getData(mesh = True)
 
                if len(mesh.getVertGroupNames()) > 0:
                    armature_object.makeParent([mesh_object])
 
                    armature_modifier = mesh_object.modifiers.append(Blender.Modifier.Types.ARMATURE)
                    armature_modifier[Blender.Modifier.Settings.OBJECT] = armature_object
 
                if mesh_object.name.startswith('Bip') == True:
                    edit_bone = Blender.Armature.Editbone()
 
                    edit_bone.name = mesh_object.name
 
                    parent_mesh_object = mesh_object.getParent()
 
                    if parent_mesh_object is not None:
                        edit_bone.parent = armature.bones[parent_mesh_object.name]
 
                    edit_bone.matrix = mesh_object.getMatrix()
 
                    armature.bones[edit_bone.name] = edit_bone
 
                    mesh.hide = True
 
                    mesh_object.setDrawMode(Blender.Object.DrawModes['TRANSP'])
 
                    if mesh.users == 0:
                        mesh.verts = None
                        mesh.faces = None
 
                    scene.objects.unlink(mesh_object)
                else:
                    scene.objects.link(mesh_object)
 
            armature.update()
 
            if len(armature.bones) > 0:
                scene.objects.link(armature_object)
 
                armature_pose = armature_object.getPose()
 
                armature_pose_bones = armature_pose.bones
 
                for armature_pose_bone in armature_pose_bones.values():
                    try:
                        mesh_object = Blender.Object.Get(armature_pose_bone.name)
                    except:
                        pass
                    else:
                        armature_pose_bone.displayObject = mesh_object
            else:
                scene.objects.unlink(armature_object)
 
        scene.update(0)
    finally:
        if file_object is not None:
            file_object.close()
 
def main():
    def elu_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:
            elu_import(file_path)
 
    Blender.Window.FileSelector(elu_file_selector, 'Ok', Blender.sys.makename(ext='.elu'))
 
if __name__ == "__main__":
    main()
Thanks, I will try this out in a few hours!
 
DRGunZ 2 Creator
Loyal Member
Joined
Jan 21, 2007
Messages
4,493
Reaction score
161
I think he's talking about an actual character model and not Character.mrf, so I just uploaded Assassin_Male_01.elu and a weapon: flame_thrower.elu


Ah ok. I like the new weapons they are putting in. Flamethrower, minigun, chainsaw, etc :D
 
Experienced Elementalist
Joined
Apr 18, 2009
Messages
271
Reaction score
142
Thanks, I will try this out in a few hours!

He didn't change anything yet as far as I figured out.
Well, it didn't work for me at least. Let's see what he says after looking at these elu's.
 
Experienced Elementalist
Joined
Aug 27, 2006
Messages
223
Reaction score
183
Could someone upload a few more elus and if at all possible a simpler 1 like a cube, sphere, etc. ie. as few faces as possible (look for smallest file size)

ps i'd prefer a zip over an rar or 7z :p
 
Ninja Goblin
Loyal Member
Joined
Feb 3, 2009
Messages
1,715
Reaction score
489
Because the Elus werent of any use to me i already deleted those, kept the textures.
However, i could undelete a few elus.



The only difference i saw is that they dont have a ascii of the material/texture name anymore.
Tough the Mesh Name (should be the Mesh Name) is still at the top.
 
DRGunZ 2 Creator
Loyal Member
Joined
Jan 21, 2007
Messages
4,493
Reaction score
161
Sorry about that Phantom.
I'll look through it for you in a .zip or .7z next time.

EDIT: Here you go, all the 1kb .elu files in the client.
 
Last edited:
Experienced Elementalist
Joined
Aug 27, 2006
Messages
223
Reaction score
183
Just reporting the little progress I've made. Imported using a modified importer for Blender 2.4 series; No Blender 2.5x just yet. It's a crude implementation and fails all over the place but slowly the new structures are being defined.



 
Last edited:
Experienced Elementalist
Joined
Apr 18, 2009
Messages
271
Reaction score
142
2.5x is crap anyways.

Really glad to see you when you're needed ;D
 
Experienced Elementalist
Joined
Aug 27, 2006
Messages
223
Reaction score
183
The modified Blender 2.4x importer, which a far as my testing, supports versions 0x500E to 0x5011 from all the files I recieved. This is far from completition with lots of unknowns to define but the basics are there.

For any curious developers, all the fugly new code is in def elu_read_mesh2.

Code:
#!BPY
# Copyright (c) 2008-2011 Peter S. Stevens
# 
# 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: 'GUNZ (*.elu, *.ani)...'
Blender: 246
Group: 'Import'
Tooltip: 'Import GUNZ *.elu and/or *.ani game files'
"""
__author__ = 'Peter S. Stevens'
__email__ = 'pstevens:cryptomail*org'
__url__ = ('blender', 'elysiun', 'Project homepage, http://www.ragezone.com/')
__version__ = '09.12.00'
__bpydoc__ = """ \
This script imports GUNZ *.elu and/or *.ani game files.
"""

import Blender
import bpy
import struct

LEFT_TO_RIGHT = Blender.Mathutils.Matrix([-1.0, 0.0, 0.0, 0.0],
                                         [0.0, 0.0, 1.0, 0.0],
                                         [0.0, 1.0, 0.0, 0.0],
                                         [0.0, 0.0, 0.0, 1.0])

# Gunz 0x5004, 0x5005, 0x5006, 0x5007
# Gunz 2 0x500E, 0x500F, 0x5010, 0x5011
ELU_VERSIONS = (0x5004, 0x5005, 0x5006, 0x5007, 0x500E, 0x500F, 0x5010, 0x5011)

ANI_VERSIONS = (0x1001, 0x1003)

DOT_DDS = '.dds'

MAX_INFLUENCES = 4

class MagicError(ValueError):
    pass

class VersionError(ValueError):
    pass

def elu_to_blender_name(name):
    if name.startswith('Bip01 L ') == True:
        return "%s %s.L" % ('Bip01', name[8:])

    if name.startswith('Bip01 R ') == True:
        return "%s %s.R" % ('Bip01', name[8:])

    return name

def elu_read_material(file_object):
    data_chunk = file_object.read(64)

    high_index, \
    low_index = struct.unpack_from('<2I', data_chunk)
    diffuse_color = struct.unpack_from('<4f', data_chunk, 8)
    ambient_color = struct.unpack_from('<4f', data_chunk, 24)
    specular_color = struct.unpack_from('<4f', data_chunk, 40)
    specular_power, \
    emissive = struct.unpack_from('<2f', data_chunk, 56)

    material = Blender.Material.New()

    material.setRGBCol(diffuse_color[0:3])
    material.setAlpha(diffuse_color[3])
    material.setMirCol(ambient_color[0:3])
    material.setAmb(ambient_color[3])
    material.setSpecCol(specular_color[0:3])
    material.setSpec(specular_power)
    material.setEmit(emissive)

    return material

def elu_read_texture(file_object, version):
    texture_name_1 = ''
    texture_name_2 = ''

    if version == 0x5004 or version == 0x5005:
        texture_name_1 = file_object.read(40)
        texture_name_2 = file_object.read(40)
    elif version == 0x5006 or version == 0x5007:
        texture_name_1 = file_object.read(256)
        texture_name_2 = file_object.read(256)

    texture_name_1 = texture_name_1[0:texture_name_1.find('\0')]

    texture = None

    try:
        texture = Blender.Texture.Get(texture_name_1)
    except:
        texture = Blender.Texture.New(texture_name_1)

        texture.setType('Image')

        image = None

        try:
            image = Blender.Image.Get(texture_name_1 + DOT_DDS)
        except:
            search_paths = [Blender.sys.dirname(file_object.name), Blender.Get('texturesdir')]

            for search_path in search_paths:
                if search_path is not None and len(search_path) > 0:
                    image_file = Blender.sys.join(search_path, texture_name_1 + DOT_DDS)

                    if Blender.sys.exists(image_file):
                        try:
                            image = Blender.Image.Load(image_file)
                        except:
                            Blender.Draw.PupMenu("Warning%%t|Could not load %s." % image_file)

                        break
        finally:
            if image is not None:
                texture.setImage(image)
            else:
                Blender.Draw.PupMenu("Warning%%t|Could not locate %s." % texture_name_1 + DOT_DDS)

    double_sided, unknown_1 = struct.unpack('<2I', file_object.read(8))

    alpha_percentage = 0

    if version == 0x5007:
        alpha_percentage = struct.unpack('<I', file_object.read(4))[0]

    if texture is not None and alpha_percentage > 0:
        texture.useAlpha = 1

    return texture

def elu_read_mesh2(file_object, index, version):
    mesh_name_length = struct.unpack('<I', file_object.read(4))[0]

    mesh_name = file_object.read(mesh_name_length)
    mesh_name = mesh_name[:-1]

    print "mesh %s @ 0x%x" % (mesh_name, file_object.tell() - 4 - mesh_name_length)

    mesh_object = Blender.Object.New('Mesh', mesh_name)

    mesh = mesh_object.getData(mesh = True)

    parent_mesh_name_length = struct.unpack('<I', file_object.read(4))[0]

    parent_mesh_name = file_object.read(parent_mesh_name_length)
    parent_mesh_name = parent_mesh_name[:-1]

    parent_mesh_index = struct.unpack('<I8x', file_object.read(12))[0]

    world_matrix = Blender.Mathutils.Matrix(struct.unpack('<4f', file_object.read(16)), \
                                            struct.unpack('<4f', file_object.read(16)), \
                                            struct.unpack('<4f', file_object.read(16)), \
                                            struct.unpack('<4f', file_object.read(16)))

    if version >= 0x500E and version <= 0x5010:
        file_object.seek(12, 1) # unknowns
    else:
        file_object.seek(4, 1) # unknowns

    vertex_position_count = struct.unpack('<I', file_object.read(4))[0]

    print "\tvertex_position_count %d @ 0x%x" % (vertex_position_count, file_object.tell() - 4)

    for x in xrange(vertex_position_count):
        vertex_position = Blender.Mathutils.Vector(struct.unpack('<3f', file_object.read(12)))

        mesh.verts.extend(vertex_position)

    vertex_normal_count = struct.unpack('<I', file_object.read(4))[0]

    print "\tvertex_normal_count %d @ 0x%x" % (vertex_normal_count, file_object.tell() - 4)

    vertex_normals = []

    for x in xrange(vertex_normal_count):
        vertex_normal = Blender.Mathutils.Vector(struct.unpack('<3f', file_object.read(12)))

        vertex_normals.append(vertex_normal)

    vertex_unknown0_count = struct.unpack('<I', file_object.read(4))[0]

    print "\tvertex_unknown0_count %d @ 0x%x" % (vertex_unknown0_count, file_object.tell() - 4)

    if version == 0x500E:
        for x in xrange(vertex_unknown0_count):
            vertex_unknown0_vector0 = Blender.Mathutils.Vector(struct.unpack('<3f', file_object.read(12)))
    else:
        for x in xrange(vertex_unknown0_count):
            vertex_unknown0_vector0 = Blender.Mathutils.Vector(struct.unpack('<4f', file_object.read(16)))

    if version != 0x500E:
        file_object.seek(4, 1) # unknown, padding?

    vertex_texcoord_count = struct.unpack('<I', file_object.read(4))[0]

    print "\tvertex_texcoord_count %d @ 0x%x" % (vertex_texcoord_count, file_object.tell() - 4)

    vertex_texcoords = []

    for x in xrange(vertex_texcoord_count):
        texture_coordinates = Blender.Mathutils.Vector(struct.unpack('<3f', file_object.read(12)))
        texture_coordinates.y = float(1.0 - texture_coordinates.y)

        vertex_texcoords.append(texture_coordinates)

    if version == 0x500E or version == 0x500F or version == 0x5011:
        vertex_unknown2_count = struct.unpack('<I', file_object.read(4))[0]

        print "\tvertex_unknown2_count %d @ 0x%x" % (vertex_unknown2_count, file_object.tell() - 4)

        for x in xrange(vertex_unknown2_count):
            vertex_unknown2_vector0 = Blender.Mathutils.Vector(struct.unpack('<3f', file_object.read(12)))

    if version == 0x500E:
        file_object.seek(4, 1)

    unknown0_count = struct.unpack('<I', file_object.read(4))[0]

    print "\tunknown0_count %d @ 0x%x" % (unknown0_count, file_object.tell() - 4)

    if unknown0_count > 0:
        unknown0_unknown0, \
        unknown0_unknown1 = struct.unpack('<2I', file_object.read(8))

        for x in xrange(unknown0_count):
            unknown0_unknown3_count = struct.unpack('<I', file_object.read(4))[0] # totaled = unknown0_unknown0

            for y in xrange(unknown0_unknown3_count):
                unknown0_unknown3_index0, \
                unknown0_unknown3_index1, \
                unknown0_unknown3_index2, \
                unknown0_unknown3_index3, \
                unknown0_unknown3_index4 = struct.unpack('<HI3H', file_object.read(12))

            file_object.seek(2, 1)

    unknown1_count = struct.unpack('<I', file_object.read(4))[0]

    print "\tunknown1_count %d @ 0x%x" % (unknown1_count, file_object.tell() - 4)

    for x in xrange(unknown1_count):
        file_object.seek(12, 1)

    file_object.seek(4, 1) # unknown, padding?

    unknown2_count = struct.unpack('<I', file_object.read(4))[0]

    print "\tunknown2_count %d @ 0x%x" % (unknown2_count, file_object.tell() - 4)

    for x in xrange(unknown2_count):
        unknown2_unknown0_count = struct.unpack('<I', file_object.read(4))[0]

        for y in xrange(unknown2_unknown0_count):
            unknown2_unknown0_unknown0, \
            unknown2_unknown0_unknown1, \
            unknown2_unknown0_unknown2, = struct.unpack('<2Hf', file_object.read(8))

    unknown3_count = struct.unpack('<I', file_object.read(4))[0]

    print "\tunknown3_count %d @ 0x%x" % (unknown3_count, file_object.tell() - 4)

    for x in xrange(unknown3_count):
        unknown3_unknown0_matrix = struct.unpack('<16f', file_object.read(64))

    for x in xrange(unknown3_count):
        unknown3_unknown0_index = struct.unpack('<H', file_object.read(2))

    vertex_indice_count = struct.unpack('<I', file_object.read(4))[0]

    print "\tvertex_indice_count %d - 0x%x" % (vertex_indice_count, file_object.tell() - 4)

    vertex_indices = []

    for x in xrange(vertex_indice_count):
        vertex_position_index, \
        vertex_normal_index, \
        vertex_texcoord_index, \
        vertex_unknown0_index = struct.unpack('<2H2I', file_object.read(12))

        vertex_indices.append((vertex_position_index, vertex_normal_index, vertex_texcoord_index, vertex_unknown0_index))

    file_object.seek(4, 1) # unknown, padding?

    face_index_count = struct.unpack('<I', file_object.read(4))[0]

    print "\tface_index_count %d - 0x%x" % (face_index_count, file_object.tell() - 4)

    face_count = int(face_index_count / 3)

    for x in xrange(face_count):
        face_vertices = []
        face_normals = []
        face_texcoords = []

        for y in struct.unpack('<3H', file_object.read(6)):
            vertex_position_index = vertex_indices[y][0]
            vertex_normal_index = vertex_indices[y][1]
            vertex_texcoord_index = vertex_indices[y][2]
            vertex_unknown0_index = vertex_indices[y][3]

            if vertex_position_index < len(mesh.verts):
                face_vertices.append(mesh.verts[vertex_position_index])

            if vertex_normal_index < vertex_normal_count:
                face_normals.append(vertex_normals[vertex_normal_index])

            if vertex_texcoord_index < vertex_texcoord_count:
                face_texcoords.append(vertex_texcoords[vertex_texcoord_index])

        if len(face_vertices) == 3:
            mesh.faces.extend(face_vertices)

            face = mesh.faces[-1]

            if len(face_texcoords) == 3:
                face.uv = tuple(face_texcoords)

            if len(face_normals) == 3:
                for i, vertex in enumerate(face):
                    vertex.no = face_normals[i]

    unknown3_count = struct.unpack('<I', file_object.read(4))[0]

    print "\tunknown3_count %d @ 0x%x" % (unknown3_count, file_object.tell() - 4)

    for x in xrange(unknown3_count):
        file_object.seek(12, 1)

    file_object.seek(24, 1)

    return mesh_object

def elu_read_mesh(file_object, materials, version):
    def boolean_xor(a, b):
        return (not a) != (not b)

    mesh_name = file_object.read(40)
    parent_mesh_name = file_object.read(40)

    mesh_name = mesh_name[0:mesh_name.find('\0')]
    mesh_name = elu_to_blender_name(mesh_name)

    parent_mesh_name = parent_mesh_name[0:parent_mesh_name.find('\0')]
    parent_mesh_name = elu_to_blender_name(parent_mesh_name)

    print "mesh %s start 0x%x" % (mesh_name, file_object.tell() - 80)

    mesh_object = Blender.Object.New('Mesh', mesh_name)

    mesh = mesh_object.getData(mesh = True)

    if mesh is None:
        if mesh_name.startswith('Bip') == True:
            mesh = Blender.Mesh.New(mesh_name + "~tmp")
        else:
            mesh = Blender.Mesh.New(mesh_name)

        mesh_object.link(mesh)
    else:
        if mesh_name.startswith('Bip') == True:
            mesh.name = mesh_name + "~tmp"
        else:
            mesh.name = mesh_name

    world_matrix = Blender.Mathutils.Matrix(struct.unpack('<4f', file_object.read(16)), \
                                            struct.unpack('<4f', file_object.read(16)), \
                                            struct.unpack('<4f', file_object.read(16)), \
                                            struct.unpack('<4f', file_object.read(16)))
    unknown_0 = struct.unpack('<11f', file_object.read(44))

    local_matrix = Blender.Mathutils.Matrix(struct.unpack('<4f', file_object.read(16)), \
                                            struct.unpack('<4f', file_object.read(16)), \
                                            struct.unpack('<4f', file_object.read(16)), \
                                            struct.unpack('<4f', file_object.read(16)))

    vertex_position_count = struct.unpack('<I', file_object.read(4))[0]

#    print "\tvertex position count %d" % vertex_position_count

    for x in xrange(vertex_position_count):
        position = Blender.Mathutils.Vector(struct.unpack('<3f', file_object.read(12)))

        mesh.verts.extend(position)

    face_count = struct.unpack('<I', file_object.read(4))[0]

#    print "\tface count %d" % face_count

    for x in xrange(face_count):
        mesh.faces.extend([mesh.verts[y] for y in struct.unpack('<3I', file_object.read(12))])

        face = mesh.faces[-1]

        face_uvs = []

        for y in xrange(len(face.verts)):
            uv = Blender.Mathutils.Vector(struct.unpack('<2f', file_object.read(8)))
            uv.y = float(1.0 - uv.y)

            face_uvs.append(uv)

            file_object.seek(4, 1)

        face.uv = tuple(face_uvs)

        file_object.seek(8, 1)

    material_index = 0

    if version >= 0x5005 and version <= 0x5007:
        # This is an assumption that these values are normals
        for face in mesh.faces:
            face_unknown_0 = Blender.Mathutils.Vector(struct.unpack('<3f', file_object.read(12)))

            for vertex in face.verts:
                vertex.no = Blender.Mathutils.Vector(struct.unpack('<3f', file_object.read(12)))

        temp_fix = face_count - len(mesh.faces)

        for x in xrange(temp_fix):
            file_object.seek(48, 1)

        vertex_color_count = struct.unpack('<I', file_object.read(4))[0]

#        print "\tvertex color count %d" % vertex_color_count

        vertex_colors = []

        for x in xrange(vertex_color_count):
            vertex_color = struct.unpack('<3f', file_object.read(12))

            vertex_colors.append([int(y * 255.0) for y in vertex_color])

        if vertex_color_count > 0:
            mesh.vertexColors = True

            for face in mesh.faces:
                for i, vertex in enumerate(face):
                    vertex_color = vertex_colors[vertex.index]

                    face_color = face.col[i]
                    face_color.r = vertex_color[0]
                    face_color.g = vertex_color[1]
                    face_color.b = vertex_color[2]

        material_index = struct.unpack('<I', file_object.read(4))[0]

#        print "\tmaterial index %d" % material_index

        bone_influence_count = struct.unpack('<I', file_object.read(4))[0]

#        print "\tbone influence count %d" % bone_influence_count

        for x in xrange(bone_influence_count):
            bone_influence_names = []

            for y in xrange(MAX_INFLUENCES):
                bone_influence_name = file_object.read(40)
                bone_influence_name = bone_influence_name[0:bone_influence_name.find('\0')]

                if len(bone_influence_name) > 0:
                    bone_influence_name = elu_to_blender_name(bone_influence_name)

                    bone_influence_names.append(bone_influence_name)

            bone_influence_weights = [y for y in struct.unpack('<8f', file_object.read(32)) if y > 0]

            # doesn't seem to be reliable... what might be needed is verifying if
            # the sum of the weights is 1.0 just to be safe
            count = struct.unpack('<I', file_object.read(4))[0]

            for y in xrange(len(bone_influence_weights)):
                mesh.addVertGroup(bone_influence_names[y])

                mesh.assignVertsToGroup(bone_influence_names[y], \
                                        [x],
                                        bone_influence_weights[y],
                                        Blender.Mesh.AssignModes.ADD)

            for y in xrange(MAX_INFLUENCES):
                a, b, c = struct.unpack('<3f', file_object.read(12))
#                print "\t\t%f, %f, %f" % (a, b, c)
    else:
        file_object.seek(4, 1)
        material_index = struct.unpack('<I', file_object.read(4))[0]

    if material_index < len(materials):
        material = materials[material_index]

        mesh.materials = [material]

        textures = material.getTextures()

        if len(textures) > 0:
            texture = textures[0].tex

            image = texture.getImage()

            for face in mesh.faces:
                face.mode = Blender.Mesh.FaceModes.TEX + Blender.Mesh.FaceModes.TWOSIDE
                face.image = image
        else:
            Blender.Draw.PupMenu("Warning%%t|Could not set material for %s mesh." % mesh_name)

    mesh_object.setMatrix(world_matrix * LEFT_TO_RIGHT)

    if len(parent_mesh_name) > 0:
        bip_check = boolean_xor(mesh_name.startswith('Bip'), parent_mesh_name.startswith('Bip'))

        if bip_check == False:
            parent_mesh_object = Blender.Object.Get(parent_mesh_name)
            parent_mesh_object.makeParent([mesh_object])

    print "mesh %s end 0x%x" % (mesh_name, file_object.tell())

    return mesh_object

def ani_read_mesh_transformations(file_object, armature_object):
    key_frames = {}

    armature_pose = armature_object.getPose()

    armature_pose_bones = armature_pose.bones

    unknown_0 = struct.unpack('<I', file_object.read(4))[0]

    mesh_name = file_object.read(40)

    mesh_name = mesh_name[0:mesh_name.find('\0')]

    mesh_name = elu_to_blender_name(mesh_name)

    print "transform %s start 0x%x" % (mesh_name, file_object.tell() - 80)

    pose_matrix = Blender.Mathutils.Matrix(struct.unpack('<4f', file_object.read(16)), \
                                           struct.unpack('<4f', file_object.read(16)), \
                                           struct.unpack('<4f', file_object.read(16)), \
                                           struct.unpack('<4f', file_object.read(16)))

    translation_count = struct.unpack('<I', file_object.read(4))[0]

#    print "translation count %d" % translation_count

    for y in xrange(translation_count):
        translation = Blender.Mathutils.Vector(struct.unpack('<3f', file_object.read(12)))

        key_frame_second = int(struct.unpack('<I', file_object.read(4))[0] / 60)

        key_frames[key_frame_second] = Blender.Mathutils.TranslationMatrix(translation)

    rotation_count = struct.unpack('<I', file_object.read(4))[0]

#    print "rotation count %d" % rotation_count

    for y in xrange(rotation_count):
        x, y, z, w = struct.unpack('<4f', file_object.read(16))

        rotation = Blender.Mathutils.Quaternion(w, x, y, z)

        key_frame_second = int(struct.unpack('<I', file_object.read(4))[0] / 60)

        if key_frame_second in key_frames:
            key_frames[key_frame_second] = rotation.toMatrix().resize4x4() * key_frames[key_frame_second]
        else:
            inverse_parent_pose_matrix = Blender.Mathutils.Matrix()
            inverse_parent_pose_matrix.identity()

            if mesh_name in armature_pose_bones.keys():
                if armature_pose_bones[mesh_name].parent is not None:
                    inverse_parent_pose_matrix = armature_pose_bones[mesh_name].parent.poseMatrix.copy() * LEFT_TO_RIGHT

            inverse_parent_pose_matrix.invert()

            key_frames[key_frame_second] = rotation.toMatrix().resize4x4() * Blender.Mathutils.TranslationMatrix((pose_matrix * inverse_parent_pose_matrix).translationPart())

    if mesh_name in armature_pose_bones.keys():
        if len(key_frames) > 0:
            for key_frame_second, key_frame_transformation in key_frames.iteritems():
                if armature_pose_bones[mesh_name].parent is not None:
                    key_frame_transformation *= (armature_pose_bones[mesh_name].parent.poseMatrix.copy() * LEFT_TO_RIGHT)

                armature_pose_bones[mesh_name].poseMatrix = key_frame_transformation * LEFT_TO_RIGHT
                armature_pose.update()
                armature_pose_bones[mesh_name].insertKey(armature_object, key_frame_second + 1)

            armature_pose_bones[mesh_name].poseMatrix = pose_matrix * LEFT_TO_RIGHT
            armature_pose.update()
        else:
            armature_pose_bones[mesh_name].poseMatrix = pose_matrix * LEFT_TO_RIGHT
            armature_pose.update()
            armature_pose_bones[mesh_name].insertKey(armature_object, 1)

    print "transform %s end 0x%x" % (mesh_name, file_object.tell())

def elu_import(file_path):
    file_object = None

    try:
        file_object = open(file_path, 'rb')

        data_chunk = file_object.read(16)

        magic, \
        version, \
        material_count, \
        mesh_count = struct.unpack('<4I', data_chunk)

        if magic != 0x0107F060:
            raise MagicError, "Bad magic number, %x" % magic

        print "version %d" % version

        if version not in ELU_VERSIONS and version not in ANI_VERSIONS:
            raise VersionError, "Bad version number %d" % version

        if (version >= 0x500E and version <= 0x5011) and material_count > 0:
            raise Error, "%d Materials, reverse me! %d" % (material_count, file_path)

        if version in ELU_VERSIONS:
            materials = []

            for x in xrange(material_count):
                material = elu_read_material(file_object)

                texture = elu_read_texture(file_object, version)

                if texture is not None:
                    material.setTexture(0, texture, Blender.Texture.TexCo.UV)

                    if texture.useAlpha == 1:
                        material.setMode(Blender.Material.Modes.TEXFACE + Blender.Material.Modes.TEXFACE_ALPHA)
                    else:
                        material.setMode(Blender.Material.Modes.TEXFACE)

                materials.append(material)

            mesh_objects = []

            if version >= 0x5004 and version <= 0x5007:
                for x in xrange(mesh_count):
                    mesh_objects.append(elu_read_mesh(file_object, materials, version))
            elif version >= 0x500E and version <= 0x5011:
                for x in xrange(mesh_count):
                    mesh_objects.append(elu_read_mesh2(file_object, x, version))
        elif version in ANI_VERSIONS:
            try:
                armature_object = Blender.Object.Get('Armature')
            except ValueError:
                Blender.Draw.PupMenu("Error%%t|The scene does not contain an armature.")
            else:
                scene = Blender.Scene.GetCurrent()

                action_name = Blender.sys.basename(file_object.name)
                action_name = action_name[0:action_name.find('.')]

                action = Blender.Armature.NLA.NewAction(action_name)
                action.setActive(armature_object)

                for x in xrange(mesh_count):
                    ani_read_mesh_transformations(file_object, armature_object)

                scene.update(0)
    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)
    else:
        scene = Blender.Scene.GetCurrent()

        if version in ELU_VERSIONS:
            armature_object = Blender.Object.New('Armature')

            armature_object.drawMode = Blender.Object.DrawModes.XRAY

            armature = armature_object.getData()

            if armature is None:
                armature = Blender.Armature.New('Armature')
                armature_object.link(armature)

            armature.drawType = Blender.Armature.STICK
            armature.envelopes = False
            armature.vertexGroups = True

            armature.makeEditable()

            for mesh_object in mesh_objects:
                mesh = mesh_object.getData(mesh = True)

                if len(mesh.getVertGroupNames()) > 0:
                    armature_object.makeParent([mesh_object])

                    armature_modifier = mesh_object.modifiers.append(Blender.Modifier.Types.ARMATURE)
                    armature_modifier[Blender.Modifier.Settings.OBJECT] = armature_object

                if mesh_object.name.startswith('Bip') == True:
                    edit_bone = Blender.Armature.Editbone()

                    edit_bone.name = mesh_object.name

                    parent_mesh_object = mesh_object.getParent()

                    if parent_mesh_object is not None:
                        edit_bone.parent = armature.bones[parent_mesh_object.name]

                    edit_bone.matrix = mesh_object.getMatrix()

                    armature.bones[edit_bone.name] = edit_bone

                    mesh.hide = True

                    mesh_object.setDrawMode(Blender.Object.DrawModes['TRANSP'])

                    if mesh.users == 0:
                        mesh.verts = None
                        mesh.faces = None

                    scene.objects.unlink(mesh_object)
                else:
                    scene.objects.link(mesh_object)

            armature.update()

            if len(armature.bones) > 0:
                scene.objects.link(armature_object)

                armature_pose = armature_object.getPose()

                armature_pose_bones = armature_pose.bones

                for armature_pose_bone in armature_pose_bones.values():
                    try:
                        mesh_object = Blender.Object.Get(armature_pose_bone.name)
                    except:
                        pass
                    else:
                        armature_pose_bone.displayObject = mesh_object
            else:
                scene.objects.unlink(armature_object)

        scene.update(0)
    finally:
        if file_object is not None:
            file_object.close()

def main():
    def elu_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:
            elu_import(file_path)

    Blender.Window.FileSelector(elu_file_selector, 'Ok', Blender.sys.makename(ext='.elu'))

if __name__ == "__main__":
    main()
 
Status
Not open for further replies.
Back
Top