fOctreeD.pas 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. unit fOctreeD;
  2. interface
  3. uses
  4. Winapi.OpenGL,
  5. System.SysUtils,
  6. System.Classes,
  7. Vcl.Controls,
  8. Vcl.Forms,
  9. Vcl.ExtCtrls,
  10. Vcl.StdCtrls,
  11. GLS.Scene,
  12. GLS.VectorFileObjects,
  13. GLS.Objects,
  14. GLS.SceneViewer,
  15. GLScene.VectorTypes,
  16. GLS.Cadencer,
  17. GLS.GeomObjects,
  18. GLS.Coordinates,
  19. GLScene.Utils,
  20. GLS.BaseClasses,
  21. GLScene.VectorGeometry,
  22. GLS.VectorLists,
  23. GLS.File3DS;
  24. type
  25. TFormOctreedemo = class(TForm)
  26. GLScene1: TGLScene;
  27. GLLightSource1: TGLLightSource;
  28. DummyCube1: TGLDummyCube;
  29. FreeForm1: TGLFreeForm;
  30. Sphere1: TGLSphere;
  31. ArrowLine1: TGLArrowLine;
  32. GLSceneViewer2: TGLSceneViewer;
  33. GLCamera2: TGLCamera;
  34. GLCadencer1: TGLCadencer;
  35. Timer1: TTimer;
  36. Panel1: TPanel;
  37. Label1: TLabel;
  38. Label2: TLabel;
  39. Label3: TLabel;
  40. Label5: TLabel;
  41. LABuild: TLabel;
  42. CheckBox1: TCheckBox;
  43. CBOctree: TCheckBox;
  44. Label4: TLabel;
  45. LabelFPS: TLabel;
  46. procedure FormCreate(Sender: TObject);
  47. procedure GLSceneViewer2MouseDown(Sender: TObject;
  48. Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  49. procedure GLSceneViewer2MouseMove(Sender: TObject; Shift: TShiftState;
  50. X, Y: Integer);
  51. procedure GLCadencer1Progress(Sender: TObject; const deltaTime,
  52. newTime: Double);
  53. procedure Timer1Timer(Sender: TObject);
  54. private
  55. public
  56. mousex, mousey: integer;
  57. end;
  58. var
  59. FormOctreedemo: TFormOctreedemo;
  60. //---------------------------------------------------------------------
  61. implementation
  62. //---------------------------------------------------------------------
  63. {$R *.dfm}
  64. procedure TFormOctreedemo.FormCreate(Sender: TObject);
  65. begin
  66. // Load high poly mesh (10,000 triangles).
  67. var Path: TFileName := GetCurrentAssetPath();
  68. SetCurrentDir(Path + '\model');
  69. FreeForm1.LoadFromFile('HighPolyObject.3ds');
  70. var t: Int64 := StartPrecisionTimer;
  71. FreeForm1.BuildOctree;
  72. LABuild.Caption:=Format('Build time: %.3f ms', [StopPrecisionTimer(t)*1000]);
  73. with FreeForm1.Octree do begin
  74. Label1.Caption:='Octree Nodes: '+inttostr(NodeCount);
  75. Label2.Caption:='Tri Count Octree: '+inttostr(TriCountOctree);
  76. Label3.Caption:='Tri Count Mesh: '+inttostr(TriCountMesh);
  77. end;
  78. mousex:= -1;
  79. mousey:= -1;
  80. end;
  81. //---------------------------------------------------------------------
  82. procedure TFormOctreedemo.GLSceneViewer2MouseDown(Sender: TObject;
  83. Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  84. var
  85. rayStart, rayVector, iPoint, iNormal : TGLVector;
  86. t : Int64;
  87. begin
  88. SetVector(rayStart, GLCamera2.AbsolutePosition);
  89. SetVector(rayVector, GLSceneViewer2.Buffer.ScreenToVector(AffineVectorMake(x, GLSceneViewer2.Height-y, 0)));
  90. NormalizeVector(rayVector);
  91. t:=StartPrecisionTimer;
  92. if CBOctree.Checked then begin
  93. // Octree method (fast)
  94. if FreeForm1.OctreeRayCastIntersect(raystart, rayvector, @iPoint, @iNormal) then begin
  95. Sphere1.Visible:=True;
  96. Sphere1.Position.AsVector:=iPoint;
  97. Sphere1.Direction.AsVector:=VectorNormalize(iNormal);
  98. end else Sphere1.Visible:=False;
  99. Label4.Hint:='# Nodes hit with raycast: '+inttostr(High(FreeForm1.Octree.ResultArray)+1);
  100. end else begin
  101. // Brute-Force method (slow)
  102. if FreeForm1.RayCastIntersect(rayStart, rayVector, @iPoint, @iNormal) then begin
  103. Sphere1.Visible:=True;
  104. Sphere1.Position.AsVector:=iPoint;
  105. Sphere1.Direction.AsVector:=VectorNormalize(iNormal);
  106. end else Sphere1.Visible:=False;
  107. end;
  108. Label5.Hint:=Format('Intersect Time: %.3f ms', [StopPrecisionTimer(t)*1000]);
  109. end;
  110. //---------------------------------------------------------------------
  111. procedure TFormOctreedemo.GLSceneViewer2MouseMove(Sender: TObject;
  112. Shift: TShiftState; X, Y: Integer);
  113. begin
  114. mousex:=x;
  115. mousey:=y;
  116. end;
  117. //---------------------------------------------------------------------
  118. procedure TFormOctreedemo.GLCadencer1Progress(Sender: TObject; const deltaTime,
  119. newTime: Double);
  120. begin
  121. if CheckBox1.Checked then
  122. GLSceneViewer2MouseDown(Sender, TMouseButton(mbLeft), [ssShift], mousex, mousey);
  123. FreeForm1.RollAngle:=5*newTime; // 45° per second
  124. end;
  125. //---------------------------------------------------------------------
  126. procedure TFormOctreedemo.Timer1Timer(Sender: TObject);
  127. begin
  128. // Show FPS Rating
  129. LabelFPS.Caption:=Format('%.2f FPS', [GLSceneViewer2.FramesPerSecond]);
  130. GLSceneViewer2.ResetPerformanceMonitor;
  131. // Not doing so causes ugly flickering and a significant decrease in FPS...
  132. with Label4 do Caption:=Hint;
  133. with Label5 do Caption:=Hint;
  134. end;
  135. end.