00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <QStringList>
00031
00032 #include <yaml-cpp/emitter.h>
00033 #include <yaml-cpp/node.h>
00034
00035 #include "rviz/properties/quaternion_property.h"
00036
00037 namespace rviz
00038 {
00039
00040 QuaternionProperty::QuaternionProperty( const QString& name,
00041 const Ogre::Quaternion& default_value,
00042 const QString& description,
00043 Property* parent,
00044 const char *changed_slot,
00045 QObject* receiver )
00046 : Property( name, QVariant(), description, parent, changed_slot, receiver )
00047 , quaternion_( default_value )
00048 , ignore_child_updates_( false )
00049 {
00050 x_ = new Property( "X", quaternion_.x, "X coordinate", this );
00051 y_ = new Property( "Y", quaternion_.y, "Y coordinate", this );
00052 z_ = new Property( "Z", quaternion_.z, "Z coordinate", this );
00053 w_ = new Property( "W", quaternion_.w, "W coordinate", this );
00054 updateString();
00055 connect( x_, SIGNAL( aboutToChange() ), this, SLOT( emitAboutToChange() ));
00056 connect( y_, SIGNAL( aboutToChange() ), this, SLOT( emitAboutToChange() ));
00057 connect( z_, SIGNAL( aboutToChange() ), this, SLOT( emitAboutToChange() ));
00058 connect( w_, SIGNAL( aboutToChange() ), this, SLOT( emitAboutToChange() ));
00059 connect( x_, SIGNAL( changed() ), this, SLOT( updateFromChildren() ));
00060 connect( y_, SIGNAL( changed() ), this, SLOT( updateFromChildren() ));
00061 connect( z_, SIGNAL( changed() ), this, SLOT( updateFromChildren() ));
00062 connect( w_, SIGNAL( changed() ), this, SLOT( updateFromChildren() ));
00063 }
00064
00065 bool QuaternionProperty::setQuaternion( const Ogre::Quaternion& new_quaternion )
00066 {
00067 if( new_quaternion != quaternion_ ) {
00068 Q_EMIT aboutToChange();
00069 quaternion_ = new_quaternion;
00070 ignore_child_updates_ = true;
00071 x_->setValue( quaternion_.x );
00072 y_->setValue( quaternion_.y );
00073 z_->setValue( quaternion_.z );
00074 w_->setValue( quaternion_.w );
00075 ignore_child_updates_ = false;
00076 updateString();
00077 Q_EMIT changed();
00078 return true;
00079 }
00080 return false;
00081 }
00082
00083 bool QuaternionProperty::setValue( const QVariant& new_value )
00084 {
00085 QStringList strings = new_value.toString().split( ';' );
00086 if( strings.size() >= 4 )
00087 {
00088 bool x_ok = true;
00089 float x = strings[ 0 ].toFloat( &x_ok );
00090 bool y_ok = true;
00091 float y = strings[ 1 ].toFloat( &y_ok );
00092 bool z_ok = true;
00093 float z = strings[ 2 ].toFloat( &z_ok );
00094 bool w_ok = true;
00095 float w = strings[ 3 ].toFloat( &w_ok );
00096 if( x_ok && y_ok && z_ok && w_ok )
00097 {
00098 return setQuaternion( Ogre::Quaternion( w, x, y, z ));
00099 }
00100 }
00101 return false;
00102 }
00103
00104 void QuaternionProperty::updateFromChildren()
00105 {
00106 if( !ignore_child_updates_ )
00107 {
00108 quaternion_.x = x_->getValue().toFloat();
00109 quaternion_.y = y_->getValue().toFloat();
00110 quaternion_.z = z_->getValue().toFloat();
00111 quaternion_.w = w_->getValue().toFloat();
00112 updateString();
00113 Q_EMIT changed();
00114 }
00115 }
00116
00117 void QuaternionProperty::emitAboutToChange()
00118 {
00119 if( !ignore_child_updates_ )
00120 {
00121 Q_EMIT aboutToChange();
00122 }
00123 }
00124
00125 void QuaternionProperty::updateString()
00126 {
00127 value_ = QString( "%1; %2; %3; %4" )
00128 .arg( quaternion_.x, 0, 'g', 5 )
00129 .arg( quaternion_.y, 0, 'g', 5 )
00130 .arg( quaternion_.z, 0, 'g', 5 )
00131 .arg( quaternion_.w, 0, 'g', 5 );
00132 }
00133
00134 void QuaternionProperty::load( const YAML::Node& yaml_node )
00135 {
00136 float x, y, z, w;
00137 yaml_node[ "X" ] >> x;
00138 yaml_node[ "Y" ] >> y;
00139 yaml_node[ "Z" ] >> z;
00140 yaml_node[ "W" ] >> w;
00141 setQuaternion( Ogre::Quaternion( w, x, y, z ));
00142 }
00143
00144 void QuaternionProperty::save( YAML::Emitter& emitter )
00145 {
00146 emitter << YAML::Flow;
00147 emitter << YAML::BeginMap;
00148 emitter << YAML::Key << "X" << YAML::Value;
00149 x_->save( emitter );
00150 emitter << YAML::Key << "Y" << YAML::Value;
00151 y_->save( emitter );
00152 emitter << YAML::Key << "Z" << YAML::Value;
00153 z_->save( emitter );
00154 emitter << YAML::Key << "W" << YAML::Value;
00155 w_->save( emitter );
00156 emitter << YAML::EndMap;
00157 }
00158
00159 void QuaternionProperty::setReadOnly( bool read_only )
00160 {
00161 Property::setReadOnly( read_only );
00162 x_->setReadOnly( read_only );
00163 y_->setReadOnly( read_only );
00164 z_->setReadOnly( read_only );
00165 w_->setReadOnly( read_only );
00166 }
00167
00168
00169 }