gizmo.h
Engine/source/gui/worldEditor/gizmo.h
Classes:
class
class
Public Enumerations
enum
GizmoAlignment { World = 0 Object AlignEnumCount }
enum
GizmoMode { NoneMode = 0 MoveMode RotateMode ScaleMode ModeEnumCount }
Public Functions
Detailed Description
Public Enumerations
GizmoAlignment
Enumerator
- World = 0
- Object
- AlignEnumCount
GizmoMode
Enumerator
- NoneMode = 0
- MoveMode
- RotateMode
- ScaleMode
- ModeEnumCount
Public Functions
DefineEnumType(GizmoAlignment )
DefineEnumType(GizmoMode )
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#ifndef _GIZMO_H_ 25#define _GIZMO_H_ 26 27#ifndef _SIMBASE_H_ 28#include "console/simBase.h" 29#endif 30 31#ifndef _MMATRIX_H_ 32#include "math/mMatrix.h" 33#endif 34 35#ifndef _COLOR_H_ 36#include "core/color.h" 37#endif 38 39#ifndef _GUITYPES_H_ 40#include "gui/core/guiTypes.h" 41#endif 42 43#ifndef _MATHUTILS_H_ 44#include "math/mathUtils.h" 45#endif 46 47#ifndef _DYNAMIC_CONSOLETYPES_H_ 48#include "console/dynamicTypes.h" 49#endif 50 51 52enum GizmoMode 53{ 54 NoneMode = 0, 55 MoveMode, // 1 56 RotateMode, // 2 57 ScaleMode, // 3 58 ModeEnumCount 59}; 60 61enum GizmoAlignment 62{ 63 World = 0, 64 Object, 65 AlignEnumCount 66}; 67 68DefineEnumType( GizmoMode ); 69DefineEnumType( GizmoAlignment ); 70 71 72// 73class GizmoProfile : public SimObject 74{ 75 typedef SimObject Parent; 76 77public: 78 79 GizmoProfile(); 80 virtual ~GizmoProfile() {} 81 82 DECLARE_CONOBJECT( GizmoProfile ); 83 84 virtual bool onAdd(); 85 86 static void initPersistFields(); 87 static void consoleInit(); 88 89 /// Set flags to default values. 90 void restoreDefaultState(); 91 92 // Data Fields 93 94 GizmoMode mode; 95 GizmoAlignment alignment; 96 97 F32 rotateScalar; 98 F32 scaleScalar; 99 U32 screenLen; 100 ColorI axisColors[3]; 101 ColorI activeColor; 102 ColorI inActiveColor; 103 ColorI centroidColor; 104 ColorI centroidHighlightColor; 105 Resource<GFont> font; 106 107 bool snapToGrid; 108 F32 scaleSnap; 109 bool allowSnapScale; 110 F32 rotationSnap; 111 bool allowSnapRotations; 112 113 bool renderWhenUsed; 114 bool renderInfoText; 115 116 Point3F gridSize; 117 bool renderPlane; 118 bool renderPlaneHashes; 119 ColorI gridColor; 120 F32 planeDim; 121 bool renderSolid; 122 123 /// Whether to render a transparent grid overlay when using the move gizmo. 124 bool renderMoveGrid; 125 126 enum Flags { 127 CanRotate = 1 << 0, // 0 128 CanRotateX = 1 << 1, 129 CanRotateY = 1 << 2, 130 CanRotateZ = 1 << 3, 131 CanRotateScreen = 1 << 4, 132 CanRotateUniform = 1 << 5, 133 CanScale = 1 << 6, 134 CanScaleX = 1 << 7, 135 CanScaleY = 1 << 8, 136 CanScaleZ = 1 << 9, 137 CanScaleUniform = 1 << 10, 138 CanTranslate = 1 << 11, 139 CanTranslateX = 1 << 12, 140 CanTranslateY = 1 << 13, 141 CanTranslateZ = 1 << 14, 142 CanTranslateUniform = 1 << 15, 143 PlanarHandlesOn = 1 << 16 144 }; 145 146 S32 flags; 147 148 bool hideDisabledAxes; 149 150 bool allAxesScaleUniform; 151}; 152 153 154// This class contains code for rendering and manipulating a 3D gizmo, it 155// is usually used as a helper within a TSEdit-derived control. 156// 157// The Gizmo has a MatrixF transform and Point3F scale on which it will 158// operate by passing it Gui3DMouseEvent(s). 159// 160// The idea is to set the Gizmo transform/scale to that of another 3D object 161// which is being manipulated, pass mouse events into the Gizmo, read the 162// new transform/scale out, and set it to onto the object. 163// And of course the Gizmo can be rendered. 164// 165// Gizmo derives from SimObject only because this allows its properties 166// to be initialized directly from script via fields. 167 168class Gizmo : public SimObject 169{ 170 typedef SimObject Parent; 171 172 friend class WorldEditor; 173 174public: 175 176 enum Selection { 177 None = -1, 178 Axis_X = 0, 179 Axis_Y = 1, 180 Axis_Z = 2, 181 Plane_XY = 3, // Normal = Axis_Z 182 Plane_XZ = 4, // Normal = Axis_Y 183 Plane_YZ = 5, // Normal = Axis_X 184 Centroid = 6, 185 Custom1 = 7, // screen-aligned rotation 186 Custom2 = 8 187 }; 188 189 Gizmo(); 190 ~Gizmo(); 191 192 DECLARE_CONOBJECT( Gizmo ); 193 194 // SimObject 195 bool onAdd(); 196 void onRemove(); 197 static void initPersistFields(); 198 199 // Mutators 200 void set( const MatrixF &objMat, const Point3F &worldPos, const Point3F &objScale ); 201 void setProfile( GizmoProfile *profile ) 202 { 203 AssertFatal( profile != NULL, "NULL passed to Gizmo::setProfile - Gizmo must always have a profile!" ); 204 mProfile = profile; 205 } 206 207 // Accessors 208 209 GizmoProfile* getProfile() { return mProfile; } 210 211 GizmoMode getMode() const { return mCurrentMode; } 212 213 GizmoAlignment getAlignment() const { return mCurrentAlignment; } 214 215 /// Returns current object to world transform of the object being manipulated. 216 const MatrixF& getTransform() const { return mCurrentTransform; } 217 218 Point3F getPosition() const { return mCurrentTransform.getPosition(); } 219 220 const Point3F& getScale() const { return mScale; } 221 222 223 // Returns change in position in last call to on3DMouseDragged. 224 const Point3F& getOffset() const { return mDeltaPos; } 225 226 // Returns change is position since on3DMouseDown. 227 const Point3F& getTotalOffset() const { return mDeltaTotalPos; } 228 229 const Point3F& getDeltaScale() const { return mDeltaScale; } 230 231 const Point3F& getDeltaTotalScale() const { return mDeltaTotalScale; } 232 233 const Point3F& getDeltaRot() const { return mDeltaRot; } 234 235 const Point3F& getDeltaTotalRot() const { return mDeltaTotalRot; } 236 237 /// Set whether to render the grid plane. 238 void setGridPlaneEnabled( bool value ) { mGridPlaneEnabled = value; } 239 240 /// Set whether to a transparent grid overlay when using the move gizmo. 241 void setMoveGridEnabled( bool value ) { mMoveGridEnabled = value; } 242 243 /// Set the size of the move grid along one dimension. The total size of the 244 /// move grid is @a value * @a value. 245 void setMoveGridSize( F32 value ) { mMoveGridSize = value; } 246 247 /// Set the spacing between grid lines on the move grid. 248 void setMoveGridSpacing( F32 value ) { mMoveGridSpacing = value; } 249 250 // Gizmo Interface methods... 251 252 // Set the current highlight mode on the gizmo's centroid handle 253 void setCentroidHandleHighlight( bool state ) { mHighlightCentroidHandle = state; } 254 255 // Must be called before on3DMouseDragged to save state 256 void on3DMouseDown( const Gui3DMouseEvent &event ); 257 258 // So Gizmo knows the current mouse button state. 259 void on3DMouseUp( const Gui3DMouseEvent &event ); 260 261 // Test Gizmo for collisions and set the Gizmo Selection (the part under the cursor) 262 void on3DMouseMove( const Gui3DMouseEvent &event ); 263 264 // Make changes to the Gizmo transform/scale (depending on mode) 265 void on3DMouseDragged( const Gui3DMouseEvent &event ); 266 267 // Returns an enum describing the part of the Gizmo that is Selected 268 // ( under the cursor ). This should be called AFTER calling onMouseMove 269 // or collideAxisGizmo 270 // 271 // -1 None 272 // 0 Axis_X 273 // 1 Axis_Y 274 // 2 Axis_Z 275 // 3 Plane_XY 276 // 4 Plane_XZ 277 // 5 Plane_YZ 278 Selection getSelection(); 279 void setSelection( Selection sel ) { mSelectionIdx = sel; } 280 281 // Returns the object space vector corresponding to a Selection. 282 Point3F selectionToAxisVector( Selection axis ); 283 284 // These provide the user an easy way to check if the Gizmo's transform 285 // or scale have changed by calling markClean prior to calling 286 // on3DMouseDragged, and calling isDirty after. 287 bool isDirty() { return mDirty; } 288 void markClean() { mDirty = false; } 289 290 // Renders the 3D Gizmo in the scene, GFX must be setup for proper 291 // 3D rendering before calling this! 292 // Calling this will change the GFXStateBlock! 293 void renderGizmo( const MatrixF &cameraTransform, F32 camerFOV = 1.5f ); 294 295 // Renders text associated with the Gizmo, GFX must be setup for proper 296 // 2D rendering before calling this! 297 // Calling this will change the GFXStateBlock! 298 void renderText( const RectI &viewPort, const MatrixF &modelView, const MatrixF &projection ); 299 300 // Returns true if the mouse event collides with any part of the Gizmo 301 // and sets the Gizmo's current Selection. 302 // You can call this or on3DMouseMove, they are identical 303 bool collideAxisGizmo( const Gui3DMouseEvent & event ); 304 305protected: 306 307 void _calcAxisInfo(); 308 void _setStateBlock(); 309 void _renderPrimaryAxis(); 310 void _renderAxisArrows(); 311 void _renderAxisBoxes(); 312 void _renderAxisCircles(); 313 void _renderAxisText(); 314 void _renderPlane(); 315 Point3F _snapPoint( const Point3F &pnt ) const; 316 F32 _snapFloat( const F32 &val, const F32 &snap ) const; 317 GizmoAlignment _filteredAlignment(); 318 void _updateState( bool collideGizmo = true ); 319 void _updateEnabledAxices(); 320 321 F32 _getProjectionLength( F32 dist ) const 322 { 323 if( GFX->isFrustumOrtho() ) 324 return mLastCameraFOV * dist * 0.002f; 325 else 326 { 327 Point3F dir = mOrigin - mCameraPos; 328 return ( dist * dir.len() ) / mLastWorldToScreenScale.y; 329 } 330 } 331 332protected: 333 334 GizmoProfile *mProfile; 335 336 MatrixF mObjectMat; 337 MatrixF mObjectMatInv; 338 MatrixF mTransform; 339 MatrixF mCurrentTransform; 340 MatrixF mSavedTransform; 341 342 GizmoAlignment mCurrentAlignment; 343 GizmoMode mCurrentMode; 344 345 MatrixF mCameraMat; 346 Point3F mCameraPos; 347 348 Point3F mScale; 349 Point3F mSavedScale; 350 Point3F mDeltaScale; 351 Point3F mDeltaTotalScale; 352 Point3F mLastScale; 353 Point3F mScaleInfluence; 354 355 EulerF mRot; 356 EulerF mSavedRot; 357 EulerF mDeltaRot; 358 EulerF mDeltaTotalRot; 359 F32 mDeltaAngle; 360 F32 mLastAngle; 361 Point2I mMouseDownPos; 362 Point3F mMouseDownProjPnt; 363 Point3F mDeltaPos; 364 Point3F mDeltaTotalPos; 365 Point3F mProjPnt; 366 Point3F mOrigin; 367 Point3F mProjAxisVector[3]; 368 F32 mProjLen; 369 S32 mSelectionIdx; 370 bool mDirty; 371 Gui3DMouseEvent mLastMouseEvent; 372 GFXStateBlockRef mStateBlock; 373 GFXStateBlockRef mSolidStateBlock; 374 375 PlaneF mMouseCollidePlane; 376 MathUtils::Line mMouseCollideLine; 377 378 bool mMouseDown; 379 380 F32 mSign; 381 382 /// If false, don't render the grid plane even if it is enabled in the profile. 383 bool mGridPlaneEnabled; 384 385 /// If false, don't render a transparent grid overlay when using the move gizmo. 386 bool mMoveGridEnabled; 387 388 /// Size of the move grid along one dimension. 389 F32 mMoveGridSize; 390 391 /// Spacing between grid lines on the move grid. 392 U32 mMoveGridSpacing; 393 394 bool mAxisEnabled[3]; 395 bool mUniformHandleEnabled; 396 bool mScreenRotateHandleEnabled; 397 398 // Used to override rendering of handles. 399 bool mHighlightCentroidHandle; 400 bool mHighlightAll; 401 402 // Initialized in renderGizmo and saved for later use when projecting 403 // to screen space for selection testing. 404 MatrixF mLastWorldMat; 405 MatrixF mLastProjMat; 406 RectI mLastViewport; 407 Point2F mLastWorldToScreenScale; 408 F32 mLastCameraFOV; 409 410 // Screenspace cursor collision information used in rotation mode. 411 Point3F mElipseCursorCollidePntSS; 412 Point3F mElipseCursorCollideVecSS; 413 414 /// A large hard coded distance used to test 415 /// gizmo axis selection. 416 static F32 smProjectDistance; 417}; 418 419#endif // _GIZMO_H_ 420
