Creating a tiled mesh at runtime


#1

This sample needs an additional three image files to use as the textures, wich should named as ‘1.png’, ‘2.png’, ‘3.png’ and placed in the same dir with the script.

from pandac.PandaModules import *
loadPrcFileData("editor-startup", "show-frame-rate-meter #t")
import direct.directbase.DirectStart
from random import randint

node = GeomNode('gnode')
geoms = []
textures_count = 3
# Creating a separate geom for the each textures
# and prepearing the vertex data format for this geom
for i in xrange(textures_count):
    gvd = GeomVertexData('name', GeomVertexFormat.getV3t2(), Geom.UHStatic)
    geom = Geom(gvd)
    prim = GeomTriangles(Geom.UHStatic)
    vertex = GeomVertexWriter(gvd, 'vertex')
    texcoord = GeomVertexWriter(gvd, 'texcoord')
    tex = loader.loadTexture('%i.png' % (i+1))
    tex.setMagfilter(Texture.FTLinearMipmapLinear)
    tex.setMinfilter(Texture.FTLinearMipmapLinear)
    geoms.append({'geom':geom,
                  'prim':prim,
                  'vertex':vertex,
                  'texcoord':texcoord,
                  'index':0,
                  'gvd':gvd,
                  'texture':tex})

# Making and filling the mesh data
for x in xrange(0,100):
    for z in xrange(0,100):
        t_img = randint(0,textures_count - 1) # assign with random texture
        i = geoms[t_img]['index']
        geoms[t_img]['vertex'].addData3f(x, 0, z)
        geoms[t_img]['texcoord'].addData2f(0, 0)
        geoms[t_img]['vertex'].addData3f(x, 0, z+1)
        geoms[t_img]['texcoord'].addData2f(0, 1)
        geoms[t_img]['vertex'].addData3f(x+1, 0, z+1)
        geoms[t_img]['texcoord'].addData2f(1, 1)
        geoms[t_img]['vertex'].addData3f(x+1, 0, z)
        geoms[t_img]['texcoord'].addData2f(1, 0)
        # d: index displace, becouse we use one vertex pool for the all geoms
        d = i * (textures_count + 1)
        geoms[t_img]['prim'].addVertices(d, d + 2, d + 1)
        geoms[t_img]['prim'].addVertices(d, d + 3, d + 2)
        geoms[t_img]['index'] += 1

# Close a primitive, add them to the geom and add the texture attribute
for i in xrange(3):
    geoms[i]['prim'].closePrimitive()
    geoms[i]['geom'].addPrimitive(geoms[i]['prim'])
    node.addGeom(geoms[i]['geom'])
    node.setGeomState(i, node.getGeomState(i).addAttrib(TextureAttrib.make(geoms[i]['texture'])))


terrain = render.attachNewNode(node)
#terrain.setRenderModeWireframe()
terrain.analyze()
base.cam.setPos(0,-50,15)

run() 

Result:

1 total nodes (including 0 instances); 0 LODNodes.
0 transforms; 0% of nodes have some render attribute.
3 Geoms, with 3 GeomVertexDatas and 1 GeomVertexFormats, appear on 1 GeomNodes.
40000 vertices, 0 normals, 0 colors, 40000 texture coordinates.
GeomVertexData arrays occupy 782K memory.
GeomPrimitive arrays occupy 118K memory.
20000 triangles:
  0 of these are on 0 tristrips.
  20000 of these are independent triangles.
3 textures, estimated minimum 192K texture memory required.


Modifire
Help with procedurally created geoms
Minecraft clone graphics poor performance
Approach to picking tiles
Autotiling mesh with pathfinding
#2

a very useful little snippet indeed. thx for sharing.


#3

Neat stuff. I’m unfamiliar with creating geoms - is there a quick way to alter them once they’ve been created? Say, for example, that I wanted to remove every fifth quad of the 10000, or maybe add some more at a different height, or change the color of a few?

Thanks

Edit:

I figured out the different heights, but I’m still at a loss for removing at runtime.


#4

As I know, you can modify an exist geometry, but you can not to add or remove vertices at usual way. I think the easiest way to do this is recreating your geom without that vertices. If you want to do this in runtime, then it make sense to split a big geom into the some parts and recreate the needed parts separately.


#5

Sorry to resurrect a dead thread, but this topic is of a lot of interest to me as I think this technique is the only way to increase my frame rate to acceptable levels. The only problem I have is, I have no clue how to modify this to create cubes instead of a flat plane.

I think what I need to do is add an additional xrange (for y in xrange) in between the x and z lines, then add the four additional points I would need to make this a cube. But I’m getting tripped up on actual implementation.

If someone has already done this, or knows how, any chance you can provide some guidance?

Thanks!
ZM