Castle Game Engine: CastleFrustum: Object TFrustum

# Object TFrustum
Description | Hierarchy | Fields | Methods | Properties
## 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 old-style "object", to have comfort and low-overhead at the same time. ## Hierarchy TObject TFrustum ## Overview ### Fields
| `Planes: array [TFrustumPlane] of TVector4Single;`
| `ZFarInfinity: boolean;`
### Methods
| `constructor Init(const Matrix: TMatrix4Single);`
| `constructor Init(const ProjectionMatrix, ModelviewMatrix: TMatrix4Single);`
| `procedure CalculatePoints(out FrustumPoints: TFrustumPointsSingle); overload;`
| `procedure CalculatePoints(out FrustumPoints: TFrustumPointsDouble); overload;`
| `function SphereCollisionPossible( const SphereCenter: TVector3Single; const SphereRadiusSqr: Single): TFrustumCollisionPossible;`
| `function SphereCollisionPossibleSimple( const SphereCenter: TVector3Single; const SphereRadiusSqr: Single): boolean;`
| `function Box3DCollisionPossible( const Box: TBox3D): TFrustumCollisionPossible;`
| `function Box3DCollisionPossibleSimple( const Box: TBox3D): boolean;`
| `function Move(const M: TVector3Single): TFrustum;`
| `procedure MoveTo1st(const M: TVector3Single);`
| `function DirectionInside(const Direction: TVector3Single): boolean;`
| `function Transform(const M: TMatrix4Single): TFrustum;`
| `function ToNiceStr(const Indent: string): string;`
## 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 1-parameter 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 in this unit like FrustumProjMatrix), 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. E.g. using OpenGL use code like this:
      glEnableClientState(GL_VERTEX_ARRAY);
        glVertexPointer(4, GL_FLOAT / GL_DOUBLE, 0, @FrustumPoints);

        glDrawElements(GL_QUADS,
          SizeOf(FrustumPointsQuadsIndexes) div SizeOf(LongWord),
          GL_UNSIGNED_INT, @FrustumPointsQuadsIndexes);
        // or
        glDrawElements(GL_LINES,
          SizeOf(FrustumPointsLinesIndexes) div SizeOf(LongWord),
          GL_UNSIGNED_INT, @FrustumPointsLinesIndexes);

      glDisableClientState(GL_VERTEX_ARRAY);
This example rendering code will even work Ok with far plane in infinity. Then 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 double-precision". 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.
| `procedure CalculatePoints(out FrustumPoints: TFrustumPointsDouble); overload;`
| `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 SphereCollisionPossibleSimple( const SphereCenter: TVector3Single; const SphereRadiusSqr: Single): boolean;`
Checks for collision between frustum and sphere, faster. Like TFrustum.SphereCollisionPossible, but this only returns true (when TFrustum.SphereCollisionPossible would return fcSomeCollisionPossible or fcInsideFrustum) or false (when TFrustum.SphereCollisionPossible would return fcNoCollision). Consequently, it runs (very slightly) faster. Use this if you don't need to differentiate between fcSomeCollisionPossible or fcInsideFrustum cases.
| `function Box3DCollisionPossible( const Box: TBox3D): TFrustumCollisionPossible;`
Checks for collision between frustum and box. Meaning of return value like SphereCollisionPossible.
| `function Box3DCollisionPossibleSimple( const Box: TBox3D): boolean;`
Checks for collision between frustum and box, faster. Meaning of return value like SphereCollisionPossibleSimple.
| `function Move(const M: TVector3Single): TFrustum;`
| `procedure MoveTo1st(const M: TVector3Single);`
| `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.13.0 on 2015-06-15 04:43:09