| Description | Hierarchy | Fields | Methods | Properties |
type TVRMLTriangleOctree = class(TOctree)
TVRMLTriangleOctree ————————————————————
![]() |
OctreeItems: TDynOctreeItemsArray; |
![]() |
DirectCollisionTestsCounter: TCollisionCount; |
![]() |
function StatisticsBonus( const LeavesCount, ItemsCount, NonLeafNodesCount: Int64): string; override; |
![]() |
function TreeRoot: TTriangleOctreeNode; |
![]() |
procedure AddItemTriangle(const Triangle: TTriangle3Single; State: TVRMLGraphTraverseState; ShapeNode: TNodeGeneralShape; const MatNum, FaceCoordIndexBegin, FaceCoordIndexEnd: integer); |
![]() |
function SegmentCollision( out Intersection: TVector3Single; out IntersectionDistance: Single; const pos1, pos2: TVector3Single; const ReturnClosestIntersection: boolean; const OctreeItemIndexToIgnore: integer; const IgnoreMarginAtStart: boolean; const ItemsToIgnoreFunc: TOctreeItemIgnoreFunc): integer; overload; |
![]() |
function SegmentCollision( out Intersection: TVector3Single; const pos1, pos2: TVector3Single; const ReturnClosestIntersection: boolean; const OctreeItemIndexToIgnore: integer; const IgnoreMarginAtStart: boolean; const ItemsToIgnoreFunc: TOctreeItemIgnoreFunc): integer; overload; |
![]() |
function SegmentCollision( out IntersectionDistance: Single; const pos1, pos2: TVector3Single; const ReturnClosestIntersection: boolean; const OctreeItemIndexToIgnore: integer; const IgnoreMarginAtStart: boolean; const ItemsToIgnoreFunc: TOctreeItemIgnoreFunc): integer; overload; |
![]() |
function SegmentCollision( const pos1, pos2: TVector3Single; const ReturnClosestIntersection: boolean; const OctreeItemIndexToIgnore: integer; const IgnoreMarginAtStart: boolean; const ItemsToIgnoreFunc: TOctreeItemIgnoreFunc): integer; overload; |
![]() |
function SphereCollision(const pos: TVector3Single; const Radius: Single; const OctreeItemIndexToIgnore: integer; const ItemsToIgnoreFunc: TOctreeItemIgnoreFunc): integer; |
![]() |
function BoxCollision(const ABox: TBox3d; const OctreeItemIndexToIgnore: integer; const ItemsToIgnoreFunc: TOctreeItemIgnoreFunc): Integer; |
![]() |
function RayCollision( out Intersection: TVector3Single; out IntersectionDistance: Single; const Ray0, RayVector: TVector3Single; const ReturnClosestIntersection: boolean; const OctreeItemIndexToIgnore: integer; const IgnoreMarginAtStart: boolean; const ItemsToIgnoreFunc: TOctreeItemIgnoreFunc): integer; overload; |
![]() |
function RayCollision( out Intersection: TVector3Single; const Ray0, RayVector: TVector3Single; const ReturnClosestIntersection: boolean; const OctreeItemIndexToIgnore: integer; const IgnoreMarginAtStart: boolean; const ItemsToIgnoreFunc: TOctreeItemIgnoreFunc): integer; overload; |
![]() |
function RayCollision( out IntersectionDistance: Single; const Ray0, RayVector: TVector3Single; const ReturnClosestIntersection: boolean; const OctreeItemIndexToIgnore: integer; const IgnoreMarginAtStart: boolean; const ItemsToIgnoreFunc: TOctreeItemIgnoreFunc): integer; overload; |
![]() |
function RayCollision(const Ray0, RayVector: TVector3Single; const ReturnClosestIntersection: boolean; const OctreeItemIndexToIgnore: integer; const IgnoreMarginAtStart: boolean; const ItemsToIgnoreFunc: TOctreeItemIgnoreFunc): integer; overload; |
![]() |
function MoveAllowedSimple( const OldPos, ProposedNewPos: TVector3Single; const CameraRadius: Single; const OctreeItemIndexToIgnore: integer = NoItemIndex; const ItemsToIgnoreFunc: TOctreeItemIgnoreFunc = nil): boolean; |
![]() |
function MoveBoxAllowedSimple( const OldPos, ProposedNewPos: TVector3Single; const ProposedNewBox: TBox3d; const OctreeItemIndexToIgnore: integer = NoItemIndex; const ItemsToIgnoreFunc: TOctreeItemIgnoreFunc = nil): boolean; |
![]() |
function MoveAllowed( const OldPos, ProposedNewPos: TVector3Single; out NewPos: TVector3Single; const CameraRadius: Single; const OctreeItemIndexToIgnore: integer; const ItemsToIgnoreFunc: TOctreeItemIgnoreFunc): boolean; |
![]() |
procedure GetCameraHeight( const CameraPos, GravityUp: TVector3Single; out IsAboveTheGround: boolean; out SqrHeightAboveTheGround: Single; out GroundItemIndex: Integer; const OctreeItemIndexToIgnore: integer; const ItemsToIgnoreFunc: TOctreeItemIgnoreFunc); |
![]() |
procedure GetCameraHeightZ( const CameraPos: TVector3Single; out IsAboveTheGround: boolean; out HeightAboveTheGround: Single; out GroundItemIndex: Integer; const OctreeItemIndexToIgnore: Integer; const ItemsToIgnoreFunc: TOctreeItemIgnoreFunc); |
![]() |
class function IgnoreTransparentItem( Octree: TVRMLTriangleOctree; OctreeItemIndex: Integer): boolean; |
![]() |
constructor Create(const ARootBox: TBox3d); overload; |
![]() |
constructor Create(AMaxDepth, AMaxLeafItemsCount: integer; const ARootBox: TBox3d); overload; |
![]() |
destructor Destroy; override; |
![]() |
OctreeItems: TDynOctreeItemsArray; |
|
tu beda zgromadzone wszystkie | |
![]() |
DirectCollisionTestsCounter: TCollisionCount; |
|
you can use variable below for testing purposes. It is increemented each time SphereCollision or SegmentCollision or RayCollision makes a direct collision test, that is when some single triangle is tested for collision with a sphere, line segment or ray. When we use octree we expect that this number will be small. | |
![]() |
function StatisticsBonus( const LeavesCount, ItemsCount, NonLeafNodesCount: Int64): string; override; |
![]() |
function TreeRoot: TTriangleOctreeNode; |
![]() |
procedure AddItemTriangle(const Triangle: TTriangle3Single; State: TVRMLGraphTraverseState; ShapeNode: TNodeGeneralShape; const MatNum, FaceCoordIndexBegin, FaceCoordIndexEnd: integer); |
|
Add single OctreeItem. Automatically checks whether IsValidTriangle. Przed dodaniem duzej ilosci trojkatow sugerowane jest aby ustalic OctreeItems.AllowedCapacityCount na odpowiednio duza wartosc. | |
![]() |
function SegmentCollision( out Intersection: TVector3Single; out IntersectionDistance: Single; const pos1, pos2: TVector3Single; const ReturnClosestIntersection: boolean; const OctreeItemIndexToIgnore: integer; const IgnoreMarginAtStart: boolean; const ItemsToIgnoreFunc: TOctreeItemIgnoreFunc): integer; overload; |
|
Ponizej mamy najwazniejsze procedury ktore wykorzystuja cala strukture jaka zbudowalismy zeby efektywnie badac kolizje. SegmentCollision bada czy segment nie przecina zadnego elementu drzewa SphereCollision bada czy sfera nie zawiera w sobie choc czesci jakiegos elementu drzewa. RayCollision bada przeciecie promienia z drzewem. Procedury zwracaja -1 (co preferujemy wyrazac jako NoItemIndex) jesli nie ma kolizji lub indeks do tablicy OctreeItems na element z ktorym jest kolizja. Pytanie brzmi "ktore przeciecie zwrocic jesli jest ich wiele ?". SphereCollision zwraca ktorykolwiek, podobnie jak Ray/SegmentCollision gdy (not ReturnClosestIntersection). Gdy ReturnClosestIntersection = true to RayCollision zwraca przeciecie najblizsze Ray0, SegmentCollision najblizsze pos1. (pamietaj ze placisz czasem wykonania za przekazanie ReturnClosestIntersection = true, wiec unikaj tego). Segment/RayCollision uwzgledniaja ze na pewno NIE MA przeciecia z elementem OctreeItemIndexToIgnore, podaj OctreeItemIndexToIgnore = NoItemIndex aby uwzglednial wszystkie elementy (przydatne przy rekurencyjnym ray-tracingu gdy nie chcesz zeby promien odbity/zalamany/cienia omylkowo trafil na powierzchnie z ktorej wlasnie "wychodzisz" - mozna by bylo temu zaradzic tez przez nieznacznie przesuwanie Ray0, ale niniejsza metoda jest duzo bardziej elegancka). OctreeItemIndexToIgnore to naturalnie indeks do tablicy OctreeItems, podobnie jak wynik wszystkich tych funkcji *Collision i podobnie jak elementy TTriangleOctreeNode.ItemsIndices[] Uwzgledniaja tez ze na pewno nie ma przeciecia z elementami dla ktorych ItemsToIgnoreFunc zwroci true (mozesz przekazac nil aby nie ignorowac nic na podstawie ItemsToIgnoreFunc). Ponadto jesli podasz IgnoreMarginAtStart to beda ignorowac przeciecia ktore zdarzyly sie *bardzo* blisko Ray0 (lub Pos1). W ten sposob raytracer bedzie w stanie poradzic sobie nawet ze scenami ktore maja nieprawidlowo zdefiniowane (czesciowo zachodzace na siebie) polygony. Takie polygony normalnie generowalyby zbedne cienie (zaslanialyby sie nawzajem). Pozornie podajac IgnoreMarginAtStart = true raytracer moglby czesto nie podawac juz OctreeItemIndexToIgnore (tzn. podac je = NoItemIndex), bo przeciez po to sie zazwyczaj podaje OctreeItemIndexToIgnore. Ale prawda jest taka ze IgnoreMarginAtStart nie daje 100% pewnosci ze unikniemy kolizji z elementem od ktorego zaczelismy (bo on przeciez tylko unika pewnego *malego* marginesu wokol Ray0). W rezultacie i tak nalezy uzywac OctreeItemIndexToIgnore. To raczej podawanie IgnoreMarginAtStart = true jest zbedne, ale niestety jest to pozadane i daje dobre efekty gdy przychodzi do nieprawidlowo zbudowanych scen. A nawet sibenik.3ds i office.mgf.wrl a wiec sceny zrobione niby porzadnie ktorych uzywalem do zasadniczych testow na rayhunterze maja gdzeniegdzie tak nieprawidlowo zbudowane sciany. Parameters
| |
![]() |
function SegmentCollision( out Intersection: TVector3Single; const pos1, pos2: TVector3Single; const ReturnClosestIntersection: boolean; const OctreeItemIndexToIgnore: integer; const IgnoreMarginAtStart: boolean; const ItemsToIgnoreFunc: TOctreeItemIgnoreFunc): integer; overload; |
![]() |
function SegmentCollision( out IntersectionDistance: Single; const pos1, pos2: TVector3Single; const ReturnClosestIntersection: boolean; const OctreeItemIndexToIgnore: integer; const IgnoreMarginAtStart: boolean; const ItemsToIgnoreFunc: TOctreeItemIgnoreFunc): integer; overload; |
![]() |
function SegmentCollision( const pos1, pos2: TVector3Single; const ReturnClosestIntersection: boolean; const OctreeItemIndexToIgnore: integer; const IgnoreMarginAtStart: boolean; const ItemsToIgnoreFunc: TOctreeItemIgnoreFunc): integer; overload; |
![]() |
function SphereCollision(const pos: TVector3Single; const Radius: Single; const OctreeItemIndexToIgnore: integer; const ItemsToIgnoreFunc: TOctreeItemIgnoreFunc): integer; |
![]() |
function BoxCollision(const ABox: TBox3d; const OctreeItemIndexToIgnore: integer; const ItemsToIgnoreFunc: TOctreeItemIgnoreFunc): Integer; |
![]() |
function RayCollision( out Intersection: TVector3Single; out IntersectionDistance: Single; const Ray0, RayVector: TVector3Single; const ReturnClosestIntersection: boolean; const OctreeItemIndexToIgnore: integer; const IgnoreMarginAtStart: boolean; const ItemsToIgnoreFunc: TOctreeItemIgnoreFunc): integer; overload; |
![]() |
function RayCollision( out Intersection: TVector3Single; const Ray0, RayVector: TVector3Single; const ReturnClosestIntersection: boolean; const OctreeItemIndexToIgnore: integer; const IgnoreMarginAtStart: boolean; const ItemsToIgnoreFunc: TOctreeItemIgnoreFunc): integer; overload; |
![]() |
function RayCollision( out IntersectionDistance: Single; const Ray0, RayVector: TVector3Single; const ReturnClosestIntersection: boolean; const OctreeItemIndexToIgnore: integer; const IgnoreMarginAtStart: boolean; const ItemsToIgnoreFunc: TOctreeItemIgnoreFunc): integer; overload; |
![]() |
function RayCollision(const Ray0, RayVector: TVector3Single; const ReturnClosestIntersection: boolean; const OctreeItemIndexToIgnore: integer; const IgnoreMarginAtStart: boolean; const ItemsToIgnoreFunc: TOctreeItemIgnoreFunc): integer; overload; |
![]() |
function MoveAllowedSimple( const OldPos, ProposedNewPos: TVector3Single; const CameraRadius: Single; const OctreeItemIndexToIgnore: integer = NoItemIndex; const ItemsToIgnoreFunc: TOctreeItemIgnoreFunc = nil): boolean; |
|
This checks if move between OldPos and ProposedNewPos is possible, by checking is segment between OldPos and ProposedNewPos free and sphere (with radius CameraRadius) ProposedNewPos is free. CameraRadius must obviously be > 0. See MoveAllowed for some more sophisticated way of collision detection. OctreeItemIndexToIgnore and ItemsToIgnoreFunc 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.). See also
| |
![]() |
function MoveBoxAllowedSimple( const OldPos, ProposedNewPos: TVector3Single; const ProposedNewBox: TBox3d; const OctreeItemIndexToIgnore: integer = NoItemIndex; const ItemsToIgnoreFunc: TOctreeItemIgnoreFunc = nil): boolean; |
|
This is like MoveAllowedSimple, but it checks for collision around ProposedNewPos using TBox3d instead of a sphere. | |
![]() |
function MoveAllowed( const OldPos, ProposedNewPos: TVector3Single; out NewPos: TVector3Single; const CameraRadius: Single; const OctreeItemIndexToIgnore: integer; const ItemsToIgnoreFunc: TOctreeItemIgnoreFunc): boolean; |
|
This is like MoveAllowedSimple, but in some cases where MoveAllowedSimple would answer "false", this will answer "true" and will set NewPos to some other position (close to ProposedNewPos) that user is allowed to move into. This is used to allow user who is trying to walk "into the wall" to "move alongside the wall" (instead of just completely blocking his move, like MoveAllowedSimple would do). Always when MoveAllowedSimple would return true, this will also answer true and set NewPos to ProposedNewPos. CameraRadius must obviously be > 0. Note that it sometimes modifies NewPos even when it returns false. Such modification has no meaning to you. So you should not assume that NewPos is not modified when it returns with false. You should assume that when it returns false, NewPos is undefined (especiall since NewPos is "out" parameter and it may be implicitly modified anyway). OctreeItemIndexToIgnore and ItemsToIgnoreFunc meaning is just like for RayCollision. See also
| |
![]() |
procedure GetCameraHeight( const CameraPos, GravityUp: TVector3Single; out IsAboveTheGround: boolean; out SqrHeightAboveTheGround: Single; out GroundItemIndex: Integer; const OctreeItemIndexToIgnore: integer; const ItemsToIgnoreFunc: TOctreeItemIgnoreFunc); |
|
For given camera position and up vector, calculate camera height above the ground. This is comfortable for cooperation with TMatrixWalker.OnGetCameraHeight. This simply checks collision of a ray from CameraPos in direction -GravityUp, and sets IsAboveTheGround and SqrHeightAboveTheGround as needed. Also GroundItemIndex is set to index of octree item immediately below the camera (if IsAboveTheGround). This can be handy to detect e.g. that player walks on hot lava and he should be wounded, or that he walks on concrete/grass ground (to set his footsteps sound accordingly). If IsAboveTheGround then for sure GroundItemIndex <> NoItemIndex. OctreeItemIndexToIgnore and ItemsToIgnoreFunc meaning is just like for RayCollision. | |
![]() |
procedure GetCameraHeightZ( const CameraPos: TVector3Single; out IsAboveTheGround: boolean; out HeightAboveTheGround: Single; out GroundItemIndex: Integer; const OctreeItemIndexToIgnore: Integer; const ItemsToIgnoreFunc: TOctreeItemIgnoreFunc); |
|
This is just like GetCameraHeight, but it assumes that GravityUp = (0, 0, 1) and it returns the actual HeightAboveTheGround (not it's square). Thanks to the fact that calculating HeightAboveTheGround doesn't require costly Sqrt operation in case of such simple GravityUp. | |
![]() |
class function IgnoreTransparentItem( Octree: TVRMLTriangleOctree; OctreeItemIndex: Integer): boolean; |
|
This makes transparent triangles (with material with Transparency > 0) ignored (i.e. returns | |
![]() |
constructor Create(const ARootBox: TBox3d); overload; |
![]() |
constructor Create(AMaxDepth, AMaxLeafItemsCount: integer; const ARootBox: TBox3d); overload; |
![]() |
destructor Destroy; override; |