Castle Game EngineIntroduction Units Class Hierarchy Classes, Interfaces, Objects and Records Types Variables Constants Functions and Procedures Identifiers

Object TFrustum
Unit
CastleFrustum
Declaration
type TFrustum = object(TObject)
Description
Viewing frustum, defined as 6 plane equations. Calculating and operating on such frustum. Frustums with far plane in infinity (typically used in conjunction with shadow volumes) are fully supported by all methods (we just have 5 frustum planes then).
We define this using ObjectPascal oldstyle "object", to have comfort and lowoverhead at the same time.
Hierarchy
Overview
Fields
Methods
Description
Fields

Planes: array [TFrustumPlane] of TVector4Single; 
Six planes defining the frustum. Direction vectors of these planes must point to the inside of the frustum. Currently, they are always normalized.
Note that if projection has far plane in infinity (indicated by ZFarInfinity) then the far plane will be invalid — first three values of it's equation will be 0.


ZFarInfinity: boolean; 

Methods

constructor Init(const Matrix: TMatrix4Single); 
Calculate frustum, knowing the combined matrix (modelview * projection).


constructor Init(const ProjectionMatrix, ModelviewMatrix: TMatrix4Single); 
Calculate frustum, knowing projection and modelview matrices. This is equivalent to 1parameter Init with Matrix = ModelviewMatrix * ProjectionMatrix. This way you can get from OpenGL your two matrices (modelview and projection) (or you can calculate them using routines like FrustumProjectionMatrix), then pass them to this routine and you get your current viewing frustum.


procedure CalculatePoints(out FrustumPoints: TFrustumPointsSingle); overload; 
Calculate 8 points of frustum. These points are simply calculated doing ThreePlanesIntersectionPoint on appropriate planes.
Using these points you can easily draw given frustum on screen. Use FrustumPointsQuadsIndexes to obtain indexes to FrustumPoints.
Note that when the far plane is in infinity, the 4 points of the far plane will be "in infinity", that is will have 4th component set to zero. Or, equivalently, they will be directions. Homogeneous coordinates allow us for this, and in fact you can just render such points without any problems in OpenGL.
For good precision, always use TFrustumPointsDouble. Tests show that, while storing the plane equations with Single precision is sufficient, calculating FrustumPoints using Single precision is *not* sufficient.
(Testcase that the Double precision is needed: run view3dscene demo_models/vrml_2/cones.wrl . Jump to viewpoint named "Frustum needs doubleprecision". Turn "Show viewing frustum" on. When view3dscene.lpr uses Single precision with CalculatePoints (use TFrustumPointsSingle, and GL_FLOAT at glVertexPointer) the result is incorrect, near and far quads are visibly asymetrical.)
Exceptions raised
 EPlanesParallel
 If Frustum doesn't have planes of any valid frustum.


function SphereCollisionPossible( const SphereCenter: TVector3Single; const SphereRadiusSqr: Single): TFrustumCollisionPossible; 
Checks for collision between frustum and sphere.
Check is done fast, but is not accurate, that's why this function's name contains "CollisionPossible". It returns:
fcNoCollision when it's sure that there no collision,
fcSomeCollisionPossible when some collision is possible, but nothing is sure. There *probably* is some collision, but it's not difficult to find some special situations where there is no collision but this function answers fcSomeCollisionPossible. There actually may be either no collision, or only part of sphere may be inside frustum.
Note that it's guaranteed that if the whole sphere (or the whole box in case of Box3DCollisionPossible) is inside the frustum that fcInsideFrustum will be returned, not fcSomeCollisionPossible.
fcInsideFrustum if sphere is for sure inside the frustum.
So this function usually cannot be used for some precise collision detection, but it can be used for e.g. optimizing your graphic engine by doing frustum culling. Note that fcInsideFrustum result is often useful when you're comparing your frustum with bounding volume of some tree (e.g. octree) node: fcInsideFrustum tells you that not only this node collides with frustum, but also all it's children nodes collide for sure with frustum. This allows you to save some time instead of doing useless recursion down the tree.
Many useful optimization ideas used in implementing this function were found at [http://www.flipcode.com/articles/article_frustumculling.shtml].
See also
 TFrustum.Box3DCollisionPossible
 Checks for collision between frustum and box.


function Box3DCollisionPossibleSimple( const Box: TBox3D): boolean; 
Checks for collision between frustum and box, faster. Meaning of return value like SphereCollisionPossibleSimple.


function DirectionInside(const Direction: TVector3Single): boolean; 
Is Direction within a frustum. You can think of direction it as a "point infinitely away in given Direction", like the direction to the sun. Note that this ignores near/far planes of the frustum, only checking the 4 side planes.


function Transform(const M: TMatrix4Single): TFrustum; 
Transform frustum by a matrix.
Parameters
 M
 Transformation matrix. This matrix must be "sane": it must transform homogeneous positions into homogeneous positions, and homogeneous directions into homogeneous directions. Also, it must not invert or do other weird stuff (like shear) with directions. To be safe just make sure it's a matrix composed only from translations, rotations, and scale (with all scale parameters being > 0).
Exceptions raised
 ETransformedResultInvalid
 In some cases when matrix is not sane.


function ToNiceStr(const Indent: string): string; 

Generated by PasDoc 0.14.0.
