home *** CD-ROM | disk | FTP | other *** search
- # ***** BEGIN LICENSE BLOCK *****
- # Version: MPL 1.1/GPL 2.0/LGPL 2.1
- #
- # The contents of this file are subject to the Mozilla Public License Version
- # 1.1 (the "License"); you may not use this file except in compliance with
- # the License. You may obtain a copy of the License at
- # http://www.mozilla.org/MPL/
- #
- # Software distributed under the License is distributed on an "AS IS" basis,
- # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- # for the specific language governing rights and limitations under the
- # License.
- #
- # The Original Code is the Python Computer Graphics Kit.
- #
- # The Initial Developer of the Original Code is Matthias Baas.
- # Portions created by the Initial Developer are Copyright (C) 2004
- # the Initial Developer. All Rights Reserved.
- #
- # Contributor(s):
- #
- # Alternatively, the contents of this file may be used under the terms of
- # either the GNU General Public License Version 2 or later (the "GPL"), or
- # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- # in which case the provisions of the GPL or the LGPL are applicable instead
- # of those above. If you wish to allow use of your version of this file only
- # under the terms of either the GPL or the LGPL, and not to allow others to
- # use your version of this file under the terms of the MPL, indicate your
- # decision by deleting the provisions above and replace them with the notice
- # and other provisions required by the GPL or the LGPL. If you do not delete
- # the provisions above, a recipient may use your version of this file under
- # the terms of any one of the MPL, the GPL or the LGPL.
- #
- # ***** END LICENSE BLOCK *****
- # $Id: lwob.py,v 1.1 2006/03/12 22:41:42 mbaas Exp $
-
- import struct
- from cgtypes import vec3
-
- class LWOBError(Exception):
- pass
-
- # Texture
- class Texture:
- """Texture description.
-
- A value remains None if it wasn't set in the LWOB file.
- """
- def __init__(self):
- self.type = None # str
- self.flags = None # int
- self.size = None # vec3
- self.center = None # vec3
- self.falloff = None # vec3
- self.velocity = None # vec3
- self.color = None # 3-tuple
- self.value = None # int
- self.bumpamplitude = None # float
- self.floatparams = 10*[None] # list of floats
- self.intparams = 10*[None] # list of ints
- self.imagename = None # str
- self.alphaname = None # str
- self.widthwrap = None # int
- self.heightwrap = None # int
- self.antialiasingstrength = None # float
- self.opacity = None # float
- self.shader = [] # list of str
- self.shaderdata = [] # list of str
- self.seq_offset = None # int
- self.seq_flags = None # int
- self.seq_looplength = None # int
- self.flyer_begin = None # int
- self.flyer_end = None # int
- self.cycle_speed = None # int
- self.cycle_low = None # int
- self.cycle_high = None # int
-
- # Surface
- class Surface:
- """Surface description.
-
- A value remains None if it wasn't set in the LWOB file.
- """
-
- def __init__(self, name):
- self.name = name
-
- self.color = None # 3-tuple
- self.flags = None # int
- self.luminosity = None # float
- self.diffuse = None # float
- self.specular = None # float
- self.reflection = None # float
- self.transparency = None # float
- self.glossiness = None # int
- self.reflectionmode = None # int
- self.refmap = None # str
- self.refmap_seamangle = None # float
- self.refractiveindex = None # float
- self.edgetransp = None # float
- self.maxsmoothangle = None # float
-
- self.tex_color = [] # list of Texture objects
- self.tex_diffuse = []
- self.tex_specular = []
- self.tex_reflection = []
- self.tex_transparency = []
- self.tex_luminosity = []
- self.tex_bump = []
-
-
- # LWOBReader
- class LWOBReader:
- """Lightwave Object reader.
-
- This class reads Lightwave Object (*.lwo) files and calls handler
- methods for each chunk found. The following handler methods can be
- implemented in derived classes:
-
- - handlePNTS(points): points is a list of vec3 objects containing
- all vertices.
- - handleSRFS(names): names is a list of strings containing the names
- of all surface definitions.
- - handlePOLS(polys): polys is a list of polygons. Each polygon is a
- tuple (verts, surface) where verts is a list of
- vertex indices and surface the index of the surface
- that is used by this polygon.
- - handleCRVS(curves): curves is a list of curves. Each curve is a
- tuple (verts, surface, flags).
- - handlePCHS(patches): patches is a list of patches. Each patch is a
- tuple (verts, surface).
- - handleSURF(surface): surface is a Surface object that contains the
- surface attributes.
- """
-
- def __init__(self):
- """Constructor.
- """
- # The file handle
- self._file = None
- # The number of bytes that are left in the file.
- # After the FORM has been read, it is initialized with the
- # FORM length and is used to determine whether there are still
- # more chunks left or not.
- self._bytes_left = 12
-
- # Current Surface object when reading a SURF chunk
- self._current_surface = None
- # Current Texture object
- self._current_tex = None
-
- def read(self, file):
- """Read the lwo file.
-
- file is a file-like object that provides the read() and seek()
- methods.
- """
- self._file = file
- self._bytes_left = 12
-
- # Read the FORM header...
- tag, length = self.readChunkHeader()
- self.onChunk(tag, length, 0)
- self._bytes_left = length
- if tag!="FORM":
- raise LWOBError("Not a Lightwave object file")
-
- # Read the LWOB tag...
- lwob = self.readNBytes(4)
- if lwob!="LWOB":
- raise LWOBError("Not a Lightwave object file")
-
- # Read the contained chunks and call the 'reader' method if available.
- # If no reader is defined for a chunk this chunk is skipped.
- while not self._eofReached():
- tag,length = self.readChunkHeader()
- self.onChunk(tag, length, 1)
- # print tag, length
- handlername = "read%s"%tag
- handler = getattr(self, handlername, None)
- if handler==None:
- self.skipChunk(length)
- else:
- handler(length)
-
-
- # Handler methods. These methods can be overridden in derived classes.
-
- def onChunk(self, tag, length, level): pass
-
- def handlePNTS(self, points): pass
- def handleSRFS(self, names): pass
- def handlePOLS(self, polys): pass
- def handleCRVS(self, curves): pass
- def handlePCHS(self, patches): pass
- def handleSURF(self, surface): pass
-
-
- ### readXXXX() reader methods (XXXX is the chunk tag)
- ### A reader takes the chunk length as argument and has to read
- ### its data from the file and call an appropriate handler method
- ### (handleXXXX(...))
-
- def readPNTS(self, length):
- """Read a PNTS chunk and call the PNTS handler.
- """
- if length%12!=0:
- raise LWOBError, "Invalid PNTS chunk size (%d)"%length
-
- numpnts = int(length/12)
- # Read the chunk data...
- data = self.readNBytes(length)
- # Unpack the coordinates...
- coords = struct.unpack(">%s"%(numpnts*"fff"), data)
- # Initialize vec3s...
- pnts = []
- for i in range(numpnts):
- pnts.append(vec3(coords[i*3:(i+1)*3]))
-
- self.handlePNTS(pnts)
-
- def readSRFS(self, length):
- """Read a SRFS chunk and call the SRFS handler.
- """
- data = self.readNBytes(length)
- names = []
- while len(data)>0:
- n = data.find("\000")
- if n==-1:
- n = len(data)
- names.append(data[:n])
- if n%2==0:
- n+=1
- data = data[n+1:]
-
- self.handleSRFS(names)
-
- def readPOLS(self, length):
- """Read a POLS chunk and call the POLS handler.
- """
- data = self.readNBytes(length)
- idx = 0
- unpack = struct.unpack
- polys = []
- # The number of detail polygons that follow
- # (detail polygons are ignored)
- details_left = 0
- while idx<len(data):
- numverts = unpack(">H", data[idx:idx+2])[0]
- idx += 2
- verts = unpack(">%s"%(numverts*"H"), data[idx:idx+numverts*2])
- idx += numverts*2
- surf = unpack(">H", data[idx:idx+2])[0]
- idx += 2
- if details_left==0:
- polys.append((verts, surf))
- else:
- details_left -= 1
-
- # Does the polygon have detail polygons?
- if surf<0:
- details_left = unpack(">H", data[idx:idx+2])[0]
- idx += 2
-
- self.handlePOLS(polys)
-
- def readCRVS(self, length):
- """Read a CRVS chunk and call the CRVS handler.
- """
- data = self.readNBytes(length)
- idx = 0
- unpack = struct.unpack
- curves = []
- while idx<len(data):
- numverts = unpack(">H", data[idx:idx+2])[0]
- idx += 2
- verts = unpack(">%s"%(numverts*"H"), data[idx:idx+numverts*2])
- idx += numverts*2
- surf,flags = unpack(">HH", data[idx:idx+4])
- idx += 4
- curves.append((verts, surf, flags))
-
- self.handleCRVS(curves)
-
- def readPCHS(self, length):
- """Read a PCHS chunk and call the PCHS handler.
- """
- data = self.readNBytes(length)
- idx = 0
- unpack = struct.unpack
- patches = []
- while idx<len(data):
- numverts = unpack(">H", data[idx:idx+2])[0]
- idx += 2
- verts = unpack(">%s"%(numverts*"H"), data[idx:idx+numverts*2])
- idx += numverts*2
- surf = unpack(">H", data[idx:idx+2])[0]
- idx += 2
- patched.append((verts, surf))
-
- self.handlePCHS(patches)
-
- def readSURF(self, length):
- """Read a SURF chunk and call the SURF handler.
- """
- # Read the surface name byte by byte...
- name = ""
- while 1:
- c = self.readNBytes(1)
- length -= 1
- if ord(c)==0:
- if len(name)%2==0:
- # Skip the pad byte
- self.readNBytes(1)
- length -= 1
- break
- name += c
-
- self._current_surface = Surface(name)
- self._current_tex = None
-
- # print "SURFACE",name
- while length>0:
- tag,sublength = self.readSubChunkHeader()
- self.onChunk(tag, sublength, 2)
- length -= 6+sublength
- # print " ",tag,sublength
- handlername = "readSURF_%s"%tag
- handler = getattr(self, handlername, None)
- if handler==None:
- self.skipChunk(sublength)
- else:
- handler(sublength)
-
- self.handleSURF(self._current_surface)
- self._current_tex = None
- self._current_surface = None
-
- def readSURF_COLR(self, length):
- """COLR chunk."""
- if length!=4:
- raise LWOBError, "Invalid COLR size (%d instead of 4)"%length
- data = self.readNBytes(4)
- color = struct.unpack(">BBB", data[:3])
- self._current_surface.color = color
-
- def readSURF_FLAG(self, length):
- """FLAG chunk."""
- if length!=2:
- raise LWOBError, "Invalid FLAG size (%d instead of 2)"%length
- data = self.readNBytes(2)
- flags = struct.unpack(">H", data)[0]
- self._current_surface.flags = flags
-
- def readSURF_LUMI(self, length):
- """LUMI chunk."""
- if length!=2:
- raise LWOBError, "Invalid LUMI size (%d instead of 2)"%length
- data = self.readNBytes(2)
- lumi = struct.unpack(">H", data)[0]
- if self._current_surface.luminosity==None:
- self._current_surface.luminosity = lumi/256.0
-
- def readSURF_VLUM(self, length):
- """VLUM chunk."""
- if length!=4:
- raise LWOBError, "Invalid VLUM size (%d instead of 4)"%length
- data = self.readNBytes(4)
- lum = struct.unpack(">f", data)[0]
- self._current_surface.luminosity = lum
-
- def readSURF_DIFF(self, length):
- """DIFF chunk."""
- if length!=2:
- raise LWOBError, "Invalid DIFF size (%d instead of 2)"%length
- data = self.readNBytes(2)
- diff = struct.unpack(">H", data)[0]
- if self._current_surface.diffuse==None:
- self._current_surface.diffuse = diff/256.0
-
- def readSURF_VDIF(self, length):
- """VDIF chunk."""
- if length!=4:
- raise LWOBError, "Invalid VDIF size (%d instead of 4)"%length
- data = self.readNBytes(4)
- diff = struct.unpack(">f", data)[0]
- self._current_surface.diffuse = diff
-
- def readSURF_SPEC(self, length):
- """SPEC chunk."""
- if length!=2:
- raise LWOBError, "Invalid SPEC size (%d instead of 2)"%length
- data = self.readNBytes(2)
- spec = struct.unpack(">H", data)[0]
- if self._current_surface.specular==None:
- self._current_surface.specular = spec/256.0
-
- def readSURF_VSPC(self, length):
- """VSPC chunk."""
- if length!=4:
- raise LWOBError, "Invalid VSPC size (%d instead of 4)"%length
- data = self.readNBytes(4)
- spec = struct.unpack(">f", data)[0]
- self._current_surface.specular = spec
-
- def readSURF_REFL(self, length):
- """REFL chunk."""
- if length!=2:
- raise LWOBError, "Invalid REFL size (%d instead of 2)"%length
- data = self.readNBytes(2)
- refl = struct.unpack(">H", data)[0]
- if self._current_surface.reflection==None:
- self._current_surface.reflection = refl/256.0
-
- def readSURF_VRFL(self, length):
- """VRFL chunk."""
- if length!=4:
- raise LWOBError, "Invalid VRFL size (%d instead of 4)"%length
- data = self.readNBytes(4)
- refl = struct.unpack(">f", data)[0]
- self._current_surface.reflection = refl
-
- def readSURF_TRAN(self, length):
- """TRAN chunk."""
- if length!=2:
- raise LWOBError, "Invalid TRAN size (%d instead of 2)"%length
- data = self.readNBytes(2)
- tran = struct.unpack(">H", data)[0]
- if self._current_surface.transparency==None:
- self._current_surface.transparency = tran/256.0
-
- def readSURF_VTRN(self, length):
- """VTRN chunk."""
- if length!=4:
- raise LWOBError, "Invalid VTRN size (%d instead of 4)"%length
- data = self.readNBytes(4)
- tran = struct.unpack(">f", data)[0]
- self._current_surface.transparency = tran
-
- def readSURF_GLOS(self, length):
- """GLOS chunk."""
- if length!=2:
- raise LWOBError, "Invalid GLOS size (%d instead of 2)"%length
- data = self.readNBytes(2)
- glos = struct.unpack(">H", data)[0]
- self._current_surface.glossiness = glos
-
- def readSURF_RFLT(self, length):
- """RFLT chunk."""
- if length!=2:
- raise LWOBError, "Invalid RFLT size (%d instead of 2)"%length
- data = self.readNBytes(2)
- mode = struct.unpack(">H", data)[0]
- self._current_surface.reflectionmode = mode
-
- def readSURF_RIMG(self, length):
- """RIMG chunk."""
- data = self.readNBytes(length)
- n = data.find("\000")
- if n!=-1:
- data = data[:n]
- self._current_surface.refmap = data
-
- def readSURF_RSAN(self, length):
- """RSAN chunk."""
- if length!=4:
- raise LWOBError, "Invalid RSAN size (%d instead of 4)"%length
- data = self.readNBytes(4)
- deg = struct.unpack(">f", data)[0]
- self._current_surface.refmap_seamangle = deg
-
- def readSURF_RIND(self, length):
- """RIND chunk."""
- if length!=4:
- raise LWOBError, "Invalid RIND size (%d instead of 4)"%length
- data = self.readNBytes(4)
- ior = struct.unpack(">f", data)[0]
- self._current_surface.refractiveindex = ior
-
- def readSURF_EDGE(self, length):
- """EDGE chunk."""
- if length!=4:
- raise LWOBError, "Invalid EDGE size (%d instead of 4)"%length
- data = self.readNBytes(4)
- edge = struct.unpack(">f", data)[0]
- self._current_surface.edgetransp = edge
-
- def readSURF_SMAN(self, length):
- """SMAN chunk."""
- if length!=4:
- raise LWOBError, "Invalid SMAN size (%d instead of 4)"%length
- data = self.readNBytes(4)
- sman = struct.unpack(">f", data)[0]
- self._current_surface.maxsmoothangle = sman
-
- def readSURF_CTEX(self, length):
- """CTEX chunk."""
- data = self.readNBytes(length)
- n = data.find("\000")
- if n!=-1:
- data = data[:n]
-
- tex = Texture()
- tex.type = data
- self._current_tex = tex
- self._current_surface.tex_color.append(tex)
-
- def readSURF_DTEX(self, length):
- """DTEX chunk."""
- data = self.readNBytes(length)
- n = data.find("\000")
- if n!=-1:
- data = data[:n]
-
- tex = Texture()
- tex.type = data
- self._current_tex = tex
- self._current_surface.tex_diffuse.append(tex)
-
- def readSURF_STEX(self, length):
- """STEX chunk."""
- data = self.readNBytes(length)
- n = data.find("\000")
- if n!=-1:
- data = data[:n]
-
- tex = Texture()
- tex.type = data
- self._current_tex = tex
- self._current_surface.tex_specular.append(tex)
-
- def readSURF_RTEX(self, length):
- """RTEX chunk."""
- data = self.readNBytes(length)
- n = data.find("\000")
- if n!=-1:
- data = data[:n]
-
- tex = Texture()
- tex.type = data
- self._current_tex = tex
- self._current_surface.tex_reflection.append(tex)
-
- def readSURF_TTEX(self, length):
- """TTEX chunk."""
- data = self.readNBytes(length)
- n = data.find("\000")
- if n!=-1:
- data = data[:n]
-
- tex = Texture()
- tex.type = data
- self._current_tex = tex
- self._current_surface.tex_transparency.append(tex)
-
- def readSURF_LTEX(self, length):
- """LTEX chunk."""
- data = self.readNBytes(length)
- n = data.find("\000")
- if n!=-1:
- data = data[:n]
-
- tex = Texture()
- tex.type = data
- self._current_tex = tex
- self._current_surface.tex_luminosity.append(tex)
-
- def readSURF_BTEX(self, length):
- """BTEX chunk."""
- data = self.readNBytes(length)
- n = data.find("\000")
- if n!=-1:
- data = data[:n]
-
- tex = Texture()
- tex.type = data
- self._current_tex = tex
- self._current_surface.tex_bump.append(tex)
-
- def readSURF_TFLG(self, length):
- """TFLG chunk."""
- if length!=2:
- raise LWOBError, "Invalid TFLG size (%d instead of 2)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TFLG chunk"
- data = self.readNBytes(2)
- flags = struct.unpack(">H", data)[0]
- self._current_tex.flags = flags
-
- def readSURF_TSIZ(self, length):
- """TSIZ chunk."""
- if length!=12:
- raise LWOBError, "Invalid TSIZ size (%d instead of 12)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TSIZ chunk"
- data = self.readNBytes(12)
- v = vec3(struct.unpack(">fff", data))
- self._current_tex.size = v
-
- def readSURF_TCTR(self, length):
- """TCTR chunk."""
- if length!=12:
- raise LWOBError, "Invalid TCTR size (%d instead of 12)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TCTR chunk"
- data = self.readNBytes(12)
- v = vec3(struct.unpack(">fff", data))
- self._current_tex.center = v
-
- def readSURF_TFAL(self, length):
- """TFAL chunk."""
- if length!=12:
- raise LWOBError, "Invalid TFAL size (%d instead of 12)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TFAL chunk"
- data = self.readNBytes(12)
- v = vec3(struct.unpack(">fff", data))
- self._current_tex.falloff = v
-
- def readSURF_TVEL(self, length):
- """TVEL chunk."""
- if length!=12:
- raise LWOBError, "Invalid TVEL size (%d instead of 12)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TVEL chunk"
- data = self.readNBytes(12)
- v = vec3(struct.unpack(">fff", data))
- self._current_tex.velocity = v
-
- def readSURF_TCLR(self, length):
- """TCLR chunk."""
- if length!=4:
- raise LWOBError, "Invalid TCLR size (%d instead of 4)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TCLR chunk"
- data = self.readNBytes(4)
- col = struct.unpack(">BBB", data[:3])
- self._current_tex.color = v
-
- def readSURF_TVAL(self, length):
- """TVAL chunk."""
- if length!=2:
- raise LWOBError, "Invalid TVAL size (%d instead of 2)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TVAL chunk"
- data = self.readNBytes(2)
- val = struct.unpack(">H", data)[0]
- self._current_tex.value = val
-
- def readSURF_TAMP(self, length):
- """TAMP chunk."""
- if length!=4:
- raise LWOBError, "Invalid TAMP size (%d instead of 4)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TAMP chunk"
- data = self.readNBytes(4)
- amp = struct.unpack(">f", data)[0]
- self._current_tex.bumpamplitude = amp
-
- def readSURF_TFP0(self, length):
- """TFP0 chunk."""
- if length!=4:
- raise LWOBError, "Invalid TFP0 size (%d instead of 4)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TFP0 chunk"
- data = self.readNBytes(4)
- f = struct.unpack(">f", data)[0]
- self._current_tex.floatparams[0] = f
-
- def readSURF_TFP1(self, length):
- """TFP1 chunk."""
- if length!=4:
- raise LWOBError, "Invalid TFP1 size (%d instead of 4)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TFP1 chunk"
- data = self.readNBytes(4)
- f = struct.unpack(">f", data)[0]
- self._current_tex.floatparams[1] = f
-
- def readSURF_TFP2(self, length):
- """TFP2 chunk."""
- if length!=4:
- raise LWOBError, "Invalid TFP2 size (%d instead of 4)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TFP2 chunk"
- data = self.readNBytes(4)
- f = struct.unpack(">f", data)[0]
- self._current_tex.floatparams[2] = f
-
- def readSURF_TFP3(self, length):
- """TFP3 chunk."""
- if length!=4:
- raise LWOBError, "Invalid TFP3 size (%d instead of 4)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TFP3 chunk"
- data = self.readNBytes(4)
- f = struct.unpack(">f", data)[0]
- self._current_tex.floatparams[3] = f
-
- def readSURF_TFP4(self, length):
- """TFP4 chunk."""
- if length!=4:
- raise LWOBError, "Invalid TFP4 size (%d instead of 4)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TFP4 chunk"
- data = self.readNBytes(4)
- f = struct.unpack(">f", data)[0]
- self._current_tex.floatparams[4] = f
-
- def readSURF_TFP5(self, length):
- """TFP5 chunk."""
- if length!=4:
- raise LWOBError, "Invalid TFP5 size (%d instead of 4)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TFP5 chunk"
- data = self.readNBytes(4)
- f = struct.unpack(">f", data)[0]
- self._current_tex.floatparams[5] = f
-
- def readSURF_TFP6(self, length):
- """TFP6 chunk."""
- if length!=4:
- raise LWOBError, "Invalid TFP6 size (%d instead of 4)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TFP6 chunk"
- data = self.readNBytes(4)
- f = struct.unpack(">f", data)[0]
- self._current_tex.floatparams[6] = f
-
- def readSURF_TFP7(self, length):
- """TFP7 chunk."""
- if length!=4:
- raise LWOBError, "Invalid TFP7 size (%d instead of 4)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TFP7 chunk"
- data = self.readNBytes(4)
- f = struct.unpack(">f", data)[0]
- self._current_tex.floatparams[7] = f
-
- def readSURF_TFP8(self, length):
- """TFP8 chunk."""
- if length!=4:
- raise LWOBError, "Invalid TFP8 size (%d instead of 4)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TFP8 chunk"
- data = self.readNBytes(4)
- f = struct.unpack(">f", data)[0]
- self._current_tex.floatparams[8] = f
-
- def readSURF_TFP9(self, length):
- """TFP9 chunk."""
- if length!=4:
- raise LWOBError, "Invalid TFP9 size (%d instead of 4)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TFP9 chunk"
- data = self.readNBytes(4)
- f = struct.unpack(">f", data)[0]
- self._current_tex.floatparams[9] = f
-
- def readSURF_TIP0(self, length):
- """TIP0 chunk."""
- if length!=2:
- raise LWOBError, "Invalid TIP0 size (%d instead of 2)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TIP0 chunk"
- data = self.readNBytes(2)
- i = struct.unpack(">h", data)[0]
- self._current_tex.intparams[0] = i
-
- def readSURF_TIP1(self, length):
- """TIP1 chunk."""
- if length!=2:
- raise LWOBError, "Invalid TIP1 size (%d instead of 2)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TIP1 chunk"
- data = self.readNBytes(2)
- i = struct.unpack(">h", data)[0]
- self._current_tex.intparams[1] = i
-
- def readSURF_TIP2(self, length):
- """TIP2 chunk."""
- if length!=2:
- raise LWOBError, "Invalid TIP2 size (%d instead of 2)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TIP2 chunk"
- data = self.readNBytes(2)
- i = struct.unpack(">h", data)[0]
- self._current_tex.intparams[2] = i
-
- def readSURF_TIP3(self, length):
- """TIP3 chunk."""
- if length!=2:
- raise LWOBError, "Invalid TIP3 size (%d instead of 2)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TIP3 chunk"
- data = self.readNBytes(2)
- i = struct.unpack(">h", data)[0]
- self._current_tex.intparams[3] = i
-
- def readSURF_TIP4(self, length):
- """TIP4 chunk."""
- if length!=2:
- raise LWOBError, "Invalid TIP4 size (%d instead of 2)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TIP4 chunk"
- data = self.readNBytes(2)
- i = struct.unpack(">h", data)[0]
- self._current_tex.intparams[4] = i
-
- def readSURF_TIP5(self, length):
- """TIP5 chunk."""
- if length!=2:
- raise LWOBError, "Invalid TIP5 size (%d instead of 2)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TIP5 chunk"
- data = self.readNBytes(2)
- i = struct.unpack(">h", data)[0]
- self._current_tex.intparams[5] = i
-
- def readSURF_TIP6(self, length):
- """TIP6 chunk."""
- if length!=2:
- raise LWOBError, "Invalid TIP6 size (%d instead of 2)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TIP6 chunk"
- data = self.readNBytes(2)
- i = struct.unpack(">h", data)[0]
- self._current_tex.intparams[6] = i
-
- def readSURF_TIP7(self, length):
- """TIP7 chunk."""
- if length!=2:
- raise LWOBError, "Invalid TIP7 size (%d instead of 2)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TIP7 chunk"
- data = self.readNBytes(2)
- i = struct.unpack(">h", data)[0]
- self._current_tex.intparams[7] = i
-
- def readSURF_TIP8(self, length):
- """TIP8 chunk."""
- if length!=2:
- raise LWOBError, "Invalid TIP8 size (%d instead of 2)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TIP8 chunk"
- data = self.readNBytes(2)
- i = struct.unpack(">h", data)[0]
- self._current_tex.intparams[8] = i
-
- def readSURF_TIP9(self, length):
- """TIP9 chunk."""
- if length!=2:
- raise LWOBError, "Invalid TIP9 size (%d instead of 2)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TIP9 chunk"
- data = self.readNBytes(2)
- i = struct.unpack(">h", data)[0]
- self._current_tex.intparams[9] = i
-
- def readSURF_TIMG(self, length):
- """TIMG chunk."""
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TIMG chunk"
- data = self.readNBytes(length)
- n = data.find("\000")
- if n!=-1:
- data = data[:n]
-
- self._current_tex.imagename = data
-
- def readSURF_TALP(self, length):
- """TALP chunk."""
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TALP chunk"
- data = self.readNBytes(length)
- n = data.find("\000")
- if n!=-1:
- data = data[:n]
-
- self._current_tex.alphaname = data
-
- def readSURF_TWRP(self, length):
- """TWRP chunk."""
- if length!=4:
- raise LWOBError, "Invalid TWRP size (%d instead of 4)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TWRP chunk"
- data = self.readNBytes(4)
- w,h = struct.unpack(">HH", data)
- self._current_tex.widthwrap = w
- self._current_tex.heightwrap = h
-
- def readSURF_TAAS(self, length):
- """TAAS chunk."""
- if length!=4:
- raise LWOBError, "Invalid TAAS size (%d instead of 4)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TAAS chunk"
- data = self.readNBytes(4)
- aa = struct.unpack(">f", data)[0]
- self._current_tex.antialiasingstrength = aa
-
- def readSURF_TOPC(self, length):
- """TOPC chunk."""
- if length!=4:
- raise LWOBError, "Invalid TOPC size (%d instead of 4)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the TOPC chunk"
- data = self.readNBytes(4)
- op = struct.unpack(">f", data)[0]
- self._current_tex.opacity = op
-
- def readSURF_SHDR(self, length):
- """SHDR chunk."""
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the SHDR chunk"
- name = self.readNBytes(length)
- n = name.find("\000")
- if n!=-1:
- name = name[:n]
-
- self._current_tex.shader.append(name)
-
- def readSURF_SDAT(self, length):
- """SDAT chunk."""
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the SDAT chunk"
- data = self.readNBytes(length)
- self._current_tex.shaderdata.append(data)
-
- def readSURF_IMSQ(self, length):
- """IMSQ chunk."""
- if length!=6:
- raise LWOBError, "Invalid IMSQ size (%d instead of 6)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the IMSQ chunk"
- data = self.readNBytes(6)
- offset,flags,looplen = struct.unpack(">HHH", data)
- self._current_tex.seq_offset = offset
- self._current_tex.seq_flags = flags
- self._current_tex.seq_looplength = looplen
-
- def readSURF_FLYR(self, length):
- """FLYR chunk."""
- if length!=8:
- raise LWOBError, "Invalid FLYR size (%d instead of 8)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the FLYR chunk"
- data = self.readNBytes(8)
- b,e = struct.unpack(">II", data)
- self._current_tex.flyer_begin = b
- self._current_tex.flyer_end = e
-
- def readSURF_IMCC(self, length):
- """IMCC chunk."""
- if length!=6:
- raise LWOBError, "Invalid IMCC size (%d instead of 6)"%length
- if self._current_tex==None:
- raise LWOBError, "Invalid position of the IMCC chunk"
- data = self.readNBytes(6)
- speed,low,high = struct.unpack(">HHH", data)
- self._current_tex.cycle_speed = speed
- self._current_tex.cycle_low = low
- self._current_tex.cycle_high = high
-
-
- #####
-
- def skipChunk(self, length):
- """Skip a chunk/sub chunk in the file (without reading it).
-
- Sets the file's position to the begin of the next chunk.
- length is the chunk length as it is stored in the file.
- The method takes care of adding the pad byte if length is odd.
- """
- if length%2==1:
- length += 1
- self._file.seek(length, 1)
- self._bytes_left -= length
-
- def readChunkHeader(self):
- """Read the head of the next chunk.
-
- Returns a tuple (tag, length).
- """
- s = self.readNBytes(8)
- tag = s[:4]
- length = struct.unpack(">I", s[4:])[0]
- return tag, length
-
- def readSubChunkHeader(self):
- """Read the head of the next sub chunk.
-
- Returns a tuple (tag, length).
- """
- s = self.readNBytes(6)
- tag = s[:4]
- length = struct.unpack(">H", s[4:])[0]
- return tag, length
-
- def readNBytes(self, n):
- """Read n bytes.
-
- Throws an exception if less than n bytes were read.
- """
- s = self._file.read(n)
- self._bytes_left -= len(s)
- if len(s)!=n:
- raise LWOBError, "premature end of file"
- return s
-
- def _eofReached(self):
- """Return True when the end of the file has been reached.
- """
- return self._bytes_left<=1
-
-