Cafu Engine
MapElement.hpp
1 /*
2 Cafu Engine, http://www.cafu.de/
3 Copyright (c) Carsten Fuchs and other contributors.
4 This project is licensed under the terms of the MIT license.
5 */
6 
7 #ifndef CAFU_MAP_ELEMENT_HPP_INCLUDED
8 #define CAFU_MAP_ELEMENT_HPP_INCLUDED
9 
10 #include "Math3D/Angles.hpp"
11 #include "Math3D/BoundingBox.hpp"
12 #include "Templates/Array.hpp"
13 #include "Templates/Pointer.hpp"
14 #include "TypeSys.hpp"
15 
16 #include "wx/colour.h"
17 #include "wx/gdicmn.h"
18 #include "wx/string.h"
19 
20 #include <ostream>
21 
22 
23 namespace MapEditor { class CompMapEntityT; }
24 class GroupT;
25 class MapDocumentT;
26 class Renderer2DT;
27 class Renderer3DT;
28 class TextParserT;
29 class ViewWindow2DT;
30 template<class T> class Matrix4x4T;
32 
33 
34 /// The TypeInfoTs of all MapElementT derived classes must register with this TypeInfoManT instance.
35 cf::TypeSys::TypeInfoManT& GetMapElemTIM();
36 
37 
38 /// An instance of this class encapsulates the transform-related state of a MapElementT.
40 {
41  public:
42 
43  virtual ~TrafoMementoT() { }
44 };
45 
46 
47 /// This is the base class for all elements ("objects") that can exist in a map.
48 ///
49 /// Generally, elements can exist stand-alone, without being assigned to a parent entity;
50 /// they are intended to be fully functional even without a parent entity.
51 /// Examples include newly created elements, elements in the clipboard, temporary copies (e.g. for preview
52 /// rendering in Selection tool), and elements inside commands (e.g. state before or after a transform).
53 /// For stand-alone elements, GetParent() returns `NULL`.
54 ///
55 /// Usually though, elements are kept by an entity. The entity that an element is a part of can be learned
56 /// with the GetParent() method.
58 {
59  public:
60 
61  /// The default constructor.
62  MapElementT();
63 
64  /// The copy constructor for copying a map element.
65  ///
66  /// @param Elem The element to copy-construct this element from.
67  ///
68  /// Contrary to Elem, the new MapElementT instance is:
69  /// - never selected (no matter if Elem was selected),
70  /// - not in a group (and thus visible).
71  /// It is up to the caller to assign selection state and group membership if desired.
72  /// The new element is always constructed with a deep-copy (that is, the children of Elem are copied recursively).
73  MapElementT(const MapElementT& Elem);
74 
75  /// The virtual destructor.
76  virtual ~MapElementT();
77 
78 
79  virtual void Load_cmap(TextParserT& TP, MapDocumentT& MapDoc, bool IgnoreGroups);
80  virtual void Save_cmap(std::ostream& OutFile, unsigned long ElemNr, const MapDocumentT& MapDoc) const;
81 
82 
83  /// Returns the entity that this element is a part of, or `NULL` if the element has no parent entity.
84  /// See the MapElementT class documentation for additional information.
86 
87  /// Sets the parent entity that is element is a part of.
88  /// See the MapElementT class documentation for additional information.
90 
91 
92  /// Returns whether this element is currently selected in the map document.
93  bool IsSelected() const { return m_IsSelected; }
94 
95  /// Sets the selection state of this element. As this should always be in sync with the map document,
96  /// the map document is the only legitimate caller of this method (but there are some exceptions).
97  void SetSelected(bool Selected=true) { m_IsSelected=Selected; }
98 
99 
100  /// Returns whether this map element is (entirely or partially) translucent.
101  /// Translucent map elements are typically implemented with "alpha blending" and require rendering in back-to-front order.
102  /// @see EditorMaterialI::IsTranslucent()
103  virtual bool IsTranslucent() const { return false; }
104 
105  /// This method returns the "inherent" color of this map element.
106  /// The returned color should be used for rendering the map element whenever no better
107  /// (e.g. texture-mapped) alternative is available.
108  ///
109  /// @param ConsiderGroup Whether the map elements group color should be taken into account.
110  /// @returns the "inherent" color of this map element.
111  /// When the map element is in a group and ConsiderGroup is true, the group color is returned.
112  /// When the map element is an entity, the color of the entity class is returned.
113  /// Otherwise (the element is a primitive), when the map element is part of an entity, the entity color
114  /// is returned. Finally (it's a map primitive that is in the world), its native color is returned.
115  virtual wxColour GetColor(bool ConsiderGroup=true) const = 0;
116 
117  virtual wxString GetDescription() const { return ""; }
118 
119 
120  GroupT* GetGroup() const { return m_Group; } ///< Returns NULL when this map element is in no group, or the pionter to the group it is a member of otherwise.
121  void SetGroup(GroupT* Group) { m_Group = Group; } ///< Sets the group this element is a member of (use NULL for "no group").
122 
123  /// Returns whether this map element is currently visible (in the 2D, 3D and other views).
124  /// Note that the visibility does not depend on the visibility of the parent entity -- in CaWE, map elements are
125  /// mostly independent of their parents (and thus entities can also be "half visible" if the user wishes so).
126  bool IsVisible() const;
127 
128  /// Returns whether this map element can currently be selected (in the 2D, 3D and other views).
129  /// Note that as with IsVisible(), the "can select" status is independent of that of the parent entity.
130  bool CanSelect() const;
131 
132  /// Computes how the selection must be changed in order to toggle the given element when the element's entity
133  /// and group memberships are taken into account.
134  /// Unfortunately, the method cannot be `const`, because `this` map element is possibly added to one of the given
135  /// arrays, whose elements are non-`const`.
136  void GetToggleEffects(ArrayT<MapElementT*>& RemoveFromSel, ArrayT<MapElementT*>& AddToSel, bool AutoGroupEntities);
137 
138 
139  /// This is periodically called in order to have the element advance its internal clock by t seconds.
140  /// The typical use case is with elements that represent models for updating the current frame in their animation sequence.
141  virtual void AdvanceTime(float t) { }
142 
143  virtual void Render2D(Renderer2DT& Renderer) const { }
144  virtual void Render3D(Renderer3DT& Renderer) const { }
145 
146  /// Returns the spatial bounding-box of this map element.
147  virtual BoundingBox3fT GetBB() const=0;
148 
149  /// Traces a ray against this map element, and returns whether it was hit.
150  /// The ray for the trace is defined by RayOrigin + RayDir*Fraction, where Fraction is a scalar >= 0.
151  /// If a hit was detected, the Fraction is returned. Hit brushes return the number of the hit face as well.
152  /// This method has been implemented mainly for "picking", that is, left-click selection in the 3D views
153  /// (it makes sure that also objects that "clip nothing" in the engine can be picked), but it can also be used for any other purpose.
154  ///
155  /// @param RayOrigin The point in world space where the ray starts.
156  /// @param RayDir A unit vector in world space that describes the direction the ray extends to.
157  /// @param Fraction On hit, the scalar along RayDir at which the hit occurred is returned here.
158  /// @param FaceNr If this map element is a brush and it was hit, the number of the hit face is returned here.
159  ///
160  /// @returns true if the ray hit this map element, false otherwise. Additional hit data (i.e. Fraction and FaceNr)
161  /// is returned via reference paramaters.
162  virtual bool TraceRay(const Vector3fT& RayOrigin, const Vector3fT& RayDir, float& Fraction, unsigned long& FaceNr) const;
163 
164  /// This method determines if this map element is intersected/affected by the specified disc in ViewWin.
165  /// The disc for the test is defined by the given center pixel and the given radius.
166  /// For example, the caller can learn by the result of this method whether the map element should respond to a mouse-click
167  /// at the same pixel. Therefore, this method can be considered as the 2D analogue of the TraceRay() method.
168  virtual bool TracePixel(const wxPoint& Pixel, int Radius, const ViewWindow2DT& ViewWin) const;
169 
170  /// Returns a memento that encapsulates the transform-related state of this element.
171  /// The method saves all state in the memento that calls to the Trafo*() methods can possibly modify.
172  virtual TrafoMementoT* GetTrafoState() const { return NULL; }
173 
174  /// Restores the transform-related state of this element from the given memento.
175  /// The method restores all state from the memento that calls to the Trafo*() methods have possibly modified.
176  virtual void RestoreTrafoState(const TrafoMementoT* TM) { }
177 
178  /// Translates this element by the given vector (in world-space).
179  /// @param Delta The offset by which to translate the element.
180  /// @param LockTexCoords Transform the texture-space along with the geometry.
181  virtual void TrafoMove(const Vector3fT& Delta, bool LockTexCoords) { }
182 
183  /// Rotates this element about the given reference point (in world-space).
184  /// @param RefPoint The reference point (origin) for the rotation.
185  /// @param Angles The rotation angles for the three axes.
186  /// @param LockTexCoords Transform the texture-space along with the geometry.
187  virtual void TrafoRotate(const Vector3fT& RefPoint, const cf::math::AnglesfT& Angles, bool LockTexCoords) { }
188 
189  /// Scales this element about the given reference point (in world-space).
190  /// @param RefPoint The reference point (origin) for the scale.
191  /// @param Scale The scale factors for the three axes.
192  /// @param LockTexCoords Transform the texture-space along with the geometry.
193  /// @throws DivisionByZeroE, e.g. when Scale is too small and the element becomes degenerate (e.g. a brush with too small faces).
194  virtual void TrafoScale(const Vector3fT& RefPoint, const Vector3fT& Scale, bool LockTexCoords) { }
195 
196  /// Mirrors this element along the given mirror plane (in world-space).
197  /// @param NormalAxis The number of the axis along which the normal vector of the mirror plane points: 0, 1 or 2 for the x-, y- or z-axis respectively.
198  /// @param Dist The position of the mirror plane along its normal vector, where it intersects the NormalAxis.
199  /// @param LockTexCoords Transform the texture-space along with the geometry.
200  /// Note that the mirroring is not necessarily "perfect", because for some elements like models or plants,
201  /// only their point of origin can be mirrored, but not their mesh.
202  virtual void TrafoMirror(unsigned int NormalAxis, float Dist, bool LockTexCoords) { }
203 
204  /// Why does this method not replace all the other Trafo*() methods?
205  /// This method is the most generic, allowing transformations that e.g. are non-orthogonal (like shears or non-uniform scales).
206  /// This in turn conflicts with map primitives that can only store and deal with a restricted fixed set of transformations,
207  /// e.g. an origin, a rotation and a uniform scale. These values cannot properly be re-computed from a general matrix with
208  /// non-orthogonal basis vectors.
209  /// @param Matrix The matrix that describes the transform to be applied.
210  /// @param LockTexCoords Transform the texture-space along with the geometry.
211  virtual void Transform(const Matrix4x4fT& Matrix, bool LockTexCoords) { }
212 
213 
214  unsigned int GetFrameCount() const { return m_FrameCount; }
215  void SetFrameCount(unsigned int FrameCount) { m_FrameCount=FrameCount; }
216 
217 
218  // The TypeSys related declarations for this class.
219  virtual const cf::TypeSys::TypeInfoT* GetType() const { return &TypeInfo; }
220  static void* CreateInstance(const cf::TypeSys::CreateParamsT& Params);
221  static const cf::TypeSys::TypeInfoT TypeInfo;
222 
223 
224  protected:
225 
226  MapEditor::CompMapEntityT* m_Parent; ///< The entity that this element is a part of.
227  bool m_IsSelected; ///< Is this element currently selected in the map document?
228  GroupT* m_Group; ///< The group this element is in, NULL if in no group.
229  unsigned int m_FrameCount; ///< The number of the frame in which this element was last rendered in a 3D view, used in order to avoid processing/rendering it twice.
230 };
231 
232 #endif
This class provides auxiliary means for rendering a 3D view.
Definition: Renderer3D.hpp:30
This class implements the rendering into a 2D view.
Definition: Renderer2D.hpp:22
virtual void TrafoMirror(unsigned int NormalAxis, float Dist, bool LockTexCoords)
Mirrors this element along the given mirror plane (in world-space).
Definition: MapElement.hpp:202
This class represents a CaWE "map" document.
Definition: MapDocument.hpp:45
bool m_IsSelected
Is this element currently selected in the map document?
Definition: MapElement.hpp:227
virtual void TrafoRotate(const Vector3fT &RefPoint, const cf::math::AnglesfT &Angles, bool LockTexCoords)
Rotates this element about the given reference point (in world-space).
Definition: MapElement.hpp:187
void SetParent(MapEditor::CompMapEntityT *Ent)
Sets the parent entity that is element is a part of.
Definition: MapElement.cpp:73
virtual bool TraceRay(const Vector3fT &RayOrigin, const Vector3fT &RayDir, float &Fraction, unsigned long &FaceNr) const
Traces a ray against this map element, and returns whether it was hit.
Definition: MapElement.cpp:170
virtual void AdvanceTime(float t)
This is periodically called in order to have the element advance its internal clock by t seconds...
Definition: MapElement.hpp:141
MapEditor::CompMapEntityT * GetParent() const
Returns the entity that this element is a part of, or NULL if the element has no parent entity...
Definition: MapElement.hpp:85
MapElementT()
The default constructor.
Definition: MapElement.cpp:45
This class represents a generic 4x4 matrix.
Definition: MapElement.hpp:30
virtual void RestoreTrafoState(const TrafoMementoT *TM)
Restores the transform-related state of this element from the given memento.
Definition: MapElement.hpp:176
This class represents groups.
Definition: Group.hpp:20
MapEditor::CompMapEntityT * m_Parent
The entity that this element is a part of.
Definition: MapElement.hpp:226
void SetGroup(GroupT *Group)
Sets the group this element is a member of (use NULL for "no group").
Definition: MapElement.hpp:121
An instance of this class encapsulates the transform-related state of a MapElementT.
Definition: MapElement.hpp:39
void GetToggleEffects(ArrayT< MapElementT * > &RemoveFromSel, ArrayT< MapElementT * > &AddToSel, bool AutoGroupEntities)
Computes how the selection must be changed in order to toggle the given element when the element's en...
Definition: MapElement.cpp:104
This class manages the type infos.
Definition: TypeSys.hpp:145
bool IsSelected() const
Returns whether this element is currently selected in the map document.
Definition: MapElement.hpp:93
virtual ~MapElementT()
The virtual destructor.
Definition: MapElement.cpp:68
GroupT * m_Group
The group this element is in, NULL if in no group.
Definition: MapElement.hpp:228
virtual bool IsTranslucent() const
Returns whether this map element is (entirely or partially) translucent.
Definition: MapElement.hpp:103
GroupT * GetGroup() const
Returns NULL when this map element is in no group, or the pionter to the group it is a member of othe...
Definition: MapElement.hpp:120
virtual void TrafoScale(const Vector3fT &RefPoint, const Vector3fT &Scale, bool LockTexCoords)
Scales this element about the given reference point (in world-space).
Definition: MapElement.hpp:194
virtual BoundingBox3fT GetBB() const =0
Returns the spatial bounding-box of this map element.
virtual bool TracePixel(const wxPoint &Pixel, int Radius, const ViewWindow2DT &ViewWin) const
This method determines if this map element is intersected/affected by the specified disc in ViewWin...
Definition: MapElement.cpp:176
void SetSelected(bool Selected=true)
Sets the selection state of this element.
Definition: MapElement.hpp:97
bool CanSelect() const
Returns whether this map element can currently be selected (in the 2D, 3D and other views)...
Definition: MapElement.cpp:85
virtual void Transform(const Matrix4x4fT &Matrix, bool LockTexCoords)
Why does this method not replace all the other Trafo*() methods? This method is the most generic...
Definition: MapElement.hpp:211
Definition: ChildFrameViewWin2D.hpp:24
bool IsVisible() const
Returns whether this map element is currently visible (in the 2D, 3D and other views).
Definition: MapElement.cpp:79
This component houses the Map Editor specific parts of its entity.
Definition: CompMapEntity.hpp:30
unsigned int m_FrameCount
The number of the frame in which this element was last rendered in a 3D view, used in order to avoid ...
Definition: MapElement.hpp:229
virtual wxColour GetColor(bool ConsiderGroup=true) const =0
This method returns the "inherent" color of this map element.
Definition: TypeSys.hpp:52
This class keeps type information (about an entity class that occurs in the game).
Definition: TypeSys.hpp:79
This class represents an axis-aligned bounding-box ("AABB") in 3-dimensional space.
Definition: BoundingBox.hpp:23
virtual TrafoMementoT * GetTrafoState() const
Returns a memento that encapsulates the transform-related state of this element.
Definition: MapElement.hpp:172
This is the base class for all elements ("objects") that can exist in a map.
Definition: MapElement.hpp:57
virtual void TrafoMove(const Vector3fT &Delta, bool LockTexCoords)
Translates this element by the given vector (in world-space).
Definition: MapElement.hpp:181
This is a class for parsing text.
Definition: TextParser.hpp:21