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-e03cc46cb475master
parent
55a8f70713
commit
06ad4408b7
|
@ -58,9 +58,18 @@ namespace scene
|
|||
virtual bool OnEvent(const SEvent& event) = 0;
|
||||
|
||||
//! 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;
|
||||
|
||||
//! 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
|
||||
/** \return Returns the current look at target of the camera */
|
||||
virtual const core::vector3df& getTarget() const = 0;
|
||||
|
@ -125,27 +134,17 @@ namespace scene
|
|||
return IsOrthogonal;
|
||||
}
|
||||
|
||||
//! Determines how the camera's target and its scene node rotation are bound together.
|
||||
typedef enum _TargetAndRotationBinding
|
||||
{
|
||||
//! The target and scene node rotation are independent.
|
||||
/** This is the default for most cameras. */
|
||||
TARGET_AND_ROTATION_INDEPENDENT = 0x10000,
|
||||
//! Binds the camera scene node's rotation to its target position and vice vera, or unbinds them.
|
||||
/** 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
|
||||
will point at the target point. FPS camera use this binding by default; other cameras do not.
|
||||
\param binding true to bind the camera's scene node rotation and targetting, false to unbind them.
|
||||
@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 */
|
||||
ROTATION_FOLLOWS_TARGET,
|
||||
|
||||
//! 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;
|
||||
//! Queries if the camera scene node's rotation and its target position are bound together.
|
||||
/** @see bindTargetAndRotation() */
|
||||
virtual bool getTargetAndRotationBinding(void) const = 0;
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
@ -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),
|
||||
core::vector3df(1.0f, 1.0f, 1.0f)),
|
||||
Target(lookat), UpVector(0.0f, 1.0f, 0.0f), ZNear(1.0f), ZFar(3000.0f),
|
||||
InputReceiverEnabled(true)
|
||||
InputReceiverEnabled(true), TargetAndRotationAreBound(false)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
setDebugName("CCameraSceneNode");
|
||||
|
@ -110,6 +110,26 @@ bool CCameraSceneNode::OnEvent(const SEvent& event)
|
|||
void CCameraSceneNode::setTarget(const core::vector3df& 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()
|
|||
core::vector3df tgtv = Target - pos;
|
||||
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
|
||||
// problem. so solve this problem:
|
||||
core::vector3df up = UpVector;
|
||||
|
@ -286,7 +290,7 @@ void CCameraSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeR
|
|||
out->addFloat("Aspect", Aspect);
|
||||
out->addFloat("ZNear", ZNear);
|
||||
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
|
|||
Aspect = in->getAttributeAsFloat("Aspect");
|
||||
ZNear = in->getAttributeAsFloat("ZNear");
|
||||
ZFar = in->getAttributeAsFloat("ZFar");
|
||||
|
||||
Binding = (ICameraSceneNode::TargetAndRotationBinding)in->getAttributeAsInt("Binding");
|
||||
if(0 == Binding)
|
||||
Binding = TARGET_AND_ROTATION_INDEPENDENT;
|
||||
TargetAndRotationAreBound = in->getAttributeAsBool("Binding");
|
||||
|
||||
recalculateProjectionMatrix();
|
||||
recalculateViewArea();
|
||||
|
@ -312,15 +313,15 @@ void CCameraSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttribute
|
|||
|
||||
|
||||
//! 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.
|
||||
ICameraSceneNode::TargetAndRotationBinding CCameraSceneNode::getTargetAndRotationBinding(void) const
|
||||
bool CCameraSceneNode::getTargetAndRotationBinding(void) const
|
||||
{
|
||||
return Binding;
|
||||
return TargetAndRotationAreBound;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -47,10 +47,19 @@ namespace scene
|
|||
//! for changing their position, look at target or whatever.
|
||||
virtual bool OnEvent(const SEvent& event);
|
||||
|
||||
//! sets the look at target of the camera
|
||||
//! \param pos: Look at target of the camera.
|
||||
//! Sets the 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);
|
||||
|
||||
//! 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
|
||||
//! \return Returns the current look at target of the camera
|
||||
virtual const core::vector3df& getTarget() const;
|
||||
|
@ -120,11 +129,11 @@ namespace scene
|
|||
//! Returns type of the scene node
|
||||
virtual ESCENE_NODE_TYPE getType() const { return ESNT_CAMERA; }
|
||||
|
||||
//! Set the binding between the camera's rotation adn target.
|
||||
virtual void setTargetAndRotationBinding(TargetAndRotationBinding binding);
|
||||
//! Binds the camera scene node's rotation to its target position and vice vera, or unbinds them.
|
||||
virtual void bindTargetAndRotation(bool bound);
|
||||
|
||||
//! Gets the binding between the camera's rotation and target.
|
||||
virtual TargetAndRotationBinding getTargetAndRotationBinding(void) const;
|
||||
//! Queries if the camera scene node's rotation and its target position are bound together.
|
||||
virtual bool getTargetAndRotationBinding(void) const;
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -143,7 +152,7 @@ namespace scene
|
|||
|
||||
bool InputReceiverEnabled;
|
||||
|
||||
TargetAndRotationBinding Binding;
|
||||
bool TargetAndRotationAreBound;
|
||||
};
|
||||
|
||||
} // end namespace
|
||||
|
|
|
@ -667,8 +667,8 @@ ICameraSceneNode* CSceneManager::addCameraSceneNodeFPS(ISceneNode* parent,
|
|||
ISceneNodeAnimator* anm = new CSceneNodeAnimatorCameraFPS(CursorControl, rotateSpeed,
|
||||
moveSpeed, jumpSpeed, keyMapArray, keyMapSize, noVerticalMovement);
|
||||
|
||||
// Have the node's rotation follow its target. This is consistent with 1.4.2 and below.
|
||||
node->setTargetAndRotationBinding(ICameraSceneNode::ROTATION_FOLLOWS_TARGET);
|
||||
// Bind the node's rotation to its target. This is consistent with 1.4.2 and below.
|
||||
node->bindTargetAndRotation(true);
|
||||
|
||||
node->addAnimator(anm);
|
||||
anm->drop();
|
||||
|
|
Loading…
Reference in New Issue