rj-action-library/Runtime/VirtualCameras/MouseEditorCamera.cs

222 lines
4.6 KiB
C#

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;
}
}
}