FIFE
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
camera.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005-2013 by the FIFE team *
3  * http://www.fifengine.net *
4  * This file is part of FIFE. *
5  * *
6  * FIFE is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU Lesser General Public *
8  * License as published by the Free Software Foundation; either *
9  * version 2.1 of the License, or (at your option) any later version. *
10  * *
11  * This library 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 GNU *
14  * Lesser General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU Lesser General Public *
17  * License along with this library; if not, write to the *
18  * Free Software Foundation, Inc., *
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
20  ***************************************************************************/
21 
22 // Standard C++ library includes
23 
24 // 3rd party library includes
25 
26 // FIFE includes
27 // These includes are split up in two parts, separated by one empty line
28 // First block: files included from the FIFE root src directory
29 // Second block: files included from the same folder
30 
32 #include "model/metamodel/action.h"
34 #include "model/structures/map.h"
35 #include "model/structures/layer.h"
39 #include "util/log/logger.h"
40 #include "util/math/fife_math.h"
41 #include "util/math/angles.h"
42 #include "util/time/timemanager.h"
43 #include "video/renderbackend.h"
44 #include "video/image.h"
45 #include "video/animation.h"
46 #include "video/imagemanager.h"
47 
48 #include "camera.h"
49 #include "layercache.h"
50 #include "visual.h"
51 
52 
53 namespace FIFE {
54  static Logger _log(LM_CAMERA);
55 
56  class MapObserver : public MapChangeListener {
58 
59  public:
60  MapObserver(Camera* camera) {
61  m_camera = camera;
62  }
63  virtual ~MapObserver() {}
64 
65  virtual void onMapChanged(Map* map, std::vector<Layer*>& changedLayers) {
66  }
67 
68  virtual void onLayerCreate(Map* map, Layer* layer) {
69  m_camera->addLayer(layer);
70  }
71 
72  virtual void onLayerDelete(Map* map, Layer* layer) {
73  m_camera->removeLayer(layer);
74  }
75  };
76 
77  Camera::Camera(const std::string& id,
78  Layer *layer,
79  const Rect& viewport,
80  RenderBackend* renderbackend):
81  m_id(id),
82  m_matrix(),
83  m_inverse_matrix(),
84  m_tilt(0),
85  m_rotation(0),
86  m_zoom(1),
87  m_zToY(0),
88  m_enabledZToY(false),
89  m_location(),
90  m_cur_origo(ScreenPoint(0,0,0)),
91  m_viewport(),
92  m_mapViewPort(),
93  m_mapViewPortUpdated(false),
94  m_screen_cell_width(1),
95  m_screen_cell_height(1),
96  m_reference_scale(1),
97  m_enabled(true),
98  m_attachedto(NULL),
99  m_image_dimensions(),
100  m_transform(NoneTransform),
101  m_renderers(),
102  m_pipeline(),
103  m_updated(false),
104  m_renderbackend(renderbackend),
105  m_layer_to_instances(),
106  m_lighting(false),
107  m_light_colors(),
108  m_col_overlay(false),
109  m_img_overlay(false),
110  m_ani_overlay(false) {
111  m_viewport = viewport;
112  m_map_observer = new MapObserver(this);
113  m_map = 0;
114  Location location;
115  location.setLayer(layer);
116  setLocation(location);
117  }
118 
120  // Trigger removal of LayerCaches and MapObserver
121  updateMap(NULL);
122 
123  std::map<std::string, RendererBase*>::iterator r_it = m_renderers.begin();
124  for(; r_it != m_renderers.end(); ++r_it) {
125  r_it->second->reset();
126  delete r_it->second;
127  }
128  m_renderers.clear();
129  delete m_map_observer;
130  }
131 
132  void Camera::setTilt(double tilt) {
133  if (!Mathd::Equal(m_tilt, tilt)) {
135  m_tilt = tilt;
137  updateMatrices();
138  }
139  }
140 
141  double Camera::getTilt() const {
142  return m_tilt;
143  }
144 
145  void Camera::setRotation(double rotation) {
146  if (!Mathd::Equal(m_rotation, rotation)) {
148  m_rotation = rotation;
149  updateMatrices();
150  }
151  }
152 
153  double Camera::getRotation() const {
154  return m_rotation;
155  }
156 
157  void Camera::setZoom(double zoom) {
158  if (!Mathd::Equal(m_zoom, zoom)) {
160  m_zoom = zoom;
161  if (m_zoom < 0.001) {
162  m_zoom = 0.001;
163  }
164  updateMatrices();
165  }
166  }
167 
168  double Camera::getZoom() const {
169  return m_zoom;
170  }
171 
172  double Camera::getOriginalZToY() const {
173  DoubleMatrix matrix;
175  if (m_location.getLayer()) {
177  if (cg) {
180  }
181  }
182  matrix.applyRotate(-m_rotation, 0.0, 0.0, 1.0);
183  matrix.applyRotate(-m_tilt, 1.0, 0.0, 0.0);
184  return matrix.m9 * -1.0;
185  }
186 
187  void Camera::setZToY(double zToY) {
188  m_enabledZToY = true;
189  if (!Mathd::Equal(m_zToY, zToY)) {
191  m_zToY = zToY;
192  updateMatrices();
193  }
194  }
195 
196  double Camera::getZToY() const {
197  return m_zToY;
198  }
199 
200  void Camera::setZToYEnabled(bool enabled) {
201  m_enabledZToY = enabled;
202  }
203 
204  bool Camera::isZToYEnabled() const {
205  return m_enabledZToY;
206  }
207 
209  m_screen_cell_width = width;
210  m_screen_cell_height = height;
212  updateMatrices();
214  }
215 
216  void Camera::setLocation(const Location& location) {
217  if (m_location == location ) {
218  return;
219  }
220 
221  CellGrid* cell_grid = NULL;
222  if (location.getLayer()) {
223  cell_grid = location.getLayer()->getCellGrid();
224  } else {
225  throw Exception("Location without layer given to Camera::setLocation");
226  }
227  if (!cell_grid) {
228  throw Exception("Camera layer has no cellgrid specified");
229  }
230 
232  m_location = location;
233  updateMatrices();
234 
237 
238  // WARNING
239  // It is important that m_location is already set,
240  // as the updates which are triggered here
241  // need to calculate screen-coordinates
242  // which depend on m_location.
244  }
245 
246  void Camera::updateMap(Map* map) {
247  if(m_map == map) {
248  return;
249  }
250  if(m_map) {
252  const std::list<Layer*>& layers = m_map->getLayers();
253  for(std::list<Layer*>::const_iterator i = layers.begin(); i !=layers.end(); ++i) {
254  removeLayer(*i);
255  }
256  }
257  if(map) {
259  const std::list<Layer*>& layers = map->getLayers();
260  for(std::list<Layer*>::const_iterator i = layers.begin(); i !=layers.end(); ++i) {
261  addLayer(*i);
262  }
263  }
264  m_map = map;
265  }
266 
269  }
270 
272  if (layer == m_location.getLayer()) {
274  }
275  std::map<Layer*, Point>::iterator it = m_image_dimensions.find(layer);
276  if (it != m_image_dimensions.end()) {
277  return it->second;
278  }
279  Point p;
280  DoublePoint dimensions = getLogicalCellDimensions(layer);
281  p.x = static_cast<int32_t>(round(m_reference_scale * dimensions.x));
282  p.y = static_cast<int32_t>(round(m_reference_scale * dimensions.y));
283  m_image_dimensions[layer] = p;
284  return p;
285  }
286 
288  return m_location;
289  }
290 
292  return m_location;
293  }
294 
295  void Camera::setViewPort(const Rect& viewport) {
296  m_viewport = viewport;
297  }
298 
299  const Rect& Camera::getViewPort() const {
300  return m_viewport;
301  }
302 
304  if (!m_mapViewPortUpdated) {
309 
310  std::vector<ExactModelCoordinate> coords;
311  coords.push_back(toMapCoordinates(sp2, false));
312  coords.push_back(toMapCoordinates(sp3, false));
313  coords.push_back(toMapCoordinates(sp4, false));
314 
315  ExactModelCoordinate emc = toMapCoordinates(sp1, false);
316  ModelCoordinate min(static_cast<int32_t>(emc.x), static_cast<int32_t>(emc.y));
317  ModelCoordinate max(static_cast<int32_t>(emc.x+0.5), static_cast<int32_t>(emc.y+0.5));
318  std::vector<ExactModelCoordinate>::iterator it = coords.begin();
319  for (; it != coords.end(); ++it) {
320  min.x = std::min(min.x, static_cast<int32_t>((*it).x));
321  min.y = std::min(min.y, static_cast<int32_t>((*it).y));
322  max.x = std::max(max.x, static_cast<int32_t>((*it).x+0.5));
323  max.y = std::max(max.y, static_cast<int32_t>((*it).y+0.5));
324  }
325  // makes the viewport a bit larger
326  m_mapViewPort.x = min.x - 1;
327  m_mapViewPort.y = min.y - 1;
328  m_mapViewPort.w = ABS(max.x - min.x) + 2;
329  m_mapViewPort.h = ABS(max.y - min.y) + 2;
330  m_mapViewPortUpdated = true;
331  }
332 
333  return m_mapViewPort;
334  }
335 
337  Rect mapView = getMapViewPort();
338  Location loc(layer);
339  ExactModelCoordinate emc(mapView.x, mapView.y);
340  loc.setMapCoordinates(emc);
341  emc.x = mapView.x+mapView.w;
342  emc.y = mapView.y+mapView.h;
343  mapView.x = loc.getLayerCoordinates().x;
344  mapView.y = loc.getLayerCoordinates().y;
345  loc.setMapCoordinates(emc);
346  mapView.w = ABS(loc.getLayerCoordinates().x - mapView.x);
347  mapView.h = ABS(loc.getLayerCoordinates().y - mapView.y);
348 
349  return mapView;
350  }
351 
352  void Camera::setEnabled(bool enabled) {
353  m_enabled = enabled;
354  }
355 
357  return m_enabled;
358  }
359 
361  return m_cur_origo;
362  }
363 
365  double scale = m_reference_scale;
366  m_matrix.loadScale(scale, scale, scale);
367  m_vs_matrix.loadScale(scale,scale,scale);
368  if (m_location.getLayer()) {
370  if (cg) {
373  }
374  }
375  m_matrix.applyRotate(-m_rotation, 0.0, 0.0, 1.0);
376  m_matrix.applyRotate(-m_tilt, 1.0, 0.0, 0.0);
377  if (m_enabledZToY) {
378  m_matrix.m9 = -m_zToY; // z -> y height in pixels
379  }
380  scale = m_zoom;
381  m_matrix.applyScale(scale, scale, scale);
384 
385  m_vs_matrix.applyRotate(-m_rotation, 0.0, 0.0, 1.0);
386  m_vs_matrix.applyRotate(-m_tilt, 1.0, 0.0, 0.0);
387  if (m_enabledZToY) {
388  m_vs_matrix.m9 = -m_zToY; // z -> y height in pixels
389  }
391 
392  // calculate the screen<->virtual screen transformation
393  // this explicitly ignores the z-value.
395  // NOTE: mult4by4 is an in-place modification.
397  // set the z transformation to unity
398  const int32_t N=4;
399  for(int32_t i=0; i!=N; ++i) {
400  m_vscreen_2_screen[2*N + i] = 0;
401  m_vscreen_2_screen[i*N + 2] = 0;
402  }
403  m_vscreen_2_screen[2*N + 2] = 1;
405 
406  m_mapViewPortUpdated = false;
407  // FL_WARN(_log, LMsg("matrix: ") << m_matrix << " 1: " << m_matrix.inverse().mult4by4(m_matrix));
408 // FL_WARN(_log, LMsg("vs2s matrix: ") << m_vscreen_2_screen << " s2vs matrix: " << m_screen_2_vscreen);
409  }
410 
411  void Camera::calculateZValue(ScreenPoint& screen_coords) {
412  int32_t dy = -(screen_coords.y - toScreenCoordinates(m_location.getMapCoordinates()).y);
413  screen_coords.z = static_cast<int32_t>(Mathd::Tan(m_tilt * (Mathd::pi() / 180.0)) * static_cast<double>(dy));
414  }
415 
416  ExactModelCoordinate Camera::toMapCoordinates(ScreenPoint screen_coords, bool z_calculated) {
417  if (!z_calculated) {
418  calculateZValue(screen_coords);
419  }
420  return m_inverse_matrix * intPt2doublePt(screen_coords);
421  }
422 
424  ScreenPoint pt = doublePt2intPt(m_matrix * elevation_coords);
425  return pt;
426  }
427 
429  DoublePoint3D pt = (m_vs_matrix * elevation_coords);
430  return pt;
431  }
432 
435  }
436 
439  }
440 
442  assert(layer);
443  CellGrid* cg = layer->getCellGrid();
444  assert(cg);
445 
446  ModelCoordinate cell(0,0);
447  std::vector<ExactModelCoordinate> vertices;
448  cg->getVertices(vertices, cell);
449 
450  DoubleMatrix mtx;
451  mtx.loadRotate(m_rotation, 0.0, 0.0, 1.0);
452  mtx.applyRotate(m_tilt, 1.0, 0.0, 0.0);
453 
454  double x1 = 0;
455  double x2 = 0;
456  double y1 = 0;
457  double y2 = 0;
458 
459  for (uint32_t i = 0; i < vertices.size(); i++) {
460  vertices[i] = cg->toMapCoordinates(vertices[i]);
461  vertices[i] = mtx * vertices[i];
462  if (i == 0) {
463  x1 = x2 = vertices[0].x;
464  y1 = y2 = vertices[0].y;
465  } else {
466  x1 = std::min(vertices[i].x, x1);
467  x2 = std::max(vertices[i].x, x2);
468  y1 = std::min(vertices[i].y, y1);
469  y2 = std::max(vertices[i].y, y2);
470  }
471  }
472  return DoublePoint( x2 - x1, y2 - y1 );
473  }
474 
476  assert(layer && layer->getCellGrid());
477 
478  Location loc(layer);
479  ModelCoordinate cell(0,0);
480  loc.setLayerCoordinates(cell);
481  ScreenPoint sp1 = toScreenCoordinates(loc.getMapCoordinates());
482  ++cell.y;
483  loc.setLayerCoordinates(cell);
484  ScreenPoint sp2 = toScreenCoordinates(loc.getMapCoordinates());
485 
486  Point p(ABS(sp2.x - sp1.x), ABS(sp2.y - sp1.y));
487  if (p.x == 0) {
488  p.x = 1;
489  }
490  if (p.y == 0) {
491  p.y = 1;
492  }
493  return p;
494  }
495 
497  assert(layer && layer->getCellGrid());
498 
499  Location loc(layer);
500  ModelCoordinate cell(0,0,0);
501  loc.setLayerCoordinates(cell);
502  ScreenPoint sp1 = toScreenCoordinates(loc.getMapCoordinates());
503  ++cell.z;
504  loc.setLayerCoordinates(cell);
505  ScreenPoint sp2 = toScreenCoordinates(loc.getMapCoordinates());
506 
507  return Point3D(sp2.x - sp1.x, sp2.y - sp1.y, sp2.z - sp1.z);
508  }
509 
512  m_reference_scale = static_cast<double>(m_screen_cell_width) / dim.x;
513 
514  FL_DBG(_log, "Updating reference scale");
515  FL_DBG(_log, LMsg(" tilt=") << m_tilt << " rot=" << m_rotation);
516  FL_DBG(_log, LMsg(" m_screen_cell_width=") << m_screen_cell_width);
517  }
518 
520  return m_layer_to_instances[layer];
521  }
522 
523  void Camera::getMatchingInstances(ScreenPoint screen_coords, Layer& layer, std::list<Instance*>& instances, uint8_t alpha) {
524  instances.clear();
525  bool zoomed = !Mathd::Equal(m_zoom, 1.0);
526  bool special_alpha = alpha != 0;
527 
528  const RenderList& layer_instances = m_layer_to_instances[&layer];
529  RenderList::const_iterator instance_it = layer_instances.end();
530  while (instance_it != layer_instances.begin()) {
531  --instance_it;
532  Instance* i = (*instance_it)->instance;
533  const RenderItem& vc = **instance_it;
534  if ((vc.dimensions.contains(Point(screen_coords.x, screen_coords.y)))) {
535  if(vc.image->isSharedImage()) {
536  vc.image->forceLoadInternal();
537  }
538  uint8_t r, g, b, a = 0;
539  int32_t x = screen_coords.x - vc.dimensions.x;
540  int32_t y = screen_coords.y - vc.dimensions.y;
541  if (zoomed) {
542  double fx = static_cast<double>(x);
543  double fy = static_cast<double>(y);
544  double fow = static_cast<double>(vc.image->getWidth());
545  double foh = static_cast<double>(vc.image->getHeight());
546  double fsw = static_cast<double>(vc.dimensions.w);
547  double fsh = static_cast<double>(vc.dimensions.h);
548  x = static_cast<int32_t>(round(fx / fsw * fow));
549  y = static_cast<int32_t>(round(fy / fsh * foh));
550  }
551  vc.image->getPixelRGBA(x, y, &r, &g, &b, &a);
552  // instance is hit with mouse if not totally transparent
553  if (a == 0 || (special_alpha && a < alpha)) {
554  continue;
555  }
556  instances.push_back(i);
557  }
558  }
559  }
560 
561  void Camera::getMatchingInstances(Rect screen_rect, Layer& layer, std::list<Instance*>& instances, uint8_t alpha) {
562  instances.clear();
563  bool zoomed = !Mathd::Equal(m_zoom, 1.0);
564  bool special_alpha = alpha != 0;
565 
566  const RenderList& layer_instances = m_layer_to_instances[&layer];
567  RenderList::const_iterator instance_it = layer_instances.end();
568  while (instance_it != layer_instances.begin()) {
569  --instance_it;
570  Instance* i = (*instance_it)->instance;;
571  const RenderItem& vc = **instance_it;
572  if ((vc.dimensions.intersects(screen_rect))) {
573  if(vc.image->isSharedImage()) {
574  vc.image->forceLoadInternal();
575  }
576  uint8_t r, g, b, a = 0;
577  for(int32_t xx = screen_rect.x; xx < screen_rect.x + screen_rect.w; xx++) {
578  for(int32_t yy = screen_rect.y; yy < screen_rect.y + screen_rect.h; yy++) {
579  if ((vc.dimensions.contains(Point(xx, yy)))) {
580  int32_t x = xx - vc.dimensions.x;
581  int32_t y = yy - vc.dimensions.y;
582  if (zoomed) {
583  double fx = static_cast<double>(x);
584  double fy = static_cast<double>(y);
585  double fow = static_cast<double>(vc.image->getWidth());
586  double foh = static_cast<double>(vc.image->getHeight());
587  double fsw = static_cast<double>(vc.dimensions.w);
588  double fsh = static_cast<double>(vc.dimensions.h);
589  x = static_cast<int32_t>(round(fx / fsw * fow));
590  y = static_cast<int32_t>(round(fy / fsh * foh));
591  }
592  vc.image->getPixelRGBA(x, y, &r, &g, &b, &a);
593  // instance is hit with mouse if not totally transparent
594  if (a == 0 || (special_alpha && a < alpha)) {
595  continue;
596  }
597 
598  instances.push_back(i);
599  goto found_non_transparent_pixel;
600  }
601  }
602  }
603  found_non_transparent_pixel:;
604  }
605  }
606  }
607 
608  void Camera::getMatchingInstances(Location& loc, std::list<Instance*>& instances, bool use_exactcoordinates) {
609  instances.clear();
610  Layer* layer = loc.getLayer();
611  if(!layer) {
612  return;
613  }
614 
615  const RenderList& layer_instances = m_layer_to_instances[layer];
616  RenderList::const_iterator instance_it = layer_instances.end();
617  while (instance_it != layer_instances.begin()) {
618  --instance_it;
619  Instance* i = (*instance_it)->instance;
620  if (use_exactcoordinates) {
622  instances.push_back(i);
623  }
624  } else {
626  instances.push_back(i);
627  }
628  }
629  }
630  }
631 
632  void Camera::attach(Instance *instance) {
633  // fail if the layers aren't the same
634  if (m_location.getLayer()->getId() != instance->getLocation().getLayer()->getId()) {
635  FL_WARN(_log, "Tried to attach camera to instance on different layer.");
636  return ;
637  }
638  m_attachedto = instance;
639  }
640 
641  void Camera::detach() {
642  m_attachedto = NULL;
643  }
644 
645  void Camera::update() {
646  if (!m_attachedto) {
647  return;
648  }
651  if (Mathd::Equal(old_emc.x, new_emc.x) && Mathd::Equal(old_emc.y, new_emc.y)) {
652  return;
653  }
655  old_emc = new_emc;
656  updateMatrices();
657  }
658 
660  updateMatrices();
662  }
663 
665  if (m_transform == NoneTransform) {
666  m_updated = false;
667  } else {
668  m_updated = true;
669  }
671  }
672 
673  bool pipelineSort(const RendererBase* lhs, const RendererBase* rhs) {
674  return (lhs->getPipelinePosition() < rhs->getPipelinePosition());
675  }
676 
678  renderer->setRendererListener(this);
679  m_renderers[renderer->getName()] = renderer;
680  if (renderer->isEnabled()) {
681  m_pipeline.push_back(renderer);
682  }
683  m_pipeline.sort(pipelineSort);
684  }
685 
687  m_pipeline.sort(pipelineSort);
688  }
689 
691  assert(m_renderers[renderer->getName()]);
692  if (renderer->isEnabled()) {
693  FL_LOG(_log, LMsg("Enabling renderer ") << renderer->getName());
694  m_pipeline.push_back(renderer);
695  m_pipeline.sort(pipelineSort);
696  } else {
697  m_pipeline.remove(renderer);
698  }
699  }
700 
701  RendererBase* Camera::getRenderer(const std::string& name) {
702  return m_renderers[name];
703  }
704 
706  std::map<std::string, RendererBase*>::iterator r_it = m_renderers.begin();
707  for (; r_it != m_renderers.end(); ++r_it) {
708  r_it->second->reset();
709  }
710  }
711 
712  void Camera::addLayer(Layer* layer) {
713  m_cache[layer] = new LayerCache(this);
714  m_cache[layer]->setLayer(layer);
715  m_layer_to_instances[layer] = RenderList();
716  }
717 
718  void Camera::removeLayer(Layer* layer) {
719  delete m_cache[layer];
720  m_cache.erase(layer);
721  m_layer_to_instances.erase(layer);
722  }
723 
724  void Camera::setLightingColor(float red, float green, float blue) {
725  m_lighting = true;
726  m_light_colors.clear();
727  m_light_colors.push_back(red);
728  m_light_colors.push_back(green);
729  m_light_colors.push_back(blue);
730  }
731 
732  std::vector<float> Camera::getLightingColor() {
733  if(m_light_colors.empty()) {
734  for(int32_t colors = 0; colors != 3; ++colors) {
735  m_light_colors.push_back(1.0f);
736  }
737  }
738  return m_light_colors;
739  }
740 
742  m_lighting = false;
744  }
745 
746  void Camera::setOverlayColor(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) {
747  m_col_overlay = true;
748  m_overlay_color.r = red;
749  m_overlay_color.g = green;
750  m_overlay_color.b = blue;
751  m_overlay_color.unused = alpha;
752  }
753 
754  std::vector<uint8_t> Camera::getOverlayColor() {
755  std::vector<uint8_t> colors;
756  if (m_col_overlay) {
757  colors.push_back(m_overlay_color.r);
758  colors.push_back(m_overlay_color.g);
759  colors.push_back(m_overlay_color.b);
760  colors.push_back(m_overlay_color.unused);
761  } else {
762  for(uint8_t cc = 0; cc != 4; ++cc) {
763  colors.push_back(255);
764  }
765  }
766  return colors;
767  }
768 
770  m_col_overlay = false;
771  }
772 
773  void Camera::setOverlayImage(int32_t id, bool fill) {
774  m_img_overlay = true;
775  m_img_id = id;
776  m_img_fill = fill;
777  }
778 
780  int32_t id = -1;
781  if (m_img_overlay) {
782  id = m_img_id;
783  }
784  return id;
785  }
786 
788  m_img_overlay = false;
789  m_img_id = -1;
790  }
791 
793  m_ani_overlay = true;
794  m_ani_ptr = anim;
795  m_ani_fill = fill;
796  m_start_time = 0;
797  }
798 
800  return m_ani_ptr;
801  }
802 
804  m_ani_overlay = false;
805  m_ani_ptr.reset();
806  }
807 
810  return;
811  }
812  uint16_t width = m_viewport.w;
813  uint16_t height = m_viewport.h;
814  Point pm = Point(m_viewport.x + width/2, m_viewport.y + height/2);
815  Rect r;
816 
817  // color overlay
818  if (m_col_overlay) {
821  }
822  // image overlay
823  if (m_img_overlay) {
825  Image* img = resptr.get();
826  if (img) {
827  if (m_img_fill) {
828  r.w = width;
829  r.h = height;
830  } else {
831  r.w = img->getWidth();
832  r.h = img->getHeight();
833  }
834  r.x = pm.x-r.w/2;
835  r.y = pm.y-r.h/2;
836  img->render(r);
837  }
838  }
839  // animation overlay
840  if (m_ani_overlay) {
841  assert(m_ani_ptr != 0);
842 
843  if (m_start_time == 0) {
845  }
846  uint32_t animtime = scaleTime(1.0, TimeManager::instance()->getTime() - m_start_time) % m_ani_ptr->getDuration();
847  ImagePtr img = m_ani_ptr->getFrameByTimestamp(animtime);
848  if (img) {
849  if (m_ani_fill) {
850  r.w = width;
851  r.h = height;
852  } else {
853  r.w = img->getWidth();
854  r.h = img->getHeight();
855  }
856  r.x = pm.x-r.w/2;
857  r.y = pm.y-r.h/2;
858  img->render(r);
859  }
860  }
861  }
862 
863  void Camera::renderStaticLayer(Layer* layer, bool update) {
864  // ToDo: Remove this function from the camera class to something like engine pre-render.
865  // ToDo: Check if partial rendering of only updated RenderItems to existing FBO is possible/faster in our case.
866  // ToDo: Add and fix support for SDL and OpenGLe backends, for SDL it works only on the lowest layer(alpha/transparent bug).
867  LayerCache* cache = m_cache[layer];
868  ImagePtr cacheImage = cache->getCacheImage();
869  if (!cacheImage.get()) {
870  // the cacheImage name will be, camera id + _virtual_layer_image_ + layer id
871  cacheImage = ImageManager::instance()->loadBlank(m_id+"_virtual_layer_image_"+layer->getId(), m_viewport.w, m_viewport.h);
872  cache->setCacheImage(cacheImage);
873  update = true;
874  }
875  if (update) {
876  // for the case that the viewport size is not the same as the screen size,
877  // we have to change the values for OpenGL and OpenGLe backends
879  if (m_renderbackend->getName() == "SDL") {
880  rec = m_viewport;
881  }
882  m_renderbackend->attachRenderTarget(cacheImage, true);
883  // here we use the new viewport size
884  m_renderbackend->pushClipArea(rec, false);
885  // render stuff to texture
886  RenderList& instances_to_render = m_layer_to_instances[layer];
887  std::list<RendererBase*>::iterator r_it = m_pipeline.begin();
888  for (; r_it != m_pipeline.end(); ++r_it) {
889  if ((*r_it)->isActivedLayer(layer)) {
890  (*r_it)->render(this, layer, instances_to_render);
891  }
892  }
895  }
896  // render cacheImage
897  cacheImage.get()->render(m_viewport);
898  }
899 
901  Map* map = m_location.getMap();
902  if (!map) {
903  FL_ERR(_log, "No map for camera found");
904  return;
905  }
906 
907  const std::list<Layer*>& layers = map->getLayers();
908  std::list<Layer*>::const_iterator layer_it = layers.begin();
909  for (;layer_it != layers.end(); ++layer_it) {
910  LayerCache* cache = m_cache[*layer_it];
911  if(!cache) {
912  addLayer(*layer_it);
913  cache = m_cache[*layer_it];
914  FL_ERR(_log, LMsg("Layer Cache miss! (This shouldn't happen!)") << (*layer_it)->getId());
915  }
916  RenderList& instances_to_render = m_layer_to_instances[*layer_it];
917  if ((*layer_it)->isStatic() && m_transform == NoneTransform) {
918  continue;
919  }
920  cache->update(m_transform, instances_to_render);
921  }
922  resetUpdates();
923  }
924 
925  void Camera::render() {
926  static bool renderbackendOpenGLe = (m_renderbackend->getName() == "OpenGLe");
927 
929  Map* map = m_location.getMap();
930  if (!map) {
931  return;
932  }
933 
935  if (lm != 0) {
937  if (m_lighting) {
939  }
940  }
941 
943 
944  const std::list<Layer*>& layers = map->getLayers();
945  std::list<Layer*>::const_iterator layer_it = layers.begin();
946  for ( ; layer_it != layers.end(); ++layer_it) {
947  // layer with static flag will rendered as one texture
948  if ((*layer_it)->isStatic()) {
949  renderStaticLayer(*layer_it, m_updated);
950  continue;
951  }
952  RenderList& instances_to_render = m_layer_to_instances[*layer_it];
953  std::list<RendererBase*>::iterator r_it = m_pipeline.begin();
954  for (; r_it != m_pipeline.end(); ++r_it) {
955  if ((*r_it)->isActivedLayer(*layer_it)) {
956  (*r_it)->render(this, *layer_it, instances_to_render);
957  }
958  }
959  if (renderbackendOpenGLe) {
961  }
962  }
963 
964  renderOverlay();
966  if (m_lighting && lm != 0) {
968  }
970  }
971 }
#define FL_WARN(logger, msg)
Definition: logger.h:72
bool m_ani_fill
Definition: camera.h:499
Abstract interface for all the renderbackends.
Definition: renderbackend.h:92
virtual ImagePtr loadBlank(uint32_t width, uint32_t height)
Loads a blank resource.
void setZToY(double zToY)
Sets zToY value for the camera and enables their use.
Definition: camera.cpp:187
virtual void setLighting(float red, float green, float blue)=0
Set colors for lighting.
T * get() const
allows direct access to underlying pointer
Definition: sharedptr.h:155
int32_t getOverlayImage()
Returns the pool id of the overlay image.
Definition: camera.cpp:779
std::list< RendererBase * > m_pipeline
Definition: camera.h:473
DoublePoint getLogicalCellDimensions(Layer *layer)
Gets logical cell image dimensions for given layer.
Definition: camera.cpp:441
RenderBackend * m_renderbackend
Definition: camera.h:477
double m_tilt
Definition: camera.h:451
Matrix & applyRotate(T angle, T x, T y, T z)
Definition: matrix.h:306
DoubleMatrix m_vs_inverse_matrix
Definition: camera.h:447
Matrix inverse() const
Adjoint method inverse, constant time inversion implementation.
Definition: matrix.h:63
std::vector< RenderItem * > RenderList
Definition: renderitem.h:82
void setOverlayImage(int32_t id, bool fill=false)
Sets a image as overlay, if fill is true the image gets the viewport size.
Definition: camera.cpp:773
void updateMap(Map *map)
Definition: camera.cpp:246
virtual ~MapObserver()
Definition: camera.cpp:63
Base Class for Images.
Definition: image.h:47
#define ABS(x)
Definition: fife_math.h:40
uint32_t m_screen_cell_height
Definition: camera.h:462
T h
Height of the rectangle.
Definition: rect.h:93
virtual ImagePtr get(const std::string &name)
Gets a shared pointer to the Image.
void updateMatrices()
Updates the camera transformation matrix T with requested values.
Definition: camera.cpp:364
void resetUpdates()
Resets temporary values from last update round, like warped flag.
Definition: camera.cpp:664
DoubleMatrix m_inverse_matrix
Definition: camera.h:444
virtual void onMapChanged(Map *map, std::vector< Layer * > &changedLayers)
Called when some layer is changed on map.
Definition: camera.cpp:65
Helper class to create log strings out from separate parts Usage: LMsg(&quot;some text&quot;) &lt;&lt; variable &lt;&lt; &quot;...
Definition: logger.h:82
void removeChangeListener(MapChangeListener *listener)
Removes associated change listener.
Definition: map.cpp:230
MapObserver(Camera *camera)
Definition: camera.cpp:60
void setOverlayColor(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha)
Sets a color as overlay.
Definition: camera.cpp:746
Rect m_viewport
Definition: camera.h:458
void setLayer(Layer *layer)
Sets layer where this location is pointing to.
Definition: location.cpp:79
Matrix< T > & mult4by4(const Matrix< T > &mat)
Definition: matrix.h:281
T x
The X Coordinate.
Definition: rect.h:84
Transform m_transform
Definition: camera.h:469
int32_t m_img_id
Definition: camera.h:496
void reset(T *ptr=0)
reset this pointer to a null shared pointer this can be used to lower the reference count of the shar...
Definition: sharedptr.h:164
virtual const std::string & getName() const =0
The name of the renderbackend.
DoubleMatrix m_vs_matrix
Definition: camera.h:446
RenderList & getRenderListRef(Layer *layer)
Returns reference to RenderList.
Definition: camera.cpp:519
bool isZToYEnabled() const
Gets if z to y manipulation is enabled / disabled.
Definition: camera.cpp:204
uint32_t getHeight() const
DoublePoint3D toVirtualScreenCoordinates(const ExactModelCoordinate &map_coords)
Transforms given point from map coordinates to virtual screen coordinates.
Definition: camera.cpp:428
bool contains(const PointType2D< T > &point) const
Checks whether a rectangle contains a Point.
Definition: rect.h:184
void resetLightingColor()
Resets lighting color.
Definition: camera.cpp:741
void setMapCoordinates(const ExactModelCoordinate &coordinates)
Sets map coordinates to this location.
Definition: location.cpp:98
void setZToYEnabled(bool enabled)
Sets z to y manipulation enabled / disabled.
Definition: camera.cpp:200
void resetRenderers()
resets active layer information on all renderers.
Definition: camera.cpp:705
void setTilt(double tilt)
Sets tilt for the camera.
Definition: camera.cpp:132
uint32_t getDuration() const
Gets the total duration for the whole animation.
Definition: animation.h:129
void getPixelRGBA(int32_t x, int32_t y, uint8_t *r, uint8_t *g, uint8_t *b, uint8_t *a)
Definition: image.cpp:176
void resetOverlayAnimation()
Resets the animation overlay.
Definition: camera.cpp:803
bool isEnabled() const
Is renderer enabled.
Definition: rendererbase.h:136
virtual void detachRenderTarget()=0
Detaches current render surface.
bool m_enabledZToY
Definition: camera.h:455
void addChangeListener(MapChangeListener *listener)
Adds new change listener.
Definition: map.cpp:226
bool m_img_fill
Definition: camera.h:498
static Logger _log(LM_AUDIO)
PointType3D< int32_t > Point3D
Definition: point.h:325
void attach(Instance *instance)
Attaches the camera to an instance.
Definition: camera.cpp:632
double getTilt() const
Gets camera tilt.
Definition: camera.cpp:141
Point3D getZOffset(Layer *layer)
Gets a point that contain the visual z(z=1) difference, based on the given layer. ...
Definition: camera.cpp:496
DoubleMatrix m_screen_2_vscreen
Definition: camera.h:449
Camera * m_camera
Definition: camera.cpp:57
PointType2D< double > DoublePoint
Definition: point.h:195
Exception base class.
Definition: exception.h:43
Matrix & applyScale(T x, T y, T z)
Apply scale into this matrix.
Definition: matrix.h:148
std::vector< uint8_t > getOverlayColor()
Returns a vector that contain the overlay color.
Definition: camera.cpp:754
void setRotation(double rotation)
Sets rotation for the camera.
Definition: camera.cpp:145
void resetOverlayColor()
Resets the color overlay.
Definition: camera.cpp:769
void onRendererEnabledChanged(RendererBase *renderer)
Renderer is enabled / disabled.
Definition: camera.cpp:690
Camera(const std::string &id, Layer *layer, const Rect &viewport, RenderBackend *renderbackend)
Constructor Camera needs to be added to the view.
Definition: camera.cpp:77
bool isEnabled()
Gets if camera is enabled / disabled.
Definition: camera.cpp:356
Camera describes properties of a view port shown in the main screen Main screen can have multiple cam...
Definition: camera.h:58
Layer * getLayer() const
Gets the layer where this location is pointing to.
Definition: location.cpp:83
bool m_col_overlay
Definition: camera.h:492
static ImageManager * instance()
Definition: singleton.h:84
Location & getLocationRef()
Gets reference of current location of instance.
Definition: instance.cpp:307
uint32_t m_start_time
Definition: camera.h:500
ModelCoordinate getLayerCoordinates() const
Gets cell precision layer coordinates set to this location.
Definition: location.cpp:113
virtual void getVertices(std::vector< ExactModelCoordinate > &vtx, const ModelCoordinate &cell)=0
Fills given point vector with vertices from selected cell.
ScreenPoint m_cur_origo
Definition: camera.h:457
RendererBase * getRenderer(const std::string &name)
Gets renderer with given name.
Definition: camera.cpp:701
std::map< std::string, RendererBase * > m_renderers
Definition: camera.h:472
#define FL_ERR(logger, msg)
Definition: logger.h:73
virtual uint32_t getLightingModel() const =0
Gets the current light model.
DoubleMatrix m_matrix
Definition: camera.h:443
uint32_t getHeight() const
Definition: image.cpp:155
bool m_enabled
Definition: camera.h:464
void addRenderer(RendererBase *renderer)
Adds new renderer on the view.
Definition: camera.cpp:677
double m_zToY
Definition: camera.h:454
unsigned char uint8_t
Definition: core.h:38
Map * getMap() const
Gets the map where this location is pointing to.
Definition: location.cpp:72
double getOriginalZToY() const
Gets original zToY transformation value.
Definition: camera.cpp:172
std::map< Layer *, LayerCache * > m_cache
Definition: camera.h:482
bool m_ani_overlay
Definition: camera.h:494
PointType2D< int32_t > Point
Definition: point.h:194
uint32_t getTime() const
Get the time.
const Rect & getViewPort() const
Gets the viewport for camera in pixel coordinates.
Definition: camera.cpp:299
void onRendererPipelinePositionChanged(RendererBase *renderer)
Renderer&#39;s pipeline position has been changed.
Definition: camera.cpp:686
ImagePtr getFrameByTimestamp(uint32_t timestamp)
Gets the frame image that matches the given timestamp.
Definition: animation.cpp:99
void setLocation(const Location &location)
Sets the location for camera.
Definition: camera.cpp:216
static bool Equal(T _val1, T _val2)
Definition: fife_math.h:286
friend class MapObserver
Definition: camera.h:400
Base class for all view renderers View renderer renders one aspect of the view shown on screen...
Definition: rendererbase.h:78
void pushClipArea(const Rect &cliparea, bool clear=true)
Pushes clip area to clip stack Clip areas define which area is drawn on screen.
bool m_updated
Definition: camera.h:475
t_layer_to_instances m_layer_to_instances
Definition: camera.h:480
ImagePtr getCacheImage()
Definition: layercache.cpp:706
void removeLayer(Layer *layer)
Definition: camera.cpp:718
A basic layer on a map.
Definition: layer.h:98
double getZoom() const
Gets camera zoom.
Definition: camera.cpp:168
virtual void onLayerDelete(Map *map, Layer *layer)
Called when some instance gets deleted on layer.
Definition: camera.cpp:72
Point doublePt2intPt(DoublePoint pt)
Convert from 2D double point to 2D int32_t point.
Definition: point.h:330
Location getLocation() const
Gets current location of instance.
Definition: instance.cpp:303
void setLightingColor(float red, float green, float blue)
Sets lighting color.
Definition: camera.cpp:724
Location & getLocationRef()
Gets a reference to the camera location.
Definition: camera.cpp:291
void setCacheImage(ImagePtr image)
Definition: layercache.cpp:710
void resetOverlayImage()
Resets the image overlay.
Definition: camera.cpp:787
void popClipArea()
Pops clip area from clip stack.
ExactModelCoordinate & getExactLayerCoordinatesRef()
Gets reference to exact layer coordinates.
Definition: location.cpp:105
void detach()
Detaches the camera from an instance.
Definition: camera.cpp:641
uint32_t getWidth() const
Definition: image.cpp:146
unsigned short uint16_t
Definition: core.h:39
T y
The Y Coordinate.
Definition: rect.h:87
void renderOverlay()
Renders the overlay(color, image, animation) for the camera.
Definition: camera.cpp:808
CellGrid * getCellGrid() const
Get the Cellgrid.
Definition: layer.cpp:92
const Rect & getMapViewPort()
Gets the viewport for camera in map coordinates.
Definition: camera.cpp:303
bool m_lighting
Definition: camera.h:487
void addLayer(Layer *layer)
Definition: camera.cpp:712
AnimationPtr getOverlayAnimation()
Returns an AnimationPtr to the overlay animation.
Definition: camera.cpp:799
void setRendererListener(IRendererListener *listener)
Sets listener for renderer.
Definition: rendererbase.h:140
virtual std::string getName()=0
Name of the renderer.
static T Tan(T _val)
Definition: fife_math.h:281
bool pipelineSort(const RendererBase *lhs, const RendererBase *rhs)
Definition: camera.cpp:673
virtual ~Camera()
Destructor.
Definition: camera.cpp:119
double m_reference_scale
Definition: camera.h:463
void refresh()
Refreshes camera view in case e.g.
Definition: camera.cpp:659
#define FL_LOG(logger, msg)
Definition: logger.h:71
AnimationPtr m_ani_ptr
Definition: camera.h:497
void updateReferenceScale()
Updates camera reference scale Reference scale is in a sense an internal zooming factor, which adjusts cell dimensions in logical space to ones shown on screen.
Definition: camera.cpp:510
Point getCellImageDimensions()
Gets screen cell image dimensions.
Definition: camera.cpp:267
Matrix & loadRotate(T angle, T x, T y, T z)
Make this a rotation matrix.
Definition: matrix.h:113
Matrix & loadScale(T x, T y, T z=1)
Make this a scale matrix.
Definition: matrix.h:157
bool intersects(const RectType< T > &rect) const
Check whether two rectangles share some area.
Definition: rect.h:227
bool isSharedImage() const
Returns true if this image shares data with another one.
Definition: image.h:143
ImagePtr image
Definition: renderitem.h:67
virtual void render(const Rect &rect, uint8_t alpha=255, uint8_t const *rgb=0)=0
Renders itself to the current render target (main screen or attached destination image) at the rectan...
ScreenPoint toScreenCoordinates(const ExactModelCoordinate &map_coords)
Transforms given point from map coordinates to screen coordinates.
Definition: camera.cpp:423
std::map< Layer *, Point > m_image_dimensions
Definition: camera.h:467
A 3D Point.
Definition: point.h:202
Instance * m_attachedto
Definition: camera.h:465
bool m_mapViewPortUpdated
Definition: camera.h:460
const std::string & getId() const
Get the id of this layer.
Definition: layer.cpp:80
void getMatchingInstances(ScreenPoint screen_coords, Layer &layer, std::list< Instance * > &instances, uint8_t alpha=0)
Returns instances that match given screen coordinate.
Definition: camera.cpp:523
Location getLocation() const
Gets the location camera is rendering.
Definition: camera.cpp:287
void calculateZValue(ScreenPoint &screen_coords)
calculates z-value for given screenpoint
Definition: camera.cpp:411
DoublePoint intPt2doublePt(Point pt)
Convert from 2D int32_t point to 2D double point.
Definition: point.h:344
void update(Camera::Transform transform, RenderList &renderlist)
Definition: layercache.cpp:370
const std::list< Layer * > & getLayers() const
Get the layers on this map.
Definition: map.h:119
Map * m_map
Definition: camera.h:484
static num_type pi()
Definition: fife_math.h:133
ExactModelCoordinate toMapCoordinates(ScreenPoint screen_coords, bool z_calculated=true)
Transforms given point from screen coordinates to map coordinates.
Definition: camera.cpp:416
virtual void forceLoadInternal()=0
Forces to load the image into internal memory of GPU.
virtual void attachRenderTarget(ImagePtr &img, bool discard)=0
Attaches given image as a new render surface.
void setOverlayAnimation(AnimationPtr anim, bool fill=false)
Sets a animation as overlay, if fill is true the animation gets the viewport size.
Definition: camera.cpp:792
std::string m_id
Definition: camera.h:404
void renderStaticLayer(Layer *layer, bool update)
Renders the layer part that is on screen as one image.
Definition: camera.cpp:863
Rect m_mapViewPort
Definition: camera.h:459
DoubleMatrix m_vscreen_2_screen
Definition: camera.h:448
virtual void onLayerCreate(Map *map, Layer *layer)
Called when some layer gets created on the map.
Definition: camera.cpp:68
Point3D getOrigin() const
Gets screen point for the camera location.
Definition: camera.cpp:360
virtual void renderVertexArrays()=0
Render the Vertex Arrays, only for primitives (points, lines,...)
virtual void fillRectangle(const Point &p, uint16_t w, uint16_t h, uint8_t r, uint8_t g, uint8_t b, uint8_t a=255)=0
Draws a filled axis parallel rectangle.
void update()
General update routine.
Definition: camera.cpp:645
std::vector< float > m_light_colors
Definition: camera.h:489
uint32_t scaleTime(float multiplier, uint32_t ticks)
Utility function to calculate time scaling.
void setCellImageDimensions(uint32_t width, uint32_t height)
Sets screen cell image dimensions.
Definition: camera.cpp:208
void setViewPort(const Rect &viewport)
Sets the viewport for camera viewport is rectangle inside the view where camera renders.
Definition: camera.cpp:295
A container of Layer(s).
Definition: map.h:87
double m_zoom
Definition: camera.h:453
MapObserver * m_map_observer
Definition: camera.h:483
unsigned int uint32_t
Definition: core.h:40
DoublePoint3D screenToVirtualScreen(const ScreenPoint &p)
Definition: camera.cpp:437
ExactModelCoordinate toMapCoordinates(const ModelCoordinate &layer_coords)
Transforms given point from layer coordinates to map coordinates.
Definition: cellgrid.cpp:75
Location m_location
Definition: camera.h:456
virtual void resetLighting()=0
Reset lighting with default values.
virtual void resetStencilBuffer(uint8_t buffer)=0
Reset stencil buffer with given value.
void setEnabled(bool enabled)
Sets camera enabled / disabled.
Definition: camera.cpp:352
int32_t getPipelinePosition() const
Gets renderer position in the rendering pipeline.
Definition: rendererbase.h:117
Matrix & applyTranslate(T x, T y, T z)
Apply translation into this matrix.
Definition: matrix.h:180
ExactModelCoordinate getExactLayerCoordinates() const
Gets exact layer coordinates set to this location.
Definition: location.cpp:109
SDL_Color m_overlay_color
Definition: camera.h:495
T w
Width of the rectangle.
Definition: rect.h:90
#define FL_DBG(logger, msg)
Definition: logger.h:70
double getZToY() const
Gets zToY value.
Definition: camera.cpp:196
void render()
Renders camera.
Definition: camera.cpp:925
An Instance is an &quot;instantiation&quot; of an Object at a Location.
Definition: instance.h:97
void updateRenderLists()
Updates camera RenderLists.
Definition: camera.cpp:900
ScreenPoint virtualScreenToScreen(const DoublePoint3D &p)
Definition: camera.cpp:433
double m_rotation
Definition: camera.h:452
std::vector< float > getLightingColor()
Returns a vector that contain the light color.
Definition: camera.cpp:732
ExactModelCoordinate getMapCoordinates() const
Gets map coordinates set to this location.
Definition: location.cpp:117
bool m_img_overlay
Definition: camera.h:493
uint32_t m_screen_cell_width
Definition: camera.h:461
double getRotation() const
Gets camera rotation.
Definition: camera.cpp:153
Point getRealCellDimensions(Layer *layer)
Gets real cell image dimensions for given layer.
Definition: camera.cpp:475
Rect getLayerViewPort(Layer *layer)
Gets the viewport for camera in layer coordinates.
Definition: camera.cpp:336
void setZoom(double zoom)
Sets zoom for the camera.
Definition: camera.cpp:157
Listener interface for changes happening on map.
Definition: map.h:55