Unit1.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. //---------------------------------------------------------------------------
  2. #include <vcl.h>
  3. #include <stdlib.h>
  4. #include <math.hpp>
  5. #pragma hdrstop
  6. #include "Unit1.h"
  7. #pragma link "Physics.ODEUtils"
  8. #pragma link "GLS.Navigator"
  9. #pragma link "GLS.ShadowPlane"
  10. #pragma link "GLS.VectorGeometry"
  11. #pragma link "GLS.Extrusion"
  12. #pragma link "GLS.Texture"
  13. #pragma link "GLS.Cadencer"
  14. #pragma link "GLS.Objects"
  15. #pragma link "GLS.Scene"
  16. #pragma link "GLS.SceneViewer"
  17. #pragma link "GLS.Keyboard"
  18. #pragma link "GLS.VerletTypes"
  19. //---------------------------------------------------------------------------
  20. #pragma package(smart_init)
  21. //---------------------------------------------------------------------------
  22. #pragma resource "*.dfm"
  23. TForm1 *Form1;
  24. //---------------------------------------------------------------------------
  25. float random(void)
  26. {
  27. return (float)(rand() & 0xFFF) / (float)0xFFF;
  28. }
  29. //---------------------------------------------------------------------------
  30. void __cdecl nearCallback(void *data, PdxGeom o1, PdxGeom o2)
  31. {
  32. const int cCOL_MAX = 1;
  33. int i, numc;
  34. PdxBody b1, b2;
  35. TdContact contact[cCOL_MAX];
  36. TdJointID c;
  37. // exit without doing anything if the two bodies are connected by a joint
  38. b1 = dGeomGetBody(o1);
  39. b2 = dGeomGetBody(o2);
  40. if(b1 && b2 && (dAreConnected(b1, b2) != 0))
  41. return;
  42. for(i = 0; i <= cCOL_MAX - 1; i++)
  43. {
  44. contact[i].surface.mode = dContactBounce;
  45. // This determines friction, play around with it!
  46. contact[i].surface.mu = 3; //10e9; //dInfinity; SHOULD BE INFINITY!
  47. contact[i].surface.mu2 = 0;
  48. contact[i].surface.bounce = 0.5;
  49. contact[i].surface.bounce_vel = 0.1;
  50. }
  51. numc = dCollide(o1, o2, cCOL_MAX, contact[0].geom, sizeof(TdContact));
  52. if(numc > 0)
  53. {
  54. for(i = 0; i <= numc - 1; i++)
  55. {
  56. c = dJointCreateContact(Form1->world, Form1->contactgroup, &contact[i]);
  57. dJointAttach(c, b1, b2);
  58. }
  59. }
  60. }
  61. //---------------------------------------------------------------------------
  62. __fastcall TForm1::TForm1(TComponent* Owner)
  63. : TForm(Owner)
  64. {
  65. }
  66. //---------------------------------------------------------------------------
  67. const float cOffset = 0.03;
  68. void __fastcall TForm1::FormCreate(TObject *Sender)
  69. {
  70. Show();
  71. Randomize();
  72. world = dWorldCreate();
  73. space = dHashSpaceCreate(NULL);
  74. contactgroup = dJointGroupCreate (1000000);
  75. dWorldSetGravity (world,0,0,-9.81);
  76. CreateODEPlaneFromGLPlane(GLShadowPlane_Floor, space);
  77. CreateODEPlaneFromGLPlane(GLShadowPlane_Floor2, space);
  78. CreateODEPlaneFromGLPlane(GLShadowPlane_Wall, space);
  79. CreateODEPlaneFromGLPlane(GLShadowPlane_Wall2, space);
  80. CreateODEPlaneFromGLPlane(GLShadowPlane_Wall3, space);
  81. // dCreatePlane (space,0,0,1,0);
  82. VerletWorld = new TGLVerletWorld;
  83. VerletWorld->Iterations = 2;
  84. VerletWorld->VerletNodeClass = __classid(TGLVerletNode);
  85. CheckBox_FurGravityClick(Sender);
  86. CheckBox_WindResistenceClick(Sender);
  87. CreateVCPlaneFromGLPlane(GLShadowPlane_Floor, VerletWorld, cOffset);
  88. CreateVCPlaneFromGLPlane(GLShadowPlane_Floor2, VerletWorld, cOffset);
  89. CreateVCPlaneFromGLPlane(GLShadowPlane_Wall, VerletWorld, cOffset);
  90. CreateVCPlaneFromGLPlane(GLShadowPlane_Wall2, VerletWorld, cOffset);
  91. CreateVCPlaneFromGLPlane(GLShadowPlane_Wall3, VerletWorld, cOffset);
  92. HairList = new TList;
  93. CreateBall();
  94. }
  95. //---------------------------------------------------------------------------
  96. void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
  97. {
  98. GLCadencer1->Enabled = false;
  99. dJointGroupDestroy(contactgroup);
  100. dSpaceDestroy(space);
  101. dWorldDestroy(world);
  102. CloseODE();
  103. }
  104. //---------------------------------------------------------------------------
  105. double angle = 0;
  106. void __fastcall TForm1::GLCadencer1Progress(TObject *Sender, const double deltaTime,
  107. const double newTime)
  108. {
  109. const float cTIME_STEP = 0.01;
  110. int i, j;
  111. float Delta;
  112. TGLVerletHair *Hair;
  113. TGLLines *GLLines;
  114. Delta = deltaTime;
  115. angle = angle + Delta * 3;
  116. while(PhysicsTime < newTime)
  117. {
  118. PhysicsTime = PhysicsTime + cTIME_STEP;
  119. if(!CheckBox_LockBall->Checked)
  120. {
  121. dSpaceCollide(space, NULL, nearCallback);
  122. dWorldStep(world, cTIME_STEP); //}
  123. // remove all contact joints
  124. dJointGroupEmpty(contactgroup);
  125. if(IsKeyDown(VK_UP))
  126. dBodyAddForce(odeFurBallBody, 0, 0, 2.5);
  127. else if(IsKeyDown(VK_DOWN))
  128. dBodyAddForce(odeFurBallBody, 0, 0, -2.5);
  129. if(IsKeyDown('A'))
  130. dBodyAddForce(odeFurBallBody, 0, -1, 0);
  131. else if(IsKeyDown('D'))
  132. dBodyAddForce(odeFurBallBody, 0, 1, 0);
  133. if(IsKeyDown('W'))
  134. dBodyAddForce(odeFurBallBody, -1, 0, 0);
  135. else if(IsKeyDown('S'))
  136. dBodyAddForce(odeFurBallBody, 1, 0, 0);
  137. }
  138. PositionSceneObject(FurBall, odeFurBallGeom);
  139. VCSphere->Location = FurBall->Position->AsAffineVector;
  140. VerletWorld->Progress(cTIME_STEP, PhysicsTime);
  141. }
  142. for(i = 0; i <= HairList->Count - 1; i++)
  143. {
  144. Hair = (TGLVerletHair *) HairList->Items[i];
  145. GLLines = (TGLLines *) Hair->Data;
  146. for(j = 1; j <= Hair->NodeList->Count - 1; j++)
  147. GLLines->Nodes->Items[j - 1]->AsAffineVector =
  148. Hair->NodeList->Items[j]->Location;
  149. }
  150. }
  151. //---------------------------------------------------------------------------
  152. void __fastcall TForm1::DC_LightHolderProgress(TObject *Sender, const double deltaTime,
  153. const double newTime)
  154. {
  155. DC_LightHolder->Roll(deltaTime*M_PI*2*8);
  156. }
  157. //---------------------------------------------------------------------------
  158. void __fastcall TForm1::GLSceneViewer1MouseMove(TObject *Sender, TShiftState Shift,
  159. int X, int Y)
  160. {
  161. if (Shift.Contains(ssLeft))
  162. GLCamera1->MoveAroundTarget(mY-Y, mX-X);
  163. mX = X;
  164. mY = Y;
  165. }
  166. //---------------------------------------------------------------------------
  167. const int cRadiusMultiplier = 5, cSegmentCount = 4, cHairCount =
  168. 200, cRootDepth = 4;
  169. void __fastcall TForm1::CreateRandomHair()
  170. {
  171. int i;
  172. TAffineVector Dir;
  173. TGLVerletHair *Hair;
  174. TGLLines *GLLines;
  175. Dir = AffineVectorMake(random() - 0.5, random() - 0.5, random() - 0.5);
  176. NormalizeVector(Dir);
  177. TVHStiffnessSet vhs;
  178. vhs << vhsSkip1Node;
  179. Hair =
  180. new TGLVerletHair(VerletWorld, FurBall->Radius * cRootDepth,
  181. FurBall->Radius * cRadiusMultiplier, cSegmentCount,
  182. VectorAdd(AffineVectorMake(FurBall->AbsolutePosition),
  183. VectorScale(Dir, FurBall->Radius)), Dir, vhs);
  184. GLLines = (TGLLines *) (DCShadowCaster->AddNewChild(__classid(TGLLines)));
  185. GLLines->NodesAspect = lnaInvisible;
  186. GLLines->LineWidth = 2;
  187. GLLines->LineColor->Color = clrBlack;
  188. for(i = 0; i <= Hair->NodeList->Count - 1; i++)
  189. ((TGLVerletNode *) Hair->NodeList->Items[i])->GLBaseSceneObject = FurBall;
  190. for(i = 1; i <= Hair->NodeList->Count - 1; i++)
  191. GLLines->AddNode(Hair->NodeList->Items[i]->Location);
  192. for(i = 0; i <= GLLines->Nodes->Count - 1; i++)
  193. ((TGLLinesNode *) GLLines->Nodes->Items[i])->Color->Color = clrBlack;
  194. GLLines->ObjectStyle = GLLines->ObjectStyle << osDirectDraw;
  195. GLLines->SplineMode = lsmCubicSpline;
  196. Hair->Data = GLLines;
  197. HairList->Add(Hair);
  198. }
  199. //---------------------------------------------------------------------------
  200. void __fastcall TForm1::CreateFur()
  201. {
  202. TGLVerletHair *Hair;
  203. int i;
  204. for(i = 0; i <= HairList->Count - 1; i++)
  205. {
  206. Hair = ((TGLVerletHair *) HairList->Items[i]);
  207. delete((TGLLines *) Hair->Data);
  208. delete Hair;
  209. }
  210. HairList->Clear();
  211. for(i = 0; i <= cHairCount - 1; i++)
  212. CreateRandomHair();
  213. }
  214. //---------------------------------------------------------------------------
  215. void __fastcall TForm1::CreateBall()
  216. {
  217. TdMass m;
  218. dMassSetSphere(m, 1, FurBall->Radius);
  219. odeFurBallGeom = dCreateSphere(space, FurBall->Radius);
  220. odeFurBallBody = dBodyCreate(world);
  221. dGeomSetBody(odeFurBallGeom, odeFurBallBody);
  222. dBodySetMass(odeFurBallBody, &m);
  223. dBodySetLinearVel(odeFurBallBody, 0, 14, 0);
  224. dBodyAddTorque(odeFurBallBody, 0.1, 0.1, 0.1);
  225. // Add the GLScene object
  226. odeFurBallGeom->data = FurBall;
  227. CopyPosFromGeomToGL(odeFurBallGeom, FurBall);
  228. VCSphere = new TVCSphere(VerletWorld);
  229. VCSphere->Radius = FurBall->Radius * 1.1;
  230. VCSphere->Location = AffineVectorMake(FurBall->AbsolutePosition);
  231. CreateFur();
  232. }
  233. //---------------------------------------------------------------------------
  234. void __fastcall TForm1::CheckBox_FurGravityClick(TObject *Sender)
  235. {
  236. if(!CheckBox_FurGravity->Checked)
  237. delete Gravity;
  238. else
  239. {
  240. Gravity = new TVFGravity(VerletWorld);
  241. Gravity->Gravity = AffineVectorMake(0, 0, -9.81);
  242. }
  243. }
  244. //---------------------------------------------------------------------------
  245. const float cMaxWindMag = 8;
  246. void __fastcall TForm1::CheckBox_WindResistenceClick(TObject *Sender)
  247. {
  248. if(!CheckBox_WindResistence->Checked)
  249. delete AirResistance;
  250. else
  251. {
  252. AirResistance = new TVFAirResistance(VerletWorld);
  253. AirResistance->DragCoeff = 0.01;
  254. AirResistance->WindDirection = AffineVectorMake(1, 0, 0);
  255. AirResistance->WindMagnitude =
  256. (float)(TrackBar_WindForce->Position) / 100.0 * cMaxWindMag;
  257. AirResistance->WindChaos = 0.4;
  258. }
  259. TrackBar_WindForce->Enabled = CheckBox_WindResistence->Checked;
  260. }
  261. //---------------------------------------------------------------------------
  262. void __fastcall TForm1::TrackBar_WindForceChange(TObject *Sender)
  263. {
  264. if(AirResistance)
  265. AirResistance->WindMagnitude =
  266. (float)(TrackBar_WindForce->Position) / 100.0 * cMaxWindMag;
  267. }
  268. //---------------------------------------------------------------------------
  269. void __fastcall TForm1::CheckBox_BaldClick(TObject *Sender)
  270. {
  271. for(int i = 0; i <= HairList->Count - 1; i++)
  272. {
  273. TGLVerletHair *h = (TGLVerletHair *) (HairList->Items[i]);
  274. {
  275. h->Anchor->NailedDown = !CheckBox_Bald->Checked;
  276. h->Anchor->OldLocation = h->Anchor->Location;
  277. h->Root->NailedDown = !CheckBox_Bald->Checked;
  278. h->Root->OldLocation = h->Root->Location;
  279. }
  280. }
  281. if(!CheckBox_Bald->Checked)
  282. VerletWorld->PauseInertia(5);
  283. }
  284. //---------------------------------------------------------------------------
  285. void __fastcall TForm1::Timer1Timer(TObject *Sender)
  286. {
  287. Label_FPS->Caption = GLSceneViewer1->FramesPerSecondText(1);
  288. GLSceneViewer1->ResetPerformanceMonitor();
  289. }
  290. //---------------------------------------------------------------------------
  291. void __fastcall TForm1::CheckBox_ShadowsClick(TObject *Sender)
  292. {
  293. TGLLightSource *light;
  294. if(CheckBox_Shadows->Checked)
  295. light = GLLightSource1;
  296. else
  297. light = NULL;
  298. GLShadowPlane_Floor->ShadowedLight = light;
  299. GLShadowPlane_Floor2->ShadowedLight = light;
  300. GLShadowPlane_Wall->ShadowedLight = light;
  301. GLShadowPlane_Wall2->ShadowedLight = light;
  302. GLShadowPlane_Wall3->ShadowedLight = light;
  303. }
  304. //---------------------------------------------------------------------------
  305. void __fastcall TForm1::CheckBox_InertiaClick(TObject *Sender)
  306. {
  307. VerletWorld->Inertia = CheckBox_Inertia->Checked;
  308. }
  309. //---------------------------------------------------------------------------
  310. void __fastcall TForm1::FormMouseWheel(TObject *Sender, TShiftState Shift, int WheelDelta,
  311. TPoint &MousePos, bool &Handled)
  312. {
  313. GLCamera1-> AdjustDistanceToTarget(Power(1.1, WheelDelta / 120.0));
  314. }
  315. //---------------------------------------------------------------------------