Skip to content

Commit

Permalink
Camera and Navigation are split into 2 properties and 2 classes
Browse files Browse the repository at this point in the history
Camera holds the viewer position/dir/up.
It is automatically created with each viewport.

Navigation reacts to user input, changing camera.
It may be, but doesn't have to be, assigned to a viewport.
It's more-or-less a normal TCastleUserInterface descendant.
  • Loading branch information
michaliskambi committed Jul 20, 2019
1 parent 7371573 commit fcc2985
Show file tree
Hide file tree
Showing 10 changed files with 1,489 additions and 1,230 deletions.
1,977 changes: 1,094 additions & 883 deletions src/3d/castlecameras.pas

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions src/3d/castletransform.pas
Expand Up @@ -1009,7 +1009,7 @@ TCastleTransform = class(TCastleComponent)
{ Main camera observing this 3D object changed. { Main camera observing this 3D object changed.
This is usually called by our container (like TCastleSceneManager) This is usually called by our container (like TCastleSceneManager)
to notify that camera changed. } to notify that camera changed. }
procedure CameraChanged(ACamera: TCamera); virtual; procedure CameraChanged(const ACamera: TCastleCamera); virtual;


{ Mouse cursor over this object. } { Mouse cursor over this object. }
property Cursor: TMouseCursor read FCursor write SetCursor default mcDefault; property Cursor: TMouseCursor read FCursor write SetCursor default mcDefault;
Expand Down Expand Up @@ -1864,7 +1864,7 @@ TSceneManagerWorld = class(TCastleTransform)
property CameraKnown: boolean read FCameraKnown; property CameraKnown: boolean read FCameraKnown;
{ @groupEnd } { @groupEnd }


procedure CameraChanged(ACamera: TCamera); override; procedure CameraChanged(const ACamera: TCastleCamera); override;


{ Yoo can temporarily disable physics (no transformations will be updated { Yoo can temporarily disable physics (no transformations will be updated
by the physics engine) by setting this property to @false. } by the physics engine) by setting this property to @false. }
Expand Down Expand Up @@ -2605,7 +2605,7 @@ procedure TCastleTransform.VisibleChangeNotification(const Changes: TVisibleChan
List[I].VisibleChangeNotification(Changes); List[I].VisibleChangeNotification(Changes);
end; end;


procedure TCastleTransform.CameraChanged(ACamera: TCamera); procedure TCastleTransform.CameraChanged(const ACamera: TCastleCamera);
var var
I: Integer; I: Integer;
begin begin
Expand Down Expand Up @@ -3393,7 +3393,7 @@ function TSceneManagerWorld.WorldPointCollision2D(const Point: TVector2): boolea
Result := PointCollision2D(Point, nil); Result := PointCollision2D(Point, nil);
end; end;


procedure TSceneManagerWorld.CameraChanged(ACamera: TCamera); procedure TSceneManagerWorld.CameraChanged(const ACamera: TCastleCamera);
begin begin
ACamera.GetView(FCameraPosition, FCameraDirection, FCameraUp); ACamera.GetView(FCameraPosition, FCameraDirection, FCameraUp);
FCameraKnown := true; FCameraKnown := true;
Expand Down
8 changes: 4 additions & 4 deletions src/3d/castletransform_renderparams.inc
Expand Up @@ -90,7 +90,7 @@
This is interesting to you only if you write custom rendering code. This is interesting to you only if you write custom rendering code.
In normal applications, you shoud only get/set camera using TCamera In normal applications, you shoud only get/set camera using TCastleCamera
descendants, through TCastleAbstractViewport.Camera and related properties. descendants, through TCastleAbstractViewport.Camera and related properties.
Do not use the TRenderingCamera class in normal applications. } Do not use the TRenderingCamera class in normal applications. }
TRenderingCamera = class TRenderingCamera = class
Expand Down Expand Up @@ -147,11 +147,11 @@
function RotationMatrix3: TMatrix3; function RotationMatrix3: TMatrix3;
function RotationInverseMatrix3: TMatrix3; function RotationInverseMatrix3: TMatrix3;


{ Set all properties (except Target) from TCamera instance in ACamera. { Set all properties (except Target) from TCastleCamera instance in ACamera.
See @link(FromMatrix) for comments about @link(Target) property. See @link(FromMatrix) for comments about @link(Target) property.
The IgnoredViewpoint parameter is only for backward compatibility, The IgnoredViewpoint parameter is only for backward compatibility,
it is ignored. } it is ignored. }
procedure FromCameraObject(const ACamera: TCamera; procedure FromCameraObject(const ACamera: TCastleCamera;
const IgnoredViewpoint: TObject = nil); const IgnoredViewpoint: TObject = nil);


{ Set all properties (except Target) from explict matrices. { Set all properties (except Target) from explict matrices.
Expand Down Expand Up @@ -290,7 +290,7 @@ begin
Move(RotationInverseMatrix.Data[2], Result.Data[2], SizeOf(Single) * 3); Move(RotationInverseMatrix.Data[2], Result.Data[2], SizeOf(Single) * 3);
end; end;


procedure TRenderingCamera.FromCameraObject(const ACamera: TCamera; procedure TRenderingCamera.FromCameraObject(const ACamera: TCastleCamera;
const IgnoredViewpoint: TObject = nil); const IgnoredViewpoint: TObject = nil);
begin begin
Matrix := ACamera.Matrix; Matrix := ACamera.Matrix;
Expand Down
28 changes: 14 additions & 14 deletions src/game/castle2dscenemanager.pas
Expand Up @@ -83,7 +83,7 @@ TCastle2DSceneManager = class(TCastleSceneManager)
DefaultCameraZ = DefaultProjectionSpan / 2; DefaultCameraZ = DefaultProjectionSpan / 2;


constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
procedure AssignDefaultCamera; override; procedure AssignDefaultNavigation; override;


property CurrentProjectionWidth: Single read FCurrentProjectionWidth; property CurrentProjectionWidth: Single read FCurrentProjectionWidth;
property CurrentProjectionHeight: Single read FCurrentProjectionHeight; property CurrentProjectionHeight: Single read FCurrentProjectionHeight;
Expand Down Expand Up @@ -221,24 +221,24 @@ constructor TCastle2DSceneManager.Create(AOwner: TComponent);
FProjectionWidth := 0; FProjectionWidth := 0;


{ Make camera already existing, so WalkCamera returns it, { Make camera already existing, so WalkCamera returns it,
instead of using AssignDefaultCamera and then switching to ntWalk. } instead of using AssignDefaultNavigation and then switching to ntWalk. }
AssignDefaultCamera; AssignDefaultNavigation;
end; end;


procedure TCastle2DSceneManager.AssignDefaultCamera; procedure TCastle2DSceneManager.AssignDefaultNavigation;
begin begin
{ Set Camera explicitly, otherwise SetNavigationType below could call { Set Camera explicitly, otherwise SetNavigationType below could call
ExamineCamera / WalkCamera that call AssignDefaultCamera when Camera = nil, ExamineCamera / WalkCamera that call AssignDefaultNavigation when Camera = nil,
and we would have infinite AssignDefaultCamera calls loop. } and we would have infinite AssignDefaultNavigation calls loop. }
Camera := InternalWalkCamera; Navigation := InternalWalkNavigation;


NavigationType := ntNone; NavigationType := ntNone;
Camera.SetInitialView( Navigation.SetInitialView(
{ pos } Vector3(0, 0, DefaultCameraZ), { pos } Vector3(0, 0, DefaultCameraZ),
{ dir } Vector3(0, 0, -1), { dir } Vector3(0, 0, -1),
{ up } Vector3(0, 1, 0), false); { up } Vector3(0, 1, 0), false);
Camera.GoToInitial; Navigation.GoToInitial;
Camera.Radius := 0.01; { will not be used for anything, but set to something sensible just in case } Navigation.Radius := 0.01; { will not be used for anything, but set to something sensible just in case }
end; end;


function TCastle2DSceneManager.PositionTo2DWorld(const Position: TVector2; function TCastle2DSceneManager.PositionTo2DWorld(const Position: TVector2;
Expand All @@ -262,8 +262,8 @@ function TCastle2DSceneManager.PositionTo2DWorld(const Position: TVector2;
raise Exception.Create('TCastle2DSceneManager.PositionTo2DWorld assumes an orthographic projection, like the one set by TCastle2DSceneManager.CalculateProjection'); raise Exception.Create('TCastle2DSceneManager.PositionTo2DWorld assumes an orthographic projection, like the one set by TCastle2DSceneManager.CalculateProjection');
ProjRect := Proj.Dimensions; ProjRect := Proj.Dimensions;
if Camera <> nil then if Navigation <> nil then
ProjRect := ProjRect.Translate(Camera.Position.XY); ProjRect := ProjRect.Translate(Navigation.Position.XY);
Result := Vector2( Result := Vector2(
MapRange(P.X, 0, EffectiveWidth , ProjRect.Left , ProjRect.Right), MapRange(P.X, 0, EffectiveWidth , ProjRect.Left , ProjRect.Right),
Expand All @@ -285,7 +285,7 @@ function TCastle2DSceneManager.PositionTo2DWorld(const Position: TVector2;
P := Position * UIScale + RenderRect.LeftBottom P := Position * UIScale + RenderRect.LeftBottom
else else
P := Position; P := Position;
RequiredCamera.CustomRay(RenderRect, P, Projection, RayOrigin, RayDirection); RequiredNavigation.CustomRay(RenderRect, P, Projection, RayOrigin, RayDirection);
Result := RayOrigin.XY; Result := RayOrigin.XY;
end; } end; }


Expand All @@ -300,7 +300,7 @@ function TCastle2DSceneManager.PositionTo2DWorld(const Position: TVector2;
ScreenToWorldMatrix: TMatrix4; ScreenToWorldMatrix: TMatrix4;
P: TVector2; P: TVector2;
begin begin
WorldToScreenMatrix := RequiredCamera.ProjectionMatrix * RequiredCamera.Matrix; WorldToScreenMatrix := RequiredNavigation.ProjectionMatrix * RequiredNavigation.Matrix;
if not WorldToScreenMatrix.TryInverse(ScreenToWorldMatrix) then if not WorldToScreenMatrix.TryInverse(ScreenToWorldMatrix) then
raise Exception.Create('Cannot invert projection * camera matrix. Possibly one of them was not initialized, or camera contains scale to zero.'); raise Exception.Create('Cannot invert projection * camera matrix. Possibly one of them was not initialized, or camera contains scale to zero.');
Expand Down
4 changes: 2 additions & 2 deletions src/game/castlelevels.pas
Expand Up @@ -841,7 +841,7 @@ procedure TGameSceneManager.LoadLevelCore(const AInfo: TLevelInfo);
WalkCamera.MoveVerticalSpeed := 20; WalkCamera.MoveVerticalSpeed := 20;
end; end;


Camera := WalkCamera; Navigation := WalkCamera;


WalkCamera.Init(InitialPosition, InitialDirection, WalkCamera.Init(InitialPosition, InitialDirection,
InitialUp, GravityUp, PreferredHeight, CameraRadius); InitialUp, GravityUp, PreferredHeight, CameraRadius);
Expand Down Expand Up @@ -875,7 +875,7 @@ procedure TGameSceneManager.LoadLevelCore(const AInfo: TLevelInfo);
Otherwise, it would be updated by MainScene loading binding new Otherwise, it would be updated by MainScene loading binding new
NavigationInfo (with it's speed) and Viewpoint. NavigationInfo (with it's speed) and Viewpoint.
We prefer to do it ourselves in InitializeCamera. } We prefer to do it ourselves in InitializeCamera. }
Camera := nil; Navigation := nil;


MainScene := TCastleScene.Create(Self); MainScene := TCastleScene.Create(Self);
Inc(MainScene.InternalDirty); Inc(MainScene.InternalDirty);
Expand Down

0 comments on commit fcc2985

Please sign in to comment.