Example #1
0
  def __pack_data(self):
    # Pack points,normals and texcoords into tuples and convert to ctype floats.
    n_verts = len(self.vertices)
    if len(self.tex_coords) != n_verts:
      if len(self.normals) != n_verts:
        self.N_BYTES = 12 # only use pts
        self.array_buffer = c_floats(self.vertices.reshape(-1).tolist())
      else:
        self.N_BYTES = 24 # use pts and normals
        self.array_buffer = c_floats(np.concatenate((self.vertices, self.normals),
                            axis=1).reshape(-1).tolist())
    else:
      self.N_BYTES = 32 # use all three NB doesn't check that normals are there
      self.array_buffer = c_floats(np.concatenate((self.vertices, self.normals, self.tex_coords),
                          axis=1).reshape(-1).tolist())

    self.ntris = len(self.indices)
    self.element_array_buffer = c_shorts(self.indices.reshape(-1))
    from pi3d.Display import Display
    self.disp = Display.INSTANCE # rely on there always being one!
Example #2
0
    def __init__(self, shape, pts, texcoords, faces, normals=None, smooth=True):
        """Generate a vertex buffer to hold data and indices. If no normals
    are provided then these are generated.

    Arguments:
      *shape*
        Shape object that this Buffer is a child of
      *pts*
        array of vertices tuples i.e. [(x0,y0,z0), (x1,y1,z1),...]
      *texcoords*
        array of texture (uv) coordinates tuples
        i.e. [(u0,v0), (u1,v1),...]
      *faces*
        array of indices (of pts array) defining triangles
        i.e. [(a0,b0,c0), (a1,b1,c1),...]

    Keyword arguments:
      *normals*
        array of vector component tuples defining normals at each
        vertex i.e. [(x0,y0,z0), (x1,y1,z1),...]
      *smooth*
        if calculating normals then average normals for all faces
        meeting at this vertex, otherwise just use first (for speed).

    """
        super(Buffer, self).__init__()

        # Uniform variables all in one array!
        self.unib = (c_float * 9)(0.0, 0.0, 0.0, 0.5, 0.5, 0.5, 1.0, 1.0, 0.0)
        """ pass to shader array of vec3 uniform variables:

    ===== ============================ ==== ==
    vec3        description            python
    ----- ---------------------------- -------
    index                              from to
    ===== ============================ ==== ==
        0  ntile, shiny, blend           0   2
        1  material                      3   5
        2  umult, vmult (only 2 used)    6   7
    ===== ============================ ==== ==
    """
        self.shape = shape

        if not normals:
            LOGGER.debug("Calculating normals ...")

            normals = [[] for p in pts]
            # Calculate normals.
            for f in faces:
                a, b, c = f[0:3]

                ab = Utility.vec_sub(pts[a], pts[b])
                bc = Utility.vec_sub(pts[a], pts[c])
                n = tuple(Utility.vec_normal(Utility.vec_cross(ab, bc)))
                for x in f[0:3]:
                    normals[x].append(n)

            for i, n in enumerate(normals):
                if n:
                    if smooth:
                        norms = [sum(v[k] for v in n) for k in range(3)]
                    else:  # This should be slightly faster for large shapes
                        norms = [n[0][k] for k in range(3)]
                    normals[i] = tuple(Utility.vec_normal(norms))
                else:
                    normals[i] = 0, 0, 0.01

        # keep a copy for speeding up the collision testing of ElevationMap
        self.vertices = pts
        self.normals = normals
        self.tex_coords = texcoords
        self.indices = faces
        self.material = (0.5, 0.5, 0.5, 1.0)

        # Pack points,normals and texcoords into tuples and convert to ctype floats.
        points = [p + n + t for p, n, t in zip(pts, normals, texcoords)]
        self.array_buffer = c_floats(list(itertools.chain(*points)))

        self.ntris = len(faces)
        points = [f[0:3] for f in faces]
        self.element_array_buffer = c_shorts(list(itertools.chain(*points)))
Example #3
0
  def __init__(self, shape, pts, texcoords, faces, normals=None, smooth=True):
    """Generate a vertex buffer to hold data and indices. If no normals
    are provided then these are generated.

    Arguments:
      *shape*
        Shape object that this Buffer is a child of
      *pts*
        array of vertices tuples i.e. [(x0,y0,z0), (x1,y1,z1),...]
      *texcoords*
        array of texture (uv) coordinates tuples
        i.e. [(u0,v0), (u1,v1),...]
      *faces*
        array of indices (of pts array) defining triangles
        i.e. [(a0,b0,c0), (a1,b1,c1),...]

    Keyword arguments:
      *normals*
        array of vector component tuples defining normals at each
        vertex i.e. [(x0,y0,z0), (x1,y1,z1),...]
      *smooth*
        if calculating normals then average normals for all faces
        meeting at this vertex, otherwise just use first (for speed).

    """
    super(Buffer, self).__init__()

    # Uniform variables all in one array!
    self.unib = (c_float * 12)(0.0, 0.0, 0.0,
                              0.5, 0.5, 0.5,
                              1.0, 1.0, 0.0,
                              0.0, 0.0, 0.0)
    """ pass to shader array of vec3 uniform variables:

    ===== ============================ ==== ==
    vec3        description            python
    ----- ---------------------------- -------
    index                              from to
    ===== ============================ ==== ==
        0  ntile, shiny, blend           0   2
        1  material                      3   5
        2  umult, vmult, point_size      6   8
        3  u_off, v_off (only 2 used)    9  10
    ===== ============================ ==== ==
    """
    #self.shape = shape
    self.textures = []
    pts = np.array(pts)
    texcoords = np.array(texcoords)
    faces = np.array(faces)

    if normals == None: #i.e. normals will only be generated if explictly None
      LOGGER.debug('Calculating normals ...')

      normals = np.zeros(pts.shape, dtype=pts.dtype) #empty array rights size

      fv = pts[faces] #expand faces with x,y,z values for each vertex
      #cross product of two edges of triangles
      fn = np.cross(fv[:][:][:,1] - fv[:][:][:,0], fv[:][:][:,2] - fv[:][:][:,0])
      fn = Utility.normalize_v3(fn)
      normals[faces[:,0]] += fn #add up all normal vectors for a vertex
      normals[faces[:,1]] += fn
      normals[faces[:,2]] += fn
      Utility.normalize_v3(normals)
    else:
      normals = np.array(normals)
      
    # keep a copy for speeding up the collision testing of ElevationMap
    self.vertices = pts
    self.normals = normals
    self.tex_coords = texcoords
    self.indices = faces
    self.material = (0.5, 0.5, 0.5, 1.0)

    # Pack points,normals and texcoords into tuples and convert to ctype floats.
    n_verts = len(pts)
    if len(texcoords) != n_verts:
      if len(normals) != n_verts:
        self.N_BYTES = 12 # only use pts
        self.array_buffer = c_floats(pts.reshape(-1).tolist())
      else:
        self.N_BYTES = 24 # use pts and normals
        self.array_buffer = c_floats(np.concatenate((pts, normals),
                            axis=1).reshape(-1).tolist())
    else:
      self.N_BYTES = 32 # use all three NB doesn't check that normals are there
      self.array_buffer = c_floats(np.concatenate((pts, normals, texcoords),
                          axis=1).reshape(-1).tolist())

    self.ntris = len(faces)
    self.element_array_buffer = c_shorts(faces.reshape(-1))