File: AINodeContainer.h

package info (click to toggle)
scummvm 2.9.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 450,580 kB
  • sloc: cpp: 4,299,825; asm: 28,322; python: 12,901; sh: 11,302; java: 9,289; xml: 7,895; perl: 2,639; ansic: 2,465; yacc: 1,670; javascript: 1,020; makefile: 933; lex: 578; awk: 275; objc: 82; sed: 11; php: 1
file content (303 lines) | stat: -rw-r--r-- 7,374 bytes parent folder | download | duplicates (2)
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
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
/* ScummVM - Graphic Adventure Engine
 *
 * ScummVM is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * This program 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 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

/*
 * Copyright (C) 2006-2010 - Frictional Games
 *
 * This file is part of HPL1 Engine.
 */

#ifndef HPL_AI_NODE_CONTAINER_H
#define HPL_AI_NODE_CONTAINER_H

#include "hpl1/engine/math/MathTypes.h"
#include "hpl1/engine/system/SystemTypes.h"

#include "common/array.h"
#include "common/list.h"
#include "hpl1/engine/physics/PhysicsWorld.h"

namespace hpl {

class cWorld3D;

//--------------------------------

typedef tFlag tAIFreePathFlag;

#define eAIFreePathFlag_SkipStatic (0x00000001)
#define eAIFreePathFlag_SkipDynamic (0x00000002)
#define eAIFreePathFlag_SkipVolatile (0x00000004)

//--------------------------------
class cAINode;

class cAINodeEdge {
public:
	float mfDistance;
	float mfSqrDistance;
	cAINode *mpNode;
};

typedef Common::Array<cAINodeEdge> tAINodeEdgeVec;
typedef tAINodeEdgeVec::iterator tAINodeEdgeVecIt;

//--------------------------------

class cAINode {
	friend class cAINodeContainer;

public:
	cAINode();
	~cAINode();

	void AddEdge(cAINode *pNode);

	int GetEdgeNum() const { return (int)mvEdges.size(); }
	inline cAINodeEdge *GetEdge(int alIdx) { return &mvEdges[alIdx]; }

	const cVector3f &GetPosition() { return mvPosition; }

	const tString &GetName() { return msName; }

private:
	tString msName;
	cVector3f mvPosition;
	void *mpUserData;

	tAINodeEdgeVec mvEdges;
};

typedef Common::Array<cAINode *> tAINodeVec;
typedef tAINodeVec::iterator tAINodeVecIt;

typedef Common::List<cAINode *> tAINodeList;
typedef tAINodeList::iterator tAINodeListIt;

typedef Common::StableMap<tString, cAINode *> tAINodeMap;
typedef tAINodeMap::iterator tAINodeMapIt;

//--------------------------------

class iAIFreePathCallback {
public:
	virtual ~iAIFreePathCallback() = default;
	virtual bool Intersects(iPhysicsBody *pBody, cPhysicsRayParams *apParams) = 0;
};

//--------------------------------

class cAINodeRayCallback : public iPhysicsRayCallback {
public:
	void Reset();
	void SetFlags(tAIFreePathFlag aFlags) { mFlags = aFlags; }

	bool BeforeIntersect(iPhysicsBody *pBody);
	bool OnIntersect(iPhysicsBody *pBody, cPhysicsRayParams *apParams);

	bool Intersected();

	iAIFreePathCallback *mpCallback;

private:
	bool mbIntersected;
	tAIFreePathFlag mFlags;
};

//--------------------------------

class cAIGridNode {
public:
	tAINodeList mlstNodes;
};

//--------------------------------
class cAINodeContainer;

class cAINodeIterator {
public:
	cAINodeIterator(cAINodeContainer *apContainer, const cVector3f &avPos, float afRadius);

	bool HasNext();
	cAINode *Next();

private:
	bool IncGridPos();

	cAINodeContainer *mpContainer;
	cVector3f mvPosition;
	float mfRadius;
	cVector2l mvStartGridPos;
	cVector2l mvEndGridPos;
	cVector2l mvGridPos;

	tAINodeList *mpNodeList;
	tAINodeListIt mNodeIt;
};

//--------------------------------

class cAINodeContainer {
	friend class cAINodeIterator;

public:
	cAINodeContainer(const tString &asName, const tString &asNodeName,
					 cWorld3D *apWorld, const cVector3f &avCollideSize);
	~cAINodeContainer();

	const tString &GetNodeName() { return msNodeName; }
	const tString &GetName() { return msName; }

	const cVector3f &GetCollideSize() { return mvSize; }

	/**
	 * Reserves spaces for nodes.
	 * \param alReserveSpace Number of nodes to reserve space for.
	 */
	void ReserveSpace(size_t alReserveSpace);

	/**
	 * Adds a new node to the container.
	 * \param &asName Name of the node
	 * \param &avPosition Position of the node.
	 * \param *apUserData Data supplied by user.
	 */
	void AddNode(const tString &asName, const cVector3f &avPosition, void *apUserData = NULL);

	/**
	 * Get the number of nodes.
	 */
	int GetNodeNum() const;

	/**
	 * Get a node.
	 * \param alIdx index of node.
	 */
	inline cAINode *GetNode(int alIdx) { return mvNodes[alIdx]; }

	/**
	 * Gets a node based on the name.
	 * \param &asName Name of the node.
	 */
	cAINode *GetNodeFromName(const tString &asName);

	/**
	 * Compile the added nodes.
	 */
	void Compile();

	/**
	 * Build a grid map for nodes. (Used internally mostly)
	 */
	void BuildNodeGridMap();

	/**
	 * Returns a node iterator. Note that the radius is not checked, some nodes may lie outside.
	 * \param &avPosition
	 * \param afRadius
	 * \return
	 */
	cAINodeIterator GetNodeIterator(const cVector3f &avPosition, float afRadius);

	/**
	 * Checks for a free path using the containers collide size.
	 * \param &avStart
	 * \param &avEnd
	 * \param alRayNum The max number of rays cast, -1 = maximum
	 * \param alFlags Set Flags for the ray casting.
	 * \param apCallback Check for every body and overrides alFlags.
	 * \return
	 */
	bool FreePath(const cVector3f &avStart, const cVector3f &avEnd, int alRayNum = -1,
				  tAIFreePathFlag aFlags = 0, iAIFreePathCallback *apCallback = NULL);

	/**
	 * Sets the max number of end node added to a node.
	 * \param alX The max number, -1 = unlimited
	 */
	void SetMaxEdges(int alX) { mlMaxNodeEnds = alX; }

	/**
	 * Sets the min number of end node added to a node. This overrides max distance when needed.
	 */
	void SetMinEdges(int alX) { mlMinNodeEnds = alX; }

	/**
	 * Sets the max distance for an end node.
	 * \param afX
	 */
	void SetMaxEdgeDistance(float afX) { mfMaxEndDistance = afX; }

	float GetMaxEdgeDistance() const { return mfMaxEndDistance; }

	void SetMaxHeight(float afX) { mfMaxHeight = afX; }
	float GetMaxHeight() const { return mfMaxHeight; }

	/**
	 * When calculating if there is a free path between two nodes. Is the node position the center of the collider.
	 * If not the position is the feet position.
	 */
	void SetNodeIsAtCenter(bool abX) { mbNodeIsAtCenter = abX; }
	bool GetNodeIsAtCenter() { return mbNodeIsAtCenter; }

	/**
	 * Saves all the node connections to file.
	 */
	void SaveToFile(const tString &asFile);
	/**
	 * Loads all node connections from file. Only to be done after all nodes are loaded.
	 */
	void LoadFromFile(const tString &asFile);

private:
	cVector2l GetGridPosFromLocal(const cVector2f &avLocalPos);
	cAIGridNode *GetGrid(const cVector2l &avPos);

	tString msName;
	tString msNodeName;

	cWorld3D *mpWorld;
	cVector3f mvSize;

	cAINodeRayCallback *mpRayCallback;
	tAINodeVec mvNodes;
	tAINodeMap m_mapNodes;

	bool mbNodeIsAtCenter;

	cVector2l mvGridMapSize;
	cVector2f mvGridSize;
	cVector2f mvMinGridPos;
	cVector2f mvMaxGridPos;
	int mlNodesPerGrid;

	Common::Array<cAIGridNode> mvGrids;

	// properties
	int mlMaxNodeEnds;
	int mlMinNodeEnds;
	float mfMaxEndDistance;
	float mfMaxHeight;
};

} // namespace hpl

#endif // HPL_AI_NODE_CONTAINER_H