You can use this function to set land materials using either a greyscale or 
indexed image.  I've tested it with several dozen materials.

To create a material map in GIMP, you'll want to start with the correct size, 
draw blocks of the colors you want to use (don't leave black or white unless 
you intend to use them as colors), Image > Mode > Indexed with an optimum 
palette made of the number of colors you want, then once it's indexed go to 
work on your material map.

When calling it, you'll need to pass a tuple or list with the materials you 
want to use; ie:

  material_names = ("water", "sand", "grass", "shale", "snow", "lava")
  materials = []
  for mat in material_names :
    materials.append(soya.Material.get(mat))
  land.set_material_from_image(soya.Image.get("texmap.png"), materials)

I don't know if it'll work without my previous patch to add indexed image 
support, since this tests to see if self.palette is true (set to None for 
greyscale or RGB(A) images, otherwise a string).

It's several times faster than the version I wrote in python earlier this week:

class NewLand(soya.Land) :
  def set_material_from_image(self, texmap, materials) :
    if texmap.width != self.width or texmap.height != self.depth :
      raise('Texture map must be the same size as heightexmap')
    if texmap.nb_color != 1 :
      raise('Texture map must be greyscale or indexed')
    if self.palette : num_materials = len(self.palette)/3
    else : num_materials = 256
    if len(materials) < num_materials :
      raise('Not enough materials provided')
    pixs = texmap.pixels
    for y in range(self.depth) :
      print 'processing line %d' % y
      yoffset = y * self.width
      for x in range(self.width) :
        pix = pixs[(yoffset + x)]
        self.set_material(x, y, materials[pix])

The patch to land.pyx in pyrex is attached:
Index: model/land.pyx
===================================================================
RCS file: /cvs/soya/soya/model/land.pyx,v
retrieving revision 1.23
diff -r1.23 land.pyx
417a418,443
> 
>   def set_material_from_image(self, _Image image, materials):
>     cdef int i, m, w, h, hoffset
>     cdef LandVertex* vertex
>     cdef Pack*       pack[256]
>     if (self._nb_vertex_width != image.width) or \
>        (self._nb_vertex_depth != image.height) :
>       print "WARNING Material map size must equal land size"
>       return
>     if image.nb_color != 1 :
>       print "WARNING Material map must be greyscale or indexed"
>       return
>     if image.palette : m = len(image.palette)/3
>     else : m = 256
>     if len(materials) < m :
>       print "WARNING Material map has more colors than provided materials"
>       return
>     for i from 0 <= i < m :
>       self._add_material(<_Material> (materials[i]))
>       pack[i] =  (<_Material> (materials[i]))._pack(FACE_TRIANGLE)
>     for h from 0 <= h < self._nb_vertex_depth :
>       hoffset = h * self._nb_vertex_width
>       for w from 0 <= w < self._nb_vertex_width :
>         vertex = self._get_vertex(w, h)
>         i = image._pixels[hoffset+w]
>         vertex.pack = pack[i]
_______________________________________________
Soya-user mailing list
[email protected]
https://mail.gna.org/listinfo/soya-user

Reply via email to