Falling from terrain at the End

Hello,
i have a question. I created a terrain and it is all working well. I can stand on it and walk on it.
But when i reach the end of the map i fall down in an endless hole :-D.
How can i make invisible Walls at the End? I hope someone can tell me :-).
I dont find any clue in the tutorials

mfg Ice

Hm, from a visual perspective ending terrain does not look good. Depending on the gametype/camera perspective you could simply make unpassable mountains surrounding the map itself.

At a point I also wanted to add physics bounds to a small terrain, so that one couldnt walk off the map.

My approach was to create some simple boxes surrounding the edges of the terrain.

Note that this approach presumes that you have moved your terrain so that 0,0 is the corner of the terrain and the terrain is aligned in positive X/Z to make the world space coordinates in the positive axis ranges.

[java]
public class Terrain extends TerrainQuad implements CollisionGroups {

public Terrain() {
}

public Terrain(final String name, final int patchSize, final int totalSize,
		final float[] heightMap) {
	super(name, patchSize, totalSize, heightMap);
}

public Terrain(final String name, final int patchSize, final int quadSize,
		final Vector3f scale, final float[] heightMap, final int totalSize,
		final Vector2f offset, final float offsetAmount) {
	super(name, patchSize, quadSize, scale, heightMap, totalSize, offset,
			offsetAmount);
}

private RigidBodyControl physicsBoundsControl;
private Geometry physicsGeom;

public void setupPhysicsBounds(final Node worldNode, final PhysicsSpace ps) {

	final float terrainSize = getTotalSize() - 1f;
	final float size = getTotalSize() + 10;
	final float boundWidth = 1f;

	final ColorRGBA boundsColor = new ColorRGBA(0f, 0f, 1f, 0.3f);
	final Vector3f[] dir = new Vector3f[] { Vector3f.UNIT_Z,
			Vector3f.UNIT_Z, Vector3f.UNIT_X, Vector3f.UNIT_X };

	final float[] offsetX = new float[] { terrainSize / 2, terrainSize / 2,
			0, terrainSize };
	final float[] offsetZ = new float[] { 0, terrainSize, terrainSize / 2,
			terrainSize / 2 };

	for (int i = 0; i < 4; i++) {
		final Box q = new Box(size / 2, size / 2, boundWidth / 2);
		physicsGeom = new Geometry("physicsBounds" + i, q);
		physicsGeom.lookAt(dir[i], Vector3f.UNIT_Y);
		physicsGeom.setLocalTranslation(offsetX[i] - 0.5f, size / 2,
				offsetZ[i] - 0.5f);
		physicsGeom.setQueueBucket(RenderQueue.Bucket.Transparent);
		physicsGeom.setShadowMode(RenderQueue.ShadowMode.Off);
		physicsGeom.setCullHint(CullHint.Always);

		// Lighting
		final Material mat = MaterialFactory.LIGHTBLOW
				.getInstance(GameClient.getInstance().getAssetManager());
		mat.setBoolean("UseMaterialColors", true);
		mat.setColor("Diffuse", boundsColor);

		// Unshaded
		// Material mat = TempCache.unshadedMaterial.clone();
		// mat.setColor("Color, boundsColor");

		mat.getAdditionalRenderState().setBlendMode(
				RenderState.BlendMode.Alpha);
		// mat.getAdditionalRenderState().setWireframe(true);

		physicsGeom.setMaterial(mat);

		// Physics
		physicsBoundsControl = new RigidBodyControl(0.0f);
		physicsBoundsControl.setCollisionGroup(COLLISION_TERRAIN);
		physicsBoundsControl.setCollideWithGroups(COLLISION_PLAYERS);
		physicsGeom.addControl(physicsBoundsControl);
		worldNode.attachChild(physicsGeom);
		ps.add(physicsBoundsControl);
	}
}

public void remove(final PhysicsSpace ps) {
	physicsGeom.removeControl(physicsBoundsControl);
	physicsGeom.removeFromParent();
	ps.remove(physicsBoundsControl);
	ps.removeAll(this);
	removeFromParent();
}

}
[/java]

And my usage (note: It contains some non-core references, but nothing affecting this particular part of it)
[java]
public Terrain createSingleTerrain(final CachedMap map,
final MapDefinition mapDef) {
final Material terrainMat = getMapMat(mapDef);
logger.log(Level.SEVERE, "Loading heightMap: {0} ",
map.getHeightMapPath());

	final int patchSize = REGION_SIZE;
	final int quadSize = patchSize * map.getWidth();

	logger.log(Level.SEVERE, "Loading alphaMap: {0}", map.getAlphaMapPath());
	final Terrain terrain = new Terrain("terrain", patchSize + 1,
			quadSize + 1, heightmap.getHeightMap());
	if (map.getAlphaMap(app.getAssetManager()) != null) {
		terrainMat.setTexture("AlphaMap", app.getAssetManager()
				.loadTexture(map.getAlphaMapPath()));
	}

	terrain.setMaterial(terrainMat);
	terrain.setShadowMode(ShadowMode.Receive);
	terrain.setLocalTranslation(new Vector3f(0.5f * quadSize, 0,
			0.5f * quadSize));
	...
}

[/java]

You could directly create a physicrigidbody with a planecollisionshape

<cite>@Empire Phoenix said:</cite> You could directly create a physicrigidbody with a planecollisionshape

How well does PlaneCollisionShape work with high velocities?

I noticed that if an object travels at higher speed than what a frame in the physics evaluation can handle, you can pass through at least thin boxes,
is it the same with planes or are they handled differently?

The reason I chose boxes were that I could set the thickness of them to something like 2 meters, which allows the object to travel at a speed of 60 x 2 m/s or so, without actually passing through the wall.

I might relay you here
http://www.bulletphysics.org/mediawiki-1.5.8/index.php?title=Collision_Shapes

A static plane that is solid to infinity on one side. Several of these can be used to confine a convex space in a manner that completely prevents tunneling to the outside. The plane itself is specified with a normal and distance as is standard in mathematics.

Oh nice to know, must’ve missed that part while I studied the tutorials some time ago.

A couple other solutions I’ve seen in games, are:

  • You have like 10 seconds to get back into the allowed areas, if you go over the boundary (such as in BattleField)
  • Apply a force to push you back into allowed areas (is more smooth, than running into a solid invisible wall), but is open to potential bugs