WPF 3D - 如何保存和加载相机视图?

发布于 2024-08-13 02:32:27 字数 698 浏览 2 评论 0原文

我有一个 WPF 3D 场景,可以使用 3DTools 中的 TrackballDecorator 进行平移、旋转和缩放库。我想保存相机设置(转换),并能够在应用程序下次重新启动时重新应用它们(以便恢复视图)。

我尝试保存 Camera 的每个单独值:

private void SaveCameraSettings()
{
  var d = Properties.Settings.Default;
  d.CameraPositionX = camera.Position.X;
  d.CameraPositionY = camera.Position.Y;
  ...
  d.Save();
}

我猜这是行不通的,因为这些设置不会根据应用于相机的转换进行更新(我总是获取 xaml 中设置的初始值) )。

我检查了 Transformation3D 类,但找不到任何方法来设置其值...

问题是我需要从 PerspectiveCamera 获取什么值,以便能够将其恢复为关闭应用程序时的状态最后一次。将相机设置为默认位置(在 Xaml 中),然后由 TrackBallDecorator 将变换应用到该相机。如何保存此转换(要存储哪些值)?我以后如何重新应用它们?

I have a WPF 3D scene where I can pan, rotate and zoom using the TrackballDecorator from the 3DTools library. I would like to save the camera settings (transformation) and be able to re-apply them when the application restarts the next time (so the view is restored).

I tried to save each individual value of the Camera:

private void SaveCameraSettings()
{
  var d = Properties.Settings.Default;
  d.CameraPositionX = camera.Position.X;
  d.CameraPositionY = camera.Position.Y;
  ...
  d.Save();
}

This doesn't work, I guess because those settings are not updated according to the transformations applied to the camera (I always get the initial values set in xaml).

I checked the the Transformation3D class but couldn't find any way to set its value...

The problem is what values do I need to get from the PerspectiveCamera in order to be able to restore it the way it was when I closed my application the last time. The camera is set to a default position (in Xaml), then a transformation is applied to this camera by the TrackBallDecorator. How can I save this transformation (what values to store)? And how can I re-apply them at a later time?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

余生再见 2024-08-20 02:32:27

这会有点长,所以请耐心等待...

第一,您需要修改 3DTools 库,以便可以将转换应用到 TrackballDecorator,如下所示:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Media3D;
using System.Windows.Input;

namespace _3DTools
{
  public class TrackballDecorator : Viewport3DDecorator
  {

    #region Private Members

    private Point m_PreviousPosition2D;
    private Vector3D m_PreviousPosition3D = new Vector3D(0, 0, 1);

    private Transform3DGroup m_Transform;
    private ScaleTransform3D m_Scale = new ScaleTransform3D();
    private AxisAngleRotation3D m_Rotation = new AxisAngleRotation3D();
    private TranslateTransform3D m_Translate = new TranslateTransform3D();

    private readonly Border m_EventSource;

    #endregion

    #region Constructor

    public TrackballDecorator()
    {
      TranslateScale = 10;
      ZoomScale = 1;
      RotateScale = 1;
      // the transform that will be applied to the viewport 3d's camera
      m_Transform = new Transform3DGroup();
      m_Transform.Children.Add(m_Scale);
      m_Transform.Children.Add(new RotateTransform3D(m_Rotation));
      m_Transform.Children.Add(m_Translate);

      // used so that we always get events while activity occurs within
      // the viewport3D
      m_EventSource = new Border { Background = Brushes.Transparent };

      PreViewportChildren.Add(m_EventSource);
    }

    #endregion

    #region Properties

    /// <summary>
    /// A transform to move the camera or scene to the trackball's
    /// current orientation and scale.
    /// </summary>
    public Transform3DGroup Transform
    {
      get { return m_Transform; }
      set
      {
        m_Transform = value;
        m_Scale = m_Transform.GetScaleTransform3D();
        m_Translate = m_Transform.GetTranslateTransform3D();
        m_Rotation = m_Transform.GetRotateTransform3D().Rotation as AxisAngleRotation3D;
        ApplyTransform();
      }
    }

    public double TranslateScale { get; set; }

    public double RotateScale { get; set; }

    public double ZoomScale { get; set; }

    #endregion

    #region Event Handling

    protected override void OnMouseDown(MouseButtonEventArgs e)
    {
      base.OnMouseDown(e);

      m_PreviousPosition2D = e.GetPosition(this);
      m_PreviousPosition3D = ProjectToTrackball(ActualWidth,
                                               ActualHeight,
                                               m_PreviousPosition2D);
      if (Mouse.Captured == null)
      {
        Mouse.Capture(this, CaptureMode.Element);
      }
    }

    protected override void OnMouseUp(MouseButtonEventArgs e)
    {
      base.OnMouseUp(e);

      if (IsMouseCaptured)
      {
        Mouse.Capture(this, CaptureMode.None);
      }
    }

    protected override void OnMouseMove(MouseEventArgs e)
    {
      base.OnMouseMove(e);

      if (IsMouseCaptured)
      {
        Point currentPosition = e.GetPosition(this);

        // avoid any zero axis conditions
        if (currentPosition == m_PreviousPosition2D) return;

        // Prefer tracking to zooming if both buttons are pressed.
        if (e.LeftButton == MouseButtonState.Pressed)
        {
          Track(currentPosition);
        }
        else if (e.RightButton == MouseButtonState.Pressed)
        {
          Zoom(currentPosition);
        }
        else if (e.MiddleButton == MouseButtonState.Pressed)
        {
          Translate(currentPosition);
        }

        m_PreviousPosition2D = currentPosition;

        ApplyTransform();
      }
    }

    private void ApplyTransform()
    {
      Viewport3D viewport3D = Viewport3D;
      if (viewport3D != null)
      {
        if (viewport3D.Camera != null)
        {
          if (viewport3D.Camera.IsFrozen)
          {
            viewport3D.Camera = viewport3D.Camera.Clone();
          }

          if (viewport3D.Camera.Transform != m_Transform)
          {
            viewport3D.Camera.Transform = m_Transform;
          }
        }
      }
    }

    #endregion Event Handling

    private void Track(Point currentPosition)
    {
      var currentPosition3D = ProjectToTrackball(ActualWidth, ActualHeight, currentPosition);

      var axis = Vector3D.CrossProduct(m_PreviousPosition3D, currentPosition3D);
      var angle = Vector3D.AngleBetween(m_PreviousPosition3D, currentPosition3D);

      // quaterion will throw if this happens - sometimes we can get 3D positions that
      // are very similar, so we avoid the throw by doing this check and just ignoring
      // the event 
      if (axis.Length == 0) return;

      var delta = new Quaternion(axis, -angle);

      // Get the current orientantion from the RotateTransform3D
      var r = m_Rotation;
      var q = new Quaternion(m_Rotation.Axis, m_Rotation.Angle);

      // Compose the delta with the previous orientation
      q *= delta;

      // Write the new orientation back to the Rotation3D
      m_Rotation.Axis = q.Axis;
      m_Rotation.Angle = q.Angle;

      m_PreviousPosition3D = currentPosition3D;
    }

    private static Vector3D ProjectToTrackball(double width, double height, Point point)
    {
      var x = point.X / (width / 2);    // Scale so bounds map to [0,0] - [2,2]
      var y = point.Y / (height / 2);

      x = x - 1;                           // Translate 0,0 to the center
      y = 1 - y;                           // Flip so +Y is up instead of down

      var z2 = 1 - x * x - y * y;       // z^2 = 1 - x^2 - y^2
      var z = z2 > 0 ? Math.Sqrt(z2) : 0;

      return new Vector3D(x, y, z);
    }

    private void Zoom(Point currentPosition)
    {
      var yDelta = currentPosition.Y - m_PreviousPosition2D.Y;

      var scale = Math.Exp(yDelta / 100) / ZoomScale;    // e^(yDelta/100) is fairly arbitrary.

      m_Scale.ScaleX *= scale;
      m_Scale.ScaleY *= scale;
      m_Scale.ScaleZ *= scale;
    }

    private void Translate(Point currentPosition)
    {
      // Calculate the panning vector from screen(the vector component of the Quaternion
      // the division of the X and Y components scales the vector to the mouse movement
      var qV = new Quaternion(((m_PreviousPosition2D.X - currentPosition.X) / TranslateScale),
      ((currentPosition.Y - m_PreviousPosition2D.Y) / TranslateScale), 0, 0);

      // Get the current orientantion from the RotateTransform3D
      var q = new Quaternion(m_Rotation.Axis, m_Rotation.Angle);
      var qC = q;
      qC.Conjugate();

      // Here we rotate our panning vector about the the rotaion axis of any current rotation transform
      // and then sum the new translation with any exisiting translation
      qV = q * qV * qC;
      m_Translate.OffsetX += qV.X;
      m_Translate.OffsetY += qV.Y;
      m_Translate.OffsetZ += qV.Z;
    }

  }

}

GetXXXTransform3D方法是扩展方法,定义如下:

public static ScaleTransform3D GetScaleTransform3D(this Transform3DGroup transform3DGroup)
{
  ScaleTransform3D scaleTransform3D = null;
  if (transform3DGroup != null)
  {
    foreach (var transform in transform3DGroup.Children)
    {
      scaleTransform3D = transform as ScaleTransform3D;
      if (scaleTransform3D != null) return scaleTransform3D;
    }
  }
  return scaleTransform3D;
}

public static RotateTransform3D GetRotateTransform3D(this Transform3DGroup transform3DGroup)
{
  RotateTransform3D rotateTransform3D = null;
  if (transform3DGroup != null)
  {
    foreach (var transform in transform3DGroup.Children)
    {
      rotateTransform3D = transform as RotateTransform3D;
      if (rotateTransform3D != null) return rotateTransform3D;
    }
  }
  return rotateTransform3D;
}

public static TranslateTransform3D GetTranslateTransform3D(this Transform3DGroup transform3DGroup)
{
  TranslateTransform3D translateTransform3D = null;
  if (transform3DGroup != null)
  {
    foreach (var transform in transform3DGroup.Children)
    {
      translateTransform3D = transform as TranslateTransform3D;
      if (translateTransform3D != null) return translateTransform3D;
    }
  }
  return translateTransform3D;
}

第二,您需要为您的PerspectiveCamera声明一个Transform如下:
(该示例取自 Sasha Barber 的 Elements3D 我用来测试这个的项目)

<Tools:TrackballDecorator x:Name="tbViewPort">

  <Viewport3D x:Name="vpFeeds">

    <Viewport3D.Camera>
      <PerspectiveCamera x:Name="camera" Position="-2,2,40" LookDirection="2,-2,-40" FieldOfView="90">
        <PerspectiveCamera.Transform>
          <Transform3DGroup />
        </PerspectiveCamera.Transform>
      </PerspectiveCamera>
    </Viewport3D.Camera>

    <ContainerUIElement3D x:Name="container" />

    <ModelVisual3D x:Name="model">
      <ModelVisual3D.Content>
        <DirectionalLight Color="White" Direction="-1,-1,-1" />
      </ModelVisual3D.Content>
    </ModelVisual3D>

  </Viewport3D>
</Tools:TrackballDecorator>

第三,因为我们要将整个转换的每个部分存储在一个单独的值中,所以您需要在设置文件中创建相关属性,即 CameraScaleXCameraScaleYCameraScaleZCameraTranslateXCameraTranslateYCameraTranslateZ >、CameraRotateAxisXCameraRotateAxisYCameraRotateAxisZCameraRotateAngle。所有的都是double类型并且存储在用户范围内。

第四步也是最后一步是使用以下代码实际保存这些设置并将其加载到相机中:

private void SaveCameraSettings()
{
  var transform3DGroup = camera.Transform as Transform3DGroup;
  if (transform3DGroup != null)
  {
    foreach (var transform in transform3DGroup.Children)
    {
      var scale = transform as ScaleTransform3D;
      if (scale != null) SaveCameraSetting(scale);
      var rotate = transform as RotateTransform3D;
      if (rotate != null) SaveCameraSetting(rotate);
      var translate = transform as TranslateTransform3D;
      if (translate != null) SaveCameraSetting(translate);
    }
    Settings.Default.Save();
  }
}

private static void SaveCameraSetting(ScaleTransform3D transform)
{
  Properties.Settings.Default.CameraScaleX = transform.ScaleX;
  Properties.Settings.Default.CameraScaleY = transform.ScaleY;
  Properties.Settings.Default.CameraScaleZ = transform.ScaleZ;
}

private static void SaveCameraSetting(RotateTransform3D transform)
{
  var axisAngleRotation3D = transform.Rotation as AxisAngleRotation3D;
  if (axisAngleRotation3D != null)
  {
    Properties.Settings.Default.CameraRotateAxisX = axisAngleRotation3D.Axis.X;
    Properties.Settings.Default.CameraRotateAxisY = axisAngleRotation3D.Axis.Y;
    Properties.Settings.Default.CameraRotateAxisZ = axisAngleRotation3D.Axis.Z;
    Properties.Settings.Default.CameraRotateAngle = axisAngleRotation3D.Angle;
  }
}

private static void SaveCameraSetting(TranslateTransform3D transform)
{
  Properties.Settings.Default.CameraTranslateX = transform.OffsetX;
  Properties.Settings.Default.CameraTranslateY = transform.OffsetY;
  Properties.Settings.Default.CameraTranslateZ = transform.OffsetZ;
}

private void LoadCameraPosition()
{
  var d = Settings.Default;

  var transform3DGroup = new Transform3DGroup();

  var scaleTransform3D = new ScaleTransform3D(d.CameraScaleX, d.CameraScaleY, d.CameraScaleZ);
  var translateTransform3D = new TranslateTransform3D(d.CameraTranslateX, d.CameraTranslateY, d.CameraTranslateZ);
  var axisAngleRotation3D = new AxisAngleRotation3D(new Vector3D(d.CameraRotateAxisX, d.CameraRotateAxisY, d.CameraRotateAxisZ),
                                                    d.CameraRotateAngle);
  var rotateTransform3D = new RotateTransform3D(axisAngleRotation3D);

  transform3DGroup.Children.Add(scaleTransform3D);
  transform3DGroup.Children.Add(translateTransform3D);
  transform3DGroup.Children.Add(rotateTransform3D);

  tbViewPort.Transform = transform3DGroup;
}

希望我没有忘记任何事情。如果您需要更多帮助或有不明白的地方,请随时询问;-)

This is going to be a bit long, so bear with me...

1st, you need to modify the 3DTools library so you can apply a transformation to the TrackballDecorator as follow:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Media3D;
using System.Windows.Input;

namespace _3DTools
{
  public class TrackballDecorator : Viewport3DDecorator
  {

    #region Private Members

    private Point m_PreviousPosition2D;
    private Vector3D m_PreviousPosition3D = new Vector3D(0, 0, 1);

    private Transform3DGroup m_Transform;
    private ScaleTransform3D m_Scale = new ScaleTransform3D();
    private AxisAngleRotation3D m_Rotation = new AxisAngleRotation3D();
    private TranslateTransform3D m_Translate = new TranslateTransform3D();

    private readonly Border m_EventSource;

    #endregion

    #region Constructor

    public TrackballDecorator()
    {
      TranslateScale = 10;
      ZoomScale = 1;
      RotateScale = 1;
      // the transform that will be applied to the viewport 3d's camera
      m_Transform = new Transform3DGroup();
      m_Transform.Children.Add(m_Scale);
      m_Transform.Children.Add(new RotateTransform3D(m_Rotation));
      m_Transform.Children.Add(m_Translate);

      // used so that we always get events while activity occurs within
      // the viewport3D
      m_EventSource = new Border { Background = Brushes.Transparent };

      PreViewportChildren.Add(m_EventSource);
    }

    #endregion

    #region Properties

    /// <summary>
    /// A transform to move the camera or scene to the trackball's
    /// current orientation and scale.
    /// </summary>
    public Transform3DGroup Transform
    {
      get { return m_Transform; }
      set
      {
        m_Transform = value;
        m_Scale = m_Transform.GetScaleTransform3D();
        m_Translate = m_Transform.GetTranslateTransform3D();
        m_Rotation = m_Transform.GetRotateTransform3D().Rotation as AxisAngleRotation3D;
        ApplyTransform();
      }
    }

    public double TranslateScale { get; set; }

    public double RotateScale { get; set; }

    public double ZoomScale { get; set; }

    #endregion

    #region Event Handling

    protected override void OnMouseDown(MouseButtonEventArgs e)
    {
      base.OnMouseDown(e);

      m_PreviousPosition2D = e.GetPosition(this);
      m_PreviousPosition3D = ProjectToTrackball(ActualWidth,
                                               ActualHeight,
                                               m_PreviousPosition2D);
      if (Mouse.Captured == null)
      {
        Mouse.Capture(this, CaptureMode.Element);
      }
    }

    protected override void OnMouseUp(MouseButtonEventArgs e)
    {
      base.OnMouseUp(e);

      if (IsMouseCaptured)
      {
        Mouse.Capture(this, CaptureMode.None);
      }
    }

    protected override void OnMouseMove(MouseEventArgs e)
    {
      base.OnMouseMove(e);

      if (IsMouseCaptured)
      {
        Point currentPosition = e.GetPosition(this);

        // avoid any zero axis conditions
        if (currentPosition == m_PreviousPosition2D) return;

        // Prefer tracking to zooming if both buttons are pressed.
        if (e.LeftButton == MouseButtonState.Pressed)
        {
          Track(currentPosition);
        }
        else if (e.RightButton == MouseButtonState.Pressed)
        {
          Zoom(currentPosition);
        }
        else if (e.MiddleButton == MouseButtonState.Pressed)
        {
          Translate(currentPosition);
        }

        m_PreviousPosition2D = currentPosition;

        ApplyTransform();
      }
    }

    private void ApplyTransform()
    {
      Viewport3D viewport3D = Viewport3D;
      if (viewport3D != null)
      {
        if (viewport3D.Camera != null)
        {
          if (viewport3D.Camera.IsFrozen)
          {
            viewport3D.Camera = viewport3D.Camera.Clone();
          }

          if (viewport3D.Camera.Transform != m_Transform)
          {
            viewport3D.Camera.Transform = m_Transform;
          }
        }
      }
    }

    #endregion Event Handling

    private void Track(Point currentPosition)
    {
      var currentPosition3D = ProjectToTrackball(ActualWidth, ActualHeight, currentPosition);

      var axis = Vector3D.CrossProduct(m_PreviousPosition3D, currentPosition3D);
      var angle = Vector3D.AngleBetween(m_PreviousPosition3D, currentPosition3D);

      // quaterion will throw if this happens - sometimes we can get 3D positions that
      // are very similar, so we avoid the throw by doing this check and just ignoring
      // the event 
      if (axis.Length == 0) return;

      var delta = new Quaternion(axis, -angle);

      // Get the current orientantion from the RotateTransform3D
      var r = m_Rotation;
      var q = new Quaternion(m_Rotation.Axis, m_Rotation.Angle);

      // Compose the delta with the previous orientation
      q *= delta;

      // Write the new orientation back to the Rotation3D
      m_Rotation.Axis = q.Axis;
      m_Rotation.Angle = q.Angle;

      m_PreviousPosition3D = currentPosition3D;
    }

    private static Vector3D ProjectToTrackball(double width, double height, Point point)
    {
      var x = point.X / (width / 2);    // Scale so bounds map to [0,0] - [2,2]
      var y = point.Y / (height / 2);

      x = x - 1;                           // Translate 0,0 to the center
      y = 1 - y;                           // Flip so +Y is up instead of down

      var z2 = 1 - x * x - y * y;       // z^2 = 1 - x^2 - y^2
      var z = z2 > 0 ? Math.Sqrt(z2) : 0;

      return new Vector3D(x, y, z);
    }

    private void Zoom(Point currentPosition)
    {
      var yDelta = currentPosition.Y - m_PreviousPosition2D.Y;

      var scale = Math.Exp(yDelta / 100) / ZoomScale;    // e^(yDelta/100) is fairly arbitrary.

      m_Scale.ScaleX *= scale;
      m_Scale.ScaleY *= scale;
      m_Scale.ScaleZ *= scale;
    }

    private void Translate(Point currentPosition)
    {
      // Calculate the panning vector from screen(the vector component of the Quaternion
      // the division of the X and Y components scales the vector to the mouse movement
      var qV = new Quaternion(((m_PreviousPosition2D.X - currentPosition.X) / TranslateScale),
      ((currentPosition.Y - m_PreviousPosition2D.Y) / TranslateScale), 0, 0);

      // Get the current orientantion from the RotateTransform3D
      var q = new Quaternion(m_Rotation.Axis, m_Rotation.Angle);
      var qC = q;
      qC.Conjugate();

      // Here we rotate our panning vector about the the rotaion axis of any current rotation transform
      // and then sum the new translation with any exisiting translation
      qV = q * qV * qC;
      m_Translate.OffsetX += qV.X;
      m_Translate.OffsetY += qV.Y;
      m_Translate.OffsetZ += qV.Z;
    }

  }

}

The GetXXXTransform3D methods are extension methods defined as follow:

public static ScaleTransform3D GetScaleTransform3D(this Transform3DGroup transform3DGroup)
{
  ScaleTransform3D scaleTransform3D = null;
  if (transform3DGroup != null)
  {
    foreach (var transform in transform3DGroup.Children)
    {
      scaleTransform3D = transform as ScaleTransform3D;
      if (scaleTransform3D != null) return scaleTransform3D;
    }
  }
  return scaleTransform3D;
}

public static RotateTransform3D GetRotateTransform3D(this Transform3DGroup transform3DGroup)
{
  RotateTransform3D rotateTransform3D = null;
  if (transform3DGroup != null)
  {
    foreach (var transform in transform3DGroup.Children)
    {
      rotateTransform3D = transform as RotateTransform3D;
      if (rotateTransform3D != null) return rotateTransform3D;
    }
  }
  return rotateTransform3D;
}

public static TranslateTransform3D GetTranslateTransform3D(this Transform3DGroup transform3DGroup)
{
  TranslateTransform3D translateTransform3D = null;
  if (transform3DGroup != null)
  {
    foreach (var transform in transform3DGroup.Children)
    {
      translateTransform3D = transform as TranslateTransform3D;
      if (translateTransform3D != null) return translateTransform3D;
    }
  }
  return translateTransform3D;
}

2nd, you need to declare a Transform to your PerspectiveCamera as follow:
(the example is taken from Sasha Barber's Elements3D project which I used to test this)

<Tools:TrackballDecorator x:Name="tbViewPort">

  <Viewport3D x:Name="vpFeeds">

    <Viewport3D.Camera>
      <PerspectiveCamera x:Name="camera" Position="-2,2,40" LookDirection="2,-2,-40" FieldOfView="90">
        <PerspectiveCamera.Transform>
          <Transform3DGroup />
        </PerspectiveCamera.Transform>
      </PerspectiveCamera>
    </Viewport3D.Camera>

    <ContainerUIElement3D x:Name="container" />

    <ModelVisual3D x:Name="model">
      <ModelVisual3D.Content>
        <DirectionalLight Color="White" Direction="-1,-1,-1" />
      </ModelVisual3D.Content>
    </ModelVisual3D>

  </Viewport3D>
</Tools:TrackballDecorator>

3rd, since we are going to store each part of the whole transformation in a separate value, you need to create the relevant properties in your settings file, i.e. CameraScaleX, CameraScaleY, CameraScaleZ, CameraTranslateX, CameraTranslateY, CameraTranslateZ, CameraRotateAxisX, CameraRotateAxisY, CameraRotateAxisZ and CameraRotateAngle. All are of type double and are stored in User scope.

4th and last step is to actually save and load these settings into the camera using the following code:

private void SaveCameraSettings()
{
  var transform3DGroup = camera.Transform as Transform3DGroup;
  if (transform3DGroup != null)
  {
    foreach (var transform in transform3DGroup.Children)
    {
      var scale = transform as ScaleTransform3D;
      if (scale != null) SaveCameraSetting(scale);
      var rotate = transform as RotateTransform3D;
      if (rotate != null) SaveCameraSetting(rotate);
      var translate = transform as TranslateTransform3D;
      if (translate != null) SaveCameraSetting(translate);
    }
    Settings.Default.Save();
  }
}

private static void SaveCameraSetting(ScaleTransform3D transform)
{
  Properties.Settings.Default.CameraScaleX = transform.ScaleX;
  Properties.Settings.Default.CameraScaleY = transform.ScaleY;
  Properties.Settings.Default.CameraScaleZ = transform.ScaleZ;
}

private static void SaveCameraSetting(RotateTransform3D transform)
{
  var axisAngleRotation3D = transform.Rotation as AxisAngleRotation3D;
  if (axisAngleRotation3D != null)
  {
    Properties.Settings.Default.CameraRotateAxisX = axisAngleRotation3D.Axis.X;
    Properties.Settings.Default.CameraRotateAxisY = axisAngleRotation3D.Axis.Y;
    Properties.Settings.Default.CameraRotateAxisZ = axisAngleRotation3D.Axis.Z;
    Properties.Settings.Default.CameraRotateAngle = axisAngleRotation3D.Angle;
  }
}

private static void SaveCameraSetting(TranslateTransform3D transform)
{
  Properties.Settings.Default.CameraTranslateX = transform.OffsetX;
  Properties.Settings.Default.CameraTranslateY = transform.OffsetY;
  Properties.Settings.Default.CameraTranslateZ = transform.OffsetZ;
}

private void LoadCameraPosition()
{
  var d = Settings.Default;

  var transform3DGroup = new Transform3DGroup();

  var scaleTransform3D = new ScaleTransform3D(d.CameraScaleX, d.CameraScaleY, d.CameraScaleZ);
  var translateTransform3D = new TranslateTransform3D(d.CameraTranslateX, d.CameraTranslateY, d.CameraTranslateZ);
  var axisAngleRotation3D = new AxisAngleRotation3D(new Vector3D(d.CameraRotateAxisX, d.CameraRotateAxisY, d.CameraRotateAxisZ),
                                                    d.CameraRotateAngle);
  var rotateTransform3D = new RotateTransform3D(axisAngleRotation3D);

  transform3DGroup.Children.Add(scaleTransform3D);
  transform3DGroup.Children.Add(translateTransform3D);
  transform3DGroup.Children.Add(rotateTransform3D);

  tbViewPort.Transform = transform3DGroup;
}

Hopefully, I didn't forget anything. If you need more help or don't understand something, please don't hesitate to ask ;-)

起风了 2024-08-20 02:32:27

您将需要相机视图矩阵数据和投影矩阵数据。视图矩阵将包含有关相机的位置、旋转、缩放和平移的数据,投影矩阵将包含视场、近平面、远平面等数据。

抱歉,我无法帮助导出/导入该数据,因为我没有使用过 WPF,但如果它使用与 as3 内置 Matrix 类有关的任何内容,则可能会暴露原始数据属性,这通常是一个 as3 Vector。对象将矩阵 16 值公开为行排序浮点值。

You would need both the cameras view matrix data and the projection matrix data. The view matrix will contain the data about the position, rotation, scale and translation of the camera and the projection matrix will contain things like the field of view, near plane, far plane and other data.

Sorry I cant help with exporting/importing that data since I've not used WPF, but there might be rawdata properties exposed if it uses anything to do with as3's built in Matrix classes, this is usualy a as3 Vector. Object the the matrices 16 values exposed as row ordered floating point values.

心碎的声音 2024-08-20 02:32:27

我相信你需要的是Position、LookDirection、UpDirection、FieldOfView、NearPlaneDistance、FarPlaneDistance。所有上述属性都定义了相机。

I believe what you need is Position, LookDirection, UpDirection, FieldOfView, NearPlaneDistance, FarPlaneDistance. All the above properties define the camera.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文