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

Newbie Spellweaver
Joined
Jul 9, 2011
Messages
15
Reaction score
0
is there anyone of you already make your unique item using this tools?
 
Banned
Banned
Joined
Oct 20, 2006
Messages
3,245
Reaction score
1,652
Please start paying attention to what we tell you, pingfreak. This is just an importer. I have explained how to make custom models before in my OBJ -> EBM converter thread.
 
Elite Diviner
Joined
Jul 27, 2009
Messages
478
Reaction score
411
ebm_import.py Links die . :/ Please try upload links.
Please read the full OP, it states that you need to copy and paste the enclosed code into a text editor (ex. notepad) and save it as ebm_import.py. There is no download.
 
Initiate Mage
Joined
Feb 25, 2012
Messages
2
Reaction score
0
Please read the full OP, it states that you need to copy and paste the enclosed code into a text editor (ex. notepad) and save it as ebm_import.py. There is no download.

I'm doing, but does not read
 
Newbie Spellweaver
Joined
Jun 2, 2012
Messages
6
Reaction score
0
Which one O.O?
Phantom* - EBM Blender Importer - RaGEZONE Forums
 
Experienced Elementalist
Joined
Sep 7, 2011
Messages
217
Reaction score
15
*File "C:\downloads\blender-2.49b-win64-python26\.blender\scripts\ebm_import.py", line 58, in <module>
Import Struct
ImportError: no Module Named Stcruct

UPDATE: I got it , need python 2.6.1 ^^ :).
 
Last edited by a moderator:
Initiate Mage
Joined
Nov 2, 2012
Messages
1
Reaction score
0
Sr Yamachi, I was able to import the model and it is like expected but in my case the model is coming without the textures or i am not knowing how to make it appear. I am a solidworks user... in blender I know nothing... if you may help me solving that I will really enjoy.

Thank you!
 
Initiate Mage
Joined
Jan 3, 2013
Messages
1
Reaction score
0
its don't work in windows 64?
I normally used on my old computer
 
Initiate Mage
Joined
Jan 25, 2013
Messages
1
Reaction score
0
I dnt get this working ._.


I installed Blender 2.49b and python 2.6.1 and copy the ebm_import ind the script direction but Cabal dont show in File-->Import

What is wrong ?
 
Initiate Mage
Joined
Mar 31, 2013
Messages
2
Reaction score
0
Hi,

There is a way to import in Blender ALL model animations ?
I'm asking this because after importing every Cabal monster model in blender (2.49+ Python 2.54), only a DEATH animation is imported - so no walking, attack etc.

Thanks for script and any help!
 
Elite Diviner
Joined
Jul 27, 2009
Messages
478
Reaction score
411
Hi,

There is a way to import in Blender ALL model animations ?
I'm asking this because after importing every Cabal monster model in blender (2.49+ Python 2.54), only a DEATH animation is imported - so no walking, attack etc.

Thanks for script and any help!

All animations included into the EBM file should be loaded when importing. You need to select the animation you want to see in blender. I don't have it installed here but this should give you an idea of where to look for the list of imported animations.
 
Initiate Mage
Joined
Mar 31, 2013
Messages
2
Reaction score
0
Thanks for help, but after importing every EBM that surely must have many animation sequences(ex. monster), i cant see in Blender any menu like in the jpg image you attached.
It seems to be a script related menu, but i didnt found anything like you explained.
The script does not have an option to choose witch animation to import, so i suppose it does import all the animations, but how to select an specific animation in Blender?
 
Elite Diviner
Joined
Jul 27, 2009
Messages
478
Reaction score
411
That image was from a newer version of blender so maybe not the best reference but I've made a screenshot myself which should help you out. When you have imported your EBM go and set one of the view ports as the action editor and select the skeleton in the 3D view. You should then be able to see that drop down list with all the animations in the EBM file.
 

eci

Experienced Elementalist
Joined
Sep 20, 2013
Messages
229
Reaction score
195
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

Nice release man.. :)
Great Software..!!
Before 10min I exported from Blender: 'Armature' and 'Bone Sistem' of bike_24.ebm... after that i imported both in 3d Studio Max..

test2.PNG - EBM Blender Importer - RaGEZONE Forums test1.PNG - EBM Blender Importer - RaGEZONE Forums

All animation...everything works as it should work..
I'm working on something really huge.. :)
I would not have done it without your release..
 

Attachments

You must be registered for see attachments list
Banned
Banned
Joined
Aug 2, 2011
Messages
1,427
Reaction score
979
Nice release man.. :)
Great Software..!!
Before 10min I exported from Blender: 'Armature' and 'Bone Sistem' of bike_24.ebm... after that i imported both in 3d Studio Max..

View attachment 137539 View attachment 137540

All animation...everything works as it should work..
I'm working on something really huge.. :)
I would not have done it without your release..

nice release bike !!!!!!!
 
Back
Top