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_render_client/camera.h"
00031 #include "rve_render_client/scene.h"
00032 #include "rve_render_client/perspective_projection_factory.h"
00033
00034 #include <rve_interfaces/Camera.h>
00035 #include <rve_common/eigen_conversions.h>
00036
00037 #include <boost/bind.hpp>
00038
00039 #include <Eigen/Geometry>
00040
00041 using namespace rve_common;
00042
00043 namespace rve_render_client
00044 {
00045
00046 CameraPtr createCamera(Scene* scene)
00047 {
00048 CameraPtr cam(new Camera, destroySceneObject);
00049 scene->addObject(cam.get());
00050 return cam;
00051 }
00052
00053 Camera::Camera()
00054 : scene_(0)
00055 {
00056 orientation_.w = 1.0;
00057 proxy_index_ = addProxy("camera");
00058 setProjectionMatrixFactory( ProjectionMatrixFactoryPtr( new PerspectiveProjectionFactory() ));
00059 }
00060
00061 Camera::~Camera()
00062 {
00063
00064 }
00065
00066 void Camera::doCreate(ContextInfo& context)
00067 {
00068 ROS_ASSERT(!scene_ || context.scene == scene_);
00069 scene_ = context.scene;
00070
00071 rve_interfaces::CameraProxy* proxy = getProxy(context);
00072 const rve_common::UUID& scene_id = getSceneID(context.scene);
00073 proxy->create(scene_id, getID());
00074 proxy->setPosition(scene_id, getID(), position_);
00075 proxy->setOrientation(scene_id, getID(), orientation_);
00076 proxy->setProjectionMatrix(scene_id, getID(), projection_matrix_);
00077 }
00078
00079 void Camera::doDestroy(ContextInfo& context)
00080 {
00081 rve_interfaces::CameraProxy* proxy = getProxy(context);
00082 proxy->destroyAsync(getSceneID(context.scene), getID());
00083
00084 if (getContexts().empty())
00085 {
00086 scene_ = 0;
00087 }
00088 }
00089
00090 rve_interfaces::CameraProxy* Camera::getProxy(const ContextInfo& context)
00091 {
00092 return SceneObject::getProxy<rve_interfaces::CameraProxy>(context, proxy_index_);
00093 }
00094
00095 #define CAMERA_MULTIPLEX(func, ...) \
00096 multiplex<rve_interfaces::CameraProxy>(boost::bind(&rve_interfaces::CameraProxy::func, _1, _2, getID(), __VA_ARGS__), proxy_index_);
00097
00098 void Camera::setPosition(const rve_msgs::Vector3& pos)
00099 {
00100 position_ = pos;
00101 CAMERA_MULTIPLEX(setPositionAsync, pos);
00102 }
00103
00104 void Camera::setOrientation(const rve_msgs::Quaternion& orient)
00105 {
00106 orientation_ = orient;
00107 CAMERA_MULTIPLEX(setOrientationAsync, orient);
00108 }
00109
00110 void Camera::setDirection(const rve_msgs::Vector3& d)
00111 {
00112 Eigen::Vector3f dir(msgToEigen(d));
00113 if (dir.isZero())
00114 {
00115 return;
00116 }
00117
00118 Eigen::Quaternionf orient;
00119 orient.setFromTwoVectors(Eigen::Vector3f::UnitX(), dir);
00120 setOrientation(eigenToMsg(orient));
00121 }
00122
00123 void Camera::lookAt(const rve_msgs::Vector3& point)
00124 {
00125 Eigen::Vector3f dir = msgToEigen(point) - msgToEigen(position_);
00126 setDirection(eigenToMsg(dir));
00127 }
00128
00129 void Camera::move(const rve_msgs::Vector3& v)
00130 {
00131 Eigen::Vector3f vec(msgToEigen(v));
00132 Eigen::Vector3f pos(msgToEigen(position_));
00133
00134 pos = pos + vec;
00135 setPosition(eigenToMsg(pos));
00136 }
00137
00138 void Camera::moveRelative(const rve_msgs::Vector3& v)
00139 {
00140 Eigen::Vector3f vec(msgToEigen(v));
00141 Eigen::Vector3f pos(msgToEigen(position_));
00142 Eigen::Quaternionf orient(msgToEigen(orientation_));
00143
00144 pos = pos + (orient * vec);
00145 setPosition(eigenToMsg(pos));
00146 }
00147
00148 void Camera::rotate(const rve_msgs::Quaternion& q)
00149 {
00150
00151 Eigen::Quaternionf qnorm(msgToEigen(q));
00152 qnorm.normalize();
00153 Eigen::Quaternionf orient = msgToEigen(orientation_) * qnorm;
00154 setOrientation(eigenToMsg(orient));
00155 }
00156
00157 void Camera::setTransform(const rve_msgs::Vector3& pos, const rve_msgs::Quaternion& orient)
00158 {
00159 setPosition(pos);
00160 setOrientation(orient);
00161 }
00162
00163 void Camera::setProjectionMatrix(const rve_msgs::Matrix4& matrix)
00164 {
00165 projection_matrix_ = matrix;
00166 CAMERA_MULTIPLEX(setProjectionMatrixAsync, matrix);
00167 }
00168
00169 void Camera::setProjectionMatrixFactory(const ProjectionMatrixFactoryPtr& factory)
00170 {
00171 projection_matrix_factory_ = factory;
00172 if( projection_matrix_factory_ )
00173 {
00174 projection_matrix_factory_->setAspectRatio( aspect_ratio_ );
00175 projection_matrix_factory_->setCamera( this );
00176 }
00177 }
00178
00179 void Camera::setAspectRatio( float width_over_height )
00180 {
00181 aspect_ratio_ = width_over_height;
00182 if( projection_matrix_factory_ )
00183 {
00184 projection_matrix_factory_->setAspectRatio( aspect_ratio_ );
00185 }
00186 }
00187
00188 }