Go to the documentation of this file.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 <rve_common_transformers/orbit_camera.h>
00031 #include <rve_transformer/transformer_manager.h>
00032 #include <rve_transformer/frame_manager.h>
00033 #include <rve_render_client/camera.h>
00034 #include <rve_render_client/perspective_projection_factory.h>
00035 #include <rve_properties/property_node.h>
00036
00037 #include <rve_msgs/MouseEvent.h>
00038
00039 #include <rve_common/eigen_conversions.h>
00040 #include <geometry_msgs/TransformStamped.h>
00041 #include <ros/callback_queue.h>
00042 #include <geometry_msgs/Pose.h>
00043
00044 #include <sys/time.h>
00045
00046 static const float MIN_DISTANCE = 0.01;
00047
00048 namespace rve_common_transformers
00049 {
00050
00051 OrbitCamera::OrbitCamera()
00052 : focal_point_(Eigen::Vector3f::Zero())
00053 , pitch_quat_(Eigen::Quaternionf::Identity())
00054 , yaw_quat_(Eigen::Quaternionf::Identity())
00055 , distance_(10.0f)
00056 , last_x_(-1)
00057 , last_y_(-1)
00058 , camera_projection_( new rve_render_client::PerspectiveProjectionFactory() )
00059 {
00060 setRelativePosition( Eigen::Vector3f( 0, 2, 2 ));
00061 }
00062
00063 void OrbitCamera::onInit()
00064 {
00065 addSubscriber("mouse_input", 100, &OrbitCamera::mouseCallback, this);
00066 addSubscriber("set_camera_pose", 1, &OrbitCamera::setPoseCallback, this);
00067
00068 std::string frame_id;
00069 getPropertyNode()->get(std::string("target_frame"), frame_id, std::string("map"));
00070 setReferenceFrame( frame_id );
00071 getPropertyNode()->addChangeCallback(boost::bind(&OrbitCamera::onPropertyChanged, this, _1, _2, _3), this, getCallbackQueue());
00072 }
00073
00074 void OrbitCamera::setPoseCallback(const geometry_msgs::PoseConstPtr& pose)
00075 {
00076
00077
00078
00079
00080 focal_point_.x() = pose->position.x;
00081 focal_point_.y() = pose->position.y;
00082 focal_point_.z() = pose->position.z;
00083
00084 }
00085
00086 void OrbitCamera::mouseCallback(const rve_msgs::MouseEventConstPtr& evt)
00087 {
00088 if (last_x_ == -1)
00089 {
00090 last_x_ = evt->x;
00091 last_y_ = evt->y;
00092 }
00093
00094 int32_t diff_x = evt->x - last_x_;
00095 int32_t diff_y = evt->y - last_y_;
00096 last_x_ = evt->x;
00097 last_y_ = evt->y;
00098
00099 if (evt->type == rve_msgs::MouseEvent::EVENT_MOVE)
00100 {
00101 if (evt->buttons & rve_msgs::MouseEvent::BUTTON_LEFT)
00102 {
00103 yaw( diff_x*0.005 );
00104 pitch( -diff_y*0.005 );
00105 }
00106 if (evt->buttons & rve_msgs::MouseEvent::BUTTON_MIDDLE)
00107 {
00108 rve_msgs::Matrix4 proj_mat = getCamera()->getProjectionMatrix();
00109 float proj_width = 2 / proj_mat.m[0*4+0];
00110 float proj_height = 2 / proj_mat.m[1*4+1];
00111
00112 uint32_t width = evt->window_width;
00113 uint32_t height = evt->window_height;
00114
00115 move(0.0, ((float)diff_x / (float)width) * distance_ * proj_width, ((float)diff_y / (float)height) * distance_ * proj_height);
00116 }
00117 if (evt->buttons & rve_msgs::MouseEvent::BUTTON_RIGHT)
00118 {
00119 if (evt->modifiers & rve_msgs::MouseEvent::MODIFIER_SHIFT)
00120 {
00121 move(-diff_y * 0.1 * (distance_ / 10.0f), 0.0f, 0.0f);
00122 }
00123 else
00124 {
00125 zoom( -diff_y * 0.1 * (distance_ / 10.0f) );
00126 }
00127 }
00128 }
00129 }
00130
00131 void OrbitCamera::onCameraSet()
00132 {
00133 FrameRelativeCameraController::onCameraSet();
00134 getCamera()->setProjectionMatrixFactory( camera_projection_ );
00135 }
00136
00137 void OrbitCamera::onPropertyChanged(const rve_properties::PropertyNodePtr& node, const std::string& path, rve_properties::PropertyChangeType type)
00138 {
00139 if (type != rve_properties::PropertyChanged)
00140 {
00141 return;
00142 }
00143
00144 if (path == "target_frame")
00145 {
00146 setReferenceFrame( node->get<std::string>() );
00147 }
00148 }
00149
00150 void OrbitCamera::updateRelativePose()
00151 {
00152 Eigen::Vector3f mouse_pos;
00153 Eigen::Quaternionf mouse_rot;
00154
00155 mouse_rot = yaw_quat_ * pitch_quat_;
00156 mouse_pos = focal_point_ - distance_ * (mouse_rot * Eigen::Vector3f::UnitX());
00157
00158 setRelativePosition( mouse_pos );
00159 setRelativeOrientation( mouse_rot );
00160 }
00161
00162 void OrbitCamera::yaw( float angle )
00163 {
00164 yaw_quat_ = yaw_quat_ * Eigen::AngleAxisf(-angle, Eigen::Vector3f::UnitZ());
00165 }
00166
00167 void OrbitCamera::pitch( float angle )
00168 {
00169 pitch_quat_ = pitch_quat_ * Eigen::AngleAxisf(-angle, Eigen::Vector3f::UnitY());
00170 }
00171
00172 void OrbitCamera::zoom( float amount )
00173 {
00174 distance_ -= amount;
00175
00176 if ( distance_ <= MIN_DISTANCE )
00177 {
00178 distance_ = MIN_DISTANCE;
00179 }
00180 }
00181
00182 void OrbitCamera::move( float x, float y, float z )
00183 {
00184 focal_point_ += getAbsoluteOrientation() * Eigen::Vector3f( x, y, z );
00185 }
00186
00187 }