orbit_view_controller.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009, 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 <stdint.h>
31 
32 #include <OgreCamera.h>
33 #include <OgreQuaternion.h>
34 #include <OgreSceneManager.h>
35 #include <OgreSceneNode.h>
36 #include <OgreVector3.h>
37 #include <OgreViewport.h>
38 
39 #include "rviz/display_context.h"
40 #include "rviz/geometry.h"
47 #include "rviz/load_resource.h"
48 #include "rviz/render_panel.h"
49 
51 
52 static const float PITCH_START = Ogre::Math::HALF_PI / 2.0;
53 static const float YAW_START = Ogre::Math::HALF_PI * 0.5;
54 static const float DISTANCE_START = 10;
55 static const float FOCAL_SHAPE_SIZE_START = 0.05;
56 static const bool FOCAL_SHAPE_FIXED_SIZE = true;
57 
58 namespace rviz
59 {
61 {
63  new FloatProperty("Distance", DISTANCE_START, "Distance from the focal point.", this);
64  distance_property_->setMin(0.001);
65 
67  new FloatProperty("Focal Shape Size", FOCAL_SHAPE_SIZE_START, "Focal shape size.", this);
69 
71  new BoolProperty("Focal Shape Fixed Size", FOCAL_SHAPE_FIXED_SIZE, "Focal shape size.", this);
72 
74  new FloatProperty("Yaw", YAW_START, "Rotation of the camera around the Z (up) axis.", this);
75 
77  new FloatProperty("Pitch", PITCH_START, "How much the camera is tipped downward.", this);
78  pitch_property_->setMax(Ogre::Math::HALF_PI - 0.001);
80 
81  focal_point_property_ = new VectorProperty("Focal Point", Ogre::Vector3::ZERO,
82  "The center point which the camera orbits.", this);
83 }
84 
86 {
88 
89  camera_->setProjectionType(Ogre::PT_PERSPECTIVE);
90 
93  focal_shape_->setColor(1.0f, 1.0f, 0.0f, 0.5f);
94  focal_shape_->getRootNode()->setVisible(false);
95 }
96 
98 {
99  delete focal_shape_;
100 }
101 
103 {
104  dragging_ = false;
111  focal_point_property_->setVector(Ogre::Vector3::ZERO);
112 }
113 
115 {
116  if (event.shift())
117  {
118  setStatus(
119  "<b>Left-Click:</b> Move X/Y. <b>Right-Click:</b>: Move Z. <b>Mouse Wheel:</b>: Zoom. ");
120  }
121  else
122  {
123  setStatus("<b>Left-Click:</b> Rotate. <b>Middle-Click:</b> Move X/Y. <b>Right-Click/Mouse "
124  "Wheel:</b>: Zoom. <b>Shift</b>: More options.");
125  }
126 
127  float distance = distance_property_->getFloat();
129 
130  int32_t diff_x = 0;
131  int32_t diff_y = 0;
132 
133  bool moved = false;
134 
135  if (event.type == QEvent::MouseButtonPress)
136  {
137  focal_shape_->getRootNode()->setVisible(true);
138  moved = true;
139  dragging_ = true;
140  }
141  else if (event.type == QEvent::MouseButtonRelease)
142  {
143  focal_shape_->getRootNode()->setVisible(false);
144  moved = true;
145  dragging_ = false;
146  }
147  else if (dragging_ && event.type == QEvent::MouseMove)
148  {
149  diff_x = event.x - event.last_x;
150  diff_y = event.y - event.last_y;
151  moved = true;
152  }
153 
154  // regular left-button drag
155  if (event.left() && !event.shift())
156  {
158  yaw(diff_x * 0.005);
159  pitch(-diff_y * 0.005);
160  }
161  // middle or shift-left drag
162  else if (event.middle() || (event.shift() && event.left()))
163  {
164  setCursor(MoveXY);
165  float fovY = camera_->getFOVy().valueRadians();
166  float fovX = 2.0f * atan(tan(fovY / 2.0f) * camera_->getAspectRatio());
167 
168  int width = camera_->getViewport()->getActualWidth();
169  int height = camera_->getViewport()->getActualHeight();
170 
171  move(-((float)diff_x / (float)width) * distance * tan(fovX / 2.0f) * 2.0f,
172  ((float)diff_y / (float)height) * distance * tan(fovY / 2.0f) * 2.0f, 0.0f);
173  }
174  else if (event.right())
175  {
176  if (event.shift())
177  {
178  // move in z direction
179  setCursor(MoveZ);
180  move(0.0f, 0.0f, diff_y * 0.1 * (distance / 10.0f));
181  }
182  else
183  {
184  // zoom
185  setCursor(Zoom);
186  zoom(-diff_y * 0.1 * (distance / 10.0f));
187  }
188  }
189  else
190  {
191  setCursor(event.shift() ? MoveXY : Rotate3D);
192  }
193 
194  moved = true;
195 
196  if (event.wheel_delta != 0)
197  {
198  int diff = event.wheel_delta;
199  if (event.shift())
200  {
201  move(0, 0, -diff * 0.001 * distance);
202  }
203  else
204  {
205  zoom(diff * 0.001 * distance);
206  }
207 
208  moved = true;
209  }
210 
211  if (moved)
212  {
214  }
215 }
216 
218 {
220 
221  Ogre::Camera* source_camera = source_view->getCamera();
222  Ogre::Vector3 position = source_camera->getPosition();
223  Ogre::Quaternion orientation = source_camera->getOrientation();
224 
225  if (source_view->getClassId() == "rviz/Orbit")
226  {
227  // If I'm initializing from another instance of this same class, get the distance exactly.
228  distance_property_->setFloat(source_view->subProp("Distance")->getValue().toFloat());
230  }
231  else
232  {
233  // Determine the distance from here to the reference frame, and use
234  // that as the distance our focal point should be at.
235  distance_property_->setFloat(position.length());
237  }
238 
239  Ogre::Vector3 direction =
240  orientation * (Ogre::Vector3::NEGATIVE_UNIT_Z * distance_property_->getFloat());
241  focal_point_property_->setVector(position + direction);
242 
244 }
245 
246 void OrbitViewController::update(float dt, float ros_dt)
247 {
249  updateCamera();
250 }
251 
252 void OrbitViewController::lookAt(const Ogre::Vector3& point)
253 {
254  Ogre::Vector3 camera_position = camera_->getPosition();
255  focal_point_property_->setVector(target_scene_node_->getOrientation().Inverse() *
256  (point - target_scene_node_->getPosition()));
257  distance_property_->setFloat(focal_point_property_->getVector().distance(camera_position));
259  calculatePitchYawFromPosition(camera_position);
260 }
261 
262 void OrbitViewController::onTargetFrameChanged(const Ogre::Vector3& old_reference_position,
263  const Ogre::Quaternion& /*old_reference_orientation*/)
264 {
265  focal_point_property_->add(old_reference_position - reference_position_);
266 }
267 
269 {
270  float distance = distance_property_->getFloat();
271  float yaw = yaw_property_->getFloat();
272  float pitch = pitch_property_->getFloat();
273  Ogre::Vector3 camera_z = Ogre::Vector3::UNIT_Z;
274 
275  // If requested, turn the world upside down.
276  if (this->invert_z_->getBool())
277  {
278  yaw = -yaw;
279  pitch = -pitch;
280  camera_z = -camera_z;
281  }
282 
283  Ogre::Vector3 focal_point = focal_point_property_->getVector();
284 
285  float x = distance * cos(yaw) * cos(pitch) + focal_point.x;
286  float y = distance * sin(yaw) * cos(pitch) + focal_point.y;
287  float z = distance * sin(pitch) + focal_point.z;
288 
289 
290  Ogre::Vector3 pos(x, y, z);
291 
292  camera_->setPosition(pos);
293  camera_->setFixedYawAxis(true, target_scene_node_->getOrientation() * camera_z);
294  camera_->setDirection(target_scene_node_->getOrientation() * (focal_point - pos));
295 
296  focal_shape_->setPosition(focal_point);
297 }
298 
299 void OrbitViewController::yaw(float angle)
300 {
302 }
303 
304 void OrbitViewController::pitch(float angle)
305 {
306  pitch_property_->add(-angle);
307 }
308 
309 void OrbitViewController::calculatePitchYawFromPosition(const Ogre::Vector3& position)
310 {
311  Ogre::Vector3 diff = position - focal_point_property_->getVector();
313  yaw_property_->setFloat(atan2(diff.y, diff.x));
314 }
315 
317 {
318  const double fshape_size(focal_shape_size_property_->getFloat());
319  double distance_property(distance_property_->getFloat());
321  distance_property = 1;
322 
323  focal_shape_->setScale(Ogre::Vector3(fshape_size * distance_property, fshape_size * distance_property,
324  fshape_size * distance_property / 5.0));
325 }
326 
327 void OrbitViewController::zoom(float amount)
328 {
329  distance_property_->add(-amount);
331 }
332 
333 void OrbitViewController::move(float x, float y, float z)
334 {
335  focal_point_property_->add(camera_->getOrientation() * Ogre::Vector3(x, y, z));
336 }
337 
338 } // end namespace rviz
339 
void setMin(float min)
FloatProperty * distance_property_
The camera&#39;s distance from the focal point.
void calculatePitchYawFromPosition(const Ogre::Vector3 &position)
Calculates pitch and yaw values given a new position and the current focal point. ...
void update(float dt, float ros_dt) override
Called at 30Hz by ViewManager::update() while this view is active. Override with code that needs to r...
void setMax(float max)
FloatProperty * pitch_property_
The camera&#39;s pitch (rotation around the x-axis), in radians.
void onTargetFrameChanged(const Ogre::Vector3 &old_reference_position, const Ogre::Quaternion &old_reference_orientation) override
Override to implement the change in properties which nullifies the change in target frame...
virtual bool setVector(const Ogre::Vector3 &vector)
f
static const float YAW_START
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:160
void mimic(ViewController *source_view) override
Configure the settings of this view controller to give, as much as possible, a similar view as that g...
void updateFocalShapeSize()
Calculates the focal shape size and update it&#39;s geometry.
void zoom(float amount)
Move in/out from the focal point, ie. adjust #distance_ by amount.
IMETHOD Vector diff(const Vector &p_w_a, const Vector &p_w_b, double dt=1)
void setCursor(CursorType cursor_type)
Ogre::Camera * getCamera() const
virtual Ogre::Vector3 getVector() const
BoolProperty * invert_z_
Ogre::Camera * camera_
Property specialized to enforce floating point max/min.
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:140
bool add(const Ogre::Vector3 &offset)
static const float YAW_START
virtual QString getClassId() const
Return the class identifier which was used to create this instance. This version just returns whateve...
float mapAngleTo0_2Pi(float angle)
Return the input angle mapped back to the range 0 to 2*PI.
Definition: geometry.cpp:64
BoolProperty * focal_shape_fixed_size_property_
Whether the focal shape size is fixed or not.
void onInitialize() override
Do subclass-specific initialization.
bool add(float delta)
Add the given delta to the property value.
static const bool FOCAL_SHAPE_FIXED_SIZE
bool setFloat(float new_value)
Float-typed "SLOT" version of setValue().
virtual Property * subProp(const QString &sub_name)
Return the first child Property with the given name, or the FailureProperty if no child has the name...
Definition: property.cpp:179
An orbital camera, controlled by yaw, pitch, distance, and focal point.
VectorProperty * focal_point_property_
The point around which the camera "orbits".
static const float FOCAL_SHAPE_SIZE_START
INLINE Rall1d< T, V, S > atan(const Rall1d< T, V, S > &x)
FloatProperty * focal_shape_size_property_
The focal shape size.
void handleMouseEvent(ViewportMouseEvent &evt) override
INLINE Rall1d< T, V, S > asin(const Rall1d< T, V, S > &x)
void lookAt(const Ogre::Vector3 &point) override
This should be implemented in each subclass to aim the camera at the given point in space (relative t...
void setStatus(const QString &message)
static const float PITCH_START
void update(float dt, float ros_dt) override
Called at 30Hz by ViewManager::update() while this view is active. Override with code that needs to r...
void onInitialize() override
Do subclass-specific initialization. Called by ViewController::initialize after context_, target_scene_node_, and camera_ are set.
void setPosition(const Ogre::Vector3 &position) override
Set the position of this object.
Definition: shape.cpp:150
virtual Ogre::SceneManager * getSceneManager() const =0
Returns the Ogre::SceneManager used for the main RenderPanel.
FloatProperty * yaw_property_
The camera&#39;s yaw (rotation around the y-axis), in radians.
virtual void queueRender()=0
Queues a render. Multiple calls before a render happens will only cause a single render.
Property specialized to provide getter for booleans.
Definition: bool_property.h:38
virtual float getFloat() const
INLINE Rall1d< T, V, S > atan2(const Rall1d< T, V, S > &y, const Rall1d< T, V, S > &x)
void mimic(ViewController *source_view) override
Configure the settings of this view controller to give, as much as possible, a similar view as that g...
virtual QVariant getValue() const
Return the value of this Property as a QVariant. If the value has never been set, an invalid QVariant...
Definition: property.cpp:150
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
INLINE Rall1d< T, V, S > tan(const Rall1d< T, V, S > &arg)
Ogre::SceneNode * getRootNode()
Get the root scene node (pivot node) for this object.
Definition: shape.h:100
virtual bool getBool() const
DisplayContext * context_
bool setBool(bool value)
Definition: bool_property.h:62
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
static const float DISTANCE_START
static const float PITCH_START
void move(float x, float y, float z)


rviz
Author(s): Dave Hershberger, David Gossow, Josh Faust
autogenerated on Sat May 27 2023 02:06:24