aboutsummaryrefslogtreecommitdiff
path: root/engines/sword25/math/region.h
blob: 4ce71a85613f8bd13e0137f0d645aa45d41538d1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
// -----------------------------------------------------------------------------
// This file is part of Broken Sword 2.5
// Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsd�rfer
//
// Broken Sword 2.5 is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// Broken Sword 2.5 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Broken Sword 2.5; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// -----------------------------------------------------------------------------

#ifndef SWORD25_REGION_H
#define SWORD25_REGION_H

#include "sword25/kernel/memlog_off.h"
#include <vector>
#include "sword25/kernel/memlog_on.h"

#include "sword25/kernel/common.h"
#include "sword25/kernel/persistable.h"
#include "sword25/math/vertex.h"
#include "sword25/math/polygon.h"
#include "sword25/math/rect.h"

/**
	@brief Diese Klasse ist die Basisklasse aller Regionen.

	Mit der Methode IsValid() l�sst sich abfragen, ob sich das Objekt in einem g�ltigen Zustand befindet.<br>
	Sollte dies nicht der Fall sein, ist die Methode Init() die einzige Methode die aufgerufen werden darf.
	Diese Klasse garantiert, dass die Vertecies der die Umriss- und die Lochpolygone im Uhrzeigersinn angeordnet sind, so dass auf den Polygonen
	arbeitende Algorithmen nur f�r diese Anordnung implementiert werden m�ssen.
*/
class BS_Region : public BS_Persistable
{
protected:
	/**
		@brief Erzeugt ein uninitialisiertes #BS_Region Objekt.

		Nach dem Erzeugen ist das Objekt noch ung�ltig (IsValid() gibt false zur�ck), allerdings kann das Objekt nachtr�glich �ber
		einen Aufruf von Init() in einen g�ltigen Zustand versetzt werden.
	*/
	BS_Region();

	BS_Region(BS_InputPersistenceBlock & Reader, unsigned int Handle);

public:
	enum REGION_TYPE
	{
		RT_REGION,
		RT_WALKREGION,
	};

	static unsigned int Create(REGION_TYPE Type);
	static unsigned int Create(BS_InputPersistenceBlock & Reader, unsigned int Handle = 0);

	virtual ~BS_Region();

	/**
		@brief Initialisiert ein BS_Region Objekt.
		@param Contour ein Polygon das den Umriss der Region angibt.
		@param pHoles ein Pointer auf einen Vector von Polygonen, die L�cher in der Region angeben.<br>
					  Falls die Region keine L�cher hat, muss NULL �bergeben werden.<br>
					  Der Standardwert ist NULL.
		@return Gibt true zur�ck, wenn die Initialisierung erfolgreich war.<br>
				Gibt false zur�ck, wenn die Intialisierung fehlgeschlagen ist.
		@remark Falls die Region bereits initialisiert war, wird der alte Zustand gel�scht.
	*/
	virtual bool Init(const BS_Polygon& Contour, const std::vector<BS_Polygon>* pHoles = NULL);
	
	//@{
	/** @name Sondierende Methoden */

	/**
		@brief Gibt an, ob das Objekt in einem g�ltigen Zustand ist.
		@return Gibt true zur�ck, wenn sich das Objekt in einem g�ltigen Zustand befindet.
				Gibt false zur�ck, wenn sich das Objekt in einem ung�ltigen Zustand befindet.
		@remark Ung�ltige Objekte k�nnen durch einen Aufruf von Init() in einen g�ltigen Zustand versetzt werden.
	*/
	bool IsValid() const { return m_Valid; }

	/**
		@brief Gibt die Position der Region zur�ck.
	*/
	const BS_Vertex& GetPosition() const { return m_Position; }

	/**
		@brief Gibt die Position des Region auf der X-Achse zur�ck.
	*/
	int GetPosX() const { return m_Position.X; }

	/**
		@brief Gibt die Position des Region auf der Y-Achse zur�ck.
	*/
	int GetPosY() const { return m_Position.Y; }

	/**
		@brief Gibt an, ob sich ein Punkt innerhalb der Region befindet.
		@param Vertex ein Vertex, mit den Koordinaten des zu testenden Punktes.
		@return Gibt true zur�ck, wenn sich der Punkt innerhalb der Region befindet.<br>
				Gibt false zur�ck, wenn sich der Punkt au�erhalb der Region befindet.
	*/
	bool IsPointInRegion(const BS_Vertex& Vertex) const;

	/**
		@brief Gibt an, ob sich ein Punkt innerhalb der Region befindet.
		@param X die Position des Punktes auf der X-Achse.
		@param Y die Position des Punktes auf der Y-Achse.
		@return Gibt true zur�ck, wenn sich der Punkt innerhalb der Region befindet.<br>
				Gibt false zur�ck, wenn sich der Punkt au�erhalb der Region befindet.
	*/
	bool IsPointInRegion(int X, int Y) const;

	/**
		@brief Gibt das Umrisspolygon der Region zur�ck.
	*/
	const BS_Polygon& GetContour() const { return m_Polygons[0]; }

	/**
		@brief Gibt die Anzahl der Lochpolygone in der Region zur�ck.
	*/
	int GetHoleCount() const { return static_cast<int>(m_Polygons.size() - 1); }

	/**
		@brief Gibt ein bestimmtes Lochpolygon in der Region zur�ck.
		@param i die Nummer des zur�ckzugebenen Loches.<br>
				 Dieser Wert muss zwischen 0 und GetHoleCount() - 1 liegen.
		@return Gibt das gew�nschte Lochpolygon zur�ck.
	*/
	inline const BS_Polygon& GetHole(unsigned int i) const;

	/**
		@brief Findet f�r einen Punkt ausserhalb der Region den n�chsten Punkt, der sich innerhalb der Region befindet.
		@param Point der Punkt, der sich ausserhalb der Region befindet
		@return Gibt den Punkt innerhalb der Region zur�ck, der den geringsten Abstand zum �bergebenen Punkt hat.
		@remark Diese Methode arbeitet nicht immer Pixelgenau. Man sollte sich also nicht darauf verlassen, dass es wirklich keine Punkt innerhalb der
				Region gibt, der dichter am �bergebenen Punkt liegt.
	*/
	BS_Vertex FindClosestRegionPoint(const BS_Vertex& Point) const;

	/**
		@brief Gibt den Schwerpunkt des Umrisspolygons zur�ck.
	*/
	BS_Vertex GetCentroid() const;

	bool IsLineOfSight(const BS_Vertex & a, const BS_Vertex & b) const;

	//@}

	//@{
	/** @name Manipulierende Methoden */

	/**
		@brief Setzt die Position der Region.
		@param X die neue Position der Region auf der X-Achse.
		@param Y die neue Position der Region auf der Y-Achse.
	*/
	virtual void SetPos(int X, int Y);

	/**
		@brief Setzt die Position der Region auf der X-Achse.
		@param X die neue Position der Region auf der X-Achse.
	*/
	void SetPosX(int X);

	/**
		@brief Setzt die Position der Region auf der Y-Achse.
		@param Y die neue Position der Region auf der Y-Achse.
	*/
	void SetPosY(int Y);

	//@}

	virtual bool Persist(BS_OutputPersistenceBlock & Writer);
	virtual bool Unpersist(BS_InputPersistenceBlock & Reader);

protected:
	/// Diese Variable gibt den Typ des Objektes an.
	REGION_TYPE m_Type;
	/// Diese Variable gibt an, ob der aktuelle Objektzustand g�ltig ist.
	bool m_Valid;
	/// Dieses Vertex gibt die Position der Region an.
	BS_Vertex m_Position;
	/// Dieser Vector enth�lt alle Polygone die die Region definieren. Das erste Element des Vectors ist die Kontur, alle weiteren sind die L�cher.
	std::vector<BS_Polygon> m_Polygons;
	/// Die Bounding-Box der Region.
	BS_Rect m_BoundingBox;

	/**
		@brief Aktualisiert die Bounding-Box der Region.
	*/
	void UpdateBoundingBox();

	/**
		@brief Findet den Punkt auf einer Linie, der einem anderen Punkt am n�chsten ist.
		@param LineStart der Startpunkt der Linie
		@param LineEnd der Endpunkt der Linie
		@param Point der Punkt, zu dem der n�chste Punkt auf der Linie konstruiert werden soll.
		@return Gibt den Punkt auf der Linie zur�ck, der dem �bergebenen Punkt am n�chsten ist.
	*/
	BS_Vertex FindClosestPointOnLine(const BS_Vertex & LineStart, const BS_Vertex & LineEnd, const BS_Vertex Point) const;
};


// -----------------------------------------------------------------------------
// Inlines
// -----------------------------------------------------------------------------

inline const BS_Polygon& BS_Region::GetHole(unsigned int i) const
{
	BS_ASSERT(i < m_Polygons.size() - 1);
	return m_Polygons[i + 1];
}

#endif