FIFE  2008.0
 All Classes Namespaces Functions Variables Enumerations Enumerator Pages
location.cpp
1 /***************************************************************************
2  * Copyright (C) 2005-2011 by the FIFE team *
3  * http://www.fifengine.net *
4  * This file is part of FIFE. *
5  * *
6  * FIFE is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU Lesser General Public *
8  * License as published by the Free Software Foundation; either *
9  * version 2.1 of the License, or (at your option) any later version. *
10  * *
11  * This library is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14  * Lesser General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU Lesser General Public *
17  * License along with this library; if not, write to the *
18  * Free Software Foundation, Inc., *
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
20  ***************************************************************************/
21 
22 // Standard C++ library includes
23 
24 // 3rd party library includes
25 
26 // FIFE includes
27 // These includes are split up in two parts, separated by one empty line
28 // First block: files included from the FIFE root src directory
29 // Second block: files included from the same folder
30 #include "util/base/exception.h"
31 #include "model/metamodel/grids/cellgrid.h"
32 
33 #include "layer.h"
34 
35 namespace FIFE {
36  static std::string INVALID_LAYER_SET = "Cannot set layer coordinates, given layer is not initialized properly";
37  static std::string INVALID_LAYER_GET = "Cannot get layer coordinates, layer is not initialized properly";
38 
39  Location::Location() {
40  reset();
41  }
42 
43  Location::Location(const Location& loc) {
44  reset();
45  m_layer = loc.m_layer;
46  m_exact_layer_coords = loc.m_exact_layer_coords;
47  }
48 
49  Location::Location(Layer* layer) {
50  reset();
51  m_layer = layer;
52  }
53 
54  Location::~Location() {
55  }
56 
57  void Location::reset() {
58  m_exact_layer_coords.x = 0;
59  m_exact_layer_coords.y = 0;
60  m_exact_layer_coords.z = 0;
61  m_layer = NULL;
62  }
63 
64  Location& Location::operator=(const Location& rhs) {
65  m_layer = rhs.m_layer;
66  m_exact_layer_coords.x = rhs.m_exact_layer_coords.x;
67  m_exact_layer_coords.y = rhs.m_exact_layer_coords.y;
68  m_exact_layer_coords.z = rhs.m_exact_layer_coords.z;
69  return *this;
70  }
71 
72  Map* Location::getMap() const {
73  if (!m_layer) {
74  return NULL;
75  }
76  return m_layer->getMap();
77  }
78 
79  void Location::setLayer(Layer* layer) {
80  m_layer = layer;
81  }
82 
83  Layer* Location::getLayer() const {
84  return m_layer;
85  }
86 
87  void Location::setExactLayerCoordinates(const ExactModelCoordinate& coordinates) {
88  if (!isValid()) {
89  throw NotSet(INVALID_LAYER_SET);
90  }
91  m_exact_layer_coords = coordinates;
92  }
93 
94  void Location::setLayerCoordinates(const ModelCoordinate& coordinates) {
95  setExactLayerCoordinates(intPt2doublePt(coordinates));
96  }
97 
98  void Location::setMapCoordinates(const ExactModelCoordinate& coordinates) {
99  if (!isValid()) {
100  throw NotSet(INVALID_LAYER_SET);
101  }
102  m_exact_layer_coords = m_layer->getCellGrid()->toExactLayerCoordinates(coordinates);
103  }
104 
105  ExactModelCoordinate& Location::getExactLayerCoordinatesRef() {
106  return m_exact_layer_coords;
107  }
108 
109  ExactModelCoordinate Location::getExactLayerCoordinates() const {
110  return m_exact_layer_coords;
111  }
112 
113  ModelCoordinate Location::getLayerCoordinates() const {
114  return ModelCoordinate(doublePt2intPt(m_exact_layer_coords));
115  }
116 
117  ExactModelCoordinate Location::getMapCoordinates() const {
118  return m_layer->getCellGrid()->toMapCoordinates(m_exact_layer_coords);
119  }
120 
121  bool Location::isValid() const {
122  return isValid(m_layer);
123  }
124 
125  bool Location::isValid(const Layer* layer) const {
126  return (layer && layer->getCellGrid());
127  }
128 
129  ExactModelCoordinate Location::getExactLayerCoordinates(const Layer* layer) const {
130  if (!isValid(layer)) {
131  throw NotSet(INVALID_LAYER_GET);
132  }
133 
134  if (layer == m_layer) {
135  return m_exact_layer_coords;
136  }
137 
138  CellGrid* cg1 = m_layer->getCellGrid();
139  CellGrid* cg2 = layer->getCellGrid();
140  return cg2->toExactLayerCoordinates(cg1->toMapCoordinates(m_exact_layer_coords));
141  }
142 
143  ModelCoordinate Location::getLayerCoordinates(const Layer* layer) const {
144  if (!isValid(layer)) {
145  throw NotSet(INVALID_LAYER_GET);
146  }
147 
148  if (layer == m_layer) {
149  return getLayerCoordinates();
150  }
151 
152  CellGrid* cg1 = m_layer->getCellGrid();
153  CellGrid* cg2 = layer->getCellGrid();
154  return cg2->toLayerCoordinates(cg1->toMapCoordinates(m_exact_layer_coords));
155  }
156 
157  double Location::getCellOffsetDistance() const {
158  const ExactModelCoordinate& pt = m_exact_layer_coords;
159  double dx = pt.x - static_cast<double>(static_cast<int32_t>(pt.x));
160  double dy = pt.y - static_cast<double>(static_cast<int32_t>(pt.y));
161  return Mathd::Sqrt(dx*dx + dy*dy);
162  }
163 
164  std::ostream& operator<<(std::ostream& os, const Location& l) {
165  ExactModelCoordinate p = l.getExactLayerCoordinates();
166  return os << "x=" << p.x << ", y=" << p.y;
167  }
168 
169  double Location::getMapDistanceTo(const Location& location) const{
170  ExactModelCoordinate current = getMapCoordinates();
171  ExactModelCoordinate target = location.getMapCoordinates();
172 
173  double rx = current.x - target.x;
174  double ry = current.y - target.y;
175  double rz = current.z - target.z;
176 
177  return Mathd::Sqrt(rx*rx + ry*ry + rz*rz);
178  }
179 
180  double Location::getLayerDistanceTo(const Location& location) const{
181  ModelCoordinate current = getLayerCoordinates();
182  ModelCoordinate target = location.getLayerCoordinates(m_layer);
183 
184  double rx = current.x - target.x;
185  double ry = current.y - target.y;
186  double rz = current.z - target.z;
187 
188  return Mathd::Sqrt(rx*rx + ry*ry + rz*rz);
189  }
190 }