Work on knob/slider animations.
Rename some values, and support mouse-dragging.
This commit is contained in:
parent
870fc2e53e
commit
eeeb30dc3f
@ -27,13 +27,15 @@
|
|||||||
#include <osg/PolygonMode>
|
#include <osg/PolygonMode>
|
||||||
#include <osg/Material>
|
#include <osg/Material>
|
||||||
#include <osgGA/GUIEventAdapter>
|
#include <osgGA/GUIEventAdapter>
|
||||||
|
|
||||||
|
#include <simgear/sg_inlines.h>
|
||||||
#include <simgear/scene/util/SGPickCallback.hxx>
|
#include <simgear/scene/util/SGPickCallback.hxx>
|
||||||
#include <simgear/scene/material/EffectGeode.hxx>
|
#include <simgear/scene/material/EffectGeode.hxx>
|
||||||
#include <simgear/scene/util/SGSceneUserData.hxx>
|
#include <simgear/scene/util/SGSceneUserData.hxx>
|
||||||
#include <simgear/structure/SGBinding.hxx>
|
#include <simgear/structure/SGBinding.hxx>
|
||||||
#include <simgear/scene/util/StateAttributeFactory.hxx>
|
#include <simgear/scene/util/StateAttributeFactory.hxx>
|
||||||
#include <simgear/scene/model/SGRotateTransform.hxx>
|
#include <simgear/scene/model/SGRotateTransform.hxx>
|
||||||
|
#include <simgear/scene/model/SGTranslateTransform.hxx>
|
||||||
|
|
||||||
using namespace simgear;
|
using namespace simgear;
|
||||||
|
|
||||||
@ -49,6 +51,23 @@ static void readOptionalBindingList(const SGPropertyNode* aNode, SGPropertyNode*
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
osg::Vec2d eventToWindowCoords(const osgGA::GUIEventAdapter* ea)
|
||||||
|
{
|
||||||
|
using namespace osg;
|
||||||
|
const GraphicsContext* gc = ea->getGraphicsContext();
|
||||||
|
const GraphicsContext::Traits* traits = gc->getTraits() ;
|
||||||
|
// Scale x, y to the dimensions of the window
|
||||||
|
double x = (((ea->getX() - ea->getXmin()) / (ea->getXmax() - ea->getXmin()))
|
||||||
|
* (double)traits->width);
|
||||||
|
double y = (((ea->getY() - ea->getYmin()) / (ea->getYmax() - ea->getYmin()))
|
||||||
|
* (double)traits->height);
|
||||||
|
if (ea->getMouseYOrientation() == osgGA::GUIEventAdapter::Y_INCREASING_DOWNWARDS)
|
||||||
|
y = (double)traits->height - y;
|
||||||
|
|
||||||
|
return osg::Vec2d(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
class SGPickAnimation::PickCallback : public SGPickCallback {
|
class SGPickAnimation::PickCallback : public SGPickCallback {
|
||||||
public:
|
public:
|
||||||
PickCallback(const SGPropertyNode* configNode,
|
PickCallback(const SGPropertyNode* configNode,
|
||||||
@ -79,12 +98,15 @@ static void readOptionalBindingList(const SGPropertyNode* aNode, SGPropertyNode*
|
|||||||
_repeatTime = -_repeatInterval; // anti-bobble: delay start of repeat
|
_repeatTime = -_repeatInterval; // anti-bobble: delay start of repeat
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
virtual void buttonReleased(void)
|
virtual void buttonReleased(int keyModState)
|
||||||
{
|
{
|
||||||
|
SG_UNUSED(keyModState);
|
||||||
fireBindingList(_bindingsUp);
|
fireBindingList(_bindingsUp);
|
||||||
}
|
}
|
||||||
virtual void update(double dt)
|
|
||||||
|
virtual void update(double dt, int keyModState)
|
||||||
{
|
{
|
||||||
|
SG_UNUSED(keyModState);
|
||||||
if (!_repeatable)
|
if (!_repeatable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -193,6 +215,7 @@ static void readOptionalBindingList(const SGPropertyNode* aNode, SGPropertyNode*
|
|||||||
bool _done;
|
bool _done;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class SGPickAnimation::VncCallback : public SGPickCallback {
|
class SGPickAnimation::VncCallback : public SGPickCallback {
|
||||||
public:
|
public:
|
||||||
@ -231,15 +254,14 @@ static void readOptionalBindingList(const SGPropertyNode* aNode, SGPropertyNode*
|
|||||||
return vv.wasSuccessful();
|
return vv.wasSuccessful();
|
||||||
|
|
||||||
}
|
}
|
||||||
virtual void buttonReleased(void)
|
virtual void buttonReleased(int keyModState)
|
||||||
{
|
{
|
||||||
|
SG_UNUSED(keyModState);
|
||||||
SG_LOG(SG_INPUT, SG_DEBUG, "VNC release");
|
SG_LOG(SG_INPUT, SG_DEBUG, "VNC release");
|
||||||
VncVisitor vv(_x, _y, 0);
|
VncVisitor vv(_x, _y, 0);
|
||||||
_node->accept(vv);
|
_node->accept(vv);
|
||||||
}
|
}
|
||||||
virtual void update(double dt)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
private:
|
private:
|
||||||
double _x, _y;
|
double _x, _y;
|
||||||
osg::ref_ptr<osg::Group> _node;
|
osg::ref_ptr<osg::Group> _node;
|
||||||
@ -247,6 +269,8 @@ static void readOptionalBindingList(const SGPropertyNode* aNode, SGPropertyNode*
|
|||||||
double _squaredRight, _squaredDown;
|
double _squaredRight, _squaredDown;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
SGPickAnimation::SGPickAnimation(const SGPropertyNode* configNode,
|
SGPickAnimation::SGPickAnimation(const SGPropertyNode* configNode,
|
||||||
SGPropertyNode* modelRoot) :
|
SGPropertyNode* modelRoot) :
|
||||||
SGAnimation(configNode, modelRoot)
|
SGAnimation(configNode, modelRoot)
|
||||||
@ -363,30 +387,30 @@ static void repeatBindings(const SGBindingList& a, SGBindingList& out, int count
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool static_knobMouseWheelAlternateDirection = false;
|
static bool static_knobMouseWheelAlternateDirection = false;
|
||||||
|
static bool static_knobDragAlternateAxis = false;
|
||||||
|
|
||||||
class SGKnobAnimation::KnobPickCallback : public SGPickCallback {
|
class KnobSliderPickCallback : public SGPickCallback {
|
||||||
public:
|
public:
|
||||||
KnobPickCallback(const SGPropertyNode* configNode,
|
KnobSliderPickCallback(const SGPropertyNode* configNode,
|
||||||
SGPropertyNode* modelRoot) :
|
SGPropertyNode* modelRoot) :
|
||||||
SGPickCallback(PriorityPanel),
|
SGPickCallback(PriorityPanel),
|
||||||
_direction(DIRECTION_NONE),
|
_direction(DIRECTION_NONE),
|
||||||
_repeatInterval(configNode->getDoubleValue("interval-sec", 0.1)),
|
_repeatInterval(configNode->getDoubleValue("interval-sec", 0.1))
|
||||||
_stickyShifted(false)
|
|
||||||
{
|
{
|
||||||
readOptionalBindingList(configNode, modelRoot, "action", _action);
|
readOptionalBindingList(configNode, modelRoot, "action", _action);
|
||||||
readOptionalBindingList(configNode, modelRoot, "cw", _bindingsCW);
|
readOptionalBindingList(configNode, modelRoot, "increase", _bindingsCW);
|
||||||
readOptionalBindingList(configNode, modelRoot, "ccw", _bindingsCCW);
|
readOptionalBindingList(configNode, modelRoot, "decrease", _bindingsCCW);
|
||||||
|
|
||||||
readOptionalBindingList(configNode, modelRoot, "release", _releaseAction);
|
readOptionalBindingList(configNode, modelRoot, "release", _releaseAction);
|
||||||
readOptionalBindingList(configNode, modelRoot, "hovered", _hover);
|
readOptionalBindingList(configNode, modelRoot, "hovered", _hover);
|
||||||
|
|
||||||
if (configNode->hasChild("shift-action") || configNode->hasChild("shift-cw") ||
|
if (configNode->hasChild("shift-action") || configNode->hasChild("shift-increase") ||
|
||||||
configNode->hasChild("shift-ccw"))
|
configNode->hasChild("shift-decrease"))
|
||||||
{
|
{
|
||||||
// explicit shifted behaviour - just do exactly what was provided
|
// explicit shifted behaviour - just do exactly what was provided
|
||||||
readOptionalBindingList(configNode, modelRoot, "shift-action", _shiftedAction);
|
readOptionalBindingList(configNode, modelRoot, "shift-action", _shiftedAction);
|
||||||
readOptionalBindingList(configNode, modelRoot, "shift-cw", _shiftedCW);
|
readOptionalBindingList(configNode, modelRoot, "shift-increase", _shiftedCW);
|
||||||
readOptionalBindingList(configNode, modelRoot, "shift-ccw", _shiftedCCW);
|
readOptionalBindingList(configNode, modelRoot, "shift-decrease", _shiftedCCW);
|
||||||
} else {
|
} else {
|
||||||
// default shifted behaviour - repeat normal bindings N times.
|
// default shifted behaviour - repeat normal bindings N times.
|
||||||
int shiftRepeat = configNode->getIntValue("shift-repeat", 10);
|
int shiftRepeat = configNode->getIntValue("shift-repeat", 10);
|
||||||
@ -394,12 +418,12 @@ public:
|
|||||||
repeatBindings(_bindingsCW, _shiftedCW, shiftRepeat);
|
repeatBindings(_bindingsCW, _shiftedCW, shiftRepeat);
|
||||||
repeatBindings(_bindingsCCW, _shiftedCCW, shiftRepeat);
|
repeatBindings(_bindingsCCW, _shiftedCCW, shiftRepeat);
|
||||||
} // of default shifted behaviour
|
} // of default shifted behaviour
|
||||||
|
|
||||||
|
_dragScale = configNode->getDoubleValue("drag-scale-px", 10.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool buttonPressed(int button, const osgGA::GUIEventAdapter* ea, const Info&)
|
virtual bool buttonPressed(int button, const osgGA::GUIEventAdapter* ea, const Info&)
|
||||||
{
|
{
|
||||||
_stickyShifted = ea->getModKeyMask() & osgGA::GUIEventAdapter::MODKEY_SHIFT;
|
|
||||||
|
|
||||||
// the 'be nice to Mac / laptop' users option; alt-clicking spins the
|
// the 'be nice to Mac / laptop' users option; alt-clicking spins the
|
||||||
// opposite direction. Should make this configurable
|
// opposite direction. Should make this configurable
|
||||||
if ((button == 0) && (ea->getModKeyMask() & osgGA::GUIEventAdapter::MODKEY_ALT)) {
|
if ((button == 0) && (ea->getModKeyMask() & osgGA::GUIEventAdapter::MODKEY_ALT)) {
|
||||||
@ -418,22 +442,61 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_repeatTime = -_repeatInterval; // anti-bobble: delay start of repeat
|
_lastFirePos = eventToWindowCoords(ea);
|
||||||
fire(_stickyShifted);
|
// delay start of repeat, makes dragging more usable
|
||||||
|
_repeatTime = -_repeatInterval;
|
||||||
|
_hasDragged = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void buttonReleased(void)
|
virtual void buttonReleased(int keyModState)
|
||||||
{
|
{
|
||||||
|
// for *clicks*, we only fire on button release
|
||||||
|
if (!_hasDragged) {
|
||||||
|
// std::cout << "no drag, firing" << std::endl;
|
||||||
|
fire(keyModState & osgGA::GUIEventAdapter::MODKEY_SHIFT);
|
||||||
|
}
|
||||||
|
|
||||||
fireBindingList(_releaseAction);
|
fireBindingList(_releaseAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void update(double dt)
|
virtual void mouseMoved(const osgGA::GUIEventAdapter* ea)
|
||||||
{
|
{
|
||||||
|
_mousePos = eventToWindowCoords(ea);;
|
||||||
|
osg::Vec2d deltaMouse = _mousePos - _lastFirePos;
|
||||||
|
|
||||||
|
if (!_hasDragged) {
|
||||||
|
|
||||||
|
double manhattanDist = deltaMouse.x() * deltaMouse.x() + deltaMouse.y() * deltaMouse.y();
|
||||||
|
if (manhattanDist < 5) {
|
||||||
|
// don't do anything, just input noise
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// user is dragging, disable repeat behaviour
|
||||||
|
_hasDragged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
double delta = static_knobDragAlternateAxis ? deltaMouse.y() : deltaMouse.x();
|
||||||
|
delta /= _dragScale;
|
||||||
|
if (fabs(delta) >= 1.0) {
|
||||||
|
// determine direction from sign of delta
|
||||||
|
_direction = (delta > 0.0) ? DIRECTION_CLOCKWISE : DIRECTION_ANTICLOCKWISE;
|
||||||
|
fire(ea->getModKeyMask());
|
||||||
|
_lastFirePos = _mousePos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void update(double dt, int keyModState)
|
||||||
|
{
|
||||||
|
if (_hasDragged) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_repeatTime += dt;
|
_repeatTime += dt;
|
||||||
while (_repeatInterval < _repeatTime) {
|
while (_repeatInterval < _repeatTime) {
|
||||||
_repeatTime -= _repeatInterval;
|
_repeatTime -= _repeatInterval;
|
||||||
fire(_stickyShifted);
|
fire(keyModState & osgGA::GUIEventAdapter::MODKEY_SHIFT);
|
||||||
} // of repeat iteration
|
} // of repeat iteration
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,11 +549,14 @@ private:
|
|||||||
double _repeatInterval;
|
double _repeatInterval;
|
||||||
double _repeatTime;
|
double _repeatTime;
|
||||||
|
|
||||||
// FIXME - would be better to pass the current modifier state
|
bool _hasDragged; ///< has the mouse been dragged since the press?
|
||||||
// into update(), but for now let's make it sticky
|
osg::Vec2d _mousePos, ///< current window coords location of the mouse
|
||||||
bool _stickyShifted;
|
_lastFirePos; ///< mouse location where we last fired the bindings
|
||||||
|
double _dragScale;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class SGKnobAnimation::UpdateCallback : public osg::NodeCallback {
|
class SGKnobAnimation::UpdateCallback : public osg::NodeCallback {
|
||||||
public:
|
public:
|
||||||
UpdateCallback(SGExpressiond const* animationValue) :
|
UpdateCallback(SGExpressiond const* animationValue) :
|
||||||
@ -535,7 +601,7 @@ SGKnobAnimation::createAnimationGroup(osg::Group& parent)
|
|||||||
transform->setAxis(_axis);
|
transform->setAxis(_axis);
|
||||||
|
|
||||||
SGSceneUserData* ud = SGSceneUserData::getOrCreateSceneUserData(transform);
|
SGSceneUserData* ud = SGSceneUserData::getOrCreateSceneUserData(transform);
|
||||||
ud->setPickCallback(new KnobPickCallback(getConfig(), getModelRoot()));
|
ud->setPickCallback(new KnobSliderPickCallback(getConfig(), getModelRoot()));
|
||||||
|
|
||||||
return transform;
|
return transform;
|
||||||
}
|
}
|
||||||
@ -545,3 +611,56 @@ void SGKnobAnimation::setAlternateMouseWheelDirection(bool aToggle)
|
|||||||
static_knobMouseWheelAlternateDirection = aToggle;
|
static_knobMouseWheelAlternateDirection = aToggle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SGKnobAnimation::setAlternateDragAxis(bool aToggle)
|
||||||
|
{
|
||||||
|
static_knobDragAlternateAxis = aToggle;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class SGSliderAnimation::UpdateCallback : public osg::NodeCallback {
|
||||||
|
public:
|
||||||
|
UpdateCallback(SGExpressiond const* animationValue) :
|
||||||
|
_animationValue(animationValue)
|
||||||
|
{
|
||||||
|
setName("SGSliderAnimation::UpdateCallback");
|
||||||
|
}
|
||||||
|
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||||
|
{
|
||||||
|
SGTranslateTransform* transform = static_cast<SGTranslateTransform*>(node);
|
||||||
|
transform->setValue(_animationValue->getValue());
|
||||||
|
|
||||||
|
traverse(node, nv);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
SGSharedPtr<SGExpressiond const> _animationValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
SGSliderAnimation::SGSliderAnimation(const SGPropertyNode* configNode,
|
||||||
|
SGPropertyNode* modelRoot) :
|
||||||
|
SGPickAnimation(configNode, modelRoot)
|
||||||
|
{
|
||||||
|
SGSharedPtr<SGExpressiond> value = read_value(configNode, modelRoot, "-m",
|
||||||
|
-SGLimitsd::max(), SGLimitsd::max());
|
||||||
|
_animationValue = value->simplify();
|
||||||
|
|
||||||
|
_axis = readTranslateAxis(configNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::Group*
|
||||||
|
SGSliderAnimation::createAnimationGroup(osg::Group& parent)
|
||||||
|
{
|
||||||
|
SGTranslateTransform* transform = new SGTranslateTransform();
|
||||||
|
innerSetupPickGroup(transform, parent);
|
||||||
|
|
||||||
|
UpdateCallback* uc = new UpdateCallback(_animationValue);
|
||||||
|
transform->setUpdateCallback(uc);
|
||||||
|
transform->setAxis(_axis);
|
||||||
|
|
||||||
|
SGSceneUserData* ud = SGSceneUserData::getOrCreateSceneUserData(transform);
|
||||||
|
ud->setPickCallback(new KnobSliderPickCallback(getConfig(), getModelRoot()));
|
||||||
|
|
||||||
|
return transform;
|
||||||
|
}
|
||||||
|
@ -60,8 +60,14 @@ public:
|
|||||||
* Since no one can agree on that, make it a global toggle.
|
* Since no one can agree on that, make it a global toggle.
|
||||||
*/
|
*/
|
||||||
static void setAlternateMouseWheelDirection(bool aToggle);
|
static void setAlternateMouseWheelDirection(bool aToggle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* by default mouse is dragged left-right to change knobs.
|
||||||
|
* set this to true to default to up-down. Individual knobs
|
||||||
|
* can overrider this,
|
||||||
|
*/
|
||||||
|
static void setAlternateDragAxis(bool aToggle);
|
||||||
private:
|
private:
|
||||||
class KnobPickCallback;
|
|
||||||
class UpdateCallback;
|
class UpdateCallback;
|
||||||
|
|
||||||
SGVec3d _axis;
|
SGVec3d _axis;
|
||||||
@ -69,5 +75,19 @@ private:
|
|||||||
SGSharedPtr<SGExpressiond const> _animationValue;
|
SGSharedPtr<SGExpressiond const> _animationValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SGSliderAnimation : public SGPickAnimation
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SGSliderAnimation(const SGPropertyNode* configNode,
|
||||||
|
SGPropertyNode* modelRoot);
|
||||||
|
virtual osg::Group* createAnimationGroup(osg::Group& parent);
|
||||||
|
|
||||||
|
private:
|
||||||
|
class UpdateCallback;
|
||||||
|
|
||||||
|
SGVec3d _axis;
|
||||||
|
SGSharedPtr<SGExpressiond const> _animationValue;
|
||||||
|
};
|
||||||
|
|
||||||
#endif // of SG_SCENE_PICK_ANIMATION_HXX
|
#endif // of SG_SCENE_PICK_ANIMATION_HXX
|
||||||
|
|
||||||
|
@ -399,6 +399,9 @@ SGAnimation::animate(osg::Node* node, const SGPropertyNode* configNode,
|
|||||||
} else if (type == "knob") {
|
} else if (type == "knob") {
|
||||||
SGKnobAnimation animInst(configNode, modelRoot);
|
SGKnobAnimation animInst(configNode, modelRoot);
|
||||||
animInst.apply(node);
|
animInst.apply(node);
|
||||||
|
} else if (type == "slider") {
|
||||||
|
SGSliderAnimation animInst(configNode, modelRoot);
|
||||||
|
animInst.apply(node);
|
||||||
} else if (type == "range") {
|
} else if (type == "range") {
|
||||||
SGRangeAnimation animInst(configNode, modelRoot);
|
SGRangeAnimation animInst(configNode, modelRoot);
|
||||||
animInst.apply(node);
|
animInst.apply(node);
|
||||||
@ -645,22 +648,7 @@ SGTranslateAnimation::SGTranslateAnimation(const SGPropertyNode* configNode,
|
|||||||
else
|
else
|
||||||
_initialValue = 0;
|
_initialValue = 0;
|
||||||
|
|
||||||
if (configNode->hasValue("axis/x1-m")) {
|
_axis = readTranslateAxis(configNode);
|
||||||
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);
|
|
||||||
_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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Group*
|
osg::Group*
|
||||||
@ -876,6 +864,30 @@ void readRotationCenterAndAxis(const SGPropertyNode* configNode, SGVec3d& center
|
|||||||
center[2] = configNode->getDoubleValue("center/z-m", center[2]);
|
center[2] = configNode->getDoubleValue("center/z-m", center[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SGVec3d readTranslateAxis(const SGPropertyNode* configNode)
|
||||||
|
{
|
||||||
|
SGVec3d axis;
|
||||||
|
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
|
||||||
|
return axis;
|
||||||
|
}
|
||||||
|
|
||||||
SGRotateAnimation::SGRotateAnimation(const SGPropertyNode* configNode,
|
SGRotateAnimation::SGRotateAnimation(const SGPropertyNode* configNode,
|
||||||
SGPropertyNode* modelRoot) :
|
SGPropertyNode* modelRoot) :
|
||||||
SGAnimation(configNode, modelRoot)
|
SGAnimation(configNode, modelRoot)
|
||||||
|
@ -36,6 +36,7 @@ read_value(const SGPropertyNode* configNode, SGPropertyNode* modelRoot,
|
|||||||
const char* unit, double defMin, double defMax);
|
const char* unit, double defMin, double defMax);
|
||||||
|
|
||||||
void readRotationCenterAndAxis(const SGPropertyNode* configNode, SGVec3d& center, SGVec3d& axis);
|
void readRotationCenterAndAxis(const SGPropertyNode* configNode, SGVec3d& center, SGVec3d& axis);
|
||||||
|
SGVec3d readTranslateAxis(const SGPropertyNode* configNode);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// Base class for animation installers
|
// Base class for animation installers
|
||||||
|
@ -54,9 +54,10 @@ public:
|
|||||||
virtual bool buttonPressed(int button, const osgGA::GUIEventAdapter* event, const Info& info)
|
virtual bool buttonPressed(int button, const osgGA::GUIEventAdapter* event, const Info& info)
|
||||||
{ return false; }
|
{ return false; }
|
||||||
|
|
||||||
virtual void update(double dt)
|
virtual void update(double dt, int keyModState)
|
||||||
{ }
|
{ }
|
||||||
virtual void buttonReleased(void)
|
|
||||||
|
virtual void buttonReleased(int keyModState)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual void mouseMoved(const osgGA::GUIEventAdapter* event)
|
virtual void mouseMoved(const osgGA::GUIEventAdapter* event)
|
||||||
|
Loading…
Reference in New Issue
Block a user