Sign in to follow this  
Convergence

Prevent camera from going 'underground'

Recommended Posts

Since the default camera collision behavior is kind of awkward (camera 'glues' to any surface it bumps into until manually 'released'), I resorted to just try to prevent the camera from going underground, so to speak, with just moving its target upwards as much as the camera would otherwise be underground.

 

http://www.babylonjs-playground.com/#1OWKH4

 

However the camera will start to flickr from going underground in one frame to being corrected in the next frame. More noticeable on lower FPS. How to prevent this?

 

Thanks in advance  :)

Share this post


Link to post
Share on other sites

You could use a raycast each frame from the position of the camera of 1 frame ago to the position of the camera at the current frame. If something hits in that raycast, then you should set the camera position to the hit world position.

 

Or have the raycast from the current camera position to the mesh you're looking at.

Share this post


Link to post
Share on other sites

Since the default camera collision behavior is kind of awkward (camera 'glues' to any surface it bumps into until manually 'released')

Just wondering - What do you mean by that? How would you expect the collision system to work?

Share this post


Link to post
Share on other sites

You could use a raycast each frame from the position of the camera of 1 frame ago to the position of the camera at the current frame. If something hits in that raycast, then you should set the camera position to the hit world position.

 

Or have the raycast from the current camera position to the mesh you're looking at.

with an arcrotate camera the position cannot be modified directly, only alpha and beta I guess.

 

 

In my project, each frame I raycast from the camera target back to the camera, and zoom the camera in if an obstruction is met. But this is with a freely moving camera - doing the same thing with the ArcRotateCamera would take some trig, I guess.

I'll try this, thanks :) Though I'm not a big fan of Raycast for its speed. 

 

 

Oh, my bad. 

I tryed a long time ago something like. But I used ground.getHeightAtCoordinates, and this is not too fast.

 

http://www.babylonjs-playground.com/#225AVV

Maybe with raycast it's faster and more precisely. I'll try too

It looks like  ground.getHeightAtCoordinates uses a raycast as well, (and I believe that's why its slow).

 

Just wondering - What do you mean by that? How would you expect the collision system to work?

If an arcrotate camera collides with something, it stops (good), but when the cameraTarget starts to move while the camera is still 'glued' to its collision surface, the camera won't slide along with it. According to the docs:

 

 

 

The ArcRotateCamera can also check collisions but instead of sliding along obstacles, this camera won't move when a collision appends.

Share this post


Link to post
Share on other sites

I'll try this, thanks :) Though I'm not a big fan of Raycast for its speed. 

 

Well, in my case I'm doing it with voxels, so raycasts are very fast and there's no height map anyway. But even with a simple height map there can be a hill between the camera and the camera target, and if you want to catch those cases you'll need something - a raycast, or sampling the height map at multiple points, etc.

 

In general I'd assume that using BJS's built-in raycast will be the slowest option, but it may still be fast enough to not bother worrying about.

Share this post


Link to post
Share on other sites

Well, in my case I'm doing it with voxels, so raycasts are very fast and there's no height map anyway. But even with a simple height map there can be a hill between the camera and the camera target, and if you want to catch those cases you'll need something - a raycast, or sampling the height map at multiple points, etc.

 

In general I'd assume that using BJS's built-in raycast will be the slowest option, but it may still be fast enough to not bother worrying about.

Since its only one pick per frame, its acceptable, though it looks like the single pickWIthRay call already makes it in the top 5 most time consuming function calls in the profiler..

 

my solution using the pickWithRay method and ArcRotateCam :

if (obstruction = scene.pickWithRay(cameraRay, function(mesh) { return mesh.checkCollisions; })) {  if (obstruction.hit) {    camera.radius = BABYLON.Vector3.Distance(obstruction.pickedPoint, cameraTarget.position);  }}

Share this post


Link to post
Share on other sites

Yep, that's basically what I do, plus I add in a small offset to avoid partly seeing through the ground when the camera's near plane intersects it. I tried a couple of ways of doing this and it got pretty hairy; I think what I settled on is: whenever the raycast hits an obstruction, I shift the camera by a small amount (0.05 or something) along the normal of the raycast collision.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.