Castle Game Engine: CastleSceneManager: Class TCastleSceneManager

# Class TCastleSceneManager
Description | Hierarchy | Fields | Methods | Properties
## Unit CastleSceneManager ## Declaration `type TCastleSceneManager = class(TCastleAbstractViewport)` ## Description Scene manager that knows about all 3D things inside your world. Single scenes/models (like TCastleScene or TCastlePrecalculatedAnimation instances) can be rendered directly, but it's not always comfortable. Scenes have to assume that they are "one of the many" inside your 3D world, which means that multi-pass rendering techniques have to be implemented at a higher level. This concerns the need for multiple passes from the same camera (for shadow volumes) and multiple passes from different cameras (for generating textures for shadow maps, cube map environment etc.). Scene manager overcomes this limitation. A single SceneManager object knows about all 3D things in your world, and renders them all for you, taking care of doing multiple rendering passes for particular features. Naturally, it also serves as container for all your visible 3D scenes. Items property keeps a tree of T3D objects. All our 3D objects, like TCastleSceneCore (and so also TCastleScene) and TCastlePrecalculatedAnimationCore (and so also TCastlePrecalculatedAnimation) descend from T3D, and you can add them to the scene manager. And naturally you can implement your own T3D descendants, representing any 3D (possibly dynamic, animated and even interactive) object. TCastleSceneManager.Render can assume that it's the only manager rendering to the screen (although you can safely render more 3D geometry *after* calling TCastleSceneManager.Render). So it's Render method takes care of clearing the screen, rendering the background of the scene, rendering the headlight, rendering the scene from given camera, and making multiple passes for shadow volumes and generated textures. For some of these features, you'll have to set the MainScene property. This is a TUIControl descendant, which means it's advised usage is to add this to TCastleWindowCustom.Controls or TCastleControlCustom.Controls. This passes relevant TUIControl events to all the T3D objects inside. Note that even when you set DefaultViewport = `False` (and use custom viewports, by TCastleViewport class, to render your 3D world), you still should add scene manager to the controls list (this allows e.g. 3D items to receive Update events). ## Hierarchy TComponent TInputListener TUIControl TUIRectangularControl TCastleAbstractViewport TCastleSceneManager ## Overview ### Fields
| `FSectors: TSectorList;`
| `Waypoints: TWaypointList;`
### Methods
| `procedure SetCamera(const Value: TCamera); override;`
| `function CollisionIgnoreItem(const Sender: TObject; const Triangle: P3DTriangle): boolean; virtual;`
| `procedure Notification(AComponent: TComponent; Operation: TOperation); override;`
| `function CameraMoveAllowed(ACamera: TWalkCamera; const ProposedNewPos: TVector3Single; out NewPos: TVector3Single; const BecauseOfGravity: boolean): boolean; override;`
| `function CameraHeight(ACamera: TWalkCamera; const Position: TVector3Single; out AboveHeight: Single; out AboveGround: P3DTriangle): boolean; override;`
| `function CameraRayCollision(const RayOrigin, RayDirection: TVector3Single): TRayCollision; override;`
| `procedure CameraVisibleChange(ACamera: TObject); override;`
| `function GetItems: T3DWorld; override;`
| `function GetMainScene: TCastleScene; override;`
| `function GetShadowVolumeRenderer: TGLShadowVolumeRenderer; override;`
| `function GetMouseRayHit: TRayCollision; override;`
| `function GetHeadlightCamera: TCamera; override;`
| `function GetPlayer: TPlayer; override;`
| `function GetTimeScale: Single; override;`
| `function PointingDeviceActivate(const Active: boolean): boolean; override;`
| `function PointingDeviceMove(const RayOrigin, RayDirection: TVector3Single): boolean; override;`
| `procedure PointingDeviceActivateFailed(const Active: boolean); virtual;`
| `function PointingDeviceActivate3D(const Item: T3D; const Active: boolean; const Distance: Single): boolean; virtual;`
| `function MoveAllowed(const OldPosition, NewPosition: TVector3Single; const BecauseOfGravity: boolean): boolean; virtual;`
| `procedure BoundNavigationInfoChanged; virtual;`
| `procedure BoundViewpointChanged; virtual;`
| `function Headlight: TAbstractLightNode; override;`
| `constructor Create(AOwner: TComponent); override;`
| `destructor Destroy; override;`
| `procedure GLContextOpen; override;`
| `procedure GLContextClose; override;`
| `function PositionInside(const Position: TVector2Single): boolean; override;`
| `procedure PrepareResources(const DisplayProgressTitle: string = ''); virtual;`
| `procedure BeforeRender; override;`
| `procedure Render; override;`
| `function CameraToChanges: TVisibleChanges; virtual;`
| `procedure Update(const SecondsPassed: Single; var HandleInput: boolean); override;`
| `function CreateDefaultCamera(AOwner: TComponent): TCamera; override;`
| `function GravityUp: TVector3Single;`
### Properties
| `property MoveLimit: TBox3D read FMoveLimit write FMoveLimit;`
| `property ShadowVolumeRenderer: TGLShadowVolumeRenderer read FShadowVolumeRenderer;`
| `property MouseRayHit: TRayCollision read FMouseRayHit;`
| `property Viewports: TCastleAbstractViewportList read FViewports;`
| `property Sectors: TSectorList read FSectors;`
| `property Water: TBox3D read FWater write FWater;`
| `property TimeScale: Single read FTimeScale write FTimeScale default 1;`
| `property Items: T3DWorld read FItems;`
| `property MainScene: TCastleScene read FMainScene write SetMainScene;`
| `property OnCameraChanged: TNotifyEvent read FOnCameraChanged write FOnCameraChanged;`
| `property OnBoundViewpointChanged: TNotifyEvent read FOnBoundViewpointChanged write FOnBoundViewpointChanged;`
| `property OnBoundNavigationInfoChanged: TNotifyEvent read FOnBoundNavigationInfoChanged write FOnBoundNavigationInfoChanged;`
| `property DefaultViewport: boolean read FDefaultViewport write SetDefaultViewport default true;`
| `property Player: TPlayer read FPlayer write SetPlayer;`
| `property OnMoveAllowed: TWorldMoveAllowedEvent read FOnMoveAllowed write FOnMoveAllowed;`
## Description ### Fields
| `FSectors: TSectorList;`
| `Waypoints: TWaypointList;`
### Methods
| `procedure SetCamera(const Value: TCamera); override;`
| `function CollisionIgnoreItem(const Sender: TObject; const Triangle: P3DTriangle): boolean; virtual;`
Triangles to ignore by all collision detection in scene manager. The default implementation in this class resturns always `False`, so nothing is ignored. You can override it e.g. to ignore your "water" material, when you want player to dive under the water.
| `procedure Notification(AComponent: TComponent; Operation: TOperation); override;`
| `function CameraMoveAllowed(ACamera: TWalkCamera; const ProposedNewPos: TVector3Single; out NewPos: TVector3Single; const BecauseOfGravity: boolean): boolean; override;`
| `function CameraHeight(ACamera: TWalkCamera; const Position: TVector3Single; out AboveHeight: Single; out AboveGround: P3DTriangle): boolean; override;`
| `function CameraRayCollision(const RayOrigin, RayDirection: TVector3Single): TRayCollision; override;`
| `procedure CameraVisibleChange(ACamera: TObject); override;`
| `function GetItems: T3DWorld; override;`
| `function GetMainScene: TCastleScene; override;`
| `function GetShadowVolumeRenderer: TGLShadowVolumeRenderer; override;`
| `function GetMouseRayHit: TRayCollision; override;`
| `function GetHeadlightCamera: TCamera; override;`
| `function GetPlayer: TPlayer; override;`
| `function GetTimeScale: Single; override;`
| `function PointingDeviceActivate(const Active: boolean): boolean; override;`
| `function PointingDeviceMove(const RayOrigin, RayDirection: TVector3Single): boolean; override;`
| `procedure PointingDeviceActivateFailed(const Active: boolean); virtual;`
Called when PointingDeviceActivate was not handled by any 3D object. You can override this to make a message / sound signal to notify user that his Input_Interact click was not successful.
| `function PointingDeviceActivate3D(const Item: T3D; const Active: boolean; const Distance: Single): boolean; virtual;`
Handle pointing device (mouse) activation/deactivation event over a given 3D object. See T3D.PointingDeviceActivate method for description how it should be handled. Default implementation in TCastleSceneManager just calls T3D.PointingDeviceActivate.
| `function MoveAllowed(const OldPosition, NewPosition: TVector3Single; const BecauseOfGravity: boolean): boolean; virtual;`
Handle OnMoveAllowed and default MoveLimit algorithm. See the description of OnMoveAllowed property for information. When this is called, collision detection determined that this move is allowed. The default implementation in TCastleSceneManager calculates the result using the algorithm described at the MoveLimit property, then calls OnMoveAllowed event.
| `procedure BoundNavigationInfoChanged; virtual;`
| `procedure BoundViewpointChanged; virtual;`
| `function Headlight: TAbstractLightNode; override;`
| `constructor Create(AOwner: TComponent); override;`
| `destructor Destroy; override;`
| `procedure GLContextOpen; override;`
| `procedure GLContextClose; override;`
| `function PositionInside(const Position: TVector2Single): boolean; override;`
| `procedure PrepareResources(const DisplayProgressTitle: string = ''); virtual;`
Prepare resources, to make various methods (like Render) execute fast. If DisplayProgressTitle <> '', we will display progress bar during loading. This is especially useful for long precalculated animations (TCastlePrecalculatedAnimation with a lot of ScenesCount), they show nice linearly increasing progress bar.
| `procedure BeforeRender; override;`
| `procedure Render; override;`
| `function CameraToChanges: TVisibleChanges; virtual;`
What changes happen when camera changes. You may want to use it when calling Scene.CameraChanged. Implementation in this class is correlated with RenderHeadlight.
| `procedure Update(const SecondsPassed: Single; var HandleInput: boolean); override;`
| `function CreateDefaultCamera(AOwner: TComponent): TCamera; override;`
| `function GravityUp: TVector3Single;`
Up vector, according to gravity. Gravity force pulls in -`GravityUp` direction.
### Properties
| `property MoveLimit: TBox3D read FMoveLimit write FMoveLimit;`
Where the 3D items (player, creatures, items) can move, and where the gravity works. In case of 1st-person view (always, for now) limiting the player position also implies limiting the camera position. Intuitively, this is the "sensible" part of 3D space where normal physics should work. TODO: When you activate 3rd-person camera (not implemented yet), this limit will apply to the Player.Position, not Camera.Position. When `MoveLimit` is an empty box (this is the default situation) then movement is limited to not fall because of gravity outside of Items.BoundingBox. Still, we can freely move anywhere (only gravity effect is limited to the Items.BoundingBox). This is the safest behavior for general 3D model browsers, it prevents camera from falling into an infinite abyss of our 3D space, since gravity will always stop at the Items.BoundingBox border. When `MoveLimit` is not an empty box, then position cannot go outside of this box. Note that the TGameSceneManager.LoadLevel always, automatically, assigns this property to be non-empty. It's either determined by CasMoveLimit placeholder in the level 3D model, or it's automatically calculated to include level bounding box + some space for flying.
| `property ShadowVolumeRenderer: TGLShadowVolumeRenderer read FShadowVolumeRenderer;`
Renderer of shadow volumes. You can use this to optimize rendering of your shadow quads in RenderShadowVolume, and you can control it's statistics (TGLShadowVolumeRenderer.Count and related properties). This is internally initialized by scene manager. It's `Nil` when OpenGL context is not yet initialized (or scene manager is not added to `Controls` list yet).
| `property MouseRayHit: TRayCollision read FMouseRayHit;`
Current 3D objects under the mouse cursor. Updated in every mouse move. May be `Nil`.
| `property Viewports: TCastleAbstractViewportList read FViewports;`
List of viewports connected to this scene manager. This contains all TCastleViewport instances that have TCastleViewport.SceneManager set to us. Also it contains Self (this very scene manager) if and only if DefaultViewport = `True` (because when DefaultViewport, scene manager acts as an additional viewport too). This list is read-only from the outside! It's automatically managed in this unit (when you change TCastleViewport.SceneManager or TCastleSceneManager.DefaultViewport, we automatically update this list as appropriate).
| `property Sectors: TSectorList read FSectors;`
Sectors and waypoints of this world, for AI in 3D. Initialized by TGameSceneManager.LoadLevel. `Nil` if you never call TGameSceneManager.LoadLevel. A generic AI code should work regardless if these are `Nil` or not. But if you're making a game and you know you will always call TGameSceneManager.LoadLevel, you can just use them straight away.
| `property Water: TBox3D read FWater write FWater;`
Water volume in the scene. It may be used by various 3D objects to indicate appropriate behavior — some things swim, some things drown and such. For now, this is only used by TPlayer class to detect swimming (and make appropriate sounds, special rendering, drowning and such). For now, this is just a simple TBox3D. It will be extended to represent a set of flexible 3D volumes in the future. Empty initially. Initialize it however you want.
| `property TimeScale: Single read FTimeScale write FTimeScale default 1;`
Time scale used when not Paused.
| `property Items: T3DWorld read FItems;`
Tree of 3D objects within your world. This is the place where you should add your scenes to have them handled by scene manager. You may also set your main TCastleScene (if you have any) as MainScene. T3DList is also T3D instance, so yes — this may be a tree of T3D, not only a flat list.
| `property MainScene: TCastleScene read FMainScene write SetMainScene;`
The main scene of your 3D world. It's not necessary to set this (after all, your 3D world doesn't even need to have any TCastleScene instance). This must be also added to our Items (otherwise things will work strangely). When set, this is used for a couple of things: Decides what headlight is used (by TCastleScene.Headlight). Decides what background is rendered. Notes for implementing descendants of this class: You can change this by overriding Background method. Decides if, and where, the main light casting shadows is. Notes for implementing descendants of this class: You can change this by overriding MainLightForShadows method. Determines projection for viewing (if you use default CalculateProjection implementation). Synchronizes our Camera with VRML/X3D viewpoints and navigation info. This means that Camera will be updated when VRML/X3D events change current Viewpoint or NavigationInfo, for example you can animate the camera by animating the viewpoint (or it's transformation) or bind camera to a viewpoint. Note that scene manager "hijacks" some Scene events: TCastleSceneCore.OnBoundViewpointVectorsChanged, TCastleSceneCore.ViewpointStack.OnBoundChanged, TCastleSceneCore.NavigationInfoStack.OnBoundChanged for this purpose. If you want to know when viewpoint changes, you can use scene manager's event OnBoundViewpointChanged, OnBoundNavigationInfoChanged. The above stuff is only sensible when done once per scene manager, that's why we need `MainScene` property to indicate this. (We cannot just use every 3D object from Items for this.) Freeing `MainScene` will automatically set this to `Nil`.
| `property OnCameraChanged: TNotifyEvent read FOnCameraChanged write FOnCameraChanged;`
Called on any camera change. Exactly when TCamera generates it's OnVisibleChange event.
| `property OnBoundViewpointChanged: TNotifyEvent read FOnBoundViewpointChanged write FOnBoundViewpointChanged;`
Called when bound Viewpoint node changes. Called exactly when TCastleSceneCore.ViewpointStack.OnBoundChanged is called.
| `property OnBoundNavigationInfoChanged: TNotifyEvent read FOnBoundNavigationInfoChanged write FOnBoundNavigationInfoChanged;`
Called when bound NavigationInfo changes (to a different node, or just a field changes).
| `property DefaultViewport: boolean read FDefaultViewport write SetDefaultViewport default true;`
Should we render the 3D world in a default viewport that covers the whole window. This is usually what you want. For more complicated uses, you can turn this off, and use explicit TCastleViewport (connected to this scene manager by TCastleViewport.SceneManager property) for making your world visible.
| `property Player: TPlayer read FPlayer write SetPlayer;`
Player in this 3D world. This currently serves various purposes: In the 1st person view, this 3D object guides the camera and it never collides with the camera. That is, our CameraMoveAllowed and similar methods simply call Player.MoveAllowed, that in turn calls World.WorldMoveAllowed making sure that player is temporarily disabled (does not collide with itself). TGameSceneManager.LoadLevel will set Player.Camera to TCastleSceneManager.Camera. This means that user can directly control Player.Camera view (position, direction, up), which in turn is always synchronized with Player view (that is, TPlayer.Direction always equals TPlayer.Camera.Direction and so on). For simple AI in CastleCreatures, hostile creatures will attack this player. So this determines the target position that creatures try to reach, where they shoot missiles etc. More advanced AI, with friendlies/companions, or cooperating factions of creatures, may have other mechanisms to determine who wants to attack who. For items on level in CastleItems, this player will pick up the items lying on the ground, and will be able to equip weapons. This functionality may be generalized in the future, to allow anyone to pick up and carry and equip items.
| `property OnMoveAllowed: TWorldMoveAllowedEvent read FOnMoveAllowed write FOnMoveAllowed;`
- Enable or disable movement of the player, items and creatures. This applies to all 3D objects using T3D.WorldMoveAllowed for movement. In case of 1st-person view (always for now), limiting the player position also implies limiting the camera position. When this event is called at all, the basic collision detection already decided that the move is allowed (so object does not collide with other collidable 3D features). You can now implement additional rules to say when the move is, or is not, allowed. Callback parameters: Allowed: Initially, the Allowed parameter is set following the algorithm described at the MoveLimit property. Your event can use this, and e.g. do something like
        Allowed := Allowed and (my custom move rule);
  Or you can simply ignore the default Allowed value, thus ignoring the algorithm described at the MoveLimit property, and simply always set Allowed to your own decision. For example, setting
        Allowed := true;
- will make gravity and movement work everywhere. BecauseOfGravity: `True` if this move was caused by gravity, that is: given object is falling down. You can use this to limit gravity to some box, but keep other movement unlimited, like
        { Allow movement everywhere, but limit gravity to a box. }
        Allowed := (not BecauseOfGravity) or MyGravityBox.PointInside(NewPos);
Generated by PasDoc 0.13.0 on 2015-06-15 04:43:11