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!

EBM Blender Importer

Experienced Elementalist
Joined
Aug 27, 2006
Messages
223
Reaction score
183
Completed Functionality:

  • Meshes
    • Sticky and Per-face UV Coordinates
    • Vertex Groups/Weights
  • Armature
  • Materials
  • Textures (Stored in your temporary directory)
  • Animations

Incomplete Functionality:

  • Define unknowns

Installation:

  1. Download and install Blender 2.49b from
  2. Download and install Python 2.7.x from (Windows Users)
  3. Copy and paste embedded source code and save as ebm_import.py in your .

Usage:

  1. Click File > Import > CABAL (*.ebm)
  2. Select *.ebm file
  3. Click Ok

License:

Source:
Copy and save as: ebm_import.py

Code:
#!BPY

# Copyright (c) 2007-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.
#
# -----------------------------------------------------------------------------
#
# Version 0.0.1
#     * Initial release
#
# Version 0.0.2
#     * Fixed setting face mode to double sided
#     * Fixed mirroring the UV coordinates
#     * Fixed reading vertex influences
#     * Added setting material mode to texture face with alpha
#
# Version 0.0.3
#     * Fixed importing textures in Microsoft Windows
#
# Version 0.0.4
#     * Fixed armature edit bone matrix
#     * Added animation importing

"""
Name: 'CABAL (.ebm)...'
Blender: 246
Group: 'Import'
Tooltip: 'Import CABAL game (*.ebm) files'
"""

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


import Blender
import struct
import tempfile
import math
import re


EBM_BONE_NAMES = []


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


class MagicError(ValueError):
    pass


def ebm_read_material(file_object):
    diffuse = struct.unpack('<4f', file_object.read(16))
    ambient = struct.unpack('<4f', file_object.read(16))
    specular = struct.unpack('<4f', file_object.read(16))
    emissive = struct.unpack('<4f', file_object.read(16))
    power = struct.unpack('<f', file_object.read(4))[0]
    
    material = Blender.Material.New()
    
    material.setRGBCol(diffuse[0:3])
    material.setAlpha(diffuse[3])
    material.setMirCol(ambient[0:3])
    material.setAmb(ambient[3])
    material.setSpecCol(specular[0:3])
    material.setSpec(power)
    material.setEmit(emissive[3])
    
    return material


def ebm_read_texture(file_object):
    name_length = struct.unpack('<H', file_object.read(2))[0]
    
    name = file_object.read(name_length)
    
    texture_data_size = struct.unpack('<I', file_object.read(4))[0]
    
    texture_data = file_object.read(texture_data_size)
    
    file_object.read(26) # ?, 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 04 00 00 00 DXT3
    
    # Clean the file name
    rec = re.compile('[^\w\.]*')
    name = rec.sub('', name)
    # Create a temporary texture file
    texture_file = open(Blender.sys.join(tempfile.gettempdir(), name), 'wb')
    texture_file.write(texture_data)
    texture_file.close()
    
    texture = None
    
    try:
        texture = Blender.Texture.Get(name)
    except:
        texture = Blender.Texture.New(name)
        texture.setType('Image')
        
        image = None
        
        try:
            image = Blender.Image.Get(name)
        except:
            try:
                image = Blender.Image.Load(Blender.sys.join(tempfile.gettempdir(), name))
            except:
                raise
        finally:
            if image is not None:
                texture.setImage(image)
    
    return texture


def ebm_read_mesh(file_object, materials):
    name_length = struct.unpack('<H', file_object.read(2))[0]
    
    name = file_object.read(name_length)
    
    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)))
    
    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)))
    
    unknown_0 = struct.unpack('<I', file_object.read(4))[0] # 0xFFFFFF
    
    material_index = struct.unpack('<B', file_object.read(1))[0]
    
    vertex_count = struct.unpack('<H', file_object.read(2))[0]
    
    face_count = struct.unpack('<H', file_object.read(2))[0]
    
    if vertex_count == 0 or face_count == 0:
        return None
    
    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
    
    material = materials[material_index]
    
    mesh.materials = [material]
    
    textures = material.getTextures()
    
    image = None
    
    if len(textures) > 0:
        texture = textures[0].tex
        
        image = texture.getImage()
    
    for x in xrange(vertex_count):
        position = Blender.Mathutils.Vector(struct.unpack('<3f', file_object.read(12)))
        normal = Blender.Mathutils.Vector(struct.unpack('<3f', file_object.read(12)))
        uv = Blender.Mathutils.Vector(struct.unpack('<2f', file_object.read(8)))
        
        mesh.verts.extend(position)
        
        vertex = mesh.verts[-1]
        vertex.no = normal
        vertex.uvco = uv
        vertex.uvco[1] = 1.0 - vertex.uvco[1]
    
    for x in xrange(face_count):
        mesh.faces.extend([mesh.verts[y] for y in struct.unpack('<3H', file_object.read(6))])
        
        face = mesh.faces[-1]
        face.uv = [vertex.uvco for vertex in face.verts]
        
        if image is not None:
            face.mode = Blender.Mesh.FaceModes.TEX + Blender.Mesh.FaceModes.TWOSIDE
            face.image = image
    
    mesh.faceUV = True
    
    mesh_object.setMatrix(LEFT_TO_RIGHT) # mesh_object.setMatrix(world_matrix)
    
    return mesh_object


def ebm_read_influence(file_object, mesh, armatures):
    armature_object = armatures[-1]
    
    mesh_object = mesh
    
    armature_object.makeParent([mesh_object])
    
    armature_modifier = mesh_object.modifiers.append(Blender.Modifier.Types.ARMATURE)
    armature_modifier[Blender.Modifier.Settings.OBJECT] = armature_object
    
    armature = armature_object.getData()
    
    mesh = mesh_object.getData(mesh = True)
    
    for x in xrange(0, len(EBM_BONE_NAMES)):
        vertex_influences_count = struct.unpack('<I', file_object.read(4))[0]
        
        group_id = EBM_BONE_NAMES[x]
        
        mesh.addVertGroup(group_id)
        
        if vertex_influences_count != 0:
            vertex_influences = []
            
            for y in xrange(vertex_influences_count):
                vertex_index = struct.unpack('<I', file_object.read(4))[0]
                vertex_influences.append(vertex_index)
            
            for y in xrange(vertex_influences_count):
                vertex_weight = struct.unpack('<f', file_object.read(4))[0]
                mesh.assignVertsToGroup(group_id, \
                                        [vertex_influences[y]], \
                                        vertex_weight, \
                                        Blender.Mesh.AssignModes.ADD)
#        else: # problems on bike_10, comment out
#                mesh.assignVertsToGroup(group_id, \
#                                        [vertex.index for vertex in mesh.verts], \
#                                        1.0, \
#                                        Blender.Mesh.AssignModes.ADD)


def ebm_read_bone(file_object, bones):
    global EBM_BONE_NAMES
    
    name_length = struct.unpack('<H', file_object.read(2))[0]
    
    name = file_object.read(name_length)
    
    parent_bone_index = struct.unpack('<I', file_object.read(4))[0]
    
    armature_space_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)))
    
    parent_armature_space_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)))
    
    armature_space_matrix.invert()
    
    edit_bone = Blender.Armature.Editbone()
    
    edit_bone.name = name
    
    edit_bone.matrix = armature_space_matrix

    if parent_bone_index != 0xFFFFFFFF:
        edit_bone.parent = bones[parent_bone_index]
    
    bones.append(edit_bone)
    
    EBM_BONE_NAMES.append(name)
    
    return edit_bone


def ebm_read_animation(file_object, magic, armatures):
    name_length = struct.unpack('<H', file_object.read(2))[0]
    
    name = file_object.read(name_length)
    
    armature_object = armatures[-1]#EBM_ARMATURES[-1]
    
    armature = armature_object.getData()
    
    action = Blender.Armature.NLA.NewAction(name)
    action.setActive(armature_object)
    
#    ipo = Blender.Ipo.New('Object', name)
    
    armature_pose = armature_object.getPose()
    
    armature_pose_bones = armature_pose.bones
    
    bone_count = struct.unpack('<H', file_object.read(2))[0]
    
    for x in xrange(bone_count):
        bone_name_length = struct.unpack('<H', file_object.read(2))[0]
        
        bone_name = file_object.read(bone_name_length)
        
        translation_count = struct.unpack('<I', file_object.read(4))[0]
        
        key_frames = {}
        
        for y in xrange(translation_count):
            key_frame_second = struct.unpack('<f', file_object.read(4))[0]
            
            x, y, z = struct.unpack('<3f', file_object.read(12))
            
            key_frame_index = int(math.floor(key_frame_second * 100))
            
            if key_frame_index < 1:
                key_frame_index = 1
            
            translation = Blender.Mathutils.Vector(x, y, z)
            
            key_frames[key_frame_index] = Blender.Mathutils.TranslationMatrix(translation)
        
        rotation_count = struct.unpack('<I', file_object.read(4))[0]
        
        for y in xrange(rotation_count):
            key_frame_second = struct.unpack('<f', file_object.read(4))[0]
            
            x, y, z, w = struct.unpack('<4f', file_object.read(16))
            
            key_frame_index = int(math.floor(key_frame_second * 100))
            
            if key_frame_index < 1:
                key_frame_index = 1
            
            xx = x * x
            xy = x * y
            xz = x * z
            xw = x * w
            
            yy = y * y
            yz = y * z
            yw = y * w
            
            zz = z * z
            zw = z * w
            
            rotation_matrix = Blender.Mathutils.Matrix([1.0 - 2.0 * (yy + zz), 2.0 * (xy - zw), 2.0 * (xz + yw), 0.0], \
                                                       [2.0 * (xy + zw), 1.0 - 2.0 * (xx + zz), 2.0 * (yz - xw), 0.0], \
                                                       [2.0 * (xz - yw), 2.0 * (yz + xw), 1.0 - 2.0 * (xx + yy), 0.0], \
                                                       [0.0, 0.0, 0.0, 1.0])
            
            if key_frame_index in key_frames:
                key_frames[key_frame_index] = rotation_matrix * key_frames[key_frame_index]
            else:
                bone = armature.bones[bone_name]
                
                rest_bone_matrix = bone.matrix['ARMATURESPACE'].copy()
                
                if bone.parent is not None:
                    parent_bone = bone.parent
                    
                    parent_rest_bone_matrix = parent_bone.matrix['ARMATURESPACE'].copy()
                    
                    parent_rest_bone_matrix.invert()
                    
                    rest_bone_matrix *= parent_rest_bone_matrix
                
                translation = rest_bone_matrix.translationPart()
                
                translation_matrix = Blender.Mathutils.TranslationMatrix(translation)
                
                key_frames[key_frame_index] = rotation_matrix * translation_matrix
        
        if bone_name in armature.bones.keys():
            for key_frame_index, key_frame_transformation in key_frames.iteritems():
                local_matrix = key_frame_transformation.copy()
                
                bone = armature.bones[bone_name]
                
                rest_bone_matrix = bone.matrix['ARMATURESPACE'].copy()
                
                if bone.parent is not None and magic != 0x3EF03:
                    parent_bone = bone.parent
                    
                    parent_rest_bone_matrix = parent_bone.matrix['ARMATURESPACE'].copy()
                    
                    parent_rest_bone_matrix.invert()
                    
                    local_matrix *= (rest_bone_matrix * parent_rest_bone_matrix).invert()
                else:
                    rest_bone_matrix.invert()
                    
                    local_matrix *= rest_bone_matrix
                
                armature_pose_bones[bone_name].localMatrix = local_matrix
                armature_pose_bones[bone_name].insertKey(armature_object, key_frame_index, [Blender.Object.Pose.ROT, Blender.Object.Pose.LOC])
#        else:
#            mesh_object = Blender.Object.Get(bone_name)
#            
#            mesh_object.setIpo(ipo)
#            
#            for key_frame_index, key_frame_transformation in key_frames.iteritems():
#                Blender.Set("curframe", key_frame_index)
#                
#                mesh_object.setMatrix(key_frame_transformation)
#                
#                mesh_object.insertIpoKey(Blender.Object.LOCROT)
#            
#            Blender.Set("curframe", 1)
    
    armature_pose.update()


def ebm_read_material_chunk(file_object, materials):
    material_count = struct.unpack('<H', file_object.read(2))[0]
    
    for x in xrange(material_count):
        material = ebm_read_material(file_object)
        texture = ebm_read_texture(file_object)
        
        if texture is not None:
            material.setTexture(0, texture, Blender.Texture.TexCo.UV)
            material.setMode(Blender.Material.Modes.TEXFACE + Blender.Material.Modes.TEXFACE_ALPHA)
        
        materials.append(material)


def ebm_read_influence_chunk(file_object, mesh, armatures):
    influence_count = struct.unpack('<H', file_object.read(2))[0]
    
    for x in xrange(influence_count):
        ebm_read_influence(file_object, mesh, armatures)


def ebm_read_mesh_chunk(file_object, materials, meshes, armatures):
    mesh_count = struct.unpack('<H', file_object.read(2))[0]
    
    for x in xrange(mesh_count):
        mesh_object = ebm_read_mesh(file_object, materials)
        
        if mesh_object is not None:
            chunk_id = struct.unpack('<I', file_object.read(4))[0]
            
            if chunk_id == 0x41470205:
                ebm_read_influence_chunk(file_object, mesh_object, armatures)
            else: # WTF? fix...
                file_object.seek(-5, os.SEEK_CUR)
            
            meshes.append(mesh_object)


def ebm_read_armature_chunk(file_object):
    bone_count = struct.unpack('<H', file_object.read(2))[0]
    
    armature_object = Blender.Object.New('Armature')
    
    armature_object.drawMode = Blender.Object.DrawModes.XRAY
    
    armature = armature_object.getData()
    
    if armature is None:
        base_name = Blender.sys.basename(file_object.name)
        
        armature_name = Blender.sys.splitext(base_name)[0]
        
        armature = Blender.Armature.New(armature_name)
        
        armature_object.link(armature)
    
    armature.drawType = Blender.Armature.STICK
    armature.envelopes = False
    armature.vertexGroups = True
    
    armature.makeEditable()
    
    bones = []
    
    for x in xrange(bone_count):
        edit_bone = ebm_read_bone(file_object, bones)
        
        armature.bones[edit_bone.name] = edit_bone
    
    armature_object.setMatrix(LEFT_TO_RIGHT)
    
    armature.update()
    
    return armature_object


def ebm_read_animation_chunk(file_object, magic, armatures):
    animation_count = struct.unpack('<H', file_object.read(2))[0]
    
    for x in xrange(animation_count):
        ebm_read_animation(file_object, magic, armatures)


def ebm_import(file_path):
    file_object = None
    
    materials = []
    meshes = []
    armatures = []
    
    try:
        Blender.Window.WaitCursor(1)
        
        file_object = open(file_path, 'rb')
        
        magic = struct.unpack('<I', file_object.read(4))[0]
        
        if magic != 0x3ED03 and \
           magic != 0x3EE03 and \
           magic != 0x3EF03:
            raise MagicError, "Bad magic number, %08x" % magic
        
        print hex(magic)
        
        unknown_0 = struct.unpack('<H', file_object.read(2))[0] # 0x100 (256)
        
        unknown_1 = struct.unpack('<I', file_object.read(4))[0] # ?
        
        bounding_box_min = Blender.Mathutils.Vector(struct.unpack('<3f', file_object.read(12)))
        
        bounding_box_max = Blender.Mathutils.Vector(struct.unpack('<3f', file_object.read(12)))
        
        unknown_2 = struct.unpack('<I', file_object.read(4))[0] # 0x64 (100)
        
        while True:
            data = file_object.read(4)
            
            if len(data) == 0: # Clean break
                break
            
            chunk_id = struct.unpack('<I', data)[0]
            
            if chunk_id == 0x41470201:
                ebm_read_material_chunk(file_object, materials)
                continue
            
            if chunk_id == 0x41470202:
                ebm_read_mesh_chunk(file_object, materials, meshes, armatures)
                continue
            
            if chunk_id == 0x41470203:
                armature_object = ebm_read_armature_chunk(file_object)
                
                armatures.append(armature_object)
                continue
            
            if chunk_id == 0x41470204:
                ebm_read_animation_chunk(file_object, magic, armatures)
                continue
    except IOError:
        raise
    else:
        scene = Blender.Scene.GetCurrent()
        
        for mesh_object in meshes:
            scene.objects.link(mesh_object)
        
        for armature_object in armatures:
            scene.objects.link(armature_object)
    finally:
        if file_object is not None:
            file_object.close()
        
        Blender.Window.WaitCursor(0)


def main():
    def ebm_file_selector(file_path):
        if file_path and \
           not Blender.sys.exists(file_path):
            Blender.Draw.PupMenu("Warning%%t|The file %s does not exist." % file_path)
        else:
            ebm_import(file_path)
    
    Blender.Window.FileSelector(ebm_file_selector, 'Ok', Blender.sys.makename(ext='.ebm'))


if __name__ == "__main__":
    main()

Collaboration:
Check out the list of other importers and exporters RZ Project Listing
 
Last edited:
Banned
Banned
Joined
Sep 6, 2007
Messages
834
Reaction score
167
Thank you, i have problems after press CABAL .ebm in Import
 
Banned
Banned
Joined
Sep 6, 2007
Messages
834
Reaction score
167
Compiled with Python version 2.5.
'import site' failed; use -v for traceback
Checking for installed Python... No installed Python found.
Only built-in modules are available. Some scripts may not run.
Continuing happily.
Traceback (most recent call last):
File "<string>", line 41, in <module>
ImportError: No module named tempfile

found it, is needed to edit the py file?
 
Experienced Elementalist
Joined
Aug 27, 2006
Messages
223
Reaction score
183
found it, is needed to edit the py file?

Thankfully no, but you need to install python 2.5.x, . I will add the requirement to the installation instructions because most Windows users will probably need to install it.

FYI, I use the tempfile module to get the systems temporary files directory to store the embedded DDS texture images. You can go to the directory and view them with .
 
Banned
Banned
Joined
Sep 6, 2007
Messages
834
Reaction score
167
Thank you phantom, i will check it in some minuts and report here.
 
Banned
Banned
Joined
Sep 6, 2007
Messages
834
Reaction score
167
Yah phantom, needed the phyton, now working sucefully ^^
Thank you.
 
Mythic Archon
Loyal Member
Joined
Feb 1, 2008
Messages
719
Reaction score
10
Phantom do you got plans to make a EBM exporter to?
 
Banned
Banned
Joined
Oct 20, 2006
Messages
3,245
Reaction score
1,652
I'm getting texture problems after importing. The model itself imports perfectly, but the textures are all screwed up. They look like a ton of coloured blocks...
 
Experienced Elementalist
Joined
Aug 27, 2006
Messages
223
Reaction score
183
Wow Phantom* working on Cabal now ?

I'm not working on it per se. The viral FrienzNetwork advertisements on this forum worked, and so I downloaded the client. I don't play any of the games, but this one is a first in that I've never got to the point where I needed to run the client (It's a good thing because the format is simple and well structured), atleast for now... It's all in good fun and my way of playing without playing.

Phantom do you got plans to make a EBM exporter to?

Yes, once the animation importing is complete. I always stress that you can't write an exporter without an importer. I use an importer as a test suite so it's critical it works somewhat correctly.

I'm getting texture problems after importing. The model itself imports perfectly, but the textures are all screwed up. They look like a ton of coloured blocks...

I have no reasoning towards why this would be. As you can see from the showcase, I've had no problems. You may want to try manually importing a DDS texture and if it continues, report a bug through the Blender bug tracker.
 
Experienced Elementalist
Joined
Aug 27, 2006
Messages
223
Reaction score
183
Version 0.0.3: Bug fix release
  • Fixed importing textures for Microsoft Windows
http://forum.ragezone.com/showpost.php?p=3873814&postcount=1


I'm getting texture problems after importing. The model itself imports perfectly, but the textures are all screwed up. They look like a ton of coloured blocks...

I've re-reviewed your problem and fixed it in version 0.0.3

how going friend?

I've been in hiatus enjoying the last moments of the summer. I've written an exporter and it's currently being tested.

Where are the mithrill items located-martialsuit. I mean i see eveything else, i wanted to edit the colors..

Please don't hijack this thread with unrelated material.
 
Newbie Spellweaver
Joined
Jun 7, 2007
Messages
44
Reaction score
1
i have problems after press CABAL .ebm in Import
 
Experienced Elementalist
Joined
Aug 27, 2006
Messages
223
Reaction score
183
Re-uploaded! Leave my inbox alone :p I've also noticed I worked on an exporter but for the life of me can't remember doing so. It looks like I stopped at animation exporting which makes sense since I couldn't get importing working. If anyone is interested go to this . I take it you can export static objects but don't take my word for it.

i have problems after press CABAL .ebm in Import

Looks like they introduced a new format.

could someone upload this script to rapidshare so it won't die anymore?
Thanks in advance.

Sorry but Rapidshare does not provide anonymity to its users.
 
Last edited:
Banned
Banned
Joined
Oct 20, 2006
Messages
3,245
Reaction score
1,652
Nice work so far on the exporter. I was working on my own exporter, but was having issues with the whole "windows likes to export 0x0A as 0x0D0A" crap. Anyways, just wanted to point something out and ask you a quick question.
You forgot to export the empty chunks :p
Also, do you have any idea why the UV coords get screwed up after exporting a model I've been working on? I was having the same issue with my exporter, and I'm guessing it has something to do with Blender not creating sticky UV coords from the model's face UV coords correctly? Oh, and the exported model is being rotated by 90
 
Last edited:
Newbie Spellweaver
Joined
Jun 4, 2007
Messages
17
Reaction score
0
Can you reupload it again to the same place or post it here?
Thanks in advance :)
 
Banned
Banned
Joined
Oct 20, 2006
Messages
3,245
Reaction score
1,652
I've updated Phantom*'s exporter script (I lost mine when my backup partition was corrupted) to convert per-face UV's to per-vertex UV's if the mesh doesn't have per-vertex (sticky) UV coordinates. Later I'll be editing the script so that it exports empty chunks (which CABAL requires), so I'll upload it later if Phantom* is OK with it.
 
Experienced Elementalist
Joined
Aug 27, 2006
Messages
223
Reaction score
183
I've updated Phantom*'s exporter script (I lost mine when my backup partition was corrupted) to convert per-face UV's to per-vertex UV's if the mesh doesn't have per-vertex (sticky) UV coordinates. Later I'll be editing the script so that it exports empty chunks (which CABAL requires), so I'll upload it later if Phantom* is OK with it.

Thanks you for being the first person to ever openly contribute to any of my projects here on Rage Zone. It's open source and the only implications in the MIT license are:

"The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software."

BTW what empty chunks? Has something changed in the format from my inital importer or did I miss it from the beginning?
 
Last edited:
Banned
Banned
Joined
Oct 20, 2006
Messages
3,245
Reaction score
1,652
BTW what empty chunks? Has something changed in the format from my inital importer or did I miss it from the beginning?

Basically, even if a model has no bones or animations, the EBM should still contain the bone/animation/influence chunks. Even though they're practically empty chunks, CABAL still needs them. BTW, I've found a flag in EBM files that handles the texture. The flag tells CABAL whether to use the alpha layer for the model glow or whether to actually display the alpha, and it can also be used to give the texture an additive-like blend effect. This is how the header should look:
Code:
uint32 Magic <format=hex>;
uint16 unk_0 <format=hex>;
FLAG Model_Flag <format=hex>;
Vec3D bound_min;        //  Bounding box lower vertex
Vec3D bound_max;        //  Bounding box upper vertex
uint32 unk_2 <format=hex>;
CID chunk_id <format=hex>;      //  ID for the next chunk

Now, my question is, does Blender support texture blending modes like "additive"? I know there's an option to use the alpha layer on a model or not, but I don't know if there's a texture-blending mode option.
 
Back
Top