Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
blender python script help
11-03-2008, 03:52 PM,
#8
 
Hi,
the texture name is only stored in the list.txt.
I've tried to write a script that loads joe files directly into blender and one to load the entire list.txt if the joe files are unpacked to the same directory with joepack.
I didn't succeed to get the normals right, but otherwise it seems to work.
And the faces in the track models seem to face in the opposite direction as the cars (cw vs ccw), perhaps that's because the normals are not imported, but i don't know really.
The scripts are based on the joe-exporter and md2-importer, and are my first experience with python.


import-joe.py
Code:
#!BPY

"""
Name: 'JOE (.joe)'
Blender: 239
Group: 'Import'
Tooltip: 'Import JOE file format. (.joe)'
"""
######################################################
# JOE Importer
# By:    Rikard Öxler, based on JOE exporter by Joe Venzon
#        and    MD2 importer by Bob Holcomb
# Date:    1 NOV 08
# Ver:    0.1
######################################################
# This script imports a JOE file, textures,
# and animations from blender.
######################################################

import Blender
from Blender import Mesh, Object, sys
from Blender.BGL import *
from Blender.Draw import *
from Blender.Window import *
from Blender.Mathutils import Vector
import struct
import sys
from types import *


######################################################
# Main Body
######################################################

#returns the string from a null terminated string
def asciiz (s):
  n = 0
  while (ord(s[n]) != 0):
    n = n + 1
  return s[0:n]


######################################################
# JOE Model Constants
######################################################
JOE_MAX_TRIANGLES=4096
JOE_MAX_VERTICES=2048
JOE_MAX_TEXCOORDS=2048
JOE_MAX_FRAMES=512
JOE_MAX_SKINS=32
JOE_MAX_FRAMESIZE=(JOE_MAX_VERTICES * 4 + 128)

######################################################
# JOE data structures
######################################################
class joe_alias_triangle(object):
    __slots__ = 'vertices',
    binary_format="<fff" #little-endian (<), 3 Unsigned char
    
    def __init__(self):
        self.vertices=[0]*3


    def load(self, file):
        temp_data = file.read(struct.calcsize(self.binary_format))
        data = struct.unpack(self.binary_format, temp_data)
        self.vertices[0]=data[0]
        self.vertices[1]=data[1]
        self.vertices[2]=data[2]
        return self

    def dump(self):
        print "JOE Alias_Triangle Structure"
        print "vertex: ", self.vertices[0]
        print "vertex: ", self.vertices[1]
        print "vertex: ", self.vertices[2]
        print ""

class joe_face(object):
    
    binary_format="<3h3h3h" #little-endian (<), 3 short, 3 short
    
    __slots__ = 'vertex_index', 'normal_index', 'texture_index'
    
    def __init__(self):
        self.vertex_index = [ 0, 0, 0 ]
        self.normal_index = [ 0, 0, 0 ]
        self.texture_index = [ 0, 0, 0]

    def load (self, file):
        temp_data=file.read(struct.calcsize(self.binary_format))
        data=struct.unpack(self.binary_format, temp_data)
        self.vertex_index[0]=data[0]
        self.vertex_index[1]=data[1]
        self.vertex_index[2]=data[2]
        self.normal_index[0]=data[3]
        self.normal_index[1]=data[4]
        self.normal_index[2]=data[5]
        self.texture_index[0]=data[6]
        self.texture_index[1]=data[7]
        self.texture_index[2]=data[8]
        return self

    def dump (self):
        print "JOE Face Structure"
        print "vertex index: ", self.vertex_index[0]
        print "vertex index: ", self.vertex_index[1]
        print "vertex index: ", self.vertex_index[2]
        print "normal index: ", self.normal_index[0]
        print "normal index: ", self.normal_index[1]
        print "normal index: ", self.normal_index[2]
        print "texture index: ", self.texture_index[0]
        print "texture index: ", self.texture_index[1]
        print "texture index: ", self.texture_index[2]
        print ""

class joe_tex_coord(object):
    __slots__ = 'u', 'v'
    binary_format="<2f" #little-endian (<), 2 float
    
    def __init__(self):
        self.u=0
        self.v=0

    def load (self, file):
        temp_data=file.read(struct.calcsize(self.binary_format))
        data=struct.unpack(self.binary_format, temp_data)
        self.u=data[0]
        self.v=data[1]
        return self

    def dump (self):
        print "JOE Texture Coordinate Structure"
        print "texture coordinate u: ",self.u
        print "texture coordinate v: ",self.v
        print ""


class joe_skin(object):
    __slots__ = 'name'
    binary_format="<64s" #little-endian (<), char[64]

    def __init__(self):
        self.name=""

    def load (self, file):
        temp_data=file.read(struct.calcsize(self.binary_format))
        data=struct.unpack(self.binary_format, temp_data)
        self.name=asciiz(data[0])
        return self

    def dump (self):
        print "JOE Skin"
        print "skin name: ",self.name
        print ""

class joe_alias_frame(object):
    __slots__ = 'faces', 'verts', 'texcoords', 'normals',\
    'num_vertices', 'num_normals', 'num_texcoords'
    '''
    num_vertices=0
    num_normals=0
    num_texcoords=0
    '''
    binary_format="<3i" #little-endian (<), 3 integers
    #num_vertices=0
    #num_texcoords=0
    #num_normals=0


    def __init__(self):
        self.faces=[]
        self.verts=[]
        self.texcoords=[]
        self.normals=[]

    def load (self, file):
        temp_data=file.read(struct.calcsize(self.binary_format))
        data=struct.unpack(self.binary_format, temp_data)
        self.num_vertices=data[0]
        self.num_texcoords=data[1]
        self.num_normals=data[2]
        for i in xrange(0, self.num_vertices):
            self.verts.append(joe_alias_triangle())
        for i in xrange(0, self.num_normals):
            self.normals.append(joe_alias_triangle())
        for i in xrange(0, self.num_texcoords):
            self.texcoords.append(joe_tex_coord())

        for i in xrange(0, self.num_vertices):
            self.verts[i].load(file)
            #self.verts[i].dump()
        for i in xrange(0, self.num_normals):
            self.normals[i].load(file)
            #self.normals[i].dump()
        for i in xrange(0, self.num_texcoords):
            self.texcoords[i].load(file)
            #self.texcoords[i].dump()
        return self

    def dump (self):
        print "JOE Alias Frame"
        print "number of verts: ",self.num_vertices
        print "number of texcoords",self.num_texcoords
        print "number of normals ",self.num_normals
        print ""

class joe_obj(object):
    __slots__ =\
    'frames',\
    'ident', 'version',\
    'num_faces',\
    'num_frames',\
    'skin_width', 'skin_height', 'num_skins',
    
    
    '''
    #Header Structure
    ident=0                #int 0    This is used to identify the file
    version=0            #int 1    The version number of the file (Must be 8)
    num_faces=0            #int 8    The number of faces (polygons)
    num_frames=0        #int 10    The number of animation frames
    '''
    binary_format="<4i"  #little-endian (<4> 0:
#        for i in xrange(0,joe.num_skins):
#            joe.skins[i].dump()
#            if (Blender.sys.exists(joe.skins[i].name)):
#                try:    return Blender.Image.Load(joe.skins[i].name)
#                except:    return -1
    

def animate_joe(joe, mesh):
    ######### Animate the verts through keyframe animation
    
    # Fast access to the meshes vertex coords
    verts = [v.co for v in mesh.verts]
    scale = g_scale.val
    
    for i in xrange(1, joe.num_frames):
        frame = joe.frames[i]
        #update the vertices
        for j in xrange(joe.num_vertices):
            x=(frame.verts[j].vertices[0]) * scale
            y=(frame.verts[j].vertices[1]) * scale
            z=(frame.verts[j].vertices[2]) * scale
            
            #put the vertex in the right spot
            verts[j][:] = y,-x,z
            
        mesh.insertKey(i,"absolute")
        # mesh.insertKey(i)
        
        #not really necissary, but I like playing with the frame counter
        Blender.Set("curframe", i)
    
    
    # Make the keys animate in the 3d view.
#    key = mesh.key
#    key.relative = False
    
    # Add an IPO to teh Key
#    ipo = Blender.Ipo.New('Key', 'joe')
#    key.ipo = ipo
    # Add a curve to the IPO
#    curve = ipo.addCurve('Basis')
    
    # Add 2 points to cycle through the frames.
#    curve.append((1, 0))
#    curve.append((joe.num_frames, (joe.num_frames-1)/10.0))
#    curve.interpolation = Blender.IpoCurve.InterpTypes.LINEAR
    


def load_joe(joe_filename, texture_filename):
    sys.stdout.flush()
    #read the file in
    file=open(joe_filename,"rb")
    WaitCursor(1)
    DrawProgressBar(0.0, 'Loading JOE')
    joe=joe_obj()
    joe.load(file)
    joe.dump()
    file.close()

    ######### Creates a new mesh
    mesh = Mesh.New()

    uv_coord=[]
    uv_list=[]
    verts_extend = []
    #load the textures to use later
    #-1 if there is no texture to load
    mesh_image=load_textures(joe, texture_filename)
    if mesh_image == -1 and texture_filename:
        print 'JOE Import, Warning, texture "%s" could not load'

    if (mesh_image != -1 and texture_filename != ""):
        size=mesh_image.getSize()
        #is this really what the user wants
    #    if (size[0]!=256 or size[1]!=256):
    #        result=Blender.Draw.PupMenu("Texture map size is not 256x256, it's: "+str(size[0])+"x"+str(size[1])+": Continue?%t|Yes|No")
    #        if(result==2):
    #            Exit()
        joe.skin_width=size[0]
        joe.skin_height=size[1]
        joe.num_skins = 1


    ######### Make the verts
    DrawProgressBar(0.25,"Loading Vertex Data")
    frame = joe.frames[0]
    scale = g_scale.val
    
    def tmp_get_vertex(i):
        #use the first frame for the mesh vertices
        x=(frame.verts[i].vertices[0])*scale
        y=(frame.verts[i].vertices[1])*scale
        z=(frame.verts[i].vertices[2])*scale
        return x,y,z

    def tmp_get_normal(i):
        #use the first frame for the mesh vertices
        x=(frame.normals[i].vertices[0])*scale
        y=(frame.normals[i].vertices[1])*scale
        z=(frame.normals[i].vertices[2])*scale
        return x,y,z
    
    mesh.verts.extend( [tmp_get_vertex(i) for i in xrange(0,frame.num_vertices)] )
    del tmp_get_vertex
    
    ######## Make the UV list
    DrawProgressBar(0.50,"Loading UV Data")
    
    #w = float(joe.skin_width)
    #h = float(joe.skin_height)
    #if w <= 0.0: w = 1.0
    #if h <0>blender
    g_scale= Slider("Scale Factor: ", EVENT_NOEVENT, 10, 75, 210, 18,
                    1.0, 0.001, 10.0, 1, "Scale factor for obj Model");

    ######### Draw and Exit Buttons
    Button("Load",EVENT_LOAD_JOE , 10, 10, 80, 18)
    Button("Exit",EVENT_EXIT , 170, 10, 80, 18)

def event(evt, val):    
    if (evt == QKEY and not val):
        Blender.Draw.Exit()

def bevent(evt):
    global g_joe_filename
    global g_texture_filename
    global EVENT_NOEVENT,EVENT_LOAD_JOE,EVENT_SAVE_JOE,EVENT_EXIT

    ######### Manages GUI events
    if (evt==EVENT_EXIT):
        Blender.Draw.Exit()
    elif (evt==EVENT_CHOOSE_FILENAME):
        FileSelector(filename_callback, "JOE File Selection")
    elif (evt==EVENT_CHOOSE_TEXTURE):
        FileSelector(texture_callback, "Texture Selection")
    elif (evt==EVENT_LOAD_JOE):
        if not Blender.sys.exists(g_joe_filename.val):
            PupMenu('Model file does not exist')
            return
        else:
            load_joe(g_joe_filename.val, g_texture_filename.val)
            Blender.Redraw()
            Blender.Draw.Exit()
            return

if __name__ == '__main__':
    Register(draw_gui, event, bevent)

and:
import-vdrift-list.py
Code:
#!BPY

"""
Name: 'VDrift (list.txt)'
Blender: 239
Group: 'Import'
Tooltip: 'Import VDrift tracks. (list.txt)'
"""
######################################################
# JOE Importer
# By:    Rikard Öxler, based on JOE exporter by Joe Venzon
#        and    MD2 importer by Bob Holcomb
# Date:    1 NOV 08
# Ver:    0.1
######################################################
# This script imports a JOE file, textures,
# and animations from blender.
######################################################

import Blender
from Blender import Mesh, Object, sys
from Blender.BGL import *
from Blender.Draw import *
from Blender.Window import *
from Blender.Mathutils import Vector
import struct
import sys
from types import *


######################################################
# Main Body
######################################################

#returns the string from a null terminated string
def asciiz (s):
  n = 0
  while (ord(s[n]) != 0):
    n = n + 1
  return s[0:n]


######################################################
# JOE Model Constants
######################################################
JOE_MAX_TRIANGLES=4096
JOE_MAX_VERTICES=2048
JOE_MAX_TEXCOORDS=2048
JOE_MAX_FRAMES=512
JOE_MAX_SKINS=32
JOE_MAX_FRAMESIZE=(JOE_MAX_VERTICES * 4 + 128)

######################################################
# JOE data structures
######################################################
class joe_alias_triangle(object):
    __slots__ = 'vertices',
    binary_format="<fff" #little-endian (<), 3 Unsigned char
    
    def __init__(self):
        self.vertices=[0]*3


    def load(self, file):
        temp_data = file.read(struct.calcsize(self.binary_format))
        data = struct.unpack(self.binary_format, temp_data)
        self.vertices[0]=data[0]
        self.vertices[1]=data[1]
        self.vertices[2]=data[2]
        return self

    def dump(self):
        print "JOE Alias_Triangle Structure"
        print "vertex: ", self.vertices[0]
        print "vertex: ", self.vertices[1]
        print "vertex: ", self.vertices[2]
        print ""

class joe_face(object):
    
    binary_format="<3h3h3h" #little-endian (<), 3 short, 3 short
    
    __slots__ = 'vertex_index', 'normal_index', 'texture_index'
    
    def __init__(self):
        self.vertex_index = [ 0, 0, 0 ]
        self.normal_index = [ 0, 0, 0 ]
        self.texture_index = [ 0, 0, 0]

    def load (self, file):
        temp_data=file.read(struct.calcsize(self.binary_format))
        data=struct.unpack(self.binary_format, temp_data)
        self.vertex_index[0]=data[0]
        self.vertex_index[1]=data[1]
        self.vertex_index[2]=data[2]
        self.normal_index[0]=data[3]
        self.normal_index[1]=data[4]
        self.normal_index[2]=data[5]
        self.texture_index[0]=data[6]
        self.texture_index[1]=data[7]
        self.texture_index[2]=data[8]
        return self

    def dump (self):
        print "JOE Face Structure"
        print "vertex index: ", self.vertex_index[0]
        print "vertex index: ", self.vertex_index[1]
        print "vertex index: ", self.vertex_index[2]
        print "normal index: ", self.normal_index[0]
        print "normal index: ", self.normal_index[1]
        print "normal index: ", self.normal_index[2]
        print "texture index: ", self.texture_index[0]
        print "texture index: ", self.texture_index[1]
        print "texture index: ", self.texture_index[2]
        print ""

class joe_tex_coord(object):
    __slots__ = 'u', 'v'
    binary_format="<2f" #little-endian (<), 2 float
    
    def __init__(self):
        self.u=0
        self.v=0

    def load (self, file):
        temp_data=file.read(struct.calcsize(self.binary_format))
        data=struct.unpack(self.binary_format, temp_data)
        self.u=data[0]
        self.v=data[1]
        return self

    def dump (self):
        print "JOE Texture Coordinate Structure"
        print "texture coordinate u: ",self.u
        print "texture coordinate v: ",self.v
        print ""


class joe_skin(object):
    __slots__ = 'name'
    binary_format="<64s" #little-endian (<), char[64]

    def __init__(self):
        self.name=""

    def load (self, file):
        temp_data=file.read(struct.calcsize(self.binary_format))
        data=struct.unpack(self.binary_format, temp_data)
        self.name=asciiz(data[0])
        return self

    def dump (self):
        print "JOE Skin"
        print "skin name: ",self.name
        print ""

class joe_alias_frame(object):
    __slots__ = 'faces', 'verts', 'texcoords', 'normals',\
    'num_vertices', 'num_normals', 'num_texcoords'
    '''
    num_vertices=0
    num_normals=0
    num_texcoords=0
    '''
    binary_format="<3i" #little-endian (<), 3 integers
    #num_vertices=0
    #num_texcoords=0
    #num_normals=0


    def __init__(self):
        self.faces=[]
        self.verts=[]
        self.texcoords=[]
        self.normals=[]

    def load (self, file):
        temp_data=file.read(struct.calcsize(self.binary_format))
        data=struct.unpack(self.binary_format, temp_data)
        self.num_vertices=data[0]
        self.num_texcoords=data[1]
        self.num_normals=data[2]
        for i in xrange(0, self.num_vertices):
            self.verts.append(joe_alias_triangle())
        for i in xrange(0, self.num_normals):
            self.normals.append(joe_alias_triangle())
        for i in xrange(0, self.num_texcoords):
            self.texcoords.append(joe_tex_coord())

        for i in xrange(0, self.num_vertices):
            self.verts[i].load(file)
            #self.verts[i].dump()
        for i in xrange(0, self.num_normals):
            self.normals[i].load(file)
            #self.normals[i].dump()
        for i in xrange(0, self.num_texcoords):
            self.texcoords[i].load(file)
            #self.texcoords[i].dump()
        return self

    def dump (self):
        print "JOE Alias Frame"
        print "number of verts: ",self.num_vertices
        print "number of texcoords",self.num_texcoords
        print "number of normals ",self.num_normals
        print ""

class joe_obj(object):
    __slots__ =\
    'frames',\
    'ident', 'version',\
    'num_faces',\
    'num_frames',\
    'skin_width', 'skin_height', 'num_skins',
    
    
    '''
    #Header Structure
    ident=0                #int 0    This is used to identify the file
    version=0            #int 1    The version number of the file (Must be 8)
    num_faces=0            #int 8    The number of faces (polygons)
    num_frames=0        #int 10    The number of animation frames
    '''
    binary_format="<4i"  #little-endian (<4> 0:
#        for i in xrange(0,joe.num_skins):
#            joe.skins[i].dump()
#            if (Blender.sys.exists(joe.skins[i].name)):
#                try:    return Blender.Image.Load(joe.skins[i].name)
#                except:    return -1
    

def animate_joe(joe, mesh):
    ######### Animate the verts through keyframe animation
    
    # Fast access to the meshes vertex coords
    verts = [v.co for v in mesh.verts]
    scale = g_scale.val
    
    for i in xrange(1, joe.num_frames):
        frame = joe.frames[i]
        #update the vertices
        for j in xrange(joe.num_vertices):
            x=(frame.verts[j].vertices[0]) * scale
            y=(frame.verts[j].vertices[1]) * scale
            z=(frame.verts[j].vertices[2]) * scale
            
            #put the vertex in the right spot
            verts[j][:] = y,-x,z
            
        mesh.insertKey(i,"absolute")
        # mesh.insertKey(i)
        
        #not really necissary, but I like playing with the frame counter
        Blender.Set("curframe", i)
    
    
    # Make the keys animate in the 3d view.
#    key = mesh.key
#    key.relative = False
    
    # Add an IPO to teh Key
#    ipo = Blender.Ipo.New('Key', 'joe')
#    key.ipo = ipo
    # Add a curve to the IPO
#    curve = ipo.addCurve('Basis')
    
    # Add 2 points to cycle through the frames.
#    curve.append((1, 0))
#    curve.append((joe.num_frames, (joe.num_frames-1)/10.0))
#    curve.interpolation = Blender.IpoCurve.InterpTypes.LINEAR
    


def load_joe(joe_filename, texture_filename):
    #sys.stdout.flush()
    #read the file in
    file=open(joe_filename,"rb")
    WaitCursor(1)
    DrawProgressBar(0.0, 'Loading JOE')
    joe=joe_obj()
    joe.load(file)
    joe.dump()
    file.close()

    ######### Creates a new mesh
    mesh = Mesh.New()

    uv_coord=[]
    uv_list=[]
    verts_extend = []
    #load the textures to use later
    #-1 if there is no texture to load
    mesh_image=load_textures(joe, texture_filename)
    if mesh_image == -1 and texture_filename:
        print 'JOE Import, Warning, texture "%s" could not load'

    if (mesh_image != -1 and texture_filename != ""):
        size=mesh_image.getSize()
        #is this really what the user wants
    #    if (size[0]!=256 or size[1]!=256):
    #        result=Blender.Draw.PupMenu("Texture map size is not 256x256, it's: "+str(size[0])+"x"+str(size[1])+": Continue?%t|Yes|No")
    #        if(result==2):
    #            Exit()
        joe.skin_width=size[0]
        joe.skin_height=size[1]
        joe.num_skins = 1


    ######### Make the verts
    DrawProgressBar(0.25,"Loading Vertex Data")
    frame = joe.frames[0]
    scale = g_scale.val
    
    def tmp_get_vertex(i):
        #use the first frame for the mesh vertices
        x=(frame.verts[i].vertices[0])*scale
        y=(frame.verts[i].vertices[1])*scale
        z=(frame.verts[i].vertices[2])*scale
        return x,y,z
    
    mesh.verts.extend( [tmp_get_vertex(i) for i in xrange(0,frame.num_vertices)] )
    del tmp_get_vertex
    
    ######## Make the UV list
    DrawProgressBar(0.50,"Loading UV Data")
    
    #w = float(joe.skin_width)
    #h = float(joe.skin_height)
    #if w <= 0.0: w = 1.0
    #if h <0>blender
    g_scale= Slider("Scale Factor: ", EVENT_NOEVENT, 10, 75, 210, 18,
                    1.0, 0.001, 10.0, 1, "Scale factor for obj Model");

    ######### Draw and Exit Buttons
    Button("Load",EVENT_LOAD_JOE , 10, 10, 80, 18)
    Button("Exit",EVENT_EXIT , 170, 10, 80, 18)

def event(evt, val):    
    if (evt == QKEY and not val):
        Blender.Draw.Exit()

def bevent(evt):
    global g_joe_filename
    global g_texture_filename
    global EVENT_NOEVENT,EVENT_LOAD_JOE,EVENT_SAVE_JOE,EVENT_EXIT

    ######### Manages GUI events
    if (evt==EVENT_EXIT):
        Blender.Draw.Exit()
    elif (evt==EVENT_CHOOSE_FILENAME):
        FileSelector(filename_callback, "JOE File Selection")
    elif (evt==EVENT_CHOOSE_TEXTURE):
        FileSelector(texture_callback, "Texture Selection")
    elif (evt==EVENT_LOAD_JOE):
        if not Blender.sys.exists(g_joe_filename.val):
            PupMenu('Model file does not exist')
            return
        else:
            #sys.stdout.flush()
            nextline = True;
            nextline2 = False;
            model = ""
            texture = ""
            list_txt=g_joe_filename.val
            dir=Blender.sys.dirname(list_txt)
            file=open(list_txt,"rb")
               for line in file.readlines():
                if line.strip() == "":
                    nextline = True
                    continue
                if nextline2 == True:
                    texture = line.strip()
                    print "Texture:", texture
                    if (Blender.sys.exists(Blender.sys.join(dir,model)) and  Blender.sys.exists(Blender.sys.join(dir,texture))):
                        load_joe(Blender.sys.join(dir,model), Blender.sys.join(dir,texture))
                    nextline2 = False
                if nextline == True and line[:1] != "#":
                    model = line.strip()
                    print "Model:", model
                    nextline = False
                    nextline2 = True
            del line
            file.close()
            Blender.Redraw()
            Blender.Draw.Exit()
            return

if __name__ == '__main__':
    Register(draw_gui, event, bevent)
Reply


Messages In This Thread
blender python script help - by alex25 - 08-12-2008, 01:23 PM
[No subject] - by alex25 - 08-12-2008, 03:57 PM
[No subject] - by alex25 - 08-12-2008, 07:16 PM
[No subject] - by joevenzon_phpbb2_import3 - 08-13-2008, 10:05 PM
[No subject] - by alex25 - 08-15-2008, 02:29 PM
[No subject] - by joevenzon_phpbb2_import3 - 08-16-2008, 12:56 PM
[No subject] - by alex25 - 08-17-2008, 02:37 PM
[No subject] - by osteron - 11-03-2008, 03:52 PM
[No subject] - by joevenzon_phpbb2_import3 - 11-03-2008, 09:39 PM
[No subject] - by osteron - 11-04-2008, 01:09 PM
[No subject] - by joevenzon_phpbb2_import3 - 11-07-2008, 11:12 AM
[No subject] - by osteron - 11-09-2008, 10:46 AM
[No subject] - by joevenzon_phpbb2_import3 - 11-09-2008, 01:57 PM

Forum Jump:


Users browsing this thread: 1 Guest(s)