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
|