Class TCastleNavigation

Unit

Declaration

type TCastleNavigation = class(TCastleUserInterface)

Description

Handle user input to modify viewport's camera.

Once you create an instance of this class (create non-abstract descendants like TCastleExamineNavigation, TCastleWalkNavigation, TCastleThirdPersonNavigation) just and add it as TCastleViewport child. The navigation will automatically affect the current camera of parent viewport.

In many ways, this is just a normal TCastleUserInterface descendant. E.g. it processes input just like any other TCastleUserInterface descendant (there isn't any special mechanism through which TCastleViewport passes input to the navigation), the Exists property works and so on.

Note that you don't really need to use any TCastleNavigation to manipulate the camera. You can just access TCastleViewport.Camera from anywhere (like TUIState code) and move, rotate it as you wish. TCastleNavigation is just a comfortable way to encapsulate some navigation methods, but it's not the only way to manipulate the camera.

Various TCastleNavigation descendants implement various navigation methods, for example TCastleExamineNavigation allows the user to rotate and scale the model (imagine that you're holding a 3D model in your hands and you look at it from various sides) and TCastleWalkNavigation implements typical navigation in the style of first-person shooter games.

Hierarchy

Overview

Fields

Protected MouseDraggingStarted: Integer;
Protected MouseDraggingStart: TVector2;
Public nested const DefaultRadius = 0.25;
Public nested const DefaultPreferredHeight = 1.6;
Public nested const DefaultInput = [niNormal, niMouseDragging, ni3dMouse, niGesture];
Public nested const DefaultHeadBobbingTime = 0.5;
Public nested const DefaultHeadBobbing = 0.02;
Public nested const DefaultCrouchHeight = 0.5;

Methods

Protected function GoodModelBox: TBox3D;
Protected function InternalViewport: TCastleUserInterface;
Protected function Valid: Boolean;
Protected function UsingInput: TNavigationInputs;
Protected function ReallyEnableMouseDragging: boolean; virtual;
Protected procedure Height(const APosition: TVector3; out AIsAbove: Boolean; out AnAboveHeight: Single; out AnAboveGround: PTriangle);
Protected function MoveAllowed( const OldPos: TVector3; ProposedNewPos: TVector3; out NewPos: TVector3; const BecauseOfGravity, CheckClimbHeight: Boolean): Boolean; virtual;
Protected function MoveTo(const LocalProposedNewPos: TVector3; const BecauseOfGravity, CheckClimbHeight: boolean): boolean;
Protected function Move(const MoveVector: TVector3; const BecauseOfGravity, CheckClimbHeight: boolean): boolean;
Protected function Zoom(const Factor: Single): Boolean; virtual;
Public constructor Create(AOwner: TComponent); override;
Public procedure Assign(Source: TPersistent); override;
Public function PropertySections(const PropertyName: String): TPropertySections; override;
Public function Camera: TCastleCamera;
Public procedure Ray(const WindowPosition: TVector2; const Projection: TProjection; out RayOrigin, RayDirection: TVector3); deprecated 'use Viewport.Camera.CustomRay with proper viewport sizes, or use higher-level utilities like Viewport.MouseRayHit instead';
Public procedure MouseRay( const Projection: TProjection; out RayOrigin, RayDirection: TVector3); deprecated 'use Viewport.Camera.CustomRay with proper viewport sizes, or use higher-level utilities like Viewport.MouseRayHit instead';
Public procedure CustomRay( const ViewportRect: TRectangle; const WindowPosition: TVector2; const Projection: TProjection; out RayOrigin, RayDirection: TVector3); overload; deprecated 'use Viewport.Camera.CustomRay';
Public procedure CustomRay( const ViewportRect: TFloatRectangle; const WindowPosition: TVector2; const Projection: TProjection; out RayOrigin, RayDirection: TVector3); overload; deprecated 'use Viewport.Camera.CustomRay';
Public function Press(const Event: TInputPressRelease): boolean; override;
Public function Release(const Event: TInputPressRelease): boolean; override;
Public procedure AnimateTo(const OtherCamera: TCastleCamera; const Time: TFloatTime); overload; deprecated 'use Viewport.Camera.AnimateTo';
Public procedure AnimateTo(const OtherNavigation: TCastleNavigation; const Time: TFloatTime); overload; deprecated 'use AnimateTo with TCastleCamera, not TCastleNavigation';
Public procedure AnimateTo(const APos, ADir, AUp: TVector3; const Time: TFloatTime); overload; deprecated 'use Viewport.Camera.AnimateTo';
Public function Animation: boolean; deprecated 'use Viewport.Camera.Animation';

Properties

Public property OnMoveAllowed: TMoveAllowedFunc read FOnMoveAllowed write FOnMoveAllowed;
Public property OnFall: TFallNotifyFunc read FOnFall write FOnFall;
Public property IgnoreAllInputs: boolean read GetIgnoreAllInputs write SetIgnoreAllInputs default false; deprecated;
Public property Radius: Single read FRadius write FRadius default DefaultRadius;
Public property ModelBox: TBox3D read FModelBox write FModelBox;
Public property Input: TNavigationInputs read FInput write FInput default DefaultInput;
Public property Input_ZoomIn: TInputShortcut read FInput_ZoomIn;
Public property Input_ZoomOut: TInputShortcut read FInput_ZoomOut;
Published property FullSize default true;
Published property ZoomEnabled: Boolean read FZoomEnabled write FZoomEnabled default false;
Published property CheckCollisions: Boolean read FCheckCollisions write FCheckCollisions default true;

Description

Fields

Protected MouseDraggingStarted: Integer;

Needed for niMouseDragging navigation. Checking MouseDraggingStarted means that we handle only dragging that was initialized on viewport (since the viewport passed events to navigation). MouseDraggingStarted -1 means none, otherwise it's the finder index (to support multitouch).

Protected MouseDraggingStart: TVector2;

This item has no description.

Public nested const DefaultRadius = 0.25;

Default value for TCastleNavigation.Radius. Matches the default VRML/X3D NavigationInfo.avatarSize[0].

Public nested const DefaultPreferredHeight = 1.6;

Default value for TCastleNavigation.PreferredHeight. Matches the default VRML/X3D NavigationInfo.avatarSize[1].

Public nested const DefaultInput = [niNormal, niMouseDragging, ni3dMouse, niGesture];

This item has no description.

Public nested const DefaultHeadBobbingTime = 0.5;

This item has no description.

Public nested const DefaultHeadBobbing = 0.02;

This item has no description.

Public nested const DefaultCrouchHeight = 0.5;

This item has no description.

Methods

Protected function GoodModelBox: TBox3D;

This item has no description.

Protected function InternalViewport: TCastleUserInterface;

Viewport we should manipulate. This is Nil, or TCastleViewport instance, but it cannot be declared as TCastleViewport due to unit dependencies.

Protected function Valid: Boolean;

If this is True, then Camera is non-nil, InternalViewport is non-nil, and navigation should function as usual.

Protected function UsingInput: TNavigationInputs;

Behave as if Input is like this. This allows to disable input when not Valid.

Protected function ReallyEnableMouseDragging: boolean; virtual;

Can we use mouse dragging. Checks UsingInput and so Valid already.

Protected procedure Height(const APosition: TVector3; out AIsAbove: Boolean; out AnAboveHeight: Single; out AnAboveGround: PTriangle);

Check collisions to determine how high above ground is given point (in world coordinates). Checks collisions through parent TCastleViewport, if CheckCollisions.

Protected function MoveAllowed( const OldPos: TVector3; ProposedNewPos: TVector3; out NewPos: TVector3; const BecauseOfGravity, CheckClimbHeight: Boolean): Boolean; virtual;

Check collisions to determine can the object move. Object wants to move from OldPos to ProposedNewPos (in world coordinates).

Returns False if no move is allowed. Otherwise returns True and sets NewPos to the position where user should be moved.

If you're doing a simple check for collisions, you will always want to set NewPos to ProposedNewPos when returning True.

But you can also do more sophisticated calculations and sometimes not allow user to move to ProposedNewPos, but allow him to move instead to some other close position. For example when doing "wall sliding" (common in FPS games): when you're trying to walk "into the wall", you move along the wall instead.

It's allowed to modify NewPos when returning False. It makes no effect.

BecauseOfGravity says whether this move is caused by gravity dragging the player down. You can use BecauseOfGravity e.g. to implement TCastleViewport.PreventInfiniteFallingDown.

Implementation calls OnMoveAllowed and checks collisions through parent TCastleViewport, if CheckCollisions.

Protected function MoveTo(const LocalProposedNewPos: TVector3; const BecauseOfGravity, CheckClimbHeight: boolean): boolean;

Like Move, but you pass here final ProposedNewPos.

LocalProposedNewPos is given in TCastleCamera parent coordinates, so it works naturally in the same space as TCastleCamera.Translation, Direction, Up. You can think "I want to move to Translation + MoveVector".

Protected function Move(const MoveVector: TVector3; const BecauseOfGravity, CheckClimbHeight: boolean): boolean;

Try to move from current Translation to Translation + MoveVector. Checks MoveAllowed, also (if CheckClimbHeight is True) checks the ClimbHeight limit.

MoveVector is given in TCastleCamera parent coordinates, so it works naturally in the same space as TCastleCamera.Translation, Direction, Up. You can think "I want to move TCastleCamera to Translation + MoveVector".

Returns False if move was not possible and Position didn't change. Returns True is some move occured (but don't assume too much: possibly we didn't move to exactly Position + MoveVector because of wall sliding).

Protected function Zoom(const Factor: Single): Boolean; virtual;

Zoom in / out. Negative Factor makes "zoom out", positive makes "zoom in" (zero makes nothing).

Called only if ZoomEnabled, so no need to check it within implementation.

Factor values correspond to TInputPressRelease.MouseWheelScroll values, so 1.0 should be treated like a "one operation" and some systems only generate values -1 or +1 (and never fractions).

Public constructor Create(AOwner: TComponent); override;

This item has no description.

Public procedure Assign(Source: TPersistent); override;

This item has no description.

Public function PropertySections(const PropertyName: String): TPropertySections; override;

This item has no description. Showing description inherited from TCastleComponent.PropertySections.

Section where to show property in the editor.

Public function Camera: TCastleCamera;

Associated TCastleCamera of the viewport. May return Nil if the viewport camera is not assigned.

Exceptions raised
EViewportNotAssigned
If Viewport not assigned yet.
Public procedure Ray(const WindowPosition: TVector2; const Projection: TProjection; out RayOrigin, RayDirection: TVector3); deprecated 'use Viewport.Camera.CustomRay with proper viewport sizes, or use higher-level utilities like Viewport.MouseRayHit instead';

Warning: this symbol is deprecated: use Viewport.Camera.CustomRay with proper viewport sizes, or use higher-level utilities like Viewport.MouseRayHit instead

Calculate a 3D ray picked by the WindowX, WindowY position on the window.

Uses current container size, which means that it assumes that viewport fills the whole container. The navigation, as well as the parent viewport, must be part of some container UI hierarchy for this to work.

Projection (read-only here) describe your projection, required for calculating the ray properly. Resulting RayDirection is always normalized.

WindowPosition is given in the same style as TCastleContainer.MousePosition: (0, 0) is bottom-left.

Public procedure MouseRay( const Projection: TProjection; out RayOrigin, RayDirection: TVector3); deprecated 'use Viewport.Camera.CustomRay with proper viewport sizes, or use higher-level utilities like Viewport.MouseRayHit instead';

Warning: this symbol is deprecated: use Viewport.Camera.CustomRay with proper viewport sizes, or use higher-level utilities like Viewport.MouseRayHit instead

Calculate a ray picked by current mouse position on the window.

Uses current container size, which means that it assumes that viewport fills the whole container. The navigation, as well as the parent viewport, must be part of some container UI hierarchy for this to work.

See also
Ray
Calculate a 3D ray picked by the WindowX, WindowY position on the window.
CustomRay
Public procedure CustomRay( const ViewportRect: TRectangle; const WindowPosition: TVector2; const Projection: TProjection; out RayOrigin, RayDirection: TVector3); overload; deprecated 'use Viewport.Camera.CustomRay';

Warning: this symbol is deprecated: use Viewport.Camera.CustomRay

Calculate a ray picked by WindowPosition position on the viewport, assuming current viewport dimensions are as given. This doesn't look at our container sizes at all.

Projection (read-only here) describe projection, required for calculating the ray properly.

Resulting RayDirection is always normalized.

WindowPosition is given in the same style as TCastleContainer.MousePosition: (0, 0) is bottom-left.

Public procedure CustomRay( const ViewportRect: TFloatRectangle; const WindowPosition: TVector2; const Projection: TProjection; out RayOrigin, RayDirection: TVector3); overload; deprecated 'use Viewport.Camera.CustomRay';

Warning: this symbol is deprecated: use Viewport.Camera.CustomRay

This item has no description.

Public function Press(const Event: TInputPressRelease): boolean; override;

This item has no description. Showing description inherited from TCastleUserInterface.Press.

Handle press or release of a key, mouse button or mouse wheel. Return True if the event was somehow handled, which prevents from passing this event to other UI controls.

When implementing in descendants it is best to override it like this:

function TMyControl.Press(const Event: TInputPressRelease): boolean;
begin
  Result := inherited;
  if Result then Exit; // exit if ancestor already handled event

  if Event.IsKey(keyEnter) then
  begin
    // do something in reaction on Enter
    Exit(ExclusiveEvents); // ExclusiveEvents is true by default
  end;

  if Event.IsMouseButton(buttonLeft) then
  begin
    // do something in reaction on Enter
    Exit(ExclusiveEvents); // ExclusiveEvents is true by default
  end;
end;

Note that releasing of the mouse wheel is not reported now by any backend. Only releasing of keys and mouse buttons is reported.

The events PreviewPress and PreviewRelease are passed first to the parent control, before children have a chance to process this event. Overriding them makes sense if you draw something in TCastleUserInterface.RenderOverChildren.

The events Press and Release are passed to the parent only after the children had a chance to process this event. Overriding them makes sense if you draw something in TCastleUserInterface.Render. This is usually more natural, and adviced.

Public function Release(const Event: TInputPressRelease): boolean; override;

This item has no description.

Public procedure AnimateTo(const OtherCamera: TCastleCamera; const Time: TFloatTime); overload; deprecated 'use Viewport.Camera.AnimateTo';

Warning: this symbol is deprecated: use Viewport.Camera.AnimateTo

This item has no description.

Public procedure AnimateTo(const OtherNavigation: TCastleNavigation; const Time: TFloatTime); overload; deprecated 'use AnimateTo with TCastleCamera, not TCastleNavigation';

Warning: this symbol is deprecated: use AnimateTo with TCastleCamera, not TCastleNavigation

This item has no description.

Public procedure AnimateTo(const APos, ADir, AUp: TVector3; const Time: TFloatTime); overload; deprecated 'use Viewport.Camera.AnimateTo';

Warning: this symbol is deprecated: use Viewport.Camera.AnimateTo

This item has no description.

Public function Animation: boolean; deprecated 'use Viewport.Camera.Animation';

Warning: this symbol is deprecated: use Viewport.Camera.Animation

This item has no description.

Properties

Public property OnMoveAllowed: TMoveAllowedFunc read FOnMoveAllowed write FOnMoveAllowed;

Used by MoveAllowed, see there for description. You can assign this property.

Public property OnFall: TFallNotifyFunc read FOnFall write FOnFall;

Notification that we have been falling down for some time due to gravity, and suddenly stopped (which means we "hit the ground").

This event can be useful in games, for example to lower player's health, and/or make a visual effect (like a "red out" indicating pain) and/or make a sound effect ("Ouch!" or "Thud!" or such sounds). You can look at FallHeight parameter, given to the callback, e.g. to gauge how much health decreases.

Public property IgnoreAllInputs: boolean read GetIgnoreAllInputs write SetIgnoreAllInputs default false; deprecated;

Warning: this symbol is deprecated.

Deprecated, use more flexible Input instead. IgnoreAllInputs := true is equivalent to Input := [], IgnoreAllInputs := false is equivalent to Input := DefaultInput.

Public property Radius: Single read FRadius write FRadius default DefaultRadius;

The radius of a sphere around the camera that makes collisions with the world.

  • Collision detection routines use this.

  • It determines the projection near plane (that must be slightly smaller than this radius), see also TCastleCamera.ProjectionNear.

  • Walk navigation uses this for automatically correcting PreferredHeight, otherwise weird things could happen if your avatar height is too small compared to the camera radius. See CorrectPreferredHeight.

    Especially useful if you let user change PreferredHeight at runtime by Input_IncreasePreferredHeight, Input_DecreasePreferredHeight.

Public property ModelBox: TBox3D read FModelBox write FModelBox;

Approximate size of the world that is viewed. Determines the speed of zooming and (in case of TCastleExamineNavigation) of many other operations too. Initially this is an empty box. Internally we will use the Viewport.Items.BoundingBox if this is empty.

Public property Input: TNavigationInputs read FInput write FInput default DefaultInput;

Input methods available to user. See documentation of TNavigationInput type for possible values and their meaning.

To disable any user interaction with this navigation you can simply set this to empty.

Public property Input_ZoomIn: TInputShortcut read FInput_ZoomIn;

Bring camera closer to the model. Works only if ZoomEnabled. By deafult mwUp (mouse wheel up).

Public property Input_ZoomOut: TInputShortcut read FInput_ZoomOut;

Bring camera further from the model. Works only if ZoomEnabled. By deafult mwDown (mouse wheel down).

Published property FullSize default true;

By default this captures events from whole parent, which should be whole Viewport.

Published property ZoomEnabled: Boolean read FZoomEnabled write FZoomEnabled default false;

Enable zooming in / out. Depending on the projection, zooming either moves camera or scales the projection size. When False, no keys / mouse dragging / 3d mouse etc. can make a zoom. If True, at least mouse wheel makes a zoom (som,e navigation methods may have additional ways to make zoom, they will all honor this property.)

Published property CheckCollisions: Boolean read FCheckCollisions write FCheckCollisions default true;

Check collisions when moving with the environment.

Note: some descendants may ignore it for some operations. Right now, TCastleWalkNavigation checks is always, but TCastleExamineNavigation checks it only at zooming. But future engine versions may harden the collision checks (to make them always), so be sure to set CheckCollisions appropriately.


Generated by PasDoc 0.16.0.