orbit_camera.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008, Willow Garage, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Willow Garage, Inc. nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include "orbit_camera.h"
31 #include "shape.h"
32 
33 #include <OgreCamera.h>
34 #include <OgreSceneManager.h>
35 #include <OgreSceneNode.h>
37 #include <OgreQuaternion.h>
38 #include <OgreViewport.h>
39 
40 #include <cmath>
41 #include <stdint.h>
42 
43 #include <sstream>
44 
45 #define MIN_DISTANCE 0.01
46 
47 namespace rviz
48 {
49 static const float PITCH_LIMIT_LOW = 0.001;
50 static const float PITCH_LIMIT_HIGH = Ogre::Math::PI - 0.001;
51 static const float YAW_START = Ogre::Math::PI; // - 0.001;
52 static const float PITCH_START = Ogre::Math::HALF_PI;
53 
54 OrbitCamera::OrbitCamera(Ogre::SceneManager* scene_manager)
55  : CameraBase(scene_manager)
56  , focal_point_(Ogre::Vector3::ZERO)
57  , yaw_(YAW_START)
58  , pitch_(PITCH_START)
59  , distance_(10.0f)
60 {
61  focal_point_object_ = new Shape(Shape::Sphere, scene_manager);
62  focal_point_object_->setScale(Ogre::Vector3(0.05f, 0.01f, 0.05f));
63  focal_point_object_->setColor(1.0f, 1.0f, 0.0f, 0.5f);
64  focal_point_object_->getRootNode()->setVisible(false);
65 
67 }
68 
70 {
71  delete focal_point_object_;
72 }
73 
75 {
76  if (pitch_ < PITCH_LIMIT_LOW)
77  {
79  }
80  else if (pitch_ > PITCH_LIMIT_HIGH)
81  {
83  }
84 }
85 
87 {
88  yaw_ = fmod(yaw_, Ogre::Math::TWO_PI);
89 
90  if (yaw_ < 0.0f)
91  {
92  yaw_ = Ogre::Math::TWO_PI + yaw_;
93  }
94 }
95 
97 {
98  Ogre::Vector3 global_focal_point = focal_point_;
99 
100  if (relative_node_)
101  {
102  global_focal_point = relative_node_->getOrientation() * focal_point_ + relative_node_->getPosition();
103  }
104 
105  return global_focal_point;
106 }
107 
109 {
110  Ogre::Vector3 global_focal_point = getGlobalFocalPoint();
111 
112  float x = distance_ * std::cos(yaw_) * std::sin(pitch_) + global_focal_point.x;
113  float y = distance_ * std::cos(pitch_) + global_focal_point.y;
114  float z = distance_ * std::sin(yaw_) * std::sin(pitch_) + global_focal_point.z;
115 
116  Ogre::Vector3 pos(x, y, z);
117 
118  if (relative_node_)
119  {
120  Ogre::Vector3 vec = pos - global_focal_point;
121  pos = relative_node_->getOrientation() * vec + global_focal_point;
122 
123  camera_->setFixedYawAxis(true, relative_node_->getOrientation() * Ogre::Vector3::UNIT_Y);
124  }
125 
126  camera_->setPosition(pos);
127  camera_->lookAt(global_focal_point);
128 
129  focal_point_object_->setPosition(global_focal_point);
130 }
131 
132 void OrbitCamera::yaw(float angle)
133 {
134  yaw_ += angle;
135 
136  normalizeYaw();
137 
138  update();
139 }
140 
141 void OrbitCamera::pitch(float angle)
142 {
143  pitch_ += angle;
144 
145  normalizePitch();
146 
147  update();
148 }
149 
150 void OrbitCamera::roll(float /*angle*/)
151 {
152 }
153 
155 {
156  return camera_->getPosition();
157 }
158 
159 Ogre::Quaternion OrbitCamera::getOrientation()
160 {
161  return camera_->getOrientation();
162 }
163 
164 void OrbitCamera::calculatePitchYawFromPosition(const Ogre::Vector3& position)
165 {
166  float x = position.x - focal_point_.x;
167  float y = position.y - focal_point_.y;
168  pitch_ = std::acos(y / distance_);
169 
170  normalizePitch();
171 
172  float val = x / (distance_ * std::sin(pitch_));
173 
174  yaw_ = std::acos(val);
175 
176  Ogre::Vector3 direction = focal_point_ - position;
177 
178  if (direction.dotProduct(Ogre::Vector3::NEGATIVE_UNIT_Z) < 0)
179  {
180  yaw_ = Ogre::Math::TWO_PI - yaw_;
181  }
182 }
183 
185 {
186  Ogre::Vector3 position = camera->getPosition();
187  Ogre::Quaternion orientation = camera->getOrientation();
188 
189  Ogre::Vector3 direction = orientation * (Ogre::Vector3::NEGATIVE_UNIT_Z * distance_);
190  focal_point_ = position + direction;
191 
193 
194  update();
195 }
196 
197 void OrbitCamera::setOrientation(float x, float y, float z, float w)
198 {
199  Ogre::Vector3 position = camera_->getPosition();
200  Ogre::Quaternion orientation(w, x, y, z);
201 
202  Ogre::Vector3 direction = orientation * (Ogre::Vector3::NEGATIVE_UNIT_Z * distance_);
203  focal_point_ = position + direction;
204 
206 
207  update();
208 }
209 
210 void OrbitCamera::zoom(float amount)
211 {
212  distance_ -= amount;
213 
214  if (distance_ <= MIN_DISTANCE)
215  {
217  }
218 
219  update();
220 }
221 
222 void OrbitCamera::setFocalPoint(const Ogre::Vector3& focal_point)
223 {
224  focal_point_ = focal_point;
225 
226  update();
227 }
228 
229 void OrbitCamera::move(float x, float y, float z)
230 {
231  Ogre::Quaternion orientation = camera_->getOrientation();
232 
233  if (relative_node_)
234  {
235  orientation = relative_node_->getOrientation().Inverse() * orientation;
236  }
237 
238  focal_point_ += orientation * Ogre::Vector3(x, y, z);
239 
240  update();
241 }
242 
243 void OrbitCamera::setPosition(float x, float y, float z)
244 {
245  Ogre::Vector3 pos(x, y, z);
246  distance_ = (pos - getGlobalFocalPoint()).length();
247 
248  calculatePitchYawFromPosition(Ogre::Vector3(x, y, z));
249 
250  update();
251 }
252 
253 void OrbitCamera::lookAt(const Ogre::Vector3& point)
254 {
255  Ogre::Vector3 focal_point = point;
256  Ogre::Vector3 camera_position = camera_->getPosition();
257 
258  if (relative_node_)
259  {
260  Ogre::Vector3 rel_pos = relative_node_->getPosition();
261  Ogre::Quaternion rel_orient = relative_node_->getOrientation();
262 
263  focal_point = rel_orient.Inverse() * (focal_point - rel_pos);
264  camera_position = rel_orient.Inverse() * (camera_position - rel_pos);
265  }
266 
267  distance_ = focal_point.distance(camera_position);
268  focal_point_ = focal_point;
269 
270  update();
271 }
272 
273 void OrbitCamera::mouseLeftDrag(int diff_x, int diff_y, bool /*ctrl*/, bool /*alt*/, bool /*shift*/)
274 {
275  yaw(diff_x * 0.005);
276  pitch(-diff_y * 0.005);
277 }
278 
279 void OrbitCamera::mouseMiddleDrag(int diff_x, int diff_y, bool /*ctrl*/, bool /*alt*/, bool /*shift*/)
280 {
281  float fovY = camera_->getFOVy().valueRadians();
282  float fovX = 2.0f * std::atan(std::tan(fovY / 2.0f) * camera_->getAspectRatio());
283 
284  int width = camera_->getViewport()->getActualWidth();
285  int height = camera_->getViewport()->getActualHeight();
286 
287  move(-((float)diff_x / (float)width) * distance_ * std::tan(fovX / 2.0f) * 2.0f,
288  ((float)diff_y / (float)height) * distance_ * std::tan(fovY / 2.0f) * 2.0f, 0.0f);
289 }
290 
291 void OrbitCamera::mouseRightDrag(int /*diff_x*/, int diff_y, bool /*ctrl*/, bool /*alt*/, bool shift)
292 {
293  if (shift)
294  {
295  move(0.0f, 0.0f, diff_y * 0.1 * (distance_ / 10.0f));
296  }
297  else
298  {
299  zoom(-diff_y * 0.1 * (distance_ / 10.0f));
300  }
301 }
302 
303 void OrbitCamera::scrollWheel(int diff, bool /*ctrl*/, bool /*alt*/, bool shift)
304 {
305  if (shift)
306  {
307  move(0.0f, 0.0f, -diff * 0.01 * (distance_ / 10.0f));
308  }
309  else
310  {
311  zoom(diff * 0.01 * (distance_ / 10.0f));
312  }
313 }
314 
315 void OrbitCamera::mouseLeftDown(int /*x*/, int /*y*/)
316 {
317  focal_point_object_->getRootNode()->setVisible(true);
318 }
319 
320 void OrbitCamera::mouseMiddleDown(int /*x*/, int /*y*/)
321 {
322  focal_point_object_->getRootNode()->setVisible(true);
323 }
324 
325 void OrbitCamera::mouseRightDown(int /*x*/, int /*y*/)
326 {
327  focal_point_object_->getRootNode()->setVisible(true);
328 }
329 
330 void OrbitCamera::mouseLeftUp(int /*x*/, int /*y*/)
331 {
332  focal_point_object_->getRootNode()->setVisible(false);
333 }
334 
335 void OrbitCamera::mouseMiddleUp(int /*x*/, int /*y*/)
336 {
337  focal_point_object_->getRootNode()->setVisible(false);
338 }
339 
340 void OrbitCamera::mouseRightUp(int /*x*/, int /*y*/)
341 {
342  focal_point_object_->getRootNode()->setVisible(false);
343 }
344 
345 void OrbitCamera::fromString(const std::string& str)
346 {
347  std::istringstream iss(str);
348 
349  iss >> pitch_;
350  iss.ignore();
351  iss >> yaw_;
352  iss.ignore();
353  iss >> distance_;
354  iss.ignore();
355  iss >> focal_point_.x;
356  iss.ignore();
357  iss >> focal_point_.y;
358  iss.ignore();
359  iss >> focal_point_.z;
360 
361  update();
362 }
363 
365 {
366  std::ostringstream oss;
367  oss << pitch_ << " " << yaw_ << " " << distance_ << " " << focal_point_.x << " " << focal_point_.y
368  << " " << focal_point_.z;
369 
370  return oss.str();
371 }
372 
373 } // namespace rviz
shape.h
rviz::OrbitCamera::yaw_
float yaw_
The camera's yaw (rotation around the y-axis), in radians.
Definition: orbit_camera.h:148
rviz::Shape::getRootNode
Ogre::SceneNode * getRootNode()
Get the root scene node (pivot node) for this object.
Definition: shape.h:100
rviz::OrbitCamera::getOrientation
Ogre::Quaternion getOrientation() override
Get the orientation of this camera.
Definition: orbit_camera.cpp:159
rviz::OrbitCamera::mouseRightDown
void mouseRightDown(int x, int y) override
Definition: orbit_camera.cpp:325
rviz::OrbitCamera::mouseMiddleDrag
void mouseMiddleDrag(int diff_x, int diff_y, bool ctrl, bool alt, bool shift) override
Handle a middle mouse button drag.
Definition: orbit_camera.cpp:279
Ogre
Definition: axes_display.h:35
rviz::Shape::setColor
void setColor(float r, float g, float b, float a) override
Set the color of the object. Values are in the range [0, 1].
Definition: shape.cpp:136
rviz::OrbitCamera::mouseLeftDrag
void mouseLeftDrag(int diff_x, int diff_y, bool ctrl, bool alt, bool shift) override
Handle a left mouse button drag.
Definition: orbit_camera.cpp:273
angle
TFSIMD_FORCE_INLINE tfScalar angle(const Quaternion &q1, const Quaternion &q2)
rviz::OrbitCamera::normalizeYaw
void normalizeYaw()
Normalizes the camera's yaw in the range [0, 2*pi)
Definition: orbit_camera.cpp:86
rviz::OrbitCamera::setOrientation
void setOrientation(float x, float y, float z, float w) override
Set the orientation of the camera from a quaternion.
Definition: orbit_camera.cpp:197
rviz::CameraBase::camera_
Ogre::Camera * camera_
Ogre camera associated with this camera object.
Definition: camera_base.h:236
rviz::OrbitCamera::lookAt
void lookAt(const Ogre::Vector3 &point) override
Point the camera at the specified point.
Definition: orbit_camera.cpp:253
rviz::CameraBase::relative_node_
Ogre::SceneNode * relative_node_
Definition: camera_base.h:239
rviz::OrbitCamera::getGlobalFocalPoint
Ogre::Vector3 getGlobalFocalPoint()
Definition: orbit_camera.cpp:96
rviz::OrbitCamera::setPosition
void setPosition(float x, float y, float z) override
Set the position of the camera.
Definition: orbit_camera.cpp:243
rviz::PITCH_START
static const float PITCH_START
Definition: orbit_camera.cpp:52
rviz::CameraBase
Generic interface for a camera.
Definition: camera_base.h:53
MIN_DISTANCE
#define MIN_DISTANCE
Definition: orbit_camera.cpp:45
rviz::OrbitCamera::setFocalPoint
void setFocalPoint(const Ogre::Vector3 &focal_point)
Set the focal point of the camera. Keeps the pitch/yaw/distance the same.
Definition: orbit_camera.cpp:222
rviz::OrbitCamera::move
void move(float x, float y, float z) override
Move the camera relative to its orientation.
Definition: orbit_camera.cpp:229
f
f
rviz::OrbitCamera::getPosition
Ogre::Vector3 getPosition() override
Get the position of this camera.
Definition: orbit_camera.cpp:154
rviz::OrbitCamera::zoom
void zoom(float amount)
Move in/out from the focal point, ie. adjust distance_ by amount.
Definition: orbit_camera.cpp:210
rviz::OrbitCamera::pitch
void pitch(float angle) override
Pitch the camera.
Definition: orbit_camera.cpp:141
orbit_camera.h
rviz::PITCH_LIMIT_HIGH
static const float PITCH_LIMIT_HIGH
Definition: orbit_camera.cpp:50
rviz
Definition: add_display_dialog.cpp:54
rviz::OrbitCamera::~OrbitCamera
~OrbitCamera() override
Definition: orbit_camera.cpp:69
Vector3
rviz::OrbitCamera::calculatePitchYawFromPosition
void calculatePitchYawFromPosition(const Ogre::Vector3 &position)
Calculates pitch and yaw values given a new position and the current focal point.
Definition: orbit_camera.cpp:164
ogre_vector.h
rviz::OrbitCamera::scrollWheel
void scrollWheel(int diff, bool ctrl, bool alt, bool shift) override
Handle a scrollwheel change.
Definition: orbit_camera.cpp:303
rviz::CameraBase::getOrientation
virtual Ogre::Quaternion getOrientation()=0
Get the orientation of this camera.
rviz::Shape::Sphere
@ Sphere
Definition: shape.h:59
rviz::PITCH_LIMIT_LOW
static const float PITCH_LIMIT_LOW
Definition: orbit_camera.cpp:49
rviz::OrbitCamera::mouseRightUp
void mouseRightUp(int x, int y) override
Definition: orbit_camera.cpp:340
rviz::OrbitCamera::focal_point_object_
Shape * focal_point_object_
Definition: orbit_camera.h:152
rviz::OrbitCamera::update
void update() override
Calculates the camera's position and orientation from the yaw, pitch, distance and focal point.
Definition: orbit_camera.cpp:108
rviz::OrbitCamera::pitch_
float pitch_
The camera's pitch (rotation around the x-axis), in radians.
Definition: orbit_camera.h:149
rviz::OrbitCamera::mouseMiddleDown
void mouseMiddleDown(int x, int y) override
Definition: orbit_camera.cpp:320
rviz::OrbitCamera::yaw
void yaw(float angle) override
Yaw the camera.
Definition: orbit_camera.cpp:132
length
TFSIMD_FORCE_INLINE tfScalar length(const Quaternion &q)
rviz::OrbitCamera::roll
void roll(float angle) override
Roll the camera.
Definition: orbit_camera.cpp:150
rviz::OrbitCamera::distance_
float distance_
The camera's distance from the focal point.
Definition: orbit_camera.h:150
rviz::Shape
Definition: shape.h:51
rviz::OrbitCamera::OrbitCamera
OrbitCamera(Ogre::SceneManager *scene_manager)
Definition: orbit_camera.cpp:54
rviz::OrbitCamera::mouseMiddleUp
void mouseMiddleUp(int x, int y) override
Definition: orbit_camera.cpp:335
rviz::Shape::setScale
void setScale(const Ogre::Vector3 &scale) override
Set the scale of the object. Always relative to the identity orientation of the object.
Definition: shape.cpp:156
rviz::OrbitCamera::focal_point_
Ogre::Vector3 focal_point_
The camera's focal point.
Definition: orbit_camera.h:147
rviz::OrbitCamera::toString
std::string toString() override
Returns a string representation of the camera's configuration.
Definition: orbit_camera.cpp:364
rviz::YAW_START
static const float YAW_START
Definition: orbit_camera.cpp:51
rviz::CameraBase::getPosition
virtual Ogre::Vector3 getPosition()=0
Get the position of this camera.
rviz::OrbitCamera::mouseRightDrag
void mouseRightDrag(int diff_x, int diff_y, bool ctrl, bool alt, bool shift) override
Handle a right mouse button drag.
Definition: orbit_camera.cpp:291
rviz::Shape::setPosition
void setPosition(const Ogre::Vector3 &position) override
Set the position of this object.
Definition: shape.cpp:146
rviz::OrbitCamera::mouseLeftDown
void mouseLeftDown(int x, int y) override
Definition: orbit_camera.cpp:315
rviz::OrbitCamera::fromString
void fromString(const std::string &str) override
Loads the camera's configure from the supplied string (generated through toString())
Definition: orbit_camera.cpp:345
rviz::OrbitCamera::normalizePitch
void normalizePitch()
Normalizes the camera's pitch, preventing it from reaching vertical (or turning upside down)
Definition: orbit_camera.cpp:74
rviz::OrbitCamera::mouseLeftUp
void mouseLeftUp(int x, int y) override
Definition: orbit_camera.cpp:330
rviz::OrbitCamera::setFrom
void setFrom(CameraBase *camera) override
Set the position/orientation of this camera from another camera.
Definition: orbit_camera.cpp:184


rviz
Author(s): Dave Hershberger, David Gossow, Josh Faust, William Woodall
autogenerated on Fri Aug 2 2024 08:43:10