Unit1.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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 "GLS.Cadencer"
  9. #pragma link "GLS.Coordinates"
  10. #pragma link "GLS.Material"
  11. #pragma link "GLS.Objects"
  12. #pragma link "GLParticleFX"
  13. #pragma link "GLS.Scene"
  14. #pragma link "GLS.ShadowPlane"
  15. #pragma link "GLS.VectorFileObjects"
  16. #pragma link "GLS.SceneViewer"
  17. #pragma link "GLFileMD3"
  18. #pragma resource "*.dfm"
  19. TForm1 *Form1;
  20. // ---------------------------------------------------------------------------
  21. __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) {
  22. }
  23. // ---------------------------------------------------------------------------
  24. void __fastcall TForm1::FormCreate(TObject *Sender) {
  25. // Build the model
  26. BuildModel();
  27. ModelCube->Scale->SetVector(0.044, 0.044, 0.044);
  28. Legs->AnimationMode = aamLoop;
  29. Torso->AnimationMode = aamLoop;
  30. // Populate the combo boxes with the names of the
  31. // loaded animations
  32. Legs->Animations->SetToStrings(ComboBox1->Items);
  33. Torso->Animations->SetToStrings(ComboBox2->Items);
  34. // Set up some initial animations
  35. ComboBox1->ItemIndex = ComboBox1->Items->IndexOf("LEGS_IDLE");
  36. ComboBox2->ItemIndex = ComboBox2->Items->IndexOf("TORSO_STAND");
  37. // And trigger them
  38. ComboBox1Change(NULL);
  39. ComboBox2Change(NULL);
  40. }
  41. // ---------------------------------------------------------------------------
  42. Glvectorgeometry::TMatrix __fastcall TForm1::InterpolateMatrix
  43. (Glvectorgeometry::TMatrix m1, Glvectorgeometry::TMatrix m2, float delta) {
  44. int i, j;
  45. Glvectorgeometry::TMatrix mat;
  46. // This is used for interpolating between 2 matrices. The result
  47. // is used to reposition the model parts each frame.
  48. //
  49. for (j = 0; j < 3; j++)
  50. for (i = 0; i < 3; i++)
  51. mat.V[i].V[j] = m1.V[i].V[j] + (m2.V[i].V[j] - m1.V[i].V[j])
  52. * delta;
  53. return mat;
  54. }
  55. // ---------------------------------------------------------------------------
  56. void __fastcall TForm1::BuildModel() {
  57. // Path to models
  58. String ModelPath = ExtractFilePath(ParamStr(0));
  59. int I = ModelPath.Pos("Q3Demo");
  60. if (I != 0) {
  61. ModelPath.Delete(I + 7, ModelPath.Length() - I);
  62. ModelPath += "Model";
  63. ModelPath = IncludeTrailingBackslash(ModelPath);
  64. SetCurrentDir(ModelPath);
  65. }
  66. // Load model data from MD3 files into the actor
  67. //
  68. Legs->LoadFromFile("..\\model\\lower.md3");
  69. Torso->LoadFromFile("..\\model\\upper.md3");
  70. Head->LoadFromFile("..\\model\\head.md3");
  71. Weapon->LoadFromFile("..\\model\\plasma.md3");
  72. // Load the required tag lists
  73. // These are used to locally transform the separate
  74. // parts of the model into the correct places
  75. //
  76. LegsTags = new TMD3TagList;
  77. LegsTags->LoadFromFile("..\\model\\lower.md3");
  78. TorsoTags = new TMD3TagList;
  79. TorsoTags->LoadFromFile("..\\model\\upper.md3");
  80. // The tag_flash tag in the railgun model gives the
  81. // transform offset for the nozzle of the gun. I've
  82. // added a GunSmoke dummycube there to demonstrate with
  83. // a smoke like effect
  84. //
  85. WeaponTags = new TMD3TagList;
  86. WeaponTags->LoadFromFile("..\\model\\plasma.md3");
  87. GunSmoke->Matrix = WeaponTags->GetTransform("tag_flash", 0);
  88. // Apply textures to preloaded materials
  89. // The md3 file loader puts a material into the actors
  90. // assigned material library (if there is one) with
  91. // the names of the mesh objects. The skin and/or shader
  92. // files can tell you which objects need which textures loaded
  93. //
  94. LoadQ3Skin("..\\model\\lower_default.skin", Legs);
  95. LoadQ3Skin("..\\model\\upper_default.skin", Torso);
  96. LoadQ3Skin("..\\model\\head_default.skin", Head);
  97. // Load the weapon textures
  98. //
  99. MatLib->Materials->GetLibMaterialByName("plasma2")
  100. ->Material->Texture->Image->LoadFromFile("..\\model\\plasma2.jpg");
  101. // Load the animation data from the cfg file
  102. // This procedure populates an animation list from a
  103. // file or TStrings object. The last parameter tells
  104. // it which class of animation is to be loaded.
  105. //
  106. LoadQ3Anims(Legs->Animations, "..\\model\\animation.cfg", "BOTH");
  107. LoadQ3Anims(Legs->Animations, "..\\model\\animation.cfg", "LEGS");
  108. LoadQ3Anims(Torso->Animations, "..\\model\\animation.cfg", "BOTH");
  109. LoadQ3Anims(Torso->Animations, "..\\model\\animation.cfg", "TORSO");
  110. }
  111. // ---------------------------------------------------------------------------
  112. void __fastcall TForm1::ComboBox1Change(TObject *Sender) {
  113. Legs->SwitchToAnimation(ComboBox1->Text, false);
  114. }
  115. // ---------------------------------------------------------------------------
  116. void __fastcall TForm1::ComboBox2Change(TObject *Sender) {
  117. Torso->SwitchToAnimation(ComboBox2->Text, false);
  118. }
  119. // ---------------------------------------------------------------------------
  120. void __fastcall TForm1::GLCadencer1Progress(TObject *Sender,
  121. const double deltaTime, const double newTime) {
  122. Glvectorgeometry::TMatrix m1;
  123. Glvectorgeometry::TMatrix m2;
  124. // Set the transform for the torso
  125. m1 = LegsTags->GetTransform("tag_torso", Legs->CurrentFrame);
  126. m2 = LegsTags->GetTransform("tag_torso", Legs->NextFrameIndex());
  127. Torso->Matrix = InterpolateMatrix(m1, m2, Legs->CurrentFrameDelta);
  128. Torso->Roll(-TrackBar1->Position);
  129. Torso->Turn(-TrackBar2->Position);
  130. // Set the transform for the head
  131. m1 = TorsoTags->GetTransform("tag_head", Torso->CurrentFrame);
  132. m2 = TorsoTags->GetTransform("tag_head", Torso->NextFrameIndex());
  133. Head->Matrix = InterpolateMatrix(m1, m2, Torso->CurrentFrameDelta);
  134. Head->Roll(-TrackBar3->Position);
  135. Head->Turn(-TrackBar4->Position);
  136. // Set the transform for the weapon
  137. m1 = TorsoTags->GetTransform("tag_weapon", Torso->CurrentFrame);
  138. m2 = TorsoTags->GetTransform("tag_weapon", Torso->NextFrameIndex());
  139. Weapon->Matrix = InterpolateMatrix(m1, m2, Torso->CurrentFrameDelta);
  140. GLSceneViewer1->Invalidate();
  141. }
  142. // ---------------------------------------------------------------------------
  143. void __fastcall TForm1::GLSceneViewer1MouseDown(TObject *Sender,
  144. TMouseButton Button, TShiftState Shift, int X, int Y) {
  145. mx = X;
  146. my = Y;
  147. }
  148. // ---------------------------------------------------------------------------
  149. void __fastcall TForm1::GLSceneViewer1MouseMove(TObject *Sender,
  150. TShiftState Shift, int X, int Y) {
  151. if (Shift.Contains(ssLeft))
  152. GLCamera1->MoveAroundTarget(my - Y, mx - X);
  153. if (Shift.Contains(ssRight))
  154. GLCamera1->AdjustDistanceToTarget(Power(1.05, my - Y));
  155. mx = X;
  156. my = Y;
  157. }
  158. // ---------------------------------------------------------------------------
  159. void __fastcall TForm1::Timer1Timer(TObject *Sender) {
  160. Caption = "Quake Actor " + Format("%.1f FPS",
  161. ARRAYOFCONST((GLSceneViewer1->FramesPerSecond())));
  162. GLSceneViewer1->ResetPerformanceMonitor();
  163. }
  164. // ---------------------------------------------------------------------------
  165. void __fastcall TForm1::ComboSkinChange(TObject *Sender) {
  166. switch (ComboSkin->ItemIndex) {
  167. case 0: {
  168. LoadQ3Skin("..\\model\\lower_default.skin", Legs);
  169. LoadQ3Skin("..\\model\\upper_default.skin", Torso);
  170. LoadQ3Skin("..\\model\\head_default.skin", Head);
  171. break;
  172. }
  173. case 1: {
  174. LoadQ3Skin("..\\model\\lower_red.skin", Legs);
  175. LoadQ3Skin("..\\model\\upper_red.skin", Torso);
  176. LoadQ3Skin("..\\model\\head_red.skin", Head);
  177. break;
  178. }
  179. case 2: {
  180. LoadQ3Skin("..\\model\\lower_blue.skin", Legs);
  181. LoadQ3Skin("..\\model\\upper_blue.skin", Torso);
  182. LoadQ3Skin("..\\model\\head_blue.skin", Head);
  183. break;
  184. }
  185. default: ;
  186. }
  187. }
  188. // ---------------------------------------------------------------------------
  189. void __fastcall TForm1::FormDestroy(TObject *Sender) {
  190. LegsTags->Free();
  191. TorsoTags->Free();
  192. WeaponTags->Free();
  193. }
  194. // ---------------------------------------------------------------------------