2
// C++ Implementation: TerrainArea
7
// Author: Erik Hjortsberg <erik.hjortsberg@gmail.com>, (C) 2005
9
// This program is free software; you can redistribute it and/or modify
10
// it under the terms of the GNU General Public License as published by
11
// the Free Software Foundation; either version 2 of the License, or
12
// (at your option) any later version.
14
// This program is distributed in the hope that it will be useful,
15
// but WITHOUT ANY WARRANTY; without even the implied warranty of
16
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
// GNU General Public License for more details.
19
// You should have received a copy of the GNU General Public License
20
// along with this program; if not, write to the Free Software
21
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.//
27
#include "TerrainArea.h"
28
#include "TerrainAreaParser.h"
30
#include "../EmberEntity.h"
31
#include <Mercator/Area.h>
40
TerrainArea::TerrainArea(EmberEntity* entity) : mArea(0), mOldArea(0), mEntity(entity)
45
TerrainArea::~TerrainArea()
47
mAttrChangedSlot.disconnect();
48
EventAreaRemoved.emit();
52
bool TerrainArea::init() {
55
//_controlfp(_PC_64, _MCW_PC);
56
//_controlfp(_RC_NEAR , _MCW_RC);
57
bool successfulParsing = parseArea();
58
if (successfulParsing) {
61
return successfulParsing;
65
bool TerrainArea::parseArea()
67
if (!mEntity->hasAttr("area")) {
68
S_LOG_FAILURE("TerrainArea created for entity with no area attribute");
72
const Atlas::Message::Element areaElem(mEntity->valueOfAttr("area"));
74
if (!areaElem.isMap()) {
75
S_LOG_FAILURE("TerrainArea element ('area') must be of map type.");
79
const Atlas::Message::MapType& areaData(areaElem.asMap());
82
WFMath::Polygon<2> poly;
83
TerrainAreaParser parser;
84
if (parser.parseArea(areaData, poly, layer)) {
86
mArea = new Mercator::Area(layer, false);
88
///A bit of an ugly hack here since the Mercator system doesn't support changing the layer. We need to swap the old area for a new one if the layer has changed.
89
if (mArea->getLayer() != layer) {
91
mArea = new Mercator::Area(layer, false);
94
/// transform polygon into terrain coords
95
WFMath::Vector<3> xVec = WFMath::Vector<3>(1.0, 0.0, 0.0).rotate(mEntity->getOrientation());
96
double theta = atan2(xVec.y(), xVec.x()); // rotation about Z
98
WFMath::RotMatrix<2> rm;
99
poly.rotatePoint(rm.rotation(theta), WFMath::Point<2>(0,0));
100
poly.shift(WFMath::Vector<2>(mEntity->getPosition().x(), mEntity->getPosition().y()));
102
mArea->setShape(poly);
110
void TerrainArea::attributeChanged(const Atlas::Message::Element& attributeValue)
114
EventAreaSwapped(*mOldArea);
123
void TerrainArea::entity_Moved()
130
void TerrainArea::observeEntity()
132
mAttrChangedSlot.disconnect();
134
mAttrChangedSlot = sigc::mem_fun(*this, &TerrainArea::attributeChanged);
135
mEntity->observe("area", mAttrChangedSlot);
136
mEntity->Moved.connect(sigc::mem_fun(*this, &TerrainArea::entity_Moved));