Unit1.cpp 11 KB

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