1-
2- namespace Editor . MeshEditor ;
1+ namespace Editor . MeshEditor ;
32
43/// <summary>
54/// Set the location of the gizmo for the current selection.
5+ /// <br/><b>Space (Hold)</b> - Snap pivot to scene/vertices
66/// </summary>
77[ Title ( "Pivot Tool" ) ]
88[ Icon ( "adjust" ) ]
@@ -13,8 +13,16 @@ public sealed class PivotMode : MoveMode
1313 private Vector3 _pivot ;
1414 private Rotation _basis ;
1515
16+ public override bool AllowSceneSelection => ! Application . IsKeyDown ( KeyCode . Space ) ;
17+
1618 protected override void OnUpdate ( SelectionTool tool )
1719 {
20+ if ( Application . IsKeyDown ( KeyCode . Space ) && Gizmo . HasMouseFocus )
21+ {
22+ RunPicker ( tool ) ;
23+ return ;
24+ }
25+
1826 var origin = tool . Pivot ;
1927
2028 if ( ! Gizmo . Pressed . Any )
@@ -34,4 +42,108 @@ protected override void OnUpdate( SelectionTool tool )
3442 }
3543 }
3644 }
45+
46+ private void RunPicker ( SelectionTool tool )
47+ {
48+ var tr = tool . Scene . Trace
49+ . Ray ( Gizmo . CurrentRay , Gizmo . RayDepth )
50+ . UseRenderMeshes ( true , EditorPreferences . BackfaceSelection )
51+ . UsePhysicsWorld ( false )
52+ . Run ( ) ;
53+
54+ Vector3 targetPosition = default ;
55+ bool hasTarget = false ;
56+ bool snappedToVertex = false ;
57+
58+ if ( tr . Hit && tr . Component is MeshComponent meshComponent )
59+ {
60+ var mesh = meshComponent . Mesh ;
61+ if ( mesh != null )
62+ {
63+ targetPosition = tr . HitPosition ;
64+ hasTarget = true ;
65+
66+ var face = mesh . TriangleToFace ( tr . Triangle ) ;
67+ var bestDist = float . MaxValue ;
68+ Vector3 ? bestVert = null ;
69+
70+ foreach ( var vHandle in mesh . GetFaceVertices ( face ) )
71+ {
72+ var vPosLocal = mesh . GetVertexPosition ( vHandle ) ;
73+ var vPosWorld = meshComponent . WorldTransform . PointToWorld ( vPosLocal ) ;
74+ var screenDist = Gizmo . Camera . ToScreen ( vPosWorld ) . Distance ( Gizmo . Camera . ToScreen ( targetPosition ) ) ;
75+
76+ if ( screenDist < bestDist )
77+ {
78+ bestDist = screenDist ;
79+ bestVert = vPosWorld ;
80+ }
81+ }
82+
83+ if ( bestVert . HasValue )
84+ {
85+ Gizmo . Draw . IgnoreDepth = true ;
86+ var screenDist = Gizmo . Camera . ToScreen ( bestVert . Value ) . Distance ( Gizmo . Camera . ToScreen ( targetPosition ) ) ;
87+ var isSnapRange = screenDist < 20.0f ;
88+
89+ var color = isSnapRange ? Theme . Green : Theme . Red ;
90+ Gizmo . Draw . Color = color . WithAlpha ( screenDist . Remap ( 0 , 100 , 1.0f , 0.0f , true ) ) ;
91+ Gizmo . Draw . SolidSphere ( bestVert . Value , 4 ) ;
92+
93+ if ( isSnapRange )
94+ {
95+ targetPosition = bestVert . Value ;
96+ snappedToVertex = true ;
97+ }
98+ }
99+ }
100+ }
101+
102+ if ( ! hasTarget )
103+ {
104+ var plane = new Plane ( new Vector3 ( 0 , 0 , tool . Pivot . z ) , Vector3 . Up ) ;
105+ if ( plane . TryTrace ( Gizmo . CurrentRay , out var dist ) )
106+ {
107+ targetPosition = Gizmo . CurrentRay . Project ( dist . Length ) ;
108+ hasTarget = true ;
109+ }
110+ }
111+
112+ if ( ! hasTarget ) return ;
113+
114+ if ( ! snappedToVertex && ( Gizmo . Settings . SnapToGrid || Gizmo . IsCtrlPressed ) )
115+ {
116+ targetPosition = Gizmo . Snap ( targetPosition , Vector3 . One ) ;
117+ }
118+
119+ using ( Gizmo . Scope ( "Pivot Pick" ) )
120+ {
121+ Gizmo . Transform = new Transform ( targetPosition ) ;
122+
123+ Gizmo . Draw . IgnoreDepth = true ;
124+ Gizmo . Draw . Color = Theme . Yellow ;
125+ Gizmo . Draw . SolidSphere ( Vector3 . Zero , 2 ) ;
126+
127+ Gizmo . Draw . Color = Color . White . WithAlpha ( 0.8f ) ;
128+ Gizmo . Draw . Line ( Vector3 . Zero , Vector3 . Up * 16 ) ;
129+ Gizmo . Draw . Line ( Vector3 . Zero , Vector3 . Forward * 16 ) ;
130+ Gizmo . Draw . Line ( Vector3 . Zero , Vector3 . Left * 16 ) ;
131+
132+ Gizmo . Transform = new Transform ( tool . Pivot ) ;
133+ Gizmo . Draw . Color = Gizmo . Colors . Up ;
134+ Gizmo . Draw . Line ( Vector3 . Zero , Vector3 . Up * 16 ) ;
135+ Gizmo . Draw . Color = Gizmo . Colors . Forward ;
136+ Gizmo . Draw . Line ( Vector3 . Zero , Vector3 . Forward * 16 ) ;
137+ Gizmo . Draw . Color = Gizmo . Colors . Left ;
138+ Gizmo . Draw . Line ( Vector3 . Zero , Vector3 . Left * 16 ) ;
139+
140+ Gizmo . Draw . Color = Color . White ;
141+ Gizmo . Draw . SolidSphere ( Vector3 . Zero , 1.5f ) ;
142+ }
143+
144+ if ( Gizmo . IsLeftMouseDown )
145+ {
146+ tool . Pivot = targetPosition ;
147+ }
148+ }
37149}
0 commit comments