Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control):
m_smgr(smgr),
m_playernode(NULL),
+ m_headnode(NULL),
m_cameranode(NULL),
m_draw_control(draw_control),
m_viewing_range_min(5.0),
// note: making the camera node a child of the player node
// would lead to unexpected behaviour, so we don't do that.
m_playernode = smgr->addEmptySceneNode(smgr->getRootSceneNode());
+ m_headnode = smgr->addEmptySceneNode(m_playernode);
m_cameranode = smgr->addCameraSceneNode(smgr->getRootSceneNode());
m_cameranode->bindTargetAndRotation(true);
{
}
+bool Camera::successfullyCreated(std::wstring& error_message)
+{
+ if (m_playernode == NULL)
+ {
+ error_message = L"Failed to create the player scene node";
+ return false;
+ }
+ if (m_headnode == NULL)
+ {
+ error_message = L"Failed to create the head scene node";
+ return false;
+ }
+ if (m_cameranode == NULL)
+ {
+ error_message = L"Failed to create the camera scene node";
+ return false;
+ }
+ return true;
+}
+
void Camera::step(f32 dtime)
{
if (m_view_bobbing_state != 0)
void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize)
{
- if (m_playernode == NULL || m_cameranode == NULL)
- return;
-
// Set player node transformation
m_playernode->setPosition(player->getPosition());
m_playernode->setRotation(v3f(0, -1 * player->getYaw(), 0));
m_playernode->updateAbsolutePosition();
+ // Set head node transformation
+ v3f eye_offset = player->getEyePosition() - player->getPosition();
+ m_headnode->setPosition(eye_offset);
+ m_headnode->setRotation(v3f(player->getPitch(), 0, 0));
+
// Compute relative camera position and target
- v3f relative_cam_pos = player->getEyePosition() - player->getPosition();
+ v3f relative_cam_pos = eye_offset;
v3f relative_cam_target = v3f(0,0,1);
relative_cam_target.rotateYZBy(player->getPitch());
relative_cam_target += relative_cam_pos;
m_cameranode->setPosition(m_camera_position);
// *100.0 helps in large map coordinates
m_cameranode->setTarget(m_camera_position + 100.0 * m_camera_direction);
-
// FOV and and aspect ratio
m_aspect = (f32)screensize.X / (f32) screensize.Y;
m_fov_x = 2 * atan(0.5 * m_aspect * tan(m_fov_y));
// Get player scene node.
// This node is positioned at the player's torso (without any view bobbing),
// as given by Player::m_position. Yaw is applied but not pitch.
- // Things like wielded tools should be positioned relative to this node.
inline scene::ISceneNode* getPlayerNode() const
{
return m_playernode;
}
+ // Get head scene node.
+ // It has the eye transformation and pitch applied,
+ // but no view bobbing.
+ inline scene::ISceneNode* getHeadNode() const
+ {
+ return m_headnode;
+ }
+
// Get camera scene node.
- // It has the eye transformation and view bobbing applied.
+ // It has the eye transformation, pitch and view bobbing applied.
inline scene::ICameraSceneNode* getCameraNode() const
{
return m_cameranode;
return MYMAX(m_fov_x, m_fov_y);
}
+ // Checks if the constructor was able to create the scene nodes
+ bool successfullyCreated(std::wstring& error_message);
+
// Step the camera: updates the viewing range and view bobbing.
void step(f32 dtime);
// Scene manager and nodes
scene::ISceneManager* m_smgr;
scene::ISceneNode* m_playernode;
+ scene::ISceneNode* m_headnode;
scene::ICameraSceneNode* m_cameranode;
// draw control
Create the camera node
*/
Camera camera(smgr, draw_control);
- if (camera.getPlayerNode() == NULL)
- {
- error_message = L"Failed to create the player node";
+ if (!camera.successfullyCreated(error_message))
return;
- }
- if (camera.getCameraNode() == NULL)
- {
- error_message = L"Failed to create the camera node";
- return;
- }
f32 camera_yaw = 0; // "right/left"
f32 camera_pitch = 0; // "up/down"
mesh->addMeshBuffer(buf);
buf->drop();
- tool_wield = smgr->addMeshSceneNode(mesh, camera.getCameraNode());
+ tool_wield = smgr->addMeshSceneNode(mesh, camera.getHeadNode());
mesh->drop();
}
tool_wield->setVisible(false);