| 1 | /* |
|---|
| 2 | ================================================================================= |
|---|
| 3 | This file is part of Cafu, the open-source game engine and graphics engine |
|---|
| 4 | for multiplayer, cross-platform, real-time 3D action. |
|---|
| 5 | Copyright (C) 2002-2012 Carsten Fuchs Software. |
|---|
| 6 | |
|---|
| 7 | Cafu is free software: you can redistribute it and/or modify it under the terms |
|---|
| 8 | of the GNU General Public License as published by the Free Software Foundation, |
|---|
| 9 | either version 3 of the License, or (at your option) any later version. |
|---|
| 10 | |
|---|
| 11 | Cafu is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
|---|
| 12 | without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
|---|
| 13 | PURPOSE. See the GNU General Public License for more details. |
|---|
| 14 | |
|---|
| 15 | You should have received a copy of the GNU General Public License |
|---|
| 16 | along with Cafu. If not, see <http://www.gnu.org/licenses/>. |
|---|
| 17 | |
|---|
| 18 | For support and more information about Cafu, visit us at <http://www.cafu.de>. |
|---|
| 19 | ================================================================================= |
|---|
| 20 | */ |
|---|
| 21 | |
|---|
| 22 | #ifndef CAFU_TRANSFORMATION_BOX_HPP_INCLUDED |
|---|
| 23 | #define CAFU_TRANSFORMATION_BOX_HPP_INCLUDED |
|---|
| 24 | |
|---|
| 25 | #include "AxesInfo.hpp" |
|---|
| 26 | #include "Math3D/BoundingBox.hpp" |
|---|
| 27 | #include "wx/gdicmn.h" |
|---|
| 28 | |
|---|
| 29 | |
|---|
| 30 | class ChildFrameT; |
|---|
| 31 | class CommandTransformT; |
|---|
| 32 | class MapDocumentT; |
|---|
| 33 | class Renderer2DT; |
|---|
| 34 | class Renderer3DT; |
|---|
| 35 | class ViewWindow2DT; |
|---|
| 36 | class MatrixT; |
|---|
| 37 | |
|---|
| 38 | |
|---|
| 39 | /// This class implements a spatial box that can be used to define a transformation (translation, rotation, scale or shear). |
|---|
| 40 | /// A command for the command hierarchy can be created (see method GetTransformCommand()) that actually applies the |
|---|
| 41 | /// transformation to a set of map elements. |
|---|
| 42 | class TrafoBoxT |
|---|
| 43 | { |
|---|
| 44 | public: |
|---|
| 45 | |
|---|
| 46 | enum TrafoModeT |
|---|
| 47 | { |
|---|
| 48 | TM_SCALE =0, // The numbering is important, because these constants are also used as array indices. |
|---|
| 49 | TM_ROTATE=1, |
|---|
| 50 | TM_SHEAR =2 |
|---|
| 51 | }; |
|---|
| 52 | |
|---|
| 53 | enum TrafoHandleT |
|---|
| 54 | { |
|---|
| 55 | TH_NONE =0, |
|---|
| 56 | TH_BODY =1, |
|---|
| 57 | // TH_CENTER =2, // For future use, e.g. drag the origin of rotation. |
|---|
| 58 | |
|---|
| 59 | TH_TOP =0x10, |
|---|
| 60 | TH_BOTTOM =0x20, |
|---|
| 61 | TH_LEFT =0x40, |
|---|
| 62 | TH_RIGHT =0x80, |
|---|
| 63 | |
|---|
| 64 | TH_TOP_LEFT =TH_TOP | TH_LEFT, |
|---|
| 65 | TH_TOP_RIGHT =TH_TOP | TH_RIGHT, |
|---|
| 66 | TH_BOTTOM_LEFT =TH_BOTTOM | TH_LEFT, |
|---|
| 67 | TH_BOTTOM_RIGHT=TH_BOTTOM | TH_RIGHT |
|---|
| 68 | }; |
|---|
| 69 | |
|---|
| 70 | |
|---|
| 71 | /// The constructor. |
|---|
| 72 | TrafoBoxT(); |
|---|
| 73 | |
|---|
| 74 | /// Returns the spatial dimensions of this trafo box. |
|---|
| 75 | const BoundingBox3fT& GetBB() const { return m_BB; } |
|---|
| 76 | |
|---|
| 77 | /// Sets new spatial dimensions for this trafo box. Can only be called when no drag is currently in progress (GetDragState() returns TH_NONE). |
|---|
| 78 | void SetBB(const BoundingBox3fT& BB); |
|---|
| 79 | |
|---|
| 80 | /// Cycles the transformation modes. Can only be called when no drag is currently in progress (GetDragState() returns TH_NONE). |
|---|
| 81 | void SetNextTrafoMode(); |
|---|
| 82 | |
|---|
| 83 | /// Returns which of our handles (if any) is currently being dragged by the user. |
|---|
| 84 | TrafoHandleT GetDragState() const { return m_DragState; } |
|---|
| 85 | |
|---|
| 86 | |
|---|
| 87 | /// Returns the handle under the given point PointTS in ViewWindow, TH_NONE if there is none |
|---|
| 88 | /// (only handles matching the current trafo mode are considered). |
|---|
| 89 | /// |
|---|
| 90 | /// @param ViewWindow The 2D window in which we should search for hits. |
|---|
| 91 | /// @param PointTS The coordinate in tool space at which we are to look for a handle. |
|---|
| 92 | /// |
|---|
| 93 | /// @returns the handle that was hit in ViewWindow at Point. |
|---|
| 94 | TrafoHandleT CheckForHandle(const ViewWindow2DT& ViewWindow, const wxPoint& PointTS) const; |
|---|
| 95 | |
|---|
| 96 | /// For the current trafo mode and the given trafo handle, this method returns the related matching |
|---|
| 97 | /// cursor that should be activated in the related view window. |
|---|
| 98 | wxCursor SuggestCursor(TrafoHandleT TrafoHandle) const; |
|---|
| 99 | |
|---|
| 100 | |
|---|
| 101 | bool BeginTrafo(const ViewWindow2DT& ViewWindow, const wxPoint& PointTS, const Vector3fT* UseRefPos=NULL); |
|---|
| 102 | bool UpdateTrafo(const ViewWindow2DT& ViewWindow, const wxPoint& PointTS, bool ToggleGrid); |
|---|
| 103 | |
|---|
| 104 | /// This method creates a transform command, according to the current state of the box. |
|---|
| 105 | /// IMPORTANT NOTE: This method must be called after a call to BeginTrafo() and *before* the matching call to EndTrafo()! |
|---|
| 106 | /// @returns the generated transform command, or NULL if no command could be generated. |
|---|
| 107 | CommandTransformT* GetTrafoCommand(MapDocumentT& MapDoc, bool UserWishClone, bool ForceClone) const; |
|---|
| 108 | |
|---|
| 109 | void FinishTrafo(); |
|---|
| 110 | |
|---|
| 111 | |
|---|
| 112 | void Render(Renderer2DT& Renderer, const wxColour& OutlineColor, const wxColour& HandleColor) const; |
|---|
| 113 | void Render(Renderer3DT& Renderer, const wxColour& OutlineColor, const wxColour& HandleColor) const; |
|---|
| 114 | bool UpdateStatusBar(ChildFrameT* ChildFrame) const; |
|---|
| 115 | |
|---|
| 116 | |
|---|
| 117 | private: |
|---|
| 118 | |
|---|
| 119 | /// A lookup table for valid handles for each transformation mode. |
|---|
| 120 | static const TrafoHandleT HandleTable[3][3][3]; |
|---|
| 121 | |
|---|
| 122 | /// Converts transformation handles from window to world space. |
|---|
| 123 | /// Our transformation handles are normally in "window space" (the origin is in the upper left corner, |
|---|
| 124 | /// the x-axis points right and the y-axis points down), and our understanding of the TrafoHandleT names |
|---|
| 125 | /// (e.g. TH_TOP_LEFT, TH_BOTTOM_RIGHT etc.) is accordingly. |
|---|
| 126 | /// Note that we say "top" is where the vertical coordinates get smaller, "left" is where the horizontal coordinates get smaller! |
|---|
| 127 | /// However, "world space" axes can be opposite the "window space" axes, i.e. inverted, and thus a handle that is "top left" |
|---|
| 128 | /// in window space could in fact be (for example) "bottom right" in world space. Therefore, this function computes from a given |
|---|
| 129 | /// handle in window space the proper handle in world space. |
|---|
| 130 | static TrafoHandleT GetWorldSpaceHandle(TrafoHandleT WindowSpaceHandle, const AxesInfoT& Axes); |
|---|
| 131 | |
|---|
| 132 | /// Computes the matrix for the shear transformation that is currently in progress. |
|---|
| 133 | /// @param ShearMatrix The computed matrix is returned here. |
|---|
| 134 | /// @returns whether the shear matrix could be computed. |
|---|
| 135 | bool GetShearMatrix(MatrixT& ShearMatrix) const; |
|---|
| 136 | |
|---|
| 137 | // The overall state of the box is defined by these members: |
|---|
| 138 | BoundingBox3fT m_BB; ///< The spatial dimensions of the transformation box. m_BB.IsInited()==false is possible, e.g. when there is no selection. |
|---|
| 139 | 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. |
|---|
| 140 | TrafoHandleT m_DragState; ///< Which of our handles (if any) is currently being dragged by the user. |
|---|
| 141 | |
|---|
| 142 | // This data is initialized in BeginTrafo() and used while a handle is being dragged. |
|---|
| 143 | // It is independent of and commonly used by all trafo modes. |
|---|
| 144 | AxesInfoT m_DragAxes; ///< The drag axes with which the drag was started and initialized. |
|---|
| 145 | Vector3fT m_LDownPosWorld; ///< The mouse cursor position in world space when BeginTrafo() was called for beginning the drag. |
|---|
| 146 | |
|---|
| 147 | // Data for the specific transformations. Initialized in BeginTrafo(), then updated in UpdateTrafo() while the drag is active. |
|---|
| 148 | Vector3fT m_RefPos; ///< A multi-purpose reference point in world space used for translations, scales and rotations. |
|---|
| 149 | Vector3fT m_Translate; ///< The translation delta in world space as defined by the current drag operation. |
|---|
| 150 | Vector3fT m_Scale; ///< The scale as defined by the current drag operation. |
|---|
| 151 | 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. |
|---|
| 152 | 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. |
|---|
| 153 | }; |
|---|
| 154 | |
|---|
| 155 | #endif |
|---|