コード例 #1
0
def makeTerrainFromHeightMap(heightmap):
    """Return a tuple of NodePaths (renderNodePath,collisionNodePath) to
  renderable and collision geometry for a chainable terrain model built from
  the given heightmap.

  collisionNodePath is parented to renderNodePath. renderNodePath is not
  parented to anything by this function.

  Every 3x3 group of quads in the collision geometry is collected under a
  PandaNode for efficient collision detection. This could be improved on by
  building both the renderable and collision geometry as octrees.

  Keyword arguments:
  heightmap -- a 2D list of height values.

  """
    size = len(heightmap)
    renderNodePath = P.NodePath('')
    renderEggData = P.EggData()
    renderVertexPool = P.EggVertexPool('')
    collisionNodePath = renderNodePath.attachNewNode('')
    # Supply the EggGroup & EggVertexPool for the first node.
    collisionVertexPool = P.EggVertexPool('')
    collisionEggGroup = P.EggGroup('')
    collisionEggGroup.addObjectType('barrier')
    # We group every (numQuadGrid x numQuadGrid) quads under 1 collision node.
    numQuadGrid = 3
    # The modulo of (size-2)/numQuadGrid marks when the quads must be grouped
    # into 1 geom.
    edgeMod = (size - 2) % numQuadGrid
    for i in range(0, len(heightmap) - 1, numQuadGrid):
        # Limit nextIrange to avoid it from jump over the edge.
        nextIrange = min(numQuadGrid, len(heightmap) - 1 - i)
        for j in range(0, len(heightmap) - 1):
            for nextI in range(0, nextIrange):
                bl = P.Point3D(i + nextI, j, heightmap[i + nextI][j])
                tr = P.Point3D(i + nextI + 1, j + 1,
                               heightmap[i + nextI + 1][j + 1])
                br = P.Point3D(i + nextI + 1, j, heightmap[i + nextI + 1][j])
                tl = P.Point3D(i + nextI, j + 1, heightmap[i + nextI][j + 1])
                # Construct polygons (quads) with makeQuads.
                renderQuad, collisionQuad = makeQuad(renderVertexPool,
                                                     collisionVertexPool, bl,
                                                     tr, br, tl)
                renderEggData.addChild(renderQuad)
                collisionEggGroup.addChild(collisionQuad)
                if j % numQuadGrid == edgeMod and nextI == nextIrange - 1:
                    # Group the previous (numQuadGrid x numQuadGrid) quads under
                    # collision node.
                    collisionEggData = P.EggData()
                    collisionEggData.addChild(collisionEggGroup)
                    pandaNode = P.loadEggData(collisionEggData)
                    nodePath = collisionNodePath.attachNewNode(
                        pandaNode.getChild(0).getChild(0))
                    # Uncomment the next line to see the collision geom.
                    #nodePath.show()
                    # Supply the EggGroup & EggVertexPool for the next node.
                    collisionEggGroup = P.EggGroup('')
                    collisionEggGroup.addObjectType('barrier')
                    collisionVertexPool = P.EggVertexPool('')
    pandaNode = P.loadEggData(renderEggData)
    renderNodePath.attachNewNode(pandaNode)
    return renderNodePath, collisionNodePath