Unit1.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. //---------------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include "Unit1.h"
  5. //---------------------------------------------------------------------------
  6. #pragma package(smart_init)
  7. #pragma link "GLFile3DS"
  8. #pragma link "GLFileMD2"
  9. #pragma link "GLProxyObjects"
  10. #pragma link "GLBaseClasses"
  11. #pragma link "GLBitmapFont"
  12. #pragma link "GLCadencer"
  13. #pragma link "GLCoordinates"
  14. #pragma link "GLCrossPlatform"
  15. #pragma link "GLDCE"
  16. #pragma link "GLHeightData"
  17. #pragma link "GLHUDObjects"
  18. #pragma link "GLMaterial"
  19. #pragma link "GLObjects"
  20. #pragma link "GLScene"
  21. #pragma link "GLTerrainRenderer"
  22. #pragma link "GLVectorFileObjects"
  23. #pragma link "GLWin32Viewer"
  24. #pragma link "GLWindowsFont"
  25. #pragma resource "*.dfm"
  26. TForm1 *Form1;
  27. const
  28. float cForce = 250.0;
  29. const
  30. int cSpread = 200;
  31. const
  32. int cNbMushrooms = 20;
  33. float random(void)
  34. {
  35. return (float)(rand() & 0x1FFF) / (float)0x1FFF;
  36. }
  37. //---------------------------------------------------------------------------
  38. __fastcall TForm1::TForm1(TComponent* Owner)
  39. : TForm(Owner)
  40. {
  41. }
  42. //---------------------------------------------------------------------------
  43. void TForm1::Load()
  44. {
  45. SetGLSceneMediaDir();
  46. //Load Materials
  47. GLMatLib->AddTextureMaterial("Terrain", "snow512.jpg");
  48. GLMatLib->AddTextureMaterial("Actor", "waste.jpg");
  49. //Load Terrain
  50. GLBitmapHDS1->MaxPoolSize = 8 * 1024 * 1024;
  51. GLBitmapHDS1->Picture->LoadFromFile("terrain.bmp");
  52. Terrain->Direction->SetVector(0.0, 1.0, 0.0);
  53. Terrain->Material->LibMaterialName = "Terrain";
  54. Terrain->TilesPerTexture = 256 / Terrain->TileSize;
  55. Terrain->Scale->SetVector(1.0, 1.0, 0.02);
  56. Ground->Material->LibMaterialName = "Terrain";
  57. // Load mushroom mesh
  58. //Always use AutoScaling property or you may get some problems
  59. moMushroom->AutoScaling->SetPoint(0.1, 0.1, 0.1);
  60. moMushroom->LoadFromFile("Mushroom.3ds");
  61. moMushroom->Direction->SetVector(0.0, 1.0, 0.0);
  62. moMushroom->BuildOctree();
  63. //Load player
  64. Player->Position->SetPoint(0.0, 3.0, 0.0);
  65. //Actor
  66. GLActor1->LoadFromFile("Waste.md2");
  67. GLActor1->Direction->SetVector(0.0, 1.0, 0.0);
  68. GLActor1->Up->SetVector(1.0, 0.0, 0.0);
  69. GLActor1->Scale->SetVector(0.05, 0.05, 0.05);
  70. GLActor1->Material->LibMaterialName = "Actor";
  71. GLActor1->Animations->LoadFromFile("Quake2Animations.aaf");
  72. // Define animation properties
  73. GLActor1->AnimationMode = aamLoop;
  74. GLActor1->SwitchToAnimation("stand");
  75. GLActor1->FrameInterpolation = afpLinear;
  76. //DCE Behaviour
  77. GLSphere1->Scale->Assign(GetOrCreateDCEDynamic(Player)->Size);
  78. // GetOrCreateDCEDynamic(Player)->OnCollision = PlayerBehaviours0Collision;
  79. }
  80. //---------------------------------------------------------------------------
  81. void TForm1::AddBall()
  82. {
  83. TGLSphere *Ball;
  84. float S;
  85. float pX,pY,pZ;
  86. float cR,cG,cB;
  87. Ball = (TGLSphere *)(Balls->AddNewChild(__classid(TGLSphere)));
  88. //with Ball do
  89. Ball->Tag = 1; //set the identifier of a ball
  90. Ball->Radius = 1.0;
  91. S = (float)(100.0 + random(900.0))/ 500.0;
  92. Ball->Scale->SetVector(S, S, S);
  93. pX = random(40.0) - random(40.0);
  94. pY = 4.0 + random(10.0);
  95. pZ = random(40.0) - random(40.0);
  96. Ball->Position->SetPoint(pX, pY, pZ);
  97. cR = (float)(100.0 + random(900.0))/1000;
  98. cG = (float)(100.0 + random(900.0))/1000;
  99. cB = (float)(100.0 + random(900.0))/1000;
  100. Ball->Material->FrontProperties->Diffuse->SetColor(cR, cG, cB);
  101. GetOrCreateDCEDynamic(Ball)->Manager = GLDCEManager1;
  102. GetOrCreateDCEDynamic(Ball)->BounceFactor = 0.75;
  103. GetOrCreateDCEDynamic(Ball)->Friction = 0.1;
  104. GetOrCreateDCEDynamic(Ball)->SlideOrBounce = csbBounce;
  105. GetOrCreateDCEDynamic(Ball)->Size->Assign(Ball->Scale);
  106. }
  107. //---------------------------------------------------------------------------
  108. void TForm1::AddMushrooms()
  109. {
  110. int i;
  111. TGLFreeFormProxy *Proxy;
  112. Glvectorgeometry::TVector s;
  113. float f;
  114. // spawn some more mushrooms using proxy objects
  115. for (i = 0; i < cNbMushrooms - 1; i++) {
  116. // create a new Proxy and set its MasterObject property
  117. Proxy = (TGLFreeFormProxy *)(Mushrooms->AddNewChild(__classid(TGLFreeFormProxy)));
  118. Proxy->ProxyOptions = Proxy->ProxyOptions << pooObjects;
  119. Proxy->MasterObject = moMushroom;
  120. // retrieve reference attitude
  121. Proxy->Direction = moMushroom->Direction;
  122. Proxy->Up = moMushroom->Up;
  123. // randomize scale
  124. s = moMushroom->Scale->AsVector;
  125. f = 2.0 * random() + 1.0;
  126. ScaleVector(s, f);
  127. Proxy->Scale->AsVector = s;
  128. // randomize position
  129. Proxy->Position->SetPoint(
  130. (random(cSpread) - (float)(cSpread / 2.0)),
  131. (moMushroom->Position->Z + 1.5 * f),
  132. (random(cSpread) - (float)(cSpread / 2.0)));
  133. // randomize orientation
  134. Proxy->RollAngle = random(360.0);
  135. Proxy->TransformationChanged();
  136. GetOrCreateDCEStatic(Proxy)->Manager = GLDCEManager1;
  137. GetOrCreateDCEStatic(Proxy)->BounceFactor = 0.75;
  138. GetOrCreateDCEStatic(Proxy)->Friction = 10.0;
  139. GetOrCreateDCEStatic(Proxy)->Shape = csFreeform;
  140. }
  141. }
  142. //---------------------------------------------------------------------------
  143. void TForm1::HandleAnimation()
  144. {
  145. String anim;
  146. if (VectorNorm(GetOrCreateDCEDynamic(Player)->Speed) > 0.1)
  147. anim = "run";
  148. else
  149. anim = "stand";
  150. if (Jumped==true)
  151. {
  152. if (!GetOrCreateDCEDynamic(Player)->InGround)
  153. anim = "jump";
  154. else
  155. Jumped = false;
  156. }
  157. if (anim == "jump")
  158. GLActor1->Interval = 500;
  159. else
  160. GLActor1->Interval = 100;
  161. if (GLActor1->CurrentAnimation() != anim)
  162. GLActor1->SwitchToAnimation(anim);
  163. }
  164. //---------------------------------------------------------------------------
  165. void TForm1::HandleKeys()
  166. {
  167. TAffineVector Force;
  168. Force = NullVector;
  169. if (IsKeyDown(VK_ESCAPE)) Close();
  170. if (IsKeyDown('w') || IsKeyDown('W') || IsKeyDown(VK_UP))
  171. Force.Z = cForce;
  172. if (IsKeyDown('s') || IsKeyDown('S') || IsKeyDown(VK_DOWN))
  173. Force.Z = -cForce;
  174. if (IsKeyDown('a') || IsKeyDown('A') || IsKeyDown(VK_LEFT))
  175. Force.X = cForce;
  176. if (IsKeyDown('d') || IsKeyDown('D') || IsKeyDown(VK_RIGHT))
  177. Force.X = -cForce;
  178. GetOrCreateDCEDynamic(Player)->ApplyAccel(Force);
  179. }
  180. //---------------------------------------------------------------------------
  181. void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
  182. {
  183. int i;
  184. if (Key == VK_F1)
  185. AddBall();
  186. if (Key == VK_F2)
  187. for (i = 1; i <= 10; i++)
  188. AddBall();
  189. if (Key == VK_F3)
  190. AddMushrooms();
  191. if (Key == VK_SPACE)
  192. {
  193. GetOrCreateDCEDynamic(Player)->Jump(1.0, 20.0);
  194. Jumped = true;
  195. }
  196. if (Key == VK_F4)
  197. {
  198. Terrain->Visible = false;
  199. Ground->Visible = true;
  200. GetOrCreateDCEStatic(Terrain)->Active = false;
  201. GetOrCreateDCEStatic(Ground)->Active = true;
  202. }
  203. if (Key == VK_F5)
  204. GLDCEManager1->ManualStep = !GLDCEManager1->ManualStep;
  205. if (Key = VK_RETURN) {
  206. Player->Position->SetPoint(0.0, 3.0, 0.0);
  207. Balls->DeleteChildren();
  208. Mushrooms->DeleteChildren();
  209. Help->ModulateColor->Alpha = 1.0;
  210. Terrain->Visible = true;
  211. Ground->Visible = false;
  212. GetOrCreateDCEStatic(Terrain)->Active = true;
  213. GetOrCreateDCEStatic(Ground)->Active = false;
  214. }
  215. }
  216. //---------------------------------------------------------------------------
  217. void __fastcall TForm1::GLSceneViewer1MouseMove(TObject *Sender, TShiftState Shift,
  218. int X, int Y)
  219. {
  220. //Mouse look
  221. if (Shift.Contains(ssLeft))
  222. {
  223. GLCamera1->MoveAroundTarget((my - Y), 0);
  224. Player->Turn(-(mx - X));
  225. }
  226. mx = X;
  227. my = Y;
  228. }
  229. //---------------------------------------------------------------------------
  230. void __fastcall TForm1::GLCadencer1Progress(TObject *Sender, const double deltaTime,
  231. const double newTime)
  232. {
  233. HandleKeys();
  234. HandleAnimation();
  235. //This shows the manual progress, don't need this if you use the automatic mode
  236. if (GLDCEManager1->ManualStep)
  237. GLDCEManager1->Step(deltaTime);
  238. Help->ModulateColor->Alpha = Help->ModulateColor->Alpha - (deltaTime * 0.05);
  239. if (Help->ModulateColor->Alpha < 0.25)
  240. Help->ModulateColor->Alpha = 0.25;
  241. HelpShadow->ModulateColor->Alpha = Help->ModulateColor->Alpha;
  242. HelpShadow->Text = Help->Text;
  243. }
  244. //---------------------------------------------------------------------------
  245. void __fastcall TForm1::FormShow(TObject *Sender)
  246. {
  247. Load();
  248. GLCadencer1->Enabled = true;
  249. Help->Text =
  250. "Mouse Drag - Look\n\r\
  251. A,W,S,D - movement\n\r\
  252. SPACE - Jump\n\r\
  253. F1 - Add one ball\n\r\
  254. F2 - Add 10 balls\n\r\
  255. F3 - Add 20 mushrooms\n\r\
  256. F4 - Change ground to box\n\r\
  257. F5 - Toggle step mode\n\r\
  258. RETURN - Reset";
  259. }
  260. //---------------------------------------------------------------------------
  261. void __fastcall TForm1::Timer1Timer(TObject *Sender)
  262. {
  263. String s;
  264. if (GLDCEManager1->ManualStep)
  265. s = "Manual";
  266. else
  267. s = "Automatic";
  268. GLHUDText1->Text = Format("FPS: %.1f - Dynamics: %d - Statics: %d - Step mode: %s",
  269. ARRAYOFCONST((GLSceneViewer1->FramesPerSecond(),GLDCEManager1->DynamicCount,GLDCEManager1->StaticCount,s)));
  270. GLSceneViewer1->ResetPerformanceMonitor();
  271. }
  272. //---------------------------------------------------------------------------
  273. void __fastcall TForm1::PlayerBehaviours0Collision(TObject *Sender,
  274. TGLBaseSceneObject *ObjectCollided, TDCECollision &CollisionInfo)
  275. {
  276. //Use some kind of identifier to know what object you are colliding
  277. //You can use the Tag, TagFloat, Name, Class
  278. TAffineVector v;
  279. if (ObjectCollided->Tag == 1)
  280. {
  281. v = AffineVectorMake(VectorSubtract(ObjectCollided->AbsolutePosition, Player->AbsolutePosition));
  282. NormalizeVector(v);
  283. ScaleVector(v, 400.0);
  284. GetOrCreateDCEDynamic(ObjectCollided)->StopAbsAccel();
  285. GetOrCreateDCEDynamic(ObjectCollided)->ApplyAbsAccel(v);
  286. }
  287. }
  288. //---------------------------------------------------------------------------
  289. void __fastcall TForm1::GLDirectOpenGL1Render(TObject *Sender, TGLRenderContextInfo &rci)
  290. {
  291. int i;
  292. TAffineVector p, n;
  293. //To use this you will need to enable the debug define in the
  294. //GLEllipseCollision.pas, if you do, don't forget to clear the
  295. //triangle list! -> SetLength(debug_tri,0);
  296. rci.GLStates->PointSize = 5.0;
  297. glColor3f(0.0, 1.0, 0.0);
  298. for (i = 0; i < debug_tri.High; i++) {
  299. glColor3f(0.0, 0.0, 0.0);
  300. glBegin(GL_LINE_STRIP);
  301. glVertex3f(debug_tri[i].p1.X, debug_tri[i].p1.Y, debug_tri[i].p1.Z);
  302. glVertex3f(debug_tri[i].p2.X, debug_tri[i].p2.Y, debug_tri[i].p2.Z);
  303. glVertex3f(debug_tri[i].p3.X, debug_tri[i].p3.Y, debug_tri[i].p3.Z);
  304. glEnd;
  305. CalcPlaneNormal(debug_tri[i].p1, debug_tri[i].p2, debug_tri[i].p3, n);
  306. ScaleVector(n, 0.25);
  307. p.X = (debug_tri[i].p1.X + debug_tri[i].p2.X + debug_tri[i].p3.X) / 3.0;
  308. p.Y = (debug_tri[i].p1.Y + debug_tri[i].p2.Y + debug_tri[i].p3.Y) / 3.0;
  309. p.Z = (debug_tri[i].p1.Z + debug_tri[i].p2.Z + debug_tri[i].p3.Z) / 3.0;
  310. glColor3f(0.0, 0.0, 1.0);
  311. glBegin(GL_LINE_STRIP);
  312. glVertex3f(p.X, p.Y, p.Z);
  313. glVertex3f(p.X + n.X, p.Y + n.Y, p.Z + n.Z);
  314. glEnd;
  315. glBegin(GL_POINTS);
  316. glVertex3f(p.X + n.X, p.Y + n.Y, p.Z + n.Z);
  317. glEnd;
  318. }
  319. debug_tri.Length = 0.0;
  320. }
  321. //---------------------------------------------------------------------------