Beispiel #1
0
    def onConvert(self, evt):
        dumplib=self.dumplib.GetValue()
        fspath=self.fspath.GetValue().strip()
        lbpath=self.lbpath.GetValue().strip()
        xppath=self.xppath.GetValue().strip()
        if not xppath:
            myMessageBox('You must specify an X-Plane scenery location',
                         "Can't convert.", wx.ICON_ERROR|wx.OK, self)
            return
        xppath=abspath(xppath)

        if not dumplib:
            if not fspath:
                myMessageBox('You must specify a MSFS scenery location',
                             "Can't convert.", wx.ICON_ERROR|wx.OK, self)
                return
            fspath=abspath(fspath)
            if not lbpath:
                lbpath=None
            else:
                lbpath=abspath(lbpath)
            if basename(xppath).lower()=='custom scenery':
                xppath=join(xppath, asciify(basename(fspath)))
        else:
            fspath=None
            if not lbpath:
                myMessageBox('You must specify a MSFS library location',
                             "Can't convert.", wx.ICON_ERROR|wx.OK, self)
                return
            lbpath=abspath(lbpath)
            if basename(xppath).lower()=='custom scenery':
                xppath=join(xppath, asciify(basename(lbpath)))
            
        season=self.season.GetSelection()	# zero-based
        xpver=self.xpver.GetSelection()+8	# zero-based

        try:
            self.logname=abspath(join(xppath, 'summary.txt'))
            if not isdir(dirname(self.logname)):
                mkdir(dirname(self.logname))
            logfile=file(self.logname, 'wt')
            logfile.write("%sTarget:\tX-Plane %d\n\n" % (sysdesc,xpver))
            logfile.close()
        except IOError, e:
            myMessageBox('Can\'t write to folder\n"%s"' % xppath,
                         e.strerror, wx.ICON_ERROR|wx.OK, self)
            return
Beispiel #2
0
def friendlytxt(filename, friendly, names):
    try:
        h = codecs.open(filename, 'rU', 'latin1')
        for line in h:
            line = line.strip()
            if not line or line[0] in [';', '#']:
                continue
            uid = line.split()[0].lower()
            if len(uid) != 32 or not isalnum(uid):
                continue
            name = asciify(line[33:].strip())
            if not name in names:
                friendly[uid] = name
                name[names] = True
        h.close()
    except:
        pass
Beispiel #3
0
def friendlytxt(filename, friendly, names):
    try:
        h=codecs.open(filename, 'rU', 'latin1')
        for line in h:
            line=line.strip()
            if not line or line[0] in [';', '#']:
                continue
            uid=line.split()[0].lower()
            if len(uid)!=32 or not isalnum(uid):
                continue
            name=asciify(line[33:].strip())
            if not name in names:
                friendly[uid]=name
                name[names]=True
        h.close()
    except:
        pass
Beispiel #4
0
    def __init__(self, bgl, enda, scale, libname, srcfile, texdir, output):

        self.old = False  # Old style scenery found and skipped
        self.rrt = False  # Old style runways/roads found and skipped
        self.anim = False  # Animations found and skipped

        assert (scale == 1)  # new-style objects are scaled when placed

        comment = "object %s in file %s" % (libname,
                                            asciify(basename(srcfile), False))

        tex = []
        mattex = []
        vt = []
        idx = []
        matrix = []
        amap = []
        scen = []
        data = {}

        if bgl.read(4) != 'RIFF': raise IOError
        (mdlsize, ) = unpack('<I', bgl.read(4))
        endmdl = bgl.tell() + mdlsize
        if bgl.read(4) != 'MDLX': raise IOError
        while bgl.tell() < endmdl:
            c = bgl.read(4)
            (size, ) = unpack('<I', bgl.read(4))
            if c == 'MDLD':
                end = size + bgl.tell()
                while bgl.tell() < end:
                    c = bgl.read(4)
                    (size, ) = unpack('<I', bgl.read(4))
                    if c == 'TEXT':
                        tex.extend([
                            bgl.read(64).strip('\0').strip()
                            for i in range(0, size, 64)
                        ])
                    elif c == 'MATE':
                        # http://www.fsdeveloper.com/wiki/index.php?title=MDL_file_format_(FSX)#MATE
                        for i in range(0, size, 120):
                            (flags1, flags2, diffuse, detail, normal, specular,
                             emissive, reflection, fresnel, dr, dg, db, da, sr,
                             sg, sb, sa, sp, ds, normalscale, recflectionscale,
                             po, power, bloomfloor, ambientscale, srcblend,
                             dstblend, alphafunc, alphathreshhold,
                             zwritealpha) = unpack('<9I16f3I2f', bgl.read(120))
                            # Get texture names
                            diffuse = (flags1 & Material.FSX_MAT_HAS_DIFFUSE
                                       ) and tex[diffuse] or None
                            emissive = (flags1 & Material.FSX_MAT_HAS_EMISSIVE
                                        ) and tex[emissive] or None
                            if output.xpver <= 10:
                                normal = specular = reflection = None  # Not supported in<=10, so no point doing lookup
                            else:
                                specular = (flags1
                                            & Material.FSX_MAT_HAS_SPECULAR
                                            ) and tex[specular] or None
                                normal = (flags1 & Material.FSX_MAT_HAS_NORMAL
                                          ) and tex[normal] or None
                                reflection = (flags1
                                              & Material.FSX_MAT_HAS_REFLECTION
                                              ) and tex[reflection] or None
                            # Get texture filenames
                            if diffuse:
                                diffuse = findtex(diffuse, texdir,
                                                  output.addtexdir)
                            if emissive:
                                emissive = findtex(emissive, texdir,
                                                   output.addtexdir)
                            if specular:
                                specular = findtex(specular, texdir,
                                                   output.addtexdir)
                            if normal:
                                normal = findtex(normal, texdir,
                                                 output.addtexdir)
                            if reflection:
                                reflection = findtex(reflection, texdir,
                                                     output.addtexdir)

                            t = (diffuse or emissive) and Texture(
                                output.xpver, diffuse, emissive, specular,
                                normal, reflection) or None
                            m = Material(
                                output.xpver,
                                (dr, dg, db),
                                (flags1 & Material.FSX_MAT_SPECULAR)
                                and not specular and
                                ((sr != sg or sr != sb or sr < 0.9) and
                                 (sr, sg, sb) !=
                                 (0, 0, 0)) and [sr, sg, sb] or None,
                                False,  # Poly
                                flags2 & Material.FSX_MAT_DOUBLE_SIDED != 0,
                                flags1 & Material.FSX_MAT_ZTEST_ALPHA
                                and alphafunc in [
                                    Material.FSX_MAT_ALPHA_TEST_GREATER,
                                    Material.FSX_MAT_ALPHA_TEST_GREATER_EQUAL
                                ] and alphathreshhold / 255 or None,
                                not diffuse
                                and ((flags1 & Material.FSX_MAT_SPECULAR) and
                                     (sr, sg, sb) != (0, 0, 0)) and True,
                                flags1 & Material.FSX_MAT_NO_SHADOW != 0)
                            mattex.append((m, t))
                        if __debug__:
                            if output.debug:
                                output.debug.write("Materials %d\n" %
                                                   len(mattex))
                                for i in range(len(mattex)):
                                    output.debug.write(
                                        "%3d:\t%s\t%s\n" %
                                        (i, mattex[i][0], mattex[i][1]))
                    elif c == 'INDE':
                        idx = unpack('<%dH' % (size / 2), bgl.read(size))
                    elif c == 'VERB':
                        endv = size + bgl.tell()
                        while bgl.tell() < endv:
                            c = bgl.read(4)
                            (size, ) = unpack('<I', bgl.read(4))
                            if c == 'VERT':
                                vt.append([
                                    unpack('<8f', bgl.read(32))
                                    for i in range(0, size, 32)
                                ])
                            else:
                                bgl.seek(size, 1)
                    elif c == 'TRAN':
                        for i in range(0, size, 64):
                            matrix.append(
                                Matrix([
                                    unpack('<4f', bgl.read(16))
                                    for j in range(4)
                                ]))
                        if __debug__:
                            if output.debug:
                                output.debug.write("Matrices %d\n" %
                                                   len(matrix))
                                for i in range(len(matrix)):
                                    output.debug.write("%s = %d\n" %
                                                       (matrix[i], i))
                    elif c == 'AMAP':
                        for i in range(0, size, 8):
                            (a, b) = unpack('<2I', bgl.read(8))
                            amap.append(b)
                        if __debug__:
                            if output.debug:
                                output.debug.write("Animation map %d\n" %
                                                   len(amap))
                                for i in range(len(amap)):
                                    output.debug.write("%2d: %2d\n" %
                                                       (i, amap[i]))
                    elif c == 'SCEN':
                        # Assumed to be after TRAN and AMAP sections
                        count = size / 8
                        for i in range(count):
                            (child, peer, offset,
                             unk) = unpack('<4h', bgl.read(8))
                            scen.append((child, peer, offset, -1))
                        # Invert Child/Peer pointers to get parents
                        for i in range(count):
                            (child, peer, thisoff, parent) = scen[i]
                            if child != -1:  # child's parent is me
                                (xchild, xpeer, xoff, xparent) = scen[child]
                                scen[child] = (xchild, xpeer, xoff, i)
                            if peer != -1:  # peer's parent is my parent
                                (xchild, xpeer, xoff, xparent) = scen[peer]
                                scen[peer] = (xchild, xpeer, xoff, parent)
                        # Replace AMAP offsets with matrix
                        if __debug__:
                            if output.debug:
                                output.debug.write("Scene Graph %d\n" %
                                                   len(scen))
                        for i in range(count):
                            (child, peer, offset, parent) = scen[i]
                            scen[i] = (child, peer, matrix[amap[offset / 8]],
                                       parent)
                            if __debug__:
                                if output.debug:
                                    output.debug.write(
                                        "%2d: %2d %2d %2d %2d\n" %
                                        (i, child, peer, parent, offset / 8))
                    elif c == 'LODT':
                        endt = size + bgl.tell()
                        partno = 0
                        maxlod = 0
                        while bgl.tell() < endt:
                            c = bgl.read(4)
                            (size, ) = unpack('<I', bgl.read(4))
                            if c == 'LODE':
                                ende = size + bgl.tell()
                                (lod, ) = unpack('<I', bgl.read(4))
                                while bgl.tell() < ende:
                                    c = bgl.read(4)
                                    (size, ) = unpack('<I', bgl.read(4))
                                    if c == 'PART':
                                        (typ, scene, material, verb, voff,
                                         vcount, ioff, icount,
                                         unk) = unpack('<9I', bgl.read(36))
                                        assert (typ == 1)
                                        maxlod = max(lod, maxlod)
                                        (child, peer, finalmatrix,
                                         parent) = scen[scene]
                                        if __debug__:
                                            if output.debug:
                                                output.debug.write(
                                                    "LOD %4d: scene %d verb %d material %d tris %d voff %d vcount %d ioff %d icount %d\n"
                                                    % (lod, scene, verb,
                                                       material, icount / 3,
                                                       voff, vcount, ioff,
                                                       icount))

                                        while parent != -1:
                                            (child, peer, thismatrix,
                                             parent) = scen[parent]
                                            finalmatrix = finalmatrix * thismatrix
                                        if not lod in data: data[lod] = []
                                        data[lod].append(
                                            (mattex[material][0],
                                             mattex[material][1],
                                             vt[verb][voff:voff + vcount],
                                             idx[ioff:ioff + icount],
                                             finalmatrix))
                                        partno += 1
                                    else:
                                        bgl.seek(size, 1)
                            else:
                                bgl.seek(size, 1)
                    else:
                        bgl.seek(size, 1)
            else:
                bgl.seek(size, 1)

        # Only interested in highest LOD
        objs = {}  # objs by texture
        for (m, t, vt, idx, matrix) in data[maxlod]:
            if __debug__:
                if output.debug: output.debug.write("%s\n%s\n" % (t, matrix))
            objvt = []
            nrmmatrix = matrix.adjoint()
            if t:
                assert not t.s and not t.n and not t.r  # Bunching scheme will need re-work
                for (x, y, z, nx, ny, nz, tu, tv) in vt:
                    (x, y, z) = matrix.transform(x, y, z)
                    (nx, ny, nz) = nrmmatrix.rotateAndNormalize(nx, ny, nz)
                    objvt.append((x, y, -z, nx, ny, -nz, tu, tv))
            else:
                # replace material with palette texture
                (pu, pv) = rgb2uv(m.d)
                for (x, y, z, nx, ny, nz, tu, tv) in vt:
                    (x, y, z) = matrix.transform(x, y, z)
                    (nx, ny, nz) = nrmmatrix.rotateAndNormalize(nx, ny, nz)
                    objvt.append((x, y, -z, nx, ny, -nz, pu, pv))
            if t in objs:
                obj = objs[t]
                if t and t.e:
                    obj.tex.e = t.e  # Because we don't compare on emissive
            else:
                objs[t] = obj = Object(libname, comment, t, None)
            obj.addgeometry(m, objvt, idx)

        # Add objs to library with one name
        if objs: output.objdat[libname] = objs.values()
Beispiel #5
0
 def start_element(self, name, attrs):
     if name == 'obj' and attrs['guid'] and attrs['name']:
         name = asciify(attrs['name'])
         if not name in self.names:
             self.friendly[str(attrs['guid']).lower()] = name
             self.name[names] = True
Beispiel #6
0
 def start_element(self, name, attrs):
     if name=='obj' and attrs['guid'] and attrs['name']:
         name=asciify(attrs['name'])
         if not name in self.names:
             self.friendly[str(attrs['guid']).lower()]=name
             self.name[names]=True
Beispiel #7
0
    def __init__(self, bgl, enda, scale, libname, srcfile, texdir, output):

        self.old=False	# Old style scenery found and skipped
        self.rrt=False	# Old style runways/roads found and skipped
        self.anim=False	# Animations found and skipped

        assert(scale==1)	# new-style objects are scaled when placed

        comment="object %s in file %s" % (libname,asciify(basename(srcfile),False))

        tex=[]
        mattex=[]
        vt=[]
        idx=[]
        matrix=[]
        amap=[]
        scen=[]
        data={}
        
        if bgl.read(4)!='RIFF': raise IOError
        (mdlsize,)=unpack('<I', bgl.read(4))
        endmdl=bgl.tell()+mdlsize
        if bgl.read(4)!='MDLX': raise IOError
        while bgl.tell()<endmdl:
            c=bgl.read(4)
            (size,)=unpack('<I', bgl.read(4))
            if c=='MDLD':
                end=size+bgl.tell()
                while bgl.tell()<end:
                    c=bgl.read(4)
                    (size,)=unpack('<I', bgl.read(4))
                    if c=='TEXT':
                        tex.extend([bgl.read(64).strip('\0').strip() for i in range(0,size,64)])
                    elif c=='MATE':
                        # http://www.fsdeveloper.com/wiki/index.php?title=MDL_file_format_(FSX)#MATE
                        for i in range(0,size,120):
                            (flags1,flags2,diffuse,detail,normal,specular,emissive,reflection,fresnel,dr,dg,db,da,sr,sg,sb,sa,sp,ds,normalscale,recflectionscale,po,power,bloomfloor,ambientscale,srcblend,dstblend,alphafunc,alphathreshhold,zwritealpha)=unpack('<9I16f3I2f', bgl.read(120))
                            # Get texture names
                            diffuse   =(flags1 & Material.FSX_MAT_HAS_DIFFUSE) and tex[diffuse] or None
                            emissive  =(flags1 & Material.FSX_MAT_HAS_EMISSIVE) and tex[emissive] or None
                            if output.xpver<=10:
                                normal=specular=reflection=None	# Not supported in<=10, so no point doing lookup
                            else:
                                specular  =(flags1 & Material.FSX_MAT_HAS_SPECULAR) and tex[specular] or None
                                normal    =(flags1 & Material.FSX_MAT_HAS_NORMAL) and tex[normal] or None
                                reflection=(flags1 & Material.FSX_MAT_HAS_REFLECTION) and tex[reflection] or None
                            # Get texture filenames
                            if diffuse:   diffuse   =findtex(diffuse, texdir, output.addtexdir)
                            if emissive:  emissive  =findtex(emissive, texdir, output.addtexdir)
                            if specular:  specular  =findtex(specular, texdir, output.addtexdir)
                            if normal:    normal    =findtex(normal, texdir, output.addtexdir)
                            if reflection:reflection=findtex(reflection, texdir, output.addtexdir)

                            t=(diffuse or emissive) and Texture(output.xpver, diffuse, emissive, specular, normal, reflection) or None
                            m=Material(output.xpver,
                                       (dr,dg,db),
                                       (flags1 & Material.FSX_MAT_SPECULAR) and not specular and ((sr!=sg or sr!=sb or sr<0.9) and (sr,sg,sb)!=(0,0,0)) and [sr,sg,sb] or None,
                                       False,	# Poly
                                       flags2&Material.FSX_MAT_DOUBLE_SIDED != 0,
                                       flags1&Material.FSX_MAT_ZTEST_ALPHA and alphafunc in [Material.FSX_MAT_ALPHA_TEST_GREATER,Material.FSX_MAT_ALPHA_TEST_GREATER_EQUAL] and alphathreshhold/255 or None,
                                       not diffuse and ((flags1 & Material.FSX_MAT_SPECULAR) and (sr,sg,sb)!=(0,0,0)) and True,
                                       flags1&Material.FSX_MAT_NO_SHADOW != 0)
                            mattex.append((m,t))
                        if __debug__:
                            if output.debug:
                                output.debug.write("Materials %d\n" % len(mattex))
                                for i in range(len(mattex)):
                                    output.debug.write("%3d:\t%s\t%s\n" % (i, mattex[i][0], mattex[i][1]))
                    elif c=='INDE':
                        idx=unpack('<%dH' % (size/2), bgl.read(size))
                    elif c=='VERB':
                        endv=size+bgl.tell()
                        while bgl.tell()<endv:
                            c=bgl.read(4)
                            (size,)=unpack('<I', bgl.read(4))
                            if c=='VERT':
                                vt.append([unpack('<8f',bgl.read(32)) for i in range(0,size,32)])
                            else:
                                bgl.seek(size,1)
                    elif c=='TRAN':
                        for i in range(0,size,64):
                            matrix.append(Matrix([unpack('<4f',bgl.read(16)) for j in range(4)]))
                        if __debug__:
                            if output.debug:
                                output.debug.write("Matrices %d\n" % len(matrix))
                                for i in range(len(matrix)): output.debug.write("%s = %d\n" % (matrix[i], i))
                    elif c=='AMAP':
                        for i in range(0,size,8):
                            (a,b)=unpack('<2I',bgl.read(8))
                            amap.append(b)
                        if __debug__:
                            if output.debug:
                                output.debug.write("Animation map %d\n" % len(amap))
                                for i in range(len(amap)):
                                    output.debug.write("%2d: %2d\n" % (i, amap[i]))
                    elif c=='SCEN':
                        # Assumed to be after TRAN and AMAP sections
                        count=size/8
                        for i in range(count):
                            (child,peer,offset,unk)=unpack('<4h',bgl.read(8))
                            scen.append((child,peer,offset,-1))
                        # Invert Child/Peer pointers to get parents
                        for i in range(count):
                            (child, peer, thisoff, parent)=scen[i]
                            if child!=-1:	# child's parent is me
                                (xchild, xpeer, xoff, xparent)=scen[child]
                                scen[child]=(xchild, xpeer, xoff, i)
                            if peer!=-1:	# peer's parent is my parent
                                (xchild, xpeer, xoff, xparent)=scen[peer]
                                scen[peer]=(xchild, xpeer, xoff, parent)
                        # Replace AMAP offsets with matrix
                        if __debug__:
                            if output.debug: output.debug.write("Scene Graph %d\n" % len(scen))
                        for i in range(count):
                            (child, peer, offset, parent)=scen[i]
                            scen[i]=(child, peer, matrix[amap[offset/8]], parent)
                            if __debug__:
                                if output.debug: output.debug.write("%2d: %2d %2d %2d %2d\n" % (i, child, peer, parent, offset/8))
                    elif c=='LODT':
                        endt=size+bgl.tell()
                        partno=0
                        maxlod=0
                        while bgl.tell()<endt:
                            c=bgl.read(4)
                            (size,)=unpack('<I', bgl.read(4))
                            if c=='LODE':
                                ende=size+bgl.tell()
                                (lod,)=unpack('<I', bgl.read(4))
                                while bgl.tell()<ende:
                                    c=bgl.read(4)
                                    (size,)=unpack('<I', bgl.read(4))
                                    if c=='PART':
                                        (typ,scene,material,verb,voff,vcount,ioff,icount,unk)=unpack('<9I', bgl.read(36))
                                        assert (typ==1)
                                        maxlod=max(lod,maxlod)
                                        (child, peer, finalmatrix, parent)=scen[scene]
                                        if __debug__:
                                            if output.debug:
                                                output.debug.write("LOD %4d: scene %d verb %d material %d tris %d voff %d vcount %d ioff %d icount %d\n" % (lod, scene, verb, material, icount/3, voff, vcount, ioff, icount))

                                        while parent!=-1:
                                            (child, peer, thismatrix, parent)=scen[parent]
                                            finalmatrix=finalmatrix*thismatrix
                                        if not lod in data: data[lod]=[]
                                        data[lod].append((mattex[material][0], mattex[material][1], vt[verb][voff:voff+vcount], idx[ioff:ioff+icount], finalmatrix))
                                        partno+=1
                                    else:
                                        bgl.seek(size,1)
                            else:
                                bgl.seek(size,1)
                    else:
                        bgl.seek(size,1)
            else:
                bgl.seek(size,1)

        # Only interested in highest LOD
        objs={}	# objs by texture
        for (m,t,vt,idx,matrix) in data[maxlod]:
            if __debug__:
                if output.debug: output.debug.write("%s\n%s\n" % (t, matrix))
            objvt=[]
            nrmmatrix=matrix.adjoint()
            if t:
                assert not t.s and not t.n and not t.r	# Bunching scheme will need re-work
                for (x,y,z, nx,ny,nz, tu,tv) in vt:
                    (x,y,z)=matrix.transform(x,y,z)
                    (nx,ny,nz)=nrmmatrix.rotateAndNormalize(nx,ny,nz)
                    objvt.append((x,y,-z, nx,ny,-nz, tu,tv))
            else:
                # replace material with palette texture
                (pu,pv)=rgb2uv(m.d)
                for (x,y,z, nx,ny,nz, tu,tv) in vt:
                    (x,y,z)=matrix.transform(x,y,z)
                    (nx,ny,nz)=nrmmatrix.rotateAndNormalize(nx,ny,nz)
                    objvt.append((x,y,-z, nx,ny,-nz, pu,pv))
            if t in objs:
                obj=objs[t]
                if t and t.e: obj.tex.e=t.e	# Because we don't compare on emissive
            else:
                objs[t]=obj=Object(libname, comment, t, None)
            obj.addgeometry(m, objvt, idx)

        # Add objs to library with one name
        if objs: output.objdat[libname]=objs.values()