Mercurial > fife-parpg
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 |