ModelVisual3D преобразует null при попытке переместить объект

#c# #wpf #3d

#c# #wpf #3D

Вопрос:

Я пытаюсь переместить куб, щелкнув по нему и отслеживая мышь. Мой куб реализован следующим образом:

App.xaml

 <MeshGeometry3D x:Key="solidCube" 
Positions="2, 2, 2 -2, 2, 2 -2, -2, 2 2, -2, 2 2, 2, -2 -2, 2, -2 -2, -2, -2 2, -2, -2"
TriangleIndices="0,1,2 2,3,0 3,4,0 7,4,3 5,4,7 7,6,5 1,5,6 6,2,1 2,6,7 7,3,2 1,0,4 4,5,1"/> 
  

MainWindow.xaml

 <ModelVisual3D.Content>
    <GeometryModel3D x:Name="solidCubeGeometryModel3D" Geometry="{StaticResource solidCube}">
            <GeometryModel3D.Material>
                    <DiffuseMaterial>
                            <DiffuseMaterial.Brush>
                                    <SolidColorBrush Color="Red" Opacity="1.0"/>
                            </DiffuseMaterial.Brush>
                    </DiffuseMaterial>
            </GeometryModel3D.Material>
            <GeometryModel3D.Transform>
                <TranslateTransform3D x:Name="myTranslateTransform3D" OffsetX="0" OffsetY="0" OffsetZ="0" />
            </GeometryModel3D.Transform>
    </GeometryModel3D>
</ModelVisual3D.Content> 
  

У меня есть TrackballDecorator вокруг моего окна просмотра, в котором хранятся события:

 <custom:TrackballDecorator x:Name="trackballDecorator"         Grid.Column="1"MouseLeftButtonDown="OnMouseLeftButtonDown"
MouseMove="OnMouseMove"
MouseWheel="OnMouseWheel"
MouseLeftButtonUp="OnMouseLeftButtonUp"
PreviewTextInput="OnPreviewTextInput"
LostMouseCapture="OnLostMouseCapture"
Width="600" Height="600">

<custom:Interactive3DDecorator Grid.Column="1">

/// viewport etc... 
  

И мое первое событие, OnMouseLeftButtonDown, я взял из http://www.charlespetzold.com/3D /, пример отслеживания мыши, который:

  protected void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs args)
        {
        base.OnMouseLeftButtonDown(args);

        Point ptMouse = args.GetPosition(myViewport);
        HitTestResult result = VisualTreeHelper.HitTest(myViewport, ptMouse);

        // We're only interested in 3D hits.
        RayMeshGeometry3DHitTestResult result3d =
                            result as RayMeshGeometry3DHitTestResu<
        if (result3d == null)
            return;

        // We're only interested in ModelVisual3D hits.
        ModelVisual3D vis3d = result3d.VisualHit as ModelVisual3D;
        if (vis3d == null)
            return;

        // We're only interested in visuals with translate transforms.
        transTracking = vis3d.Transform as TranslateTransform3D; //NULL !!!!!!!!!!!
        if (transTracking == null)
            return;

        LineRange range;
        ViewportInfo.Point2DtoPoint3D(myViewport, ptMouse, out range);
        pointOriginal = range.PointFromZ(transTracking.OffsetZ);
        transOriginal = transTracking.Clone();
        isTracking = true;
        CaptureMouse();
        Focus();

        args.Handled = true;
    } 
  

Я обновил его, удалив переопределения и поместив отправитель объекта в параметры.
Есть ли что-то очень очевидное, чего мне не хватает, чтобы мое преобразование ModelVisual3D было нулевым?

Заранее спасибо, если вам нужна дополнительная информация, чтобы помочь мне, просто спросите: D

Комментарии:

1. vis3d.Transform Установлено на что-нибудь? Если это не так, то проблема в этом, но если это так, то проверьте, что это на самом деле TranslateTransform3D . Если это что-то другое, то as преобразование не будет действительным и вернется null .

2. Хм… Да, он установлен на {System.Windows.Media.Media3D.MatrixTransform3D} , может быть, мне следует использовать другой способ?

Ответ №1:

vis3d.Transform Установлено на что-нибудь?

Если это не так, то проблема в этом, но если это так, то проверьте, что это на самом деле TranslateTransform3D . Если это что-то другое, то as преобразование не будет действительным и вернет null результат.

Вы сказали, что на самом деле это MatrixTransform3D , которое является общим преобразованием матрицы. Измените свою строку на:

 transTracking = vis3d.Transform as MatrixTransform3D;
  

и это должно сработать.

Комментарии:

1. Я могу выполнить преобразования translate с помощью MatrixTransform? Я думал, что могу просто изменить размер своего объекта; но я попробую.

2. @PedroDusso — MatrixTransform содержит общую матрицу преобразования — это может быть что угодно — масштабирование, поворот, перевод или любая комбинация из трех.

3. спасибо за помощь. Мой подход заключался в изменении преобразования для ModelVisual3D.Transform. Но это продолжает не работать. Я начинаю добавлять свой код в свой пример по частям и обнаруживаю, что TrackballDecorator и Interactive3DDecorator не позволяют перемещать. Я собираюсь проверить, проводят ли они события раньше.