Files
sbox-public/engine/Sandbox.Engine/Editor/Gizmos/Control/Control.BoundingBox.cs
s&box team 71f266059a Open source release
This commit imports the C# engine code and game files, excluding C++ source code.

[Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
2025-11-24 09:05:18 +00:00

140 lines
4.1 KiB
C#

namespace Sandbox;
public static partial class Gizmo
{
public sealed partial class GizmoControls
{
private static bool ArrowPoint( string name, Vector3 direction, float length, Color color, out float distance, ref bool pressed )
{
distance = 0.0f;
var rotation = Rotation.LookAt( direction, Vector3.Up );
using var x = Scope( name, direction * length, rotation );
var worldBoxScale = Transform.UniformScale;
using var scaler = PushFixedScale();
length /= Transform.UniformScale;
const float sphereRadius = 1.3f;
const float hoverSphereRadius = sphereRadius * 1.25f;
float actualSphereRadius = IsHovered ? hoverSphereRadius : sphereRadius;
float arrowHeadRadius = sphereRadius * 0.9f;
float hoverArrowHeadRadius = arrowHeadRadius * 1.25f;
float actualArrowHeadRadius = IsHovered ? hoverArrowHeadRadius : arrowHeadRadius;
float actualArrowHeadLength = actualArrowHeadRadius * 2;
var db = Gizmo.Hitbox.DepthBias;
Gizmo.Hitbox.DepthBias = 0.01f;
Hitbox.Sphere( new Sphere( 0, hoverSphereRadius * Transform.UniformScale ) );
Vector3 arrowFrom = Vector3.Forward * -(actualArrowHeadLength + actualSphereRadius);
Vector3 arrowTo = Vector3.Forward * -actualSphereRadius;
Hitbox.Sphere( new Sphere( arrowFrom / 2, hoverArrowHeadRadius * Transform.UniformScale ) );
Gizmo.Hitbox.DepthBias = db;
color = IsHovered || Pressed.This ? Colors.Active : color;
Draw.IgnoreDepth = true;
Draw.Color = color;
Draw.SolidSphere( Vector3.Zero, actualSphereRadius );
// Draw an arrow pointing inward from the box to the sphere
Draw.Arrow( arrowFrom, arrowTo, actualArrowHeadLength, actualArrowHeadRadius );
if ( Pressed.This )
{
pressed = true;
Transform = Transform.ToWorld( new Transform( Vector3.Backward * (length * 2.0f) ) );
using ( PushFixedScale() )
{
Transform = Transform.WithRotation( Rotation.LookAt( Transform.Rotation.Forward, Camera.Rotation.Forward ) );
var delta = GetMouseDelta( Vector3.Zero, Vector3.Up );
distance = Vector3.Forward.Dot( GetMouseDelta( Vector3.Zero, Vector3.Up ) );
distance /= worldBoxScale;
}
}
return distance != 0.0f;
}
public bool BoundingBox( string name, BBox value, out BBox outValue )
{
return BoundingBox( name, value, out outValue, out _ );
}
public bool BoundingBox( string name, BBox value, out BBox outValue, out bool outPressed )
{
outValue = value;
using ( Scope( name ) )
{
Transform = Transform.ToWorld( new Transform( value.Center ) );
var halfSize = value.Size * 0.5f;
var resized = false;
var resizeDist = 0.0f;
var resizeAxis = Vector3.Zero;
var pressed = false;
if ( ArrowPoint( "Forward", Vector3.Forward, halfSize.x, Colors.Forward, out var forwardDist, ref pressed ) )
{
resized = true;
resizeDist = forwardDist;
resizeAxis = Vector3.Forward;
}
if ( ArrowPoint( "Backward", Vector3.Backward, halfSize.x, Colors.Forward, out var backwardDist, ref pressed ) )
{
resized = true;
resizeDist = backwardDist;
resizeAxis = Vector3.Backward;
}
if ( ArrowPoint( "Up", Vector3.Up, halfSize.z, Colors.Up, out var upDist, ref pressed ) )
{
resized = true;
resizeDist = upDist;
resizeAxis = Vector3.Up;
}
if ( ArrowPoint( "Down", Vector3.Down, halfSize.z, Colors.Up, out var downDist, ref pressed ) )
{
resized = true;
resizeDist = downDist;
resizeAxis = Vector3.Down;
}
if ( ArrowPoint( "Left", Vector3.Left, halfSize.y, Colors.Left, out var leftDist, ref pressed ) )
{
resized = true;
resizeDist = leftDist;
resizeAxis = Vector3.Left;
}
if ( ArrowPoint( "Right", Vector3.Right, halfSize.y, Colors.Left, out var rightDist, ref pressed ) )
{
resized = true;
resizeDist = rightDist;
resizeAxis = Vector3.Right;
}
outPressed = pressed;
if ( resized && !resizeDist.AlmostEqual( 0 ) )
{
var center = value.Center + resizeAxis * (resizeDist * 0.5f);
halfSize = value.Size + resizeAxis.Abs() * resizeDist;
outValue = BBox.FromPositionAndSize( center, halfSize );
return true;
}
}
return false;
}
}
}