Bladeren bron

Merge pull request #1961 from Azaezel/snapwork

[augs]Snapwork
Areloch 8 jaren geleden
bovenliggende
commit
b052a1f970

+ 31 - 15
Engine/source/gui/worldEditor/worldEditor.cpp

@@ -68,7 +68,8 @@ ImplementEnumType( WorldEditorDropType,
    { WorldEditor::DropAtScreenCenter,     "screenCenter",   "Places at a position projected outwards from the screen's center.\n"    },
    { WorldEditor::DropAtCentroid,         "atCentroid",     "Places at the center position of the current centroid.\n"      },
    { WorldEditor::DropToTerrain,          "toTerrain",      "Places on the terrain.\n"       },
-   { WorldEditor::DropBelowSelection,     "belowSelection", "Places at a position below the selected object.\n"  }
+   { WorldEditor::DropBelowSelection,     "belowSelection", "Places at a position below the selected object.\n"  },
+   { WorldEditor::DropAtGizmo,            "atGizmo",        "Places at the gizmo point.\n"  }
 EndImplementEnumType;
 
 ImplementEnumType( WorldEditorAlignmentType,
@@ -643,10 +644,10 @@ void WorldEditor::dropSelection(Selection*  sel)
             Point3F offset = -boxCenter;
             offset.z += bounds.len_z() * 0.5f;
 
-            sel->offset( offset, mGridSnap ? mGridPlaneSize : 0.f );
+            sel->offset(offset, (!mUseGroupCenter && mGridSnap) ? mGridPlaneSize : 0.f);
          }
          else
-            sel->offset( Point3F( -centroid ), mGridSnap ? mGridPlaneSize : 0.f );
+            sel->offset(Point3F(-centroid), (!mUseGroupCenter && mGridSnap) ? mGridPlaneSize : 0.f);
 
          break;
       }
@@ -657,7 +658,7 @@ void WorldEditor::dropSelection(Selection*  sel)
          if(mDropAtBounds && !sel->containsGlobalBounds())
             center = sel->getBoxBottomCenter();
 
-         sel->offset( Point3F( smCamPos - center ), mGridSnap ? mGridPlaneSize : 0.f );
+         sel->offset(Point3F(smCamPos - center), (!mUseGroupCenter && mGridSnap) ? mGridPlaneSize : 0.f);
          sel->orient(smCamMatrix, center);
          break;
       }
@@ -668,7 +669,7 @@ void WorldEditor::dropSelection(Selection*  sel)
          if(mDropAtBounds && !sel->containsGlobalBounds())
             sel->getBoxBottomCenter();
 
-         sel->offset( Point3F( smCamPos - center ), mGridSnap ? mGridPlaneSize : 0.f );
+         sel->offset(Point3F(smCamPos - center), (!mUseGroupCenter && mGridSnap) ? mGridPlaneSize : 0.f);
          break;
       }
 
@@ -680,7 +681,7 @@ void WorldEditor::dropSelection(Selection*  sel)
 
          Point3F offset = smCamPos - center;
          offset.z -= mDropBelowCameraOffset;
-         sel->offset( offset, mGridSnap ? mGridPlaneSize : 0.f );
+         sel->offset(offset, (!mUseGroupCenter && mGridSnap) ? mGridPlaneSize : 0.f);
          break;
       }
 
@@ -712,7 +713,7 @@ void WorldEditor::dropSelection(Selection*  sel)
          event.vec = wp - smCamPos;
          event.vec.normalizeSafe();
          event.vec *= viewdist;
-         sel->offset( Point3F( event.pos - center ) += event.vec, mGridSnap ? mGridPlaneSize : 0.f );
+         sel->offset(Point3F(event.pos - center) += event.vec, (!mUseGroupCenter && mGridSnap) ? mGridPlaneSize : 0.f);
 
          break;
       }
@@ -728,12 +729,26 @@ void WorldEditor::dropSelection(Selection*  sel)
          dropBelowSelection(sel, centroid, mDropAtBounds);
          break;
       }
+
+      case DropAtGizmo:
+      {
+         dropAtGizmo(sel, mGizmo->getPosition()-centroid);
+         break;
+      }
    }
 
    //
    updateClientTransforms(sel);
 }
 
+void WorldEditor::dropAtGizmo(Selection*  sel, const Point3F & gizmoPos)
+{
+   if (!sel->size())
+      return;
+
+   sel->offset(gizmoPos, (!mUseGroupCenter && mGridSnap) ? mGridPlaneSize : 0.f);
+}
+
 void WorldEditor::dropBelowSelection(Selection*  sel, const Point3F & centroid, bool useBottomBounds)
 {
    if(!sel->size())
@@ -756,7 +771,7 @@ void WorldEditor::dropBelowSelection(Selection*  sel, const Point3F & centroid,
    sel->enableCollision();
 
    if( hit )
-      sel->offset( ri.point - start, mGridSnap ? mGridPlaneSize : 0.f );
+      sel->offset(ri.point - start, (!mUseGroupCenter && mGridSnap) ? mGridPlaneSize : 0.f);
 }
 
 //------------------------------------------------------------------------------
@@ -800,7 +815,7 @@ void WorldEditor::terrainSnapSelection(Selection* sel, U8 modifier, Point3F gizm
    {
       mStuckToGround = true;
 
-      sel->offset( ri.point - centroid, mGridSnap ? mGridPlaneSize : 0.f );
+      sel->offset(ri.point - centroid, (!mUseGroupCenter && mGridSnap) ? mGridPlaneSize : 0.f);
 
       if(mTerrainSnapAlignment != AlignNone)
       {
@@ -1026,7 +1041,7 @@ void WorldEditor::softSnapSelection(Selection* sel, U8 modifier, Point3F gizmoPo
       if ( minT <= 1.0f )
          foundPoint += ( end - start ) * (0.5f - minT);
 
-      sel->offset( foundPoint - sel->getCentroid(), mGridSnap ? mGridPlaneSize : 0.f );
+      sel->offset(foundPoint - sel->getCentroid(), (!mUseGroupCenter && mGridSnap) ? mGridPlaneSize : 0.f);
    }
 
    mSoftSnapIsStuck = found;
@@ -1805,7 +1820,7 @@ WorldEditor::WorldEditor()
    mSoftSnapDebugPoint.set(0.0f, 0.0f, 0.0f);
    
    mGridSnap = false;
-   
+   mUseGroupCenter = true;
    mFadeIcons = true;
    mFadeIconsDist = 8.f;
 }
@@ -2254,7 +2269,7 @@ void WorldEditor::on3DMouseDragged(const Gui3DMouseEvent & event)
             mGizmo->getProfile()->snapToGrid = snapToGrid;
          }
 
-         mSelected->offset( mGizmo->getOffset() );
+         mSelected->offset(mGizmo->getOffset(), (!mUseGroupCenter && mGridSnap) ? mGridPlaneSize : 0.f);
 
          // Handle various sticking
          terrainSnapSelection( mSelected, event.modifier, mGizmo->getPosition() );
@@ -2686,7 +2701,8 @@ void WorldEditor::initPersistFields()
    addGroup( "Grid" );
    
       addField( "gridSnap",               TypeBool,   Offset( mGridSnap, WorldEditor ),
-         "If true, transform operations will snap to the grid." );
+         "If true, transform operations will snap to the grid.");
+      addField("useGroupCenter", TypeBool, Offset(mUseGroupCenter, WorldEditor));
    
    endGroup( "Grid" );
    
@@ -3035,7 +3051,7 @@ void WorldEditor::transformSelection(bool position, Point3F& p, bool relativePos
    {
       if( relativePos )
       {
-         mSelected->offset( p, mGridSnap ? mGridPlaneSize : 0.f );
+         mSelected->offset(p, (!mUseGroupCenter && mGridSnap) ? mGridPlaneSize : 0.f);
       }
       else
       {
@@ -3641,7 +3657,7 @@ void WorldEditor::makeSelectionPrefab( const char *filename )
          else
          {
             //Only push the cleanup of the group if it's ONLY a SimGroup.
-            cleanup.push_back(grp);
+         cleanup.push_back( grp );
          }
       }
       else

+ 5 - 2
Engine/source/gui/worldEditor/worldEditor.h

@@ -164,7 +164,8 @@ class WorldEditor : public EditTSCtrl
       bool copySelection(Selection*  sel);
       bool pasteSelection(bool dropSel=true);
       void dropSelection(Selection*  sel);
-      void dropBelowSelection(Selection*  sel, const Point3F & centroid, bool useBottomBounds=false);
+      void dropBelowSelection(Selection*  sel, const Point3F & centroid, bool useBottomBounds = false);
+      void dropAtGizmo(Selection*  sel, const Point3F & gizmoPos);
 
       void terrainSnapSelection(Selection* sel, U8 modifier, Point3F gizmoPos, bool forceStick=false);
       void softSnapSelection(Selection* sel, U8 modifier, Point3F gizmoPos);
@@ -296,7 +297,8 @@ class WorldEditor : public EditTSCtrl
          DropAtScreenCenter,
          DropAtCentroid,
          DropToTerrain,
-         DropBelowSelection
+         DropBelowSelection,
+         DropAtGizmo
       };
 
       // Snapping alignment mode
@@ -349,6 +351,7 @@ class WorldEditor : public EditTSCtrl
       F32               mDropAtScreenCenterMax;
 
       bool              mGridSnap;
+      bool              mUseGroupCenter;
       bool              mStickToGround;
       bool              mStuckToGround;            ///< Selection is stuck to the ground
       AlignmentType     mTerrainSnapAlignment;     ///< How does the stickied object align to the terrain

+ 19 - 3
Engine/source/gui/worldEditor/worldEditorSelection.cpp

@@ -306,9 +306,9 @@ void WorldEditorSelection::offset( const Point3F& offset, F32 gridSnap )
       
       if( gridSnap != 0.f )
       {
-         wPos.x -= mFmod( wPos.x, gridSnap );
-         wPos.y -= mFmod( wPos.y, gridSnap );
-         wPos.z -= mFmod( wPos.z, gridSnap );
+         wPos.x = _snapFloat(wPos.x, gridSnap);
+         wPos.y = _snapFloat(wPos.y, gridSnap);
+         wPos.z = _snapFloat(wPos.z, gridSnap);
       }
       
       mat.setColumn(3, wPos);
@@ -318,6 +318,22 @@ void WorldEditorSelection::offset( const Point3F& offset, F32 gridSnap )
    mCentroidValid = false;
 }
 
+F32 WorldEditorSelection::_snapFloat(const F32 &val, const F32 &snap) const
+{
+   if (snap == 0.0f)
+      return val;
+
+   F32 a = mFmod(val, snap);
+
+   F32 temp = val;
+
+   if (mFabs(a) > (snap / 2))
+      val < 0.0f ? temp -= snap : temp += snap;
+
+   return(temp - a);
+}
+
+
 //-----------------------------------------------------------------------------
 
 void WorldEditorSelection::setPosition(const Point3F & pos)

+ 1 - 0
Engine/source/gui/worldEditor/worldEditorSelection.h

@@ -108,6 +108,7 @@ class WorldEditorSelection : public SimPersistSet
       //
       void offset(const Point3F& delta, F32 gridSnap = 0.f );
       void setPosition(const Point3F & pos);
+      F32 _snapFloat(const F32 &val, const F32 &snap) const;
       void setCentroidPosition(bool useBoxCenter, const Point3F & pos);
 
       void orient(const MatrixF &, const Point3F &);

+ 21 - 2
Templates/BaseGame/game/tools/worldEditor/gui/ObjectSnapOptionsWindow.ed.gui

@@ -28,7 +28,7 @@
       canMinimize = "0";
       canMaximize = "0";
       position = "400 31";
-      extent =" 175 257";
+      extent =" 175 267";
       MinExtent = "175 130";
       text = "Snap Options";
       closeCommand = "ESnapOptions.hideDialog();";
@@ -51,7 +51,7 @@
          Visible = "1";
          hovertime = "1000";
          Docking = "Client";
-         Margin = "3 22 3 3";
+         Margin = "3 32 3 3";
          Padding = "0 0 0 0";
          AnchorTop = "1";
          AnchorBottom = "0";
@@ -793,6 +793,25 @@
             canSave = "1";
             canSaveDynamicFields = "0";
          };
+      new GuiCheckBoxCtrl() {
+            text = "Use Group Center";
+            groupNum = "1";
+            useMouseEvents = "0";
+            isContainer = "0";
+            horizSizing = "right";
+            vertSizing = "top";
+            position = "4 246";
+            extent = "105 24";
+            minExtent = "8 8";
+            visible = "1";
+            active = "1";
+            command = "toggleSnappingOptions(\"byGroup\");";
+            tooltipProfile = "ToolsGuiToolTipProfile";
+            hovertime = "1000";
+            internalName = "GroupSnapButton";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
       new GuiTextCtrl() {
          text = "Size";
          maxLength = "1024";

+ 7 - 0
Templates/BaseGame/game/tools/worldEditor/scripts/EditorGui.ed.cs

@@ -2050,12 +2050,14 @@ function EWorldEditor::syncGui( %this )
    EWorldEditorToolbar-->renderHandleBtn.setStateOn( EWorldEditor.renderObjHandle );
    EWorldEditorToolbar-->renderTextBtn.setStateOn( EWorldEditor.renderObjText );
 
+   EWorldEditorToolbar-->objectSnapDownBtn.setStateOn( %this.stickToGround );
    SnapToBar-->objectSnapBtn.setStateOn( EWorldEditor.getSoftSnap() );
    EWorldEditorToolbar-->softSnapSizeTextEdit.setText( EWorldEditor.getSoftSnapSize() );
    ESnapOptions-->SnapSize.setText( EWorldEditor.getSoftSnapSize() );
    ESnapOptions-->GridSize.setText( EWorldEditor.getGridSize() );
    
    ESnapOptions-->GridSnapButton.setStateOn( %this.getGridSnap() );
+   ESnapOptions-->GroupSnapButton.setStateOn( %this.UseGroupCenter );
    SnapToBar-->objectGridSnapBtn.setStateOn( %this.getGridSnap() );
    ESnapOptions-->NoSnapButton.setStateOn( !%this.stickToGround && !%this.getSoftSnap() && !%this.getGridSnap() );
 }
@@ -2458,6 +2460,11 @@ function toggleSnappingOptions( %var )
    {
       EWorldEditor.setGridSnap( !EWorldEditor.getGridSnap() );
    }
+   else if( %var $= "byGroup" )
+   {
+	   EWorldEditor.UseGroupCenter = !EWorldEditor.UseGroupCenter;
+	   ESnapOptions->GroupSnapButton.setStateOn(EWorldEditor.UseGroupCenter);
+   }
    else
    { 
       // No snapping.

+ 1 - 0
Templates/BaseGame/game/tools/worldEditor/scripts/menus.ed.cs

@@ -315,6 +315,7 @@ function EditorGui::buildMenus(%this)
          item[5] = "at Centroid" TAB "" TAB "atCentroid";
          item[6] = "to Terrain" TAB "" TAB "toTerrain";
          item[7] = "Below Selection" TAB "" TAB "belowSelection";
+         item[8] = "At Gizmo" TAB "" TAB "atGizmo";
       };
       
       %this.alignBoundsMenu = new PopupMenu()

+ 21 - 2
Templates/Full/game/tools/worldEditor/gui/ObjectSnapOptionsWindow.ed.gui

@@ -28,7 +28,7 @@
       canMinimize = "0";
       canMaximize = "0";
       position = "400 31";
-      extent =" 175 257";
+      extent =" 175 267";
       MinExtent = "175 130";
       text = "Snap Options";
       closeCommand = "ESnapOptions.hideDialog();";
@@ -51,7 +51,7 @@
          Visible = "1";
          hovertime = "1000";
          Docking = "Client";
-         Margin = "3 22 3 3";
+         Margin = "3 32 3 3";
          Padding = "0 0 0 0";
          AnchorTop = "1";
          AnchorBottom = "0";
@@ -793,6 +793,25 @@
             canSave = "1";
             canSaveDynamicFields = "0";
          };
+      new GuiCheckBoxCtrl() {
+            text = "Use Group Center";
+            groupNum = "1";
+            useMouseEvents = "0";
+            isContainer = "0";
+            horizSizing = "right";
+            vertSizing = "top";
+            position = "4 246";
+            extent = "105 24";
+            minExtent = "8 8";
+            visible = "1";
+            active = "1";
+            command = "toggleSnappingOptions(\"byGroup\");";
+            tooltipProfile = "ToolsGuiToolTipProfile";
+            hovertime = "1000";
+            internalName = "GroupSnapButton";
+            canSave = "1";
+            canSaveDynamicFields = "0";
+         };
       new GuiTextCtrl() {
          text = "Size";
          maxLength = "1024";

+ 7 - 0
Templates/Full/game/tools/worldEditor/scripts/EditorGui.ed.cs

@@ -2050,12 +2050,14 @@ function EWorldEditor::syncGui( %this )
    EWorldEditorToolbar-->renderHandleBtn.setStateOn( EWorldEditor.renderObjHandle );
    EWorldEditorToolbar-->renderTextBtn.setStateOn( EWorldEditor.renderObjText );
 
+   EWorldEditorToolbar-->objectSnapDownBtn.setStateOn( %this.stickToGround );
    SnapToBar-->objectSnapBtn.setStateOn( EWorldEditor.getSoftSnap() );
    EWorldEditorToolbar-->softSnapSizeTextEdit.setText( EWorldEditor.getSoftSnapSize() );
    ESnapOptions-->SnapSize.setText( EWorldEditor.getSoftSnapSize() );
    ESnapOptions-->GridSize.setText( EWorldEditor.getGridSize() );
    
    ESnapOptions-->GridSnapButton.setStateOn( %this.getGridSnap() );
+   ESnapOptions-->GroupSnapButton.setStateOn( %this.UseGroupCenter );
    SnapToBar-->objectGridSnapBtn.setStateOn( %this.getGridSnap() );
    ESnapOptions-->NoSnapButton.setStateOn( !%this.stickToGround && !%this.getSoftSnap() && !%this.getGridSnap() );
 }
@@ -2458,6 +2460,11 @@ function toggleSnappingOptions( %var )
    {
       EWorldEditor.setGridSnap( !EWorldEditor.getGridSnap() );
    }
+   else if( %var $= "byGroup" )
+   {
+	   EWorldEditor.UseGroupCenter = !EWorldEditor.UseGroupCenter;
+	   ESnapOptions->GroupSnapButton.setStateOn(EWorldEditor.UseGroupCenter);
+   }
    else
    { 
       // No snapping.

+ 1 - 0
Templates/Full/game/tools/worldEditor/scripts/menus.ed.cs

@@ -315,6 +315,7 @@ function EditorGui::buildMenus(%this)
          item[5] = "at Centroid" TAB "" TAB "atCentroid";
          item[6] = "to Terrain" TAB "" TAB "toTerrain";
          item[7] = "Below Selection" TAB "" TAB "belowSelection";
+         item[8] = "At Gizmo" TAB "" TAB "atGizmo";
       };
       
       %this.alignBoundsMenu = new PopupMenu()