Embarcadero FireMonkey 3D相机旋转和缩放

时间:2012-08-29 16:21:26

标签: delphi firemonkey

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

有人能帮助我吗?

2 个答案:

答案 0 :(得分: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及以上版本。

答案 1 :(得分:-2)

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