TrafoBox.hpp
1 /*
2 Cafu Engine, http://www.cafu.de/
3 Copyright (c) Carsten Fuchs and other contributors.
5 */
6
7 #ifndef CAFU_TRANSFORMATION_BOX_HPP_INCLUDED
8 #define CAFU_TRANSFORMATION_BOX_HPP_INCLUDED
9
10 #include "../AxesInfo.hpp"
11 #include "Math3D/BoundingBox.hpp"
12 #include "wx/gdicmn.h"
13
14
15 class ChildFrameT;
16 class CommandTransformT;
17 class MapDocumentT;
18 class MapElementT;
19 class Renderer2DT;
20 class Renderer3DT;
21 class ViewWindow2DT;
22 template<class T> class Matrix4x4T;
24
25
26 /// This class implements a spatial box that can be used to define a transformation (translation, rotation, scale or shear).
27 /// A command for the command history can be created (see method GetTransformCommand()) that actually applies the
28 /// transformation to a set of map elements.
29 class TrafoBoxT
30 {
31  public:
32
33  enum TrafoModeT
34  {
35  TM_SCALE =0, // The numbering is important, because these constants are also used as array indices.
36  TM_ROTATE=1,
37  TM_SHEAR =2
38  };
39
40  enum TrafoHandleT
41  {
42  TH_NONE =0,
43  TH_BODY =1,
44  // TH_CENTER =2, // For future use, e.g. drag the origin of rotation.
45
46  TH_TOP =0x10,
47  TH_BOTTOM =0x20,
48  TH_LEFT =0x40,
49  TH_RIGHT =0x80,
50
51  TH_TOP_LEFT =TH_TOP | TH_LEFT,
52  TH_TOP_RIGHT =TH_TOP | TH_RIGHT,
53  TH_BOTTOM_LEFT =TH_BOTTOM | TH_LEFT,
54  TH_BOTTOM_RIGHT=TH_BOTTOM | TH_RIGHT
55  };
56
57
58  /// The constructor.
59  TrafoBoxT();
60
61  /// Returns the spatial dimensions of this trafo box.
62  const BoundingBox3fT& GetBB() const { return m_BB; }
63
64  /// Sets new spatial dimensions for this trafo box. Can only be called when no drag is currently in progress (GetDragState() returns TH_NONE).
65  void SetBB(const BoundingBox3fT& BB, const ArrayT<Vector3fT>& ExtraRefPos);
66
67  /// Sets the specified transformation mode. Can only be called when no drag is currently in progress (GetDragState() returns TH_NONE).
68  void SetTrafoMode(TrafoModeT TM);
69
70  /// Cycles the transformation modes. Can only be called when no drag is currently in progress (GetDragState() returns TH_NONE).
71  void SetNextTrafoMode();
72
73  /// Returns which of our handles (if any) is currently being dragged by the user.
74  TrafoHandleT GetDragState() const { return m_DragState; }
75
76
77  /// Returns the handle under the given point PointTS in ViewWindow, TH_NONE if there is none
78  /// (only handles matching the current trafo mode are considered).
79  ///
80  /// @param ViewWindow The 2D window in which we should search for hits.
81  /// @param PointTS The coordinate in tool space at which we are to look for a handle.
82  ///
83  /// @returns the handle that was hit in ViewWindow at Point.
84  TrafoHandleT CheckForHandle(const ViewWindow2DT& ViewWindow, const wxPoint& PointTS) const;
85
86  /// For the current trafo mode and the given trafo handle, this method returns the related matching
87  /// cursor that should be activated in the related view window.
88  wxCursor SuggestCursor(TrafoHandleT TrafoHandle) const;
89
90
91  bool BeginTrafo(const ViewWindow2DT& ViewWindow, const wxPoint& PointTS);
92  bool UpdateTrafo(const ViewWindow2DT& ViewWindow, const wxPoint& PointTS, bool ToggleGrid);
93
94  /// This method creates a transform command, according to the current state of the box.
95  /// IMPORTANT NOTE: This method must be called after a call to BeginTrafo() and *before* the matching call to EndTrafo()!
96  /// @returns the generated transform command, or NULL if no command could be generated.
97  CommandTransformT* GetTrafoCommand(MapDocumentT& MapDoc, bool LockTexCoords) const;
98
99  /// Like GetTrafoCommand(), but applies the transformation to the given element immediately.
100  void ApplyTrafo(MapElementT* Elem, bool LockTexCoords) const;
101
102  void FinishTrafo();
103
104
105  void Render(Renderer2DT& Renderer, const wxColour& OutlineColor, const wxColour& HandleColor) const;
106  void Render(Renderer3DT& Renderer, const wxColour& OutlineColor, const wxColour& HandleColor) const;
108
109
110  private:
111
112  /// A lookup table for valid handles for each transformation mode.
113  static const TrafoHandleT HandleTable[3][3][3];
114
115  /// Converts transformation handles from window to world space.
116  /// Our transformation handles are normally in "window space" (the origin is in the upper left corner,
117  /// the x-axis points right and the y-axis points down), and our understanding of the TrafoHandleT names
118  /// (e.g. TH_TOP_LEFT, TH_BOTTOM_RIGHT etc.) is accordingly.
119  /// Note that we say "top" is where the vertical coordinates get smaller, "left" is where the horizontal coordinates get smaller!
120  /// However, "world space" axes can be opposite the "window space" axes, i.e. inverted, and thus a handle that is "top left"
121  /// in window space could in fact be (for example) "bottom right" in world space. Therefore, this function computes from a given
122  /// handle in window space the proper handle in world space.
123  static TrafoHandleT GetWorldSpaceHandle(TrafoHandleT WindowSpaceHandle, const AxesInfoT& Axes);
124
125  void RenderRefPosHint(Renderer2DT& Renderer) const;
126
127  /// Computes the matrix for the shear transformation that is currently in progress.
128  /// @param ShearMatrix The computed matrix is returned here.
129  /// @returns whether the shear matrix could be computed.
130  bool GetShearMatrix(Matrix4x4fT& ShearMatrix) const;
131
132  // The overall state of the box is defined by these members:
133  BoundingBox3fT m_BB; ///< The spatial dimensions of the transformation box. m_BB.IsInited()==false is possible, e.g. when there is no selection.
134  ArrayT<Vector3fT> m_ExtraRefPos; ///< Extra reference points that we may use (besides the m_BB corners) for grid snapping in TH_BODY dragging mode.
135  TrafoModeT m_TrafoMode; ///< The mode of transformation that the box is currently in: scale, rotate or shear. Translation is always possible by grabbing the box's body.
136  TrafoHandleT m_DragState; ///< Which of our handles (if any) is currently being dragged by the user.
137
138  // This data is initialized in BeginTrafo() and used while a handle is being dragged.
139  // It is independent of and commonly used by all trafo modes.
140  AxesInfoT m_DragAxes; ///< The drag axes with which the drag was started and initialized.
141  Vector3fT m_LDownPosWorld; ///< The mouse cursor position in world space when BeginTrafo() was called for beginning the drag.
142
143  // Data for the specific transformations. Initialized in BeginTrafo(), then updated in UpdateTrafo() while the drag is active.
144  Vector3fT m_RefPos; ///< A multi-purpose reference point in world space used for translations, scales and rotations.
145  Vector3fT m_Translate; ///< The translation delta in world space as defined by the current drag operation.
146  Vector3fT m_Scale; ///< The scale as defined by the current drag operation.
147  float m_RotAngle; ///< The angle of rotation around m_RefPos as defined by the current drag operation. The axis of rotation is m_DragAxis.ThirdAxis.
148  float m_Shear; ///< The amount of shear in world space as defined by the current drag operation. The direction of the shear depends on the handle that is being dragged.
149 };
150
151 #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
This class represents a CaWE "map" document.
Definition: MapDocument.hpp:45
TrafoBoxT()
The constructor.
Definition: TrafoBox.cpp:54
This class implements a spatial box that can be used to define a transformation (translation, rotation, scale or shear).
Definition: TrafoBox.hpp:29
TrafoHandleT CheckForHandle(const ViewWindow2DT &ViewWindow, const wxPoint &PointTS) const
Returns the handle under the given point PointTS in ViewWindow, TH_NONE if there is none (only handle...
Definition: TrafoBox.cpp:114
CommandTransformT * GetTrafoCommand(MapDocumentT &MapDoc, bool LockTexCoords) const
This method creates a transform command, according to the current state of the box.
Definition: TrafoBox.cpp:438
void SetNextTrafoMode()
Cycles the transformation modes. Can only be called when no drag is currently in progress (GetDragSta...
Definition: TrafoBox.cpp:99
This class represents a child frame.
Definition: ChildFrame.hpp:55
void SetBB(const BoundingBox3fT &BB, const ArrayT< Vector3fT > &ExtraRefPos)
Sets new spatial dimensions for this trafo box. Can only be called when no drag is currently in progr...
Definition: TrafoBox.cpp:70
wxCursor SuggestCursor(TrafoHandleT TrafoHandle) const
For the current trafo mode and the given trafo handle, this method returns the related matching curso...
Definition: TrafoBox.cpp:149
This class represents a generic 4x4 matrix.
Definition: MapElement.hpp:30
const BoundingBox3fT & GetBB() const
Returns the spatial dimensions of this trafo box.
Definition: TrafoBox.hpp:62
This class describes how the three world-space axes are mapped to the two screen- or window-space axe...
Definition: AxesInfo.hpp:15
TrafoHandleT GetDragState() const
Returns which of our handles (if any) is currently being dragged by the user.
Definition: TrafoBox.hpp:74
Definition: ChildFrameViewWin2D.hpp:24
void SetTrafoMode(TrafoModeT TM)
Sets the specified transformation mode. Can only be called when no drag is currently in progress (Get...
Definition: TrafoBox.cpp:89
void ApplyTrafo(MapElementT *Elem, bool LockTexCoords) const
Like GetTrafoCommand(), but applies the transformation to the given element immediately.
Definition: TrafoBox.cpp:493
Command to transform an object or a list of objects using a delta and a transform mode...
Definition: Transform.hpp:21
Definition: Renderer.hpp:16
This is the base class for all elements ("objects") that can exist in a map.
Definition: MapElement.hpp:57