Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
IldusEps committed Jun 4, 2021
2 parents 7d0fa64 + a56eca9 commit 5420b02
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 14 deletions.
45 changes: 36 additions & 9 deletions src/3d/castlecameras.pas
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,12 @@ TCastleOrthographic = class(TComponent)
FOrigin: TVector2;
FWidth, FHeight, FScale: Single;
FEffectiveWidth, FEffectiveHeight: Single;
FStretch: Boolean;
procedure SetOrigin(const Value: TVector2);
procedure SetWidth(const Value: Single);
procedure SetHeight(const Value: Single);
procedure SetScale(const Value: Single);
procedure SetStretch(const Value: Boolean);
private
Camera: TCastleCamera;
public
Expand Down Expand Up @@ -222,17 +224,27 @@ TCastleOrthographic = class(TComponent)
of the viewport control.
)
@item(When both @link(Width) and @link(Height) are non-zero,
then they explicitly determine the @italic(minimum)
projection width and height along the given axis.
This, again, allows to easily display the same piece of the game world,
@item(When both @link(Width) and @link(Height) are non-zero, then
they determine the projection width and height.
This also allows to easily display the same piece of the game world,
regardless of the viewport size.
If the displayed viewport aspect ratio wil be different than given
@link(Width) and @link(Height) ratio, then these value will be
treated as minimum values, and they will be adjusted.
This follows the X3D OrthoViewpoint.fieldOfView specification.
@unorderedList(
@item(When @link(Stretch) = @false (default), they determine the @italic(minimum)
projection width and height along the given axis.
If the displayed viewport aspect ratio wil be different than given
@link(Width) and @link(Height) ratio, then these value will be
treated as minimum values, and they will be adjusted.
This follows the X3D OrthoViewpoint.fieldOfView specification.)
@item(When @link(Stretch) = @true, these values are used directly,
even if it means that aspect ratio of the projection
will not reflect the aspect ratio of the viewport on screen.
This allows for some tricks, like @italic(Military Projection),
https://github.com/castle-engine/castle-engine/issues/290 .)
)
)
)
Expand All @@ -257,6 +269,12 @@ TCastleOrthographic = class(TComponent)
the middle of the viewport. }
property Scale: Single read FScale write SetScale default 1;

{ Allow non-proportional stretch of projection.
In effect the @link(Width) and @link(Height)
(if both non-zero) are applied directly, without correcting them to follow
aspect ratio of the viewport. }
property Stretch: Boolean read FStretch write SetStretch default false;

{$define read_interface_class}
{$I auto_generated_persistent_vectors/tcastleorthographic_persistent_vectors.inc}
{$undef read_interface_class}
Expand Down Expand Up @@ -2320,6 +2338,15 @@ procedure TCastleOrthographic.SetScale(const Value: Single);
end;
end;

procedure TCastleOrthographic.SetStretch(const Value: Boolean);
begin
if FStretch <> Value then
begin
FStretch := Value;
Camera.VisibleChange;
end;
end;

procedure TCastleOrthographic.InternalSetEffectiveSize(const W, H: Single);
begin
FEffectiveWidth := W;
Expand Down
1 change: 1 addition & 0 deletions src/x3d/castlescenecore.pas
Original file line number Diff line number Diff line change
Expand Up @@ -7565,6 +7565,7 @@ procedure TCastleSceneCore.InternalUpdateCamera(const ACamera: TCastleCamera;
ACamera.Orthographic.Width := 0;
ACamera.Orthographic.Height := 0;
ACamera.Orthographic.Origin := TVector2.Zero;
ACamera.Orthographic.Stretch := false;

ViewpointNode := ViewpointStack.Top;
NavigationNode := NavigationInfoStack.Top;
Expand Down
6 changes: 5 additions & 1 deletion src/x3d/castleshapes.pas
Original file line number Diff line number Diff line change
Expand Up @@ -1243,7 +1243,11 @@ procedure TShapeTree.UnAssociateNode(const Node: TX3DNode);
begin
if Node.InternalSceneShape = nil then
begin
WritelnWarning('Calling %s.UnAssociateNode on X3D node that is already not associated with anything: %s. This can happen when you manually change nodes.',
{ TODO: Document when it may happen, seems this situation is just valid,
and it occurs easily with primitives like TCastleBox
if you change TCastleAbstractPrimitive.Material type.
For now change warning -> log. }
WritelnLog('Calling %s.UnAssociateNode on X3D node that is already not associated with anything: %s. This can happen when you manually change nodes.',
[ClassName, Node.NiceName]);
Exit;
end;
Expand Down
9 changes: 5 additions & 4 deletions src/x3d/opengl/castleviewport.pas
Original file line number Diff line number Diff line change
Expand Up @@ -2031,10 +2031,11 @@ function TCastleViewport.CalculateProjection: TProjection;

CalculateDimensions;

Result.Dimensions := TOrthoViewpointNode.InternalFieldOfView(
Result.Dimensions,
Viewport.Width,
Viewport.Height);
if not Camera.Orthographic.Stretch then
Result.Dimensions := TOrthoViewpointNode.InternalFieldOfView(
Result.Dimensions,
Viewport.Width,
Viewport.Height);

EffectiveProjectionWidth := Result.Dimensions.Width;
EffectiveProjectionHeight := Result.Dimensions.Height;
Expand Down

0 comments on commit 5420b02

Please sign in to comment.