2

我在 FireMonkey 3D 中搜索相机旋转和缩放的示例。就像使用鼠标左键围绕场景旋转相机并使用鼠标滚轮放大和缩小一样。

有谁能够帮我?

4

2 回答 2

1

下面的表格显示了一个简单的演示,只需保存 .fmx 和 .pas 文件并将表格添加到 FMX 应用程序。关键部分是将相机和嵌套的灯光对象放在单独的 X 和 Y 轴上,以作为相机目标的 DummyObject。将 X 和 Y 作为单独的虚拟对象使旋转垂直和水平,这在某些情况下是可取的。您还可以将 DummyX 和 DummyY 对象合并为单个 DummyXY 对象,这将提供更真实的世界旋转样式,但取决于您的需要,哪个更可取。

MainForm.pas:

unit MainForm;

interface

uses
  FMX.Forms, FMX.Materials, System.Math.Vectors, FMX.Types3D, FMX.Objects3D, FMX.Controls3D, FMX.Viewport3D,
  System.Classes, FMX.Types, FMX.Controls, FMX.Layouts, FMX.MaterialSources, System.Types, System.UITypes;

type

  TForm1 = class(TForm)
    Viewport3D: TViewport3D;
    DummyX: TDummy;
    DummyObject: TDummy;
    CameraZ: TCamera;
    Light1: TLight;
    LayoutMain: TLayout;
    DummyY: TDummy;
    Cone1: TCone;
    LightMaterialSource1: TLightMaterialSource;
    procedure Viewport3DMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
    procedure Viewport3DMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single);
    procedure Viewport3DMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; var Handled: Boolean);
  private
    FDown: TPointF;
    procedure DoZoom(aIn: Boolean);
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

const
  CAMERA_MAX_Z = -2;
  CAMERA_MIN_Z = -200;
  ZOOM_STEP = 2;

procedure TForm1.DoZoom(aIn: Boolean);
var
  newZ: Single;
begin
  if aIn then
    newZ := CameraZ.Position.Z + ZOOM_STEP
  else
    newZ := CameraZ.Position.Z - ZOOM_STEP;

  if (newZ < CAMERA_MAX_Z) and (newZ > CAMERA_MIN_Z) then
    CameraZ.Position.Z := newZ;
end;

procedure TForm1.Viewport3DMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
begin
  FDown := PointF(X, Y);
end;

procedure TForm1.Viewport3DMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Single);
begin
  if (ssLeft in Shift) then
  begin
    DummyX.RotationAngle.X := DummyX.RotationAngle.X - ((Y - FDown.Y) * 0.3);
    DummyY.RotationAngle.Y := DummyY.RotationAngle.Y + ((X - FDown.X) * 0.3);
    FDown := PointF(X, Y);
  end;
end;

procedure TForm1.Viewport3DMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; var Handled: Boolean);
begin
  DoZoom(WheelDelta > 0);
end;

end.

MainForm.fmx:

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 592
  ClientWidth = 713
  FormFactor.Width = 320
  FormFactor.Height = 480
  FormFactor.Devices = [Desktop]
  DesignerMasterStyle = 0
  object LayoutMain: TLayout
    Align = Client
    Size.Width = 713.000000000000000000
    Size.Height = 592.000000000000000000
    Size.PlatformDefault = False
    TabOrder = 2
    object Viewport3D: TViewport3D
      Align = Client
      Camera = CameraZ
      Size.Width = 713.000000000000000000
      Size.Height = 592.000000000000000000
      Size.PlatformDefault = False
      UsingDesignCamera = False
      OnMouseDown = Viewport3DMouseDown
      OnMouseMove = Viewport3DMouseMove
      OnMouseWheel = Viewport3DMouseWheel
      object DummyX: TDummy
        Width = 1.000000000000000000
        Height = 1.000000000000000000
        Depth = 1.000000000000000000
        object DummyY: TDummy
          Width = 1.000000000000000000
          Height = 1.000000000000000000
          Depth = 1.000000000000000000
          object CameraZ: TCamera
            AngleOfView = 45.000000000000000000
            Target = DummyObject
            Position.Z = -20.000000000000000000
            Width = 1.000000000000000000
            Height = 1.000000000000000000
            Depth = 1.000000000000000000
            object Light1: TLight
              Color = claWhite
              LightType = Directional
              SpotCutOff = 180.000000000000000000
              Width = 1.000000000000000000
              Height = 1.000000000000000000
              Depth = 1.000000000000000000
            end
          end
        end
      end
      object DummyObject: TDummy
        Width = 1.000000000000000000
        Height = 1.000000000000000000
        Depth = 1.000000000000000000
        object Cone1: TCone
          Width = 1.000000000000000000
          Height = 1.000000000000000000
          Depth = 1.000000000000000000
          SubdivisionsCap = 3
          MaterialSource = LightMaterialSource1
        end
      end
    end
  end
  object LightMaterialSource1: TLightMaterialSource
    Diffuse = claWhite
    Ambient = xFF202020
    Emissive = claNull
    Specular = xFF606060
    Shininess = 30
    Left = 436
    Top = 56
  end
end

我从某个地方的演示中提取了这个,但非常适合我的需求。应该适用于 Delphi XE5 及更高版本。

于 2016-04-04T22:56:36.650 回答
-2

您可以通过拖动旋转相机并使用滚轮进行缩放。重要的是,不同轴上的旋转都应该在不同的嵌套对象上处理,以便旋转计算应该像我们在现实世界中所期望的那样相互影响。

于 2012-11-20T12:59:50.013 回答