changeset 482:16c2b3ee59ce

* Merged the view performance branch back into trunk. fixes[ticket:419]
author helios2000@33b003aa-7bff-0310-803a-e67f0ece8222
date Thu, 29 Apr 2010 13:51:45 +0000
parents 1f37adc9a685
children 82d44c471959
files engine/core/gui/console/console.cpp engine/core/model/structures/instance.cpp engine/core/model/structures/instance.h engine/core/model/structures/layer.cpp engine/core/model/structures/layer.h engine/core/util/math/matrix.h engine/core/video/animation.cpp engine/core/view/camera.cpp engine/core/view/camera.h engine/core/view/layercache.cpp engine/core/view/layercache.h engine/core/view/rendererbase.h engine/core/view/renderers/blockinginforenderer.cpp engine/core/view/renderers/blockinginforenderer.h engine/core/view/renderers/camerazonerenderer.cpp engine/core/view/renderers/camerazonerenderer.h engine/core/view/renderers/cellselectionrenderer.cpp engine/core/view/renderers/cellselectionrenderer.h engine/core/view/renderers/coordinaterenderer.cpp engine/core/view/renderers/coordinaterenderer.h engine/core/view/renderers/floatingtextrenderer.cpp engine/core/view/renderers/floatingtextrenderer.h engine/core/view/renderers/genericrenderer.cpp engine/core/view/renderers/genericrenderer.h engine/core/view/renderers/genericrenderer.i engine/core/view/renderers/gridrenderer.cpp engine/core/view/renderers/gridrenderer.h engine/core/view/renderers/instancerenderer.cpp engine/core/view/renderers/instancerenderer.h engine/core/view/renderers/quadtreerenderer.cpp engine/core/view/renderers/quadtreerenderer.h engine/core/view/renderitem.cpp engine/core/view/renderitem.h engine/core/view/visual.cpp engine/core/view/visual.h
diffstat 35 files changed, 905 insertions(+), 321 deletions(-) [+]
line wrap: on
line diff
--- 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() {
--- 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) {
--- 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.
 		 */
--- 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<LayerChangeListener*>::iterator i = m_changelisteners.begin();
 		while (i != m_changelisteners.end()) {
@@ -113,7 +120,7 @@
 			(*i)->onInstanceDelete(this, instance);
 			++i;
 		}
-
+		setInstanceActivityStatus(instance, false);
 		std::vector<Instance*>::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<Instance*>::iterator it = m_instances.begin();
 		for(; it != m_instances.end(); ++it) {
@@ -232,8 +247,8 @@
 
 	bool Layer::update() {
 		m_changedinstances.clear();
-		std::vector<Instance*>::iterator it = m_instances.begin();
-		for(; it != m_instances.end(); ++it) {
+		std::set<Instance*>::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;
--- 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 <algorithm>
 #include <string>
 #include <vector>
+#include <set>
 
 // 3rd party library includes
 
@@ -238,6 +239,8 @@
 			 */
 			std::vector<Instance*>& 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<Instance*> m_instances;
 
+			// all the active instances on this layer
+			std::set<Instance*> m_active_instances;
+
 			//The instance tree
 			InstanceTree* m_instanceTree;
 
--- 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<typename T>
-	std::ostream& operator<<(std::ostream& os, Matrix<T>& m) {
+	std::ostream& operator<<(std::ostream& os, const Matrix<T>& 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" << \
--- 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)) {
--- 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<Layer*>& 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<std::string, RendererBase*>::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<Layer*>& layers = m_map->getLayers();
+			for(std::list<Layer*>::const_iterator i = layers.begin(); i !=layers.end(); ++i) {
+				removeLayer(*i);
+			}
+		}
+		if(map) {
+			map->addChangeListener(m_map_observer);
+			const std::list<Layer*>& layers = map->getLayers();
+			for(std::list<Layer*>::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<Instance*>& instances) {
 		instances.clear();
-		const std::vector<Instance*>& layer_instances = m_layer_to_instances[&layer];
-		std::vector<Instance*>::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<InstanceVisual>();
-			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<Instance*>& instances) {
 		instances.clear();
-		const std::vector<Instance*>& layer_instances = m_layer_to_instances[&layer];
-		std::vector<Instance*>::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<InstanceVisual>();
-			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<Instance*>& instances, bool use_exactcoordinates) {
 		instances.clear();
-		const std::vector<Instance*>& layer_instances = m_layer_to_instances[loc.getLayer()];
-		std::vector<Instance*>::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>();
-			InstanceVisual* riv = rhs->getVisual<InstanceVisual>();
-			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<std::string, RendererBase*>::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<Layer*>& layers = map->getLayers();
 		std::list<Layer*>::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<Instance*>& allinstances = (*layer_it)->getInstances();
-			std::vector<Instance*>::const_iterator instance_it = allinstances.begin();
-			std::vector<Instance*>& instances_to_render = m_layer_to_instances[*layer_it];
-			for (;instance_it != allinstances.end(); ++instance_it) {
-				Instance* instance = *instance_it;
-				InstanceVisual* visual = instance->getVisual<InstanceVisual>();
-				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<ActionVisual>()->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<ActionVisual>()->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<unsigned int>(ceil(static_cast<double>(vc.dimensions.w) * m_zoom)) + 2;
-						r.h = static_cast<unsigned int>(ceil(static_cast<double>(vc.dimensions.h) * m_zoom)) + 2;
-						int xo = static_cast<int>(ceil(static_cast<double>(vc.image->getXShift()) * m_zoom)) - vc.image->getXShift();
-						int yo = static_cast<int>(ceil(static_cast<double>(vc.image->getYShift()) * m_zoom)) - vc.image->getYShift();
-						r.x = vc.dimensions.x - static_cast<unsigned int>(ceil(static_cast<double>(r.w - vc.dimensions.w) / 2)) + xo - 1;
-						r.y = vc.dimensions.y - static_cast<unsigned int>(ceil(static_cast<double>(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<RendererBase*>::iterator r_it = m_pipeline.begin();
 			for (; r_it != m_pipeline.end(); ++r_it) {
--- 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<Layer*, std::vector<Instance*> > t_layer_to_instances;
+	class LayerCache;
+	class MapObserver;
+	typedef std::map<Layer*, RenderList > 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<Layer*,LayerCache*> m_cache;
+		MapObserver* m_map_observer;
+		Map* m_map;
 	};
 }
 #endif
--- /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 <SDL.h>
+
+// 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<Instance*>& instances)
+		{
+			for(std::vector<Instance*>::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<Instance*>& instances = m_layer->getInstances();
+		for(std::vector<Instance*>::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<ActionVisual>()->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<int>& m_indices;
+			Rect m_viewport;
+		public:
+			CacheTreeCollector(std::vector<int>& 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<int>& list = node->data();
+		for(std::set<int>::iterator i = list.begin(); i!=list.end();++i) {
+			m_indices.push_back(*i);
+		}
+		return true;
+	}
+
+	void LayerCache::collect(const Rect& viewport, std::vector<int>& 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>();
+				InstanceVisual* riv = rhs->instance->getVisual<InstanceVisual>();
+				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<int> 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=" <<renderlist.size() << "/" << m_instances.size() << "/" << index_list.size());
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/engine/core/view/layercache.h	Thu Apr 29 13:51:45 2010 +0000
@@ -0,0 +1,99 @@
+/***************************************************************************
+ *   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_LAYERCACHE_H
+#define FIFE_VIEW_LAYERCACHE_H
+
+// Standard C++ library includes
+#include <string>
+#include <map>
+#include <set>
+
+// 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<std::set<int> > 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<int>& 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<Instance*,int> m_instance_map;
+		std::vector<Entry> m_entries;
+
+		CacheTree* m_tree;
+		std::vector<RenderItem> m_instances;
+	};
+
+}
+#endif
--- 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<Instance*>& instances) = 0;
+		virtual void render(Camera* cam, Layer* layer, RenderList& instances) = 0;
 		
 		/** Name of the renderer
 		 */
--- 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<Instance*>& 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<Instance*>::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;
 			}
--- 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<Instance*>& instances);
+		void render(Camera* cam, Layer* layer, RenderList& instances);
 
 		std::string getName() { return "BlockingInfoRenderer"; }
 	private:
--- 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<Instance*>& 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");
--- 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<Instance*>& instances);
+		void render(Camera* cam, Layer* layer, RenderList& instances);
 
 		std::string getName() { return "CameraZoneRenderer"; }
 
--- 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<Instance*>& instances) {
+	void CellSelectionRenderer::render(Camera* cam, Layer* layer, RenderList& instances) {
 		std::vector<Location>::const_iterator locit = m_locations.begin();
 
 		for (; locit != m_locations.end(); locit++) {
--- 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<Instance*>& instances);
+		void render(Camera* cam, Layer* layer, RenderList& instances);
 
 		/** Returns the renderer name */
 		std::string getName() { return "CellSelectionRenderer"; }
--- 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<Instance*>& 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;
--- 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<Instance*>& instances);
+		void render(Camera* cam, Layer* layer, RenderList& instances);
 
 		std::string getName() { return "CoordinateRenderer"; }
 
--- 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<Instance*>& instances) {
+	void FloatingTextRenderer::render(Camera* cam, Layer* layer, RenderList& instances) {
 		if (!m_font) {
 			return;
 		}
 		
-		std::vector<Instance*>::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<InstanceVisual>();
-				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;
--- 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<Instance*>& instances);
+		void render(Camera* cam, Layer* layer, RenderList& instances);
 
 		std::string getName() { return "FloatingTextRenderer"; }
 		
--- 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<Instance*>& 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<Instance*>& 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<Instance*>& 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<Instance*>& 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<Instance*>& 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<Instance*>& 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<Instance*>& 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<Instance*>& 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<Instance*>& instances) {
+	void GenericRenderer::render(Camera* cam, Layer* layer, RenderList& instances) {
 		std::map<std::string, std::vector<GenericRendererElementInfo*> >::iterator group_it = m_groups.begin();
 		for(; group_it != m_groups.end(); ++group_it) {
 			std::vector<GenericRendererElementInfo*>::const_iterator info_it = group_it->second.begin();
--- 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<Instance*>& 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<Instance*>& 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<Instance*>& 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<Instance*>& 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<Instance*>& 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<Instance*>& 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<Instance*>& 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<Instance*>& 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<Instance*>& 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<Instance*>& instances);
+		void render(Camera* cam, Layer* layer, RenderList& instances);
 		std::string getName() { return "GenericRenderer"; }
 
 		/** Gets instance for interface access
--- 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<Instance*>& 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<Instance*>& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {};
 		virtual ~GenericRendererElementInfo() {};
 	};
 
 	class GenericRendererLineInfo : public GenericRendererElementInfo {
 	public:
-		void render(Camera* cam, Layer* layer, std::vector<Instance*>& 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<Instance*>& 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<Instance*>& 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<Instance*>& 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<Instance*>& 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<Instance*>& 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<Instance*>& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool);
 		GenericRendererTextInfo(GenericRendererNode n, AbstractFont* font, std::string text);
 		virtual ~GenericRendererTextInfo() {};
 	private:
--- 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<Instance*>& 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<Instance*>::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<ExactModelCoordinate> vertices;
 			cg->getVertices(vertices, instance->getLocationRef().getLayerCoordinates());
 			std::vector<ExactModelCoordinate>::const_iterator it = vertices.begin();
--- 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<Instance*>& instances);
+		void render(Camera* cam, Layer* layer, RenderList& instances);
 
 		std::string getName() { return "GridRenderer"; }
 
--- 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<Instance*>& 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<Instance*>::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<InstanceVisual>();
-
+			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 {
--- 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<Instance*>& 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);
 	};
 }
 
--- 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<Instance*>& 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");
--- 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<Instance*>& instances);
+			void render(Camera* cam, Layer* layer, RenderList& instances);
 
 			std::string getName() {
 				return "QuadTreeRenderer";
--- /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<int>(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<ObjectVisual>())
+			return Pool::INVALID_ID;
+		m_cached_static_img_id = instance->getObject()->getVisual<ObjectVisual>()->getStaticImageIndexByAngle(angle);
+		m_cached_static_img_angle = angle;
+		return m_cached_static_img_id;
+	}
+}
--- /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 <vector>
+
+// 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<RenderItem*> RenderList;
+}
+
+#endif
--- 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<int>(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<ObjectVisual>()->getStaticImageIndexByAngle(angle);
- 		m_cached_static_img_angle = angle;
-		return m_cached_static_img_id;
-	}
-
-	InstanceVisual::InstanceVisual():
+	InstanceVisual::InstanceVisual(): 
 		m_stackposition(0) {
 	}
 
--- 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<Camera*, InstanceVisualCacheItem> m_cache;
 	};
 
 	/** Action visual contains data that is needed to visualize different actions on screen