@@ -163,19 +163,56 @@ protected virtual void CopyCachedData(TInstanceData[] data, TInstanceData[] cach
163163
164164 }
165165
166- protected override ( Vector3 , float ) GetTeleportPosition ( CameraComponent camera )
166+ protected override ( Vector3 , float ) GetTeleportPosition ( CameraComponent camera , Quaternion rotation )
167167 {
168- var vHalfFov = camera . FieldOfViewRadians / 2f ;
169- var hHalfFov = MathF . Atan ( MathF . Tan ( vHalfFov ) * camera . AspectRatio ) ;
170- var limitingHalfFov = MathF . Min ( vHalfFov , hHalfFov ) ;
168+ var upLimit = MathF . Tan ( camera . FieldOfViewRadians / 2f ) ;
169+ var sideLimit = upLimit * camera . AspectRatio ;
170+
171+ var forward = Vector3 . Transform ( Settings . ForwardVector , rotation ) ;
172+ var right = Vector3 . Transform ( Settings . RightVector , rotation ) ;
173+ var up = Vector3 . Transform ( Settings . UpVector , rotation ) ;
171174
172- var sphereRadius = Descriptor . Bounds . Extents . Length ( ) ;
173- var distance = sphereRadius / MathF . Tan ( limitingHalfFov ) * 1.25f ;
174175 var center = Vector3 . Transform ( Descriptor . Bounds . Center , GizmoMatrix ) ;
175176
177+ var distance = 0f ;
178+ for ( var i = 0 ; i < 8 ; i ++ )
179+ {
180+ var offset = Vector3 . Transform ( GetBoundsCorner ( i ) , GizmoMatrix ) - center ;
181+ var depth = Vector3 . Dot ( offset , - forward ) ;
182+
183+ distance = MathF . Max ( distance , MathF . Abs ( Vector3 . Dot ( offset , right ) ) / sideLimit - depth ) ;
184+ distance = MathF . Max ( distance , MathF . Abs ( Vector3 . Dot ( offset , up ) ) / upLimit - depth ) ;
185+ }
186+
176187 return ( center , MathF . Max ( distance , 0.1f ) ) ;
177188 }
178189
190+ private Vector3 GetBoundsCorner ( int index )
191+ {
192+ var extents = Descriptor . Bounds . Extents ;
193+
194+ return Descriptor . Bounds . Center + new Vector3 (
195+ ( index & 1 ) == 0 ? - extents . X : extents . X ,
196+ ( index & 2 ) == 0 ? - extents . Y : extents . Y ,
197+ ( index & 4 ) == 0 ? - extents . Z : extents . Z ) ;
198+ }
199+
200+ public void SnapToGround ( )
201+ {
202+ var lowest = float . MaxValue ;
203+ for ( var i = 0 ; i < 8 ; i ++ )
204+ {
205+ lowest = MathF . Min ( lowest , Vector3 . Transform ( GetBoundsCorner ( i ) , WorldMatrix ) . Y ) ;
206+ }
207+
208+ if ( lowest == 0f || ! Matrix4x4 . Invert ( GetRelationMatrix ( ) , out var invRelation ) )
209+ return ;
210+
211+ var transform = GetLocalTransform ( ) ;
212+ transform . Position -= Vector3 . TransformNormal ( new Vector3 ( 0f , lowest , 0f ) , invRelation ) ;
213+ SetLocalTransform ( transform ) ;
214+ }
215+
179216 protected override void BeginPlay ( ActorManager scene )
180217 {
181218 base . BeginPlay ( scene ) ;
@@ -288,13 +325,13 @@ public override void DrawControls()
288325
289326 ImGui . BeginGroup ( ) ;
290327 ImGui . SetNextItemWidth ( - 1 ) ;
291- if ( ImGui . BeginCombo ( "##SectionCombo" , $ "{ _sectionIndex } : { GetMaterialName ( selected . MaterialIndex ) } ") )
328+ if ( ImGui . BeginCombo ( "##SectionCombo" , $ "{ _sectionIndex } : { selected . Name } ") )
292329 {
293330 for ( var i = 0 ; i < lod . Sections . Length ; i ++ )
294331 {
295332 var isSelected = i == _sectionIndex ;
296333
297- if ( ImGui . Selectable ( $ "{ i } : { GetMaterialName ( lod . Sections [ i ] . MaterialIndex ) } ##Section{ i } ", isSelected ) )
334+ if ( ImGui . Selectable ( $ "{ i } : { lod . Sections [ i ] . Name } ##Section{ i } ", isSelected ) )
298335 {
299336 _sectionIndex = i ;
300337 _materialLayerIndex = 0 ;
@@ -331,11 +368,6 @@ public override void DrawControls()
331368 } ) ;
332369 }
333370
334- private string GetMaterialName ( uint materialIndex ) =>
335- materialIndex < Materials . Length && Materials [ materialIndex ] is { } section
336- ? section . MaterialDataContainer ? . Name ?? Settings . NoName
337- : Settings . NoName ;
338-
339371 private void DrawInfoPopup ( )
340372 {
341373 var viewport = ImGui . GetMainViewport ( ) ;
0 commit comments