Одним из распространенных требований в 3D-графике является возможность перемещать объекты с помощью мыши. В данной статье мы рассмотрим, как реализовать движение 3D объекта с мышью в Delphi с помощью библиотеки GLScene.
Предположим, что у нас есть 3D объект, представляющий собой плоскость (не авиационный, а 2D-изображение в 3D пространстве). Мы хотим, чтобы при нажатии и удержании левой кнопки мыши объект перемещался вместе с курсором мыши, сохраняя исходное положение курсора относительно объекта.
Для реализации этой функции мы будем использовать обработчики событий MouseDown, MouseMove и MouseUp компонента GLSceneViewer. В обработчике MouseDown мы получим выбранный объект и сохраним точку клика в 3D пространстве. В обработчике MouseMove мы будем перемещать объект так, чтобы точка клика всегда находилась под курсором мыши. В обработчике MouseUp мы просто сбросим флаг, указывающий на состояние нажатой кнопки мыши.
Пример кода:
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, GLScene, GLObjects, GLMaterial, GLTexture, GLGraph,
GLSLPostBlurShader, GLOutlineShader, GLSmoothNavigator, GLWindows, GLGui, GLCrossPlatform, GLColor,
GLCoordinates, GLTextureFormat, VectorGeometry;
type
TPoint3D = record
X, Y, Z: single;
end;
TForm1 = class(TForm)
GLSceneViewer1: TGLSceneViewer;
procedure FormCreate(Sender: TObject);
procedure GLSceneViewer1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
procedure GLSceneViewer1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
procedure GLSceneViewer1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
private
FSelectedObject: TGLCustomSceneObject;
FClickPoint: TPoint3D;
FIsMouseDown: Boolean;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
FIsMouseDown := False;
end;
procedure TForm1.GLSceneViewer1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
FSelectedObject := GLSceneViewer1.Buffer.GetPickedObject(X, Y) as TGLCustomSceneObject;
if Assigned(FSelectedObject) then
begin
FClickPoint := GLSceneViewer1.Buffer.ScreenToWorld(VectorMake(X, GLSceneViewer1.Height - Y, 0));
FIsMouseDown := True;
end;
end;
procedure TForm1.GLSceneViewer1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
if FIsMouseDown then
begin
if Assigned(FSelectedObject) then
begin
var newPoint: TPoint3D;
newPoint := GLSceneViewer1.Buffer.ScreenToWorld(VectorMake(X, GLSceneViewer1.Height - Y, 0));
FSelectedObject.Position.X := newPoint.X - FClickPoint.X;
FSelectedObject.Position.Y := newPoint.Y - FClickPoint.Y;
end;
end;
end;
procedure TForm1.GLSceneViewer1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
FIsMouseDown := False;
end;
end.
В данном примере мы используем обработчики событий MouseDown, MouseMove и MouseUp компонента GLSceneViewer. В обработчике MouseDown мы получаем выбранный объект и сохраняем точку клика в 3D пространстве. В обработчике MouseMove мы перемещаем объект так, чтобы точка клика всегда находилась под курсором мыши. В обработчике MouseUp мы просто сбрасываем флаг, указывающий на состояние нажатой кнопки мыши.
Примечание: Приведенный выше код является упрощенным примером и не учитывает такие факторы, как изменение масштаба, вращение камеры и т.д. Для более сложных сценариев может потребоваться более сложная реализация.
Реализация движения 3D объекта с мышью в Delphi с помощью GLScene.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.