fQuakeActorC.cpp 8.1 KB

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