How do you prevent cameras from crossing terrain

What’s a good way to keep the camera from going through terrain

I need advice and help

make camera use physics or ray in physics to determine where is “max distance from character”

1 Like

Good advice

any suggestions for what method to use (on a spatial or node) to then prevent the movement when you detect the collision with a ray?

I’ve seen setWalkDirection()–I’m not sure how to set that up on a model without the model being a charactercontrol or without it being physics enabled

Any other suggestions for what method to use to stop the model from moving?

but setWalkDirection is for Character physics, not Camera. It just move RigidBody per frame based on this direction, thats all it do.

Camera could use for example GhostControl/RigidBody for itself (to setup some margin from elements)
while Ray in physics should teleport GhostControl/RigidBody to “maximum distance” detected.

Can also use just Ray (its not accurate so much then, but its fast) to determine distance of camera to not cross terrain/etc. Its fine for terrain but if there would be objects with crazy mesh, it might cause little issues.

Can only just use GhostControl/RigidBody with Cone Collision Body.(and restrict its movement to some axis line) So when it contast with terrain/etc, it will just move closer to character

There are a lot of solutions.

1 Like

Yeah I didn’t mean for camera, specifically – didn’t mean to hijack you were just discussing rays so I saw an opportunity. I am trying to go after Idea2 hehe

I’ll mess around more and then make a separate topic on it if needed. Thanks for the reply :melting_face:

1 Like

Sometimes you can use a long capsule ghost aligned with one end at the head-pivot and the other end at the maximum camera distance… then use any intersection with the ghost to decide how close/far to render the camera. (Or to temporarily go back to first person.) It’s like the Ray idea but a little better because you can give it some thickness (doesn’t take much).

I did something similar with the unreleased second Mythruna engine and I will end up doing similar for this recent third one.

Best to add some interpolation from camera location to desired location. Really fast interpolation for getting out of the way of a contact and slower interpolation for zooming back out again.


Ok I will add this to my list of ideas to monkey around with … Thank you!

1 Like

ray.setLimit (10f)
I set the length to 10F and collision detection can detect distances greater than 10F

碰撞结果(collision results):2
序号(serial number):0, 距离(distance):12.60, 物体名称(Collision object name):floor, 交点(collision point):(6.2831354, -1.9000006, -1.4240495), 交点法线:(0.0, -1.0, 0.0)
序号(serial number):1, 距离(distance):12.95, 物体名称(Collision object name):floor, 交点(collision point):(5.9899693, -1.7000003, -1.4513258), 交点法线:(-0.0, 1.0, 0.0)
最近点(Near point):(6.2831354, -1.9000006, -1.4240495), 最远点(Far point):(5.9899693, -1.7000003, -1.4513258)

Why is a distance greater than 10 detected?

Using a physics ghost object is a neat idea. Thanks for mentioning it!

For avoiding line-of-sight obstructions, I’ve found that rapid changes to the camera distance are disorienting; I prefer to change the camera’s near clipping plane instead.


This can sometimes create its own artifacts… like clipping things strangely that just happen to be nearby. It’s a neat trick, though.

I guess I’m used to the 90% of third-person behind-head/over-shoulder games that slide the camera around to keep the player in view. As long as the tweening is nice, it doesn’t even make me sick.

I find zooming in quickly to be less jarring than zooming out quickly. (Even for sniper-scope style stuff I find this to be the case.) Which is fortunate in this case because zooming in to move out of the way is where being quick is useful. For zooming out again, I do it pretty slow (walking speed)… which also helps keep from jittering around a lot for bump walls.

1 Like

The limit is an optimization so that the collision routines can eliminate objects that are too far to matter. However, there is the chance that an object is close enough (bounding shape) that it is within the distance but then the actual collision is still farther than the limit. Since jMonkeyEngine did the calculation is does not throw this information away.

If you strictly want to limit the results based on distance then add an if statement.
if( distance > 10 ) skip it


If the terrain is represented as a physics rigid body, you can prevent cameras from penetrating it by attaching each camera to a physics object.

For instance, some of the terrain examples in jme3-examples attach the camera to a capsule-shaped CharacterControl … including TerrainGridTileLoaderTest and TerrainGridSerializationTest.

Since Bullet’s character dynamics are … peculiar, I prefer to attach each camera to a sphere-shaped dynamic rigid body. I recently published DynamicCamera, which is a reusable AppState using this approach. It’s included in version 0.5.0 of the Garrett Library.


This is a very good suggestion and hint.

1 Like
警告: Failed to set root path Connection timed out: connect
	at java.base/ Method)
	at java.base/
	at java.base/
	at java.base/
	at java.base/
	at java.base/
	at java.base/
	at java.base/
	at java.base/
	at java.base/<init>(
	at java.base/
	at java.base/
	at java.base/
	at java.base/
	at java.base/
	at java.base/
	at com.jme3.asset.plugins.HttpZipLocator.readData(
	at com.jme3.asset.plugins.HttpZipLocator.readEndHeader(
	at com.jme3.asset.plugins.HttpZipLocator.load(
	at com.jme3.asset.plugins.HttpZipLocator.setRootPath(
	at com.jme3.asset.ImplHandler$ImplThreadLocal.initialValue(
	at java.base/java.lang.ThreadLocal.setInitialValue(
	at java.base/java.lang.ThreadLocal.get(
	at com.jme3.asset.ImplHandler.tryLocate(
	at com.jme3.asset.DesktopAssetManager.loadAsset(
	at com.jme3.asset.DesktopAssetManager.loadModel(
	at com.jme3.asset.DesktopAssetManager.loadModel(
	at com.jme3.terrain.geomipmap.grid.AssetTileLoader.getTerrainQuadAt(
	at com.jme3.terrain.geomipmap.TerrainGrid$
	at java.base/java.util.concurrent.Executors$
	at java.base/
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(
	at java.base/java.util.concurrent.ThreadPoolExecutor$
	at java.base/

I can’t seem to access this file properly

I used the second option you mentioned
My screen flickered
I don’t know what the problem is
But I found a word “interpolation”
I don’t know what interpolation is
What method is used to implement interpolation in JME? :thinking:

Found on Github

Google mothballed “” many years ago. You must be running a very old version of jme3-examples, because that URL was removed from the JMonkeyEngine codebase in 2016.

1 Like

Thank you for your reply.
I found the file on GitHub.
The Discord group Ali-rs gave me a hint :smile:


Looks like TerrainGridSerializationTest and TerrainGridTileLoaderTest still points to old URL:

However TerrainGridAlphaMapTest points to a valid one:

1 Like