fSubdivideC.cpp 7.3 KB

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