fQ3DemoC.cpp 7.5 KB

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