using System.Diagnostics; using System.Collections; using System.Collections.Generic; using System; using Godot; namespace Rokojori { [Tool] [GlobalClass] public partial class MouseEditorCamera:VirtualCamera3D { [Export] public Vector3 target; [Export] public float yaw = 0; [Export] public float pitch = 0; [Export] public float distance = 10; float smoothDistance = 10; [ExportGroup("Orbit")] [Export] public float yawSpeed = 1; [Export] public float pitchSpeed = 1; [Export] public float minPitch = -89; [Export] public float maxPitch = 89; [Export] public RJSensor orbitButton; [Export] public RJSensor[] orbitModifierButtons; [ExportGroup("Pan")] [Export] public float panSpeedX = 0.01f; [Export] public float panSpeedY = 0.01f; [Export] public RJSensor panButton; [Export] public RJSensor[] panModifierButtons; [ExportGroup("Zoom")] [Export] public float zoomStepInPercentage = 10; [Export] public float minDistance = 0.001f; [Export] public float maxDistance = 200f; [Export] public RJSensor zoomInButton; [Export] public RJSensor[] zoomInModifierButtons; [Export] public RJSensor zoomOutButton; [Export] public RJSensor[] zoomOutModifierButtons; [Export] public float zoomSmoothingCoefficient = 0.1f; Smoother smoother = new Smoother(); [ExportGroup("Move")] [Export] public RJSensor forwardButton; [Export] public RJSensor backwardsButton; [Export] public RJSensor leftButton; [Export] public RJSensor rightButton; [Export] public RJSensor upButton; [Export] public RJSensor downButton; [Export] public float moveSpeed = 1; public override void _Process( double delta ) { Orbit(); Pan(); Zoom(); Move(); Apply( (float) delta ); if ( ! hasMotionDelta ) { motionDelta.X = 0; motionDelta.Y = 0; } hasMotionDelta = false; } bool hasMotionDelta = false; Vector2 motionDelta = Vector2.Zero; public override void _Input( InputEvent inputEvent ) { var mouseMotionEvent = inputEvent as InputEventMouseMotion; if ( mouseMotionEvent == null ) { return; } motionDelta = mouseMotionEvent.ScreenRelative; hasMotionDelta = true; } void Orbit() { if ( ! Sensors.IsActive( orbitButton ) ) { return; } yaw += motionDelta.X * yawSpeed; pitch += motionDelta.Y * pitchSpeed; pitch = Mathf.Clamp( pitch, minPitch, maxPitch ); } void Pan() { if ( ! Sensors.IsActive( panButton ) ) { return; } var xAmount = motionDelta.X * smoothDistance * GlobalBasis.X * panSpeedX; var yAmount = motionDelta.Y * smoothDistance * GlobalBasis.Y * panSpeedY; target += xAmount + yAmount; } void Zoom() { if ( Sensors.IsActive( zoomInButton ) ) { distance *= Mathf.Pow( 1 + zoomStepInPercentage / 100f, 1 ); } if ( Sensors.IsActive( zoomOutButton ) ) { distance *= Mathf.Pow( 1 + zoomStepInPercentage / 100f, -1 ); } distance = Mathf.Clamp( distance, minDistance, maxDistance ); } Vector3 moveDirection = Vector3.Zero; void Move() { moveDirection = Vector3.Zero; if ( Sensors.IsActive( forwardButton ) || Sensors.IsActive( backwardsButton ) ) { moveDirection = ( Sensors.GetValue( forwardButton ) - Sensors.GetValue( backwardsButton ) ) * this.GlobalForward(); } if ( Sensors.IsActive( rightButton ) || Sensors.IsActive( leftButton ) ) { moveDirection = ( Sensors.GetValue( rightButton ) - Sensors.GetValue( leftButton ) ) * this.GlobalRight(); } if ( Sensors.IsActive( upButton ) || Sensors.IsActive( downButton ) ) { moveDirection = ( Sensors.GetValue( upButton ) - Sensors.GetValue( downButton ) ) * this.GlobalUp(); } moveDirection = moveDirection.Normalized() * moveSpeed; } void Apply( float delta ) { smoothDistance = smoother.SmoothWithCoefficient( smoothDistance, distance, zoomSmoothingCoefficient, delta ); GlobalRotation = new Vector3( Mathf.DegToRad( pitch ), Mathf.DegToRad( yaw ), 0 ); var forward = Math3D.GetGlobalForward( this ) * smoothDistance; target -= moveDirection * delta; GlobalPosition = target + forward; } } }