Class TCastleTransform

Unit

Declaration

type TCastleTransform = class(TCastleComponent)

Description

Group and transform (move, rotate, scale) children objects.

Add and remove children using the Add, Remove and similar methods. A child can be any TCastleTransform instance, in particular it can be a TCastleScene instance (which allows to load and render any 3D or 2D model).

Control the transformation using these properties:

  1. Move using Translation.

  2. Rotate using Rotation. The rotation is performed around the Center point. The rotation may be alternatively controlled using the Direction and Up vectors.

  3. Change size using Scale. Scale is done around Center and with orientation given by ScaleOrientation.

This class is the base object that is managed by the TCastleViewport. You insert instances of this class into TCastleViewport.Items, which is actually an instance of TCastleTransform too.

This class implements also optional gravity and physics. See the Gravity property for a simple unrealistic gravity model. See the RigidBody for a proper rigid-bidy simulation, with correct gravity model and collisions with other rigid bodies.

Hierarchy

Overview

Fields

Public nested const DefaultMiddleHeight = 0.5;
Public nested const DefaultDirection: array [TOrientationType] of TVector3 = ( (X: 0; Y: 0; Z: -1), (X: 0; Y: 0; Z: +1), (X: 0; Y: -1; Z: 0), (X: 1; Y: 0; Z: 0) );
Public nested const DefaultUp: array [TOrientationType] of TVector3 = ( (X: 0; Y: 1; Z: 0), (X: 0; Y: 1; Z: 0), (X: 0; Y: 0; Z: 1), (X: 0; Y: 0; Z: 1) );
Public nested const DefaultCameraOrientation = otUpYDirectionMinusZ;
Public class var DefaultOrientation: TOrientationType;
Public InternalExcludeFromParentBoundingVolume: Boolean;

Methods

Protected function GetRenderList(const Params: TRenderParams): TCastleTransformList; virtual;
Protected procedure RegisterGLContextClose;
Protected procedure ChangeWorld(const Value: TCastleAbstractRootTransform); virtual;
Protected procedure Notification(AComponent: TComponent; Operation: TOperation); override;
Protected function HeightCollision(const APosition, GravityUp: TVector3; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc; out AboveHeight: Single; out AboveGround: PTriangle): boolean;
Protected function MoveCollision( const OldPos, ProposedNewPos: TVector3; out NewPos: TVector3; const IsRadius: boolean; const Radius: Single; const OldBox, NewBox: TBox3D; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc): boolean; overload;
Protected function MoveCollision( const OldPos, NewPos: TVector3; const IsRadius: boolean; const Radius: Single; const OldBox, NewBox: TBox3D; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc): boolean; overload;
Protected function SegmentCollision(const Pos1, Pos2: TVector3; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc; const ALineOfSight: boolean): boolean;
Protected function SphereCollision(const Pos: TVector3; const Radius: Single; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc): boolean;
Protected function SphereCollision2D(const Pos: TVector2; const Radius: Single; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc; const Details: TCollisionDetails = nil): boolean;
Protected function PointCollision2D(const Point: TVector2; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc): boolean;
Protected function BoxCollision(const Box: TBox3D; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc): boolean;
Protected function RayCollision(const RayOrigin, RayDirection: TVector3; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc): TRayCollision;
Protected function LocalHeightCollision(const APosition, GravityUp: TVector3; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc; out AboveHeight: Single; out AboveGround: PTriangle): boolean; virtual;
Protected function LocalMoveCollision( const OldPos, ProposedNewPos: TVector3; out NewPos: TVector3; const IsRadius: boolean; const Radius: Single; const OldBox, NewBox: TBox3D; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc): boolean; overload; virtual;
Protected function LocalMoveCollision( const OldPos, NewPos: TVector3; const IsRadius: boolean; const Radius: Single; const OldBox, NewBox: TBox3D; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc): boolean; overload; virtual;
Protected function LocalSegmentCollision(const Pos1, Pos2: TVector3; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc; const ALineOfSight: boolean): boolean; virtual;
Protected function LocalSphereCollision(const Pos: TVector3; const Radius: Single; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc): boolean; virtual;
Protected function LocalSphereCollision2D(const Pos: TVector2; const Radius: Single; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc; const Details: TCollisionDetails = nil): boolean; virtual;
Protected function LocalPointCollision2D(const Point: TVector2; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc): boolean; virtual;
Protected function LocalBoxCollision(const Box: TBox3D; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc): boolean; virtual;
Protected function LocalRayCollision(const RayOrigin, RayDirection: TVector3; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc): TRayCollision; virtual;
Protected procedure LocalRender(const Params: TRenderParams); virtual;
Protected procedure LocalRenderShadowVolume(const Params: TRenderParams; const ShadowVolumeRenderer: TBaseShadowVolumeRenderer); virtual;
Protected function Translation2D: TVector2; deprecated 'use TranslationXY';
Protected procedure TransformMatricesMult(var M, MInverse: TMatrix4); deprecated 'do not use this directly, instead use Transform and InverseTransform methods';
Protected procedure TransformMatrices(out M, MInverse: TMatrix4); deprecated 'do not use this directly, instead use Transform and InverseTransform methods';
Protected function AverageScale: Single;
Protected function AverageScale2D: Single;
Protected procedure Fall(const FallHeight: Single); virtual;
Protected procedure ChangedTransform; virtual;
Protected procedure ExistsInRootChanged; virtual;
Protected function InternalBuildNodeInside: TObject; virtual;
Public constructor Create(AOwner: TComponent); override;
Public destructor Destroy; override;
Public procedure BeforeDestruction; override;
Public procedure CustomSerialization(const SerializationProcess: TSerializationProcess); override;
Public function PropertySections(const PropertyName: String): TPropertySections; override;
Public procedure DesignerWarnings(const SList: TStrings); override;
Public function GetEnumerator: TEnumerator;
Public function HasColliderMesh: Boolean; virtual;
Public procedure ColliderMesh(const TriangleEvent: TTriangleEvent); virtual;
Public function CheckCollides: Boolean;
Public function GetCollides: boolean; virtual; deprecated 'use CheckCollides';
Public function CheckPickable: boolean;
Public function GetPickable: boolean; virtual; deprecated 'use CheckPickable';
Public function CheckVisible: boolean;
Public function GetVisible: boolean; virtual; deprecated 'use CheckVisible';
Public procedure Add(const Item: TCastleTransform);
Public procedure Insert(const Index: Integer; const Item: TCastleTransform);
Public procedure Remove(const Item: TCastleTransform);
Public procedure RemoveDelayed(const Item: TCastleTransform; const FreeItem: Boolean = false);
Public procedure Delete(const Index: Integer);
Public function Count: Integer;
Public procedure Clear;
Public procedure Exchange(const Index1, Index2: Integer);
Public function BoundingBox: TBox3D;
Public function LocalBoundingBox: TBox3D; virtual;
Public function WorldBoundingBox: TBox3D;
Public procedure Render(const Params: TRenderParams); overload; virtual;
Public procedure Render(const Frustum: TFrustum; const Params: TRenderParams); overload; deprecated 'use Render method without an explicit Frustum parameter, it is in Params.Frustum now';
Public procedure RenderShadowVolume(const Params: TRenderParams; const ShadowVolumeRenderer: TBaseShadowVolumeRenderer);
Public procedure PrepareResources(const Options: TPrepareResourcesOptions; const Params: TPrepareParams); virtual;
Public function Press(const Event: TInputPressRelease): boolean; virtual;
Public function Release(const Event: TInputPressRelease): boolean; virtual;
Public function PointingDevicePress(const Pick: TRayCollisionNode; const Distance: Single): Boolean; virtual;
Public function PointingDeviceRelease(const Pick: TRayCollisionNode; const Distance: Single; const CancelAction: Boolean): Boolean; virtual;
Public function PointingDeviceMove(const Pick: TRayCollisionNode; const Distance: Single): Boolean; virtual;
Public procedure Update(const SecondsPassed: Single; var RemoveMe: TRemoveType); virtual;
Public procedure AddAfterUpdateListener(const UpdateListener: TNotifyEvent);
Public procedure RemoveAfterUpdateListener(const UpdateListener: TNotifyEvent);
Public procedure VisibleChangeHere(const Changes: TVisibleChanges); virtual;
Public procedure GLContextClose; virtual;
Public function Middle: TVector3; virtual;
Public function WorldMiddle: TVector3;
Public function Sphere(out Radius: Single): boolean; virtual;
Public function Height(const MyPosition: TVector3; out AboveHeight: Single): boolean; overload;
Public function Height(const MyPosition: TVector3; out AboveHeight: Single; out AboveGround: PTriangle): boolean; overload;
Public function LineOfSight(const Pos1, Pos2: TVector3): boolean;
Public function MoveAllowed(const OldPos, ProposedNewPos: TVector3; out NewPos: TVector3; const BecauseOfGravity: boolean): boolean; overload;
Public function MoveAllowed(const OldPos, NewPos: TVector3; const BecauseOfGravity: boolean): boolean; overload;
Public function Ray(const RayOrigin, RayDirection: TVector3): TRayCollision;
Public function RayCast(const RayOrigin, RayDirection: TVector3): TCastleTransform; overload;
Public function RayCast(const RayOrigin, RayDirection: TVector3; out Distance: Single): TCastleTransform; overload;
Public function OutsideToLocal(const Pos: TVector3): TVector3;
Public function LocalToOutside(const Pos: TVector3): TVector3;
Public function WorldToLocal(const Pos: TVector3): TVector3;
Public function LocalToWorld(const Pos: TVector3): TVector3;
Public function WorldToLocalDirection(const Dir: TVector3): TVector3;
Public function LocalToWorldDirection(const Dir: TVector3): TVector3;
Public function LocalToWorldDistance(const Distance: Single): Single;
Public function WorldToLocalDistance(const Distance: Single): Single;
Public function PreferredHeight: Single; virtual; deprecated 'use physics (TCastleRigidBody, TCastleCollider) to make things affected by gravity';
Public function Transform: TMatrix4;
Public function InverseTransform: TMatrix4;
Public function HasWorldTransform: boolean;
Public function WorldTransform: TMatrix4;
Public function WorldInverseTransform: TMatrix4;
Public procedure Translate(const TranslationChange: TVector3);
Public function Move(const TranslationChange: TVector3; const BecauseOfGravity: boolean; const EnableWallSliding: boolean = true): boolean;
Public procedure Identity;
Public procedure GetView(out APos, ADir, AUp: TVector3);
Public procedure GetWorldView(out APos, ADir, AUp: TVector3);
Public function WorldTranslation: TVector3;
Public procedure SetView(const APos, ADir, AUp: TVector3; const AdjustUp: boolean = true); overload;
Public procedure SetView(const ADir, AUp: TVector3; const AdjustUp: boolean = true); overload;
Public procedure SetWorldView(const APos, ADir, AUp: TVector3; const AdjustUp: boolean = true);
Public procedure UpPrefer(const AUp: TVector3);
Public procedure AddBehavior(const Behavior: TCastleBehavior);
Public function BehaviorIndex(const Behavior: TCastleBehavior): Integer;
Public procedure RemoveBehavior(const Behavior: TCastleBehavior);
Public function FindBehavior(const BehaviorClass: TCastleBehaviorClass): TCastleBehavior;
Public function FindAllBehaviors(const BehaviorClass: TCastleBehaviorClass): TCastleBehaviorList;
Public function FindRequiredBehavior(const BehaviorClass: TCastleBehaviorClass): TCastleBehavior;
Public function BehaviorsCount: Integer;
Public function BehaviorsEnumerate: TCastleBehaviorEnumerator;
Public procedure AddWorldChangeNotification(const Behavior: TCastleBehavior);
Public procedure RemoveWorldChangeNotification(const Behavior: TCastleBehavior);
Public function InternalBuildNode: TObject;

Properties

Public property GetExists: Boolean read FExists; deprecated 'use Exists';
Public property Items[const I: Integer]: TCastleTransform read GetItem write SetItem;
Public property Parent: TCastleTransform read FParent write SetParent;
Public property UniqueParent: TCastleTransform read FParent; deprecated 'use Parent';
Public property CastShadowVolumes: boolean read FCastShadows write FCastShadows default true; deprecated 'use CastShadows';
Public property ListenPressRelease: Boolean read FListenPressRelease write SetListenPressRelease default false;
Public property World: TCastleAbstractRootTransform read FWorld;
Public property WorldDirection: TVector3 read GetWorldDirection write SetWorldDirection;
Public property CollidesWithMoving: boolean read FCollidesWithMoving write FCollidesWithMoving default false;
Public property Gravity: boolean read FGravity write FGravity default false; deprecated 'use physics (TCastleRigidBody, TCastleCollider) to make things affected by gravity';
Public property FallSpeed: Single read FFallSpeed write FFallSpeed default 0; deprecated 'use physics (TCastleRigidBody, TCastleCollider) to make things affected by gravity';
Public property GrowSpeed: Single read FGrowSpeed write FGrowSpeed default 0; deprecated 'use physics (TCastleRigidBody, TCastleCollider) to make things affected by gravity';
Public property MiddleHeight: Single read FMiddleHeight write FMiddleHeight default DefaultMiddleHeight;
Public property Translation: TVector3 read FTranslation write SetTranslation;
Public property TranslationXY: TVector2 read GetTranslationXY write SetTranslationXY;
Public property Center: TVector3 read FCenter write SetCenter;
Public property Rotation: TVector4 read FRotation write SetRotation;
Public property Scale: TVector3 read FScale write SetScale;
Public property ScaleOrientation: TVector4 read FScaleOrientation write SetScaleOrientation;
Public property RigidBody: TCastleRigidBody read FCachedRigidBody;
Public property Collider: TCastleCollider read FCachedCollider;
Public property Position: TVector3 read FTranslation write SetTranslation; deprecated 'use Translation';
Public property Direction: TVector3 read GetDirection write SetDirection;
Public property Up: TVector3 read GetUp write SetUp;
Public property WorldView: TViewVectors read GetWorldViewRec write SetWorldViewRec;
Public property Orientation: TOrientationType read FOrientation write FOrientation;
Public property List: TCastleTransformList read FList;
Public property Behaviors [const Index: Integer]: TCastleBehavior read GetBehaviors;
Public property ExistsInRoot: Boolean read FExistsInRoot;
Published property Exists: Boolean read FExists write SetExists default true;
Published property Collides: boolean read FCollides write FCollides default true;
Published property Pickable: boolean read FPickable write FPickable default true;
Published property Visible: boolean read FVisible write FVisible default true;
Published property CollisionSphereRadius: Single read FCollisionSphereRadius write FCollisionSphereRadius;
Published property CastShadows: boolean read FCastShadows write FCastShadows default true;
Published property RenderLayer: TRenderLayer read FRenderLayer write FRenderLayer default rlParent;
Published property CenterPersistent: TCastleVector3Persistent read FCenterPersistent ;
Published property RotationPersistent: TCastleVector4RotationPersistent read FRotationPersistent ;
Published property ScalePersistent: TCastleVector3Persistent read FScalePersistent ;
Published property ScaleOrientationPersistent: TCastleVector4Persistent read FScaleOrientationPersistent ;
Published property TranslationPersistent: TCastleVector3Persistent read FTranslationPersistent ;
Published property DirectionPersistent: TCastleVector3Persistent read FDirectionPersistent stored false;
Published property UpPersistent: TCastleVector3Persistent read FUpPersistent stored false;

Description

Fields

Public nested const DefaultMiddleHeight = 0.5;

This item has no description.

Public nested const DefaultDirection: array [TOrientationType] of TVector3 = ( (X: 0; Y: 0; Z: -1), (X: 0; Y: 0; Z: +1), (X: 0; Y: -1; Z: 0), (X: 1; Y: 0; Z: 0) );

This item has no description.

Public nested const DefaultUp: array [TOrientationType] of TVector3 = ( (X: 0; Y: 1; Z: 0), (X: 0; Y: 1; Z: 0), (X: 0; Y: 0; Z: 1), (X: 0; Y: 0; Z: 1) );

This item has no description.

Public nested const DefaultCameraOrientation = otUpYDirectionMinusZ;

Default TCastleCamera.Orientation.

Public class var DefaultOrientation: TOrientationType;

Default value of TCastleTransform.Orientation for new TCastleTransform instances, except for cameras (cameras use special DefaultCameraOrientation).

This is otUpYDirectionZ by default. This matches glTF orientation (as exported from Blender and other software).

Public InternalExcludeFromParentBoundingVolume: Boolean;

Exclude this object's bounding volume from parent bounding volume.

This should be always False for non-debug scenes. Changing this may cause rendering artifacts, things could disappear when they should not. Using this is reasonable only if you attach a debug geometry to your scene, and you don't want to enlarge your bounding volume (e.g. because this debug geometry visualizes something determined by the bounding volume, and it would create a "feedback loop" if the visualization itself would enlarge the bounding box).

Methods

Protected function GetRenderList(const Params: TRenderParams): TCastleTransformList; virtual;

Returns list of TCastleTransform to render. By default, it just returns List.

Protected procedure RegisterGLContextClose;

Call this when doing anything that allocates GL resources. This will make sure GLContextClose will get called.

Protected procedure ChangeWorld(const Value: TCastleAbstractRootTransform); virtual;

Called when the current World that contains this object changes. In the usual case, World corresponds to a TCastleViewport.Items instance, and when this method is called it means that object is added/removed from a viewport.

You can ignore this when called with Value equal to current World.

Note that each TCastleTransform instance can only be part of one world (TCastleAbstractRootTransform) at a time. Although we may be present many times within the same world. Always remove the TCastleTransform from previous world before adding it to a new one.

Protected procedure Notification(AComponent: TComponent; Operation: TOperation); override;

This item has no description.

Protected function HeightCollision(const APosition, GravityUp: TVector3; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc; out AboveHeight: Single; out AboveGround: PTriangle): boolean;

Height of a point above the 3D model. This checks ray collision, from APosition along the negated GravityUp vector. Measures distance to the nearest scene item (called "ground" here).

Parameters
AboveHeight
Height above the ground. One height unit equals one GravityUp vector. Always use normalized GravityUp vector if you expect to receive here a normal distance.

AboveHeight is always set to MaxSingle when returned result is False (this guarantee simplifies some code).

AboveGround
Pointer to PTriangle representing the ground. Must be Nil if returned result is False. May be Nil even if we returned True (not all 3D objects may be able to generate PTriangle information about collision).

This may be useful for example to make a footsteps sound dependent on texture of the ground. Or to decrease player life points for walking on hot lava. See "The Castle" game for examples.

Returns

If the 3D scene is hit. False means that APosition floats above an empty space. That is, if you turn gravity on, it will fall down forever, as far as this 3D scene is concerned.

Protected function MoveCollision( const OldPos, ProposedNewPos: TVector3; out NewPos: TVector3; const IsRadius: boolean; const Radius: Single; const OldBox, NewBox: TBox3D; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc): boolean; overload;

Can other 3D object (maybe a player) move without colliding with this object.

If IsRadius, then you should prefer to perform exact collision with sphere of given radius (must be > 0). At the very least, this checks that the line segment between OldPos and NewPos doesn't collide, and that sphere with given Radius centered around NewPos doesn't collide.

If not IsRadius, or if checking for collisions with sphere is not possible for some reasons, then you can check for collisions with boxes. OldBox should usually be ignored (it can be useful when collision-checking has to be approximate in some corner cases, see TCreature.MoveCollision). NewBox plays the same role as "sphere centered around NewPos" in paragraph above.

Overloaded version with separate ProposedNewPos and NewPos parameters allows you to accept the move, but for NewPos (that should be some slightly modified version of ProposedNewPos). This allows to implement wall-sliding: when camera tries to walk into the wall, we will change movement to move alongside the wall (instead of just completely blocking the move). When this version returns False, it's undefined what is the NewPos.

Protected function MoveCollision( const OldPos, NewPos: TVector3; const IsRadius: boolean; const Radius: Single; const OldBox, NewBox: TBox3D; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc): boolean; overload;

This item has no description.

Protected function SegmentCollision(const Pos1, Pos2: TVector3; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc; const ALineOfSight: boolean): boolean;

Check collision with a line segment, that is: a line between 2 points in 3D.

Protected function SphereCollision(const Pos: TVector3; const Radius: Single; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc): boolean;

Check collision with a 3D sphere.

This works precisely when transformation hierarchy has uniform scaling, i.e. scale is the same in all X, Y, Z axes. In case of non-uniform scaling, this is an approximation.

Protected function SphereCollision2D(const Pos: TVector2; const Radius: Single; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc; const Details: TCollisionDetails = nil): boolean;

Check collision with a sphere in 2D (a circle, extruded to infinity along the Z axis).

Note that PointCollision2D and SphereCollision2D do not work reliably on objects that have 3D rotations. See PointCollision2D for details.

This works precisely when transformation hierarchy has uniform scaling, i.e. scale is the same in all X, Y, Z axes. In case of non-uniform scaling, this is an approximation.

Parameters
Details
If non-nil, these are automatically filled with the details about the collision. If the result is False, the Details contents are untouched. If the result is True, the Details contents are set to describe the 3D objects hierarchy that caused this collision.
Protected function PointCollision2D(const Point: TVector2; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc): boolean;

Check collision with a point in 2D (which is an infinite line along the Z axis in 3D).

Note that PointCollision2D and SphereCollision2D do not work reliably on objects that have 3D rotations, that is: rotations that change the direction of Z axis! This applies to all ways of rotating – using the TCastleTransform or using the X3D node TTransformNode (within a TCastleSce).

  1. The reason: we transform the point (or sphere center) to the local coordinates, and we should also transform the Z axis to the local coordinates, to be always correct. Right now, we don't do the latter.

  2. And we don't want to do it (at least not in all cases)! The simple 2D point collision check would then actually perform a 3D line collision check, thus PointCollision2D would lose all the speed benefits over LineCollision. PointCollision2D would become a simple shortcut to perform LineCollision with a line parallel to Z axis.

    And in case of 2D games, or mostly 2D games, this speed loss would not be justified. Often you know that your objects have no 3D rotations, for example if your animations are done in Spine.

  3. In the future, we may overcome this limitation. To do this, we will detect whether the transformation is "only 2D" (actually this part is easy, you can detect it by looking at the matrix even, so check whether appropriate numbers are zero). And then PointCollision2D will change to LineCollision, and SphereCollision2D will change to something like ExtrudedCircleCollision, only when necessary.

Protected function BoxCollision(const Box: TBox3D; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc): boolean;

Check collision with axis-aligned box in 3D.

Protected function RayCollision(const RayOrigin, RayDirection: TVector3; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc): TRayCollision;

First object hit by the ray, as a TRayCollision. Returns a collision as TRayCollision instance, or Nil if no collision. Caller is responsible for freeing the returned TRayCollision instance.

Contrary to other collision routines, this should ignore the Collides property. The Collides property specifies whether item collides with camera. And this method is used for picking (pointing) 3D stuff — everything visible can be picked, collidable or not. Instead, this looks at Pickable and Exists properties.

This always returns the first collision with the world, that is the one with smallest TRayCollision.Distance. For example, when implemented in TCastleTransform, this checks collisions for all list items, and chooses the closest one.

Protected function LocalHeightCollision(const APosition, GravityUp: TVector3; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc; out AboveHeight: Single; out AboveGround: PTriangle): boolean; virtual;

This item has no description.

Protected function LocalMoveCollision( const OldPos, ProposedNewPos: TVector3; out NewPos: TVector3; const IsRadius: boolean; const Radius: Single; const OldBox, NewBox: TBox3D; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc): boolean; overload; virtual;

This item has no description.

Protected function LocalMoveCollision( const OldPos, NewPos: TVector3; const IsRadius: boolean; const Radius: Single; const OldBox, NewBox: TBox3D; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc): boolean; overload; virtual;

This item has no description.

Protected function LocalSegmentCollision(const Pos1, Pos2: TVector3; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc; const ALineOfSight: boolean): boolean; virtual;

This item has no description.

Protected function LocalSphereCollision(const Pos: TVector3; const Radius: Single; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc): boolean; virtual;

This item has no description.

Protected function LocalSphereCollision2D(const Pos: TVector2; const Radius: Single; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc; const Details: TCollisionDetails = nil): boolean; virtual;

This item has no description.

Protected function LocalPointCollision2D(const Point: TVector2; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc): boolean; virtual;

This item has no description.

Protected function LocalBoxCollision(const Box: TBox3D; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc): boolean; virtual;

This item has no description.

Protected function LocalRayCollision(const RayOrigin, RayDirection: TVector3; const TrianglesToIgnoreFunc: TTriangleIgnoreFunc): TRayCollision; virtual;

This item has no description.

Protected procedure LocalRender(const Params: TRenderParams); virtual;

Collect the things to be rendered now.

Override this method if you need to perform custom rendering, by direct OpenGL(ES) calls. Never call this method yourself – the rendering of TCastleViewport will call it when needed.

Warning: It is an advanced topic how to make such rendering work, and make it work in a cross-platform way. You will need to understand how OpenGL(ES) works, and you will need to account for how the engine renders things too, to not conflict with the engine – e.g. you will have to use RenderContext for some things. If you're not ready for this, then you're better off not overriding this method, instead just rely on the engine built-in rendering, done by TCastleScene and other components.

This method gets parameters (Params) including a full transformation of this scene.

In return, it should add the things to be rendered in this frame using Params.AddRenderEvent.

Internally: TCastleScene also adds X3D shapes to be rendered to TRenderParams.Collector. But you should not need to deal with TRenderParams.Collector in your own code.

TODO: The names LocalRender, TRenderParams are now confusing. LocalRender is not a method where one should "render" anymore. It's a "collection phase". Think of it as "TCastleTranssform.CollectThingsToRender(const Params: ...)" and bear with us as we figure out a non-confusing naming around this.

Protected procedure LocalRenderShadowVolume(const Params: TRenderParams; const ShadowVolumeRenderer: TBaseShadowVolumeRenderer); virtual;

Render shadow volumes (with a full transformation of this scene).

Override this if you do custom rendering (overriding also LocalRender) and would like to render shadow volumes for your custom rendering. Never call this method yourself – the rendering of TCastleViewport will call it when needed.

Just like for LocalRender, the same warning applies: doing custom rendering is an advanced topic, you need to understand how OpenGL(ES) works, and how the engine renders things, to make it all work. Most projects should not need to override this method, instead rely on built-in engine components like TCastleScene to render everything.

Protected function Translation2D: TVector2; deprecated 'use TranslationXY';

Warning: this symbol is deprecated: use TranslationXY

Get translation in 2D (uses Translation, ignores Z coord).

Protected procedure TransformMatricesMult(var M, MInverse: TMatrix4); deprecated 'do not use this directly, instead use Transform and InverseTransform methods';

Warning: this symbol is deprecated: do not use this directly, instead use Transform and InverseTransform methods

Transformation matrices, like Transform and InverseTransform.

Protected procedure TransformMatrices(out M, MInverse: TMatrix4); deprecated 'do not use this directly, instead use Transform and InverseTransform methods';

Warning: this symbol is deprecated: do not use this directly, instead use Transform and InverseTransform methods

This item has no description.

Protected function AverageScale: Single;

Average value of 3D scale in Scale. It is not calculated as a simple average, it's a little smarter to prevent from weird results sometimes, see Approximate3DScale.

Protected function AverageScale2D: Single;

Average value of 2D scale, from XY components of Scale. It is not calculated as a simple average, it's a little smarter to prevent from weird results sometimes, see Approximate2DScale.

Protected procedure Fall(const FallHeight: Single); virtual;

Called when fall ended. You can use FallHeight to decrease creature life or such.

Protected procedure ChangedTransform; virtual;

Override to be notified about every transformation change. By default, this calls VisibleChangeHere, which causes the window to redraw.

Protected procedure ExistsInRootChanged; virtual;

Override to be notified after ExistsInRoot value changed.

Protected function InternalBuildNodeInside: TObject; virtual;

Helper for InternalBuildNode. Result must be TAbstractChildNode or Nil.

Public constructor Create(AOwner: TComponent); override;

This item has no description.

Public destructor Destroy; override;

This item has no description.

Public procedure BeforeDestruction; override;

This item has no description.

Public procedure CustomSerialization(const SerializationProcess: TSerializationProcess); override;

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

Override this method to call various methods of SerializationProcess, which in turn allows to serialize/deserialize things that are not published. This allows to serialize/deserialize with more freedom, e.g. to serialize/deserialize some private field.

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 procedure DesignerWarnings(const SList: TStrings); override;

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

Override to add warnings that should be visible at design-time. Call SList.Add for each new warning.

Public function GetEnumerator: TEnumerator;

This item has no description.

Public function HasColliderMesh: Boolean; virtual;

Does this transform have a collision mesh that TCastleMeshCollider can use. Default implementation returns False.

Public procedure ColliderMesh(const TriangleEvent: TTriangleEvent); virtual;

Enumerate triangles for a collision mesh that TCastleMeshCollider can use. Always the front side of triangles is CCW (this matters for TCastleMeshCollider with TCastleMeshCollider.DoubleSided = False).

Public function CheckCollides: Boolean;

Does the item really collide. Trivial shortcut for checking Collides and Exists.

Public function GetCollides: boolean; virtual; deprecated 'use CheckCollides';

Warning: this symbol is deprecated: use CheckCollides

This item has no description.

Public function CheckPickable: boolean;

Is the item really pickable. Trivial shortcut for checking Pickable and Exists.

Public function GetPickable: boolean; virtual; deprecated 'use CheckPickable';

Warning: this symbol is deprecated: use CheckPickable

This item has no description.

Public function CheckVisible: boolean;

Is the item really visible. Trivial shortcut for checking Visible and Exists.

Public function GetVisible: boolean; virtual; deprecated 'use CheckVisible';

Warning: this symbol is deprecated: use CheckVisible

This item has no description.

Public procedure Add(const Item: TCastleTransform);

Add a child.

Note that adding the same child multiple times is allowed, in general you can use the same TCastleTransform instance multiple times in one hierarchy of TCastleRootTransform.

Public procedure Insert(const Index: Integer; const Item: TCastleTransform);

Insert a child at a specific position on the children list.

Note: Usually the order of children doesn't matter, so you can as well add children at the end, using Add.

In particular, when rendering opaque (3D or 2D) objects, the front/back is decided by the actual translation of the object, i.e. what is closer to the camera. (In a typical 2D setup, larger Z values mean "closer to the camera".) The position on the children list doesn't matter in this case.

When rendering with blending, we recommend to use TCastleViewport.BlendingSort to automatically use proper order when rendering partially-transparent objects. This will mean that the order of children really doesn't matter.

However, the position matters in case of blending, if you set TCastleViewport.BlendingSort to sortNone. See https://castle-engine.io/blending . For correct blending, when you have multiple partially-transparent scenes, the partially-transparent objects must be sorted from back to front on the list. So you should add them in the proper order, or insert on proper positions.

Public procedure Remove(const Item: TCastleTransform);

Remove a child.

Adding and removing from the TCastleTransform hierarchy is guaranteed to be fast, so you can do it even in the middle of the game. In particular calling Remove doesn't free rendering reasources of the removed scene, So e.g. removing scene only to add it later to another TCastleViewport.Items is fast.

Note that removing the child Item does not free the Item. It merely makes the Item no longer be a child of this TCastleTransform, so it will no longer be shown in the viewport. If you want to free the item instance, you have to do it explicitly, by Item.Free or FreeAndNil(Item). Freed items are automatically removed from parent. See also What is the difference between Owner and Parent in CGE?.

Public procedure RemoveDelayed(const Item: TCastleTransform; const FreeItem: Boolean = false);

Use this to remove (and possibly free) the child, but not immediately.

The actual removal (and freeing, if FreeItem) will be done at some crucial points:

  • Right before we render children.

  • Right before we loop over children in the Update method.

  • Right after we loop over children in the Update method.

  • From our destructor.

This allows to use this method safely even in the middle of iteration over TCastleTransform children. For example you can use it from Update method, from any TCastleTransform.Update or TCastleUserInterface.Update (including TCastleView.Update).

Note: It is not a problem if the child scheduled to be removed will also be removed (or even freed) directly e.g. by just calling Free on it. We ignore removal of items that are no longer our children, and we automatically remove the child from "pending to remove" list if it is freed. You only need to be careful in case you add the same TCastleTransform instance multiple times to the same parent (see https://castle-engine.io/viewport_and_scenes_from_code#_multiple_instances_of_the_same_scene ) as then each removal removes one instance (not all) of the child from parent.

Note: When you want to free the Item (that is, FreeItem parameter is True) then it actually doesn't matter on what parent will you call this. Freeing the Item will always remove it from all parents.

Public procedure Delete(const Index: Integer);

Remove a child, by index on the Items list.

Public function Count: Integer;

Count of current children, to iterate over Items from 0 to Count-1.

Public procedure Clear;

Remove all children TCastleTransform instances.

Note that removing the children using this method, just like using Remove, does not free the children. It merely makes the children no longer be inside this TCastleTransform, so they will no longer be shown in the viewport. If you want to free the children, you have to do it explicitly, calling Item.Free or FreeAndNil(Item) for each child. Freed items are automatically removed from parent. See also What is the difference between Owner and Parent in CGE?.

Public procedure Exchange(const Index1, Index2: Integer);

Exchange position of 2 children TCastleTransform instances.

Public function BoundingBox: TBox3D;

Bounding box of this object, in the coordinate system of the parent transformation. This method takes into account current transformation (like Translation, Rotation) but not parent TCastleTransform transformations. Use WorldBoundingBox instead to know bounding box that accounts for all TCastleTransform transformations. Use LocalBoundingBox instead to know bounding box that does not account for any parent or this TCastleTransform transformations.

Takes into account both collidable and visible objects. For example, invisible walls (not visible) and fake walls (not collidable) should all be accounted here.

It's a bounding volume, it should be as large as necessary to include the object inside. At the same time, it should be as "tight" as it can, to make various optimizations work best.

See also
WorldBoundingBox
Bounding box of this object, taking into account all transformations of this and parents.
LocalBoundingBox
Bounding box of this object, ignoring the transformations of this scene and parents.
Public function LocalBoundingBox: TBox3D; virtual;

Bounding box of this object, ignoring the transformations of this scene and parents.

See also
BoundingBox
Bounding box of this object, in the coordinate system of the parent transformation.
WorldBoundingBox
Bounding box of this object, taking into account all transformations of this and parents.
Public function WorldBoundingBox: TBox3D;

Bounding box of this object, taking into account all transformations of this and parents.

See also
BoundingBox
Bounding box of this object, in the coordinate system of the parent transformation.
LocalBoundingBox
Bounding box of this object, ignoring the transformations of this scene and parents.
Public procedure Render(const Params: TRenderParams); overload; virtual;

Render given object. Should check and immediately exit when CheckVisible is False.

The rendering transformation, frustum, and filtering is specified inside TRenderParams class. This method should only update TRenderParams.Statistics.

Public procedure Render(const Frustum: TFrustum; const Params: TRenderParams); overload; deprecated 'use Render method without an explicit Frustum parameter, it is in Params.Frustum now';

Warning: this symbol is deprecated: use Render method without an explicit Frustum parameter, it is in Params.Frustum now

This item has no description.

Public procedure RenderShadowVolume(const Params: TRenderParams; const ShadowVolumeRenderer: TBaseShadowVolumeRenderer);

Render shadow quads for all the things rendered by Render. This is done only if Exists and CastShadows.

It does shadow volumes culling inside (so ShadowVolumeRenderer should have FrustumCullingInit already initialized).

Params.Transformation describe the transformation, just like for Render.

Public procedure PrepareResources(const Options: TPrepareResourcesOptions; const Params: TPrepareParams); virtual;

Prepare resources, making various methods (like rendering and such) to execute fast.

It is usually simpler to call TCastleViewport.PrepareResources then this method. Calling Viewport.PrepareResources(MyScene) will automatically call MyScene.PrepareResources(...) underneath, with proper parameters.

It is best to call this when the rendering context is initailized, e.g. at Application.OnInitialize or later. Calling this method before the rendering context is initialized (e.g. from initializaton section of some unit) will have to skip some preparations, thus reducing the effectiveness of this method. But it is allowed to call this at any time, regardless of the context being initialized, just like e.g. TCastleContainer.LoadSettings (which may call this, to warmup cache).

This makes sure that appropriate methods execute as fast as possible. It's never required to call this method — everything will be prepared "as needed" anyway. But if you allow everything to be prepared "as needed", then e.g. the first Render call may take a long time because it may have to prepare resources that will be reused in next Render calls. This may make your program seem slow at the beginning (when rendering resources are being prepared, so at the first frame, or a couple of first animation frames). To avoid this, call this method, showing the user something like "now we're preparing the resources — please wait".

TODO: It is not possible to call this now without TPrepareParams, and to get params you need to access deprecated TCastleViewport.PrepareParams. We advise to call TCastleViewport.PrepareResources instead. We'd like to get rid of TPrepareParams eventually.

Parameters
Options
What features should be prepared to execute fast. See TPrepareResourcesOption.
Params
Rendering parameters to prepare for. It is used only if Options contains prRenderSelf or prRenderClones.
Public function Press(const Event: TInputPressRelease): boolean; virtual;

Press and release events of key and mouse, passed only to instances that set ListenPressRelease. Return True if you handled the event, and it should not be passed to other objects. See also TCastleUserInterface analogous events.

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

This item has no description.

Public function PointingDevicePress(const Pick: TRayCollisionNode; const Distance: Single): Boolean; virtual;

Pointing device (mouse or touch) events, you can override these to handle pointing device events. These methods are automatically called by the TCastleViewport. They are exposed here only to allow overriding them. Return True if you handled the event.

  • PointingDevicePress signals that the picking button (usually, left mouse button) was pressed.

    Note that the exact key or mouse responsible for this is configurable in our engine by Input_Interact. By default it's the left mouse button, as is usual for VRML/X3D browsers. But it can be configured to be other mouse button or a key, for example most 3D games use "e" key to interact.

  • PointingDeviceRelease signals that the picking button is released.

    An extra parameter CancelAction indicates whether this pointing device "press and release" sequence may be considered a "click". When CancelAction = True, then you should not make a "click" event (e.g. TouchSensor should not send touchTime event etc.).

  • PointingDeviceMove signals that pointer moves over this object.

They receive Pick information (TRayCollisionNode) about what exactly is hit by the 3D ray corresponding to the current pointing device position. It contains the detailed information about the point, triangle and ray (all in local coordinate system of this TCastleTransform) that are indicated by the pointing device. TRayCollisionNode.Triangle is Nil when it was not possible to determine, and TRayCollisionNode.Point is undefined in this case.

They also receive Distance to the collision point, in world coordinates. See TRayCollision.Distance. The Distance may be MaxSingle when it was not possible to determine.

There is a concept of a TCastleTransform that is currently "capturing" the pointing device events. Once TCastleTransform handles TCastleTransform.PointingDevicePress (returns True for it), it captures the following PointingDeviceMove and PointingDeviceRelease events, regardless if ray still hits this TCastleTransform instance. The "capturing" instance of TCastleTransform is informed first about pointing device move/release.

After the "capturing" instance, every pointing device event (press, release or move) is send to the leaf in TCastleTransform hierarchy (usually a TCastleScene) that is under the mouse/touch position. If the event is not handled, it is passed to other objects under the mouse/touch position.

The PointingDeviceMove event is also always passed to TCastleRootTransform.MainScene at the end (if it wasn't already the "capturing" transform, or under the mouse/touch position). This way TCastleRootTransform.MainScene is always informed about pointing device movement.

These methods are called only if the object Exists. There's no need to check this condition inside the method implementation.

Public function PointingDeviceRelease(const Pick: TRayCollisionNode; const Distance: Single; const CancelAction: Boolean): Boolean; virtual;

This item has no description.

Public function PointingDeviceMove(const Pick: TRayCollisionNode; const Distance: Single): Boolean; virtual;

This item has no description.

Public procedure Update(const SecondsPassed: Single; var RemoveMe: TRemoveType); virtual;

Continuously occuring event, for various tasks.

Executed only on instances that have Exists (no need to check this in overridden Update implementation).

Parameters
RemoveMe
Set this to rtRemove or rtRemoveAndFree to remove this item from parent after this call finished. rtRemoveAndFree additionally will free this item. Initially it's rtNone when this method is called.

You can also use RemoveDelayed from parent for similar effect.

Public procedure AddAfterUpdateListener(const UpdateListener: TNotifyEvent);

Called on update. Update listeners fire after all behaviors have been processed.

Public procedure RemoveAfterUpdateListener(const UpdateListener: TNotifyEvent);

This item has no description.

Public procedure VisibleChangeHere(const Changes: TVisibleChanges); virtual;

Something visible changed inside this object. This is usually called by implementation of this object, to notify others that it changed.

Changes is a set describing what changes occurred. See TVisibleChange docs for more information. It must specify all things that possibly changed.

Changes can be [], meaning "something tells us to redraw, but no visible change happened yet, maybe something will happen during a redraw" (this is used when e.g. possibly LOD level changed). We still increase TCastleAbstractRootTransform.InternalVisibleStateId even when Changes=[].

The information about visibility changed is passed to TCastleAbstractRootTransform in World. It increases TCastleAbstractRootTransform.InternalVisibleStateId, TCastleAbstractRootTransform.InternalVisibleGeometryStateId, TCastleAbstractRootTransform.InternalVisibleNonGeometryStateId. If you want to react to visibility changes, you should not override this method, instead watch above "state id" variables and react when they change.

Public procedure GLContextClose; virtual;

Called when rendering context is destroyed. This will be also automatically called from destructor. Object should clear here any resources that are connected to the rendering context.

Public function Middle: TVector3; virtual;

Middle point, usually "eye point", of the 3D model. This is used for sphere center (if CollisionSphereRadius is non-zero or Sphere returns True) and is the central point from which collisions of this object are checked (Move, MoveAllowed, Height, LineOfSight). It's useful for dynamic objects like player and moving creatures, which rely on MoveAllowed and gravity.

In short, it's usually most comfortable to think about this as a position of the eye, or the middle of the creature's head.

In an ideal situation, it should not be based on anything dynamic. For example, when this is based on the current bounding box of the animation, there is a risk that a large and sudden change in animation box could make the Middle point to jump to the other side of the wall (breaking collisions, as it changes Middle without a chance to check for collisions by MoveAllowed). Ideally, it should remain constant even when the shape of the object changes, and be possible to change only when MoveAllowed is checked (so only when TCastleTransform.Translation can change).

In this class this returns something sensible above the bottom of the box. See TCastleTransform.MiddleHeight.

This is expressed in the parent coordinate system (so it is close to the Translation value, but moved up, following GravityUp). So use Transform.Parent.LocalToWorld(Transform.Middle) to convert this to world coordinates.

Public function WorldMiddle: TVector3;

Our Middle, in world coordinates.

Public function Sphere(out Radius: Single): boolean; virtual;

Can the approximate sphere (around Middle point) be used for some collision-detection tasks. If True then Radius (and Middle point) determine the approximate sphere surrounding the 3D object (it does not have to be a perfect bounding sphere around the object), and it may be used for some collisions instead of BoundingBox. See CollidesWithMoving and MoveAllowed for when it may happen.

Just like Middle and CollisionSphereRadius, this is expressed in the parent coordinate system.

Must return False when not Exists (because we can't express "empty sphere" by Sphere method for now, but BoundingBox can express TBox3D.Empty).

By default, in TCastleTransform class, this returns True if CollisionSphereRadius is non-zero.

The advantages of using a sphere, that does not have to be a perfect bounding sphere (it may be smaller than necessary, and only account e.g. for upper body part of the creature), are:

  • It can have constant radius, even though the actual creature animates. This allows us to perfectly, reliably guarantee that sphere absolutely never collides with level and such.

    In case of a tight bounding volume (box or sphere) that animates, this guarantee is not really possible. Simply increasing time changes the animation to the next frame, which may be slightly larger in one dimension because e.g. creature moves a hand in this direction. This means that simply increasing time may change the non-collidable creature into a collidable one, if creature stands close to a wall/other creature and such. And we cannot simply stop/reverse an arbitrary animation at an arbitrary time (to avoid collision), this would look weird for some animations and would require some additional work at preparing animations and designing AI (as then "every action can be interrupted").

    Also using a bounding volume large enough to account for all possible positions is not doable, as it would be too large. Consider that for humanoid creatures, walking animation usually has tall and thin bounding box (creature stands) but dead/lying animation usually has flat and wide bounding box.

    So, only a bounding volume (like a sphere) that may be smaller than bounding volume can remain constant and easily guarantee the assertion "it never collides".

    This means that using such sphere results in simpler collision detection routines, as they may assume that collision doesn't occur. In contrast, detection routines looking at our (possibly animated) BoundingBox must take into account that collision may already be happening, and they must incorporate code to allow creatures/players to "get unstruck".

  • Using smaller sphere also allows to naturally ascend the stairs and upward slopes. Sphere can move forward slightly, and then creature may raise up, to reach it's preferred height. Then sphere can move further forward, and so on. This alllows to allow stair climbing for creatures without any extra effort in the code.

    The downside is that creature legs will temporarily "sink into the floor" when climbing up the stairs. But it's not noticeable if "growing up" mechanism works fast enough.

Sphere disadvantage:

  • Sphere is far from perfect as a bounding volume — it's too small, sometimes also too large, sometimes both at the same time...

    Since the Sphere radius remains always the same, it must be good for many creature animation frames. In cases where the sphere isn't suitable, and you don't need advantages above — you can make Sphere return False. E.g. a dead creature may be stuck in a wall, and it doesn't have to climb stairs. So you don't really need sphere advantages listed above, and Sphere may return False when creature is in dying state.

    But still it may be a problem sometimes, if some creature states have entirely different animations and bounding boxes. Then you will be forced to choose one universal Radius for all creature states. And you need constant radius to keep the advantage above of "guarantee".

    1. Obviously you can't set radius too small, because if it's much smaller than actual creature's geometry then the creature will noticeably collide with level geometry and other creatures.

    2. On the other hand, you can't set radius too large (or move sphere center, Middle, much lower). This would block stair climbing.

Public function Height(const MyPosition: TVector3; out AboveHeight: Single): boolean; overload;

Get height of my point above the rest of the world.

The given MyPosition, and returned AboveHeight, are in the parent coordinate system of this TCastleTransform. So for example query like this works naturally: MyTransform.Height(MyTransform.Translation, ...).

This ignores the geometry of this 3D object (to not accidentally collide with your own geometry), and checks collisions with the rest of the world.

Public function Height(const MyPosition: TVector3; out AboveHeight: Single; out AboveGround: PTriangle): boolean; overload;

This item has no description.

Public function LineOfSight(const Pos1, Pos2: TVector3): boolean;

Whether there is line of sight (the line segment does not collide with anything opaque) between these 2 points.

The given Pos1, Pos2 are in the parent coordinate system of this TCastleTransform. So for example query like this works naturally: MyTransform.LineOfSight(MyTransform.Translation, MyTransform.Translation + MyTransform.Direction * 10).

This ignores the geometry of this 3D object (to not accidentally collide with your own geometry), and checks collisions with the rest of the world.

Public function MoveAllowed(const OldPos, ProposedNewPos: TVector3; out NewPos: TVector3; const BecauseOfGravity: boolean): boolean; overload;

Is the move from OldPos to ProposedNewPos possible for this object. Returns true and sets NewPos if some move is allowed.

The NewPos may be different than ProposedNewPos, which allows to perform wall-sliding. Wall sliding will only work if collision sphere is defined, which should be configured by setting CollisionSphereRadius to something non-zero. Otherwise, the move uses only box collisions, and wall sliding doesn't happen.

When checking collisions, it avoids colliding with itself, so it only checks collisions with the rest of the world (things outside of this TCastleTransform).

The given OldPos, ProposedNewPos, NewPos are in the parent coordinate system of this TCastleTransform. Intuitively, you are asking "Can I change Translation from OldPos to NewPos". So this method is consistent with Move, Translate.

Public function MoveAllowed(const OldPos, NewPos: TVector3; const BecauseOfGravity: boolean): boolean; overload;

Is the move from OldPos to NewPos possible for this object.

This overloaded version of MoveAllowed doesn't do wall-sliding (use the version with ProposedNewPos for wall-sliding).

If this object allows to use sphere for collisions (see CollisionSphereRadius and Sphere) then sphere will be used. Otherwise, it will collide as a bounding box.

When checking collisions, it avoids colliding with itself, so it only checks collisions with the rest of the world (things outside of this TCastleTransform).

The given OldPos, NewPos are in the parent coordinate system of this TCastleTransform. Intuitively, you are asking "Can I change Translation from OldPos to NewPos". So this method is consistent with Move, Translate.

Public function Ray(const RayOrigin, RayDirection: TVector3): TRayCollision;

Cast a ray, see what is hit (checks the whole world, not just this TCastleTransform hierarchy).

The given RayOrigin, RayDirection are in the parent coordinate system of this TCastleTransform. So for example query like this works naturally: MyTransform.Ray(MyTransform.Translation, MyTransform.Direction).

This ignores the geometry of this object (to not accidentally collide with your own geometry), and checks collisions with the rest of the world.

Public function RayCast(const RayOrigin, RayDirection: TVector3): TCastleTransform; overload;

Cast a ray, see what is hit (checks the whole world, not just this TCastleTransform hierarchy).

The given RayOrigin, RayDirection are in the parent coordinate system of this TCastleTransform. So for example query like this works naturally: MyTransform.RayCast(MyTransform.Translation, MyTransform.Direction). In case of the overloaded version with Distance parameter, the Distance is consistently in the same, parent coordinate system.

This ignores the geometry of this object (to not accidentally collide with your own geometry), and checks collisions with the rest of the world.

This returns the TCastleTransform that is hit (this is the "leaf" TCastleTransform in the TCastleTransform tree that is hit) and a distance from RayOrigin to the hit point. Returns Nil (Distance is undefined in this case) if nothing was hit. Use Ray for a more advanced version of this, with more complicated result.

Public function RayCast(const RayOrigin, RayDirection: TVector3; out Distance: Single): TCastleTransform; overload;

This item has no description.

Public function OutsideToLocal(const Pos: TVector3): TVector3;

Convert position between local and outside coordinate system. This is called OutsideToLocal, not WorldToLocal, because it only handles transformation defined in this item — it does not recursively apply all transform on the way to root.

Public function LocalToOutside(const Pos: TVector3): TVector3;

This item has no description.

Public function WorldToLocal(const Pos: TVector3): TVector3;

Convert position between local and world coordinate system. This applies all the transformations on the way to root, so it looks at this object as well as all parents' transformations.

Public function LocalToWorld(const Pos: TVector3): TVector3;

This item has no description.

Public function WorldToLocalDirection(const Dir: TVector3): TVector3;

Convert direction between local and world coordinate system. This applies all the transformations on the way to root, so it looks at this object as well as all parents' transformations.

Public function LocalToWorldDirection(const Dir: TVector3): TVector3;

This item has no description.

Public function LocalToWorldDistance(const Distance: Single): Single;

Convert distance, like sphere radius, between local and world coordinate system. This applies all the scaling on the way to root, so it looks at this object as well as all parents' transformations.

Public function WorldToLocalDistance(const Distance: Single): Single;

This item has no description.

Public function PreferredHeight: Single; virtual; deprecated 'use physics (TCastleRigidBody, TCastleCollider) to make things affected by gravity';

Warning: this symbol is deprecated: use physics (TCastleRigidBody, TCastleCollider) to make things affected by gravity

The preferred height of the object Middle above the ground, when the object is standing on the ground firmly. This is used by objects affected by gravity (like non-flying creatures and items) to know how far they should fall down or grow up.

The default implementation in this class looks at MiddleHeight property, see the algorithm described there. This may be dynamic (may change during creature lifetime, so you can make the creature duck or grow if you want).

Public function Transform: TMatrix4;

Transformation (from local to outside) as a matrix. This matrix represents a concise version of properties like Translation, Rotation, Scale. It does not take into account the transformation of parent TCastleTransform (for this, use WorldTransform).

Public function InverseTransform: TMatrix4;

Inverse transformation as a matrix, thus transforming from outside to local coordinate system. This is an inverse of Transform.

Public function HasWorldTransform: boolean;

All conditions are satisfied to have WorldTransform. When this returns True, you know that WorldTransform and WorldInverseTransform will not raise ETransformParentUndefined.

Public function WorldTransform: TMatrix4;

Transformation (from local to world) as a matrix. This accumulates the transformation of this instance (derived from properties like Translation, Rotation, Scale) with the transformation of parent TCastleTransform instances, all the way up to and including the root transformation (TCastleAbstractRootTransform). Thus, this is a transformation to the world known to the TCastleViewport instance.

Two conditions are necessary to make this available:

You can check HasWorldTransform before calling this method, to avoid catching an exception.

Note that the WorldTransform is not updated in Update, it is smartly updated on-demand. So you do not have to wait for Update or other method to be called before accessing the WorldTransform.

Exceptions raised
ENotAddedToWorld
When this instance is not yet part of World.
EMultipleReferencesInWorld
When this instance is added multiple times to World.
ETransformParentUndefined
When this instance was once added multiple times to World, or for some other reason cannot be calculated. This is an ancestor of ENotAddedToWorld and EMultipleReferencesInWorld too.
Public function WorldInverseTransform: TMatrix4;

Inverse transformation of WorldTransform, thus transforming from world to local coordinate system.

See WorldTransform for more details how this works.

Exceptions raised
ENotAddedToWorld
When this instance is not yet part of World.
EMultipleReferencesInWorld
When this instance is added multiple times to World.
EMultipleReferencesInWorld
When this instance was once added multiple times to World, or for some other reason cannot be calculated. This is an ancestor of ENotAddedToWorld and EMultipleReferencesInWorld too.
Public procedure Translate(const TranslationChange: TVector3);

Unconditionally move this object by a given vector.

To move and check collisions, use Move instead of this method.

The provided TranslationChange should be a direction in the parent coordinate system of this TCastleTransform. Using this routine is exactly equivalent to Translation := Translation + TranslationChange.

Public function Move(const TranslationChange: TVector3; const BecauseOfGravity: boolean; const EnableWallSliding: boolean = true): boolean;

Move, if possible (checking collisions with other objects in world). This is the simplest way to move an object, and a basic building block for artificial intelligence of creatures.

Checks move possibility by MoveAllowed, using Middle point. Actual move is done using Translate.

Note that wall sliding will only work if collision sphere is defined, which should be configured by setting CollisionSphereRadius to something non-zero. Otherwise, the move uses only box collisions, and wall sliding doesn't happen.

The provided TranslationChange should be a direction in the parent coordinate system of this TCastleTransform, so using this routine is consistent with doing Translation := Translation + TranslationChange however this checks collisions.

Public procedure Identity;

Make the transform do nothing — zero Translation, zero Rotation, Scale to one. Also resets ScaleOrientation.

Public procedure GetView(out APos, ADir, AUp: TVector3);

Get at once vectors: position, direction, up.

Just like Translation and Rotation, these vectors reflect the transformation defined locally in this TCastleTransform, disregarding the parent transformations. Use GetWorldView to account for parent transformations.

Public procedure GetWorldView(out APos, ADir, AUp: TVector3);

Get position, direction, up. Similar to GetView, but in world coordinates.

Returned ADir and AUp are always orthogonal. Returned ADir and AUp are always normalized.

Public function WorldTranslation: TVector3;

Get position in world coordinates.

The returned position is the same as by GetWorldView. This method just doesn't calculation anything else, thus it is faster than GetWorldView if you don't need direction/up.

Public procedure SetView(const APos, ADir, AUp: TVector3; const AdjustUp: boolean = true); overload;

Set at once vectors: position, direction, up.

ADir and AUp given here do not have to be normalized (they will be normalized if needed). They will be automatically fixed to be orthogonal, if necessary: when AdjustUp = True (the default) we will adjust the up vector (preserving the given direction value), otherwise we will adjust the direction (preserving the given up value).

Just like Translation and Rotation, these vectors reflect the transformation defined locally in this TCastleTransform, disregarding the parent transformations. Use SetWorldView to account for parent transformations.

Public procedure SetView(const ADir, AUp: TVector3; const AdjustUp: boolean = true); overload;

This item has no description.

Public procedure SetWorldView(const APos, ADir, AUp: TVector3; const AdjustUp: boolean = true);

Set position, direction, up. Similar to SetView, but in world coordinates.

Given ADir, AUp do not have to be normalized, we will normalize them internally if necessary. But make sure they are non-zero.

We will automatically fix ADir and AUp to be orthogonal, if necessary: when AdjustUp = True (the default) we will adjust the up vector (preserving the given direction value), otherwise we will adjust the direction (preserving the given up value).

Public procedure UpPrefer(const AUp: TVector3);

Change up vector, keeping the direction unchanged. If necessary, the up vector provided here will be fixed to be orthogonal to direction.

This is similar to assigning Up vector using it's property setter, but different behavior happens when we need to fix vectors to have direction orthogonal to up (which must be always true). In case of assigning Up by property setter, the Direction vector is changed (if necessary, to be orthogonal to up). In case of this method, the up vector is changed (if necessary, to be orthogonal to direction).

It's good to use this if you have a preferred up vector for creatures, but still preserving the direction vector has the highest priority.

Public procedure AddBehavior(const Behavior: TCastleBehavior);

Add a TCastleBehavior to this TCastleTransform. In effect, the virtual methods of TCastleBehavior, like TCastleBehavior.Update, will be automatically called. Also the TCastleBehavior.Parent gets assigned. If the TCastleBehavior was part of another TCastleTransform, it is removed from it.

See also
FindBehavior
Find the first behavior of the given class, Nil if none.
BehaviorsEnumerate
You can enumerate current behaviors using loop like for B in MyTransform.BehaviorsEnumerate do ....
Public function BehaviorIndex(const Behavior: TCastleBehavior): Integer;

Returns behavior index, -1 means not found.

Public procedure RemoveBehavior(const Behavior: TCastleBehavior);

Remove TCastleBehavior from this TCastleTransform. In effect, the virtual methods of TCastleBehavior, like TCastleBehavior.Update, will no longer be automatically called. The TCastleBehavior.Parent is set to Nil.

Public function FindBehavior(const BehaviorClass: TCastleBehaviorClass): TCastleBehavior;

Find the first behavior of the given class, Nil if none.

Public function FindAllBehaviors(const BehaviorClass: TCastleBehaviorClass): TCastleBehaviorList;

Find all behaviors of given class, in this transform and children (up to any depth). The behaviors are added to the list, disregaring the Exists or ExistsInRoot property of parents. Returned class does not own children. The caller is responsible for freeing the returned list.

Public function FindRequiredBehavior(const BehaviorClass: TCastleBehaviorClass): TCastleBehavior;

Find the first behavior of the given class, or create and add a new one if necessary. Never returns Nil.

Public function BehaviorsCount: Integer;

Count of behaviors.

See also
AddBehavior
Add a TCastleBehavior to this TCastleTransform.
RemoveBehavior
Remove TCastleBehavior from this TCastleTransform.
Public function BehaviorsEnumerate: TCastleBehaviorEnumerator;

You can enumerate current behaviors using loop like for B in MyTransform.BehaviorsEnumerate do .... Do not call this method in other contexts, it is only useful for "for..in" construction.

Public procedure AddWorldChangeNotification(const Behavior: TCastleBehavior);

Adds a behavior to the list that needs to be informed about the world change. Adding multiple times the same behavior is harmless and has no effect.

Public procedure RemoveWorldChangeNotification(const Behavior: TCastleBehavior);

Removes a behavior from the list that needs to be informed about the world change.

Public function InternalBuildNode: TObject;

Create X3D nodes graph representing this TCastleTransorm (and its children). This can be used to save to any format supported by the SaveNode, like X3D and STL. See this news post for a summary of available features.

This method is internal, because:

  • It is not the adviced way to save TCastleTransform to file. Rather, we advise to save hierarchy using the TransformSave to .castle-transform files. See also CastleComponentSerialize. You can then reuse designs using the TCastleTransformDesign component. This is the way to reliably save and restore 100% of published properties of TCastleTransform and its descendants.

  • The export is not complete, and it will never be. X3D and other formats cannot express everything that Castle Game Engine components can express.

  • While you can load the resulting X3D back inside the engine editor, this will be just a single component TCastleScene, not all the components you exported.

    (though it could be an option some day, see https://castle-engine.io/expose ).

    Solution: If you want to use CGE editor for authoring X3D or other model formats, just keep the original CGE editor files around, as the "source" version of your 3D / 2D world and export it to X3D as many times as you wish.

That said, this is useful, because:

  • It allows to open things designed in CGE in X3D browsers, like Castle Model Viewer, Castle Model Viewer Mobile, X3DOM (in WWW browser), X_ITE (in WWW browser), FreeWRL. See X3D Resources for even more useful tools.

  • It's useful for debugging purposes when developing CGE.

    Since some CGE components are realized under the hood using X3D as well, e.g. light components like TCastlePointLight are mostly just wrappers for X3D nodes like TPointLightNode – just with somewhat better defaults and sometimes better naming. Though it is not guaranteed to always be like it (our own components allow us to implement lights without X3D nodes under the hood as well), but when it is -> this method allows to "peek under the hood" at nodes really used to render.

Result must be TTransformNode but it cannot be declared as such.

It exports content for all nodes, even csTransient, and thus it is never Nil. Caller should avoid check for csTransient in Transform.ComponentState if you want to avoid this.

Properties

Public property GetExists: Boolean read FExists; deprecated 'use Exists';

Warning: this symbol is deprecated: use Exists

This item has no description.

Public property Items[const I: Integer]: TCastleTransform read GetItem write SetItem;

List of current children.

Public property Parent: TCastleTransform read FParent write SetParent;

Parent TCastleTransform.

In most cases, a TCastleTransform is just a child of one other TCastleTransform, and then this property returns this natural parent.

Returns Nil if TCastleTransform is not a child of any other TCastleTransform.

Setting this property removes us from old parent, and adds to the new one. The local transformation (translation, rotation, scale) doesn't change, so changing parent may change the effective (world) transformation of the object.

In rare cases the child can have multiple parents. The behavior is then:

Public property UniqueParent: TCastleTransform read FParent; deprecated 'use Parent';

Warning: this symbol is deprecated: use Parent

This item has no description.

Public property CastShadowVolumes: boolean read FCastShadows write FCastShadows default true; deprecated 'use CastShadows';

Warning: this symbol is deprecated: use CastShadows

Does the 3D object cast shadows by shadow volumes. See also TCastleScene.ReceiveShadowVolumes.

Public property ListenPressRelease: Boolean read FListenPressRelease write SetListenPressRelease default false;

Are Press and Release virtual methods called.

Public property World: TCastleAbstractRootTransform read FWorld;

Root transformation (TCastleAbstractRootTransform) containing us. Nil if we are not (yet) part of some hierarchy rooted in TCastleAbstractRootTransform.

Public property WorldDirection: TVector3 read GetWorldDirection write SetWorldDirection;

Our Direction, in world coordinates.

Public property CollidesWithMoving: boolean read FCollidesWithMoving write FCollidesWithMoving default false;

Can this object be pushed by (or block movement of) doors, elevators and other moving level parts (TCastleMoving instances).

Some 3D moving objects may try to avoid crushing this item. Like an automatic door that stops it's closing animation to not crush things standing in the doorway.

Some other 3D moving objects may push this object. Like elevators (vertical, or horizontal moving platforms). We may use sphere (see CollisionSphereRadius and Sphere) for checking collisions, or bounding box (TCastleTransform.BoundingBox), depending on need.

Public property Gravity: boolean read FGravity write FGravity default false; deprecated 'use physics (TCastleRigidBody, TCastleCollider) to make things affected by gravity';

Warning: this symbol is deprecated: use physics (TCastleRigidBody, TCastleCollider) to make things affected by gravity

Gravity may make this object fall down (see FallSpeed) or grow up (see GrowSpeed). See also PreferredHeight.

Special notes for TPlayer: player doesn't use this (TPlayer.Gravity should remain False), instead player relies on TPlayer.Navigation.Gravity = True, that does a similar thing (with some extras, to make camera effects). This will change in the future, to merge these two gravity implementations. Although the TPlayer.Fall method still works as expected (it's linked to TCastleWalkNavigation.OnFall in this case).

Public property FallSpeed: Single read FFallSpeed write FFallSpeed default 0; deprecated 'use physics (TCastleRigidBody, TCastleCollider) to make things affected by gravity';

Warning: this symbol is deprecated: use physics (TCastleRigidBody, TCastleCollider) to make things affected by gravity

Falling speed, in units per second, for Gravity.

This is relevant only if Gravity and PreferredHeight <> 0. 0 means no falling.

Public property GrowSpeed: Single read FGrowSpeed write FGrowSpeed default 0; deprecated 'use physics (TCastleRigidBody, TCastleCollider) to make things affected by gravity';

Warning: this symbol is deprecated: use physics (TCastleRigidBody, TCastleCollider) to make things affected by gravity

Growing (raising from crouching to normal standing position) speed, in units per second. This is used by non-flying creatures when climbing up stairs, in which case Translation ("legs positon") may be sometimes under the ground while Middle ("eyes position") will be always above the ground and will try to grow to be at PreferredHeight above the ground.

This is relevant only if Gravity and PreferredHeight <> 0. 0 means no growing.

Public property MiddleHeight: Single read FMiddleHeight write FMiddleHeight default DefaultMiddleHeight;

How high are creature eyes in the model. Value 0 means that eyes are at the bottom of the model, 0.5 means the middle, 1 means top.

The top is always considered to be at the top of the bounding box.

Definition of bottom depends on Gravity:

  • When Gravity is True, then the bottom is considered to be the plane where World.GravityCoordinate (like Z or Y axis) is zero. The actual bottom (lowest point) of the bounding box doesn't matter. This means that things placed below zero plane (like a creature tentacle or leg) will sink into the ground, instead of causing whole creature to move up. It also means that the creature can easily float above the ground, just model it a little above the zero plane.

    In other words, this allows you to model the creature with respect to the ground (zero plane), which is comfortable.

    Note that setting MiddleHeight to exact 0 means that gravity will not work, as it means that the PreferredHeight above the ground is to be stuck right at the ground level.

    For gravity to work right, the MiddleHeight should be large enough to cause PreferredHeight to be > Sphere radius, for all possible animation states (for all possible bounding box values).

  • When Gravity is False, then the bottom is considered at the bottom of the bounding box.

    This way it works regardless of where (0,0,0) is in your model (regardless if (0,0,0) represents legs, or middle of your creature), since we adjust to the BoundingBox position.

This property determines how the TCastleTransform handles the Middle implementation (this is the point used for various collision detection routines) and PreferredHeight (this is the preferred height of Middle above the ground). You can override these two methods to use a different approach, and then ignore MiddleHeight completely.

Public property Translation: TVector3 read FTranslation write SetTranslation;

Translation (move) the children. Zero by default.

Set it like this:

Scene.Translation := Vector3(1, 2, 3);
Scene.Translation := Scene.Translation + Vector3(4, 5, 6);

Public property TranslationXY: TVector2 read GetTranslationXY write SetTranslationXY;

Get or set the XY components of the translation. Useful for 2D games.

Public property Center: TVector3 read FCenter write SetCenter;

Center point around which the Rotation and Scale is performed.

Public property Rotation: TVector4 read FRotation write SetRotation;

Rotation in 3D, around a specified axis. Rotation is expressed as a 4D vector, in which the first 3 components specify the rotation axis (does not need to be normalized, but must be non-zero) and the last component is the rotation angle in radians.

Note: the Rotation axis (first 3 components) must not be a zero vector, however as a special case the rotation value TVector4.Zero (so all components, axis and angle, are zero) is also allowed.

Rotation is done around Center.

Set it like this:

Scene.Rotation := Vector4(0, 0, 1, Pi / 10);
Scene.Rotation := Scene.Rotation + Vector4(0, 0, 0, Pi / 10);

To combine multiple rotations, you can use quaternion multiplication. For example to combine a rotation around Y axis with rotation around Z axis, you can do this:

var
  Q, Q1, Q2: TQuaternion;
begin
  Q1 := QuatFromAxisAngle(Vector3(0, 1, 0), 0.123);
  Q2 := QuatFromAxisAngle(Vector3(0, 0, 1), 0.456);
  Q := Q1 * Q2;
  MyTransform.Rotation := Q.ToAxisAngle;
end;

Combining rotations this way is very flexible. You can combine as many as you want, and it is clear (you define it yourself) in which order each rotation is applied. Note that you can also just nest one TCastleTransform within another TCastleTransform, and set different rotations on each of them, to also effectively combine the rotations.

Public property Scale: TVector3 read FScale write SetScale;

Scale in 3D. Scaling is done around Center and with orientation given by ScaleOrientation.

We do the best we can to work with any scale value, even negative or zero. But usually, it's best to keep the scale positive. More information:

  1. If you can, keep the scale uniform, that is scale equal amount in X, Y and Z. For example set scale = (3.0, 3.0, 3.0) to scale 3x times, and avoid scale like (3.0, 1.0, 1.0) that scales more in one direction.

    Non-uniform scale works, but some collisions are not perfectly calculated then:

    Note that ScaleOrientation matters only in case of non-uniform scale.

  2. All scale components should > 0 if you want 3D lighting to work corrrectly. That is, avoid negative scale, that changes the normals and orientation of faces (counter-clockwise becomes clockwise, if all scale components are -1), or standard lighting may not work Ok.

    For unlit stuff, or custom lighting, negative scale may be Ok. For many 2D games that use no lighting/custom lighting, negative scale is Ok.

    If you really need to use negative scale and lighting, enable TCastleRenderOptions.RobustNegativeScale.

  3. At least, keep all scale components non-zero. Otherwise the scaling operation is not invertible, and generally collisions will not work correctly.

    If you really need to set zero scale, the object should not be collidable then. Set Collides = False and don't add TCastleCollider as a behavior.

Set it like this:

Scene.Scale := Vector3(5, 5, 5);
Scene.Scale := Scene.Scale * 1.5;

Public property ScaleOrientation: TVector4 read FScaleOrientation write SetScaleOrientation;

Orientation in which 3D Scale is performed.

Public property RigidBody: TCastleRigidBody read FCachedRigidBody;

Current TCastleRigidBody behavior that determines do we participate in the physics simulation.

This property is always exactly equivalent to using FindBehavior(TCastleRigidBody) as TCastleRigidBody. It is just a more convenient (and marginally faster) way to access this common behavior.

See physics manual for an overview of using physics. You need to add both TCastleRigidBody and TCastleCollider to make physics work. Then this object is collidable with other rigid bodies, it can move and rotate because of gravity or because of collisions with other objects (if TCastleRigidBody.Dynamic is True).

It is not possible to set this property. Instead use AddBehavior to add an instance of TCastleRigidBody to the behaviors list. If there was a previous TCastleRigidBody instance, you can decide what to do with it, e.g. you can remove it using RemoveBehavior.

Note that an object can only be present once in the World to be a rigid body. Breaking this rule will cause the EMultipleReferencesInWorld exception at an undefined time.

Public property Collider: TCastleCollider read FCachedCollider;

Current TCastleCollider behavior that determines what is the shape of this object when it participates in the physics simulation.

This property is always exactly equivalent to using FindBehavior(TCastleCollider) as TCastleCollider. It is just a more convenient (and marginally faster) way to access this common behavior.

See physics manual for an overview of using physics. You need to add both TCastleRigidBody and TCastleCollider to make physics work. Then this object is collidable with other rigid bodies, it can move and rotate because of gravity or because of collisions with other objects (if TCastleRigidBody.Dynamic is True).

It is not possible to set this property. Instead use AddBehavior to add an instance of TCastleCollider to the behaviors list. If there was a previous TCastleCollider instance, you can decide what to do with it, e.g. you can remove it using RemoveBehavior.

Note that an object can only be present once in the World to be a rigid body. Breaking this rule will cause the EMultipleReferencesInWorld exception at an undefined time.

Public property Position: TVector3 read FTranslation write SetTranslation; deprecated 'use Translation';

Warning: this symbol is deprecated: use Translation

Deprecated name for Translation.

Public property Direction: TVector3 read GetDirection write SetDirection;

Direction that this transformation (like creature, space ship, missile, a camera...) is facing. The property Up contains an associated up vector. Together, the Direction and Up properties provide an alternative way to get and set the Rotation of the transformation.

Thinking in terms of "direction" and "up" is more natural than thinking about Rotation for various game objects. For example, you can move a missile forward by this simple operation:

MyMissile.Translation := MyMissile.Translation +
  MyMissile.Direction * SecondsPassed * MissileMoveSpeed;

The Orientation determines what is the direction and up you get when the Rotation is zero. For example Orientation = otUpYDirectionZ (default now) means that:

  1. When Rotation is zero, then Up will be +Y axis (0,1,0) and Direction will be +Z axis (0,0,1).

  2. Setting the Direction and Up to other values will be properly converted.

  3. So when Orientation = otUpYDirectionZ, and you set

    MyMissile.Direction := Vector3(0, 0, 1);
    MyMissile.Up := Vector3(0, 1, 0);

    then you effectively have set MyMissile.Rotation to zero (no rotation). That is, you could have as well done just this:

    MyMissile.Rotation := TVector4.Zero;

    Note that you can also set direction and up more efficiently by one SetView call. So this is one more way to do it, also equivalent:

    MyMissile.SetView(Vector3(0, 0, 1), Vector3(0, 1, 0));

Note that changing Orientation property does not perform any transformation of the model, it will look the same as it was, no matter what Orientation you set. Only changing the Direction or Up actually change the Rotation, which in turn actually change how the model looks. This also implies that Orientation value completely doesn't matter if you never get or set Direction or Up. All engine rendering and processing just looks at Rotation.

See Orientation for documentation of its default value.

The Direction and Up vectors should always be normalized (have length 1). But when setting them by these properties, we will normalize them automatically, so you don't need to worry about that.

The direction and up vectors must always be orthogonal. When setting Direction, Up will always be automatically adjusted to be orthogonal to Direction. And vice versa — when setting Up, Direction will be adjusted.

Public property Up: TVector3 read GetUp write SetUp;

This item has no description.

Public property WorldView: TViewVectors read GetWorldViewRec write SetWorldViewRec;

Position, direction and up in world coordinates.

Returned TViewVectors.Direction and TViewVectors.Up are always orthogonal. Returned TViewVectors.Dir and TViewVectors.Up are always normalized.

When setting, TViewVectors.Direction and TViewVectors.Up do not need to be normalized. We will internally normalize them if necessary.

When setting, we will also automatically fix TViewVectors.Direction and TViewVectors.Up to be orthogonal, if necessary: we will adjust the up vector (preserving the given direction value).

Public property Orientation: TOrientationType read FOrientation write FOrientation;

How the direction and up vectors determine transformation. See TOrientationType for values documentation.

The default value of this is:

This value determines how you should model your 3D models, like the creatures, the items, and the player weapons.

Public property List: TCastleTransformList read FList;

Transformation objects inside. Freeing these items automatically removes them from this list.

Public property Behaviors [const Index: Integer]: TCastleBehavior read GetBehaviors;

Enumerate current behaviors.

See also
AddBehavior
Add a TCastleBehavior to this TCastleTransform.
RemoveBehavior
Remove TCastleBehavior from this TCastleTransform.
Public property ExistsInRoot: Boolean read FExistsInRoot;

Does this object, and all it's parents up to the root, exist. This has undefined value in case you place this TCastleTransform instance (or any parent) many times within the viewport root, and some parents exist while some not.

This property doesn't check whether this TCastleTransform is actually part of some World. So it will be True if this item doesn't have any parent. It only checks that "all parents, going up the tree, have Exists true".

Published property Exists: Boolean read FExists write SetExists default true;

Is this object (and all children) visible and colliding. Setting this to False makes this object non-existing, just as if removing the object from parent would do.

Non-existing object implies also that all children are non-existing. Behaviors on non-existing objects should also stop working, e.g. physics engine should ignore bodies / colliders attached to non-existing objects, and (TODO) TCastleSoundsource should not play when attached to non-existing object.

Published property Collides: boolean read FCollides write FCollides default true;

Should this collide when simple physics is used. This setting is honored e.g. by current collisions done by FPS walk/fly navigation using TCastleWalkNavigation. This setting is ignored by the physics engine (for physics, control if something collides just by adding / removing a TCastleCollider component).

You can turn this off, useful to make e.g. "fake" walls (to some secret places on level).

This describes collision resolution with almost everything — camera, player (in third-person perspective, camera may differ from player), other creatures. That is because everything resolves collisions through our methods MoveCollision and HeightCollision (high-level) or SegmentCollision, SphereCollision, SphereCollision2D, PointCollision2D, BoxCollision (low-level).

(Note that RayCollision is excluded from this, it exceptionally ignores Collides value, as it's primarily used for picking. Same for SegmentCollision with LineOfSight=true.)

The only exception are the collisions with TCastleMoving instances (movable world parts like elevators and doors) that have their own detection routines and look at CollidesWithMoving property of other objects. That is, the TCastleMoving instance itself must still have Collides = True, but it interacts with other objects if and only if they have CollidesWithMoving = True (ignoring their Collides value). This allows items to be moved by elevators, but still player and creatures can pass through them.

Note that if not Exists then this doesn't matter (non-existing objects never participate in collision detection).

Published property Pickable: boolean read FPickable write FPickable default true;

Is item pickable by RayCollision method. Note that if not Exists then this doesn't matter (non-existing objects are never pickable).

This affects ray collisions only for some methods that are part of old simple physics. This setting is ignored by the physics engine.

This is independent from Collides, as RayCollision does not look at Collides, it only looks at Pickable.

Published property Visible: boolean read FVisible write FVisible default true;

Is this object (and all children) visible. Note that if not Exists then this doesn't matter (non-existing objects are never visible).

Just like most TCastleTransform properties, this affects both this TCastleTransform instance (which may be a TCastleScene instance) and all children, recursively. In other words, setting this to False hides this object and all children.

This is independent from Collides or Pickable.

Published property CollisionSphereRadius: Single read FCollisionSphereRadius write FCollisionSphereRadius;

When non-zero, we can approximate collisions with this object using a sphere in certain situations (MoveAllowed, Gravity). This usually makes dynamic objects, like player and creatures, collide better.

Just like Middle, this is expressed in the parent coordinate system.

Published property CastShadows: boolean read FCastShadows write FCastShadows default true;

Does this object (and children) cast shadows.

Just like most TCastleTransform properties, this affects both this TCastleTransform instance (which may be a TCastleScene instance) and all children, recursively. In other words, setting this to False makes this object and all children not cast shadows.

TODO: Right now this only affects casting shadows by shadow volumes. It will be extended to account for shadow maps.

Published property RenderLayer: TRenderLayer read FRenderLayer write FRenderLayer default rlParent;

Objects on front render layer are rendered in front of objects on back render layer, regardless of their actual position (depth) relative to camera.

rlParent means that object follows the parent layer, which is by default back.

The typical use-case is to force some object to be in front, by setting rlFront.

Published property CenterPersistent: TCastleVector3Persistent read FCenterPersistent ;

Center that can be visually edited in Castle Game Engine Editor, Lazarus and Delphi. Normal user code does not need to deal with this, instead read or write Center directly.

See also
Center
Center point around which the Rotation and Scale is performed.
Published property RotationPersistent: TCastleVector4RotationPersistent read FRotationPersistent ;

Rotation that can be visually edited in Castle Game Engine Editor, Lazarus and Delphi. Normal user code does not need to deal with this, instead read or write Rotation directly.

See also
Rotation
Rotation in 3D, around a specified axis.
Published property ScalePersistent: TCastleVector3Persistent read FScalePersistent ;

Scale that can be visually edited in Castle Game Engine Editor, Lazarus and Delphi. Normal user code does not need to deal with this, instead read or write Scale directly.

See also
Scale
Scale in 3D.
Published property ScaleOrientationPersistent: TCastleVector4Persistent read FScaleOrientationPersistent ;

ScaleOrientation that can be visually edited in Castle Game Engine Editor, Lazarus and Delphi. Normal user code does not need to deal with this, instead read or write ScaleOrientation directly.

See also
ScaleOrientation
Orientation in which 3D Scale is performed.
Published property TranslationPersistent: TCastleVector3Persistent read FTranslationPersistent ;

Translation that can be visually edited in Castle Game Engine Editor, Lazarus and Delphi. Normal user code does not need to deal with this, instead read or write Translation directly.

See also
Translation
Translation (move) the children.
Published property DirectionPersistent: TCastleVector3Persistent read FDirectionPersistent stored false;

Direction that can be visually edited in Castle Game Engine Editor, Lazarus and Delphi. Normal user code does not need to deal with this, instead read or write Direction directly.

See also
Direction
Direction that this transformation (like creature, space ship, missile, a camera...) is facing.
Published property UpPersistent: TCastleVector3Persistent read FUpPersistent stored false;

Up that can be visually edited in Castle Game Engine Editor, Lazarus and Delphi. Normal user code does not need to deal with this, instead read or write Up directly.

See also
Up

Generated by PasDoc 0.16.0-snapshot.