Example #1
0
def loadECfiles(path, fname, suffix='jpg', nobottom=False):
    """Helper for loading environment cube faces.
  TODO nobottom will redraw the top on the bottom of cube. It really should
  substitute a blank (black) texture instead!
  
  Arguments:
    *path*
      to the image files relative to the top directory.
    *fname*
      The stem of the file name without the _top, _bottom, _right etc.
  
  Keyword arguments:
    *suffix*
      String to add after the '_top','_bottom' has been added to the stem.
    *nobottom*
      If True then only load five parts into array the bottom will be
      drawn with the previous image i.e. top.
  """
    if nobottom:
        parts = [p for p in CUBE_PARTS if p != 'bottom']
    else:
        parts = CUBE_PARTS

    files = (os.path.join(path, '%s_%s.%s' % (fname, p, suffix))
             for p in parts)
    return [Texture(f) for f in files]
Example #2
0
File: Sprite.py Project: jmalm/pi3d
 def __init__(self, texture, shader, **kwds):
     super(ImageSprite, self).__init__(**kwds)
     if not isinstance(texture, Texture):  # i.e. can load from file name
         texture = Texture(texture)
     self.set_shader(shader)
     self.buf[0].set_draw_details(shader, [texture])
     self.set_2d_size()  # method in Shape, default full window size
Example #3
0
print("Good turnings are often greener and tend to be near")
print("(but in the opposite direction to) big holes")
print("############################################################")
print("If you get touched by a monster you will return to the start!")
print("############################################################")
print()

# Setup display and initialise pi3d
DISPLAY = Display.create(x=100, y=100, background=(0.4, 0.8, 0.8, 1))

shader = Shader("shaders/uv_reflect")
flatsh = Shader("shaders/uv_flat")
#========================================

# load Textures
rockimg1 = Texture("textures/techy1.jpg")
rockimg2 = Texture("textures/rocktile2.jpg")
tree2img = Texture("textures/tree2.png")
raspimg = Texture("textures/Raspi256x256.png")
monstimg = Texture("textures/pong2.jpg")
monsttex = Texture("textures/floor_nm.jpg")
shineimg = Texture("textures/stars.jpg")

# environment cube
ectex = Texture("textures/ecubes/skybox_stormydays.jpg")
myecube = EnvironmentCube(size=900.0, maptype="CROSS")
myecube.set_draw_details(flatsh, ectex)

# Create elevation map
mapwidth = 1000.0
mapdepth = 1000.0
Example #4
0
  def __init__(self, pex_file, emission_rate=10, scale=1.0, rot_rate=None,
                                                rot_var=0.0, **kwargs):
    ''' has to be supplied with a pex xml type file to parse. The results
    are loaded into new attributes of the instance of this class with identifiers
    matching the Elements of the pex file. There is zero checking for the
    correct file format:
      self.texture={name:'particle.png'}
      self.sourcePosition={x:160.00,y:369.01}
      self.sourcePositionVariance={x:60.00,y:0.00}
      self.speed=138.16
      self.speedVariance=0.00
      self.particleLifeSpan=0.7000
      self.particleLifespanVariance=0.0000
      self.angle=224.38
      self.angleVariance=360.00
      self.gravity={x:0.00,y:-1400.00}
      self.radialAcceleration=0.00
      self.tangentialAcceleration=0.00
      self.radialAccelVariance=0.00
      self.tangentialAccelVariance=-0.00
      self.startColor={red:0.15,green:0.06,blue:1.00,alpha:1.00}
      self.startColorVariance={red:0.00,green:0.00,blue:0.00,alpha:0.00}
      self.finishColor={red:0.00,green:0.14,blue:0.23,alpha:0.00}
      self.finishColorVariance={red:0.00,green:0.00,blue:0.00,alpha:0.00}
      self.maxParticles=300
      self.startParticleSize=43.79
      self.startParticleSizeVariance=0.00
      self.finishParticleSize=138.11
      self.FinishParticleSizeVariance=0.00
      self.duration=-1.00
      self.emitterType=0
      self.maxRadius=100.00
      self.maxRadiusVariance=0.00
      self.minRadius=0.00
      self.rotatePerSecond=0.00
      self.rotatePerSecondVariance=0.00
      self.blendFuncSource=770
      self.blendFuncDestination=772
      self.rotationStart=0.00
      self.rotationStartVariance=0.00
      self.rotationEnd=0.00
      self.rotationEndVariance=0.00
    '''
    # first parse the pex file, json would have been nicer than xml!
    _config = parse(pex_file).childNodes[0].childNodes
    for c in _config:
      if c.localName is not None:
        key = c.localName
        val = {}
        for v in c.attributes.items():
          try:
            v_tp = int(v[1]) # try int first
          except ValueError:
            try:
              v_tp = float(v[1]) # if not try float
            except ValueError:
              v_tp = v[1] # otherwise leave as string
          if v[0] == 'value': # single value 'value' don't use dictionary
            val = v_tp
            break
          else:
            val[v[0]] = v_tp # not just a value
        self.__setattr__(key, val)

    self._emission_rate = emission_rate # particles per second
    self._last_emission_time = None
    self._last_time = None
    self.scale = scale
    self.rot_rate = rot_rate
    self.rot_var = rot_var
    
    ''' make the numpy arrays to hold the particle info
    vertices[0]   x position of centre of point relative to centre of screen in pixels
    vertices[1]   y position
    vertices[2]   z depth but fract(z) is used as a multiplier for point size
    normals[0]    rotation in radians
    normals[1]    red and green values to multiply with the texture
    normals[2]    blue and alph values to multiply with the texture. The values
                  are packed into the whole number and fractional parts of
                  the float i.e. where R and G are between 0.0 and 0.999
                  normals[:,2] = floor(999 * R) + G
    tex_coords[0] distance of left side of sprite square from left side of
                  texture in uv scale 0.0 to 1.0
    tex_coords[1] distance of top of sprite square from top of texture
    arr[8]        x velocity
    arr[9]        y velocity
    arr[10]       lifespan
    arr[11]       lifespan remaining
    arr[12:16]    rgba target values
    arr[16:20]    rgba difference
    arr[20]       size delta (finish size - start size) / full_lifespan
    arr[21]       radial acceleration
    arr[22]       tangential acceleration
    '''
    self.arr = np.zeros((self.maxParticles, 23), dtype='float32')
    self.point_size = max(self.startParticleSize + self.startParticleSizeVariance,
                    self.finishParticleSize + self.FinishParticleSizeVariance) #NB capital F!
    super(PexParticles, self).__init__(vertices=self.arr[:,0:3], 
                            normals=self.arr[:,3:6], 
                            tex_coords=self.arr[:,6:8], 
                            point_size=self.point_size * self.scale, **kwargs) # pass to Points.__init__()
    shader = Shader('uv_pointsprite')
    try:
      tex = Texture(self.texture['name']) # obvious first!
    except:
      import os
      tex = Texture(os.path.join(
                      os.path.split(pex_file)[0], self.texture['name']))
    self.set_draw_details(shader, [tex])
    self.unif[48] = 1.0 # sprite uses whole image
Example #5
0
def loadFileOBJ(model, fileName):
  """Loads an obj file with associated mtl file to produce Buffer object
  as part of a Shape. Arguments:
    *model*
      Model object to add to.
    *fileName*
      Path and name of obj file relative to program file.
  """
  model.coordinateSystem = "Y-up"
  model.parent = None
  #model.childModel = [] # don't really need parent and child pointers but will speed up traversing tree
  model.vNormal = False
  model.vGroup = {} # holds the information for each vertex group

  # read in the file and parse into some arrays, name='teapot', z=4

  #import os
  if fileName[0] != '/':
    for p in sys.path:
      if os.path.isfile(p + '/' + fileName): # this could theoretically get different files with same name
        fileName = p + '/' + fileName
        break
  filePath = os.path.split(os.path.abspath(fileName))[0]
  LOGGER.debug(filePath)
  f = open(fileName, 'r')

  vertices = []
  normals = []
  uvs = []

  faces = {}

  materials = {}
  material = ""
  mcounter = 0
  mcurrent = 0
  mtllib = ""

  # current face state
  group = 0
  objct = 0
  smooth = 0

  for l in f:
    chunks = l.split()
    if len(chunks) > 0:

      # Vertices as (x,y,z) coordinates
      # v 0.123 0.234 0.345
      if chunks[0] == "v" and len(chunks) >= 4:
        x = float(chunks[1])
        y = float(chunks[2])
        z = -float(chunks[3]) # z direction away in gl es 2.0 shaders
        vertices.append((x, y, z))

      # Normals in (x, y, z) form; normals might not be unit
      # vn 0.707 0.000 0.707
      if chunks[0] == "vn" and len(chunks) >= 4:
        x = float(chunks[1])
        y = float(chunks[2])
        z = -float(chunks[3]) # z direction away in gl es 2.0 shaders
        normals.append((x, y, z))

      # Texture coordinates in (u,v)
      # vt 0.500 -1.352
      if chunks[0] == "vt" and len(chunks) >= 3:
        u = float(chunks[1])
        v = float(chunks[2])
        uvs.append((u, v))

      # Face
      if chunks[0] == "f" and len(chunks) >= 4:
        vertex_index = []
        uv_index = []
        normal_index = []


        # Precompute vert / normal / uv lists
        # for negative index lookup
        vertlen = len(vertices) + 1
        normlen = len(normals) + 1
        uvlen = len(uvs) + 1

        for v in chunks[1:]:
          vertex = parse_vertex(v)
          if vertex['v']:
            if vertex['v'] < 0:
              vertex['v'] += vertlen
            vertex_index.append(vertex['v'])
          if vertex['t']:
            if vertex['t'] < 0:
              vertex['t'] += uvlen
            uv_index.append(vertex['t'])
          if vertex['n']:
            if vertex['n'] < 0:
              vertex['n'] += normlen
            normal_index.append(vertex['n'])
        if not mcurrent in faces:
          faces[mcurrent] = []

        faces[mcurrent].append({
          'vertex':vertex_index,
          'uv':uv_index,
          'normal':normal_index,

          'group':group,
          'object':objct,
          'smooth':smooth,
          })

      # Group
      if chunks[0] == "g" and len(chunks) == 2:
        group = chunks[1]

      # Object
      if chunks[0] == "o" and len(chunks) == 2:
        objct = chunks[1]

      # Materials definition
      if chunks[0] == "mtllib" and len(chunks) == 2:
        mtllib = chunks[1]

      # Material
      if chunks[0] == "usemtl":
        if len(chunks) > 1:
          material = chunks[1]
        else:
          material = ""
        if not material in materials:
          mcurrent = mcounter
          materials[material] = mcounter
          mcounter += 1
        else:
          mcurrent = materials[material]

      # Smooth shading
      if chunks[0] == "s" and len(chunks) == 2:
        smooth = chunks[1]
    
  for g in faces: # make each of these into an array_buffer with its own material
    g_vertices = []
    g_normals = []
    g_tex_coords = []
    g_indices = []
    i = 0 # vertex counter in this material
    LOGGER.debug("len uv={}".format(len(vertices)))
    vec_dict = {} # hold unique combinations of v/u/n
    for f in faces[g]:
      vec_list = [] # hold index vals for each array_buffer entry for this face
      length = len(f['vertex'])
      length_n = len(f['normal'])
      length_uv = len(f['uv'])
      for v in range(length):
        vec_tuple = (f['vertex'][v],
                    f['uv'][v] if length_uv > 0 else -1,
                    f['normal'][v] if length_n == length else -1)
        if vec_tuple in vec_dict: #already exists don't duplicate
          vec_list.append(vec_dict[vec_tuple])
        else:
          g_vertices.append(vertices[vec_tuple[0] - 1])
          if length_n == length: #only use normals if there is one for each vertex
            g_normals.append(normals[vec_tuple[2] - 1])
          if (length_uv > 0 and len(uvs[vec_tuple[1] - 1]) == 2):
            g_tex_coords.append(uvs[vec_tuple[1] - 1])
          vec_dict[vec_tuple] = i
          vec_list.append(i)
          i += 1
      for t in range(len(vec_list) - 2):
        g_indices.append((vec_list[0], vec_list[t + 2], vec_list[t + 1]))
    if len(g_normals) != len(g_vertices):
      g_normals = None # force Buffer.__init__() to generate normals
    model.buf.append(Buffer(model, g_vertices, g_tex_coords, g_indices, g_normals))
    n = len(model.buf) - 1
    model.vGroup[g] = n

    model.buf[n].indicesLen = len(model.buf[n].element_array_buffer)
    model.buf[n].material = (0.0, 0.0, 0.0, 0.0)
    model.buf[n].draw_method = GL_TRIANGLES

    LOGGER.debug("indices=%s\nvertices=%s", len(model.buf[n].element_array_buffer), 
                                       len(model.buf[n].array_buffer))

  try:
    material_lib = parse_mtl(open(os.path.join(filePath, mtllib), 'r'))
    for m in materials:
      LOGGER.debug(m)
      if 'mapDiffuse' in material_lib[m]:
        tfileName = material_lib[m]['mapDiffuse']
        model.buf[model.vGroup[materials[m]]].texFile = tfileName
        model.buf[model.vGroup[materials[m]]].textures = [Texture(filePath + '/' + tfileName, blend=False, flip=True)] # load from file
      else:
        model.buf[model.vGroup[materials[m]]].texFile = None
        model.buf[model.vGroup[materials[m]]].textures = []
        if 'colorDiffuse' in material_lib[m]:#TODO don't create this array if texture being used though not exclusive.
        #TODO check this works with appropriate mtl file
          redVal = material_lib[m]['colorDiffuse'][0]
          grnVal = material_lib[m]['colorDiffuse'][1]
          bluVal = material_lib[m]['colorDiffuse'][2]
          model.buf[model.vGroup[materials[m]]].material = (redVal, grnVal, bluVal, 1.0)
          model.buf[model.vGroup[materials[m]]].unib[3:6] = [redVal, grnVal, bluVal]
  except:
    LOGGER.warning('no material specified')
Example #6
0
# Setup display and initialise pi3d
DISPLAY = Display.create(x=200, y=200, frames_per_second=20)
DISPLAY.set_background(0.4, 0.8, 0.8, 1)  # r,g,b,alpha
camera = Camera((0, 0, 0), (0, 0, -1),
                (1, 1000, 30.0, DISPLAY.width / DISPLAY.height))
light = Light((10, -10, 20))
# load shader
shader = Shader("shaders/uv_reflect")
flatsh = Shader("shaders/uv_flat")
defocus = Defocus()
#========================================

# Setting 2nd param to True renders 'True' Blending
# (this can be changed later to 'False' with 'rockimg2.blend = False')
groundimg = Texture("textures/stripwood.jpg")
monstimg = Texture("textures/pong3.png")
ballimg = Texture("textures/pong2.jpg")

# environment cube
ectex = Texture("textures/ecubes/skybox_stormydays.jpg")
myecube = EnvironmentCube(camera, light, 900.0, "CROSS")
myecube.set_draw_details(flatsh, [ectex])

#ball
maxdsz = 0.3
radius = 1.0
ball = Sphere(camera, light, radius, 12, 12, 0.0, "sphere", -4, 8, -7)
# Shape.set_draw_details is a wrapper for calling the method on each item in buf
# as is done explicitly here for no reason than to show that it can be done!
ball.buf[0].set_draw_details(shader, [ballimg], 0.0, 0.0)
Example #7
0
    def __init__(self,
                 camera=None,
                 light=None,
                 w=1.0,
                 h=1.0,
                 corner=0.1,
                 name="",
                 texture=None,
                 shader=None,
                 x=0.0,
                 y=0.0,
                 z=20.0,
                 rx=0.0,
                 ry=0.0,
                 rz=0.0,
                 sx=1.0,
                 sy=1.0,
                 sz=1.0,
                 cx=0.0,
                 cy=0.0,
                 cz=0.0):
        """Uses standard constructor for Shape. Extra Keyword arguments:

      *w*
        Width.
      *h*
        Height.
      *corner*
        The size that the edge thirds will be. Used for mapping textures to plane
    """
        super(ButtonSprite, self).__init__(camera, light, name, x, y, z, rx,
                                           ry, rz, sx, sy, sz, cx, cy, cz)
        self.width = w
        self.height = h
        self.corner = corner
        verts = []
        norms = []
        texcoords = []
        inds = []

        ww = w / 2.0
        hh = h / 2.0

        for (j, y) in enumerate((hh, hh - corner, -hh + corner, -hh)):
            y_uv = j / 3.0
            for (i, x) in enumerate((-ww, -ww + corner, ww - corner, ww)):
                x_uv = i / 3.0
                verts.extend([[x, y, 0.0]])
                norms.extend([[0.0, 0.0, -1.0]])
                texcoords.extend([[x_uv, y_uv]])
                if i > 0 and j > 0:
                    n = j * 4 + i
                    inds.extend([[n - 1, n - 5, n - 4], [n - 4, n, n - 1]])

        self.buf = [Buffer(self, verts, texcoords, inds, norms)]
        if texture is None:
            for p in sys.path:
                img_path = os.path.join(p, "pi3d/shape/button_image.png")
                if os.path.exists(img_path):
                    texture = Texture(img_path)
                    break
        else:
            if not isinstance(texture,
                              Texture):  # i.e. can load from file name
                texture = Texture(texture)
        if shader is None:
            shader = Shader("uv_flat")
        else:
            if not isinstance(shader, Shader):
                shader = Shader(shader)
        self.set_draw_details(shader, [texture])
  def __init__(self, pex_file, emission_rate=10, scale=1.0, rot_rate=None,
                        rot_var=0.0, new_batch=0.1, hardness=2.0, **kwargs):
    ''' has to be supplied with a pex xml type file to parse. The results
    are loaded into new attributes of the instance of this class with identifiers
    matching the Elements of the pex file. There is zero checking for the
    correct file format.

      pex_file:       file name. if "circle" then lite option doesn't
                      use texture lookup and used mat_pointsprite shader
      emission_rate:  new particles per second
      scale:          scale the point size and location
      rot_rate:       UV mapping rotates
      rot_var:        variance in rotation rate
      new_batch:      proportion of emission_rate to batch (for efficiency)
      hardness:       for lite version

    The following attributes are created from the pex file and can be subsequently
    altered. i.e. self.sourcePosition['x'] += 2.0

      self.texture={name:'particle.png'}
      self.sourcePosition={x:160.00,y:369.01}
      self.sourcePositionVariance={x:60.00,y:0.00}
      self.speed=138.16
      self.speedVariance=0.00
      self.particleLifeSpan=0.7000
      self.particleLifespanVariance=0.0000
      self.angle=224.38
      self.angleVariance=360.00
      self.gravity={x:0.00,y:-1400.00}
      self.radialAcceleration=0.00
      self.tangentialAcceleration=0.00
      self.radialAccelVariance=0.00
      self.tangentialAccelVariance=-0.00
      self.startColor={red:0.15,green:0.06,blue:1.00,alpha:1.00}
      self.startColorVariance={red:0.00,green:0.00,blue:0.00,alpha:0.00}
      self.finishColor={red:0.00,green:0.14,blue:0.23,alpha:0.00}
      self.finishColorVariance={red:0.00,green:0.00,blue:0.00,alpha:0.00}
      self.maxParticles=300
      self.startParticleSize=43.79
      self.startParticleSizeVariance=0.00
      self.finishParticleSize=138.11
      self.FinishParticleSizeVariance=0.00
      self.duration=-1.00
      self.emitterType=0
      self.maxRadius=100.00
      self.maxRadiusVariance=0.00
      self.minRadius=0.00
      self.rotatePerSecond=0.00
      self.rotatePerSecondVariance=0.00
      self.blendFuncSource=770
      self.blendFuncDestination=772
      self.rotationStart=0.00
      self.rotationStartVariance=0.00
      self.rotationEnd=0.00
      self.rotationEndVariance=0.00
    '''
    # first parse the pex file, json would have been nicer than xml!
    _config = parse(pex_file).childNodes[0].childNodes
    for c in _config:
      if c.localName is not None:
        key = c.localName
        val = {}
        for v in c.attributes.items():
          try:
            v_tp = int(v[1]) # try int first
          except ValueError:
            try:
              v_tp = float(v[1]) # if not try float
            except ValueError:
              v_tp = v[1] # otherwise leave as string
          if v[0] == 'value': # single value 'value' don't use dictionary
            val = v_tp
            break
          else:
            val[v[0]] = v_tp # not just a value
        self.__setattr__(key, val)

    self._emission_rate = emission_rate # particles per second
    self._last_emission_time = None
    self._last_time = None
    self._new_batch = emission_rate * new_batch # to clump new particles
    self.scale = scale
    self.rot_rate = rot_rate
    self.rot_var = rot_var
    # make a flag to avoid this expensive operation if no accelerators
    self.any_acceleration = (self.gravity['x'] != 0.0 or self.gravity['y'] != 0.0 or
                             self.radialAcceleration != 0.0 or
                             self.tangentialAcceleration != 0.0)
    self.any_colorchange = any(self.startColor[i] != self.finishColor[i]
                               for i in ('red','green','blue','alpha'))
    ''' Buffer.array_buffer holds
    [0] vertices[0] x position of centre of point relative to centre of screen in pixels
    [1] vertices[1] y position
    [2] vertices[2] z depth but fract(z) is used as a multiplier for point size
    [3] normals[0]  rotation in radians
    [4] normals[1]  red and green values to multiply with the texture
    [5] normals[2]  blue and alph values to multiply with the texture. The values
                    are packed into the whole number and fractional parts of
                    the float i.e. where R and G are between 0.0 and 0.999
                    normals[:,2] = floor(999 * R) + G
    [6] tex_coords[0] distance of left side of sprite square from left side of
                    texture in uv scale 0.0 to 1.0
    [7] tex_coords[1] distance of top of sprite square from top of texture
       for lite version using the mat_pointsprite shader
    [3:7] hold RGBA in simple float form

       make additional numpy array to hold the particle info
    arr[0]          x velocity
    arr[1]          y velocity
    arr[2]          lifespan
    arr[3]          lifespan remaining
    arr[4:8]        rgba target values
    arr[8:12]       rgba difference
    arr[12]         size delta (finish size - start size) / full_lifespan
    arr[13]         radial acceleration
    arr[14]         tangential acceleration
    '''
    self.arr = np.zeros((self.maxParticles, 15), dtype='float32')
    self.point_size = max(self.startParticleSize + self.startParticleSizeVariance,
                    self.finishParticleSize + self.FinishParticleSizeVariance) #NB capital F!
    super(PexParticles, self).__init__(vertices=np.zeros((self.maxParticles, 3), dtype='float32'), 
                            normals=np.zeros((self.maxParticles, 3), dtype='float32'), 
                            tex_coords=np.zeros((self.maxParticles, 2), dtype='float32'), 
                            point_size=self.point_size * self.scale, **kwargs) # pass to Points.__init__()
    if self.texture['name'] == 'circle': # TODO alternative geometries
      self.lite = True
      shader = Shader('mat_pointsprite')
      self.set_shader(shader)
      self.buf[0].unib[0] = hardness
    else:
      self.lite = False
      shader = Shader('uv_pointsprite')
      try:
        tex = Texture(self.texture['name']) # obvious first!
      except:
        import os
        tex = Texture(os.path.join(
                        os.path.split(pex_file)[0], self.texture['name']))
      self.set_draw_details(shader, [tex])
      self.unif[48] = 1.0 # sprite uses whole image
Example #9
0
# create splash screen and draw it
splash = ImageSprite("textures/tiger_splash.jpg", shade2d, w=10, h=10, z=0.2)
splash.draw()
DISPLAY.swap_buffers()

# create environment cube
ectex = EnvironmentCube.loadECfiles('textures/ecubes/Miramar', 'miramar_256',
                                    suffix='png')
myecube = EnvironmentCube.EnvironmentCube(size=1800.0, maptype='FACES')
myecube.set_draw_details(flatsh, ectex)

# Create elevation map
mapwidth = 2000.0
mapdepth = 2000.0
mapheight = 100.0
mountimg1 = Texture('textures/mountains3_512.jpg')
bumpimg = Texture('textures/grasstile_n.jpg')
tigerbmp = Texture('models/Tiger/tiger_bump.jpg')
topbmp = Texture('models/Tiger/top_bump.jpg')
#roadway = Texture('textures/road5.png')
mymap = ElevationMap(mapfile='textures/mountainsHgt2.png',
                     width=mapwidth, depth=mapdepth,
                     height=mapheight, divx=64, divy=64)

mymap.buf[0].set_draw_details(shader, [mountimg1, bumpimg], 128.0, 0.0)

FOG = (0.7, 0.8, 0.9, 0.5)

def set_fog(shape):
  shape.set_fog(FOG, 1000.0)
Example #10
0
# Setup display and initialise pi3d
DISPLAY = Display.create(x=10, y=10, w=900, h=600, frames_per_second=25)
DISPLAY.set_background(0.4, 0.6, 0.8, 1.0)  # r,g,b,alpha

persp_cam = Camera.instance()  # default instance camera perspecive view
ortho_cam = Camera(is_3d=False)  # 2d orthographic view camera

#setup textures, light position and initial model position
Light((0, 5, 0))
#create shaders
shader = Shader("shaders/uv_reflect")
flatsh = Shader("shaders/uv_flat")
defocus = Defocus()

#Create textures
shapeimg = Texture("textures/straw1.jpg")
shapebump = Texture("textures/floor_nm.jpg", True)
shapeshine = Texture("textures/pong3.png")

#Create shape
myshape = MergeShape(camera=persp_cam)  #specify perspective view
asphere = Sphere(sides=16, slices=16)
myshape.radialCopy(asphere, step=72)
myshape.position(0.0, 0.0, 5.0)
myshape.set_draw_details(shader, [shapeimg, shapebump, shapeshine], 8.0, 0.1)

mysprite = Sprite(w=10.0, h=10.0, camera=persp_cam)
mysprite.position(0.0, 0.0, 15.0)
mysprite.set_draw_details(flatsh, [shapebump])

tick = 0
Example #11
0
cloud_depth = 350.0
zd = 1.0 * cloud_depth / cloudno

MARGIN = 100

# Setup display and initialise pi3d
DISPLAY = Display.create(x=MARGIN, y=MARGIN)
scnx = DISPLAY.width
scny = DISPLAY.height

DISPLAY.set_background(0, 0.7, 1, 1)
shader = Shader("shaders/uv_flat")
#############################

cloudTex = []
cloudTex.append(Texture("textures/cloud2.png", True))
cloudTex.append(Texture("textures/cloud3.png", True))
cloudTex.append(Texture("textures/cloud4.png", True))
cloudTex.append(Texture("textures/cloud5.png", True))
cloudTex.append(Texture("textures/cloud6.png", True))

# Setup cloud positions and cloud image refs
cz = 0.0
clouds = []  # an array for the clouds
for b in range(0, cloudno):
    size = 0.5 + random.random() / 2.0
    cloud = Sprite(w=size * widex,
                   h=size * widey,
                   x=150.0 * (random.random() - 0.5),
                   y=0.0,
                   z=cloud_depth - cz)
Example #12
0
from pi3d.shape.EnvironmentCube import EnvironmentCube
from pi3d.shape.EnvironmentCube import loadECfiles

from pi3d.util.Screenshot import screenshot
from pi3d.util import Utility

# Setup display and initialise pi3d
DISPLAY = Display.create(x=50, y=50)

shader = Shader('shaders/uv_flat')
#========================================

#select the environment cube with 'box'...
box = 3
if box == 0:
    ectex = [Texture('textures/ecubes/skybox_interstellar.jpg')]
    myecube = EnvironmentCube(size=900.0, maptype='CROSS')
elif box == 1:
    ectex = [Texture('textures/ecubes/SkyBox.jpg')]
    myecube = EnvironmentCube(size=900.0, maptype='HALFCROSS')
elif box == 2:
    ectex = loadECfiles('textures/ecubes', 'sbox_interstellar', nobottom=True)
    myecube = EnvironmentCube(size=900.0, maptype='FACES', nobottom=True)
else:
    ectex = loadECfiles('textures/ecubes', 'skybox_hall')
    myecube = EnvironmentCube(size=900.0, maptype='FACES')

myecube.set_draw_details(shader, ectex)

rot = 0.0
tilt = 0.0
Example #13
0
def loadFileOBJ(model, fileName):
    """Loads an obj file with associated mtl file to produce Buffer object
  as part of a Shape. Arguments:
    *model*
      Model object to add to.
    *fileName*
      Path and name of obj file relative to top directory.
  """
    model.coordinateSystem = "Y-up"
    model.parent = None
    model.childModel = [
    ]  # don't really need parent and child pointers but will speed up traversing tree
    model.vNormal = False
    model.vGroup = {}  # holds the information for each vertex group

    # read in the file and parse into some arrays

    filePath = os.path.split(os.path.abspath(fileName))[0]
    print filePath
    f = open(fileName, 'r')

    vertices = []
    normals = []
    uvs = []

    faces = {}

    materials = {}
    material = ""
    mcounter = 0
    mcurrent = 0
    numv = [
    ]  #number of vertices for each material (nb each vertex will have three coords)
    numi = []  #number of indices (triangle corners) for each material

    mtllib = ""

    # current face state
    group = 0
    objct = 0
    smooth = 0

    for l in f:
        chunks = l.split()
        if len(chunks) > 0:

            # Vertices as (x,y,z) coordinates
            # v 0.123 0.234 0.345
            if chunks[0] == "v" and len(chunks) == 4:
                x = float(chunks[1])
                y = float(chunks[2])
                z = -float(chunks[3])  # z direction away in gl es 2.0 shaders
                vertices.append((x, y, z))

            # Normals in (x, y, z) form; normals might not be unit
            # vn 0.707 0.000 0.707
            if chunks[0] == "vn" and len(chunks) == 4:
                x = float(chunks[1])
                y = float(chunks[2])
                z = -float(chunks[3])  # z direction away in gl es 2.0 shaders
                normals.append((x, y, z))

            # Texture coordinates in (u,v)
            # vt 0.500 -1.352
            if chunks[0] == "vt" and len(chunks) >= 3:
                u = float(chunks[1])
                v = float(chunks[2])
                uvs.append((u, v))

            # Face
            if chunks[0] == "f" and len(chunks) >= 4:
                vertex_index = []
                uv_index = []
                normal_index = []

                # Precompute vert / normal / uv lists
                # for negative index lookup
                vertlen = len(vertices) + 1
                normlen = len(normals) + 1
                uvlen = len(uvs) + 1

                if len(numv) < (mcurrent + 1): numv.append(0)
                if len(numi) < (mcurrent + 1): numi.append(0)

                for v in chunks[1:]:
                    numv[mcurrent] += 1
                    numi[mcurrent] += 3
                    vertex = parse_vertex(v)
                    if vertex['v']:
                        if vertex['v'] < 0:
                            vertex['v'] += vertlen
                        vertex_index.append(vertex['v'])
                    if vertex['t']:
                        if vertex['t'] < 0:
                            vertex['t'] += uvlen
                        uv_index.append(vertex['t'])
                    if vertex['n']:
                        if vertex['n'] < 0:
                            vertex['n'] += normlen
                        normal_index.append(vertex['n'])
                numi[
                    mcurrent] -= 6  # number of corners of triangle = (n-2)*3 where n is the number of corners of face
                if not mcurrent in faces: faces[mcurrent] = []

                faces[mcurrent].append({
                    'vertex': vertex_index,
                    'uv': uv_index,
                    'normal': normal_index,
                    'group': group,
                    'object': objct,
                    'smooth': smooth,
                })

            # Group
            if chunks[0] == "g" and len(chunks) == 2:
                group = chunks[1]

            # Object
            if chunks[0] == "o" and len(chunks) == 2:
                objct = chunks[1]

            # Materials definition
            if chunks[0] == "mtllib" and len(chunks) == 2:
                mtllib = chunks[1]

            # Material
            if chunks[0] == "usemtl":
                if len(chunks) > 1:
                    material = chunks[1]
                else:
                    material = ""
                if not material in materials:
                    mcurrent = mcounter
                    materials[material] = mcounter
                    mcounter += 1
                else:
                    mcurrent = materials[material]

            # Smooth shading
            if chunks[0] == "s" and len(chunks) == 2:
                smooth = chunks[1]
    if VERBOSE:
        print "materials:  ", materials
        print "numv: ", numv

    for g in faces:
        numv[g] -= 1
        numi[g] -= 1

        g_vertices = []
        g_normals = []
        g_tex_coords = []
        g_indices = []
        i = 0  # vertex counter in this material
        if VERBOSE:
            print "len uv=", len(vertices)
        for f in faces[g]:
            iStart = i
            for v in range(len(f['vertex'])):
                g_vertices.append(vertices[f['vertex'][v] - 1])
                g_normals.append(normals[f['normal'][v] - 1])
                if (len(f['uv']) > 0 and len(uvs[f['uv'][v] - 1]) == 2):
                    g_tex_coords.append(uvs[f['uv'][v] - 1])
                i += 1
            n = i - iStart - 1
            for t in range(1, n):
                g_indices.append((iStart, iStart + t + 1, iStart + t))

        model.buf.append(
            Buffer(model, g_vertices, g_tex_coords, g_indices, g_normals))
        n = len(model.buf) - 1
        model.vGroup[g] = n

        model.buf[n].indicesLen = len(model.buf[n].indices)
        model.buf[n].material = (0.0, 0.0, 0.0, 0.0)
        model.buf[n].ttype = GL_TRIANGLES

        #for i in range(len(model.vGroup[g].normals)):
        #  print model.vGroup[g].normals[i],
        if VERBOSE:
            print
            print "indices=", len(model.buf[n].indices)
            print "vertices=", len(model.buf[n].vertices)
            print "normals=", len(model.buf[n].normals)
            print "tex_coords=", len(model.buf[n].tex_coords)

    material_lib = parse_mtl(open(os.path.join(filePath, mtllib), 'r'))
    for m in materials:
        if VERBOSE:
            print m
        if 'mapDiffuse' in material_lib[m]:
            tfileName = material_lib[m]['mapDiffuse']
            model.buf[model.vGroup[materials[m]]].texFile = tfileName
            model.buf[model.vGroup[materials[m]]].textures = [
                Texture(os.path.join(filePath, tfileName), False, True)
            ]  # load from file
        else:
            model.buf[model.vGroup[materials[m]]].texFile = None
            model.buf[model.vGroup[materials[m]]].textures = []
            if 'colorDiffuse' in material_lib[
                    m]:  #TODO don't create this array if texture being used though not exclusive.
                #TODO check this works with appropriate mtl file
                redVal = material_lib[m]['colorDiffuse'][0]
                grnVal = material_lib[m]['colorDiffuse'][1]
                bluVal = material_lib[m]['colorDiffuse'][2]
                model.buf[model.vGroup[materials[m]]].material = (redVal,
                                                                  grnVal,
                                                                  bluVal, 1.0)
                model.buf[model.vGroup[materials[m]]].unib[3:6] = [
                    redVal, grnVal, bluVal
                ]
Example #14
0
from pi3d.shape.Sphere import Sphere

from pi3d.util.Screenshot import screenshot

# Setup display and initialise pi3d
DISPLAY = Display.create(x=50,
                         y=50,
                         w=-100,
                         h=-100,
                         background=(0.4, 0.8, 0.8, 1))
shader = Shader("shaders/uv_reflect")
flatsh = Shader("shaders/uv_flat")
#############################

# Load textures
reflcn = Texture("textures/stars.jpg")

#load environment cube
ectex = loadECfiles("textures/ecubes", "sbox_interstellar")
myecube = EnvironmentCube(size=900.0, maptype="FACES")
myecube.set_draw_details(flatsh, ectex)

# Create elevation map
mapwidth = 1000.0
mapdepth = 1000.0
mapheight = 60.0
mountimg1 = Texture("textures/mars_colour.png")
bumpimg = Texture("textures/mudnormal.jpg")
mymap = ElevationMap(mapfile="textures/mars_height.png",
                     width=mapwidth,
                     depth=mapdepth,
Example #15
0
from pi3d.Shader import Shader
from pi3d.Light import Light

from pi3d.shape.Model import Model
from pi3d.util.Screenshot import screenshot

# Setup display and initialise pi3d
DISPLAY = Display.create(x=100, y=100, background=(0.2, 0.4, 0.6, 1))

Light((1, 1, 1))

shader = Shader("shaders/mat_reflect")
#========================================
# load bump and reflection textures
bumptex = Texture("textures/floor_nm.jpg")
shinetex = Texture("textures/stars.jpg")

# load model_loadmodel
mymodel = Model(file_string='models/teapot.egg', name='teapot', x=0, y=0, z=10)
mymodel.set_shader(shader)
# material is set in the file
mymodel.set_normal_shine(bumptex, 4.0, shinetex, 0.2, is_uv = False)

# Fetch key presses
mykeys = Keyboard()

while DISPLAY.loop_running():
  mymodel.draw()
  mymodel.rotateIncY(2.0)
  mymodel.rotateIncZ(0.1)
Example #16
0
    def __init__(self,
                 textures,
                 shader,
                 camera=None,
                 light=None,
                 w=1.0,
                 h=1.0,
                 name="",
                 x=0.0,
                 y=0.0,
                 z=20.0,
                 rx=0.0,
                 ry=0.0,
                 rz=0.0,
                 sx=1.0,
                 sy=1.0,
                 sz=1.0,
                 cx=0.0,
                 cy=0.0,
                 cz=0.0):
        """Uses standard constructor for Shape. Arguments:
      *textures*
        must be a two dimensional list of lists of textures or strings 
        (which must be the path/names of image files) The array runs left
        to right then down so six textures in spreadsheet notation would be
        
        [[R1C1, R1C2], [R2C1, R2C2], [R3C1, R3C2]]
        
      *shader*
        shader to use
        
      Extra keyword arguments:  
        
      *w*
        Width.
      *h*
        Height.
    """
        try:
            nh = len(textures)
            nw = len(textures[0])
            super(MultiSprite, self).__init__(camera, light, name, x, y, z, rx,
                                              ry, rz, sx, sy, sz, cx, cy, cz)
            self.width = w
            self.height = h
            self.ttype = GL_TRIANGLES
            self.verts = []
            self.norms = []
            self.texcoords = []
            self.inds = []

            ww = w / 2.0 / nw
            hh = h / 2.0 / nh
            self.buf = []
            for i in range(nw):
                for j in range(nh):
                    offw = w * ((1.0 - nw) / 2.0 + i) / nw
                    offh = -h * ((1.0 - nh) / 2.0 + j) / nh
                    self.verts = ((-ww + offw, hh + offh,
                                   0.0), (ww + offw, hh + offh,
                                          0.0), (ww + offw, -hh + offh, 0.0),
                                  (-ww + offw, -hh + offh, 0.0))
                    self.norms = ((0, 0, -1), (0, 0, -1), (0, 0, -1), (0, 0,
                                                                       -1))
                    self.texcoords = ((0.0, 0.0), (1.0, 0.0), (1.0, 1.0),
                                      (0.0, 1.0))

                    self.inds = ((0, 1, 3), (1, 2, 3))

                    thisbuf = Buffer(self, self.verts, self.texcoords,
                                     self.inds, self.norms)
                    if not isinstance(textures[j][i],
                                      Texture):  # i.e. can load from file name
                        textures[j][i] = Texture(textures[j][i])
                    thisbuf.textures = [textures[j][i]]
                    self.buf.append(thisbuf)
            self.set_shader(shader)
            self.set_2d_size()  # method in Shape, default full window size
        except IndexError:
            print('Must supply a list of lists of Textures or strings')
            return
Example #17
0
print("move this terminal window to top of screen to see FPS")
print("=====================================================")

# Setup display and initialise pi3d
DISPLAY = Display.create(x=200, y=150, frames_per_second=25.0)
DISPLAY.set_background(0.4, 0.6, 0.8, 0.5)  # r,g,b,alpha

#setup textures, light position and initial model position
Light((5, -5, 8))
#create shaders
shader = Shader("shaders/uv_reflect")
matsh = Shader("shaders/mat_reflect")
flatsh = Shader("shaders/uv_flat")

#Create textures
shapeimg = Texture("textures/straw1.jpg")
shapebump = Texture("textures/mudnormal.jpg")
waterbump = []
iFiles = glob.glob("textures/water/n_norm???.png")
iFiles.sort()  # order is vital to animation!
for f in iFiles:
    waterbump.append(Texture(f))
num_n = len(waterbump)
shapeshine = Texture("textures/stars.jpg")

#Create shape
myshape = MergeShape()
num = (2, 2)
asphere = Sphere(sides=32)
for i in range(num[0]):
    for j in range(num[1]):
Example #18
0
def loadFileOBJ(model, fileName):
    """Loads an obj file with associated mtl file to produce Buffer object
  as part of a Shape. Arguments:
    *model*
      Model object to add to.
    *fileName*
      Path and name of obj file relative to program file.
  """
    model.coordinateSystem = "Y-up"
    model.parent = None
    #model.childModel = [] # don't really need parent and child pointers but will speed up traversing tree
    model.vNormal = False
    model.vGroup = {}  # holds the information for each vertex group

    # read in the file and parse into some arrays, name='teapot', z=4

    #import os
    if fileName[0] != '/':
        for p in sys.path:
            if os.path.isfile(
                    p + '/' + fileName
            ):  # this could theoretically get different files with same name
                fileName = p + '/' + fileName
                break
    filePath = os.path.split(os.path.abspath(fileName))[0]
    LOGGER.info(filePath)
    f = open(fileName, 'r')

    vertices = []
    normals = []
    uvs = []

    faces = {}

    materials = {}
    material = ""
    mcounter = 0
    mcurrent = 0
    numv = [
    ]  #number of vertices for each material (nb each vertex will have three coords)
    numi = []  #number of indices (triangle corners) for each material

    mtllib = ""

    # current face state
    group = 0
    objct = 0
    smooth = 0

    for l in f:
        chunks = l.split()
        if len(chunks) > 0:

            # Vertices as (x,y,z) coordinates
            # v 0.123 0.234 0.345
            if chunks[0] == "v" and len(chunks) >= 4:
                x = float(chunks[1])
                y = float(chunks[2])
                z = -float(chunks[3])  # z direction away in gl es 2.0 shaders
                vertices.append((x, y, z))

            # Normals in (x, y, z) form; normals might not be unit
            # vn 0.707 0.000 0.707
            if chunks[0] == "vn" and len(chunks) >= 4:
                x = float(chunks[1])
                y = float(chunks[2])
                z = -float(chunks[3])  # z direction away in gl es 2.0 shaders
                normals.append((x, y, z))

            # Texture coordinates in (u,v)
            # vt 0.500 -1.352
            if chunks[0] == "vt" and len(chunks) >= 3:
                u = float(chunks[1])
                v = float(chunks[2])
                uvs.append((u, v))

            # Face
            if chunks[0] == "f" and len(chunks) >= 4:
                vertex_index = []
                uv_index = []
                normal_index = []

                # Precompute vert / normal / uv lists
                # for negative index lookup
                vertlen = len(vertices) + 1
                normlen = len(normals) + 1
                uvlen = len(uvs) + 1

                if len(numv) < (mcurrent + 1): numv.append(0)
                if len(numi) < (mcurrent + 1): numi.append(0)

                for v in chunks[1:]:
                    numv[mcurrent] += 1
                    numi[mcurrent] += 3
                    vertex = parse_vertex(v)
                    if vertex['v']:
                        if vertex['v'] < 0:
                            vertex['v'] += vertlen
                        vertex_index.append(vertex['v'])
                    if vertex['t']:
                        if vertex['t'] < 0:
                            vertex['t'] += uvlen
                        uv_index.append(vertex['t'])
                    if vertex['n']:
                        if vertex['n'] < 0:
                            vertex['n'] += normlen
                        normal_index.append(vertex['n'])
                numi[
                    mcurrent] -= 6  # number of corners of triangle = (n-2)*3 where n is the number of corners of face
                if not mcurrent in faces: faces[mcurrent] = []

                faces[mcurrent].append({
                    'vertex': vertex_index,
                    'uv': uv_index,
                    'normal': normal_index,
                    'group': group,
                    'object': objct,
                    'smooth': smooth,
                })

            # Group
            if chunks[0] == "g" and len(chunks) == 2:
                group = chunks[1]

            # Object
            if chunks[0] == "o" and len(chunks) == 2:
                objct = chunks[1]

            # Materials definition
            if chunks[0] == "mtllib" and len(chunks) == 2:
                mtllib = chunks[1]

            # Material
            if chunks[0] == "usemtl":
                if len(chunks) > 1:
                    material = chunks[1]
                else:
                    material = ""
                if not material in materials:
                    mcurrent = mcounter
                    materials[material] = mcounter
                    mcounter += 1
                else:
                    mcurrent = materials[material]

            # Smooth shading
            if chunks[0] == "s" and len(chunks) == 2:
                smooth = chunks[1]

    LOGGER.info("materials:  %s\nnumv:  %s", materials, numv)

    for g in faces:
        numv[g] -= 1
        numi[g] -= 1

        g_vertices = []
        g_normals = []
        g_tex_coords = []
        g_indices = []
        i = 0  # vertex counter in this material
        LOGGER.info("len uv=", len(vertices))
        for f in faces[g]:
            iStart = i
            length = len(f['vertex'])
            length_n = len(f['normal'])
            #for component in 'normal', 'uv':
            #  if length > len(f[component]):
            #    LOGGER.error('There were more vertices than %ss: %d > %d',
            #                 component, length, len(f[component]))
            #    length = len(f[component])

            for v in range(length):
                g_vertices.append(vertices[f['vertex'][v] - 1])
                if length_n == length:  #only use normals if there is one for each vertex
                    g_normals.append(normals[f['normal'][v] - 1])
                if (len(f['uv']) > 0 and len(uvs[f['uv'][v] - 1]) == 2):
                    g_tex_coords.append(uvs[f['uv'][v] - 1])
                i += 1
            n = i - iStart - 1
            for t in range(1, n):
                g_indices.append((iStart, iStart + t + 1, iStart + t))
        if len(g_normals) != len(g_vertices):
            g_normals = None  # force Buffer.__init__() to generate normals
        model.buf.append(
            Buffer(model, g_vertices, g_tex_coords, g_indices, g_normals))
        n = len(model.buf) - 1
        model.vGroup[g] = n

        model.buf[n].indicesLen = len(model.buf[n].element_array_buffer)
        model.buf[n].material = (0.0, 0.0, 0.0, 0.0)
        model.buf[n].ttype = GL_TRIANGLES

        LOGGER.info("indices=%s\nvertices=%s",
                    len(model.buf[n].element_array_buffer),
                    len(model.buf[n].array_buffer))

    try:
        material_lib = parse_mtl(open(os.path.join(filePath, mtllib), 'r'))
        for m in materials:
            LOGGER.info(m)
            if 'mapDiffuse' in material_lib[m]:
                tfileName = material_lib[m]['mapDiffuse']
                model.buf[model.vGroup[materials[m]]].texFile = tfileName
                model.buf[model.vGroup[materials[m]]].textures = [
                    Texture(filePath + '/' + tfileName, blend=False, flip=True)
                ]  # load from file
            else:
                model.buf[model.vGroup[materials[m]]].texFile = None
                model.buf[model.vGroup[materials[m]]].textures = []
                if 'colorDiffuse' in material_lib[
                        m]:  #TODO don't create this array if texture being used though not exclusive.
                    #TODO check this works with appropriate mtl file
                    redVal = material_lib[m]['colorDiffuse'][0]
                    grnVal = material_lib[m]['colorDiffuse'][1]
                    bluVal = material_lib[m]['colorDiffuse'][2]
                    model.buf[model.vGroup[materials[m]]].material = (redVal,
                                                                      grnVal,
                                                                      bluVal,
                                                                      1.0)
                    model.buf[model.vGroup[materials[m]]].unib[3:6] = [
                        redVal, grnVal, bluVal
                    ]
    except:
        LOGGER.warning('no material specified')
Example #19
0
# Setup display and initialise pi3d
DISPLAY = Display.create(x=100, y=100)
DISPLAY.set_background(0.4, 0.8, 0.8, 1)  # r,g,b,alpha
# yellowish directional light blueish ambient light
Light(lightpos=(1, -1, -3),
      lightcol=(1.0, 1.0, 0.7),
      lightamb=(0.15, 0.1, 0.3))

#========================================

# load shader
shader = Shader("shaders/uv_reflect")
flatsh = Shader("shaders/uv_flat")

tree2img = Texture("textures/tree2.png")
tree1img = Texture("textures/tree1.png")
hb2img = Texture("textures/hornbeam2.png")
bumpimg = Texture("textures/grasstile_n.jpg")
reflimg = Texture("textures/stars.jpg")
rockimg = Texture("textures/rock1.jpg")

clash = Clashtest()

FOG = ((0.3, 0.3, 0.4, 0.5), 650.0)
TFOG = ((0.1, 0.14, 0.12, 0.3), 150.0)

#myecube = EnvironmentCube(900.0,"HALFCROSS")
ectex = loadECfiles("textures/ecubes", "sbox")
myecube = EnvironmentCube(size=900.0, maptype="FACES", name="cube")
myecube.set_draw_details(flatsh, ectex)
Example #20
0
def loadFileEGG(model, fileName):
  """Loads an panda3d egg file to produce Buffer object
  as part of a Shape.

  Arguments:
    *model*
      Model object to add to.
    *fileName*
      Path and name of egg file relative to top directory.

  """
  model.coordinateSystem = "Y-up"
  model.materialList = {}
  model.textureList = {}
  model.vertexGroupList = {}
  model.vertexList = []
  model.polygonList = []
  model.childModelList = []
  model.parentModel = None
  model.childModel = [] # don't really need parent and child pointers but will speed up traversing tree
  model.vNormal = False
  model.vGroup = {} # holds the information for each vertex group

  # read in the file and parse into some arrays

  filePath = os.path.split(os.path.abspath(fileName))[0]
  if VERBOSE:
    print(filePath)
  f = open(fileName, 'r')
  l = f.read() # whole thing as a string in memory this will only work for reasonably small files!!!

  ############### function to parse file as one off process to avoid re-traversing string #########
  # convertes the '<a> b { c <d> e {f} <g> h {i} }' structure
  # into nested arrays ['a', 'b', 'c',[['d','e','',['','','f',[]]],['g','h','',['','','i',[]]]]]
  def pRec(x, bReg, l, i):
    while 1:
      try:
        nxtFind = advance_iterator(bReg)
        j = nxtFind.start()
      except:
        return i+1
      c = l[j]
      if c == "<": # add entry to array at this level
        if len(x[3]) == 0: x[2] = l[i:j].strip() # text after "{" and before "<Tabxyz>"
        i = j+1 # save marker for start of descriptor
        x[3].append(["", "", "", []])

      elif c == "{":
        xn = x[3][len(x[3])-1]
        tx = l[i-1:j].strip().split()
        xn[0] = tx[0] #x[0] & x[1] is the "<Tabxyz>" & "123" prior to "{"
        xn[1] = tx[1] if len(tx) > 1 else ""
        i = pRec(xn, bReg, l, j+1)
      else: #i.e. c="}" # go up one level of recursion
        if len(x[3]) == 0: x[2] = l[i:j].strip()
        return j+1
  ################### end of pRec #################

  ####### go through all the nested <Groups> ####################
  def groupDrill(gp, np):
    structVList = {}
    offsetVList = {}
    structPList = []
    offset = 0
    #numv = 0
    #numi = 0
    for x in gp:
      if len(x) == 0: continue
      if ("<Group>" in x[0]):
        if len(x[1]) > 0:
          nextnp = np+x[1]
        else:
          nextnp = np+str(randint(10000, 99999))
        groupDrill(x[3], nextnp)
      else:
        #build vertex, polygon, normal, triangles, UVs etc etc
        if "<VertexPool>" in x[0]:
          vp = x[1]
          structVList[vp] = []
          offsetVList[vp] = offset
          for v in x[3]:
            #if "<Vertex>" in v[0]: #try with this test first!
            coords = [float(n) for n in v[2].strip().split()] # before first < error if no coords!
            # texture mapping
            UVcoords = []
            normal = []
            for u in v[3]:
              if "<UV>" in u[0]: UVcoords = [float(n) for n in u[2].strip().split()]
              #TODO get UVtangent and UVbinormal out of UVset (and use them!)
              # if ("<Tangent>" in vList[v]): UVtangent = [float(n) for n in (extBracket("<Tangent>", vList[v]))[0].split()] # not sure how to use this at this stage
              #else: UVtangent = []
              # if ("<Binormal>" in vList[v]): UVbinormal = [float(n) for n in (extBracket("<Binormal>", vList[v]))[0].split()] # not sure how to use this at this stage
              #else: UVbinormal = []
              # normals, used in 'smoothing' edges between polygons
              if "<Normal>" in u[0]: normal = [float(n) for n in u[2].strip().split()]
            vInt = int(v[1])
            while (len(structVList[vp]) < (vInt+1)): structVList[vp].append("")
            structVList[vp][vInt] = (vertex(coords, UVcoords, normal))
            offset += 1
    #
      # now go through splitting out the Polygons from this Group same level as vertexGroup
      if "<Polygon>" in x[0]:
        normal = []
        rgba = []
        MRef = ""
        TRef = ""
        for p in x[3]:
          if ("<Normal>" in p[0]): normal = [float(n) for n in p[2].strip().split()]
          if ("<RGBA>" in p[0]): rgba = [float(n) for n in p[2].strip().split()]
          if ("<MRef>" in p[0]): MRef = p[2].strip()
          if ("<TRef>" in p[0]): TRef = p[2].strip()
          if ("<VertexRef>" in p[0]):
            vref = []
            for n in p[2].strip().split():
              vref.append(int(n))
              #numv += 1
              #numi += 3
            #numi -= 6 # number of corners of triangle = (n-2)*3 where n is the number of corners of face
            vpKey = p[3][0][2].strip() # ought to do a for r in p[3]; if "Ref in...
        # add to list
        #while (len(structPList) < (p+1)): structPList.append("")
        #
        structPList.append(polygon(normal, rgba, MRef, TRef, vref, vpKey))

    # now go through the polygons in order of vertexPool+id, trying to ensure that the polygon arrays in each group are built in the order of vertexPool names
    # only cope with one material and one texture per group
    #numv -= 1
    #numi -= 1
    g_vertices = []
    g_normals = []
    g_tex_coords = []
    g_indices = []
    nv = 0 # vertex counter in this material
    #ni = 0 # triangle vertex count in this material

    gMRef = ""
    gTRef = ""
    nP = len(structPList)
    for p in xrange(nP):
      if (len(structPList[p].MRef) > 0): gMRef = structPList[p].MRef
      else: gMRef = ""
      if (len(structPList[p].TRef) > 0): gTRef = structPList[p].TRef
      else: gTRef = ""

      vpKey = structPList[p].vpKey
      vref = structPList[p].vref
      startV = nv
      for j in vref:

        if (len(structVList[vpKey][j].normal) > 0): model.vNormal = True
        else: model.vNormal = False
        if model.coordinateSystem == "z-up":
          thisV = [structVList[vpKey][j].coords[1], structVList[vpKey][j].coords[2], -structVList[vpKey][j].coords[0]]
          if model.vNormal:
            thisN = [structVList[vpKey][j].normal[1], structVList[vpKey][j].normal[2], -structVList[vpKey][j].normal[0]]
        else:
          thisV = [structVList[vpKey][j].coords[0], structVList[vpKey][j].coords[1], -structVList[vpKey][j].coords[2]]
          if model.vNormal:
            thisN = [structVList[vpKey][j].normal[0], structVList[vpKey][j].normal[1], -structVList[vpKey][j].normal[2]]
        g_vertices.append(thisV)
        if model.vNormal: nml = thisN
        else: nml = structPList[p].normal
        g_normals.append(nml)
        uvc = structVList[vpKey][j].UVcoords
        if (len(uvc) == 2):
          g_tex_coords.append(uvc)
        else:
          g_tex_coords.append([0.0, 0.0])
        nv += 1
      n = nv - startV - 1
      for j in range(1, n):
        g_indices.append((startV, startV + j + 1, startV + j))

    ilen = len(g_vertices)
    if ilen > 0:
      model.buf.append(Buffer(model, g_vertices, g_tex_coords, g_indices, g_normals))
      n = len(model.buf) - 1
      model.vGroup[np] = n

      model.buf[n].indicesLen = ilen
      model.buf[n].material = (0.0, 0.0, 0.0, 0.0)
      model.buf[n].ttype = GL_TRIANGLES

      # load the texture file TODO check if same as previously loaded files (for other loadModel()s)
      if (gTRef in model.textureList):
        model.buf[model.vGroup[np]].textures = [model.textureList[gTRef]["texID"]]
        model.buf[model.vGroup[np]].texFile = model.textureList[gTRef]["filename"]
      else:
        model.buf[model.vGroup[np]].textures = []
        model.buf[model.vGroup[np]].texFile = None
        #TODO  don't create this array if texture being used but should be able to combine
        if (gMRef in model.materialList):
          redVal = float(model.materialList[gMRef]["diffr"])
          grnVal = float(model.materialList[gMRef]["diffg"])
          bluVal = float(model.materialList[gMRef]["diffb"])
          model.buf[model.vGroup[np]].material = (redVal, grnVal, bluVal, 1.0)
          model.buf[model.vGroup[np]].unib[3:6] = [redVal, grnVal, bluVal]

        else: model.buf[model.vGroup[np]].material = (0.0, 0.0, 0.0, 0.0)
    ####### end of groupDrill function #####################

  bReg = re.finditer('[{}<]', l)
  xx = ["", "", "", []]
  pRec(xx, bReg, l, 0)
  l = None #in case it's running out of memory?
  f.close()

  for x in xx[3]:
    if "<Texture>" in x[0]:
      model.textureList[x[1]] = {}
      for i in xrange(len(x[3])): model.textureList[x[1]][x[3][i][1]] = x[3][i][2]
      model.textureList[x[1]]["filename"] = x[2].strip("\"")
      if VERBOSE:
        print(filePath, model.textureList[x[1]]["filename"])
      model.textureList[x[1]]["texID"] = Texture(os.path.join(filePath, model.textureList[x[1]]["filename"]), False, True) # load from file
    if "<CoordinateSystem>" in x[0]:
      model.coordinateSystem = x[2].lower()
    if "<Material>" in x[0]:
      model.materialList[x[1]] = {}
      for i in xrange(len(x[3])): model.materialList[x[1]][x[3][i][1]] = x[3][i][2]
    if "<Group>" in x[0]:
      groupDrill(x[3], x[1])
Example #21
0
from pi3d.shape.Building import Building, corridor, SolidObject, Size, Position

from pi3d.util.Screenshot import screenshot

from pi3d.Light import Light

from pi3d.event.Event import InputEvents

# Setup display and initialise pi3d
DISPLAY = Display.create(x=150, y=150, background=(0.4, 0.8, 0.8, 1))
shader = Shader("shaders/uv_reflect")
flatsh = Shader("shaders/uv_flat")
#############################

# Load textures
blockimg = Texture("textures/squareblocks4.png")
roofedgeimg = Texture("textures/roofedging.png")
roofimg = Texture("textures/Roof.png")
greenimg = Texture("textures/squareblocks4green.png")
ectex = loadECfiles("textures/ecubes", "sbox", "jpg")
myecube = EnvironmentCube(size=900.0, maptype="FACES")
myecube.set_draw_details(flatsh, ectex)

# Create elevation map
mapwidth=1000.0
mapdepth=1000.0
mapheight=60.0
floorimg = Texture("textures/dunes3_512.jpg")
bumpimg = Texture("textures/mudnormal.jpg")
mymap = ElevationMap(mapfile="textures/mountainsHgt2.png",
                     width=mapwidth, depth=mapdepth, height=mapheight,