Add trackTo (locked-track) animation
This commit is contained in:
parent
df46c58cb8
commit
559a5d146a
@ -17,6 +17,7 @@ set(HEADERS
|
||||
SGRotateTransform.hxx
|
||||
SGScaleTransform.hxx
|
||||
SGText.hxx
|
||||
SGTrackToAnimation.hxx
|
||||
SGTranslateTransform.hxx
|
||||
animation.hxx
|
||||
model.hxx
|
||||
@ -42,6 +43,7 @@ set(SOURCES
|
||||
SGRotateTransform.cxx
|
||||
SGScaleTransform.cxx
|
||||
SGText.cxx
|
||||
SGTrackToAnimation.cxx
|
||||
SGTranslateTransform.cxx
|
||||
animation.cxx
|
||||
model.cxx
|
||||
@ -53,3 +55,11 @@ set(SOURCES
|
||||
)
|
||||
|
||||
simgear_scene_component(model scene/model "${SOURCES}" "${HEADERS}")
|
||||
|
||||
if(ENABLE_TESTS)
|
||||
|
||||
add_executable(test_animations animation_test.cxx)
|
||||
target_link_libraries(test_animations ${TEST_LIBS} ${OPENSCENEGRAPH_LIBRARIES})
|
||||
add_test(test_animations ${EXECUTABLE_OUTPUT_PATH}/test_animations)
|
||||
|
||||
endif(ENABLE_TESTS)
|
@ -727,7 +727,7 @@ SGKnobAnimation::SGKnobAnimation(const SGPropertyNode* configNode,
|
||||
_animationValue = value->simplify();
|
||||
|
||||
|
||||
readRotationCenterAndAxis(configNode, _center, _axis);
|
||||
readRotationCenterAndAxis(_center, _axis);
|
||||
}
|
||||
|
||||
osg::Group*
|
||||
|
246
simgear/scene/model/SGTrackToAnimation.cxx
Normal file
246
simgear/scene/model/SGTrackToAnimation.cxx
Normal file
@ -0,0 +1,246 @@
|
||||
// TrackTo animation
|
||||
//
|
||||
// Copyright (C) 2013 Thomas Geymayer <tomgey@gmail.com>
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
|
||||
#include "SGRotateTransform.hxx"
|
||||
#include "SGTrackToAnimation.hxx"
|
||||
|
||||
#include <simgear/scene/util/OsgMath.hxx>
|
||||
#include <osg/Transform>
|
||||
#include <cassert>
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static osg::NodePath requireNodePath( osg::Node* node,
|
||||
osg::Node* haltTraversalAtNode = 0 )
|
||||
{
|
||||
const osg::NodePathList node_paths =
|
||||
node->getParentalNodePaths(haltTraversalAtNode);
|
||||
return node_paths.at(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a subpath of an osg::NodePath
|
||||
*
|
||||
* @param path Path to extract subpath from
|
||||
* @param start Number of elements to skip from start of #path
|
||||
*
|
||||
* @return Subpath starting with node at position #start
|
||||
*/
|
||||
static osg::NodePath subPath( const osg::NodePath& path,
|
||||
size_t start )
|
||||
{
|
||||
if( start >= path.size() )
|
||||
return osg::NodePath();
|
||||
|
||||
osg::NodePath np(path.size() - start);
|
||||
for(size_t i = start; i < path.size(); ++i)
|
||||
np[i - start] = path[i];
|
||||
|
||||
return np;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visitor to find a group by its name.
|
||||
*/
|
||||
class FindGroupVisitor:
|
||||
public osg::NodeVisitor
|
||||
{
|
||||
public:
|
||||
|
||||
FindGroupVisitor(const std::string& name):
|
||||
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
|
||||
_name(name),
|
||||
_group(0)
|
||||
{
|
||||
if( name.empty() )
|
||||
SG_LOG(SG_IO, SG_WARN, "FindGroupVisitor: empty name provided");
|
||||
}
|
||||
|
||||
osg::Group* getGroup() const
|
||||
{
|
||||
return _group;
|
||||
}
|
||||
|
||||
virtual void apply(osg::Group& group)
|
||||
{
|
||||
if( _name != group.getName() )
|
||||
return traverse(group);
|
||||
|
||||
if( !_group )
|
||||
_group = &group;
|
||||
else
|
||||
SG_LOG(SG_IO, SG_WARN, "FindGroupVisitor: name not unique");
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
std::string _name;
|
||||
osg::Group *_group;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
class SGTrackToAnimation::UpdateCallback:
|
||||
public osg::NodeCallback
|
||||
{
|
||||
public:
|
||||
UpdateCallback( osg::Group* target,
|
||||
const SGTrackToAnimation* anim ):
|
||||
_target(target)
|
||||
{
|
||||
setName("SGTrackToAnimation::UpdateCallback");
|
||||
|
||||
_node_center = toOsg( anim->readVec3("center", "-m") );
|
||||
_target_center = toOsg( anim->readVec3("target-center", "-m") );
|
||||
_lock_axis = toOsg( anim->readVec3("lock-axis") );
|
||||
_track_axis = toOsg( anim->readVec3("track-axis") );
|
||||
|
||||
if( _lock_axis.normalize() == 0.0 )
|
||||
{
|
||||
anim->log(SG_WARN, "invalid lock-axis");
|
||||
_lock_axis.set(0, 1, 0);
|
||||
}
|
||||
|
||||
for(;;)
|
||||
{
|
||||
float proj = _lock_axis * _track_axis;
|
||||
if( proj != 0.0 )
|
||||
{
|
||||
anim->log(SG_WARN, "track-axis not perpendicular to lock-axis");
|
||||
|
||||
// Make tracking axis perpendicular to locked axis
|
||||
_track_axis -= _lock_axis * proj;
|
||||
}
|
||||
|
||||
if( _track_axis.normalize() == 0.0 )
|
||||
{
|
||||
anim->log(SG_WARN, "invalid track-axis");
|
||||
if( std::fabs(_lock_axis.x()) < 0.1 )
|
||||
_track_axis.set(1, 0, 0);
|
||||
else
|
||||
_track_axis.set(0, 1, 0);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
_up_axis = _lock_axis ^ _track_axis;
|
||||
}
|
||||
|
||||
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||
{
|
||||
SGRotateTransform* tf = static_cast<SGRotateTransform*>(node);
|
||||
|
||||
if( _target )
|
||||
{
|
||||
// Get path to animated node and calculated simplified paths to the
|
||||
// nearest common parent node of both the animated node and the target
|
||||
// node
|
||||
|
||||
// start at parent to not get false results by
|
||||
// also including animation transformation
|
||||
osg::NodePath node_path = requireNodePath(node->getParent(0)),
|
||||
target_path = requireNodePath(_target);
|
||||
size_t tp_size = target_path.size(),
|
||||
np_size = node_path.size();
|
||||
size_t common_parents = 0;
|
||||
|
||||
for(; common_parents < std::min(tp_size, np_size); ++common_parents)
|
||||
{
|
||||
if( target_path[common_parents] != node_path[common_parents] )
|
||||
break;
|
||||
}
|
||||
|
||||
_node_path = subPath(node_path, common_parents);
|
||||
_target_path = subPath(target_path, common_parents);
|
||||
_target = 0;
|
||||
|
||||
tf->setCenter( toSG(_node_center) );
|
||||
tf->setAxis( toSG(_lock_axis) );
|
||||
}
|
||||
|
||||
osg::Vec3 target_pos = ( osg::computeLocalToWorld(_target_path)
|
||||
* osg::computeWorldToLocal(_node_path)
|
||||
).preMult(_target_center),
|
||||
dir = target_pos - _node_center;
|
||||
|
||||
// Ensure direction is perpendicular to lock axis
|
||||
float proj = _lock_axis * dir;
|
||||
if( proj != 0.0 )
|
||||
dir -= _lock_axis * proj;
|
||||
|
||||
float x = dir * _track_axis,
|
||||
y = dir * _up_axis;
|
||||
tf->setAngleRad( std::atan2(y, x) );
|
||||
|
||||
traverse(node, nv);
|
||||
}
|
||||
protected:
|
||||
osg::Vec3 _node_center,
|
||||
_target_center,
|
||||
_lock_axis,
|
||||
_track_axis,
|
||||
_up_axis;
|
||||
osg::Group *_target;
|
||||
osg::NodePath _node_path,
|
||||
_target_path;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
SGTrackToAnimation::SGTrackToAnimation( osg::Node* node,
|
||||
const SGPropertyNode* configNode,
|
||||
SGPropertyNode* modelRoot ):
|
||||
SGAnimation(configNode, modelRoot),
|
||||
_target_group(0)
|
||||
{
|
||||
std::string target = configNode->getStringValue("target-name");
|
||||
std::cout << "track " << target << std::endl;
|
||||
configNode->printOn(std::cout);
|
||||
|
||||
FindGroupVisitor target_finder(target);
|
||||
node->accept(target_finder);
|
||||
|
||||
if( !(_target_group = target_finder.getGroup()) )
|
||||
log(SG_ALERT, "target not found: '" + target + '\'');
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
osg::Group* SGTrackToAnimation::createAnimationGroup(osg::Group& parent)
|
||||
{
|
||||
if( !_target_group )
|
||||
return 0;
|
||||
|
||||
SGRotateTransform* transform = new SGRotateTransform;
|
||||
transform->setName("locked-track animation");
|
||||
transform->setUpdateCallback(new UpdateCallback(_target_group, this));
|
||||
parent.addChild(transform);
|
||||
return transform;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void SGTrackToAnimation::log(sgDebugPriority p, const std::string& msg) const
|
||||
{
|
||||
SG_LOG
|
||||
(
|
||||
SG_IO,
|
||||
p,
|
||||
// TODO handle multiple object-names?
|
||||
"SGTrackToAnimation(" << getConfig()->getStringValue("object-name") << "): "
|
||||
<< msg
|
||||
);
|
||||
}
|
45
simgear/scene/model/SGTrackToAnimation.hxx
Normal file
45
simgear/scene/model/SGTrackToAnimation.hxx
Normal file
@ -0,0 +1,45 @@
|
||||
// TrackTo animation
|
||||
//
|
||||
// http://wiki.blender.org/index.php/Doc:2.6/Manual/Constraints/Tracking/Locked_Track
|
||||
// TODO: http://wiki.blender.org/index.php/Doc:2.6/Manual/Constraints/Tracking/Track_To
|
||||
//
|
||||
// Copyright (C) 2013 Thomas Geymayer <tomgey@gmail.com>
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
|
||||
#ifndef SG_TRACK_TO_ANIMATION_HXX_
|
||||
#define SG_TRACK_TO_ANIMATION_HXX_
|
||||
|
||||
#include <simgear/scene/model/animation.hxx>
|
||||
|
||||
class SGTrackToAnimation:
|
||||
public SGAnimation
|
||||
{
|
||||
public:
|
||||
SGTrackToAnimation( osg::Node* node,
|
||||
const SGPropertyNode* configNode,
|
||||
SGPropertyNode* modelRoot );
|
||||
|
||||
virtual osg::Group* createAnimationGroup(osg::Group& parent);
|
||||
|
||||
protected:
|
||||
class UpdateCallback;
|
||||
|
||||
osg::Group *_target_group;
|
||||
|
||||
void log(sgDebugPriority p, const std::string& msg) const;
|
||||
};
|
||||
|
||||
#endif /* SG_TRACK_TO_ANIMATION_HXX_ */
|
@ -57,6 +57,7 @@
|
||||
#include "SGScaleTransform.hxx"
|
||||
#include "SGInteractionAnimation.hxx"
|
||||
#include "SGPickAnimation.hxx"
|
||||
#include "SGTrackToAnimation.hxx"
|
||||
|
||||
#include "ConditionNode.hxx"
|
||||
|
||||
@ -65,7 +66,6 @@ using OpenThreads::ReentrantMutex;
|
||||
using OpenThreads::ScopedLock;
|
||||
|
||||
using namespace simgear;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Static utility functions.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@ -206,7 +206,6 @@ read_value(const SGPropertyNode* configNode, SGPropertyNode* modelRoot,
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Animation installer
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@ -424,6 +423,9 @@ SGAnimation::animate(osg::Node* node, const SGPropertyNode* configNode,
|
||||
} else if (type == "timed") {
|
||||
SGTimedAnimation animInst(configNode, modelRoot);
|
||||
animInst.apply(node);
|
||||
} else if (type == "track-to" || type == "locked-track") {
|
||||
SGTrackToAnimation animInst(node, configNode, modelRoot);
|
||||
animInst.apply(node);
|
||||
} else if (type == "translate") {
|
||||
SGTranslateAnimation animInst(configNode, modelRoot);
|
||||
animInst.apply(node);
|
||||
@ -530,6 +532,41 @@ SGAnimation::installInGroup(const std::string& name, osg::Group& group,
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
SGVec3d SGAnimation::readVec3( const std::string& name,
|
||||
const std::string& suffix,
|
||||
const SGVec3d& def ) const
|
||||
{
|
||||
SGVec3d vec;
|
||||
vec[0] = _configNode->getDoubleValue(name + "/x" + suffix, def.x());
|
||||
vec[1] = _configNode->getDoubleValue(name + "/y" + suffix, def.y());
|
||||
vec[2] = _configNode->getDoubleValue(name + "/z" + suffix, def.z());
|
||||
return vec;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// factored out to share with SGKnobAnimation
|
||||
void SGAnimation::readRotationCenterAndAxis( SGVec3d& center,
|
||||
SGVec3d& axis ) const
|
||||
{
|
||||
center = SGVec3d::zeros();
|
||||
if( _configNode->hasValue("axis/x1-m") )
|
||||
{
|
||||
SGVec3d v1 = readVec3("axis", "1-m"), // axis/[xyz]1-m
|
||||
v2 = readVec3("axis", "2-m"); // axis/[xyz]2-m
|
||||
center = 0.5*(v1+v2);
|
||||
axis = v2 - v1;
|
||||
}
|
||||
else
|
||||
{
|
||||
axis = readVec3("axis");
|
||||
}
|
||||
if( 8 * SGLimitsd::min() < norm(axis) )
|
||||
axis = normalize(axis);
|
||||
|
||||
center = readVec3("center", "-m", center);
|
||||
}
|
||||
|
||||
void
|
||||
SGAnimation::removeMode(osg::Node& node, osg::StateAttribute::GLMode mode)
|
||||
{
|
||||
@ -584,7 +621,7 @@ SGAnimation::getCondition() const
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of null animation
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@ -606,7 +643,7 @@ SGGroupAnimation::createAnimationGroup(osg::Group& parent)
|
||||
return group;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of translate animation
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@ -666,7 +703,7 @@ SGTranslateAnimation::createAnimationGroup(osg::Group& parent)
|
||||
return transform;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of rotate/spin animation
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@ -837,33 +874,6 @@ void SpinAnimCallback::operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||
}
|
||||
}
|
||||
|
||||
// factored out to share with SGKnobAnimation
|
||||
void readRotationCenterAndAxis(const SGPropertyNode* configNode, SGVec3d& center, SGVec3d& axis)
|
||||
{
|
||||
center = SGVec3d::zeros();
|
||||
if (configNode->hasValue("axis/x1-m")) {
|
||||
SGVec3d v1, v2;
|
||||
v1[0] = configNode->getDoubleValue("axis/x1-m", 0);
|
||||
v1[1] = configNode->getDoubleValue("axis/y1-m", 0);
|
||||
v1[2] = configNode->getDoubleValue("axis/z1-m", 0);
|
||||
v2[0] = configNode->getDoubleValue("axis/x2-m", 0);
|
||||
v2[1] = configNode->getDoubleValue("axis/y2-m", 0);
|
||||
v2[2] = configNode->getDoubleValue("axis/z2-m", 0);
|
||||
center = 0.5*(v1+v2);
|
||||
axis = v2 - v1;
|
||||
} else {
|
||||
axis[0] = configNode->getDoubleValue("axis/x", 0);
|
||||
axis[1] = configNode->getDoubleValue("axis/y", 0);
|
||||
axis[2] = configNode->getDoubleValue("axis/z", 0);
|
||||
}
|
||||
if (8*SGLimitsd::min() < norm(axis))
|
||||
axis = normalize(axis);
|
||||
|
||||
center[0] = configNode->getDoubleValue("center/x-m", center[0]);
|
||||
center[1] = configNode->getDoubleValue("center/y-m", center[1]);
|
||||
center[2] = configNode->getDoubleValue("center/z-m", center[2]);
|
||||
}
|
||||
|
||||
SGVec3d readTranslateAxis(const SGPropertyNode* configNode)
|
||||
{
|
||||
SGVec3d axis;
|
||||
@ -905,7 +915,7 @@ SGRotateAnimation::SGRotateAnimation(const SGPropertyNode* configNode,
|
||||
else
|
||||
_initialValue = 0;
|
||||
|
||||
readRotationCenterAndAxis(configNode, _center, _axis);
|
||||
readRotationCenterAndAxis(_center, _axis);
|
||||
}
|
||||
|
||||
osg::Group*
|
||||
@ -935,7 +945,7 @@ SGRotateAnimation::createAnimationGroup(osg::Group& parent)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of scale animation
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@ -1069,7 +1079,7 @@ SGScaleAnimation::createAnimationGroup(osg::Group& parent)
|
||||
return transform;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Don't create a new state state everytime we need GL_NORMALIZE!
|
||||
|
||||
namespace
|
||||
@ -1215,7 +1225,7 @@ namespace
|
||||
&SGDistScaleAnimation::Transform::writeLocalData
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of flash animation
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@ -1371,7 +1381,7 @@ namespace
|
||||
&SGFlashAnimation::Transform::writeLocalData
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of billboard animation
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@ -1456,7 +1466,7 @@ namespace
|
||||
&SGBillboardAnimation::Transform::writeLocalData
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of a range animation
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@ -1561,7 +1571,7 @@ SGRangeAnimation::createAnimationGroup(osg::Group& parent)
|
||||
return group;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of a select animation
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@ -1591,7 +1601,7 @@ SGSelectAnimation::createAnimationGroup(osg::Group& parent)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of alpha test animation
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@ -1661,7 +1671,7 @@ SGAlphaTestAnimation::install(osg::Node& node)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Blend animation installer
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -1780,7 +1790,7 @@ SGBlendAnimation::install(osg::Node& node)
|
||||
node.accept(visitor);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Timed animation installer
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -1891,7 +1901,7 @@ SGTimedAnimation::createAnimationGroup(osg::Group& parent)
|
||||
return sw;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// dynamically switch on/off shadows
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@ -1937,7 +1947,7 @@ SGShadowAnimation::createAnimationGroup(osg::Group& parent)
|
||||
return group;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of SGTexTransformAnimation
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
@ -35,13 +35,11 @@ SGExpressiond*
|
||||
read_value(const SGPropertyNode* configNode, SGPropertyNode* modelRoot,
|
||||
const char* unit, double defMin, double defMax);
|
||||
|
||||
void readRotationCenterAndAxis(const SGPropertyNode* configNode, SGVec3d& center, SGVec3d& axis);
|
||||
SGVec3d readTranslateAxis(const SGPropertyNode* configNode);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Base class for animation installers
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Base class for animation installers
|
||||
*/
|
||||
class SGAnimation : protected osg::NodeVisitor {
|
||||
public:
|
||||
SGAnimation(const SGPropertyNode* configNode, SGPropertyNode* modelRoot);
|
||||
@ -60,6 +58,21 @@ protected:
|
||||
|
||||
virtual void apply(osg::Group& group);
|
||||
|
||||
/**
|
||||
* Read a 3d vector from the configuration property node.
|
||||
*
|
||||
* Reads values from @a name/[xyz]@a prefix and defaults to the according
|
||||
* value of @a def for each value which is not set.
|
||||
*
|
||||
* @param name Name of the root node containing all coordinates
|
||||
* @param suffix Suffix appended to each child node (x,y,z)
|
||||
* @param def Vector containing default values
|
||||
*/
|
||||
SGVec3d readVec3( const std::string& name,
|
||||
const std::string& suffix = "",
|
||||
const SGVec3d& def = SGVec3d() ) const;
|
||||
void readRotationCenterAndAxis(SGVec3d& center, SGVec3d& axis) const;
|
||||
|
||||
void removeMode(osg::Node& node, osg::StateAttribute::GLMode mode);
|
||||
void removeAttribute(osg::Node& node, osg::StateAttribute::Type type);
|
||||
void removeTextureMode(osg::Node& node, unsigned unit,
|
||||
@ -100,7 +113,7 @@ private:
|
||||
bool _enableHOT;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Null animation installer
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -111,7 +124,7 @@ public:
|
||||
virtual osg::Group* createAnimationGroup(osg::Group& parent);
|
||||
};
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Translate animation installer
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -129,7 +142,7 @@ private:
|
||||
double _initialValue;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Rotate/Spin animation installer
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -148,7 +161,7 @@ private:
|
||||
bool _isSpin;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Scale animation installer
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -166,7 +179,7 @@ private:
|
||||
SGVec3d _center;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// dist scale animation installer
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -179,7 +192,7 @@ public:
|
||||
class Transform;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// dist scale animation installer
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -193,7 +206,7 @@ public:
|
||||
class Transform;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// dist scale animation installer
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -206,7 +219,7 @@ public:
|
||||
class Transform;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Range animation installer
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -224,7 +237,7 @@ private:
|
||||
SGVec2d _initialValue;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Select animation installer
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -236,7 +249,7 @@ public:
|
||||
virtual osg::Group* createAnimationGroup(osg::Group& parent);
|
||||
};
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Alpha test animation installer
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -248,7 +261,7 @@ public:
|
||||
virtual void install(osg::Node& node);
|
||||
};
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Blend animation installer
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -265,7 +278,7 @@ private:
|
||||
SGSharedPtr<SGExpressiond> _animationValue;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Timed animation installer
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -279,7 +292,7 @@ private:
|
||||
class UpdateCallback;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Shadow animation installer
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -293,7 +306,7 @@ private:
|
||||
class UpdateCallback;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// TextureTransform animation
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -314,7 +327,7 @@ private:
|
||||
UpdateCallback* updateCallback);
|
||||
};
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Shader animation
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -329,7 +342,7 @@ private:
|
||||
class UpdateCallback;
|
||||
osg::ref_ptr<osg::Texture2D> _effect_texture;
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Light animation
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
69
simgear/scene/model/animation_test.cxx
Normal file
69
simgear/scene/model/animation_test.cxx
Normal file
@ -0,0 +1,69 @@
|
||||
#include "animation.hxx"
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
#define COMPARE(a, b) \
|
||||
if( (a) != (b) ) \
|
||||
{ \
|
||||
std::cerr << "line " << __LINE__ << ": failed: "\
|
||||
<< #a << " != " << #b\
|
||||
<< " [" << (a) << " != " << (b) << "]" << std::endl; \
|
||||
return 1; \
|
||||
}
|
||||
|
||||
#define VERIFY(a) \
|
||||
if( !(a) ) \
|
||||
{ \
|
||||
std::cerr << "failed: line " << __LINE__ << ": " << #a << std::endl; \
|
||||
return 1; \
|
||||
}
|
||||
|
||||
struct AnimationTest:
|
||||
public SGAnimation
|
||||
{
|
||||
AnimationTest(const SGPropertyNode* n):
|
||||
SGAnimation(n, 0)
|
||||
{}
|
||||
|
||||
void readConfig()
|
||||
{
|
||||
readRotationCenterAndAxis(center, axis);
|
||||
}
|
||||
|
||||
SGVec3d center,
|
||||
axis;
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
SGPropertyNode_ptr config = new SGPropertyNode;
|
||||
AnimationTest anim(config);
|
||||
|
||||
SGVec3d v1(1, 2, 3),
|
||||
v2(-1, 4, 0);
|
||||
config->setDoubleValue("axis/x1-m", v1.x());
|
||||
config->setDoubleValue("axis/y1-m", v1.y());
|
||||
config->setDoubleValue("axis/z1-m", v1.z());
|
||||
config->setDoubleValue("axis/x2-m", v2.x());
|
||||
config->setDoubleValue("axis/y2-m", v2.y());
|
||||
config->setDoubleValue("axis/z2-m", v2.z());
|
||||
anim.readConfig();
|
||||
|
||||
COMPARE(anim.center, (v1 + v2) * 0.5)
|
||||
COMPARE(anim.axis, normalize(v2 - v1))
|
||||
|
||||
config->removeChild("axis", 0, false);
|
||||
config->setDoubleValue("center/x-m", v1.x());
|
||||
config->setDoubleValue("center/y-m", v1.y());
|
||||
config->setDoubleValue("center/z-m", v1.z());
|
||||
config->setDoubleValue("axis/x", v2.x());
|
||||
config->setDoubleValue("axis/y", v2.y());
|
||||
config->setDoubleValue("axis/z", v2.z());
|
||||
anim.readConfig();
|
||||
|
||||
COMPARE(anim.center, v1)
|
||||
COMPARE(anim.axis, normalize(v2))
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user