Castle Game Engine: X3DTriangles: Class TBaseTrianglesOctree

# Class TBaseTrianglesOctree
Description | Hierarchy | Fields | Methods | Properties
## Unit X3DTriangles ## Declaration `type TBaseTrianglesOctree = class(TOctree)` ## Description Abstract class for octrees that can check and return collisions with TTriangle. Octree node class used by this must be a TBaseTrianglesOctreeNode descendant. In a simple case, this is an ancestor of TTriangleOctree, that is just an octree storing TTriangle. But it's also an ancestor of TShapeOctree, since each shape has also a triangle octree. This way, TShapeOctree can calculate collisions with TTriangle, even though it doesn't directly store TTriangle items. ## Hierarchy TObject TOctree TBaseTrianglesOctree ## Overview ### Methods
| `function SegmentCollision( out Intersection: TVector3Single; out IntersectionDistance: Single; const pos1, pos2: TVector3Single; const ReturnClosestIntersection: boolean; const TriangleToIgnore: PTriangle; const IgnoreMarginAtStart: boolean; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc): PTriangle; overload;`
| `function SegmentCollision( out Intersection: TVector3Single; const pos1, pos2: TVector3Single; const ReturnClosestIntersection: boolean; const TriangleToIgnore: PTriangle; const IgnoreMarginAtStart: boolean; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc): PTriangle; overload;`
| `function SegmentCollision( out IntersectionDistance: Single; const pos1, pos2: TVector3Single; const ReturnClosestIntersection: boolean; const TriangleToIgnore: PTriangle; const IgnoreMarginAtStart: boolean; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc): PTriangle; overload;`
| `function SegmentCollision( const pos1, pos2: TVector3Single; const ReturnClosestIntersection: boolean; const TriangleToIgnore: PTriangle; const IgnoreMarginAtStart: boolean; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc): PTriangle; overload;`
| `function IsSegmentCollision( const pos1, pos2: TVector3Single; const TriangleToIgnore: PTriangle; const IgnoreMarginAtStart: boolean; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc): boolean;`
| `function SphereCollision(const pos: TVector3Single; const Radius: Single; const TriangleToIgnore: PTriangle; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc): PTriangle;`
| `function IsSphereCollision(const pos: TVector3Single; const Radius: Single; const TriangleToIgnore: PTriangle; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc): boolean;`
| `function BoxCollision(const ABox: TBox3D; const TriangleToIgnore: PTriangle; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc): PTriangle;`
| `function IsBoxCollision(const ABox: TBox3D; const TriangleToIgnore: PTriangle; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc): boolean;`
| `function RayCollision( out Intersection: TVector3Single; out IntersectionDistance: Single; const RayOrigin, RayDirection: TVector3Single; const ReturnClosestIntersection: boolean; const TriangleToIgnore: PTriangle; const IgnoreMarginAtStart: boolean; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc): PTriangle; overload;`
| `function RayCollision( out Intersection: TVector3Single; const RayOrigin, RayDirection: TVector3Single; const ReturnClosestIntersection: boolean; const TriangleToIgnore: PTriangle; const IgnoreMarginAtStart: boolean; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc): PTriangle; overload;`
| `function RayCollision( out IntersectionDistance: Single; const RayOrigin, RayDirection: TVector3Single; const ReturnClosestIntersection: boolean; const TriangleToIgnore: PTriangle; const IgnoreMarginAtStart: boolean; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc): PTriangle; overload;`
| `function RayCollision(const RayOrigin, RayDirection: TVector3Single; const ReturnClosestIntersection: boolean; const TriangleToIgnore: PTriangle; const IgnoreMarginAtStart: boolean; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc): PTriangle; overload;`
| `function IsRayCollision( const RayOrigin, RayDirection: TVector3Single; const TriangleToIgnore: PTriangle; const IgnoreMarginAtStart: boolean; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc): boolean;`
| `function MoveCollision( const OldPos, NewPos: TVector3Single; const IsRadius: boolean; const Radius: Single; const OldBox, NewBox: TBox3D; const TriangleToIgnore: PTriangle = nil; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc = nil): boolean;`
| `function MoveCollision( const OldPos, ProposedNewPos: TVector3Single; out NewPos: TVector3Single; const IsRadius: boolean; const Radius: Single; const OldBox, NewBox: TBox3D; const TriangleToIgnore: PTriangle = nil; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc = nil): boolean;`
| `function HeightCollision( const Position, GravityUp: TVector3Single; out AboveHeight: Single; out AboveGround: PTriangle; const TriangleToIgnore: PTriangle; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc): boolean;`
| `class function IgnoreTransparentItem( const Sender: TObject; const Triangle: P3DTriangle): boolean;`
| `class function IgnoreForShadowRays( const Sender: TObject; const Triangle: P3DTriangle): boolean;`
| `function LightNotBlocked(const Light: TLightInstance; const LightedPoint, LightedPointPlane, RenderDir: TVector3Single; const TriangleToIgnore: PTriangle; const IgnoreMarginAtStart: boolean): boolean;`
| `procedure EnumerateTriangles(EnumerateTriangleFunc: TEnumerateTriangleFunc); virtual; abstract;`
| `function TrianglesCount: Cardinal; virtual; abstract;`
## Description ### Methods
| `function SegmentCollision( out Intersection: TVector3Single; out IntersectionDistance: Single; const pos1, pos2: TVector3Single; const ReturnClosestIntersection: boolean; const TriangleToIgnore: PTriangle; const IgnoreMarginAtStart: boolean; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc): PTriangle; overload;`
Collision checking using the octree. SegmentCollision checks for collision between a line segment and tree items. SphereCollision checks for collision with a sphere. BoxCollision checks for collision with a box (axis-aligned, TBox3D type). RayCollision checks for collision with a ray. All there methods return nil if there is no collision, or a pointer to colliding item. ###### Parameters ReturnClosestIntersection If `False`, then any collision detected is returned. For routines that don't have ReturnClosestIntersection parameter (SphereCollision, BoxCollision) always any collision is returned. If this is `True`, then the collision closest to RayOrigin (for RayCollision) or Pos1 (for SegmentCollision) is returned. This makes the collision somewhat slower (as we have to check all collisions, while for ReturnClosestIntersection = `False` we can terminate at first collision found.) The versions that return boolean value (IsXxxCollision) don't take this parameter, as they are naturally interested in existence of any intersection. TriangleToIgnore If this is non-nil, then Segment/RayCollision assume that there is never a collision with this octree item. It's never returned as collidable item. This is useful for recursive ray-tracer, when you start tracing from some existing face (octree item). In this case, you don't want to "hit" the starting face. So you can pass this face as TriangleToIgnore. Note that IgnoreMarginAtStart helps with the same problem, although a little differently. TrianglesToIgnoreFunc If assigned, then items for which TrianglesToIgnoreFunc returns `True` will be ignored. This is a more general mechanism than TriangleToIgnore, as you can ignore many items, you can also make some condition to ignore — for example, you can ignore partially transparent items. IgnoreMarginAtStart If `True`, then collisions that happen very very close to RayOrigin (or Pos1 for SegmentCollision) will be ignored. This is another thing helpful for recursive ray-tracers: you don't want to hit the starting face, or any coplanar faces, when tracing reflected/refracted/shadow ray. Note that if you know actual pointer of your face, it's better to use TriangleToIgnore — TriangleToIgnore is a 100% guaranteed stable solution, while IgnoreMarginAtStart necessarily has some "epsilon" constant that determines which items are ignored. This epsilon may be too large, or too small, in some cases. In practice, recursive ray-tracers should use both TriangleToIgnore (to avoid collisions with starting face) and IgnoreMarginAtStart = `True` (to avoid collisions with faces coplanar with starting face). IntersectionDistance For RayCollision: Returned IntersectionDistance is the distance along the RayDirection: smaller IntersectionDistance, closer to RayOrigin. IntersectionDistance is always >= 0. Intersection is always equal to RayOrigin + RayDirection * IntersectionDistance. For SegmentCollision: analogously, IntersectionDistance is along Pos2 - Pos1. IntersectionDistance is always in 0...1. Intersectio is always equal to Pos1 + (Pos2 - Pos1) * IntersectionDistance.
| `function SegmentCollision( out Intersection: TVector3Single; const pos1, pos2: TVector3Single; const ReturnClosestIntersection: boolean; const TriangleToIgnore: PTriangle; const IgnoreMarginAtStart: boolean; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc): PTriangle; overload;`
| `function SegmentCollision( out IntersectionDistance: Single; const pos1, pos2: TVector3Single; const ReturnClosestIntersection: boolean; const TriangleToIgnore: PTriangle; const IgnoreMarginAtStart: boolean; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc): PTriangle; overload;`
| `function SegmentCollision( const pos1, pos2: TVector3Single; const ReturnClosestIntersection: boolean; const TriangleToIgnore: PTriangle; const IgnoreMarginAtStart: boolean; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc): PTriangle; overload;`
| `function IsSegmentCollision( const pos1, pos2: TVector3Single; const TriangleToIgnore: PTriangle; const IgnoreMarginAtStart: boolean; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc): boolean;`
| `function SphereCollision(const pos: TVector3Single; const Radius: Single; const TriangleToIgnore: PTriangle; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc): PTriangle;`
| `function IsSphereCollision(const pos: TVector3Single; const Radius: Single; const TriangleToIgnore: PTriangle; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc): boolean;`
| `function BoxCollision(const ABox: TBox3D; const TriangleToIgnore: PTriangle; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc): PTriangle;`
| `function IsBoxCollision(const ABox: TBox3D; const TriangleToIgnore: PTriangle; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc): boolean;`
| `function RayCollision( out Intersection: TVector3Single; out IntersectionDistance: Single; const RayOrigin, RayDirection: TVector3Single; const ReturnClosestIntersection: boolean; const TriangleToIgnore: PTriangle; const IgnoreMarginAtStart: boolean; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc): PTriangle; overload;`
| `function RayCollision( out Intersection: TVector3Single; const RayOrigin, RayDirection: TVector3Single; const ReturnClosestIntersection: boolean; const TriangleToIgnore: PTriangle; const IgnoreMarginAtStart: boolean; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc): PTriangle; overload;`
| `function RayCollision( out IntersectionDistance: Single; const RayOrigin, RayDirection: TVector3Single; const ReturnClosestIntersection: boolean; const TriangleToIgnore: PTriangle; const IgnoreMarginAtStart: boolean; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc): PTriangle; overload;`
| `function RayCollision(const RayOrigin, RayDirection: TVector3Single; const ReturnClosestIntersection: boolean; const TriangleToIgnore: PTriangle; const IgnoreMarginAtStart: boolean; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc): PTriangle; overload;`
| `function IsRayCollision( const RayOrigin, RayDirection: TVector3Single; const TriangleToIgnore: PTriangle; const IgnoreMarginAtStart: boolean; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc): boolean;`
| `function MoveCollision( const OldPos, NewPos: TVector3Single; const IsRadius: boolean; const Radius: Single; const OldBox, NewBox: TBox3D; const TriangleToIgnore: PTriangle = nil; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc = nil): boolean;`
Check is move allowed. This is the perfect (precise, using triangle mesh, and fast) implementation of T3D.MoveCollision interface. TriangleToIgnore and TrianglesToIgnoreFunc meaning is just like for RayCollision. This can be used to allow camera to walk thorugh some surfaces (e.g. through water surface, or to allow player to walk through some "fake wall" and discover secret room in game etc.).
| `function MoveCollision( const OldPos, ProposedNewPos: TVector3Single; out NewPos: TVector3Single; const IsRadius: boolean; const Radius: Single; const OldBox, NewBox: TBox3D; const TriangleToIgnore: PTriangle = nil; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc = nil): boolean;`
| `function HeightCollision( const Position, GravityUp: TVector3Single; out AboveHeight: Single; out AboveGround: PTriangle; const TriangleToIgnore: PTriangle; const TrianglesToIgnoreFunc: T3DTriangleIgnoreFunc): boolean;`
For given camera position and up vector, calculate camera height above the ground. This is comfortable for cooperation with TWalkCamera.OnHeight. See T3D.Height for specification. TriangleToIgnore and TrianglesToIgnoreFunc meaning is just like for RayCollision.
| `class function IgnoreTransparentItem( const Sender: TObject; const Triangle: P3DTriangle): boolean;`
Ignore (return `True`) transparent triangles (with Material.Transparency > 0). This is suitable for T3DTriangleIgnoreFunc function, you can pass this to RayCollision and such.
| `class function IgnoreForShadowRays( const Sender: TObject; const Triangle: P3DTriangle): boolean;`
Ignore (return `True`) transparent triangles (with Material.Transparency > 0) and non-shadow-casting triangles (with Appearance.shadowCaster = FALSE). This is suitable for T3DTriangleIgnoreFunc function, you can pass this to RayCollision and such.
| `function LightNotBlocked(const Light: TLightInstance; const LightedPoint, LightedPointPlane, RenderDir: TVector3Single; const TriangleToIgnore: PTriangle; const IgnoreMarginAtStart: boolean): boolean;`
Checks whether VRML Light (point or directional) lights at scene point LightedPoint. "Lights at scene" means that the light is turned on (field "on" is `True`) and between light source and a LightedPoint nothing blocks the light (we check it by querying collisions using the octree, ignoring transparent and non-shadow-casting triangles), and the light source is on the same side of LightedPointPlane as RenderDir. TriangleToIgnore and IgnoreMarginAtStart work just like for SegmentCollision. You should usually set TriangleToIgnore to the triangle containing your LightedPoint and IgnoreMarginAtStart to `True`, to avoid detecting point as shadowing itself.
| `procedure EnumerateTriangles(EnumerateTriangleFunc: TEnumerateTriangleFunc); virtual; abstract;`
Enumerate every triangle of this octree. It passes to EnumerateTriangleFunc callback a Triangle. Triangle is passed as a pointer (never `Nil`) — these are guaranteed to be "stable" pointers stored inside octrees' lists (so they will be valid as long as octree (and eventual children octrees for TShapeOctree)). Every triangle is guaranteed to have it's World coordinates updated (to put it simply, when this is used on TShapeOctree, then we call UpdateWorld on each triangle).
| `function TrianglesCount: Cardinal; virtual; abstract;`
Number of triangles within the octree. This counts all triangles returned by EnumerateTriangles.
Generated by PasDoc 0.13.0 on 2015-06-15 04:43:18