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 bool forceSnapRotations; 113 114 bool renderWhenUsed; 115 bool renderInfoText; 116 117 Point3F gridSize; 118 bool renderPlane; 119 bool renderPlaneHashes; 120 ColorI gridColor; 121 F32 planeDim; 122 bool renderSolid; 123 124 /// Whether to render a transparent grid overlay when using the move gizmo. 125 bool renderMoveGrid; 126 127 enum Flags { 128 CanRotate = 1 << 0, // 0 129 CanRotateX = 1 << 1, 130 CanRotateY = 1 << 2, 131 CanRotateZ = 1 << 3, 132 CanRotateScreen = 1 << 4, 133 CanRotateUniform = 1 << 5, 134 CanScale = 1 << 6, 135 CanScaleX = 1 << 7, 136 CanScaleY = 1 << 8, 137 CanScaleZ = 1 << 9, 138 CanScaleUniform = 1 << 10, 139 CanTranslate = 1 << 11, 140 CanTranslateX = 1 << 12, 141 CanTranslateY = 1 << 13, 142 CanTranslateZ = 1 << 14, 143 CanTranslateUniform = 1 << 15, 144 PlanarHandlesOn = 1 << 16 145 }; 146 147 S32 flags; 148 149 bool hideDisabledAxes; 150 151 bool allAxesScaleUniform; 152}; 153 154 155// This class contains code for rendering and manipulating a 3D gizmo, it 156// is usually used as a helper within a TSEdit-derived control. 157// 158// The Gizmo has a MatrixF transform and Point3F scale on which it will 159// operate by passing it Gui3DMouseEvent(s). 160// 161// The idea is to set the Gizmo transform/scale to that of another 3D object 162// which is being manipulated, pass mouse events into the Gizmo, read the 163// new transform/scale out, and set it to onto the object. 164// And of course the Gizmo can be rendered. 165// 166// Gizmo derives from SimObject only because this allows its properties 167// to be initialized directly from script via fields. 168 169class Gizmo : public SimObject 170{ 171 typedef SimObject Parent; 172 173 friend class WorldEditor; 174 175public: 176 177 enum Selection { 178 None = -1, 179 Axis_X = 0, 180 Axis_Y = 1, 181 Axis_Z = 2, 182 Plane_XY = 3, // Normal = Axis_Z 183 Plane_XZ = 4, // Normal = Axis_Y 184 Plane_YZ = 5, // Normal = Axis_X 185 Centroid = 6, 186 Custom1 = 7, // screen-aligned rotation 187 Custom2 = 8 188 }; 189 190 Gizmo(); 191 ~Gizmo(); 192 193 DECLARE_CONOBJECT( Gizmo ); 194 195 // SimObject 196 bool onAdd(); 197 void onRemove(); 198 static void initPersistFields(); 199 200 // Mutators 201 void set( const MatrixF &objMat, const Point3F &worldPos, const Point3F &objScale ); 202 void setProfile( GizmoProfile *profile ) 203 { 204 AssertFatal( profile != NULL, "NULL passed to Gizmo::setProfile - Gizmo must always have a profile!" ); 205 mProfile = profile; 206 } 207 208 // Accessors 209 210 GizmoProfile* getProfile() { return mProfile; } 211 212 GizmoMode getMode() const { return mCurrentMode; } 213 214 GizmoAlignment getAlignment() const { return mCurrentAlignment; } 215 216 /// Returns current object to world transform of the object being manipulated. 217 const MatrixF& getTransform() const { return mCurrentTransform; } 218 219 Point3F getPosition() const { return mCurrentTransform.getPosition(); } 220 221 const Point3F& getScale() const { return mScale; } 222 223 224 // Returns change in position in last call to on3DMouseDragged. 225 const Point3F& getOffset() const { return mDeltaPos; } 226 227 // Returns change is position since on3DMouseDown. 228 const Point3F& getTotalOffset() const { return mDeltaTotalPos; } 229 230 const Point3F& getDeltaScale() const { return mDeltaScale; } 231 232 const Point3F& getDeltaTotalScale() const { return mDeltaTotalScale; } 233 234 const Point3F& getDeltaRot() const { return mDeltaRot; } 235 236 const Point3F& getDeltaTotalRot() const { return mDeltaTotalRot; } 237 238 /// Set whether to render the grid plane. 239 void setGridPlaneEnabled( bool value ) { mGridPlaneEnabled = value; } 240 241 /// Set whether to a transparent grid overlay when using the move gizmo. 242 void setMoveGridEnabled( bool value ) { mMoveGridEnabled = value; } 243 244 /// Set the size of the move grid along one dimension. The total size of the 245 /// move grid is @a value * @a value. 246 void setMoveGridSize( F32 value ) { mMoveGridSize = value; } 247 248 /// Set the spacing between grid lines on the move grid. 249 void setMoveGridSpacing( F32 value ) { mMoveGridSpacing = value; } 250 251 // Gizmo Interface methods... 252 253 // Set the current highlight mode on the gizmo's centroid handle 254 void setCentroidHandleHighlight( bool state ) { mHighlightCentroidHandle = state; } 255 256 // Must be called before on3DMouseDragged to save state 257 void on3DMouseDown( const Gui3DMouseEvent &event ); 258 259 // So Gizmo knows the current mouse button state. 260 void on3DMouseUp( const Gui3DMouseEvent &event ); 261 262 // Test Gizmo for collisions and set the Gizmo Selection (the part under the cursor) 263 void on3DMouseMove( const Gui3DMouseEvent &event ); 264 265 // Make changes to the Gizmo transform/scale (depending on mode) 266 void on3DMouseDragged( const Gui3DMouseEvent &event ); 267 268 // Returns an enum describing the part of the Gizmo that is Selected 269 // ( under the cursor ). This should be called AFTER calling onMouseMove 270 // or collideAxisGizmo 271 // 272 // -1 None 273 // 0 Axis_X 274 // 1 Axis_Y 275 // 2 Axis_Z 276 // 3 Plane_XY 277 // 4 Plane_XZ 278 // 5 Plane_YZ 279 Selection getSelection(); 280 void setSelection( Selection sel ) { mSelectionIdx = sel; } 281 282 // Returns the object space vector corresponding to a Selection. 283 Point3F selectionToAxisVector( Selection axis ); 284 285 // These provide the user an easy way to check if the Gizmo's transform 286 // or scale have changed by calling markClean prior to calling 287 // on3DMouseDragged, and calling isDirty after. 288 bool isDirty() { return mDirty; } 289 void markClean() { mDirty = false; } 290 291 // Renders the 3D Gizmo in the scene, GFX must be setup for proper 292 // 3D rendering before calling this! 293 // Calling this will change the GFXStateBlock! 294 void renderGizmo( const MatrixF &cameraTransform, F32 camerFOV = 1.5f ); 295 296 // Renders text associated with the Gizmo, GFX must be setup for proper 297 // 2D rendering before calling this! 298 // Calling this will change the GFXStateBlock! 299 void renderText( const RectI &viewPort, const MatrixF &modelView, const MatrixF &projection ); 300 301 // Returns true if the mouse event collides with any part of the Gizmo 302 // and sets the Gizmo's current Selection. 303 // You can call this or on3DMouseMove, they are identical 304 bool collideAxisGizmo( const Gui3DMouseEvent & event ); 305 306protected: 307 308 void _calcAxisInfo(); 309 void _setStateBlock(); 310 void _renderPrimaryAxis(); 311 void _renderAxisArrows(); 312 void _renderAxisBoxes(); 313 void _renderAxisCircles(); 314 void _renderAxisText(); 315 void _renderPlane(); 316 Point3F _snapPoint( const Point3F &pnt ) const; 317 F32 _snapFloat( const F32 &val, const F32 &snap ) const; 318 GizmoAlignment _filteredAlignment(); 319 void _updateState( bool collideGizmo = true ); 320 void _updateEnabledAxices(); 321 322 F32 _getProjectionLength( F32 dist ) const 323 { 324 if( GFX->isFrustumOrtho() ) 325 return mLastCameraFOV * dist * 0.002f; 326 else 327 { 328 Point3F dir = mOrigin - mCameraPos; 329 return ( dist * dir.len() ) / mLastWorldToScreenScale.y; 330 } 331 } 332 333protected: 334 335 GizmoProfile *mProfile; 336 337 MatrixF mObjectMat; 338 MatrixF mObjectMatInv; 339 MatrixF mTransform; 340 MatrixF mCurrentTransform; 341 MatrixF mSavedTransform; 342 343 GizmoAlignment mCurrentAlignment; 344 GizmoMode mCurrentMode; 345 346 MatrixF mCameraMat; 347 Point3F mCameraPos; 348 349 Point3F mScale; 350 Point3F mSavedScale; 351 Point3F mDeltaScale; 352 Point3F mDeltaTotalScale; 353 Point3F mLastScale; 354 Point3F mScaleInfluence; 355 356 EulerF mRot; 357 EulerF mSavedRot; 358 EulerF mDeltaRot; 359 EulerF mDeltaTotalRot; 360 F32 mDeltaAngle; 361 F32 mLastAngle; 362 Point2I mMouseDownPos; 363 Point3F mMouseDownProjPnt; 364 Point3F mDeltaPos; 365 Point3F mDeltaTotalPos; 366 Point3F mProjPnt; 367 Point3F mOrigin; 368 Point3F mProjAxisVector[3]; 369 F32 mProjLen; 370 S32 mSelectionIdx; 371 bool mDirty; 372 Gui3DMouseEvent mLastMouseEvent; 373 GFXStateBlockRef mStateBlock; 374 GFXStateBlockRef mSolidStateBlock; 375 376 PlaneF mMouseCollidePlane; 377 MathUtils::Line mMouseCollideLine; 378 379 bool mMouseDown; 380 381 F32 mSign; 382 383 /// If false, don't render the grid plane even if it is enabled in the profile. 384 bool mGridPlaneEnabled; 385 386 /// If false, don't render a transparent grid overlay when using the move gizmo. 387 bool mMoveGridEnabled; 388 389 /// Size of the move grid along one dimension. 390 F32 mMoveGridSize; 391 392 /// Spacing between grid lines on the move grid. 393 U32 mMoveGridSpacing; 394 395 bool mUniformHandleEnabled; 396 bool mScreenRotateHandleEnabled; 397 bool mAxisEnabled[3]; 398 399 // Used to override rendering of handles. 400 bool mHighlightCentroidHandle; 401 bool mHighlightAll; 402 403 // Initialized in renderGizmo and saved for later use when projecting 404 // to screen space for selection testing. 405 MatrixF mLastWorldMat; 406 MatrixF mLastProjMat; 407 RectI mLastViewport; 408 Point2F mLastWorldToScreenScale; 409 F32 mLastCameraFOV; 410 411 // Screenspace cursor collision information used in rotation mode. 412 Point3F mElipseCursorCollidePntSS; 413 Point3F mElipseCursorCollideVecSS; 414 415 /// A large hard coded distance used to test 416 /// gizmo axis selection. 417 static F32 smProjectDistance; 418}; 419 420#endif // _GIZMO_H_ 421