~ubuntu-branches/debian/sid/ember/sid

« back to all changes in this revision

Viewing changes to src/components/ogre/terrain/TerrainArea.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michael Koch
  • Date: 2009-07-23 07:46:40 UTC
  • Revision ID: james.westby@ubuntu.com-20090723074640-wh0ukzis0kda36qv
Tags: upstream-0.5.6
ImportĀ upstreamĀ versionĀ 0.5.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// C++ Implementation: TerrainArea
 
3
//
 
4
// Description: 
 
5
//
 
6
//
 
7
// Author: Erik Hjortsberg <erik.hjortsberg@gmail.com>, (C) 2005
 
8
//
 
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.
 
13
// 
 
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.
 
18
// 
 
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.//
 
22
//
 
23
#ifdef HAVE_CONFIG_H
 
24
#include "config.h"
 
25
#endif
 
26
 
 
27
#include "TerrainArea.h"
 
28
#include "TerrainAreaParser.h"
 
29
 
 
30
#include "../EmberEntity.h"
 
31
#include <Mercator/Area.h>
 
32
 
 
33
namespace EmberOgre {
 
34
namespace Terrain {
 
35
 
 
36
 
 
37
 
 
38
 
 
39
 
 
40
TerrainArea::TerrainArea(EmberEntity* entity) : mArea(0), mOldArea(0), mEntity(entity)
 
41
{
 
42
}
 
43
 
 
44
 
 
45
TerrainArea::~TerrainArea()
 
46
{
 
47
        mAttrChangedSlot.disconnect();
 
48
        EventAreaRemoved.emit();
 
49
        delete mArea;
 
50
}
 
51
 
 
52
bool TerrainArea::init() {
 
53
        
 
54
 //   _fpreset();
 
55
        //_controlfp(_PC_64, _MCW_PC);
 
56
        //_controlfp(_RC_NEAR , _MCW_RC);
 
57
        bool successfulParsing = parseArea();
 
58
        if (successfulParsing) {
 
59
                observeEntity();
 
60
        }
 
61
        return successfulParsing;
 
62
        
 
63
}
 
64
 
 
65
bool TerrainArea::parseArea()
 
66
{
 
67
        if (!mEntity->hasAttr("area")) {
 
68
                S_LOG_FAILURE("TerrainArea created for entity with no area attribute");
 
69
                return false;
 
70
        }
 
71
        
 
72
        const Atlas::Message::Element areaElem(mEntity->valueOfAttr("area"));
 
73
        
 
74
        if (!areaElem.isMap()) {
 
75
                S_LOG_FAILURE("TerrainArea element ('area') must be of map type.");
 
76
                return false;
 
77
        }
 
78
        
 
79
        const Atlas::Message::MapType& areaData(areaElem.asMap());
 
80
        
 
81
        int layer = 0;
 
82
        WFMath::Polygon<2> poly;
 
83
        TerrainAreaParser parser;
 
84
        if (parser.parseArea(areaData, poly, layer)) {
 
85
                if (!mArea) {
 
86
                        mArea = new Mercator::Area(layer, false);
 
87
                } else {
 
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) {
 
90
                                mOldArea = mArea;
 
91
                                mArea = new Mercator::Area(layer, false);
 
92
                        }
 
93
                }
 
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
 
97
                
 
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()));
 
101
 
 
102
                mArea->setShape(poly);
 
103
 
 
104
                return true;    
 
105
        } else {
 
106
                return false;
 
107
        }
 
108
}
 
109
 
 
110
void TerrainArea::attributeChanged(const Atlas::Message::Element& attributeValue)
 
111
{
 
112
        if (parseArea()) {
 
113
                if (mOldArea) {
 
114
                        EventAreaSwapped(*mOldArea);
 
115
                        delete mOldArea;
 
116
                        mOldArea = 0;
 
117
                } else {
 
118
                        EventAreaChanged();
 
119
                }
 
120
        }
 
121
}
 
122
 
 
123
void TerrainArea::entity_Moved()
 
124
{
 
125
        if (parseArea()) {
 
126
                EventAreaChanged();
 
127
        }
 
128
}
 
129
 
 
130
void TerrainArea::observeEntity()
 
131
{
 
132
        mAttrChangedSlot.disconnect();
 
133
        if (mEntity) {
 
134
                mAttrChangedSlot = sigc::mem_fun(*this, &TerrainArea::attributeChanged);
 
135
                mEntity->observe("area", mAttrChangedSlot);
 
136
                mEntity->Moved.connect(sigc::mem_fun(*this, &TerrainArea::entity_Moved));
 
137
        }
 
138
}
 
139
 
 
140
}
 
141
}