FIFE
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
layercache.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 #include <cfloat>
24 
25 // 3rd party library includes
26 
27 // FIFE includes
28 // These includes are split up in two parts, separated by one empty line
29 // First block: files included from the FIFE root src directory
30 // Second block: files included from the same folder
31 
33 #include "model/metamodel/action.h"
34 #include "model/structures/layer.h"
37 #include "util/base/exception.h"
38 #include "util/log/logger.h"
39 #include "util/math/fife_math.h"
40 #include "util/math/angles.h"
41 #include "video/renderbackend.h"
42 #include "video/image.h"
43 #include "video/animation.h"
44 #include "video/imagemanager.h"
45 
46 #include "camera.h"
47 #include "layercache.h"
48 #include "visual.h"
49 
50 
51 namespace FIFE {
55  static Logger _log(LM_CAMERA);
56 
57  // Due to image alignment, there is additional additions on image dimensions.
58  const double OVERDRAW = 1.5;
59 
61  public:
63  m_cache = cache;
64  }
66 
67  virtual void onLayerChanged(Layer* layer, std::vector<Instance*>& instances) {
68  for(std::vector<Instance*>::iterator i = instances.begin();
69  i != instances.end(); ++i) {
71  }
72  }
73 
74  virtual void onInstanceCreate(Layer* layer, Instance* instance) {
75  m_cache->addInstance(instance);
76  }
77 
78  virtual void onInstanceDelete(Layer* layer, Instance* instance) {
79  m_cache->removeInstance(instance);
80  }
81  private:
83  };
84 
87  // used screenpoint z for sorting, calculated from camera
89  public:
90  inline bool operator()(RenderItem* const & lhs, RenderItem* const & rhs) {
91  if (Mathd::Equal(lhs->screenpoint.z, rhs->screenpoint.z)) {
94  return liv->getStackPosition() < riv->getStackPosition();
95  }
96  return lhs->screenpoint.z < rhs->screenpoint.z;
97  }
98  };
99  // used instance location and camera rotation for sorting
101  public:
102  InstanceDistanceSortLocation(double rotation) {
103  if ((rotation >= 0) && (rotation <= 60)) { // 30 deg
104  xtox = 0;
105  xtoy = -1;
106  ytox = 1;
107  ytoy = 0.5;
108  } else if ((rotation >= 60) && (rotation <= 120)) { // 90 deg
109  xtox = -1;
110  xtoy = -1;
111  ytox = 0.5;
112  ytoy = -0.5;
113  } else if ((rotation >= 120) && (rotation <= 180)) { // 150 deg
114  xtox = 0;
115  xtoy = -1;
116  ytox = -1;
117  ytoy = -0.5;
118  } else if ((rotation >= 180) && (rotation <= 240)) { // 210 deg
119  xtox = 0;
120  xtoy = 1;
121  ytox = -1;
122  ytoy = -0.5;
123  } else if ((rotation >= 240) && (rotation <= 300)) { // 270 deg
124  xtox = 1;
125  xtoy = 1;
126  ytox = -0.5;
127  ytoy = 0.5;
128  } else if ((rotation >= 300) && (rotation <= 360)) { // 330 deg
129  xtox = 0;
130  xtoy = 1;
131  ytox = 1;
132  ytoy = 0.5;
133  }
134  }
135 
136  inline bool operator()(RenderItem* const & lhs, RenderItem* const & rhs) {
139  lpos.x += lpos.y / 2;
140  rpos.x += rpos.y / 2;
143  int32_t lvc = ceil(xtox*lpos.x + ytox*lpos.y) + ceil(xtoy*lpos.x + ytoy*lpos.y) + liv->getStackPosition();
144  int32_t rvc = ceil(xtox*rpos.x + ytox*rpos.y) + ceil(xtoy*rpos.x + ytoy*rpos.y) + riv->getStackPosition();
145  if (lvc == rvc) {
146  if (Mathd::Equal(lpos.z, rpos.z)) {
147  return liv->getStackPosition() < riv->getStackPosition();
148  }
149  return lpos.z < rpos.z;
150  }
151  return lvc < rvc;
152  }
153  private:
154  double xtox;
155  double xtoy;
156  double ytox;
157  double ytoy;
158  };
159  // used screenpoint z for sorting and as fallback first the instance location z and then the stack position
161  public:
162  inline bool operator()(RenderItem* const & lhs, RenderItem* const & rhs) {
163  if (Mathd::Equal(lhs->screenpoint.z, rhs->screenpoint.z)) {
166  if (Mathd::Equal(lpos.z, rpos.z)) {
169  return liv->getStackPosition() < riv->getStackPosition();
170  }
171  return lpos.z < rpos.z;
172  }
173  return lhs->screenpoint.z < rhs->screenpoint.z;
174  }
175  };
176 
178  m_camera = camera;
179  m_layer = 0;
180  m_tree = 0;
181  m_zMin = 0.0;
182  m_zMax = 0.0;
183  m_zoom = camera->getZoom();
184  m_zoomed = !Mathd::Equal(m_zoom, 1.0);
185  m_straightZoom = Mathd::Equal(fmod(m_zoom, 1.0), 0.0);
186 
187  if(RenderBackend::instance()->getName() == "OpenGLe") {
188  m_needSorting = false;
189  } else {
190  m_needSorting = true;
191  }
192  }
193 
195  // removes all Entries
196  for (std::vector<Entry*>::iterator it = m_entries.begin(); it != m_entries.end(); ++it) {
197  delete *it;
198  }
199  // removes all RenderItems
200  for (std::vector<RenderItem*>::iterator it = m_renderItems.begin(); it != m_renderItems.end(); ++it) {
201  delete *it;
202  }
204  delete m_layerObserver;
205  delete m_tree;
206  }
207 
209  if (m_layer != layer) {
210  if (m_layer) {
212  delete m_layerObserver;
213  }
214  m_layer = layer;
217  reset();
218  }
219  }
220 
222  // removes all Entries
223  for (std::vector<Entry*>::iterator it = m_entries.begin(); it != m_entries.end(); ++it) {
224  delete *it;
225  }
226  m_entries.clear();
227  // removes all RenderItems
228  for (std::vector<RenderItem*>::iterator it = m_renderItems.begin(); it != m_renderItems.end(); ++it) {
229  delete *it;
230  }
231  m_renderItems.clear();
232  m_instance_map.clear();
233  m_entriesToUpdate.clear();
234  m_freeEntries.clear();
236 
237  delete m_tree;
238  m_tree = new CacheTree;
239  const std::vector<Instance*>& instances = m_layer->getInstances();
240  for(std::vector<Instance*>::const_iterator i = instances.begin();
241  i != instances.end(); ++i) {
242  addInstance(*i);
243  }
244  }
245 
247  assert(m_instance_map.find(instance) == m_instance_map.end());
248 
249  RenderItem* item;
250  Entry* entry;
251  if (m_freeEntries.empty()) {
252  // creates new RenderItem
253  item = new RenderItem(instance);
254  m_renderItems.push_back(item);
255  m_instance_map[instance] = m_renderItems.size() - 1;
256  // creates new Entry
257  entry = new Entry();
258  m_entries.push_back(entry);
259  entry->instanceIndex = m_renderItems.size() - 1;
260  entry->entryIndex = m_entries.size() - 1;
261  } else {
262  // uses free/unused RenderItem
263  int32_t index = m_freeEntries.front();
264  m_freeEntries.pop_front();
265  item = m_renderItems[index];
266  item->instance = instance;
267  m_instance_map[instance] = index;
268  // uses free/unused Entry
269  entry = m_entries[index];
270  entry->instanceIndex = index;
271  entry->entryIndex = index;
272  }
273 
274  entry->node = 0;
275  entry->forceUpdate = true;
276  entry->visible = true;
277  entry->updateInfo = EntryFullUpdate;
278 
279  m_entriesToUpdate.insert(entry->entryIndex);
280  }
281 
283  assert(m_instance_map.find(instance) != m_instance_map.end());
284 
285  Entry* entry = m_entries[m_instance_map[instance]];
286  assert(entry->instanceIndex == m_instance_map[instance]);
287  RenderItem* item = m_renderItems[entry->instanceIndex];
288  // removes entry from updates
289  std::set<int32_t>::iterator it = m_entriesToUpdate.find(entry->entryIndex);
290  if (it != m_entriesToUpdate.end()) {
291  m_entriesToUpdate.erase(it);
292  }
293  // removes entry from CacheTree
294  if (entry->node) {
295  entry->node->data().erase(entry->entryIndex);
296  entry->node = 0;
297  }
298  entry->instanceIndex = -1;
299  entry->forceUpdate = false;
300  m_instance_map.erase(instance);
301 
302  // removes instance from RenderList
304  for (RenderList::iterator it = renderList.begin(); it != renderList.end(); ++it) {
305  if ((*it)->instance == instance) {
306  renderList.erase(it);
307  break;
308  }
309  }
310  // resets RenderItem
311  item->reset();
312  // adds free entry
313  m_freeEntries.push_back(entry->entryIndex);
314  }
315 
317  Entry* entry = m_entries[m_instance_map[instance]];
318  if (entry->instanceIndex == -1) {
319  return;
320  }
321 
322  // convert necessary instance update flags to entry update flags
323  const InstanceChangeInfo ici = instance->getChangeInfo();
324  if ((ici & ICHANGE_LOC) == ICHANGE_LOC) {
326  }
327  if ((ici & ICHANGE_ROTATION) == ICHANGE_ROTATION ||
328  (ici & ICHANGE_ACTION) == ICHANGE_ACTION ||
329  (ici & ICHANGE_TRANSPARENCY) == ICHANGE_TRANSPARENCY ||
330  (ici & ICHANGE_VISIBLE) == ICHANGE_VISIBLE) {
331  entry->updateInfo |= EntryVisualUpdate;
332  }
333 
334  // if entry is not already inserted
335  if (!entry->forceUpdate && entry->updateInfo != EntryNoneUpdate) {
336  entry->forceUpdate = true;
337  m_entriesToUpdate.insert(entry->entryIndex);
338  }
339  }
340 
342  std::vector<int32_t>& m_indices;
344  public:
345  CacheTreeCollector(std::vector<int32_t>& indices, const Rect& viewport)
346  : m_indices(indices), m_viewport(viewport) {
347  }
348  bool visit(LayerCache::CacheTree::Node* node, int32_t d = -1);
349  };
350 
352  if(!m_viewport.intersects(Rect(node->x(), node->y(),node->size(),node->size()))) {
353  return false;
354  }
355  m_indices.insert(m_indices.end(), node->data().begin(), node->data().end());
356  return true;
357  }
358 
359  void LayerCache::collect(const Rect& viewport, std::vector<int32_t>& index_list) {
360  CacheTree::Node * node = m_tree->find_container(viewport);
361  CacheTreeCollector collector(index_list, viewport);
362  node->apply_visitor(collector);
363  node = node->parent();
364  while(node) {
365  collector.visit(node);
366  node = node->parent();
367  }
368  }
369 
370  void LayerCache::update(Camera::Transform transform, RenderList& renderlist) {
371  if(!m_layer->areInstancesVisible()) {
372  FL_DBG(_log, "Layer instances hidden");
373  renderlist.clear();
374  return;
375  }
376  // if transform is none then we have only to update the instances with an update info.
377  if (transform == Camera::NoneTransform) {
378  if (!m_entriesToUpdate.empty()) {
379  std::set<int32_t> entryToRemove;
380  updateEntries(entryToRemove, renderlist);
381  //std::cout << "update entries: " << int32_t(m_entriesToUpdate.size()) << " remove entries: " << int32_t(entryToRemove.size()) <<"\n";
382  if (!entryToRemove.empty()) {
383  std::set<int32_t>::iterator entry_it = entryToRemove.begin();
384  for (; entry_it != entryToRemove.end(); ++entry_it) {
385  m_entriesToUpdate.erase(*entry_it);
386  }
387  }
388  }
389  } else {
390  m_zoom = m_camera->getZoom();
391  m_zoomed = !Mathd::Equal(m_zoom, 1.0);
392  m_straightZoom = Mathd::Equal(fmod(m_zoom, 1.0), 0.0);
393  // clear old renderlist
394  renderlist.clear();
395  // update all entries
396  fullUpdate(transform);
397 
398  // create viewport coordinates to collect entries
399  Rect viewport = m_camera->getViewPort();
400  Rect screenViewport = viewport;
401  DoublePoint3D viewport_a = m_camera->screenToVirtualScreen(Point3D(viewport.x, viewport.y));
402  DoublePoint3D viewport_b = m_camera->screenToVirtualScreen(Point3D(viewport.right(), viewport.bottom()));
403  viewport.x = static_cast<int32_t>(std::min(viewport_a.x, viewport_b.x));
404  viewport.y = static_cast<int32_t>(std::min(viewport_a.y, viewport_b.y));
405  viewport.w = static_cast<int32_t>(std::max(viewport_a.x, viewport_b.x) - viewport.x);
406  viewport.h = static_cast<int32_t>(std::max(viewport_a.y, viewport_b.y) - viewport.y);
407  m_zMin = 0.0;
408  m_zMax = 0.0;
409 
410  // FL_LOG(_log, LMsg("camera-update viewport") << viewport);
411  std::vector<int32_t> index_list;
412  collect(viewport, index_list);
413  // fill renderlist
414  for (uint32_t i = 0; i != index_list.size(); ++i) {
415  Entry* entry = m_entries[index_list[i]];
416  RenderItem* item = m_renderItems[entry->instanceIndex];
417  if (!item->image || !entry->visible) {
418  continue;
419  }
420 
421  if (item->dimensions.intersects(screenViewport)) {
422  renderlist.push_back(item);
423  if (!m_needSorting) {
424  m_zMin = std::min(m_zMin, item->screenpoint.z);
425  m_zMax = std::max(m_zMax, item->screenpoint.z);
426  }
427  }
428  }
429 
430  if (m_needSorting) {
431  sortRenderList(renderlist);
432  } else {
433  m_zMin -= 0.5;
434  m_zMax += 0.5;
435  sortRenderList(renderlist);
436  }
437  }
438  }
439 
441  bool rotationChange = (transform & Camera::RotationTransform) == Camera::RotationTransform;
442  for (uint32_t i = 0; i != m_entries.size(); ++i) {
443  Entry* entry = m_entries[i];
444  if (entry->instanceIndex != -1) {
445  if (rotationChange || entry->forceUpdate) {
446  updateVisual(entry);
447  }
448  updatePosition(entry);
449  }
450  }
451  }
452 
453  void LayerCache::updateEntries(std::set<int32_t>& removes, RenderList& renderlist) {
454  RenderList needSorting;
455  Rect viewport = m_camera->getViewPort();
456  std::set<int32_t>::const_iterator entry_it = m_entriesToUpdate.begin();
457  for (; entry_it != m_entriesToUpdate.end(); ++entry_it) {
458  Entry* entry = m_entries[*entry_it];
459  entry->forceUpdate = false;
460  if (entry->instanceIndex == -1) {
461  entry->updateInfo = EntryNoneUpdate;
462  removes.insert(*entry_it);
463  continue;
464  }
465  RenderItem* item = m_renderItems[entry->instanceIndex];
466  bool positionUpdate = (entry->updateInfo & EntryPositionUpdate) == EntryPositionUpdate;
467  if ((entry->updateInfo & EntryVisualUpdate) == EntryVisualUpdate) {
468  positionUpdate |= updateVisual(entry);
469  }
470  bool onScreenA = entry->visible && item->image && item->dimensions.intersects(viewport);
471  if (positionUpdate) {
472  updatePosition(entry);
473  }
474  bool onScreenB = entry->visible && item->image && item->dimensions.intersects(viewport);
475  if (onScreenA != onScreenB) {
476  if (!onScreenA) {
477  // add to renderlist and sort
478  renderlist.push_back(item);
479  needSorting.push_back(item);
480  } else {
481  // remove from renderlist
482  for (RenderList::iterator it = renderlist.begin(); it != renderlist.end(); ++it) {
483  if ((*it)->instance == item->instance) {
484  renderlist.erase(it);
485  break;
486  }
487  }
488  }
489  } else if (onScreenA && onScreenB && positionUpdate) {
490  // sort
491  needSorting.push_back(item);
492  }
493 
494  if (!entry->forceUpdate || !entry->visible) {
495  entry->forceUpdate = false;
496  entry->updateInfo = EntryNoneUpdate;
497  removes.insert(*entry_it);
498  } else {
499  entry->updateInfo = EntryVisualUpdate;
500  }
501  }
502 
503  if (!needSorting.empty()) {
504  if (m_needSorting) {
505  sortRenderList(renderlist);
506  } else {
507  sortRenderList(needSorting);
508  }
509  }
510  }
511 
513  RenderItem* item = m_renderItems[entry->instanceIndex];
514  Instance* instance = item->instance;
515  InstanceVisual* visual = instance->getVisual<InstanceVisual>();
516  item->facingAngle = instance->getRotation();
517  int32_t angle = static_cast<int32_t>(m_camera->getRotation()) + item->facingAngle;
518  Action* action = instance->getCurrentAction();
519  ImagePtr image;
520 
521  if (visual) {
522  uint8_t layerTrans = m_layer->getLayerTransparency();
523  uint8_t instanceTrans = visual->getTransparency();
524  if (layerTrans != 0) {
525  if (instanceTrans != 0) {
526  uint8_t calcTrans = layerTrans - instanceTrans;
527  if (calcTrans >= 0) {
528  instanceTrans = calcTrans;
529  } else {
530  instanceTrans = 0;
531  }
532  } else {
533  instanceTrans = layerTrans;
534  }
535  }
536  item->transparency = 255 - instanceTrans;
537  // only visible if visual is visible and item is not totally transparent
538  entry->visible = (visual->isVisible() && item->transparency != 0);
539  }
540 
541  if (!action) {
542  // Try static images then default action.
543  int32_t image_id = item->getStaticImageIndexByAngle(angle, instance);
544  if (image_id == -1) {
545  if (!instance->getObject()->isStatic()) {
546  action = instance->getObject()->getDefaultAction();
547  }
548  } else {
549  image = ImageManager::instance()->get(image_id);
550  }
551  }
552  entry->forceUpdate = (action != 0);
553 
554  if (action) {
555  AnimationPtr animation = action->getVisual<ActionVisual>()->getAnimationByAngle(angle);
556  uint32_t animationTime = instance->getActionRuntime() % animation->getDuration();
557  image = animation->getFrameByTimestamp(animationTime);
558 
559  int32_t actionFrame = animation->getActionFrame();
560  if (actionFrame != -1) {
561  if (item->image != image) {
562  int32_t new_frame = animation->getFrameIndex(animationTime);
563  if (actionFrame == new_frame) {
564  instance->callOnActionFrame(action, actionFrame);
565  // if action frame was skipped
566  } else if (new_frame > actionFrame && item->currentFrame < actionFrame) {
567  instance->callOnActionFrame(action, actionFrame);
568  }
569  item->currentFrame = new_frame;
570  }
571  }
572  }
573 
574  bool newPosition = false;
575  if (image != item->image) {
576  if (!item->image || !image) {
577  newPosition = true;
578  } else if (image->getWidth() != item->image->getWidth() ||
579  image->getHeight() != item->image->getHeight() ||
580  image->getXShift() != item->image->getXShift() ||
581  image->getYShift() != item->image->getYShift()) {
582  newPosition = true;
583  }
584  item->image = image;
585  }
586  return newPosition;
587  }
588 
590  RenderItem* item = m_renderItems[entry->instanceIndex];
591  Instance* instance = item->instance;
592  ExactModelCoordinate mapCoords = instance->getLocationRef().getMapCoordinates();
593  DoublePoint3D screenPosition = m_camera->toVirtualScreenCoordinates(mapCoords);
594  ImagePtr image = item->image;
595 
596  if (image) {
597  int32_t w = image->getWidth();
598  int32_t h = image->getHeight();
599  screenPosition.x = (screenPosition.x - w / 2.0) + image->getXShift();
600  screenPosition.y = (screenPosition.y - h / 2.0) + image->getYShift();
601  item->bbox.w = w;
602  item->bbox.h = h;
603  } else {
604  item->bbox.w = 0;
605  item->bbox.h = 0;
606  }
607  item->screenpoint = screenPosition;
608  item->bbox.x = static_cast<int32_t>(screenPosition.x);
609  item->bbox.y = static_cast<int32_t>(screenPosition.y);
610 
611  // seems wrong but these rounds fix the "wobbling" and gaps between tiles
612  // in case the zoom is 1.0
613  if (m_straightZoom) {
614  item->screenpoint.x = round(item->screenpoint.x);
615  item->screenpoint.y = round(item->screenpoint.y);
616  }
617  Point3D screenPoint = m_camera->virtualScreenToScreen(item->screenpoint);
618  // NOTE:
619  // One would expect this to be necessary here,
620  // however it works the same without, sofar
621  // m_camera->calculateZValue(screenPoint);
622  // item->screenpoint.z = -screenPoint.z;
623  item->dimensions.x = screenPoint.x;
624  item->dimensions.y = screenPoint.y;
625 
626  if (m_zoomed) {
627  // NOTE: Due to image alignment, there is additional additions on image dimensions
628  // There's probabaly some better solution for this, but works "good enough" for now.
629  // In case additions are removed, gaps appear between tiles.
630  // This is only needed if the zoom is a non-integer value.
631  if (!m_straightZoom) {
632  item->dimensions.w = round(static_cast<double>(item->bbox.w) * m_zoom + OVERDRAW);
633  item->dimensions.h = round(static_cast<double>(item->bbox.h) * m_zoom + OVERDRAW);
634  } else {
635  item->dimensions.w = round(static_cast<double>(item->bbox.w) * m_zoom);
636  item->dimensions.h = round(static_cast<double>(item->bbox.h) * m_zoom);
637  }
638  } else {
639  item->dimensions.w = item->bbox.w;
640  item->dimensions.h = item->bbox.h;
641  }
642 
643  CacheTree::Node* node = m_tree->find_container(item->bbox);
644  if (node) {
645  if (node != entry->node) {
646  if (entry->node) {
647  entry->node->data().erase(entry->entryIndex);
648  }
649  entry->node = node;
650  node->data().insert(entry->entryIndex);
651  }
652  }
653  }
654 
656  if (renderlist.empty()) {
657  return;
658  }
659  // We want to put every z value in [-10,10] range.
660  // To do it, we simply solve
661  // { y1 = a*x1 + b
662  // { y2 = a*x2 + b
663  // where [y1,y2]' = [-10,10]' is required z range,
664  // and [x1,x2]' is expected min,max z coords.
665  if (!m_needSorting) {
666  double det = m_zMin - m_zMax;
667  if (fabs(det) > FLT_EPSILON) {
668  double det_a = -10.0 - 10.0;
669  double det_b = 10.0 * m_zMin - (-10.0) * m_zMax;
670  double a = static_cast<float>(det_a / det);
671  double b = static_cast<float>(det_b / det);
672  float estimate = sqrtf(static_cast<float>(renderlist.size()));
673  float stack_delta = fabs(-10.0f - 10.0f) / estimate * 0.1f;
674 
675  RenderList::iterator it = renderlist.begin();
676  for ( ; it != renderlist.end(); ++it) {
677  double& z = (*it)->screenpoint.z;
678  z = a * z + b;
679  InstanceVisual* vis = (*it)->instance->getVisual<InstanceVisual>();
680  z += vis->getStackPosition() * stack_delta;
681  }
682  }
683  } else {
685  switch (strat) {
686  case SORTING_CAMERA: {
688  std::stable_sort(renderlist.begin(), renderlist.end(), ids);
689  } break;
690  case SORTING_LOCATION: {
692  std::stable_sort(renderlist.begin(), renderlist.end(), ids);
693  } break;
696  std::stable_sort(renderlist.begin(), renderlist.end(), ids);
697  } break;
698  default: {
700  std::stable_sort(renderlist.begin(), renderlist.end(), ids);
701  } break;
702  }
703  }
704  }
705 
707  return m_cacheImage;
708  }
709 
711  m_cacheImage = image;
712  }
713 }
bool visible
Definition: layercache.h:86
bool operator()(RenderItem *const &lhs, RenderItem *const &rhs)
Definition: layercache.cpp:90
void fullUpdate(Camera::Transform transform)
Definition: layercache.cpp:440
std::vector< RenderItem * > RenderList
Definition: renderitem.h:82
void updatePosition(Entry *entry)
Definition: layercache.cpp:589
void setLayer(Layer *layer)
Definition: layercache.cpp:208
QuadNode * parent()
Return the parent node.
Definition: quadtree.h:133
int32_t getStaticImageIndexByAngle(uint32_t angle, Instance *instance)
Returns closest matching static image for given angle.
Definition: renderitem.cpp:50
QuadTree< std::set< int32_t > > CacheTree
Definition: layercache.h:51
int32_t getStackPosition()
Gets current stack position of instance.
Definition: visual.cpp:140
Node * find_container(int32_t x, int32_t y, int32_t w, int32_t h)
Find a container node for a given rectangle.
Definition: quadtree.h:359
T h
Height of the rectangle.
Definition: rect.h:93
virtual ImagePtr get(const std::string &name)
Gets a shared pointer to the Image.
Instance visual contains data that is needed to visualize the instance on screen. ...
Definition: visual.h:111
void callOnActionFrame(Action *action, int32_t frame)
Auxiliary function to inform ActionListeners about the active ActionFrame.
Definition: instance.cpp:387
int32_t getXShift() const
Definition: image.h:117
T x
The X Coordinate.
Definition: rect.h:84
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
RenderList & getRenderListRef(Layer *layer)
Returns reference to RenderList.
Definition: camera.cpp:519
DoublePoint3D toVirtualScreenCoordinates(const ExactModelCoordinate &map_coords)
Transforms given point from map coordinates to virtual screen coordinates.
Definition: camera.cpp:428
DoublePoint3D screenpoint
Definition: renderitem.h:58
Action visual contains data that is needed to visualize different actions on screen.
Definition: visual.h:165
bool isStatic() const
Gets if object moves.
Definition: object.cpp:151
Instance * instance
Definition: renderitem.h:45
uint32_t getDuration() const
Gets the total duration for the whole animation.
Definition: animation.h:129
InstanceChangeInfo getChangeInfo()
Returns a bitmask of changes of the last update.
Definition: instance.cpp:891
int32_t facingAngle
Definition: renderitem.h:70
T * getVisual() const
Gets used visualization.
Definition: instance.h:331
int32_t getYShift() const
Definition: image.h:123
Action * getDefaultAction() const
Gets default action assigned to this object.
Definition: object.h:101
static Logger _log(LM_AUDIO)
PointType3D< int32_t > Point3D
Definition: point.h:325
DataType & data()
Return a reference to the data of the node.
Definition: quadtree.h:116
uint32_t getActionRuntime()
Gets the time in milliseconds how long action has been active In case there is no current action...
Definition: instance.cpp:853
bool operator()(RenderItem *const &lhs, RenderItem *const &rhs)
Definition: layercache.cpp:162
Action * getCurrentAction() const
Gets the currently active action.
Definition: instance.cpp:810
bool areInstancesVisible() const
Check object visibility.
Definition: layer.cpp:338
virtual void onInstanceCreate(Layer *layer, Instance *instance)
Called when some instance gets created on layer.
Definition: layercache.cpp:74
Camera describes properties of a view port shown in the main screen Main screen can have multiple cam...
Definition: camera.h:58
int32_t entryIndex
Definition: layercache.h:82
Camera * m_camera
Definition: layercache.h:99
static RenderBackend * instance()
Definition: singleton.h:84
Location & getLocationRef()
Gets reference of current location of instance.
Definition: instance.cpp:307
std::deque< int32_t > m_freeEntries
Definition: layercache.h:109
void apply_visitor(Visitor &visitor, int32_t d=0)
Apply a visitor recursively to the QuadTree A visitor is an object which has a visit method which tak...
Definition: quadtree.h:93
void sortRenderList(RenderList &renderlist)
Definition: layercache.cpp:655
virtual void onLayerChanged(Layer *layer, std::vector< Instance * > &instances)
Called when some instance is changed on layer.
Definition: layercache.cpp:67
RenderEntryUpdate updateInfo
Definition: layercache.h:88
int32_t getActionFrame() const
Gets the action frame.
Definition: animation.h:110
uint32_t getHeight() const
Definition: image.cpp:155
unsigned char uint8_t
Definition: core.h:38
bool isVisible()
Is instance visible or not.
Definition: visual.cpp:129
const Rect & getViewPort() const
Gets the viewport for camera in pixel coordinates.
Definition: camera.cpp:299
Comparison functions for sorting.
Definition: layercache.cpp:88
ImagePtr getFrameByTimestamp(uint32_t timestamp)
Gets the frame image that matches the given timestamp.
Definition: animation.cpp:99
T bottom() const
The Y coordinate of the bottom edge.
Definition: rect.h:173
void removeChangeListener(LayerChangeListener *listener)
Removes associated change listener.
Definition: layer.cpp:512
static bool Equal(T _val1, T _val2)
Definition: fife_math.h:286
Definition: layercache.h:76
Object * getObject()
Gets object where this instance is instantiated from.
Definition: instance.cpp:280
std::vector< RenderItem * > m_renderItems
Definition: layercache.h:107
uint32_t InstanceChangeInfo
Definition: instance.h:73
ImagePtr getCacheImage()
Definition: layercache.cpp:706
int32_t getRotation() const
Get the rotation offset of this instance Returns direction where instance is heading.
Definition: instance.cpp:327
A basic layer on a map.
Definition: layer.h:98
double getZoom() const
Gets camera zoom.
Definition: camera.cpp:168
CacheTreeCollector(std::vector< int32_t > &indices, const Rect &viewport)
Definition: layercache.cpp:345
Listener interface for changes happening on a layer.
Definition: layer.h:70
CacheLayerChangeListener * m_layerObserver
Definition: layercache.h:101
int32_t getFrameIndex(uint32_t timestamp)
Get the frame index that matches given timestamp.
Definition: animation.cpp:72
CacheTree * m_tree
Definition: layercache.h:102
SortingStrategy
Definition: layer.h:62
void addChangeListener(LayerChangeListener *listener)
Adds new change listener.
Definition: layer.cpp:508
void setCacheImage(ImagePtr image)
Definition: layercache.cpp:710
bool forceUpdate
Definition: layercache.h:84
ExactModelCoordinate & getExactLayerCoordinatesRef()
Gets reference to exact layer coordinates.
Definition: location.cpp:105
uint32_t getWidth() const
Definition: image.cpp:146
T y
The Y Coordinate.
Definition: rect.h:87
CacheLayerChangeListener(LayerCache *cache)
Definition: layercache.cpp:62
virtual void onInstanceDelete(Layer *layer, Instance *instance)
Called when some instance gets deleted on layer.
Definition: layercache.cpp:78
std::vector< Entry * > m_entries
Definition: layercache.h:106
void collect(const Rect &viewport, std::vector< int32_t > &indices)
Definition: layercache.cpp:359
std::vector< int32_t > & m_indices
Definition: layercache.cpp:342
QuadTree Node.
Definition: quadtree.h:41
int32_t instanceIndex
Definition: layercache.h:80
T right() const
The X coordinate of the right edge.
Definition: rect.h:168
bool intersects(const RectType< T > &rect) const
Check whether two rectangles share some area.
Definition: rect.h:227
uint32_t Transform
Definition: camera.h:68
ImagePtr image
Definition: renderitem.h:67
ImagePtr m_cacheImage
Definition: layercache.h:103
bool visit(LayerCache::CacheTree::Node *node, int32_t d=-1)
Definition: layercache.cpp:351
LayerCache(Camera *camera)
Definition: layercache.cpp:177
uint8_t getTransparency()
Gets current transparency value (0-255)
Definition: visual.cpp:118
SortingStrategy getSortingStrategy() const
Gets sorting strategy for the layer.
Definition: layer.cpp:399
bool operator()(RenderItem *const &lhs, RenderItem *const &rhs)
Definition: layercache.cpp:136
int32_t y() const
Return the Y position of the node.
Definition: quadtree.h:108
CacheTree::Node * node
Definition: layercache.h:78
void update(Camera::Transform transform, RenderList &renderlist)
Definition: layercache.cpp:370
const std::vector< Instance * > & getInstances() const
Get the list of instances on this layer.
Definition: layer.cpp:228
void removeInstance(Instance *instance)
Definition: layercache.cpp:282
InstanceDistanceSortLocation(double rotation)
Definition: layercache.cpp:102
void updateEntries(std::set< int32_t > &removes, RenderList &renderlist)
Definition: layercache.cpp:453
void addInstance(Instance *instance)
Definition: layercache.cpp:246
int32_t size() const
Return the size (width and height) of the node.
Definition: quadtree.h:112
unsigned int uint32_t
Definition: core.h:40
DoublePoint3D screenToVirtualScreen(const ScreenPoint &p)
Definition: camera.cpp:437
int32_t x() const
Return the X position of the node.
Definition: quadtree.h:104
bool updateVisual(Entry *entry)
Definition: layercache.cpp:512
uint8_t getLayerTransparency()
Returns the layer&#39;s transparency value.
Definition: layer.cpp:330
ExactModelCoordinate getExactLayerCoordinates() const
Gets exact layer coordinates set to this location.
Definition: location.cpp:109
uint8_t transparency
Definition: renderitem.h:73
T w
Width of the rectangle.
Definition: rect.h:90
#define FL_DBG(logger, msg)
Definition: logger.h:70
std::map< Instance *, int32_t > m_instance_map
Definition: layercache.h:105
std::set< int32_t > m_entriesToUpdate
Definition: layercache.h:108
An Instance is an &quot;instantiation&quot; of an Object at a Location.
Definition: instance.h:97
const double OVERDRAW
Definition: layercache.cpp:58
ScreenPoint virtualScreenToScreen(const DoublePoint3D &p)
Definition: camera.cpp:433
ExactModelCoordinate getMapCoordinates() const
Gets map coordinates set to this location.
Definition: location.cpp:117
void reset()
Resets the important values.
Definition: renderitem.cpp:66
void updateInstance(Instance *instance)
Definition: layercache.cpp:316
double getRotation() const
Gets camera rotation.
Definition: camera.cpp:153
int32_t currentFrame
Definition: renderitem.h:76