Hello,
I am looking for a simple implementation of a overflight (or flyover) functionality. Basically I want to use arrow keys to navigate camera (movement, yaw and maybe also pitch), ideally like the planes do (but like I said, roll is not necessary).
I can implement this on my own, but it doesnt make sense to reinvent a wheel and I am sure it can save some time not only for me but for other codes and it is also better to have something what is already nicely tweaked.
If there is similar thread, I am very sorry for duplication. I was trying the search function but nothing came up.
Thank you!
Overflight functionality
-
- Halfling
- Posts: 51
- Joined: Tue Nov 27, 2018 1:41 am
- x 5
Re: Overflight functionality
Planes pitch up and down. To turn their wing "flaps" move up and down rolling the plane. For a mouse I translate this into pitch for up/down and roll for left/right. W can increase speed until engine is maxed out and S can reduce speed until a stall incurs. Yaw is unrealistic for a plane. So to turn right 90 degrees and continue straight in my flight simulator you move the mouse right and up (pitching and rolling you at the same time) until you have reached your target angle and then move the mouse left until you have rolled upright.
Without roll it sounds like you just want a flying first person flying camera. There are a lot of examples in the Ogre samples for this. WASD movement, mouse pitch/yaw and no ray keeping you pinned down to the ground. Shift is used to move faster. You can adapt the mouse input to keyboard as you said you wanted to use the arrow keys. Modify the keyReleased method to ignore letting go of WASD keys so you are always moving will give your plane a bit more realism than stopping in midair.
Without roll it sounds like you just want a flying first person flying camera. There are a lot of examples in the Ogre samples for this. WASD movement, mouse pitch/yaw and no ray keeping you pinned down to the ground. Shift is used to move faster. You can adapt the mouse input to keyboard as you said you wanted to use the arrow keys. Modify the keyReleased method to ignore letting go of WASD keys so you are always moving will give your plane a bit more realism than stopping in midair.
-
- Gnome
- Posts: 368
- Joined: Tue Jan 06, 2009 1:12 pm
- x 43
Re: Overflight functionality
Hello saintnick,
thank you for your reply.
I took code from one of the samples (it is from MOGRE but I think easy to pick up for C++ developers as well). All is going fine, the only "issue" is that the camera is always going the way it is looking at. It means that if I want to look at terrain from top, I always go directly down. What would be the easiest way to modify this so I really overfly the terrain without going down? In summary - bird is always flying forward but looking down.
thank you for your reply.
I took code from one of the samples (it is from MOGRE but I think easy to pick up for C++ developers as well). All is going fine, the only "issue" is that the camera is always going the way it is looking at. It means that if I want to look at terrain from top, I always go directly down. What would be the easiest way to modify this so I really overfly the terrain without going down? In summary - bird is always flying forward but looking down.
Code: Select all
private void FlyOverFrameRendering(FrameEvent evt)
{
float moveScale = 3 * evt.timeSinceLastFrame;
Degree rotateSpeed = 30;
Degree rotScale = rotateSpeed * evt.timeSinceLastFrame;
Mogre.Vector3 translateVector = Mogre.Vector3.ZERO;
Degree scaleRotate = rotateSpeed * evt.timeSinceLastFrame;
Mogre.Vector3 camVelocity = Mogre.Vector3.ZERO;
keyboard.Capture();
if (keyboard.IsKeyDown(MOIS.KeyCode.KC_A))
{
translateVector.x = -moveScale;
}
if (keyboard.IsKeyDown(MOIS.KeyCode.KC_D))
{
translateVector.x = moveScale;
}
if (keyboard.IsKeyDown(MOIS.KeyCode.KC_W))
{
translateVector.z = -moveScale;
}
if (keyboard.IsKeyDown(MOIS.KeyCode.KC_S))
{
translateVector.z = moveScale;
}
if (keyboard.IsKeyDown(MOIS.KeyCode.KC_LEFT))
{
camera.Yaw(scaleRotate);
}
if (keyboard.IsKeyDown(MOIS.KeyCode.KC_RIGHT))
{
camera.Yaw(-scaleRotate);
}
if (keyboard.IsKeyDown(MOIS.KeyCode.KC_UP))
{
camera.Pitch(scaleRotate);
}
if (keyboard.IsKeyDown(MOIS.KeyCode.KC_DOWN))
{
camera.Pitch(-scaleRotate);
}
// toggle rendering mode
if (keyboard.IsKeyDown(MOIS.KeyCode.KC_R))
{
if (camera.PolygonMode == PolygonMode.PM_POINTS)
{
camera.PolygonMode = PolygonMode.PM_SOLID;
}
else if (camera.PolygonMode == PolygonMode.PM_SOLID)
{
camera.PolygonMode = PolygonMode.PM_WIREFRAME;
}
else
{
camera.PolygonMode = PolygonMode.PM_POINTS;
}
}
mouse.Capture();
MOIS.MouseState_NativePtr mouseState = mouse.MouseState;
if (!mouseState.ButtonDown(MOIS.MouseButtonID.MB_Left))
{
Degree cameraYaw = -mouseState.X.rel * .13f;
Degree cameraPitch = -mouseState.Y.rel * .13f;
camera.Yaw(cameraYaw);
camera.Pitch(cameraPitch);
}
else
{
translateVector.x += mouseState.X.rel * 0.13f;
}
if (!translateVector.IsZeroLength)
{
// move the camera based on the accumulated movement vector
camera.MoveRelative(translateVector);
}
}
-
- Halfling
- Posts: 51
- Joined: Tue Nov 27, 2018 1:41 am
- x 5
Re: Overflight functionality
Create a ray from the camera position to the terrain then check for an intersection. Then simply set the y position of the camera to the intersection plus however high you want to fly over.
Example: ( note the 5000 value for the y position of the ray. This should be higher than the highest point of your terrain to get an intersection.)
This example uses the volume component for terrains. mVolumeRoot is the terrain volume. After casting the ray you check if intersects is true, if so you set the position of the camera node to itself plus your overflight variable.
You can also add keyboard input for - and + to change OVERFLIGHT variable so you can change the height of which you stay above the terrain.
Keep in mind that this isn't a natural behavior. Planes and birds don't fly higher or lower when the terrain directly below them is a small hill or dip.
Example: ( note the 5000 value for the y position of the ray. This should be higher than the highest point of your terrain to get an intersection.)
Code: Select all
Ogre::Real OVERFLIGHT = 150; // how far up you are flying
Ogre::Real y = 5000;
Ogre::Ray mRay(
Ogre::Vector3(mCameraNode->getPosition().x, y, mCameraNode->getPosition().z),
Ogre::Vector3::NEGATIVE_UNIT_Y);
Ogre::Vector3 intersection;
Ogre::Real scale = mVolumeRoot->getChunkParameters()->scale;
bool intersects = mVolumeRoot->getChunkParameters()->src->getFirstRayIntersection(mRay, intersection, scale);
if (intersects)
{
intersection *= scale; // As it is in volume space.
Vector3 newCamPosition = mCameraNode->getPosition();
newCamPosition.y = intersection.y + OVERFLIGHT;
mCameraNode->setPosition(newCamPosition);
}
{
You can also add keyboard input for - and + to change OVERFLIGHT variable so you can change the height of which you stay above the terrain.
Keep in mind that this isn't a natural behavior. Planes and birds don't fly higher or lower when the terrain directly below them is a small hill or dip.
-
- Gnome
- Posts: 368
- Joined: Tue Jan 06, 2009 1:12 pm
- x 43
Re: Overflight functionality
Thank you for your reply saintnick.
I will definitely try that and reply how it went, I was just dragged into something else temporarily. I should come back to this soon.
I will definitely try that and reply how it went, I was just dragged into something else temporarily. I should come back to this soon.
-
- Gnome
- Posts: 368
- Joined: Tue Jan 06, 2009 1:12 pm
- x 43
Re: Overflight functionality
I was trying to make a progress in this but the technique you are suggesting is not what I am trying to achieve.
The best approach would be this:
It would work exactly the same as the code I posted before but once user presses left, right, up or down keys, it will not only yaw or pitch the camera but it will also store this change to an external variable. Once player presses WASD keys again, it will move the camera in the specific direction but it will also use the stored variable to calculate the difference between current camera direction and the "movement" direction.
An example:
Let's say we have a flat terrain (plain) and I set the initial movement direction by mouse to be parallel to terrain (aka I am looking horizontally). When I press W now, it moves further parallely to terrain. When I press "arrow down" key, it pitches the camera and saves to variable how much it pitched the camera. Let's say I will pitch it 90 degrees (aka I am now looking direction to terrain below the camera). Now I press W again - I am still moving the camera horizontally (parallely to terrain) but already looking to the terrain below.
I am sure this is not that difficult, but can someone help me to understand how to save this "pitch" and "yaw" changes and apply them later?
Thank you!
The best approach would be this:
It would work exactly the same as the code I posted before but once user presses left, right, up or down keys, it will not only yaw or pitch the camera but it will also store this change to an external variable. Once player presses WASD keys again, it will move the camera in the specific direction but it will also use the stored variable to calculate the difference between current camera direction and the "movement" direction.
An example:
Let's say we have a flat terrain (plain) and I set the initial movement direction by mouse to be parallel to terrain (aka I am looking horizontally). When I press W now, it moves further parallely to terrain. When I press "arrow down" key, it pitches the camera and saves to variable how much it pitched the camera. Let's say I will pitch it 90 degrees (aka I am now looking direction to terrain below the camera). Now I press W again - I am still moving the camera horizontally (parallely to terrain) but already looking to the terrain below.
I am sure this is not that difficult, but can someone help me to understand how to save this "pitch" and "yaw" changes and apply them later?
Thank you!
-
- Halfling
- Posts: 51
- Joined: Tue Nov 27, 2018 1:41 am
- x 5
Re: Overflight functionality
Storing last camera pitch and yaw from mouse:
Storing last camera rotations with keyboard:
You are using a speed times frames per second to rotate your camera. I don't understand how to store these changes. However I am asking my self why you want these changes in the first place.
So instead of translating your camera with respect to orientation you would translate it only considering movement direction. This will achieve a bird flying straight and looking down. (or where ever you rotate the camera to look)
You get the separation of movement direction and orientation by using scene nodes.
Apply your rotations to mCameraNode. Apply your translateVector to mCameraMoveNode. I have not tested this but it should work.
edit:
I had it in reverse.
Code: Select all
lastCameraPitch = cameraPitch;
lastCameraYaw = cameraYaw;
You are using a speed times frames per second to rotate your camera. I don't understand how to store these changes. However I am asking my self why you want these changes in the first place.
Then I re-read this:Once player presses WASD keys again, it will move the camera in the specific direction but it will also use the stored variable to calculate the difference between current camera direction and the "movement" direction.
I missed this earlier.What would be the easiest way to modify this so I really overfly the terrain without going down? In summary - bird is always flying forward but looking down.
So instead of translating your camera with respect to orientation you would translate it only considering movement direction. This will achieve a bird flying straight and looking down. (or where ever you rotate the camera to look)
You get the separation of movement direction and orientation by using scene nodes.
Code: Select all
Ogre::SceneNode *mCameraNode = mScnMgr->getRootSceneNode()->createChildSceneNode();
Ogre::SceneNode *mCameraMoveNode = mCameraNode->createChildSceneNode();
mCameraMoveNode->attachObject(mCamera);
edit:
I had it in reverse.
Code: Select all
// in setup
Ogre::SceneNode *mCameraNode = mScnMgr->getRootSceneNode()->createChildSceneNode();
Ogre::SceneNode *mCameraRotationNode = mCameraNode->createChildSceneNode();
mCameraRotationNode->attachObject(mCamera);
// every frame update
mCameraRotationNode->pitch(cameraPitch);
mCameraRotationNode->yaw(cameraYaw);
mCameraNode->translate(translateVector);