Here is some code that allows you to create a simple grid; it also shows how you can use a DecalEffect to overlay tile-highlight geometry onto your map geometry:
from panda3d.core import *
from direct.showbase.ShowBase import ShowBase
class MyGame(ShowBase):
def __init__(self):
ShowBase.__init__(self)
self.disableMouse()
self.camera.setPos(0., -200., 200.)
self.camera.setP(-45.)
self.map = self.__createMap(200.)
self.map.reparentTo(self.render)
self.map.setColor(0., .3, 0.)
grid_size = 200.
tile_size = 10.
self.grid = self.__createGrid(grid_size, tile_size)
self.grid.reparentTo(self.map)
self.grid.setColor(1., 1., 1.)
self.grid.setRenderModeThickness(2)
self.grid.setZ(.1) # prevent z-fighting
# example tile highlight
tile_hilite = self.__createTileHilite(tile_size)
tile_hilite.reparentTo(self.map)
tile_hilite.setColor(1., 0., 0.)
tile_offset = 0. if (grid_size // tile_size) % 2 else .5
tile_x = - (3 + tile_offset) * tile_size
tile_y = (2 + tile_offset) * tile_size
tile_hilite.setPos(tile_x, tile_y, 0.)
self.map.setEffect(DecalEffect.make()) # prevent z-fighting
def __createGridLineX(self, length):
""" Create a grid line in the X-direction with its origin at its center """
vertex_format = GeomVertexFormat.getV3n3cpt2()
vertex_data = GeomVertexData("gridline_data", vertex_format, Geom.UHStatic)
pos_writer = GeomVertexWriter(vertex_data, "vertex")
pos_writer.addData3f(-length * .5, 0., 0.)
pos_writer.addData3f(length * .5, 0., 0.)
lines = GeomLines(Geom.UHStatic)
lines.addVertices(0, 1)
geom = Geom(vertex_data)
geom.addPrimitive(lines)
geom_node = GeomNode("grid_line")
geom_node.addGeom(geom)
return NodePath(geom_node)
def __createGrid(self, line_length, line_spacing):
""" Create a square grid with its origin at its center """
grid = NodePath("grid")
lines_x = grid.attachNewNode("")
lines_x.setY(-line_length * .5)
line = self.__createGridLineX(line_length)
line_count = int(line_length // line_spacing) + 1
for i in range(line_count):
line_copy = line.copyTo(lines_x)
line_copy.setY(i * line_spacing)
lines_x.flattenStrong()
lines_y = lines_x.copyTo(grid)
lines_y.setH(90.)
grid.flattenStrong()
return grid
def __createMap(self, size):
vertex_format = GeomVertexFormat.getV3n3cpt2()
vertex_data = GeomVertexData("map_data", vertex_format, Geom.UHStatic)
pos_writer = GeomVertexWriter(vertex_data, "vertex")
offset = size * .5
pos_writer.addData3f(-offset, -offset, 0.)
pos_writer.addData3f(offset, -offset, 0.)
pos_writer.addData3f(offset, offset, 0.)
pos_writer.addData3f(-offset, offset, 0.)
tris = GeomTriangles(Geom.UHStatic)
tris.addVertices(0, 1, 2)
tris.addVertices(0, 2, 3)
geom = Geom(vertex_data)
geom.addPrimitive(tris)
geom_node = GeomNode("map")
geom_node.addGeom(geom)
return NodePath(geom_node)
def __createTileHilite(self, size):
""" Create a square tile highlight with its origin at its center """
vertex_format = GeomVertexFormat.getV3n3cpt2()
vertex_data = GeomVertexData("tile_data", vertex_format, Geom.UHStatic)
pos_writer = GeomVertexWriter(vertex_data, "vertex")
offset = size * .5
pos_writer.addData3f(-offset, -offset, 0.)
pos_writer.addData3f(offset, -offset, 0.)
pos_writer.addData3f(offset, offset, 0.)
pos_writer.addData3f(-offset, offset, 0.)
tris = GeomTriangles(Geom.UHStatic)
tris.addVertices(0, 1, 2)
tris.addVertices(0, 2, 3)
geom = Geom(vertex_data)
geom.addPrimitive(tris)
geom_node = GeomNode("tile")
geom_node.addGeom(geom)
return NodePath(geom_node)
game = MyGame()
game.run()
Admittedly, offsetting the grid’s Z value isn’t the greatest remedy against z-fighting here, but with GeomLines tricks like using a DecalEffect or setDepthOffset simply don’t work, while setBin, setDepthTest, setDepthWrite et al can be problematic too, so it’s all I could come up with.
Anyway, hope it helps.