Unit1.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. //---------------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include "Unit1.h"
  5. //---------------------------------------------------------------------------
  6. #pragma package(smart_init)
  7. #pragma link "GLBaseClasses"
  8. #pragma link "GLCadencer"
  9. #pragma link "GLCoordinates"
  10. #pragma link "GLCrossPlatform"
  11. #pragma link "GLMaterial"
  12. #pragma link "GLScene"
  13. #pragma link "GLVectorFileObjects"
  14. #pragma link "GLWin32Viewer"
  15. #pragma link "GLFile3DS"
  16. #pragma link "GLFileMD2"
  17. #pragma resource "*.dfm"
  18. TForm1 *Form1;
  19. //---------------------------------------------------------------------------
  20. __fastcall TForm1::TForm1(TComponent* Owner)
  21. : TForm(Owner)
  22. {
  23. }
  24. //---------------------------------------------------------------------------
  25. void __fastcall TForm1::BULoadClick(TObject *Sender)
  26. {
  27. SetGLSceneMediaDir();
  28. BUSubdivide->Enabled = true;
  29. // GLFreeForm1->LoadFromFile("polyhedron.3ds");
  30. // GLFreeForm1->LoadFromFile("mushroom.3ds");
  31. // GLFreeForm1->LoadFromFile("trinityrage.smd");
  32. // GLFreeForm1->LoadFromFile("HighPolyObject.3ds");
  33. /*
  34. GLActor1->LoadFromFile("trinityrage.smd");
  35. GLActor1->AddDataFromFile("run.smd");
  36. GLActor1->Animations[1].MakeSkeletalTranslationStatic;
  37. GLActor1->SwitchToAnimation(GLActor1.Animations[1]);
  38. */
  39. GLActor1->LoadFromFile("waste.md2");
  40. GLActor1->Material->Texture->Image->LoadFromFile("waste.jpg");
  41. GLActor1->Material->Texture->Enabled = true;
  42. GLActor1->SwitchToAnimation(GLActor1->Animations->Items[0]);
  43. CBAnimateClick(Sender);
  44. }
  45. //---------------------------------------------------------------------------
  46. void __fastcall TForm1::BUSubdivideClick(TObject *Sender)
  47. {
  48. int i, j;
  49. TAffineVectorList *tris, *norms, *tex, *buf, *morphTris, *morphNorms;
  50. TIntegerList *indices, *texIndices;
  51. TIntegerList *firstRemap, *subdivideRemap, *bufRemap;
  52. __int64 t;
  53. BUSubdivide->Enabled = false;
  54. Screen->Cursor = crHourGlass;
  55. t = StartPrecisionTimer();
  56. for (i = 0; i < GLActor1->MeshObjects->Count-1; i++ )
  57. {
  58. tex = new TAffineVectorList;
  59. tris = GLActor1->MeshObjects->Items[i]->ExtractTriangles(tex);
  60. indices = BuildVectorCountOptimizedIndices(tris);
  61. firstRemap = (TIntegerList *)(indices->CreateClone());
  62. RemapAndCleanupReferences(tris, indices);
  63. norms = BuildNormals(tris, indices);
  64. // subdivide geometry
  65. SubdivideTriangles((float)TrackBar1->Position*0.1, tris, indices, norms);
  66. texIndices = BuildVectorCountOptimizedIndices(tex);
  67. RemapAndCleanupReferences(tex, texIndices);
  68. // subdivide texture space
  69. SubdivideTriangles(0, tex, texIndices);
  70. // Re-expand everything
  71. buf = new TAffineVectorList;
  72. try
  73. {
  74. ConvertIndexedListToList(tris, indices, buf);
  75. tris->Assign(buf);
  76. buf->Count = 0;
  77. ConvertIndexedListToList(norms, indices, buf);
  78. norms->Assign(buf);
  79. buf->Count = 0;
  80. ConvertIndexedListToList(tex, texIndices, buf);
  81. tex->Assign(buf);
  82. }
  83. __finally
  84. {
  85. buf->Free();
  86. }
  87. // Pack & Optimize the expanded stuff
  88. indices->Free();
  89. indices = BuildVectorCountOptimizedIndices(tris, norms, tex);
  90. subdivideRemap = (TIntegerList *)(indices->CreateClone());
  91. RemapReferences(norms, indices);
  92. RemapReferences(tex, indices);
  93. RemapAndCleanupReferences(tris, indices);
  94. IncreaseCoherency(indices, 13);
  95. bufRemap = new TIntegerList;
  96. for (j = 0; j < GLActor1->MeshObjects->MorphTargetCount()-1; j++)
  97. {
  98. GLActor1->MeshObjects->MorphTo(j);
  99. morphTris = GLActor1->MeshObjects->ExtractTriangles();
  100. bufRemap->Assign(firstRemap);
  101. RemapAndCleanupReferences(morphTris, bufRemap);
  102. morphNorms = BuildNormals(morphTris, bufRemap);
  103. SubdivideTriangles(TrackBar1->Position*0.1, morphTris, bufRemap, morphNorms);
  104. buf = new TAffineVectorList;
  105. try
  106. {
  107. ConvertIndexedListToList(morphTris, bufRemap, buf);
  108. morphTris->Assign(buf);
  109. ConvertIndexedListToList(morphNorms, bufRemap, buf);
  110. morphNorms->Assign(buf);
  111. }
  112. __finally
  113. {
  114. buf->Free();
  115. }
  116. RemapReferences(morphTris, subdivideRemap);
  117. RemapReferences(morphNorms, subdivideRemap);
  118. GLActor1->MeshObjects->Items[j]->Vertices = morphTris;
  119. GLActor1->MeshObjects->Items[j]->Normals = morphNorms;
  120. morphTris->Free();
  121. morphNorms->Free();
  122. }
  123. bufRemap->Free();
  124. GLActor1->MeshObjects->Items[i]->Vertices = tris;
  125. GLActor1->MeshObjects->Items[i]->Normals = norms;
  126. GLActor1->MeshObjects->Items[i]->TexCoords = tex;
  127. GLActor1->MeshObjects->Items[i]->FaceGroups->Clear();
  128. //GLActor1->MeshObjects->Items[i]->FaceGroups->Items[i] = indices;
  129. GLActor1->MeshObjects->Items[i]->Mode = fgmmTriangles;
  130. texIndices->Free();
  131. subdivideRemap->Free();
  132. firstRemap->Free();
  133. tex->Free();
  134. indices->Free();
  135. norms->Free();
  136. tris->Free();
  137. }
  138. // (GLActor1->MeshObjects->Items[0] as TGLSkeletonMeshObject)->PrepareBoneMatrixInvertedMeshes;
  139. LASubdivideTime->Caption = Format("%.1f ms",
  140. ARRAYOFCONST ((StopPrecisionTimer(t)*1000)));
  141. // Initial perf: 1412 ms
  142. // Basic Edges Hash: 464 ms
  143. // Several transfer optims: 377 ms
  144. // morph & subdivide normals too : 527 ms
  145. Screen->Cursor =crDefault;
  146. GLActor1->StructureChanged();
  147. }
  148. //---------------------------------------------------------------------------
  149. void __fastcall TForm1::GLSceneViewer1MouseDown(TObject *Sender, TMouseButton Button,
  150. TShiftState Shift, int X, int Y)
  151. {
  152. mx = X;
  153. my = Y;
  154. }
  155. //---------------------------------------------------------------------------
  156. void __fastcall TForm1::GLSceneViewer1MouseMove(TObject *Sender, TShiftState Shift,
  157. int X, int Y)
  158. {
  159. if (Shift.Contains(ssLeft))
  160. GLCamera1->MoveAroundTarget(my-Y, mx-X);
  161. else
  162. if (Shift.Contains(ssRight))
  163. GLCamera1->RotateTarget(my-Y, mx-X);
  164. mx = X;
  165. my = Y;
  166. }
  167. //---------------------------------------------------------------------------
  168. void __fastcall TForm1::RBWireFrameClick(TObject *Sender)
  169. {
  170. GLActor1->Material->PolygonMode = pmLines;
  171. }
  172. //---------------------------------------------------------------------------
  173. void __fastcall TForm1::RBSolidClick(TObject *Sender)
  174. {
  175. GLActor1->Material->PolygonMode = pmFill;
  176. }
  177. //---------------------------------------------------------------------------
  178. void __fastcall TForm1::Timer1Timer(TObject *Sender)
  179. {
  180. Caption = "Subdivide " + Format("%.1f FPS - %d Triangles",
  181. ARRAYOFCONST ((GLSceneViewer1->FramesPerSecond(),
  182. GLActor1->MeshObjects->TriangleCount())));
  183. GLSceneViewer1->ResetPerformanceMonitor();
  184. }
  185. //---------------------------------------------------------------------------
  186. void __fastcall TForm1::GLCadencer1Progress(TObject *Sender, const double deltaTime,
  187. const double newTime)
  188. {
  189. GLSceneViewer1->Invalidate();
  190. }
  191. //---------------------------------------------------------------------------
  192. void __fastcall TForm1::CBAnimateClick(TObject *Sender)
  193. {
  194. // not only turns on/off animation, but also forces the TGLActor
  195. // to generate a display list when animation is off
  196. if (CBAnimate->Checked)
  197. {
  198. GLActor1->AnimationMode = aamLoop;
  199. GLActor1->ObjectStyle = GLActor1->ObjectStyle << osDirectDraw;
  200. GLActor1->Reference = aarMorph;
  201. }
  202. else
  203. {
  204. GLActor1->AnimationMode = aamNone;
  205. GLActor1->MeshObjects->MorphTo(0);
  206. GLActor1->Reference = aarNone;
  207. GLActor1->StructureChanged();
  208. GLActor1->ObjectStyle = GLActor1->ObjectStyle >> osDirectDraw;
  209. }
  210. }
  211. //---------------------------------------------------------------------------