location.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2005-2011 by the FIFE team                              *
00003  *   http://www.fifengine.net                                               *
00004  *   This file is part of FIFE.                                            *
00005  *                                                                         *
00006  *   FIFE is free software; you can redistribute it and/or                 *
00007  *   modify it under the terms of the GNU Lesser General Public            *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2.1 of the License, or (at your option) any later version.    *
00010  *                                                                         *
00011  *   This library is distributed in the hope that it will be useful,       *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00014  *   Lesser General Public License for more details.                       *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Lesser General Public      *
00017  *   License along with this library; if not, write to the                 *
00018  *   Free Software Foundation, Inc.,                                       *
00019  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
00020  ***************************************************************************/
00021 
00022 // Standard C++ library includes
00023 
00024 // 3rd party library includes
00025 
00026 // FIFE includes
00027 // These includes are split up in two parts, separated by one empty line
00028 // First block: files included from the FIFE root src directory
00029 // Second block: files included from the same folder
00030 #include "util/base/exception.h"
00031 #include "model/metamodel/grids/cellgrid.h"
00032 
00033 #include "layer.h"
00034 
00035 namespace FIFE {
00036     static std::string INVALID_LAYER_SET = "Cannot set layer coordinates, given layer is not initialized properly";
00037     static std::string INVALID_LAYER_GET = "Cannot get layer coordinates, layer is not initialized properly";
00038     
00039     Location::Location() {
00040         reset();
00041     }
00042 
00043     Location::Location(const Location& loc) {
00044         reset();
00045         m_layer = loc.m_layer;
00046         m_exact_layer_coords = loc.m_exact_layer_coords;
00047     }
00048     
00049     Location::Location(Layer* layer) {
00050         reset();
00051         m_layer = layer;
00052     }
00053     
00054     Location::~Location() {
00055     }
00056     
00057     void Location::reset() {
00058         m_exact_layer_coords.x = 0;
00059         m_exact_layer_coords.y = 0;
00060         m_exact_layer_coords.z = 0;
00061         m_layer = NULL;
00062     }
00063     
00064     Location& Location::operator=(const Location& rhs) {
00065         m_layer = rhs.m_layer;
00066         m_exact_layer_coords.x = rhs.m_exact_layer_coords.x;
00067         m_exact_layer_coords.y = rhs.m_exact_layer_coords.y;
00068         m_exact_layer_coords.z = rhs.m_exact_layer_coords.z;
00069         return *this;
00070     }
00071     
00072     Map* Location::getMap() const {
00073         if (!m_layer) {
00074             return NULL;
00075         }
00076         return m_layer->getMap();
00077     }
00078         
00079     void Location::setLayer(Layer* layer) {
00080         m_layer = layer;
00081     }
00082     
00083     Layer* Location::getLayer() const {
00084         return m_layer;
00085     }
00086     
00087     void Location::setExactLayerCoordinates(const ExactModelCoordinate& coordinates) {
00088         if (!isValid()) {
00089             throw NotSet(INVALID_LAYER_SET);
00090         }
00091         m_exact_layer_coords = coordinates;
00092     }
00093     
00094     void Location::setLayerCoordinates(const ModelCoordinate& coordinates) {
00095         setExactLayerCoordinates(intPt2doublePt(coordinates));
00096     }
00097     
00098     void Location::setMapCoordinates(const ExactModelCoordinate& coordinates) {
00099         if (!isValid()) {
00100             throw NotSet(INVALID_LAYER_SET);
00101         }
00102         m_exact_layer_coords = m_layer->getCellGrid()->toExactLayerCoordinates(coordinates);
00103     }
00104     
00105     ExactModelCoordinate& Location::getExactLayerCoordinatesRef() {
00106         return m_exact_layer_coords;
00107     }
00108     
00109     ExactModelCoordinate Location::getExactLayerCoordinates() const {
00110         return m_exact_layer_coords;
00111     }
00112     
00113     ModelCoordinate Location::getLayerCoordinates() const {
00114         return ModelCoordinate(doublePt2intPt(m_exact_layer_coords));
00115     }
00116     
00117     ExactModelCoordinate Location::getMapCoordinates() const {
00118         return m_layer->getCellGrid()->toMapCoordinates(m_exact_layer_coords);
00119     }
00120     
00121     bool Location::isValid() const {
00122         return isValid(m_layer);
00123     }
00124     
00125     bool Location::isValid(const Layer* layer) const {
00126         return (layer && layer->getCellGrid());
00127     }
00128     
00129     ExactModelCoordinate Location::getExactLayerCoordinates(const Layer* layer) const {
00130         if (!isValid(layer)) {
00131             throw NotSet(INVALID_LAYER_GET);
00132         }
00133 
00134         if (layer == m_layer) {
00135             return m_exact_layer_coords;
00136         }
00137 
00138         CellGrid* cg1 = m_layer->getCellGrid();
00139         CellGrid* cg2 = layer->getCellGrid();
00140         return cg2->toExactLayerCoordinates(cg1->toMapCoordinates(m_exact_layer_coords));
00141     }
00142     
00143     ModelCoordinate Location::getLayerCoordinates(const Layer* layer) const {
00144         if (!isValid(layer)) {
00145             throw NotSet(INVALID_LAYER_GET);
00146         }
00147 
00148         if (layer == m_layer) {
00149             return getLayerCoordinates();
00150         }
00151 
00152         CellGrid* cg1 = m_layer->getCellGrid();
00153         CellGrid* cg2 = layer->getCellGrid();
00154         return cg2->toLayerCoordinates(cg1->toMapCoordinates(m_exact_layer_coords));
00155     }
00156     
00157     double Location::getCellOffsetDistance() const {
00158         const ExactModelCoordinate& pt  = m_exact_layer_coords;
00159         double dx = pt.x - static_cast<double>(static_cast<int32_t>(pt.x));
00160         double dy = pt.y - static_cast<double>(static_cast<int32_t>(pt.y));
00161         return Mathd::Sqrt(dx*dx + dy*dy);
00162     }
00163     
00164     std::ostream& operator<<(std::ostream& os, const Location& l) {
00165         ExactModelCoordinate p = l.getExactLayerCoordinates();
00166         return os << "x=" << p.x << ", y=" << p.y;
00167     }
00168     
00169     double Location::getMapDistanceTo(const Location& location) const{
00170         ExactModelCoordinate current = getMapCoordinates();
00171         ExactModelCoordinate target = location.getMapCoordinates();
00172         
00173         double rx = current.x - target.x;
00174         double ry = current.y - target.y;
00175         double rz = current.z - target.z;
00176         
00177         return Mathd::Sqrt(rx*rx + ry*ry + rz*rz);
00178     }
00179 
00180     double Location::getLayerDistanceTo(const Location& location) const{
00181         ModelCoordinate current = getLayerCoordinates();
00182         ModelCoordinate target = location.getLayerCoordinates(m_layer);
00183         
00184         double rx = current.x - target.x;
00185         double ry = current.y - target.y;
00186         double rz = current.z - target.z;
00187         
00188         return Mathd::Sqrt(rx*rx + ry*ry + rz*rz);
00189     }   
00190 }