fOctreeD.pas 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  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. GLS.VectorTypes,
  16. GLS.Cadencer,
  17. GLS.GeomObjects,
  18. GLS.Coordinates,
  19. GLS.Utils,
  20. GLS.BaseClasses,
  21. GLS.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. implementation
  61. {$R *.dfm}
  62. procedure TFormOctreedemo.FormCreate(Sender: TObject);
  63. var
  64. t : Int64;
  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. t:=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. procedure TFormOctreedemo.GLSceneViewer2MouseDown(Sender: TObject;
  82. Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
  83. var
  84. rayStart, rayVector, iPoint, iNormal : TGLVector;
  85. t : Int64;
  86. begin
  87. SetVector(rayStart, GLCamera2.AbsolutePosition);
  88. SetVector(rayVector, GLSceneViewer2.Buffer.ScreenToVector(AffineVectorMake(x, GLSceneViewer2.Height-y, 0)));
  89. NormalizeVector(rayVector);
  90. t:=StartPrecisionTimer;
  91. if CBOctree.Checked then begin
  92. // Octree method (fast)
  93. if FreeForm1.OctreeRayCastIntersect(raystart, rayvector, @iPoint, @iNormal) then begin
  94. Sphere1.Visible:=True;
  95. Sphere1.Position.AsVector:=iPoint;
  96. Sphere1.Direction.AsVector:=VectorNormalize(iNormal);
  97. end else Sphere1.Visible:=False;
  98. Label4.Hint:='# Nodes hit with raycast: '+inttostr(High(FreeForm1.Octree.ResultArray)+1);
  99. end else begin
  100. // Brute-Force method (slow)
  101. if FreeForm1.RayCastIntersect(rayStart, rayVector, @iPoint, @iNormal) then begin
  102. Sphere1.Visible:=True;
  103. Sphere1.Position.AsVector:=iPoint;
  104. Sphere1.Direction.AsVector:=VectorNormalize(iNormal);
  105. end else Sphere1.Visible:=False;
  106. end;
  107. Label5.Hint:=Format('Intersect Time: %.3f ms', [StopPrecisionTimer(t)*1000]);
  108. end;
  109. procedure TFormOctreedemo.GLSceneViewer2MouseMove(Sender: TObject;
  110. Shift: TShiftState; X, Y: Integer);
  111. begin
  112. mousex:=x;
  113. mousey:=y;
  114. end;
  115. procedure TFormOctreedemo.GLCadencer1Progress(Sender: TObject; const deltaTime,
  116. newTime: Double);
  117. begin
  118. if CheckBox1.Checked then
  119. GLSceneViewer2MouseDown(Sender, TMouseButton(mbLeft), [ssShift], mousex, mousey);
  120. FreeForm1.RollAngle:=5*newTime; // 45° per second
  121. end;
  122. procedure TFormOctreedemo.Timer1Timer(Sender: TObject);
  123. begin
  124. // Show FPS Rating
  125. LabelFPS.Caption:=Format('%.2f FPS', [GLSceneViewer2.FramesPerSecond]);
  126. GLSceneViewer2.ResetPerformanceMonitor;
  127. // Not doing so causes ugly flickering and a significant decrease in FPS...
  128. with Label4 do Caption:=Hint;
  129. with Label5 do Caption:=Hint;
  130. end;
  131. end.