File: RegionManager.h

package info (click to toggle)
darkradiant 3.9.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 41,080 kB
  • sloc: cpp: 264,743; ansic: 10,659; python: 1,852; xml: 1,650; sh: 92; makefile: 21
file content (158 lines) | stat: -rw-r--r-- 5,011 bytes parent folder | download | duplicates (4)
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
#pragma once

#include <list>
#include "iregion.h"
#include "icommandsystem.h"
#include "math/AABB.h"
#include "math/Vector2.h"
#include "iscenegraph.h"
#include "ientity.h"
#include "imap.h"

/** 
 * greebo: The RegionManager provides methods to enable/disable
 * the regioning for map editing as well as functions
 * to set the region bounds from brushes/xyview/current selection.
 *
 * Regioned nodes are hidden during map editing (they get their excluded bit set).
 * It's still possible to apply additional filtering to a region via show/hide,
 * these systems are independent of each other.
 *
 * @SaveRegion: This saves the current region (all non-excluded nodes) to a
 * specified file and places six wall/floor/ceiling brushes to
 * the file together with an info_player_start entity.
 * The info_player_start is placed at the current camera position.
 */
namespace map
{

class RegionManager :
	public IRegionManager
{
	// TRUE, if regioning is active
	bool _active;

	// The largest/smalles possible world coordinates (+/- 65536)
	float _worldMin;
	float _worldMax;

	// The bounds of this region
	AABB _bounds;

	// The brushes around the region boundaries
	// (legacy array to stay compatible with the ConstructRegionBrushes() function)
	scene::INodePtr _brushes[6];

	// The pointer to the info_player_start entity
	IEntityNodePtr _playerStart;

public:
	RegionManager();

	// Clears the region information (and releases the wall brushes too)
	void clear();

	/** greebo: Applies the currently active AABB to the scenegraph.
	 * This excludes all nodes out of the current region bounds.
	 */
	void enable();

	// Disables regioning and resets the bounds to _worldMax
	void disable();

	/** greebo: Returns the current regioning state (true = active)
	 */
	bool isEnabled() const;

	/** greebo: Retrieves a reference to the internally stored AABB.
	 */
	const AABB& getRegion() const;

	/** greebo: Stores the corners coordinates of the currently active
	 * 			region into the given <regionMin>, <regionMax> vectors.
	 *
	 * Note: If region is inactive, the maximum possible bounds are returned.
	 */
	AABB getRegionBounds() override;
	void getMinMax(Vector3& regionMin, Vector3& regionMax) const;

	/** greebo: Sets the region bounds according to the given <aabb>
	 *
	 * Note: passing an invalid AABB disables the regioning.
	 *
	 * @autoEnable: set this to false to prevent the scenegraph from being
	 * 				traversed and its nodes being hidden (enable() is not called).
	 */
	void setRegion(const AABB& aabb, bool autoEnable = true);

	/** greebo: sets the region bounds from the given rectangle in the XY plane.
	 *
	 * The z-component is being stretched from worldMin to worldMax, so that the
	 * region contains the entire height of the map.
	 */
	void setRegionFromXY(Vector2 topLeft, Vector2 lowerRight);

	// RegisterableModule
	const std::string& getName() const override;
	const StringSet& getDependencies() const override;
	void initialiseModule(const IApplicationContext& ctx) override;

private:
	/** greebo: Adds the bounding brushes that enclose the current region.
	*/
	void addRegionBrushes();

	/** greebo: Removes the bounding brushes added by addRegionBrushes().
	*/
	void removeRegionBrushes();

	/** greebo: The traversal function that is used to save the map to a file.
	* 			This ensures that only regioned items are saved.
	*
	* Note: the map saver passes its own walker to this function and leaves it up to it
	* 		 whether the walker.pre() and walker.post() methods are invoked. This allows
	* 		 filtering of the non-regioned nodes.
	*/
	static void traverseRegion(const scene::INodePtr& root, scene::NodeVisitor& walker);

	/** greebo: Saves the current selection as Region to the queried file.
	*/
	void saveRegion(const cmd::ArgumentList& args);

	/** greebo: Disables regioning and resets the bounds.
	*/
	void disableRegion(const cmd::ArgumentList& args);

	/** greebo: Sets the region according to the XY bounds of the current orthoview
	*/
	void setRegionXY(const cmd::ArgumentList& args);

	/** greebo: Sets the region to the bounds of the currently drawn brush,
	* 			similar to the partial tall selection method.
	* 			A single brush has to be selected (an errormsg is displayed otherwise).
	*
	* Note: The brush is deleted after "use".
	*/
	void setRegionFromBrush(const cmd::ArgumentList& args);

	/** greebo: Retrieves the AABB from the current selection and
	* 			takes it as new region bounds. The selection is NOT deleted.
	* 			Not available in component selection mode.
	* 			The selected items are de-selected after "use".
	*/
	void setRegionFromSelection(const cmd::ArgumentList& args);

	/** greebo: Adds the region commands to the EventManager.
	*/
	void initialiseCommands();

	void onMapEvent(IMap::MapEvent ev);

	// Helper to create the actual brushes bounding the region
	static void constructRegionBrushes(scene::INodePtr brushes[6], 
		const Vector3& region_mins, const Vector3& region_maxs);

	AABB getVisibleBounds();
};

} // namespace