# HG changeset patch # User helios2000@33b003aa-7bff-0310-803a-e67f0ece8222 # Date 1272549105 0 # Node ID 16c2b3ee59ce1fd65f67af49b61f56075b55037f # Parent 1f37adc9a6854a65c208580c8875e656bff8116f * Merged the view performance branch back into trunk. fixes[ticket:419] diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/gui/console/console.cpp --- a/engine/core/gui/console/console.cpp Wed Apr 28 21:33:11 2010 +0000 +++ b/engine/core/gui/console/console.cpp Thu Apr 29 13:51:45 2010 +0000 @@ -171,15 +171,15 @@ setPosition(getX(), getY() - m_animationDelta); if (getY() <= m_hiddenPos){ doHide(); - m_animationTimer.stop(); + m_animationTimer.stop(); } }else{ setPosition(getX(), getY() + m_animationDelta); if (getY() >= 0){ setPosition(getX(), 0); - m_animationTimer.stop(); + m_animationTimer.stop(); } - } + } } void Console::clear() { diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/model/structures/instance.cpp --- a/engine/core/model/structures/instance.cpp Wed Apr 28 21:33:11 2010 +0000 +++ b/engine/core/model/structures/instance.cpp Thu Apr 29 13:51:45 2010 +0000 @@ -203,13 +203,23 @@ void Instance::initializeChanges() { if (!m_activity) { m_activity = new InstanceActivity(*this); + if(m_location.getLayer()) { + m_location.getLayer()->setInstanceActivityStatus(this, true); + } } } + + bool Instance::isActive() const { + return bool(m_activity); + } void Instance::setLocation(const Location& loc) { - initializeChanges(); m_location = loc; - bindTimeProvider(); + if(isActive()) { + refresh(); + } else { + initializeChanges(); + } } void Instance::setRotation(int rotation) { diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/model/structures/instance.h --- a/engine/core/model/structures/instance.h Wed Apr 28 21:33:11 2010 +0000 +++ b/engine/core/model/structures/instance.h Thu Apr 29 13:51:45 2010 +0000 @@ -250,6 +250,10 @@ * @returns marked changes */ InstanceChangeInfo update(); + + /** If this returns true, the instance needs to be updated + */ + bool isActive() const; /** Sets visualization to be used. Transfers ownership. */ diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/model/structures/layer.cpp --- a/engine/core/model/structures/layer.cpp Wed Apr 28 21:33:11 2010 +0000 +++ b/engine/core/model/structures/layer.cpp Thu Apr 29 13:51:45 2010 +0000 @@ -68,11 +68,14 @@ } Instance* Layer::createInstance(Object* object, const ExactModelCoordinate& p, const std::string& id) { - Location l; - l.setLayer(this); - l.setExactLayerCoordinates(p); + Location location; + location.setLayer(this); + location.setExactLayerCoordinates(p); - Instance* instance = new Instance(object, l, id); + Instance* instance = new Instance(object, location, id); + if(instance->isActive()) { + setInstanceActivityStatus(instance, instance->isActive()); + } m_instances.push_back(instance); m_instanceTree->addInstance(instance); @@ -91,12 +94,16 @@ return false; } - Location l; - l.setLayer(this); - l.setExactLayerCoordinates(p); + Location location; + location.setLayer(this); + location.setExactLayerCoordinates(p); + instance->setLocation(location); m_instances.push_back(instance); m_instanceTree->addInstance(instance); + if(instance->isActive()) { + setInstanceActivityStatus(instance, instance->isActive()); + } std::vector::iterator i = m_changelisteners.begin(); while (i != m_changelisteners.end()) { @@ -113,7 +120,7 @@ (*i)->onInstanceDelete(this, instance); ++i; } - + setInstanceActivityStatus(instance, false); std::vector::iterator it = m_instances.begin(); for(; it != m_instances.end(); ++it) { if(*it == instance) { @@ -126,6 +133,14 @@ m_changed = true; } + void Layer::setInstanceActivityStatus(Instance* instance, bool active) { + if(active) { + m_active_instances.insert(instance); + } else { + m_active_instances.erase(instance); + } + } + Instance* Layer::getInstance(const std::string& id) { std::vector::iterator it = m_instances.begin(); for(; it != m_instances.end(); ++it) { @@ -232,8 +247,8 @@ bool Layer::update() { m_changedinstances.clear(); - std::vector::iterator it = m_instances.begin(); - for(; it != m_instances.end(); ++it) { + std::set::iterator it = m_active_instances.begin(); + for(; it != m_active_instances.end(); ++it) { if ((*it)->update() != ICHANGE_NO_CHANGES) { m_changedinstances.push_back(*it); m_changed = true; diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/model/structures/layer.h --- a/engine/core/model/structures/layer.h Wed Apr 28 21:33:11 2010 +0000 +++ b/engine/core/model/structures/layer.h Thu Apr 29 13:51:45 2010 +0000 @@ -26,6 +26,7 @@ #include #include #include +#include // 3rd party library includes @@ -238,6 +239,8 @@ */ std::vector& getChangedInstances() { return m_changedinstances; } + void setInstanceActivityStatus(Instance* instance, bool active); + protected: std::string m_id; @@ -250,6 +253,9 @@ // all the instances on this layer std::vector m_instances; + // all the active instances on this layer + std::set m_active_instances; + //The instance tree InstanceTree* m_instanceTree; diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/util/math/matrix.h --- a/engine/core/util/math/matrix.h Wed Apr 28 21:33:11 2010 +0000 +++ b/engine/core/util/math/matrix.h Thu Apr 29 13:51:45 2010 +0000 @@ -223,6 +223,10 @@ assert(ind > -1 && ind < 16); return m[ind]; } + inline const T& operator[] (int ind) const { + assert(ind > -1 && ind < 16); + return m[ind]; + } /** Apply the matrix dot product to this matrix */ @@ -374,7 +378,8 @@ /** Print coords of the Matrix to a stream */ template - std::ostream& operator<<(std::ostream& os, Matrix& m) { + std::ostream& operator<<(std::ostream& os, const Matrix& m) { + return os << "\n|" << m[0] << "," << m[4] << "," << m[8] << "," << m[12] << "|\n" << \ "|" << m[1] << "," << m[5] << "," << m[9] << "," << m[13] << "|\n" << \ "|" << m[2] << "," << m[6] << "," << m[10] << "," << m[14] << "|\n" << \ diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/video/animation.cpp --- a/engine/core/video/animation.cpp Wed Apr 28 21:33:11 2010 +0000 +++ b/engine/core/video/animation.cpp Thu Apr 29 13:51:45 2010 +0000 @@ -82,7 +82,7 @@ bool Animation::isValidIndex(int index) const{ int size = m_frames.size(); return size > 0 && index >= 0 && index < size; - } + } Image* Animation::getFrame(int index) { if (isValidIndex(index)) { diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/view/camera.cpp --- a/engine/core/view/camera.cpp Wed Apr 28 21:33:11 2010 +0000 +++ b/engine/core/view/camera.cpp Thu Apr 29 13:51:45 2010 +0000 @@ -48,12 +48,34 @@ #include "video/animationpool.h" #include "camera.h" +#include "layercache.h" #include "visual.h" namespace FIFE { static Logger _log(LM_CAMERA); + class MapObserver : public MapChangeListener { + Camera* m_camera; + + public: + MapObserver(Camera* camera) { + m_camera = camera; + } + virtual ~MapObserver() {} + + virtual void onMapChanged(Map* map, std::vector& changedLayers) { + } + + virtual void onLayerCreate(Map* map, Layer* layer) { + m_camera->addLayer(layer); + } + + virtual void onLayerDelete(Map* map, Layer* layer) { + m_camera->removeLayer(layer); + } + }; + Camera::Camera(const std::string& id, Layer *layer, const Rect& viewport, @@ -85,24 +107,35 @@ m_ipool(ipool), m_apool(apool), m_layer_to_instances() { - m_location.setLayer(layer); - m_location.setExactLayerCoordinates(emc); + m_viewport = viewport; + m_map_observer = new MapObserver(this); + m_map = 0; + Location location; + location.setLayer(layer); + location.setExactLayerCoordinates(emc); + setLocation(location); } Camera::~Camera() { + // Trigger removal of LayerCaches and MapObserver + updateMap(NULL); + std::map::iterator r_it = m_renderers.begin(); for(; r_it != m_renderers.end(); ++r_it) { delete r_it->second; } m_renderers.clear(); + delete m_map_observer; } void Camera::setTilt(double tilt) { - m_tilt = tilt; - updateReferenceScale(); - updateMatrices(); - m_iswarped = true; + if(m_tilt != tilt) { + m_tilt = tilt; + updateReferenceScale(); + updateMatrices(); + m_iswarped = true; + } } double Camera::getTilt() const { @@ -110,10 +143,12 @@ } void Camera::setRotation(double rotation) { - m_rotation = rotation; - updateReferenceScale(); - updateMatrices(); - m_iswarped = true; + if(m_rotation != rotation) { + m_rotation = rotation; + updateReferenceScale(); + updateMatrices(); + m_iswarped = true; + } } double Camera::getRotation() const { @@ -121,12 +156,13 @@ } void Camera::setZoom(double zoom) { - m_zoom = zoom; - if (m_zoom < 0.001) { - m_zoom = 0.001; + if(m_zoom!=zoom) { + m_zoom = zoom; + if (m_zoom < 0.001) { + m_zoom = 0.001; + } + updateMatrices(); } - updateMatrices(); - m_iswarped = true; } double Camera::getZoom() const { @@ -147,23 +183,52 @@ m_cur_origo = toScreenCoordinates(ExactModelCoordinate(0,0,0)); m_prev_origo = m_cur_origo; } - m_location = location; - CellGrid* cg = NULL; - if (m_location.getLayer()) { - cg = m_location.getLayer()->getCellGrid(); + CellGrid* cell_grid = NULL; + if (location.getLayer()) { + cell_grid = location.getLayer()->getCellGrid(); } else { throw Exception("Location without layer given to Camera::setLocation"); } - if (!cg) { + if (!cell_grid) { throw Exception("Camera layer has no cellgrid specified"); } + m_location = location; updateMatrices(); + // WARNING + // It is important that m_location is already set, + // as the updates which are triggered here + // need to calculate screen-coordinates + // which depend on m_location. + updateMap(location.getMap()); + m_cur_origo = toScreenCoordinates(ExactModelCoordinate(0,0,0)); } + void Camera::updateMap(Map* map) + { + if(m_map == map) + { + return; + } + if(m_map) { + m_map->removeChangeListener(m_map_observer); + const std::list& layers = m_map->getLayers(); + for(std::list::const_iterator i = layers.begin(); i !=layers.end(); ++i) { + removeLayer(*i); + } + } + if(map) { + map->addChangeListener(m_map_observer); + const std::list& layers = map->getLayers(); + for(std::list::const_iterator i = layers.begin(); i !=layers.end(); ++i) + addLayer(*i); + } + m_map = map; + } + Point Camera::getCellImageDimensions() { return getCellImageDimensions(m_location.getLayer()); } @@ -209,10 +274,15 @@ bool Camera::isEnabled() { return m_enabled; } - + + Point3D Camera::getOrigin() const { + return m_cur_origo; + } + void Camera::updateMatrices() { double scale = m_reference_scale; m_matrix.loadScale(scale, scale, scale); + m_vs_matrix.loadScale(scale,scale,scale); if (m_location.getLayer()) { CellGrid* cg = m_location.getLayer()->getCellGrid(); if (cg) { @@ -224,7 +294,31 @@ m_matrix.applyScale(scale, scale, scale); m_matrix.applyRotate(-m_rotation, 0.0, 0.0, 1.0); m_matrix.applyRotate(-m_tilt, 1.0, 0.0, 0.0); + m_matrix.applyTranslate(+m_viewport.w/2, +m_viewport.h/2, 0); m_inverse_matrix = m_matrix.inverse(); + + + m_vs_matrix.applyTranslate(0,0,0); + m_vs_matrix.applyRotate(-m_rotation, 0.0, 0.0, 1.0); + m_vs_matrix.applyRotate(-m_tilt, 1.0, 0.0, 0.0); + m_vs_inverse_matrix = m_vs_matrix.inverse(); + + // calculate the screen<->virtual screen transformation + // this explicitly ignores the z-value. + m_vscreen_2_screen = m_matrix; + // NOTE: mult4by4 is an in-place modification. + m_vscreen_2_screen.mult4by4(m_vs_inverse_matrix); + // set the z transformation to unity + const int N=4; + for(int i=0; i!=N; ++i) { + m_vscreen_2_screen[2*N + i] = 0; + m_vscreen_2_screen[i*N + 2] = 0; + } + m_vscreen_2_screen[2*N + 2] = 1; + m_screen_2_vscreen = m_vscreen_2_screen.inverse(); + + // FL_WARN(_log, LMsg("matrix: ") << m_matrix << " 1: " << m_matrix.inverse().mult4by4(m_matrix)); +// FL_WARN(_log, LMsg("vs2s matrix: ") << m_vscreen_2_screen << " s2vs matrix: " << m_screen_2_vscreen); } void Camera::calculateZValue(ScreenPoint& screen_coords) { @@ -236,19 +330,28 @@ if (!z_calculated) { calculateZValue(screen_coords); } - screen_coords.x -= m_viewport.w / 2; - screen_coords.y -= m_viewport.h / 2; - return m_inverse_matrix * intPt2doublePt(screen_coords); } ScreenPoint Camera::toScreenCoordinates(ExactModelCoordinate elevation_coords) { ExactModelCoordinate p = elevation_coords; ScreenPoint pt = doublePt2intPt( m_matrix* p ); - pt.x += m_viewport.w / 2; - pt.y += m_viewport.h / 2; + return pt; + } + + DoublePoint3D Camera::toVirtualScreenCoordinates(ExactModelCoordinate elevation_coords) { + ExactModelCoordinate p = elevation_coords; + DoublePoint3D pt = (m_vs_matrix * p); return pt; } + + ScreenPoint Camera::virtualScreenToScreen(const DoublePoint3D& p) { + return doublePt2intPt(m_vscreen_2_screen * p); + } + + DoublePoint3D Camera::screenToVirtualScreen(const ScreenPoint& p) { + return m_screen_2_vscreen * intPt2doublePt(p); + } DoublePoint Camera::getLogicalCellDimensions(Layer* layer) { CellGrid* cg = NULL; @@ -292,13 +395,12 @@ void Camera::getMatchingInstances(ScreenPoint screen_coords, Layer& layer, std::list& instances) { instances.clear(); - const std::vector& layer_instances = m_layer_to_instances[&layer]; - std::vector::const_iterator instance_it = layer_instances.end(); + const RenderList& layer_instances = m_layer_to_instances[&layer]; + RenderList::const_iterator instance_it = layer_instances.end(); while (instance_it != layer_instances.begin()) { --instance_it; - Instance* i = (*instance_it); - InstanceVisual* visual = i->getVisual(); - InstanceVisualCacheItem& vc = visual->getCacheItem(this); + Instance* i = (*instance_it)->instance; + const RenderItem& vc = **instance_it; if ((vc.dimensions.contains(Point(screen_coords.x, screen_coords.y)))) { assert(vc.image); Uint8 r, g, b, a; @@ -325,13 +427,12 @@ void Camera::getMatchingInstances(Rect screen_rect, Layer& layer, std::list& instances) { instances.clear(); - const std::vector& layer_instances = m_layer_to_instances[&layer]; - std::vector::const_iterator instance_it = layer_instances.end(); + const RenderList& layer_instances = m_layer_to_instances[&layer]; + RenderList::const_iterator instance_it = layer_instances.end(); while (instance_it != layer_instances.begin()) { --instance_it; - Instance* i = (*instance_it); - InstanceVisual* visual = i->getVisual(); - InstanceVisualCacheItem& vc = visual->getCacheItem(this); + Instance* i = (*instance_it)->instance;; + const RenderItem& vc = **instance_it; if ((vc.dimensions.intersects(screen_rect))) { assert(vc.image); Uint8 r, g, b, a; @@ -366,11 +467,11 @@ void Camera::getMatchingInstances(Location& loc, std::list& instances, bool use_exactcoordinates) { instances.clear(); - const std::vector& layer_instances = m_layer_to_instances[loc.getLayer()]; - std::vector::const_iterator instance_it = layer_instances.end(); + const RenderList& layer_instances = m_layer_to_instances[loc.getLayer()]; + RenderList::const_iterator instance_it = layer_instances.end(); while (instance_it != layer_instances.begin()) { --instance_it; - Instance* i = (*instance_it); + Instance* i = (*instance_it)->instance; if (use_exactcoordinates) { if (i->getLocationRef().getExactLayerCoordinatesRef() == loc.getExactLayerCoordinatesRef()) { instances.push_back(i); @@ -448,21 +549,6 @@ return m_renderers[name]; } - class InstanceDistanceSort { - public: - Camera* cam; - inline bool operator()(const Instance* lhs, const Instance* rhs) { - InstanceVisual* liv = lhs->getVisual(); - InstanceVisual* riv = rhs->getVisual(); - InstanceVisualCacheItem& lic = liv->getCacheItem(cam); - InstanceVisualCacheItem& ric = riv->getCacheItem(cam); - if (lic.screenpoint.z == ric.screenpoint.z) { - return liv->getStackPosition() < riv->getStackPosition(); - } - return lic.screenpoint.z < ric.screenpoint.z; - } - }; - void Camera::resetRenderers() { std::map::iterator r_it = m_renderers.begin(); for (; r_it != m_renderers.end(); ++r_it) { @@ -471,8 +557,23 @@ } } + void Camera::addLayer(Layer* layer) { + m_cache[layer] = new LayerCache(this, m_ipool, m_apool); + m_cache[layer]->setLayer(layer); + m_layer_to_instances[layer] = RenderList(); + } + + void Camera::removeLayer(Layer* layer) { + delete m_cache[layer]; + m_cache.erase(layer); + m_layer_to_instances.erase(layer); + } + void Camera::render() { - ScreenPoint cammove = m_prev_origo - m_cur_origo; + Transform transform = NormalTransform; + if(m_iswarped) + transform = WarpedTransform; + m_iswarped = false; Map* map = m_location.getMap(); if (!map) { @@ -485,118 +586,18 @@ // update each layer m_renderbackend->pushClipArea(getViewPort()); - - m_layer_to_instances.clear(); - +// m_layer_to_instances.clear(); const std::list& layers = map->getLayers(); std::list::const_iterator layer_it = layers.begin(); for (;layer_it != layers.end(); ++layer_it) { - - // sort instances on layer based on stack position + camera distance. done only once - // here instead passing it to each renderer. - // instances are checked first if their image intersects with the viewport. - // this reduces processing load during sorting later - const std::vector& allinstances = (*layer_it)->getInstances(); - std::vector::const_iterator instance_it = allinstances.begin(); - std::vector& instances_to_render = m_layer_to_instances[*layer_it]; - for (;instance_it != allinstances.end(); ++instance_it) { - Instance* instance = *instance_it; - InstanceVisual* visual = instance->getVisual(); - if(!visual->isVisible()) - continue; - InstanceVisualCacheItem& vc = visual->getCacheItem(this); - - // use cached values if there is no need to do full recalculation - ScreenPoint drawpt; - int angle = 0; - if (m_updated && (!m_iswarped) && (!(instance->getChangeInfo() & (ICHANGE_LOC | ICHANGE_ROTATION | ICHANGE_FACING_LOC))) && (vc.image)) { - int pos_estimate_x = vc.screenpoint.x - cammove.x; - int pos_estimate_y = vc.screenpoint.y - cammove.y; - int pos_estimate_z = vc.screenpoint.z - cammove.z; - angle = vc.facing_angle; - //std::cout << "orig x = " << drawpt.x << ", est x = " << pos_estimate_x << "\n"; - //std::cout << "orig y = " << drawpt.y << ", est y = " << pos_estimate_y << "\n"; - drawpt.x = pos_estimate_x; - drawpt.y = pos_estimate_y; - drawpt.z = pos_estimate_z; - //drawpt.z = toScreenCoordinates( instance->getLocationRef().getMapCoordinates() ).z; - } else { - drawpt = toScreenCoordinates( instance->getLocationRef().getMapCoordinates() ); - vc.facing_angle = getAngleBetween(instance->getLocationRef(), instance->getFacingLocation()); - angle = vc.facing_angle; - } - - //generate angle based on camera rotation and instance rotation - angle = angle + m_rotation + instance->getRotation(); - - Image* image = NULL; - Action* action = instance->getCurrentAction(); - if (action) { - FL_DBG(_log, "Instance has action"); - int animation_id = action->getVisual()->getAnimationIndexByAngle(vc.facing_angle + m_rotation); - - int facing_angle = vc.facing_angle; - if (facing_angle < 0){ - facing_angle = 360+facing_angle; //make it a positive angle - } - facing_angle %= 360; - instance->setRotation(facing_angle); //update so the animation has correct rotation - - Animation& animation = m_apool->getAnimation(animation_id); - unsigned int animtime = instance->getActionRuntime() % animation.getDuration(); - image = animation.getFrameByTimestamp(animtime); - } else { - FL_DBG(_log, "No action"); - int imageid = vc.getStaticImageIndexByAngle(angle, instance); - FL_DBG(_log, LMsg("Instance does not have action, using static image with id ") << imageid); - if (imageid >= 0) { - image = &m_ipool->getImage(imageid); - } else { - // there was no static image for instance, trying default action - action = instance->getObject()->getDefaultAction(); - if (action) { - int animation_id = action->getVisual()->getAnimationIndexByAngle(angle); - Animation& animation = m_apool->getAnimation(animation_id); - unsigned int animtime = instance->getActionRuntime() % animation.getDuration(); - image = animation.getFrameByTimestamp(animtime); - } - } - } - if (image) { - vc.image = image; - vc.screenpoint = drawpt; - - int w = image->getWidth(); - int h = image->getHeight(); - drawpt.x -= w / 2; - drawpt.x += image->getXShift(); - drawpt.y -= h / 2; - drawpt.y += image->getYShift(); - Rect r = Rect(drawpt.x, drawpt.y, w, h); - - vc.dimensions = r; - if (m_zoom != 1.0) { - // NOTE: Due to image alignment, there is additional additions and substractions on image dimensions - // There's probabaly some better solution for this, but works "good enough" for now. - // In case additions / substractions are removed, gaps appear between tiles. - r.w = static_cast(ceil(static_cast(vc.dimensions.w) * m_zoom)) + 2; - r.h = static_cast(ceil(static_cast(vc.dimensions.h) * m_zoom)) + 2; - int xo = static_cast(ceil(static_cast(vc.image->getXShift()) * m_zoom)) - vc.image->getXShift(); - int yo = static_cast(ceil(static_cast(vc.image->getYShift()) * m_zoom)) - vc.image->getYShift(); - r.x = vc.dimensions.x - static_cast(ceil(static_cast(r.w - vc.dimensions.w) / 2)) + xo - 1; - r.y = vc.dimensions.y - static_cast(ceil(static_cast(r.h - vc.dimensions.h) / 2)) + yo - 1; - vc.dimensions = r; - } - - if (vc.dimensions.intersects(getViewPort())) { - instances_to_render.push_back(instance); - } - } + LayerCache* cache = m_cache[*layer_it]; + if(!cache) { + addLayer(*layer_it); + cache = m_cache[*layer_it]; + FL_ERR(_log, LMsg("Layer Cache miss! (This shouldn't happen!)") << (*layer_it)->getId()); } - - InstanceDistanceSort ids; - ids.cam = this; - std::stable_sort(instances_to_render.begin(), instances_to_render.end(), ids); + RenderList& instances_to_render = m_layer_to_instances[*layer_it]; + cache->update(transform, instances_to_render); std::list::iterator r_it = m_pipeline.begin(); for (; r_it != m_pipeline.end(); ++r_it) { diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/view/camera.h --- a/engine/core/view/camera.h Wed Apr 28 21:33:11 2010 +0000 +++ b/engine/core/view/camera.h Thu Apr 29 13:51:45 2010 +0000 @@ -47,7 +47,9 @@ class ImagePool; class AnimationPool; class RenderBackend; - typedef std::map > t_layer_to_instances; + class LayerCache; + class MapObserver; + typedef std::map t_layer_to_instances; /** Camera describes properties of a view port shown in the main screen * Main screen can have multiple cameras active simultanously @@ -56,6 +58,11 @@ */ class Camera: public IRendererListener, public IRendererContainer { public: + enum Transform { + NormalTransform = 0, + WarpedTransform = 1 + }; + /** Constructor * Camera needs to be added to the view. If not done so, it is not rendered. * @param id identifier for the camera @@ -149,6 +156,8 @@ */ Location getLocation() const; + Point3D getOrigin() const; + /** Gets a reference to the camera location * @note if you change returned location without calling Camera::setLocation(...), * remember to call Camera::refresh() (otherwise camera transforms are not updated) @@ -193,6 +202,14 @@ */ ScreenPoint toScreenCoordinates(ExactModelCoordinate map_coords); + /** Transforms given point from map coordinates to virtual screen coordinates + * @return point in screen coordinates + */ + DoublePoint3D toVirtualScreenCoordinates(ExactModelCoordinate map_coords); + + ScreenPoint virtualScreenToScreen(const DoublePoint3D& p); + DoublePoint3D screenToVirtualScreen(const ScreenPoint& p); + /** Sets camera enabled / disabled */ void setEnabled(bool enabled); @@ -266,9 +283,13 @@ /** Renders camera */ void render(); + private: + friend class MapObserver; + void addLayer(Layer* layer); + void removeLayer(Layer* layer); + void updateMap(Map* map); + std::string m_id; - private: - std::string m_id; /** Updates the camera transformation matrix T with requested values. * The requests are done using these functions : @@ -292,6 +313,12 @@ DoubleMatrix m_matrix; DoubleMatrix m_inverse_matrix; + + DoubleMatrix m_vs_matrix; + DoubleMatrix m_vs_inverse_matrix; + DoubleMatrix m_vscreen_2_screen; + DoubleMatrix m_screen_2_vscreen; + double m_tilt; double m_rotation; double m_zoom; @@ -320,6 +347,10 @@ // caches layer -> instances structure between renders e.g. to fast query of mouse picking order t_layer_to_instances m_layer_to_instances; + + std::map m_cache; + MapObserver* m_map_observer; + Map* m_map; }; } #endif diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/view/layercache.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/engine/core/view/layercache.cpp Thu Apr 29 13:51:45 2010 +0000 @@ -0,0 +1,345 @@ +/*************************************************************************** + * Copyright (C) 2005-2008 by the FIFE team * + * http://www.fifengine.de * + * This file is part of FIFE. * + * * + * FIFE is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +// Standard C++ library includes + +// 3rd party library includes +#include + +// FIFE includes +// These includes are split up in two parts, separated by one empty line +// First block: files included from the FIFE root src directory +// Second block: files included from the same folder + +#include "model/metamodel/grids/cellgrid.h" +#include "model/metamodel/action.h" +#include "model/structures/layer.h" +#include "model/structures/instance.h" +#include "model/structures/location.h" +#include "util/base/exception.h" +#include "util/log/logger.h" +#include "util/math/fife_math.h" +#include "util/math/angles.h" +#include "video/renderbackend.h" +#include "video/image.h" +#include "video/imagepool.h" +#include "video/animation.h" +#include "video/animationpool.h" + +#include "camera.h" +#include "layercache.h" +#include "visual.h" + + +namespace FIFE { + static Logger _log(LM_CAMERA); + + class CacheLayerChangeListener : public LayerChangeListener { + public: + CacheLayerChangeListener(LayerCache* cache) + { + m_cache = cache; + } + virtual ~CacheLayerChangeListener() {}; + + virtual void onLayerChanged(Layer* layer, std::vector& instances) + { + for(std::vector::iterator i = instances.begin(); + i != instances.end(); ++i) { + m_cache->updateInstance(*i); + } + } + + virtual void onInstanceCreate(Layer* layer, Instance* instance) + { + m_cache->addInstance(instance); + } + + virtual void onInstanceDelete(Layer* layer, Instance* instance) + { + m_cache->removeInstance(instance); + } + private: + LayerCache* m_cache; + }; + + LayerCache::LayerCache(Camera* camera, ImagePool* image_pool, AnimationPool* animation_pool) { + m_camera = camera; + m_image_pool = image_pool; + m_animation_pool = animation_pool; + m_layer = 0; + m_tree = 0; + } + + LayerCache::~LayerCache() { + m_layer->removeChangeListener(m_layer_observer); + delete m_layer_observer; + delete m_tree; + } + + void LayerCache::setLayer(Layer* layer) { + m_layer = layer; + m_layer_observer = new CacheLayerChangeListener(this); + layer->addChangeListener(m_layer_observer); + reset(); + } + + void LayerCache::reset() { + m_instances.clear(); + delete m_tree; + m_tree = new CacheTree; + const std::vector& instances = m_layer->getInstances(); + for(std::vector::const_iterator i = instances.begin(); + i != instances.end(); ++i) { + addInstance(*i); + } + } + + void LayerCache::addInstance(Instance* instance) { + if(m_instance_map.find(instance)!=m_instance_map.end()) { + throw new Duplicate(instance->getId()); + } + + RenderItem item; + Entry entry; + item.instance = instance; + m_instances.push_back(item); + m_instance_map[instance] = m_instances.size() - 1; + + entry.node = 0; + entry.instance_index = m_instances.size() - 1; + entry.entry_index = m_entries.size(); + m_entries.push_back(entry); + updateEntry(m_entries.back()); + } + + void LayerCache::removeInstance(Instance* instance) { + // FIXME + // The way LayerCache stores it's data + // it's pretty much impossible to cleanly remove + // added instances. + + // This has to get fixed. + if(m_instance_map.find(instance) == m_instance_map.end()) { + throw new NotFound(instance->getId()); + } + Entry& item = m_entries[m_instance_map[instance]]; + assert(item.instance_index == m_instance_map[instance]); + + if(item.node) + item.node->data().erase(item.entry_index); + item.node = 0; + item.instance_index = unsigned(-1); + m_instance_map.erase(instance); + } + + void LayerCache::updateInstance(Instance* instance) { + Entry& entry = m_entries[m_instance_map[instance]]; + updateEntry(entry); + } + + void LayerCache::updateEntry(LayerCache::Entry& item) { + if(item.instance_index == unsigned(-1)) { + return; + } + if(item.node) { + item.node->data().erase(item.entry_index); + } + RenderItem& render_item = m_instances[item.instance_index]; + Instance* instance = render_item.instance; + + DoublePoint3D screen_position = m_camera->toVirtualScreenCoordinates(instance->getLocationRef().getMapCoordinates()); + + render_item.facing_angle = getAngleBetween(instance->getLocationRef(), instance->getFacingLocation()); + int angle = m_camera->getRotation() + render_item.facing_angle + instance->getRotation(); + + Image* image = NULL; + Action* action = instance->getCurrentAction(); + int w = 0; + int h = 0; + int xshift = 0; + int yshift = 0; + + if(!action) { + // Try static images then default action. + int image_id = render_item.getStaticImageIndexByAngle(angle, instance); + if(image_id == Pool::INVALID_ID) { + action = instance->getObject()->getDefaultAction(); + } else { + image = &m_image_pool->getImage(image_id); + } + } + item.force_update = bool(action); + + if(action) { + int animation_id = action->getVisual()->getAnimationIndexByAngle(render_item.facing_angle + m_camera->getRotation()); + Animation& animation = m_animation_pool->getAnimation(animation_id); + unsigned animation_time = instance->getActionRuntime() % animation.getDuration(); + image = animation.getFrameByTimestamp(animation_time); + + int facing_angle = render_item.facing_angle; + if (facing_angle < 0){ + facing_angle += 360; + } + instance->setRotation(facing_angle); + } + + if (image) { + w = image->getWidth(); + h = image->getHeight(); + xshift = image->getXShift(); + yshift = image->getYShift(); + } + + screen_position.x -= w / 2; + screen_position.x += xshift; + screen_position.y -= h / 2; + screen_position.y += yshift; + + render_item.image = image; + render_item.screenpoint = screen_position; + + render_item.bbox.x = screen_position.x; + render_item.bbox.y = screen_position.y; + render_item.bbox.w = w; + render_item.bbox.h = h; + + render_item.dimensions.x = screen_position.x; + render_item.dimensions.y = screen_position.y; + render_item.dimensions.w = w; + render_item.dimensions.h = h; + + CacheTree::Node* node = m_tree->find_container(render_item.bbox); + item.node = node; + node->data().insert(item.entry_index); + } + + class CacheTreeCollector { + std::vector& m_indices; + Rect m_viewport; + public: + CacheTreeCollector(std::vector& indices, const Rect& _viewport) + : m_indices(indices), m_viewport(_viewport) { + } + bool visit(LayerCache::CacheTree::Node* node, int d = -1); + }; + + bool CacheTreeCollector::visit(LayerCache::CacheTree::Node* node, int d) { + if(!m_viewport.intersects(Rect(node->x(), node->y(),node->size(),node->size()))) + return false; + std::set& list = node->data(); + for(std::set::iterator i = list.begin(); i!=list.end();++i) { + m_indices.push_back(*i); + } + return true; + } + + void LayerCache::collect(const Rect& viewport, std::vector& index_list) { + CacheTree::Node * node = m_tree->find_container(viewport); + CacheTreeCollector collector(index_list, viewport); + node->apply_visitor(collector); + node = node->parent(); + while(node) { + collector.visit(node); + node = node->parent(); + } + } + + void LayerCache::fullUpdate() { + for(unsigned i=0; i!=m_entries.size(); ++i) + updateEntry(m_entries[i]); + } + + class InstanceDistanceSort { + public: + inline bool operator()(RenderItem* const & lhs, RenderItem* const & rhs) { + if (lhs->screenpoint.z == rhs->screenpoint.z) { + InstanceVisual* liv = lhs->instance->getVisual(); + InstanceVisual* riv = rhs->instance->getVisual(); + return liv->getStackPosition() < riv->getStackPosition(); + } + return lhs->screenpoint.z < rhs->screenpoint.z; + } + }; + + void LayerCache::update(Camera::Transform transform, RenderList& renderlist) { + const double OVERDRAW = 2.5; + renderlist.clear(); + bool isWarped = transform == Camera::WarpedTransform; + if( isWarped ) + fullUpdate(); + + Rect viewport = m_camera->getViewPort(); + Rect screen_viewport = viewport; + float zoom = m_camera->getZoom(); + DoublePoint3D viewport_a = m_camera->screenToVirtualScreen(Point3D(viewport.x, viewport.y)); + DoublePoint3D viewport_b = m_camera->screenToVirtualScreen(Point3D(viewport.right(), viewport.bottom())); + viewport.x = std::min(viewport_a.x, viewport_b.x); + viewport.y = std::min(viewport_a.y, viewport_b.y); + viewport.w = std::max(viewport_a.x, viewport_b.x) - viewport.x; + viewport.h = std::max(viewport_a.y, viewport_b.y) - viewport.y; + + // FL_LOG(_log, LMsg("camera-update viewport") << viewport); + std::vector index_list; + collect(viewport, index_list); + for(unsigned i=0; i!=index_list.size();++i) { + Entry& entry = m_entries[index_list[i]]; + // NOTE + // An update is forced if the item has an animation/action. + // This update only happens if it is _already_ included in the viewport + // Nevertheless: Moving instances - which might move into the viewport will be updated + // By the layer change listener. + if(entry.force_update) + updateEntry(entry); + + RenderItem& item = m_instances[entry.instance_index]; + if(!item.image) + continue; + + Point3D screen_point = m_camera->virtualScreenToScreen(item.screenpoint); + // NOTE: + // One would expect this to be necessary here, + // however it works the same without, sofar + // m_camera->calculateZValue(screen_point); + // item.screenpoint.z = -screen_point.z; + + item.dimensions.x = screen_point.x; + item.dimensions.y = screen_point.y; + item.dimensions.w = unsigned(double(item.bbox.w) * zoom + OVERDRAW); + item.dimensions.h = unsigned(double(item.bbox.h) * zoom + OVERDRAW); + + if (zoom != 1.0) { + // NOTE: Due to image alignment, there is additional additions on image dimensions + // There's probabaly some better solution for this, but works "good enough" for now. + // In case additions are removed, gaps appear between tiles. + item.dimensions.w = unsigned(ceil(double(item.bbox.w) * zoom)) + OVERDRAW; + item.dimensions.h = unsigned(ceil(double(item.bbox.h) * zoom)) + OVERDRAW; + } + + if(item.dimensions.intersects(screen_viewport)) + renderlist.push_back(&item); + } + + InstanceDistanceSort ids; + std::stable_sort(renderlist.begin(), renderlist.end(), ids); + // FL_LOG(_log, LMsg("camera-update ") << " N=" < +#include +#include + +// 3rd party library includes + +// FIFE includes +// These includes are split up in two parts, separated by one empty line +// First block: files included from the FIFE root src directory +// Second block: files included from the same folder +#include "model/structures/location.h" +#include "util/math/matrix.h" +#include "util/structures/rect.h" +#include "util/structures/quadtree.h" +#include "model/metamodel/grids/cellgrid.h" + +#include "rendererbase.h" + +namespace FIFE { + + class Camera; + class CacheLayerChangeListener; + + class LayerCache { + public: + typedef QuadTree > CacheTree; + + LayerCache(Camera* camera, ImagePool* image_pool, AnimationPool* animation_pool); + ~LayerCache(); + + void setLayer(Layer* layer); + void update(Camera::Transform transform, RenderList& renderlist); + + void addInstance(Instance* instance); + void removeInstance(Instance* instance); + + void updateInstance(Instance* instance); + + + private: + void collect(const Rect& viewport, std::vector& indices); + void reset(); + void fullUpdate(); + + struct Entry { + /// Node in m_tree; + CacheTree::Node* node; + + /// Index in m_instances; + unsigned instance_index; + + /// Index in m_entries; + unsigned entry_index; + /// Force update for entries with animation + bool force_update; + }; + + ImagePool* m_image_pool; + AnimationPool* m_animation_pool; + Camera* m_camera; + Layer* m_layer; + CacheLayerChangeListener* m_layer_observer; + + void updateEntry(Entry& item); + + std::map m_instance_map; + std::vector m_entries; + + CacheTree* m_tree; + std::vector m_instances; + }; + +} +#endif diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/view/rendererbase.h --- a/engine/core/view/rendererbase.h Wed Apr 28 21:33:11 2010 +0000 +++ b/engine/core/view/rendererbase.h Thu Apr 29 13:51:45 2010 +0000 @@ -33,6 +33,8 @@ // First block: files included from the FIFE root src directory // Second block: files included from the same folder +#include "renderitem.h" + namespace FIFE { class Camera; class Layer; @@ -104,7 +106,7 @@ * @param instances instances on the current layer * @ see setPipelinePosition */ - virtual void render(Camera* cam, Layer* layer, std::vector& instances) = 0; + virtual void render(Camera* cam, Layer* layer, RenderList& instances) = 0; /** Name of the renderer */ diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/view/renderers/blockinginforenderer.cpp --- a/engine/core/view/renderers/blockinginforenderer.cpp Wed Apr 28 21:33:11 2010 +0000 +++ b/engine/core/view/renderers/blockinginforenderer.cpp Thu Apr 29 13:51:45 2010 +0000 @@ -58,7 +58,7 @@ BlockingInfoRenderer::~BlockingInfoRenderer() { } - void BlockingInfoRenderer::render(Camera* cam, Layer* layer, std::vector& instances) { + void BlockingInfoRenderer::render(Camera* cam, Layer* layer, RenderList& instances) { CellGrid* cg = layer->getCellGrid(); if (!cg) { FL_WARN(_log, "No cellgrid assigned to layer, cannot draw grid"); @@ -66,9 +66,9 @@ } Rect cv = cam->getViewPort(); - std::vector::const_iterator instance_it = instances.begin(); + RenderList::const_iterator instance_it = instances.begin(); for (;instance_it != instances.end(); ++instance_it) { - Instance* instance = *instance_it; + Instance* instance = (*instance_it)->instance; if (!instance->getObject()->isBlocking()) { continue; } diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/view/renderers/blockinginforenderer.h --- a/engine/core/view/renderers/blockinginforenderer.h Wed Apr 28 21:33:11 2010 +0000 +++ b/engine/core/view/renderers/blockinginforenderer.h Thu Apr 29 13:51:45 2010 +0000 @@ -50,7 +50,7 @@ */ virtual ~BlockingInfoRenderer(); - void render(Camera* cam, Layer* layer, std::vector& instances); + void render(Camera* cam, Layer* layer, RenderList& instances); std::string getName() { return "BlockingInfoRenderer"; } private: diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/view/renderers/camerazonerenderer.cpp --- a/engine/core/view/renderers/camerazonerenderer.cpp Wed Apr 28 21:33:11 2010 +0000 +++ b/engine/core/view/renderers/camerazonerenderer.cpp Thu Apr 29 13:51:45 2010 +0000 @@ -68,7 +68,7 @@ - void CameraZoneRenderer::render(Camera* cam, Layer* layer, std::vector& instances) { + void CameraZoneRenderer::render(Camera* cam, Layer* layer, RenderList& instances) { CellGrid* cg = layer->getCellGrid(); if (!cg) { FL_WARN(_log, "No cellgrid assigned to layer, cannot draw camera zones"); diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/view/renderers/camerazonerenderer.h --- a/engine/core/view/renderers/camerazonerenderer.h Wed Apr 28 21:33:11 2010 +0000 +++ b/engine/core/view/renderers/camerazonerenderer.h Thu Apr 29 13:51:45 2010 +0000 @@ -53,7 +53,7 @@ */ virtual ~CameraZoneRenderer(); - void render(Camera* cam, Layer* layer, std::vector& instances); + void render(Camera* cam, Layer* layer, RenderList& instances); std::string getName() { return "CameraZoneRenderer"; } diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/view/renderers/cellselectionrenderer.cpp --- a/engine/core/view/renderers/cellselectionrenderer.cpp Wed Apr 28 21:33:11 2010 +0000 +++ b/engine/core/view/renderers/cellselectionrenderer.cpp Thu Apr 29 13:51:45 2010 +0000 @@ -90,7 +90,7 @@ } } - void CellSelectionRenderer::render(Camera* cam, Layer* layer, std::vector& instances) { + void CellSelectionRenderer::render(Camera* cam, Layer* layer, RenderList& instances) { std::vector::const_iterator locit = m_locations.begin(); for (; locit != m_locations.end(); locit++) { diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/view/renderers/cellselectionrenderer.h --- a/engine/core/view/renderers/cellselectionrenderer.h Wed Apr 28 21:33:11 2010 +0000 +++ b/engine/core/view/renderers/cellselectionrenderer.h Thu Apr 29 13:51:45 2010 +0000 @@ -53,7 +53,7 @@ */ virtual ~CellSelectionRenderer(); - void render(Camera* cam, Layer* layer, std::vector& instances); + void render(Camera* cam, Layer* layer, RenderList& instances); /** Returns the renderer name */ std::string getName() { return "CellSelectionRenderer"; } diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/view/renderers/coordinaterenderer.cpp --- a/engine/core/view/renderers/coordinaterenderer.cpp Wed Apr 28 21:33:11 2010 +0000 +++ b/engine/core/view/renderers/coordinaterenderer.cpp Thu Apr 29 13:51:45 2010 +0000 @@ -82,7 +82,7 @@ const int MIN_COORD = -9999999; const int MAX_COORD = 9999999; - void CoordinateRenderer::render(Camera* cam, Layer* layer, std::vector& instances) { + void CoordinateRenderer::render(Camera* cam, Layer* layer, RenderList& instances) { m_layer_area.x = MAX_COORD; m_layer_area.y = MAX_COORD; m_layer_area.w = MIN_COORD; diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/view/renderers/coordinaterenderer.h --- a/engine/core/view/renderers/coordinaterenderer.h Wed Apr 28 21:33:11 2010 +0000 +++ b/engine/core/view/renderers/coordinaterenderer.h Thu Apr 29 13:51:45 2010 +0000 @@ -55,7 +55,7 @@ */ virtual ~CoordinateRenderer(); - void render(Camera* cam, Layer* layer, std::vector& instances); + void render(Camera* cam, Layer* layer, RenderList& instances); std::string getName() { return "CoordinateRenderer"; } diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/view/renderers/floatingtextrenderer.cpp --- a/engine/core/view/renderers/floatingtextrenderer.cpp Wed Apr 28 21:33:11 2010 +0000 +++ b/engine/core/view/renderers/floatingtextrenderer.cpp Thu Apr 29 13:51:45 2010 +0000 @@ -64,20 +64,19 @@ FloatingTextRenderer::~FloatingTextRenderer() { } - void FloatingTextRenderer::render(Camera* cam, Layer* layer, std::vector& instances) { + void FloatingTextRenderer::render(Camera* cam, Layer* layer, RenderList& instances) { if (!m_font) { return; } - std::vector::const_iterator instance_it = instances.begin(); + RenderList::const_iterator instance_it = instances.begin(); const std::string* saytext = NULL; for (;instance_it != instances.end(); ++instance_it) { - Instance* instance = *instance_it; + Instance* instance = (*instance_it)->instance; saytext = instance->getSayText(); if (saytext) { - InstanceVisual* visual = instance->getVisual(); - const Rect& ir = visual->getCacheItem(cam).dimensions; + const Rect& ir = (*instance_it)->dimensions; m_font->setColor(25,25,112); Image* img = m_font->getAsImageMultiline(*saytext); Rect r; diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/view/renderers/floatingtextrenderer.h --- a/engine/core/view/renderers/floatingtextrenderer.h Wed Apr 28 21:33:11 2010 +0000 +++ b/engine/core/view/renderers/floatingtextrenderer.h Thu Apr 29 13:51:45 2010 +0000 @@ -53,7 +53,7 @@ */ virtual ~FloatingTextRenderer(); - void render(Camera* cam, Layer* layer, std::vector& instances); + void render(Camera* cam, Layer* layer, RenderList& instances); std::string getName() { return "FloatingTextRenderer"; } diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/view/renderers/genericrenderer.cpp --- a/engine/core/view/renderers/genericrenderer.cpp Wed Apr 28 21:33:11 2010 +0000 +++ b/engine/core/view/renderers/genericrenderer.cpp Thu Apr 29 13:51:45 2010 +0000 @@ -205,7 +205,7 @@ return m_point; } - Point GenericRendererNode::getCalculatedPoint(Camera* cam, Layer* layer, std::vector& instances) { + Point GenericRendererNode::getCalculatedPoint(Camera* cam, Layer* layer) { ScreenPoint p; if(m_instance != NULL) { if(m_layer == NULL) { @@ -239,9 +239,9 @@ m_green(g), m_blue(b) { } - void GenericRendererLineInfo::render(Camera* cam, Layer* layer, std::vector& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) { - Point p1 = m_edge1.getCalculatedPoint(cam, layer, instances); - Point p2 = m_edge2.getCalculatedPoint(cam, layer, instances); + void GenericRendererLineInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) { + Point p1 = m_edge1.getCalculatedPoint(cam, layer); + Point p2 = m_edge2.getCalculatedPoint(cam, layer); if(m_edge1.getLayer() == layer) { renderbackend->drawLine(p1, p2, m_red, m_green, m_blue); } @@ -254,8 +254,8 @@ m_green(g), m_blue(b) { } - void GenericRendererPointInfo::render(Camera* cam, Layer* layer, std::vector& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) { - Point p = m_anchor.getCalculatedPoint(cam, layer, instances); + void GenericRendererPointInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) { + Point p = m_anchor.getCalculatedPoint(cam, layer); if(m_anchor.getLayer() == layer) { renderbackend->putPixel(p.x, p.y, m_red, m_green, m_blue); } @@ -271,11 +271,11 @@ m_green(g), m_blue(b) { } - void GenericRendererQuadInfo::render(Camera* cam, Layer* layer, std::vector& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) { - Point p1 = m_edge1.getCalculatedPoint(cam, layer, instances); - Point p2 = m_edge2.getCalculatedPoint(cam, layer, instances); - Point p3 = m_edge3.getCalculatedPoint(cam, layer, instances); - Point p4 = m_edge4.getCalculatedPoint(cam, layer, instances); + void GenericRendererQuadInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) { + Point p1 = m_edge1.getCalculatedPoint(cam, layer); + Point p2 = m_edge2.getCalculatedPoint(cam, layer); + Point p3 = m_edge3.getCalculatedPoint(cam, layer); + Point p4 = m_edge4.getCalculatedPoint(cam, layer); if(m_edge1.getLayer() == layer) { renderbackend->drawQuad(p1, p2, p3, p4, m_red, m_green, m_blue); } @@ -289,8 +289,8 @@ m_green(g), m_blue(b) { } - void GenericRendererVertexInfo::render(Camera* cam, Layer* layer, std::vector& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) { - Point p = m_center.getCalculatedPoint(cam, layer, instances); + void GenericRendererVertexInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) { + Point p = m_center.getCalculatedPoint(cam, layer); if(m_center.getLayer() == layer) { renderbackend->drawVertex(p, m_size, m_red, m_green, m_blue); } @@ -301,8 +301,8 @@ m_anchor(anchor), m_image(image) { } - void GenericRendererImageInfo::render(Camera* cam, Layer* layer, std::vector& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) { - Point p = m_anchor.getCalculatedPoint(cam, layer, instances); + void GenericRendererImageInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) { + Point p = m_anchor.getCalculatedPoint(cam, layer); if(m_anchor.getLayer() == layer) { Image* img = &imagepool->getImage(m_image); Rect r; @@ -321,8 +321,8 @@ m_start_time(TimeManager::instance()->getTime()), m_time_scale(1.0) { } - void GenericRendererAnimationInfo::render(Camera* cam, Layer* layer, std::vector& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) { - Point p = m_anchor.getCalculatedPoint(cam, layer, instances); + void GenericRendererAnimationInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) { + Point p = m_anchor.getCalculatedPoint(cam, layer); if(m_anchor.getLayer() == layer) { Animation& animation = animpool->getAnimation(m_animation); int animtime = scaleTime(m_time_scale, TimeManager::instance()->getTime() - m_start_time) % animation.getDuration(); @@ -342,8 +342,8 @@ m_font(font), m_text(text) { } - void GenericRendererTextInfo::render(Camera* cam, Layer* layer, std::vector& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) { - Point p = m_anchor.getCalculatedPoint(cam, layer, instances); + void GenericRendererTextInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) { + Point p = m_anchor.getCalculatedPoint(cam, layer); if(m_anchor.getLayer() == layer) { Image* img = m_font->getAsImageMultiline(m_text); Rect r; @@ -419,7 +419,7 @@ m_groups.erase(group); } - void GenericRenderer::render(Camera* cam, Layer* layer, std::vector& instances) { + void GenericRenderer::render(Camera* cam, Layer* layer, RenderList& instances) { std::map >::iterator group_it = m_groups.begin(); for(; group_it != m_groups.end(); ++group_it) { std::vector::const_iterator info_it = group_it->second.begin(); diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/view/renderers/genericrenderer.h --- a/engine/core/view/renderers/genericrenderer.h Wed Apr 28 21:33:11 2010 +0000 +++ b/engine/core/view/renderers/genericrenderer.h Thu Apr 29 13:51:45 2010 +0000 @@ -76,7 +76,7 @@ Layer* getLayer(); Point getPoint(); - Point getCalculatedPoint(Camera* cam, Layer* layer, std::vector& instances); + Point getCalculatedPoint(Camera* cam, Layer* layer); private: Instance* m_instance; Location* m_location; @@ -85,13 +85,13 @@ }; class GenericRendererElementInfo { public: - virtual void render(Camera* cam, Layer* layer, std::vector& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {}; + virtual void render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {}; virtual ~GenericRendererElementInfo() {}; }; class GenericRendererLineInfo : public GenericRendererElementInfo { public: - void render(Camera* cam, Layer* layer, std::vector& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool); + void render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool); GenericRendererLineInfo(GenericRendererNode n1, GenericRendererNode n2, uint8_t r, uint8_t g, uint8_t b); virtual ~GenericRendererLineInfo() {}; private: @@ -103,7 +103,7 @@ }; class GenericRendererPointInfo : public GenericRendererElementInfo { public: - void render(Camera* cam, Layer* layer, std::vector& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool); + void render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool); GenericRendererPointInfo(GenericRendererNode n, uint8_t r, uint8_t g, uint8_t b); virtual ~GenericRendererPointInfo() {}; private: @@ -114,7 +114,7 @@ }; class GenericRendererQuadInfo : public GenericRendererElementInfo { public: - void render(Camera* cam, Layer* layer, std::vector& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool); + void render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool); GenericRendererQuadInfo(GenericRendererNode n1, GenericRendererNode n2, GenericRendererNode n3, GenericRendererNode n4, uint8_t r, uint8_t g, uint8_t b); virtual ~GenericRendererQuadInfo() {}; private: @@ -129,7 +129,7 @@ class GenericRendererVertexInfo : public GenericRendererElementInfo { public: - void render(Camera* cam, Layer* layer, std::vector& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool); + void render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool); GenericRendererVertexInfo(GenericRendererNode center, int size, uint8_t r, uint8_t g, uint8_t b); virtual ~GenericRendererVertexInfo() {}; private: @@ -142,7 +142,7 @@ class GenericRendererImageInfo : public GenericRendererElementInfo { public: - void render(Camera* cam, Layer* layer, std::vector& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool); + void render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool); GenericRendererImageInfo(GenericRendererNode n, int image); virtual ~GenericRendererImageInfo() {}; private: @@ -151,7 +151,7 @@ }; class GenericRendererAnimationInfo : public GenericRendererElementInfo { public: - void render(Camera* cam, Layer* layer, std::vector& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool); + void render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool); GenericRendererAnimationInfo(GenericRendererNode n, int animation); virtual ~GenericRendererAnimationInfo() {}; private: @@ -162,7 +162,7 @@ }; class GenericRendererTextInfo : public GenericRendererElementInfo { public: - void render(Camera* cam, Layer* layer, std::vector& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool); + void render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool); GenericRendererTextInfo(GenericRendererNode n, AbstractFont* font, std::string text); virtual ~GenericRendererTextInfo() {}; private: @@ -185,7 +185,7 @@ /** Destructor. */ virtual ~GenericRenderer(); - void render(Camera* cam, Layer* layer, std::vector& instances); + void render(Camera* cam, Layer* layer, RenderList& instances); std::string getName() { return "GenericRenderer"; } /** Gets instance for interface access diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/view/renderers/genericrenderer.i --- a/engine/core/view/renderers/genericrenderer.i Wed Apr 28 21:33:11 2010 +0000 +++ b/engine/core/view/renderers/genericrenderer.i Thu Apr 29 13:51:45 2010 +0000 @@ -65,7 +65,7 @@ Layer* getLayer(); Point getPoint(); - Point getCalculatedPoint(Camera* cam, Layer* layer, std::vector& instances); + Point getCalculatedPoint(Camera* cam, Layer* layer); private: Instance* m_instance; Location* m_location; @@ -74,13 +74,11 @@ }; class GenericRendererElementInfo { public: - virtual void render(Camera* cam, Layer* layer, std::vector& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {}; virtual ~GenericRendererElementInfo() {}; }; class GenericRendererLineInfo : public GenericRendererElementInfo { public: - void render(Camera* cam, Layer* layer, std::vector& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool); GenericRendererLineInfo(GenericRendererNode n1, GenericRendererNode n2, uint8_t r, uint8_t g, uint8_t b); virtual ~GenericRendererLineInfo() {}; private: @@ -92,7 +90,6 @@ }; class GenericRendererPointInfo : public GenericRendererElementInfo { public: - void render(Camera* cam, Layer* layer, std::vector& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool); GenericRendererPointInfo(GenericRendererNode n, uint8_t r, uint8_t g, uint8_t b); virtual ~GenericRendererPointInfo() {}; private: @@ -103,7 +100,6 @@ }; class GenericRendererQuadInfo : public GenericRendererElementInfo { public: - void render(Camera* cam, Layer* layer, std::vector& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool); GenericRendererQuadInfo(GenericRendererNode n1, GenericRendererNode n2, GenericRendererNode n3, GenericRendererNode n4, uint8_t r, uint8_t g, uint8_t b); virtual ~GenericRendererQuadInfo() {}; private: @@ -115,10 +111,8 @@ uint8_t m_green; uint8_t m_blue; }; - class GenericRendererVertexInfo : public GenericRendererElementInfo { public: - void render(Camera* cam, Layer* layer, std::vector& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool); GenericRendererVertexInfo(GenericRendererNode center, int size, uint8_t r, uint8_t g, uint8_t b); virtual ~GenericRendererVertexInfo() {}; private: @@ -128,10 +122,8 @@ uint8_t m_green; uint8_t m_blue; }; - class GenericRendererImageInfo : public GenericRendererElementInfo { public: - void render(Camera* cam, Layer* layer, std::vector& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool); GenericRendererImageInfo(GenericRendererNode n, int image); virtual ~GenericRendererImageInfo() {}; private: @@ -140,7 +132,6 @@ }; class GenericRendererAnimationInfo : public GenericRendererElementInfo { public: - void render(Camera* cam, Layer* layer, std::vector& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool); GenericRendererAnimationInfo(GenericRendererNode n, int animation); virtual ~GenericRendererAnimationInfo() {}; private: @@ -149,7 +140,6 @@ }; class GenericRendererTextInfo : public GenericRendererElementInfo { public: - void render(Camera* cam, Layer* layer, std::vector& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool); GenericRendererTextInfo(GenericRendererNode n, AbstractFont* font, std::string text); virtual ~GenericRendererTextInfo() {}; private: diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/view/renderers/gridrenderer.cpp --- a/engine/core/view/renderers/gridrenderer.cpp Wed Apr 28 21:33:11 2010 +0000 +++ b/engine/core/view/renderers/gridrenderer.cpp Thu Apr 29 13:51:45 2010 +0000 @@ -59,7 +59,7 @@ GridRenderer::~GridRenderer() { } - void GridRenderer::render(Camera* cam, Layer* layer, std::vector& instances) { + void GridRenderer::render(Camera* cam, Layer* layer, RenderList& instances) { CellGrid* cg = layer->getCellGrid(); if (!cg) { FL_WARN(_log, "No cellgrid assigned to layer, cannot draw grid"); @@ -134,9 +134,9 @@ Rect cv = cam->getViewPort(); - std::vector::const_iterator instance_it = instances.begin(); + RenderList::const_iterator instance_it = instances.begin(); for (;instance_it != instances.end(); ++instance_it) { - Instance* instance = *instance_it; + Instance* instance = (*instance_it)->instance; std::vector vertices; cg->getVertices(vertices, instance->getLocationRef().getLayerCoordinates()); std::vector::const_iterator it = vertices.begin(); diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/view/renderers/gridrenderer.h --- a/engine/core/view/renderers/gridrenderer.h Wed Apr 28 21:33:11 2010 +0000 +++ b/engine/core/view/renderers/gridrenderer.h Thu Apr 29 13:51:45 2010 +0000 @@ -50,7 +50,7 @@ */ virtual ~GridRenderer(); - void render(Camera* cam, Layer* layer, std::vector& instances); + void render(Camera* cam, Layer* layer, RenderList& instances); std::string getName() { return "GridRenderer"; } diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/view/renderers/instancerenderer.cpp --- a/engine/core/view/renderers/instancerenderer.cpp Wed Apr 28 21:33:11 2010 +0000 +++ b/engine/core/view/renderers/instancerenderer.cpp Thu Apr 29 13:51:45 2010 +0000 @@ -103,7 +103,7 @@ InstanceRenderer::~InstanceRenderer() { } - void InstanceRenderer::render(Camera* cam, Layer* layer, std::vector& instances) { + void InstanceRenderer::render(Camera* cam, Layer* layer, RenderList& instances) { // patch #335 by abeyer if (!layer->areInstancesVisible()) { FL_DBG(_log, "Layer instances hidden"); @@ -119,12 +119,12 @@ const bool any_effects = !(m_instance_outlines.empty() && m_instance_colorings.empty()); - std::vector::const_iterator instance_it = instances.begin(); + RenderList::iterator instance_it = instances.begin(); for (;instance_it != instances.end(); ++instance_it) { FL_DBG(_log, "Iterating instances..."); - Instance* instance = (*instance_it); + Instance* instance = (*instance_it)->instance; InstanceVisual* visual = instance->getVisual(); - + RenderItem& vc = **instance_it; unsigned char trans = visual->getTransparency(); /** @@ -137,7 +137,6 @@ trans = layer_trans; } - InstanceVisualCacheItem& vc = visual->getCacheItem(cam); FL_DBG(_log, LMsg("Instance layer coordinates = ") << instance->getLocationRef().getLayerCoordinates()); if (any_effects) { @@ -157,7 +156,7 @@ } } - Image* InstanceRenderer::bindOutline(OutlineInfo& info, InstanceVisualCacheItem& vc, Camera* cam) { + Image* InstanceRenderer::bindOutline(OutlineInfo& info, RenderItem& vc, Camera* cam) { if (info.curimg == vc.image) { return info.outline; } else { @@ -222,7 +221,7 @@ return info.outline; } - Image* InstanceRenderer::bindColoring(ColoringInfo& info, InstanceVisualCacheItem& vc, Camera* cam) { + Image* InstanceRenderer::bindColoring(ColoringInfo& info, RenderItem& vc, Camera* cam) { if (info.curimg == vc.image) { return info.overlay; } else { diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/view/renderers/instancerenderer.h --- a/engine/core/view/renderers/instancerenderer.h Wed Apr 28 21:33:11 2010 +0000 +++ b/engine/core/view/renderers/instancerenderer.h Thu Apr 29 13:51:45 2010 +0000 @@ -37,7 +37,6 @@ class RenderBackend; class ImagePool; class AnimationPool; - class InstanceVisualCacheItem; class InstanceRenderer: public RendererBase { public: @@ -55,7 +54,7 @@ /** Destructor. */ virtual ~InstanceRenderer(); - void render(Camera* cam, Layer* layer, std::vector& instances); + void render(Camera* cam, Layer* layer, RenderList& instances); std::string getName() { return "InstanceRenderer"; } /** Marks given instance to be outlined with given parameters @@ -123,8 +122,8 @@ /** Binds new outline (if needed) to the instance's OutlineInfo */ - Image* bindOutline(OutlineInfo& info, InstanceVisualCacheItem& vc, Camera* cam); - Image* bindColoring(ColoringInfo& info, InstanceVisualCacheItem& vc, Camera* cam); + Image* bindOutline(OutlineInfo& info, RenderItem& vc, Camera* cam); + Image* bindColoring(ColoringInfo& info, RenderItem& vc, Camera* cam); }; } diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/view/renderers/quadtreerenderer.cpp --- a/engine/core/view/renderers/quadtreerenderer.cpp Wed Apr 28 21:33:11 2010 +0000 +++ b/engine/core/view/renderers/quadtreerenderer.cpp Thu Apr 29 13:51:45 2010 +0000 @@ -99,7 +99,7 @@ } - void QuadTreeRenderer::render(Camera* cam, Layer* layer, std::vector& instances) { + void QuadTreeRenderer::render(Camera* cam, Layer* layer, RenderList& instances) { CellGrid* cg = layer->getCellGrid(); if (!cg) { FL_WARN(_log, "No cellgrid assigned to layer, cannot draw grid"); diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/view/renderers/quadtreerenderer.h --- a/engine/core/view/renderers/quadtreerenderer.h Wed Apr 28 21:33:11 2010 +0000 +++ b/engine/core/view/renderers/quadtreerenderer.h Thu Apr 29 13:51:45 2010 +0000 @@ -63,7 +63,7 @@ */ virtual ~QuadTreeRenderer(); - void render(Camera* cam, Layer* layer, std::vector& instances); + void render(Camera* cam, Layer* layer, RenderList& instances); std::string getName() { return "QuadTreeRenderer"; diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/view/renderitem.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/engine/core/view/renderitem.cpp Thu Apr 29 13:51:45 2010 +0000 @@ -0,0 +1,62 @@ +/*************************************************************************** + * Copyright (C) 2005-2008 by the FIFE team * + * http://www.fifengine.de * + * This file is part of FIFE. * + * * + * FIFE is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +// Standard C++ library includes + +// 3rd party library includes + +// FIFE includes +// These includes are split up in two parts, separated by one empty line +// First block: files included from the FIFE root src directory +// Second block: files included from the same folder +#include "model/structures/instance.h" +#include "model/metamodel/object.h" +#include "model/metamodel/action.h" +#include "util/resource/pool.h" + +#include "visual.h" +#include "renderitem.h" + +namespace FIFE { + const int STATIC_IMAGE_NOT_INITIALIZED = -2; + + RenderItem::RenderItem(): + screenpoint(), + dimensions(), + image(NULL), + m_cached_static_img_id(STATIC_IMAGE_NOT_INITIALIZED), + m_cached_static_img_angle(0) { + } + + int RenderItem::getStaticImageIndexByAngle(unsigned int angle, Instance* instance) { + if (static_cast(angle) != m_cached_static_img_angle) { + m_cached_static_img_id = STATIC_IMAGE_NOT_INITIALIZED; + } + if (m_cached_static_img_id != STATIC_IMAGE_NOT_INITIALIZED) { + return m_cached_static_img_id; + } + if(!instance->getObject()->getVisual()) + return Pool::INVALID_ID; + m_cached_static_img_id = instance->getObject()->getVisual()->getStaticImageIndexByAngle(angle); + m_cached_static_img_angle = angle; + return m_cached_static_img_id; + } +} diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/view/renderitem.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/engine/core/view/renderitem.h Thu Apr 29 13:51:45 2010 +0000 @@ -0,0 +1,75 @@ +/*************************************************************************** + * Copyright (C) 2005-2008 by the FIFE team * + * http://www.fifengine.de * + * This file is part of FIFE. * + * * + * FIFE is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef FIFE_VIEW_RENDERITEM_H +#define FIFE_VIEW_RENDERITEM_H + +// Standard C++ library includes +#include + +// 3rd party library includes + +// FIFE includes +// These includes are split up in two parts, separated by one empty line +// First block: files included from the FIFE root src directory +// Second block: files included from the same folder + +#include "visual.h" + +namespace FIFE { + + class Instance; + + class RenderItem { + public: + RenderItem(); + + Instance* instance; + + /** Returns closest matching static image for given angle + * @return id for static image + * @see ObjectVisual::getStaticImageIndexByAngle + */ + int getStaticImageIndexByAngle(unsigned int angle, Instance* instance); + + // point where instance was drawn during the previous render + DoublePoint3D screenpoint; + + // dimensions of this visual on the virtual screen + Rect bbox; + + // dimensions of this visual during the previous render + Rect dimensions; + + // image used during previous render + Image* image; + + // current facing angle + int facing_angle; + private: + int m_cached_static_img_id; + int m_cached_static_img_angle; + }; + + typedef std::vector RenderList; +} + +#endif diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/view/visual.cpp --- a/engine/core/view/visual.cpp Wed Apr 28 21:33:11 2010 +0000 +++ b/engine/core/view/visual.cpp Thu Apr 29 13:51:45 2010 +0000 @@ -86,30 +86,7 @@ } } - const int STATIC_IMAGE_NOT_INITIALIZED = -2; - const int STATIC_IMAGE_NOT_FOUND = -1; - - InstanceVisualCacheItem::InstanceVisualCacheItem(): - screenpoint(), - dimensions(), - image(NULL), - m_cached_static_img_id(STATIC_IMAGE_NOT_INITIALIZED), - m_cached_static_img_angle(0) { - } - - int InstanceVisualCacheItem::getStaticImageIndexByAngle(unsigned int angle, Instance* instance) { - if (static_cast(angle) != m_cached_static_img_angle) { - m_cached_static_img_id = STATIC_IMAGE_NOT_INITIALIZED; - } - if (m_cached_static_img_id != STATIC_IMAGE_NOT_INITIALIZED) { - return m_cached_static_img_id; - } - m_cached_static_img_id = instance->getObject()->getVisual()->getStaticImageIndexByAngle(angle); - m_cached_static_img_angle = angle; - return m_cached_static_img_id; - } - - InstanceVisual::InstanceVisual(): + InstanceVisual::InstanceVisual(): m_stackposition(0) { } diff -r 1f37adc9a685 -r 16c2b3ee59ce engine/core/view/visual.h --- a/engine/core/view/visual.h Wed Apr 28 21:33:11 2010 +0000 +++ b/engine/core/view/visual.h Thu Apr 29 13:51:45 2010 +0000 @@ -31,14 +31,16 @@ // First block: files included from the FIFE root src directory // Second block: files included from the same folder #include "model/metamodel/abstractvisual.h" -#include "view/camera.h" +#include "util/math/angles.h" +#include "util/structures/rect.h" namespace FIFE { class Object; class Instance; class Action; class Image; - + class Camera; + /** Base class for all 2 dimensional visual classes * Visual classes are extensions to visualize the stuff in model (e.g. instances) * The reason why its separated is to keep model view-agnostic, so that we could @@ -125,36 +127,6 @@ type_angle2id m_angle2img; }; - /** InstanceVisualCacheItem caches values calculated by view - * values are camera specific - * Class should be used by engine itself only - */ - class InstanceVisualCacheItem { - public: - InstanceVisualCacheItem(); - - /** Returns closest matching static image for given angle - * @return id for static image - * @see ObjectVisual::getStaticImageIndexByAngle - */ - int getStaticImageIndexByAngle(unsigned int angle, Instance* instance); - - // point where instance was drawn during the previous render - ScreenPoint screenpoint; - - // dimensions of this visual during the previous render - Rect dimensions; - - // image used during previous render - Image* image; - - // current facing angle - int facing_angle; - private: - int m_cached_static_img_id; - int m_cached_static_img_angle; - }; - /** Instance visual contains data that is needed to visualize the instance on screen */ class InstanceVisual: public Visual2DGfx { @@ -179,18 +151,11 @@ */ int getStackPosition() { return m_stackposition; } - /** Get camera specific cache item for the visual - * @return cache item - */ - inline InstanceVisualCacheItem& getCacheItem(Camera* cam) { return m_cache[cam]; } - private: /** Constructor */ InstanceVisual(); int m_stackposition; - // there is separate cache item for each camera - std::map m_cache; }; /** Action visual contains data that is needed to visualize different actions on screen