프로그래밍/WPF

[WPF] HelixToolkit.Wpf.SharpDX 사용하여 3D 공간에서 마우스 드래그로 선택 영역 그리기

흔한티벳여우 2023. 10. 30. 15:03
반응형

3D 모델링 및 시각화 툴을 개발하다 보면 사용자가 마우스로 드래그하여 특정 영역을 선택하는 기능을 구현할 필요가 종종 있습니다. 이번 글에서는 WPF와 HelixToolkit.Wpf.SharpDX를 사용하여 3D 공간에서 마우스 드래그로 선택 영역을 그리는 방법에 대해 알아보겠습니다.

개요

사용자가 마우스 왼쪽 버튼을 클릭하고 드래그하면, 그림자 박스 형태로 선택 영역을 화면에 표시합니다. 이 기능은 3D 모델링 툴에서 객체를 선택하거나, 특정 영역에 대한 작업을 수행할 때 유용하게 사용됩니다.

 

준비

먼저, WPF 프로젝트를 생성하고, NuGet 패키지 관리자를 통해 HelixToolkit.Wpf.SharpDX를 설치합니다.

 

코드 구현

디자인

<Window x:Class="Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:hx="clr-namespace:HelixToolkit.Wpf.SharpDX;assembly=HelixToolkit.Wpf.SharpDX"
        mc:Ignorable="d"
        Title="3D Drag Selection" Height="450" Width="800">
    <Grid>
        <hx:Viewport3DX x:Name="viewport" Camera="{hx:PerspectiveCamera}">
            <hx:LineGeometryModel3D x:Name="selectionBox" Color="Red"/>
        </hx:Viewport3DX>
    </Grid>
</Window>

필드 정의

private Vector3 startDragPoint3D;
private bool isDragging;

이벤트 핸들러 연결

public MainWindow()
{
    InitializeComponent();
    viewport.MouseDown += OnMouseDown;
    viewport.MouseMove += OnMouseMove;
    viewport.MouseUp += OnMouseUp;
}

마우스 이벤트 핸들러 구현

드래그 시작 위치를 저장하고, 드래그 상태를 업데이트하는 OnMouseDown, OnMouseMove, OnMouseUp 메서드를 구현합니다.

private void OnMouseDown(object sender, MouseButtonEventArgs e)
{
    if (e.LeftButton == MouseButtonState.Pressed)
    {
        startDragPoint3D = UnProject(e.GetPosition(viewport));
        isDragging = true;
    }
}

private void OnMouseMove(object sender, MouseEventArgs e)
{
    if (isDragging)
    {
        var currentPoint3D = UnProject(e.GetPosition(viewport));
        UpdateSelectionBox(startDragPoint3D, currentPoint3D);
    }
}

private void OnMouseUp(object sender, MouseButtonEventArgs e)
{
    if (isDragging)
    {
        isDragging = false;
        // 드래그 완료 후 필요한 로직을 여기에 추가합니다.
    }
}

선택 영역 업데이트 메서드

드래그 영역을 표시하는 UpdateSelectionBox 메서드를 구현합니다.

private void UpdateSelectionBox(Vector3 start, Vector3 end)
{
    var builder = new LineBuilder();

    start = new Vector3(start.X, start.Y, 0);
    end = new Vector3(end.X, end.Y, 0);

    builder.AddLine(start, new Vector3(end.X, start.Y, start.Z));
    builder.AddLine(new Vector3(end.X, start.Y, start.Z), end);
    builder.AddLine(end, new Vector3(start.X, end.Y, end.Z));
    builder.AddLine(new Vector3(start.X, end.Y, end.Z), start);

    selectionBox.Geometry = builder.ToLineGeometry3D();
}

3D 좌표 변환 메서드

화면상의 2D 포인트를 3D 공간으로 변환하는 UnProject 메서드를 구현합니다.

private Vector3 UnProject(Point point)
{
    viewport.UnProject(new Vector2((float)point.X, (float)point.Y), out Ray ray);

    var plane = new Plane(new Vector3(0, 0, 1), 0);

    if (ray.Intersects(ref plane, out float distance))
    {
        return ray.Position + ray.Direction * distance;
    }
    else
    {
        return ray.Position + ray.Direction * 10;
    }
}

 

정리

이제 마우스를 사용하여 3D 공간에서 드래그하여 선택 영역을 그릴 수 있습니다. 이 기능은 다양한 3D 응용 프로그램에서 사용될 수 있으며, 사용자와의 상호작용을 향상시키는 데 도움이 됩니다.

글에서 소개한 코드와 방법을 활용하여, 여러분의 프로젝트에 적합한 사용자 인터페이스를 구축하고, 3D 공간에서의 상호작용을 더욱 향상시켜보세요!

반응형