Commit 06ad4408 authored by Rogerborg's avatar Rogerborg

Reducing the optional camera binding to a boolean that binds both ways...

Reducing the optional camera binding to a boolean that binds both ways (rotation to target and vice versa).  Thanks to Dorth for suggesting this, which sorts the FPS camera out properly.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@1750 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 55a8f707
...@@ -58,9 +58,18 @@ namespace scene ...@@ -58,9 +58,18 @@ namespace scene
virtual bool OnEvent(const SEvent& event) = 0; virtual bool OnEvent(const SEvent& event) = 0;
//! Sets the look at target of the camera //! Sets the look at target of the camera
/** \param pos: Look at target of the camera. */ /** If the camera's target and rotation are bound ( @see bindTargetAndRotation() )
then calling this will also change the camera's scene node rotation to match the target.
\param pos: Look at target of the camera. */
virtual void setTarget(const core::vector3df& pos) = 0; virtual void setTarget(const core::vector3df& pos) = 0;
//! Sets the rotation of the node.
/** This only modifies the relative rotation of the node.
/** If the camera's target and rotation are bound ( @see bindTargetAndRotation() )
then calling this will also change the camera's target to match the rotation.
\param rotation New rotation of the node in degrees. */
virtual void setRotation(const core::vector3df& rotation) = 0;
//! Gets the current look at target of the camera //! Gets the current look at target of the camera
/** \return Returns the current look at target of the camera */ /** \return Returns the current look at target of the camera */
virtual const core::vector3df& getTarget() const = 0; virtual const core::vector3df& getTarget() const = 0;
...@@ -125,27 +134,17 @@ namespace scene ...@@ -125,27 +134,17 @@ namespace scene
return IsOrthogonal; return IsOrthogonal;
} }
//! Determines how the camera's target and its scene node rotation are bound together. //! Binds the camera scene node's rotation to its target position and vice vera, or unbinds them.
typedef enum _TargetAndRotationBinding /** When bound, calling setRotation() will update the camera's target position to be along
{ its +Z axis, and likewise calling setTarget() will update its rotation so that its +Z axis
//! The target and scene node rotation are independent. will point at the target point. FPS camera use this binding by default; other cameras do not.
/** This is the default for most cameras. */ \param binding true to bind the camera's scene node rotation and targetting, false to unbind them.
TARGET_AND_ROTATION_INDEPENDENT = 0x10000, @see getTargetAndRotationBinding() */
virtual void bindTargetAndRotation(bool bound) = 0;
//! The scene node rotation will be updated so that +Z points at the target location.
/** This is the default for FPS camera */ //! Queries if the camera scene node's rotation and its target position are bound together.
ROTATION_FOLLOWS_TARGET, /** @see bindTargetAndRotation() */
virtual bool getTargetAndRotationBinding(void) const = 0;
//! The target position will be updated to be along the node's +Z axis
TARGET_FOLLOWS_ROTATION
} TargetAndRotationBinding;
//! Set the binding between the camera's rotation adn target.
virtual void setTargetAndRotationBinding(TargetAndRotationBinding binding) = 0;
//! Gets the binding between the camera's rotation and target.
virtual TargetAndRotationBinding getTargetAndRotationBinding(void) const = 0;
protected: protected:
......
...@@ -19,7 +19,7 @@ CCameraSceneNode::CCameraSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 i ...@@ -19,7 +19,7 @@ CCameraSceneNode::CCameraSceneNode(ISceneNode* parent, ISceneManager* mgr, s32 i
: ICameraSceneNode(parent, mgr, id, position, core::vector3df(0.0f, 0.0f, 0.0f), : ICameraSceneNode(parent, mgr, id, position, core::vector3df(0.0f, 0.0f, 0.0f),
core::vector3df(1.0f, 1.0f, 1.0f)), core::vector3df(1.0f, 1.0f, 1.0f)),
Target(lookat), UpVector(0.0f, 1.0f, 0.0f), ZNear(1.0f), ZFar(3000.0f), Target(lookat), UpVector(0.0f, 1.0f, 0.0f), ZNear(1.0f), ZFar(3000.0f),
InputReceiverEnabled(true) InputReceiverEnabled(true), TargetAndRotationAreBound(false)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("CCameraSceneNode"); setDebugName("CCameraSceneNode");
...@@ -110,6 +110,26 @@ bool CCameraSceneNode::OnEvent(const SEvent& event) ...@@ -110,6 +110,26 @@ bool CCameraSceneNode::OnEvent(const SEvent& event)
void CCameraSceneNode::setTarget(const core::vector3df& pos) void CCameraSceneNode::setTarget(const core::vector3df& pos)
{ {
Target = pos; Target = pos;
if(TargetAndRotationAreBound)
{
const core::vector3df toTarget = Target - getAbsolutePosition();
ISceneNode::setRotation(toTarget.getHorizontalAngle());
}
}
//! Sets the rotation of the node.
/** This only modifies the relative rotation of the node.
/** If the camera's target and rotation are bound ( @see bindTargetAndRotation() )
then calling this will also change the camera's target to match the rotation.
\param rotation New rotation of the node in degrees. */
void CCameraSceneNode::setRotation(const core::vector3df& rotation)
{
if(TargetAndRotationAreBound)
Target = getAbsolutePosition() + rotation.rotationToDirection();
ISceneNode::setRotation(rotation);
} }
...@@ -203,22 +223,6 @@ void CCameraSceneNode::OnRegisterSceneNode() ...@@ -203,22 +223,6 @@ void CCameraSceneNode::OnRegisterSceneNode()
core::vector3df tgtv = Target - pos; core::vector3df tgtv = Target - pos;
tgtv.normalize(); tgtv.normalize();
switch(Binding)
{
case ROTATION_FOLLOWS_TARGET:
setRotation(tgtv.getHorizontalAngle());
break;
case TARGET_FOLLOWS_ROTATION:
tgtv = getRotation().rotationToDirection(); // Already normalised
setTarget(pos + tgtv);
break;
default:
break;
}
// if upvector and vector to the target are the same, we have a // if upvector and vector to the target are the same, we have a
// problem. so solve this problem: // problem. so solve this problem:
core::vector3df up = UpVector; core::vector3df up = UpVector;
...@@ -286,7 +290,7 @@ void CCameraSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeR ...@@ -286,7 +290,7 @@ void CCameraSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeR
out->addFloat("Aspect", Aspect); out->addFloat("Aspect", Aspect);
out->addFloat("ZNear", ZNear); out->addFloat("ZNear", ZNear);
out->addFloat("ZFar", ZFar); out->addFloat("ZFar", ZFar);
out->addInt("Binding", (int)Binding); out->addBool("Binding", TargetAndRotationAreBound);
} }
...@@ -301,10 +305,7 @@ void CCameraSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttribute ...@@ -301,10 +305,7 @@ void CCameraSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttribute
Aspect = in->getAttributeAsFloat("Aspect"); Aspect = in->getAttributeAsFloat("Aspect");
ZNear = in->getAttributeAsFloat("ZNear"); ZNear = in->getAttributeAsFloat("ZNear");
ZFar = in->getAttributeAsFloat("ZFar"); ZFar = in->getAttributeAsFloat("ZFar");
TargetAndRotationAreBound = in->getAttributeAsBool("Binding");
Binding = (ICameraSceneNode::TargetAndRotationBinding)in->getAttributeAsInt("Binding");
if(0 == Binding)
Binding = TARGET_AND_ROTATION_INDEPENDENT;
recalculateProjectionMatrix(); recalculateProjectionMatrix();
recalculateViewArea(); recalculateViewArea();
...@@ -312,15 +313,15 @@ void CCameraSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttribute ...@@ -312,15 +313,15 @@ void CCameraSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttribute
//! Set the binding between the camera's rotation adn target. //! Set the binding between the camera's rotation adn target.
void CCameraSceneNode::setTargetAndRotationBinding(TargetAndRotationBinding binding) void CCameraSceneNode::bindTargetAndRotation(bool bound)
{ {
Binding = binding; TargetAndRotationAreBound = bound;
} }
//! Gets the binding between the camera's rotation and target. //! Gets the binding between the camera's rotation and target.
ICameraSceneNode::TargetAndRotationBinding CCameraSceneNode::getTargetAndRotationBinding(void) const bool CCameraSceneNode::getTargetAndRotationBinding(void) const
{ {
return Binding; return TargetAndRotationAreBound;
} }
......
...@@ -47,10 +47,19 @@ namespace scene ...@@ -47,10 +47,19 @@ namespace scene
//! for changing their position, look at target or whatever. //! for changing their position, look at target or whatever.
virtual bool OnEvent(const SEvent& event); virtual bool OnEvent(const SEvent& event);
//! sets the look at target of the camera //! Sets the look at target of the camera
//! \param pos: Look at target of the camera. /** If the camera's target and rotation are bound ( @see bindTargetAndRotation() )
then calling this will also change the camera's scene node rotation to match the target.
\param pos: Look at target of the camera. */
virtual void setTarget(const core::vector3df& pos); virtual void setTarget(const core::vector3df& pos);
//! Sets the rotation of the node.
/** This only modifies the relative rotation of the node.
/** If the camera's target and rotation are bound ( @see bindTargetAndRotation() )
then calling this will also change the camera's target to match the rotation.
\param rotation New rotation of the node in degrees. */
virtual void setRotation(const core::vector3df& rotation);
//! Gets the current look at target of the camera //! Gets the current look at target of the camera
//! \return Returns the current look at target of the camera //! \return Returns the current look at target of the camera
virtual const core::vector3df& getTarget() const; virtual const core::vector3df& getTarget() const;
...@@ -120,11 +129,11 @@ namespace scene ...@@ -120,11 +129,11 @@ namespace scene
//! Returns type of the scene node //! Returns type of the scene node
virtual ESCENE_NODE_TYPE getType() const { return ESNT_CAMERA; } virtual ESCENE_NODE_TYPE getType() const { return ESNT_CAMERA; }
//! Set the binding between the camera's rotation adn target. //! Binds the camera scene node's rotation to its target position and vice vera, or unbinds them.
virtual void setTargetAndRotationBinding(TargetAndRotationBinding binding); virtual void bindTargetAndRotation(bool bound);
//! Gets the binding between the camera's rotation and target. //! Queries if the camera scene node's rotation and its target position are bound together.
virtual TargetAndRotationBinding getTargetAndRotationBinding(void) const; virtual bool getTargetAndRotationBinding(void) const;
protected: protected:
...@@ -143,7 +152,7 @@ namespace scene ...@@ -143,7 +152,7 @@ namespace scene
bool InputReceiverEnabled; bool InputReceiverEnabled;
TargetAndRotationBinding Binding; bool TargetAndRotationAreBound;
}; };
} // end namespace } // end namespace
......
...@@ -667,8 +667,8 @@ ICameraSceneNode* CSceneManager::addCameraSceneNodeFPS(ISceneNode* parent, ...@@ -667,8 +667,8 @@ ICameraSceneNode* CSceneManager::addCameraSceneNodeFPS(ISceneNode* parent,
ISceneNodeAnimator* anm = new CSceneNodeAnimatorCameraFPS(CursorControl, rotateSpeed, ISceneNodeAnimator* anm = new CSceneNodeAnimatorCameraFPS(CursorControl, rotateSpeed,
moveSpeed, jumpSpeed, keyMapArray, keyMapSize, noVerticalMovement); moveSpeed, jumpSpeed, keyMapArray, keyMapSize, noVerticalMovement);
// Have the node's rotation follow its target. This is consistent with 1.4.2 and below. // Bind the node's rotation to its target. This is consistent with 1.4.2 and below.
node->setTargetAndRotationBinding(ICameraSceneNode::ROTATION_FOLLOWS_TARGET); node->bindTargetAndRotation(true);
node->addAnimator(anm); node->addAnimator(anm);
anm->drop(); anm->drop();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment