GXS.SpatialPartitioning.pas 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. //
  2. // The graphics engine GLXEngine. The unit of GXScene for Delphi
  3. //
  4. unit GXS.SpatialPartitioning;
  5. (* Spatial partitioning related code that also uses scene objects *)
  6. interface
  7. uses
  8. Winapi.OpenGL,
  9. Stage.VectorTypes,
  10. Stage.VectorGeometry,
  11. GXS.GeometryBB,
  12. GXS.SpacePartition,
  13. GXS.Scene,
  14. GXS.Coordinates,
  15. GXS.SceneViewer,
  16. GXS.RenderContextInfo,
  17. GXS.State;
  18. type
  19. // Object for holding scene objects in a spatial partitioning
  20. TgxSceneObj = class(TSpacePartitionLeaf)
  21. public
  22. Obj: TgxBaseSceneObject;
  23. procedure UpdateCachedAABBAndBSphere; override;
  24. constructor CreateObj(Owner: TSectoredSpacePartition; aObj: TgxBaseSceneObject);
  25. destructor Destroy; override;
  26. end;
  27. (* Render a spacial partitioning descending from TSectoredSpacePartition
  28. (octree and quadtree) as a grid - great for debugging and visualisation *)
  29. procedure RenderSpatialPartitioning(var rci: TgxRenderContextInfo; const Space: TSectoredSpacePartition);
  30. (* Create an extended frustum from a SceneViewer - this makes the unit
  31. specific to the windows platform! *)
  32. function ExtendedFrustumMakeFromSceneViewer(const AFrustum: TFrustum; const vWidth, vHeight: integer; AVKCamera: TgxCamera)
  33. : TExtendedFrustum; overload;
  34. function ExtendedFrustumMakeFromSceneViewer(const AFrustum: TFrustum; const AGLXceneViewer: TgxSceneViewer)
  35. : TExtendedFrustum; overload;
  36. // Renders an AABB as a line
  37. procedure RenderAABB(var rci: TgxRenderContextInfo; AABB: TAABB; w, r, g, b: single); overload;
  38. procedure RenderAABB(var rci: TgxRenderContextInfo; AABB: TAABB); overload;
  39. // -------------------------------------------------------------------
  40. implementation
  41. // -------------------------------------------------------------------
  42. uses
  43. GXS.Context;
  44. procedure RenderAABB(var rci: TgxRenderContextInfo; AABB: TAABB);
  45. begin
  46. RenderAABB(rci, AABB, 1, 0.8, 0.8, 0.8);
  47. end;
  48. procedure RenderAABB(var rci: TgxRenderContextInfo; AABB: TAABB; w, r, g, b: single);
  49. begin
  50. glColor3f(r, g, b);
  51. rci.gxStates.LineWidth := w;
  52. glBegin(GL_LINE_STRIP);
  53. glVertex3f(AABB.min.X, AABB.min.Y, AABB.min.Z);
  54. glVertex3f(AABB.min.X, AABB.max.Y, AABB.min.Z);
  55. glVertex3f(AABB.max.X, AABB.max.Y, AABB.min.Z);
  56. glVertex3f(AABB.max.X, AABB.min.Y, AABB.min.Z);
  57. glVertex3f(AABB.min.X, AABB.min.Y, AABB.min.Z);
  58. glVertex3f(AABB.min.X, AABB.min.Y, AABB.max.Z);
  59. glVertex3f(AABB.min.X, AABB.max.Y, AABB.max.Z);
  60. glVertex3f(AABB.max.X, AABB.max.Y, AABB.max.Z);
  61. glVertex3f(AABB.max.X, AABB.min.Y, AABB.max.Z);
  62. glVertex3f(AABB.min.X, AABB.min.Y, AABB.max.Z);
  63. glEnd;
  64. glBegin(GL_LINES);
  65. glVertex3f(AABB.min.X, AABB.max.Y, AABB.min.Z);
  66. glVertex3f(AABB.min.X, AABB.max.Y, AABB.max.Z);
  67. glVertex3f(AABB.max.X, AABB.max.Y, AABB.min.Z);
  68. glVertex3f(AABB.max.X, AABB.max.Y, AABB.max.Z);
  69. glVertex3f(AABB.max.X, AABB.min.Y, AABB.min.Z);
  70. glVertex3f(AABB.max.X, AABB.min.Y, AABB.max.Z);
  71. glEnd;
  72. end;
  73. procedure RenderSpatialPartitioning(var rci: TgxRenderContextInfo; const Space: TSectoredSpacePartition);
  74. procedure RenderSectorNode(Node: TSectorNode);
  75. var
  76. i: integer;
  77. AABB: TAABB;
  78. begin
  79. if Node.NoChildren then
  80. begin
  81. AABB := Node.AABB;
  82. if Node.RecursiveLeafCount > 0 then
  83. RenderAABB(rci, AABB, 1, 0, 0, 0)
  84. else
  85. RenderAABB(rci, AABB, 1, 0.8, 0.8, 0.8) // }
  86. end
  87. else
  88. begin
  89. for i := 0 to Node.ChildCount - 1 do
  90. RenderSectorNode(Node.Children[i]);
  91. end;
  92. end;
  93. begin
  94. rci.gxStates.Disable(stLighting);
  95. RenderSectorNode(Space.RootNode);
  96. end;
  97. function ExtendedFrustumMakeFromSceneViewer(const AFrustum: TFrustum; const AGLXceneViewer: TgxSceneViewer): TExtendedFrustum;
  98. // old version
  99. begin
  100. Assert(Assigned(AGLXceneViewer.Camera), 'GLXceneViewer must have camera specified!');
  101. result := ExtendedFrustumMake(AFrustum, AGLXceneViewer.Camera.NearPlane, AGLXceneViewer.Camera.DepthOfView,
  102. AGLXceneViewer.FieldOfView, AGLXceneViewer.Camera.Position.AsAffineVector, AGLXceneViewer.Camera.Direction.AsAffineVector);
  103. end;
  104. function ExtendedFrustumMakeFromSceneViewer(const AFrustum: TFrustum; const vWidth, vHeight: integer; AVKCamera: TgxCamera)
  105. : TExtendedFrustum; // changed version
  106. var
  107. buffov: single;
  108. begin
  109. if vWidth < vHeight then
  110. buffov := AVKCamera.GetFieldOfView(vWidth)
  111. else
  112. buffov := AVKCamera.GetFieldOfView(vHeight);
  113. result := ExtendedFrustumMake(AFrustum, AVKCamera.NearPlane, AVKCamera.DepthOfView, buffov, AVKCamera.Position.AsAffineVector,
  114. AVKCamera.Direction.AsAffineVector);
  115. end;
  116. // --------- TgxSceneObj ------------
  117. constructor TgxSceneObj.CreateObj(Owner: TSectoredSpacePartition; aObj: TgxBaseSceneObject);
  118. begin
  119. Obj := aObj;
  120. inherited CreateOwned(Owner);
  121. end;
  122. destructor TgxSceneObj.Destroy;
  123. begin
  124. inherited;
  125. end;
  126. procedure TgxSceneObj.UpdateCachedAABBAndBSphere;
  127. begin
  128. FCachedAABB := Obj.AxisAlignedBoundingBox;
  129. FCachedAABB.min := Obj.LocalToAbsolute(FCachedAABB.min);
  130. FCachedAABB.max := Obj.LocalToAbsolute(FCachedAABB.max);
  131. FCachedBSphere.Radius := Obj.BoundingSphereRadius;
  132. FCachedBSphere.Center := AffineVectorMake(Obj.AbsolutePosition);
  133. end;
  134. end.