Limiting the terrain that an actor can walk on

The concept is the same for a character on terrain as for the camera. You get the character’s location relative to the terrain and use a formula to map that location onto the image.

For another example, we can say that I have a piece of terrain that is 1000 units square with it’s origin in the center in a file called “Terrain.egg”. I have an image that is 2048x2048 with the walkable path drawn on it called “Path.png”. My character is in “Character.egg”.

terrain = loader.loadModel("Terrain.egg")
terrain.reparentTo(render)

character = loader.loadModel("Character.egg")
character.reparentTo(render)

path = PNMImage()
path.read("Path.png")

def getPathPos(character, terrain, path):
  terrainPos = character.getPos(terrain) #Get character's pos relative to terrain.

#Map the 3D coords to the image's coordinates
  pathX = int( ( ( terrainPos.getX() + 500 )/1000 ) * 2048 )
  pathY = int( ( ( terrainPos.getY() + 500 )/1000 ) * 2048 )

return(pathX, pathY)

That code would give you the coordinates of the character’s position on the image if the positive-Y direction in 3D space is the same direction as moving down (from top to bottom) on the image. If the positive-Y direction in 3D space was the same as moving up (from bottom to top) on the image, you would need to use the mapping equations shown below:

  pathX = int( ( ( terrainPos.getX() + 500 )/1000 ) * 2048 )
  pathY = int( 2048 - ( ( ( terrainPos.getY() + 500 )/1000 ) * 2048 ) )

Basically, you get the character’s coordinates relative to the terrain using character.getPos(terrain). Then you remap them to a a new value range to fit the image.

The steps I use for remapping a range of values to a new range are as follows. If you already know how to remap a range of values to a new range, then feel free to ignore this part.

  1. If the minimum value for the starting range is not 0, adjust the current value so that the minimum is 0.
    Example: If the minimum value is -500, add +500 to the current value. If the minimum value is +250, add -250 to the current value.

  2. Convert the current value into a percentage of the maximum value. Note: If you adjusted the current value in step 1, you must adjust the maximum value by the same amount.
    Example: If the maximum value is 500, and I DID NOT change the current value in step 1 because the minimum value was already 0, then I just divide the current value by 500, to get the percentage.
    Example2: If the maximum value is 1500, and I added +1500 to the current value in step 1 to get a minimum value of 0, then I add +1500 to the maximum value to get the new maximum: 3000. Then I divide by the adjusted maximum of 3000 to get the percentage.

  3. Multiply the percentage from step 2 by the maximum value of the new range to get the new value.
    Example: If the maximum value of the new range is 1024, and my percentage from step 2 was 0.75, I multiply 1024 by 0.75 and get 768 as my current value in the new range.

For this method to work, you need to know the coordinate range for the terrain and for the image, of course. Both of those should be known to you anyway, though.