comparison engine/core/view/camera.h @ 0:4a0efb7baf70

* Datasets becomes the new trunk and retires after that :-)
author mvbarracuda@33b003aa-7bff-0310-803a-e67f0ece8222
date Sun, 29 Jun 2008 18:44:17 +0000
parents
children 40a7c9618ade
comparison
equal deleted inserted replaced
-1:000000000000 0:4a0efb7baf70
1 /***************************************************************************
2 * Copyright (C) 2005-2008 by the FIFE team *
3 * http://www.fifengine.de *
4 * This file is part of FIFE. *
5 * *
6 * FIFE is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
20 ***************************************************************************/
21
22 #ifndef FIFE_VIEW_CAMERA_H
23 #define FIFE_VIEW_CAMERA_H
24
25 // Standard C++ library includes
26 #include <string>
27
28 // 3rd party library includes
29
30 // FIFE includes
31 // These includes are split up in two parts, separated by one empty line
32 // First block: files included from the FIFE root src directory
33 // Second block: files included from the same folder
34 #include "model/structures/location.h"
35 #include "util/math/matrix.h"
36 #include "util/structures/rect.h"
37
38 #include "rendererbase.h"
39
40 namespace FIFE {
41
42 typedef Point3D ScreenPoint;
43 class Layer;
44 class Instance;
45 class ImagePool;
46 class AnimationPool;
47 class RenderBackend;
48 typedef std::map<Layer*, std::vector<Instance*> > t_layer_to_instances;
49
50 /** Camera describes properties of a view port shown in the main screen
51 * Main screen can have multiple cameras active simultanously
52 * Different cameras can have different properties, like location
53 * to shoot, zoom or tilt
54 */
55 class Camera: public IRendererListener, public IRendererContainer {
56 public:
57 /** Constructor
58 * Camera needs to be added to the view. If not done so, it is not rendered.
59 * @param id identifier for the camera
60 * @param layer layer where camera is bind. Camera is bind to a layer for two reasons:
61 * * camera's scaling is done based on cell image dimensions. Cell image is layer based (@see setCellImageDimensions)
62 * * camera could be bind to a pather, which operates on layer
63 * @param viewport used viewport for the camera. Viewport is measured in pixels in relation to game main screen
64 * @param emc coordinate, where camera is focused on given layer
65 * @param renderbackend to use with rendering
66 * @param ipool to use with rendering
67 * @param apool to use with rendering
68 */
69 Camera(const std::string& id,
70 Layer* layer,
71 Rect viewport,
72 ExactModelCoordinate emc,
73 RenderBackend* renderbackend,
74 ImagePool* ipool,
75 AnimationPool* apool);
76
77 /** Destructor
78 */
79 virtual ~Camera();
80
81 /** Gets the identifier for this camera.
82 */
83 const std::string& getId() { return m_id; }
84
85 /** Sets tilt for the camera.
86 * e.g. overhead camera has tilt 0, while traditional isometric camera has tilt 45
87 * @param tilt tilt for the camera
88 */
89 void setTilt(double tilt);
90
91 /** Gets camera tilt
92 * @return tilt of camera
93 */
94 double getTilt() const;
95
96 /** Sets rotation for the camera.
97 * Rotation can be visualized by thinking camera that rotates around an object
98 * that it is rendering
99 * @param rotation rotation for the camera
100 */
101 void setRotation(double rotation);
102
103 /** Gets camera rotation
104 * @return rotation of the camera
105 */
106 double getRotation() const;
107
108 /** Sets zoom for the camera.
109 * @param zoom zoom for the camera
110 */
111 void setZoom(double zoom);
112
113 /** Gets camera zoom
114 * @return zoom of the camera
115 */
116 double getZoom() const;
117
118 /** Sets screen cell image dimensions.
119 * Cell image dimension is basically width and height of a bitmap, that covers
120 * one cell in the layer where camera is bind
121 * @return Point Point containing x=width and y=height
122 */
123 void setCellImageDimensions(unsigned int width, unsigned int height);
124
125 /** Gets screen cell image dimensions.
126 * @see setCellImageDimensions
127 * @return Point containing x=width and y=height
128 */
129 Point getCellImageDimensions();
130
131 /** Gets screen cell image dimensions for given layer.
132 * @return Point Point containing x=width and y=height
133 */
134 Point getCellImageDimensions(Layer* layer);
135
136 /** Sets the location for camera
137 * @param location location (center point) to render
138 */
139 void setLocation(const Location& location);
140
141 /** Gets the location camera is rendering
142 * @return camera location
143 */
144 Location getLocation() const;
145
146 /** Gets a reference to the camera location
147 * @note if you change returned location without calling Camera::setLocation(...),
148 * remember to call Camera::refresh() (otherwise camera transforms are not updated)
149 * @return reference to the camera location
150 */
151 Location& getLocationRef();
152
153 /** Attaches the camera to an instance.
154 * @param instance Instance to which the camera shall be attached
155 * @note The camera can only be attached to an instance at the same layer!
156 */
157 void attach(Instance *instance);
158
159 /** Detaches the camera from an instance.
160 */
161 void detach();
162
163 /** Returns instance where camera is attached. NULL if not attached
164 */
165 bool getAttached() const { return m_attachedto; }
166
167 /** Sets the viewport for camera
168 * viewport is rectangle inside the view where camera renders
169 * @param viewport area for camera render
170 */
171 void setViewPort(const Rect& viewport);
172
173 /** Gets the viewport for camera
174 * @return camera viewport
175 */
176 const Rect& getViewPort() const;
177
178 /** Transforms given point from screen coordinates to map coordinates
179 * @param screen_coords screen coordinates to transform
180 * @param z_calculated if true, z-value (depth cut point) is pre-calculated. If false, camera calculates it
181 * @return point in map coordinates
182 */
183 ExactModelCoordinate toMapCoordinates(ScreenPoint screen_coords, bool z_calculated=true);
184
185 /** Transforms given point from map coordinates to screen coordinates
186 * @return point in screen coordinates
187 */
188 ScreenPoint toScreenCoordinates(ExactModelCoordinate map_coords);
189
190 /** Sets camera enabled / disabled
191 */
192 void setEnabled(bool enabled);
193
194 /** Gets if camera is enabled / disabled
195 */
196 bool isEnabled();
197
198 /** Gets angle of vector defined by given locations and camera properties (e.g. rotation)
199 * @return angle in polar coordinates
200 */
201 inline int getAngleBetween(const Location& loc1, const Location& loc2) {
202 static const double VECTOR_MULTIP = 100000.0;
203 ExactModelCoordinate c1 = loc1.getMapCoordinates();
204 ExactModelCoordinate c2 = loc2.getMapCoordinates();
205 ExactModelCoordinate cd((c2.x - c1.x) * VECTOR_MULTIP, (c2.y - c1.y) * VECTOR_MULTIP, 0);
206 c2.x = c1.x + cd.x;
207 c2.y = c1.y + cd.y;
208 ScreenPoint pt1 = this->toScreenCoordinates(c1);
209 ScreenPoint pt2 = this->toScreenCoordinates(c2);
210 double dy = (pt2.y - pt1.y);
211 double dx = (pt2.x - pt1.x);
212 int angle = static_cast<int>(atan2(-dy,dx)*(180.0/M_PI));
213 return angle;
214 }
215
216 /** Returns instances that match given screen coordinate
217 * @param screen_coords screen coordinates to be used for hit search
218 * @param layer layer to use for search
219 * @param instances list of instances that is filled based on hit test results
220 */
221 void getMatchingInstances(ScreenPoint screen_coords, Layer& layer, std::list<Instance*>& instances);
222
223 /** Returns instances that match given location. Instances are sorted based on camera view, so that "topmost"
224 * instance is first in returned list
225 * @param loc location where to fetch instances from
226 * @param instances list of instances that is filled based on hit test results
227 * @param use_exactcoordinates if true, comparison is done using exact coordinates. if not, cell coordinates are used
228 */
229 void getMatchingInstances(Location& loc, std::list<Instance*>& instances, bool use_exactcoordinates=false);
230
231 /** General update routine.
232 * In this function, the camera's position gets updated when its attached
233 * to another instance.
234 * @note call this only once in engine update cycle, so that tracking between
235 * current position and previous position keeps in sync. This information
236 * is used e.g. by view to fix the pixel wobbling problem
237 */
238 void update();
239
240 /** Refreshes camera view in case e.g. location is updated directly (not via setLocation)
241 * @note calling this function marks camera as "warped", therefore it causes all instance
242 * positions to be recalculated. If you constantly call this, you end up with pixel wobbling
243 * effect when camera is moved.
244 */
245 void refresh();
246
247 /** Returns latest camera movement in screen coordinates (dx, dy)
248 */
249 inline ScreenPoint getLatestMovement() {
250 return m_prev_origo - m_cur_origo;
251 }
252
253 /** Resets temporary values from last update round, like warped flag
254 */
255 void resetUpdates();
256
257 /** Adds new renderer on the view. Ownership is transferred to the camera.
258 */
259 void addRenderer(RendererBase* renderer);
260
261 /** Gets renderer with given name
262 */
263 RendererBase* getRenderer(const std::string& name);
264
265 /** resets active layer information on all renderers.
266 */
267 void resetRenderers();
268
269 /** calculates z-value for given screenpoint
270 */
271 void calculateZValue(ScreenPoint& screen_coords);
272
273 void onRendererPipelinePositionChanged(RendererBase* renderer);
274 void onRendererEnabledChanged(RendererBase* renderer);
275
276 /** Renders camera
277 */
278 void render();
279
280 private:
281 std::string m_id;
282
283 /** Updates the camera transformation matrix T with requested values.
284 * The requests are done using these functions :
285 * - setLocation
286 * - setRotation
287 * - setTilt
288 */
289 void updateMatrices();
290
291 /** Updates camera reference scale
292 * Reference scale is in a sense an internal zooming factor,
293 * which adjusts cell dimensions in logical space to ones shown on
294 * screen. Calculation is based on current camera properties (e.g. rotation)
295 * + given cell image dimensions for camera's layer
296 */
297 void updateReferenceScale();
298
299 /** Gets logical cell image dimensions for given layer
300 */
301 DoublePoint getLogicalCellDimensions(Layer* layer);
302
303 DoubleMatrix m_matrix;
304 DoubleMatrix m_inverse_matrix;
305 double m_tilt;
306 double m_rotation;
307 double m_zoom;
308 Location m_location;
309 ScreenPoint m_prev_origo;
310 ScreenPoint m_cur_origo;
311 Rect m_viewport;
312 bool m_view_updated;
313 unsigned int m_screen_cell_width;
314 unsigned int m_screen_cell_height;
315 double m_reference_scale;
316 bool m_enabled;
317 Instance* m_attachedto;
318 // caches calculated image dimensions for already queried & calculated layers
319 std::map<Layer*, Point> m_image_dimensions;
320 bool m_iswarped;
321
322 // list of renderers managed by the view
323 std::map<std::string, RendererBase*> m_renderers;
324 std::list<RendererBase*> m_pipeline;
325 bool m_updated; // false, if view has never been updated before
326
327 RenderBackend* m_renderbackend;
328 ImagePool* m_ipool;
329 AnimationPool* m_apool;
330
331 // caches layer -> instances structure between renders e.g. to fast query of mouse picking order
332 t_layer_to_instances m_layer_to_instances;
333 };
334 }
335 #endif