Create a separate scene manager for the wielded tool. This fixes the glitchyness in large map coordinates and some depth buffer problems. (The tool doesn't bob anymore when walking, this will be fixed later.) Fix MSVC build (thanks to dannydark).

This commit is contained in:
Kahrl 2011-09-21 01:42:52 +02:00
parent 6599002149
commit 36af9bb027
3 changed files with 49 additions and 13 deletions

@ -31,7 +31,10 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control):
m_playernode(NULL), m_playernode(NULL),
m_headnode(NULL), m_headnode(NULL),
m_cameranode(NULL), m_cameranode(NULL),
m_wieldmgr(NULL),
m_wieldnode(NULL), m_wieldnode(NULL),
m_draw_control(draw_control), m_draw_control(draw_control),
m_viewing_range_min(5.0), m_viewing_range_min(5.0),
m_viewing_range_max(5.0), m_viewing_range_max(5.0),
@ -66,13 +69,20 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control):
m_headnode = smgr->addEmptySceneNode(m_playernode); m_headnode = smgr->addEmptySceneNode(m_playernode);
m_cameranode = smgr->addCameraSceneNode(smgr->getRootSceneNode()); m_cameranode = smgr->addCameraSceneNode(smgr->getRootSceneNode());
m_cameranode->bindTargetAndRotation(true); m_cameranode->bindTargetAndRotation(true);
m_wieldnode = new ExtrudedSpriteSceneNode(m_headnode, smgr);
// This needs to be in its own scene manager. It is drawn after
// all other 3D scene nodes and before the GUI.
m_wieldmgr = smgr->createNewSceneManager();
m_wieldmgr->addCameraSceneNode();
m_wieldnode = new ExtrudedSpriteSceneNode(m_wieldmgr->getRootSceneNode(), m_wieldmgr);
updateSettings(); updateSettings();
} }
Camera::~Camera() Camera::~Camera()
{ {
m_wieldmgr->drop();
m_wieldnode->drop();
} }
bool Camera::successfullyCreated(std::wstring& error_message) bool Camera::successfullyCreated(std::wstring& error_message)
@ -92,6 +102,11 @@ bool Camera::successfullyCreated(std::wstring& error_message)
error_message = L"Failed to create the camera scene node"; error_message = L"Failed to create the camera scene node";
return false; return false;
} }
if (m_wieldmgr == NULL)
{
error_message = L"Failed to create the wielded item scene manager";
return false;
}
if (m_wieldnode == NULL) if (m_wieldnode == NULL)
{ {
error_message = L"Failed to create the wielded item scene node"; error_message = L"Failed to create the wielded item scene node";
@ -215,14 +230,14 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize)
m_cameranode->setFarValue(m_viewing_range_max * BS * 10); m_cameranode->setFarValue(m_viewing_range_max * BS * 10);
// Position the wielded item // Position the wielded item
v3f wield_position = v3f(1.3, -1.1, 2); v3f wield_position = v3f(45, -35, 65);
v3f wield_rotation = v3f(90, -90, -90); v3f wield_rotation = v3f(90, -90, -90);
if (m_digging_button != -1) if (m_digging_button != -1)
{ {
f32 digfrac = m_digging_anim; f32 digfrac = m_digging_anim;
wield_position.X -= sin(pow(digfrac, 0.8) * PI); wield_position.X -= 30 * sin(pow(digfrac, 0.8f) * PI);
wield_position.Y += 0.5 * sin(digfrac * 2 * PI); wield_position.Y += 15 * sin(digfrac * 2 * PI);
wield_position.Z += 0.2 * digfrac; wield_position.Z += 5 * digfrac;
// Euler angles are PURE EVIL, so why not use quaternions? // Euler angles are PURE EVIL, so why not use quaternions?
core::quaternion quat_begin(wield_rotation * core::DEGTORAD); core::quaternion quat_begin(wield_rotation * core::DEGTORAD);
@ -403,7 +418,7 @@ void Camera::wield(const InventoryItem* item)
if (content_features(content).solidness || content_features(content).visual_solidness) if (content_features(content).solidness || content_features(content).visual_solidness)
{ {
m_wieldnode->setCube(content_features(content).tiles); m_wieldnode->setCube(content_features(content).tiles);
m_wieldnode->setScale(v3f(0.9)); m_wieldnode->setScale(v3f(30));
isCube = true; isCube = true;
} }
} }
@ -412,7 +427,7 @@ void Camera::wield(const InventoryItem* item)
if (!isCube) if (!isCube)
{ {
m_wieldnode->setSprite(item->getImageRaw()); m_wieldnode->setSprite(item->getImageRaw());
m_wieldnode->setScale(v3f(1.2)); m_wieldnode->setScale(v3f(40));
} }
m_wieldnode->setVisible(true); m_wieldnode->setVisible(true);
@ -430,6 +445,18 @@ void Camera::setDigging(s32 button)
m_digging_button = button; m_digging_button = button;
} }
void Camera::drawWieldedTool()
{
m_wieldmgr->getVideoDriver()->clearZBuffer();
scene::ICameraSceneNode* cam = m_wieldmgr->getActiveCamera();
cam->setAspectRatio(m_cameranode->getAspectRatio());
cam->setFOV(m_cameranode->getFOV());
cam->setNearValue(0.1);
cam->setFarValue(100);
m_wieldmgr->drawAll();
}
ExtrudedSpriteSceneNode::ExtrudedSpriteSceneNode( ExtrudedSpriteSceneNode::ExtrudedSpriteSceneNode(
scene::ISceneNode* parent, scene::ISceneNode* parent,

@ -63,12 +63,6 @@ public:
return m_cameranode; return m_cameranode;
} }
// Get wielded item scene node.
inline ExtrudedSpriteSceneNode* getWieldNode() const
{
return m_wieldnode;
}
// Get the camera position (in absolute scene coordinates). // Get the camera position (in absolute scene coordinates).
// This has view bobbing applied. // This has view bobbing applied.
inline v3f getPosition() const inline v3f getPosition() const
@ -124,12 +118,19 @@ public:
// Pass 0 for left click, 1 for right click // Pass 0 for left click, 1 for right click
void setDigging(s32 button); void setDigging(s32 button);
// Draw the wielded tool.
// This has to happen *after* the main scene is drawn.
// Warning: This clears the Z buffer.
void drawWieldedTool();
private: private:
// Scene manager and nodes // Scene manager and nodes
scene::ISceneManager* m_smgr; scene::ISceneManager* m_smgr;
scene::ISceneNode* m_playernode; scene::ISceneNode* m_playernode;
scene::ISceneNode* m_headnode; scene::ISceneNode* m_headnode;
scene::ICameraSceneNode* m_cameranode; scene::ICameraSceneNode* m_cameranode;
scene::ISceneManager* m_wieldmgr;
ExtrudedSpriteSceneNode* m_wieldnode; ExtrudedSpriteSceneNode* m_wieldnode;
// draw control // draw control

@ -2161,6 +2161,14 @@ void the_game(
driver->draw3DBox(*i, video::SColor(255,0,0,0)); driver->draw3DBox(*i, video::SColor(255,0,0,0));
} }
/*
Wielded tool
*/
{
// Warning: This clears the Z buffer.
camera.drawWieldedTool();
}
/* /*
Post effects Post effects
*/ */