I'm working on designing a camera mode that will allow me to 'see' from behind a 'player' model. I'm essentially designing this for a space simulation. I want a space ship model to be followed by a camera. Unlike most flight-sim games I want the camera's orientation to be seperate from the orientation of the ship, but the camera will always look 'over' the ship. When the user double-clicks on the screen the ship will change orientation and head in that direction (via a asthetically appealing transition). It will lose a variable amount of speed depending on how sharp it is turning, and then try to catch back up to its previous speed. The ship continues on its course forever, or until it collides with something (like a planet).
I assume the best way to do the camera behind the ship would be to set the offset of the camera to behind the ship. It's mainly the double-clicking to go in a direction I'm worried about. Also, the camera should move independently from the player when right-click dragging.
Here are two images illustrating my idea:
http://www.computergod.org/Frontier/screendesign.jpg
http://www.computergod.org/Frontier/camera.jpg
My question is this:
Which camera mode do you think would be the easiest to modify, or, if you think I should just design one from ground zero, some suggestions on where to start would be nice. I have a general understanding of vector math and trig. If there is already an easy way of doing this, that'd be great too...no point in reinventing the wheel.
Thanks for any help.
Camera style for space ship sim.
Nice idea for a game!
Sounds like your camera would be a bit like the one in my game, which follows a ball around.
I re-implemented the CCameraSceneNode class, and then derived a new camera class from that, based on the FPS camera.
Rather than describe in detail how to do this, I've put the files here:
Camera.zip
To control the camera, I use this code to position the camera and get it to look at a point in front of the player. The camera angle (m_BaseCamAngle) is just incremented directly as the mouse moves:
Hope this helps, it's still a work in progress so maybe I'll do a proper demo sometimes.
Gotta go watch some TV!
Sounds like your camera would be a bit like the one in my game, which follows a ball around.
I re-implemented the CCameraSceneNode class, and then derived a new camera class from that, based on the FPS camera.
Rather than describe in detail how to do this, I've put the files here:
Camera.zip
To control the camera, I use this code to position the camera and get it to look at a point in front of the player. The camera angle (m_BaseCamAngle) is just incremented directly as the mouse moves:
Code: Select all
///////////////////////////////////////////////////////////
//find look at point
const vector3df worldUp(0,1,0);
vector3df angle(m_BaseCamAngle.X, m_BaseCamAngle.Y, 0);
matrix4 mat;
mat.setRotationDegrees(angle);
vector3df fwd(0,0,1);
mat.rotateVect(fwd);
m_pCamera->SetPosition(m_pBall->GetPosition() + fwd * -m_CamDist); //set cam pos
//now set camera look-at point at arbitrary distance in front of ball
vector3df w = worldUp.crossProduct(fwd.crossProduct(worldUp)).normalize(); //vec that intersects lookat vec, on XZ plane
fwd=m_pBall->GetPosition() - m_pCamera->GetPosition(); //vec between cam and ball
f32 cosQ = cos(DegToRad(90.f-m_BaseCamAngle.X + CAM_OFFSET_ANGLE));
f32 h = -fwd.dotProduct(worldUp);
f32 lookatLen = h / cosQ; //length of vector btween cam and lookat point
f32 hsq = h*h;
f32 cossq = cosQ*cosQ;
f32 l1 = fwd.dotProduct(w); //distance from ball to y-axis
f32 l2 = sqrt(hsq/cossq - hsq); //distance from look-at point to y-axis
w *= l2-l1; //distance from ball to look-at point
//Set cam orientation - setTargetPos is jerky, so just rotate cam manually
vector3df lookatpnt = m_pBall->GetPosition() + w;
fwd = lookatpnt - m_pCamera->GetPosition();
angle=fwd.getHorizontalAngle();
m_pCamera->SetRotation(angle);
Gotta go watch some TV!
-
dhenton9000
- Posts: 395
- Joined: Fri Apr 08, 2005 8:46 pm
You may want to consider a physics engine. The behavior you are describing could be achieved, i think, by "attaching" the camera to the ship via a damped spring, which would give you the lag you are looking for.
My guess is you are describing a 'realistic' camera behavior, which sounds to me like physically realistic.
My guess is you are describing a 'realistic' camera behavior, which sounds to me like physically realistic.
Thanks for the reply.
I'm not sure what you mean by lag, exactly. In the camera design I'm talking about, the camera's position is always in a circle around the ship, such that it always looks 'through' the ship. But the orientation of the ship (ie, which direction it is travelling) doesn't effect the direction the camera is facing.
So essentially, I can drag the direction of my camera, then double-click on the screen and the ship will go towards where I double-clicked. But, otherwise, the ship's direction and speed are not affected by the camera.
At this point I still haven't worked out how to catch the 'double-click', but I suspect it has to do with the IEventReciever derived class, which I have working for keyboard input. Nor do I totally have it figured out how to translate that into a target direction for the ship to go in.
Unless, I'm mistaken the physics should only be needed when I impliment running into things...like stations or planets. But, I have never fully used a physics engine, so I may be in the dark here.
I'm not sure what you mean by lag, exactly. In the camera design I'm talking about, the camera's position is always in a circle around the ship, such that it always looks 'through' the ship. But the orientation of the ship (ie, which direction it is travelling) doesn't effect the direction the camera is facing.
So essentially, I can drag the direction of my camera, then double-click on the screen and the ship will go towards where I double-clicked. But, otherwise, the ship's direction and speed are not affected by the camera.
At this point I still haven't worked out how to catch the 'double-click', but I suspect it has to do with the IEventReciever derived class, which I have working for keyboard input. Nor do I totally have it figured out how to translate that into a target direction for the ship to go in.
Unless, I'm mistaken the physics should only be needed when I impliment running into things...like stations or planets. But, I have never fully used a physics engine, so I may be in the dark here.
Unfortunately there is no double click event in Irrlicht, so you would need to modify the engine to implement this.
My code would give you the camera movement you need, and I would guess you can get the target direction from the getRayFromScreenCoordinates() function.
Sorry my code isn't well commented, should have mentioned you can use a value of 20 for m_CamDist and CAM_OFFSET_ANGLE. Increase m_CamDist to move the camera further from the player, change CAM_OFFSET_ANGLE to move the look-at point. m_BaseCamAngle.X and m_BaseCamAngle.Y change the camera pitch and yaw respectively.
My code would give you the camera movement you need, and I would guess you can get the target direction from the getRayFromScreenCoordinates() function.
Sorry my code isn't well commented, should have mentioned you can use a value of 20 for m_CamDist and CAM_OFFSET_ANGLE. Increase m_CamDist to move the camera further from the player, change CAM_OFFSET_ANGLE to move the look-at point. m_BaseCamAngle.X and m_BaseCamAngle.Y change the camera pitch and yaw respectively.