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; [ExportCategory("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; [ExportCategory("Pan")] [Export] public float panSpeedX = 1f; [Export] public float panSpeedY = 1f; [Export] public RJSensor panButton; [Export] public RJSensor[] panModifierButtons; [ExportCategory("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(); public override void _Process( double delta ) { Orbit(); Pan(); Zoom(); 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 ) { if ( inputEvent is InputEventMouseMotion ) { var eventMouseMotion = inputEvent as InputEventMouseMotion; motionDelta = eventMouseMotion.ScreenRelative; hasMotionDelta = true; } } void Orbit() { if ( ! orbitButton.IsActive() ) { return; } yaw += motionDelta.X * yawSpeed; pitch += motionDelta.Y * pitchSpeed; pitch = Mathf.Clamp( pitch, minPitch, maxPitch ); } void Pan() { if ( ! panButton.IsActive() ) { return; } var xAmount = motionDelta.X * smoothDistance * GlobalBasis.X * panSpeedX; var yAmount = motionDelta.Y * smoothDistance * GlobalBasis.Y * panSpeedY; target += xAmount + yAmount; } void Zoom() { if ( zoomInButton.IsActive() ) { distance *= Mathf.Pow( 1 + zoomStepInPercentage / 100f, 1 ); } if ( zoomOutButton.IsActive() ) { distance *= Mathf.Pow( 1 + zoomStepInPercentage / 100f, -1 ); } distance = Mathf.Clamp( distance, minDistance, maxDistance ); } 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; GlobalPosition = target + forward; } } }