PageRenderTime 56ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 1ms

/CollisionDetection/CollisionDetection/Game1.cs

https://github.com/vuce/GpuCollisionDetection
C# | 872 lines | 651 code | 163 blank | 58 comment | 49 complexity | 65bca17d7698ca9014f27aafe28d385f MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Microsoft.Xna.Framework;
  5. using Microsoft.Xna.Framework.Audio;
  6. using Microsoft.Xna.Framework.Content;
  7. using Microsoft.Xna.Framework.GamerServices;
  8. using Microsoft.Xna.Framework.Graphics;
  9. using Microsoft.Xna.Framework.Input;
  10. using Microsoft.Xna.Framework.Media;
  11. using Microsoft.Xna.Framework.Graphics.PackedVector;
  12. using System.Diagnostics;
  13. namespace CollisionDetection
  14. {
  15. public class Game1 : Microsoft.Xna.Framework.Game
  16. {
  17. bool draw = true;
  18. Stopwatch stopwatch, sw2;
  19. int cycles = 0;
  20. int cycles2 = 0;
  21. Camera camera, camera2;
  22. GraphicsDeviceManager graphics;
  23. SpriteBatch spriteBatch;
  24. GraphicsDevice device;
  25. float particleDiameter = 0.125f;
  26. //float particleDiameter = 0.0625f;
  27. float particleDrawSize = 0.06f;
  28. float particleStep = 0.125f;
  29. VertexPositionTexture[] particles;
  30. String fps = "0 fps";
  31. String fps2 = "0 fps";
  32. SpriteFont font1;
  33. GPUCollisionDetection gpucd;
  34. RenderTarget2D rt;
  35. Stopwatch sw = new Stopwatch();
  36. public Game1()
  37. {
  38. graphics = new GraphicsDeviceManager(this);
  39. Content.RootDirectory = "Content";
  40. graphics.PreferredBackBufferWidth = 1350;
  41. graphics.PreferredBackBufferHeight = 900;
  42. }
  43. protected override void Initialize()
  44. {
  45. base.Initialize();
  46. //TargetElapsedTime = new TimeSpan((int)(5.5 * 10000));
  47. TargetElapsedTime = new TimeSpan((int)(3 * 10000));
  48. }
  49. protected override void LoadContent()
  50. {
  51. int bodyTextureWidth = 16; int bodyTextureHeight = 16;
  52. int particleTextureWidth = 512; int particleTextureHeight = 512;
  53. //int particleTextureWidth = 512; int particleTextureHeight = 512;
  54. //int spatialHashWidth = 128; int spatialHashHeight = 128;
  55. //int spatialHashWidth = 256; int spatialHashHeight = 256;
  56. int spatialHashWidth = 512; int spatialHashHeight = 512;
  57. int bucketWidth = 12; int bucketHeight = 12;
  58. //Vector2 worldSize = new Vector2(12, 12);
  59. //Vector2 worldPosition = new Vector2(-6, -6);
  60. //Vector2 worldSize = new Vector2(60, 40);
  61. //Vector2 worldPosition = new Vector2(-30, -20);
  62. Vector2 worldSize = new Vector2(66, 40);
  63. Vector2 worldPosition = new Vector2(-33, -20);
  64. Vector3 globalWorldSize, globalWorldPosition;
  65. stopwatch = new Stopwatch();
  66. globalWorldPosition = new Vector3(worldPosition.X, worldPosition.Y, 0);
  67. globalWorldSize = new Vector3(worldSize.X, worldSize.Y, 1);
  68. bucketWidth = (int)(worldSize.X / particleStep);
  69. bucketHeight = (int)(worldSize.Y / particleStep);
  70. Console.WriteLine(bucketWidth + "," + bucketHeight);
  71. device = GraphicsDevice;
  72. spriteBatch = new SpriteBatch(GraphicsDevice);
  73. //if (first) printData();
  74. camera = new Camera(device.Viewport, 1, 1);
  75. camera.Position = new Vector3(0.5f, -0.5f, 1);
  76. camera.LookAt = new Vector3(0.5f, -0.5f, 0);
  77. camera.Update();
  78. camera2 = new Camera(device.Viewport, worldSize.X / 2, worldSize.Y / 2);
  79. camera2.LookAt = new Vector3(0, 0, 0);
  80. camera2.Position = new Vector3(0, 0, 1);
  81. camera2.Update();
  82. font1 = Content.Load<SpriteFont>(@"fonts\MyFont");
  83. stopwatch.Start();
  84. gpucd = new GPUCollisionDetection(device, Content, particleDiameter,
  85. new TextureDimension2D(bodyTextureWidth, bodyTextureHeight), new TextureDimension2D(particleTextureWidth, particleTextureHeight),
  86. new TextureDimension2D(spatialHashWidth, spatialHashHeight), globalWorldSize, globalWorldPosition, new TextureDimension3D(bucketWidth, bucketHeight, 1));
  87. interestingWorldGPUcd();
  88. //interestingWorldGPUcd2();
  89. //interestingWorldGPUcd3();
  90. //fluids();
  91. //fluidBoxes(0.25f);
  92. //fluidBoxes(0.375f);
  93. gpucd.setBuffers();
  94. //gpucd.spatialHash.setBuffersComplete();
  95. gpucd.deleteObject(0);
  96. //gpucd.deleteObject(1);
  97. rt = new RenderTarget2D(device, gpucd.bodyLinearMomentum.Width, gpucd.bodyLinearMomentum.Height, false, SurfaceFormat.Vector4, DepthFormat.None);
  98. sw2 = new Stopwatch();
  99. sw.Start();
  100. sw2.Start();
  101. cycles2 = 0;
  102. }
  103. protected override void UnloadContent()
  104. {
  105. }
  106. protected override void Update(GameTime gameTime)
  107. {
  108. if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
  109. this.Exit();
  110. VertexPositionTexture[] quad = new VertexPositionTexture[4];
  111. quad[0] = new VertexPositionTexture(new Vector3(0, 0, 0), new Vector2(0, 0));
  112. quad[1] = new VertexPositionTexture(new Vector3(1, 0, 0), new Vector2(1, 0));
  113. quad[2] = new VertexPositionTexture(new Vector3(0, -1, 0), new Vector2(0, 1));
  114. quad[3] = new VertexPositionTexture(new Vector3(1, -1, 0), new Vector2(1, 1));
  115. device.SetRenderTarget(rt);
  116. Effect gravityEffect = Content.Load<Effect>(@"external_effects\gravity");
  117. gravityEffect.CurrentTechnique = gravityEffect.Techniques["Gravity"];
  118. gravityEffect.Parameters["Projection"].SetValue(camera.ProjectionMatrix);
  119. gravityEffect.Parameters["View"].SetValue(camera.ViewMatrix);
  120. gravityEffect.Parameters["World"].SetValue(Matrix.Identity);
  121. gravityEffect.Parameters["bodyMass"].SetValue(gpucd.bodyMass);
  122. gravityEffect.Parameters["bodyLinearMomentum"].SetValue(gpucd.bodyLinearMomentum);
  123. float factor = gameTime.ElapsedGameTime.Ticks == 0 ? 1 : (gameTime.ElapsedGameTime.Ticks / 10000f);
  124. //gravityEffect.Parameters["gravity"].SetValue(0.005f * factor);
  125. gravityEffect.Parameters["gravity"].SetValue(0.002f * factor);
  126. device.BlendState = BlendState.Opaque;
  127. device.Clear(Color.Black);
  128. foreach (var pass in gravityEffect.CurrentTechnique.Passes)
  129. {
  130. pass.Apply();
  131. device.DrawUserPrimitives<VertexPositionTexture>(PrimitiveType.TriangleStrip, quad, 0, 2);
  132. }
  133. device.SetRenderTarget(null);
  134. if (sw.ElapsedMilliseconds > 3000)
  135. {
  136. gpucd.bodyLinearMomentum = (Texture2D)rt;
  137. }
  138. gpucd.update(gameTime, false);
  139. cycles++;
  140. if (stopwatch.ElapsedMilliseconds >= 500)
  141. {
  142. stopwatch.Stop();
  143. fps = (int)(1000 / (stopwatch.ElapsedMilliseconds / (float)cycles)) + " fps";
  144. stopwatch.Restart();
  145. cycles = 0;
  146. }
  147. base.Update(gameTime);
  148. }
  149. protected override void Draw(GameTime gameTime)
  150. {
  151. #region Draw
  152. if (draw)
  153. {
  154. GraphicsDevice.Clear(Color.White);
  155. Effect drawEffect = Content.Load<Effect>(@"external_effects\draw_particles");
  156. drawEffect.CurrentTechnique = drawEffect.Techniques["Draw"];
  157. drawEffect.Parameters["Projection"].SetValue(camera2.ProjectionMatrix);
  158. drawEffect.Parameters["View"].SetValue(camera2.ViewMatrix);
  159. drawEffect.Parameters["World"].SetValue(Matrix.Identity);
  160. drawEffect.Parameters["pposition"].SetValue((Texture2D)gpucd.particlePosition);
  161. drawEffect.Parameters["ptextureWidth"].SetValue(gpucd.particlesTX.Width);
  162. drawEffect.Parameters["ptextureHeight"].SetValue(gpucd.particlesTX.Height);
  163. drawEffect.Parameters["size"].SetValue(particleDrawSize / 2.0f);
  164. drawEffect.Parameters["color"].SetValue(new Vector4(1, 0, 0, 0.5f));
  165. foreach (var pass in drawEffect.CurrentTechnique.Passes)
  166. {
  167. pass.Apply();
  168. device.DrawUserPrimitives<VertexPositionTexture>(PrimitiveType.TriangleList, particles, 0, particles.Length / 3);
  169. }
  170. Effect drawEffect2 = Content.Load<Effect>(@"external_effects\draw_particles");
  171. drawEffect2.CurrentTechnique = drawEffect2.Techniques["Draw"];
  172. drawEffect2.Parameters["Projection"].SetValue(camera2.ProjectionMatrix);
  173. drawEffect2.Parameters["View"].SetValue(camera2.ViewMatrix);
  174. drawEffect2.Parameters["World"].SetValue(Matrix.Identity);
  175. drawEffect2.Parameters["pposition"].SetValue((Texture2D)gpucd.particlePosition);
  176. drawEffect2.Parameters["ptextureWidth"].SetValue(gpucd.particlesTX.Width);
  177. drawEffect2.Parameters["ptextureHeight"].SetValue(gpucd.particlesTX.Height);
  178. drawEffect2.Parameters["size"].SetValue(particleDiameter / 2.0f);
  179. drawEffect2.Parameters["color"].SetValue(new Vector4(0.7f, 0.7f, 0.7f, 1));
  180. foreach (var pass in drawEffect2.CurrentTechnique.Passes)
  181. {
  182. pass.Apply();
  183. device.DrawUserPrimitives<VertexPositionTexture>(PrimitiveType.TriangleList, particles, 0, particles.Length / 3);
  184. }
  185. }
  186. // draw fps
  187. Vector2 FontOrigin = font1.MeasureString(fps) / 2;
  188. Vector2 fontPos = new Vector2(5, 5);
  189. spriteBatch.Begin();
  190. spriteBatch.DrawString(font1, fps, fontPos + FontOrigin, Color.Purple, 0, FontOrigin, 1.0f, SpriteEffects.None, 0.5f);
  191. spriteBatch.End();
  192. // draw fps
  193. FontOrigin = font1.MeasureString(fps2) / 2;
  194. fontPos = new Vector2(5, 25);
  195. spriteBatch.Begin();
  196. spriteBatch.DrawString(font1, fps2, fontPos + FontOrigin, Color.Purple, 0, FontOrigin, 1.0f, SpriteEffects.None, 0.5f);
  197. spriteBatch.End();
  198. base.Draw(gameTime);
  199. #endregion
  200. cycles2++;
  201. if (sw2.ElapsedMilliseconds >= 500)
  202. {
  203. sw2.Stop();
  204. fps2 = (int)(1000 / (sw2.ElapsedMilliseconds / (float)cycles2)) + " fps";
  205. sw2.Restart();
  206. cycles2 = 0;
  207. }
  208. }
  209. private VertexPositionTexture[] getParticles()
  210. {
  211. VertexPositionTexture[] particles = new VertexPositionTexture[gpucd.Particles * 6];
  212. int j = 0;
  213. for (int i = 0; i < gpucd.Particles; i++)
  214. {
  215. float index = i / (float)(gpucd.particlesTX.Width * gpucd.particlesTX.Height);
  216. particles[j] = new VertexPositionTexture(new Vector3(-0.5f, 0.5f, index), new Vector2(0, 0)); j++;
  217. particles[j] = new VertexPositionTexture(new Vector3(0.5f, 0.5f, index), new Vector2(0, 0)); j++;
  218. particles[j] = new VertexPositionTexture(new Vector3(-0.5f, -0.5f, index), new Vector2(0, 0)); j++;
  219. particles[j] = new VertexPositionTexture(new Vector3(0.5f, 0.5f, index), new Vector2(0, 0)); j++;
  220. particles[j] = new VertexPositionTexture(new Vector3(0.5f, -0.5f, index), new Vector2(0, 0)); j++;
  221. particles[j] = new VertexPositionTexture(new Vector3(-0.5f, -0.5f, index), new Vector2(0, 0)); j++;
  222. }
  223. return particles;
  224. }
  225. private Particle[] circle(float diameter, float weight)
  226. {
  227. double phi = Math.Tan(particleDiameter / (diameter/2));
  228. int n = (int)(2 * Math.PI / phi) + 1;
  229. Particle[] particles = new Particle[n];
  230. int i = 0;
  231. for (double p = 0; p <= 2 * Math.PI; p += phi)
  232. {
  233. float x = (float)(diameter/2 * Math.Cos(p));
  234. float y = (float)(diameter/2 * Math.Sin(p));
  235. particles[i] = new Particle(new Vector3(x, y, 0), weight / n);
  236. i++;
  237. }
  238. return particles;
  239. }
  240. private Particle[] box(float diameter, float weight) {
  241. int n = 0;
  242. float k = diameter / 2;
  243. for (float x = -k + particleStep; x <= k - particleStep; x += particleStep)
  244. n++;
  245. for (float x = -k + particleStep; x <= k - particleStep; x += particleStep)
  246. n++;
  247. for (float y = -k; y <= k; y += particleStep)
  248. n++;
  249. for (float y = -k; y <= k; y += particleStep)
  250. n++;
  251. // add bounding box
  252. Particle[] particles = new Particle[n];
  253. int i = 0;
  254. for (float x = -k + particleStep; x <= k - particleStep; x += particleStep)
  255. {
  256. particles[i] = new Particle(new Vector3(x, -k, 0), weight/n); i++;
  257. }
  258. for (float x = -k + particleStep; x <= k - particleStep; x += particleStep)
  259. {
  260. particles[i] = new Particle(new Vector3(x, k, 0), weight / n); i++;
  261. }
  262. for (float y = -k; y <= k; y += particleStep)
  263. {
  264. particles[i] = new Particle(new Vector3(-k, y, 0), weight / n); i++;
  265. }
  266. for (float y = -k; y <= k; y += particleStep)
  267. {
  268. particles[i] = new Particle(new Vector3(k, y, 0), weight / n); i++;
  269. }
  270. return particles;
  271. }
  272. private Particle[] rectangle(float x_, float y_, float weight)
  273. {
  274. int n = 0;
  275. float kx = x_ / 2;
  276. float ky = y_ / 2;
  277. for (float x = -kx + particleStep; x <= kx - particleStep; x += particleStep)
  278. n++;
  279. for (float x = -kx + particleStep; x <= kx - particleStep; x += particleStep)
  280. n++;
  281. for (float y = -ky; y <= ky; y += particleStep)
  282. n++;
  283. for (float y = -ky; y <= ky; y += particleStep)
  284. n++;
  285. // add bounding box
  286. Particle[] particles = new Particle[n];
  287. int i = 0;
  288. for (float x = -kx + particleStep; x <= kx - particleStep; x += particleStep)
  289. {
  290. particles[i] = new Particle(new Vector3(x, -ky, 0), weight / n); i++;
  291. }
  292. for (float x = -kx + particleStep; x <= kx - particleStep; x += particleStep)
  293. {
  294. particles[i] = new Particle(new Vector3(x, ky, 0), weight / n); i++;
  295. }
  296. for (float y = -ky; y <= ky; y += particleStep)
  297. {
  298. particles[i] = new Particle(new Vector3(-kx, y, 0), weight / n); i++;
  299. }
  300. for (float y = -ky; y <= ky; y += particleStep)
  301. {
  302. particles[i] = new Particle(new Vector3(kx, y, 0), weight / n); i++;
  303. }
  304. return particles;
  305. }
  306. private void interestingWorldGPUcd()
  307. {
  308. Particle[] particles;
  309. bool run = true;
  310. particles = box(0.5f, 10);
  311. gpucd.addObject(
  312. new Vector3(-0.3f, 0.1f, 0), Quaternion.Identity,
  313. new Vector3(0, 0, 0), Vector3.Zero,
  314. particles);
  315. particles = box(0.5f, 10);
  316. gpucd.addObject(
  317. new Vector3(0.6f, -0.35f, 0), Quaternion.Identity,
  318. new Vector3(0, 0, 0), Vector3.Zero,
  319. particles);
  320. particles = box(0.5f, 10);
  321. gpucd.addObject(
  322. new Vector3(0.4f, 0.6f, 0), Quaternion.Identity,
  323. new Vector3(0, 0, 0), Vector3.Zero,
  324. particles);
  325. // circle
  326. particles = circle(2.5f, 6);
  327. gpucd.addObject(
  328. new Vector3(0.1f, 0.1f, 0), Quaternion.Identity,
  329. new Vector3(0, 0, 0), Vector3.Zero,
  330. particles);
  331. particles = box(4f, 10);
  332. gpucd.addObject(
  333. new Vector3(0.5f, -0.5f, 0), Quaternion.Identity,
  334. new Vector3(0, 0, 0), Vector3.Zero,
  335. particles);
  336. // circle
  337. particles = circle(0.8f, 6);
  338. gpucd.addObject(
  339. new Vector3(1.5f, -1.5f, 0), Quaternion.Identity,
  340. new Vector3(0, 0, 0), Vector3.Zero,
  341. particles);
  342. particles = box(1f, 10);
  343. gpucd.addObject(
  344. new Vector3(3f, 3f, 0), Quaternion.Identity,
  345. new Vector3(run ? 40 : 0, run ? 25 : 0, 0), Vector3.Zero,
  346. particles);
  347. particles = box(1f, 10);
  348. gpucd.addObject(
  349. new Vector3(-3f, 3f, 0), Quaternion.Identity,
  350. new Vector3(run ? 50 : 0, 0, 0), Vector3.Zero,
  351. //new Vector3(0, 0, 0), Vector3.Zero,
  352. particles);
  353. particles = box(1f, 10);
  354. gpucd.addObject(
  355. new Vector3(3f, -4f, 0), Quaternion.Identity,
  356. new Vector3(run ? 30 : 0, run ? 50 : 0, 0), Vector3.Zero,
  357. //new Vector3(0, 0, 0), Vector3.Zero,
  358. particles);
  359. for (int i = 0; i < 5; i++)
  360. {
  361. particles = circle(0.7f, 3);
  362. gpucd.addObject(
  363. new Vector3(-3f, i - 3, 0), Quaternion.Identity,
  364. new Vector3(0, 0, 0), Vector3.Zero,
  365. particles);
  366. particles = new Particle[] { new Particle(Vector3.Zero, 2) };
  367. gpucd.addObject(
  368. new Vector3(-3f, i - 3, 0), Quaternion.Identity,
  369. new Vector3(0, 0, 0), Vector3.Zero,
  370. particles);
  371. particles = circle(0.7f, 3);
  372. gpucd.addObject(
  373. new Vector3(-4f, i - 3, 0), Quaternion.Identity,
  374. new Vector3(0, 0, 0), Vector3.Zero,
  375. particles);
  376. particles = new Particle[] { new Particle(Vector3.Zero, 2) };
  377. gpucd.addObject(
  378. new Vector3(-4f, i - 3 - 0.1f, 0), Quaternion.Identity,
  379. new Vector3(0, 0, 0), Vector3.Zero,
  380. particles);
  381. particles = new Particle[] { new Particle(Vector3.Zero, 2) };
  382. gpucd.addObject(
  383. new Vector3(-4f, i - 3 + 0.1f, 0), Quaternion.Identity,
  384. new Vector3(0, 0, 0), Vector3.Zero,
  385. particles);
  386. particles = new Particle[] { new Particle(Vector3.Zero, 2) };
  387. gpucd.addObject(
  388. new Vector3(-4f - 0.2f, i - 3, 0), Quaternion.Identity,
  389. new Vector3(0, 0, 0), Vector3.Zero,
  390. particles);
  391. }
  392. for (int i = 0; i < 5; i++)
  393. {
  394. particles = circle(0.7f, 3);
  395. gpucd.addObject(
  396. new Vector3(4f, i - 3, 0), Quaternion.Identity,
  397. new Vector3(0, 0, 0), Vector3.Zero,
  398. particles);
  399. }
  400. for (int i = 0; i < 6; i++)
  401. {
  402. particles = box(0.25f, 3);
  403. gpucd.addObject(
  404. new Vector3(i - 3, 4f, 0), Quaternion.Identity,
  405. new Vector3(0, 0, 0), Vector3.Zero,
  406. particles);
  407. particles = box(0.25f, 3);
  408. gpucd.addObject(
  409. new Vector3(i - 3, 4f + 0.5f, 0), Quaternion.Identity,
  410. new Vector3(0, 0, 0), Vector3.Zero,
  411. particles);
  412. }
  413. for (int i = 0; i < 3; i++)
  414. {
  415. particles = box(0.25f, 3);
  416. gpucd.addObject(
  417. new Vector3(i - 1, 3f, 0), Quaternion.Identity,
  418. new Vector3(0, 0, 0), Vector3.Zero,
  419. particles);
  420. particles = box(0.25f, 3);
  421. gpucd.addObject(
  422. new Vector3(i - 1, 2.5f, 0), Quaternion.Identity,
  423. new Vector3(0, 0, 0), Vector3.Zero,
  424. particles);
  425. particles = box(0.25f, 3);
  426. gpucd.addObject(
  427. new Vector3(i - 1, 2f, 0), Quaternion.Identity,
  428. new Vector3(0, 0, 0), Vector3.Zero,
  429. particles);
  430. }
  431. for (float i = -1; i < 3.2f; i += 0.38f)
  432. {
  433. particles = box(0.25f, 3);
  434. gpucd.addObject(
  435. new Vector3(i - 1, -4.6f, 0), Quaternion.Identity,
  436. new Vector3(0, 0, 0), Vector3.Zero,
  437. particles);
  438. particles = box(0.25f, 3);
  439. gpucd.addObject(
  440. new Vector3(i - 1, -4.2f, 0), Quaternion.Identity,
  441. new Vector3(0, 0, 0), Vector3.Zero,
  442. particles);
  443. particles = box(0.25f, 3);
  444. gpucd.addObject(
  445. new Vector3(i - 1, -3.8f, 0), Quaternion.Identity,
  446. new Vector3(0, 0, 0), Vector3.Zero,
  447. particles);
  448. particles = box(0.25f, 3);
  449. gpucd.addObject(
  450. new Vector3(i - 1, -3.4f, 0), Quaternion.Identity,
  451. new Vector3(0, 0, 0), Vector3.Zero,
  452. particles);
  453. particles = box(0.25f, 3);
  454. gpucd.addObject(
  455. new Vector3(i - 1, -3f, 0), Quaternion.Identity,
  456. new Vector3(0, 0, 0), Vector3.Zero,
  457. particles);
  458. }
  459. //containment
  460. particles = box(10f, 50000);
  461. gpucd.addObject(
  462. new Vector3(0f, 0f, 0), Quaternion.Identity,
  463. new Vector3(0, 0, 0), Vector3.Zero,
  464. particles, true);
  465. this.particles = getParticles();
  466. }
  467. private void interestingWorldGPUcd3() {
  468. Particle[] particles;
  469. particles = rectangle(7f, 7f, 10);
  470. gpucd.addObject(
  471. new Vector3(-0.0f, -0.0f, 0), Quaternion.Identity,
  472. new Vector3(0, 0, 0), new Vector3(0,0,1000f),
  473. particles);
  474. this.particles = getParticles();
  475. }
  476. private void interestingWorldGPUcd2() {
  477. Particle[] particles;
  478. particles = rectangle(7f, 0.125f, 10);
  479. gpucd.addObject(
  480. new Vector3(-0.0f, -0.0f, 0), Quaternion.Identity,
  481. new Vector3(0, 0, 0), Vector3.Zero,
  482. particles);
  483. particles = new Particle[] { new Particle(Vector3.Zero, 50000) };
  484. gpucd.addObject(
  485. new Vector3(0.1f, -0.2f, 0), Quaternion.Identity,
  486. new Vector3(0, 0, 0), Vector3.Zero,
  487. particles, true);
  488. particles = new Particle[] { new Particle(Vector3.Zero, 50000) };
  489. gpucd.addObject(
  490. new Vector3(-0.1f, -0.2f, 0), Quaternion.Identity,
  491. new Vector3(0, 0, 0), Vector3.Zero,
  492. particles, true);
  493. // circle
  494. particles = circle(1.8f, 25);
  495. gpucd.addObject(
  496. new Vector3(-3f, 3.8f, 0), Quaternion.Identity,
  497. new Vector3(0, 0, 0), Vector3.Zero,
  498. particles);
  499. // circle
  500. particles = circle(0.5f, 2.5f);
  501. gpucd.addObject(
  502. new Vector3(3f, 0.438f, 0), Quaternion.Identity,
  503. new Vector3(0, 0, 0), Vector3.Zero,
  504. particles);
  505. //containment
  506. //int n = 5;
  507. //List<Particle> lst = new List<Particle>();
  508. //for (int i = 0; i < n; i++)
  509. //{
  510. // lst.AddRange(box(10f + i*particleDiameter, 50000));
  511. //}
  512. //particles = lst.ToArray();
  513. //gpucd.addObject(
  514. // new Vector3(0f, 0f, 0), Quaternion.Identity,
  515. // new Vector3(0, 0, 0), Vector3.Zero,
  516. // particles, true);
  517. //this.particles = getParticles();
  518. int n = 2;
  519. List<Particle> lst = new List<Particle>();
  520. for (int i = 0; i < n; i++)
  521. {
  522. float kx = 5;
  523. float ky = 5;
  524. float weight = 500;
  525. particles = new Particle[(int)((kx - particleStep) * 2) + 1];
  526. int m = 0;
  527. for (float x = -kx + particleStep; x <= kx - particleStep; x += particleStep)
  528. {
  529. particles[m] = new Particle(new Vector3(x, -ky, 0), weight / n); i++;
  530. }
  531. gpucd.addObject(
  532. Vector3.Zero, Quaternion.Identity,
  533. Vector3.Zero, Vector3.Zero,
  534. particles, true);
  535. for (float x = -kx + particleStep; x <= kx - particleStep; x += particleStep)
  536. {
  537. particles[i] = new Particle(new Vector3(x, ky, 0), weight / n); i++;
  538. }
  539. for (float y = -ky; y <= ky; y += particleStep)
  540. {
  541. particles[i] = new Particle(new Vector3(-kx, y, 0), weight / n); i++;
  542. }
  543. for (float y = -ky; y <= ky; y += particleStep)
  544. {
  545. particles[i] = new Particle(new Vector3(kx, y, 0), weight / n); i++;
  546. }
  547. particles = box(10f + i * particleDiameter, 50000);
  548. gpucd.addObject(
  549. Vector3.Zero, Quaternion.Identity,
  550. Vector3.Zero, Vector3.Zero,
  551. particles, true);
  552. }
  553. this.particles = getParticles();
  554. }
  555. public void fluids() {
  556. Particle[] particles;
  557. Random r = new Random();
  558. Vector3 v = new Vector3();
  559. //for (float y = -18f + particleDiameter; y < -5f; y = y + particleDiameter / 0.99f)
  560. for (float y = -14f + particleDiameter; y < 12.8f; y = y + particleDiameter / 0.99f)
  561. //for (float y = -8f + particleDiameter; y < -7; y = y + particleDiameter / 0.99f)
  562. {
  563. //for (float x = -9f + particleDiameter; x < 8.8f; x += particleDiameter / 0.99f)
  564. for (float x = -19f + particleDiameter; x < 19f; x += particleDiameter / 0.99f)
  565. {
  566. particles = new Particle[] { new Particle(Vector3.Zero, 0.1f, 7f, 0.0005f, 0.002f) };
  567. v.X = x + (float)(r.NextDouble() * 0.005f);
  568. v.Y = y + (float)(r.NextDouble() * 0.005f);
  569. gpucd.addObject(
  570. v, Quaternion.Identity,
  571. Vector3.Zero, Vector3.Zero,
  572. particles);
  573. }
  574. }
  575. #region containment box
  576. int n = 1;
  577. List<Particle> lst = new List<Particle>();
  578. for (int i = 0; i < n; i++)
  579. {
  580. float kx = 25f;
  581. float ky = 18f;
  582. float weight = 5000;
  583. particles = new Particle[(int)((kx - particleStep) * 2 / particleStep) + 1];
  584. int m = 0;
  585. for (float x = -kx + particleStep; x <= kx - particleStep; x += particleStep)
  586. {
  587. particles[m] = new Particle(new Vector3(x, -ky, 0), weight / n, 30f, 0.0f); m++;
  588. }
  589. gpucd.addObject(
  590. Vector3.Zero, Quaternion.Identity,
  591. Vector3.Zero, Vector3.Zero,
  592. particles, true);
  593. m = 0;
  594. for (float x = -kx + particleStep; x <= kx - particleStep; x += particleStep)
  595. {
  596. particles[m] = new Particle(new Vector3(x, ky, 0), weight / n, 30f, 0.0f); m++;
  597. }
  598. gpucd.addObject(
  599. Vector3.Zero, Quaternion.Identity,
  600. Vector3.Zero, Vector3.Zero,
  601. particles, true);
  602. m = 0;
  603. particles = new Particle[(int)((ky) * 2 / particleStep) + 1];
  604. for (float y = -ky; y <= ky; y += particleStep)
  605. {
  606. particles[m] = new Particle(new Vector3(-kx, y, 0), weight / n, 30f, 0.0f); m++;
  607. }
  608. gpucd.addObject(
  609. Vector3.Zero, Quaternion.Identity,
  610. Vector3.Zero, Vector3.Zero,
  611. particles, true);
  612. m = 0;
  613. for (float y = -ky; y <= ky; y += particleStep)
  614. {
  615. particles[m] = new Particle(new Vector3(kx, y, 0), weight / n, 30f, 0.0f); m++;
  616. }
  617. gpucd.addObject(
  618. Vector3.Zero, Quaternion.Identity,
  619. Vector3.Zero, Vector3.Zero,
  620. particles, true);
  621. }
  622. #endregion
  623. //particles = box(18f, 50000);
  624. //gpucd.addObject(
  625. // new Vector3(0f, 0f, 0), Quaternion.Identity,
  626. // new Vector3(0, 0, 0), Vector3.Zero,
  627. // particles, true);
  628. this.particles = getParticles();
  629. }
  630. private void fluidBoxes(float diameter) {
  631. Particle[] particles = null;
  632. Random r = new Random();
  633. Vector3 v = new Vector3();
  634. //for (float y = -14f + diameter; y < 12.8f; y = y + diameter / 0.89f)
  635. int c = 0;
  636. //for (float y = -18f + diameter; y < 17.5f; y = y + diameter / 0.85f)
  637. //for (float y = -18f + diameter; y < 17.5f; y = y + diameter / 0.59f)
  638. for (float y = -18f + diameter; y < 17.5f; y = y + diameter / 0.59f)
  639. {
  640. //for (float x = -23f + diameter; x < 8f; x += diameter / 0.59f)
  641. //for (float x = -23f + diameter; x < 17.5f; x += diameter / 0.59f)
  642. for (float x = -31.5f + diameter; x < 31.5f; x += diameter / 0.59f)
  643. {
  644. //particles = new Particle[] { new Particle(Vector3.Zero, 0.1f, 7f, 0.0005f, 0.002f) };
  645. particles = box(diameter, 1);
  646. //v.X = x + (float)(r.NextDouble() * 0.005f);
  647. //v.Y = y + (float)(r.NextDouble() * 0.005f);
  648. v.X = x;
  649. v.Y = y;
  650. int index = gpucd.addObject(
  651. v, Quaternion.Identity,
  652. Vector3.Zero, Vector3.Zero,
  653. particles);
  654. c++;
  655. }
  656. }
  657. Console.WriteLine(c + " boxes");
  658. Console.WriteLine(particles.Length * c + " particles");
  659. float kx = 32f;
  660. float ky = 18f;
  661. #region containment box
  662. int n = 1;
  663. for (int i = 0; i < n; i++)
  664. {
  665. float weight = 5000;
  666. particles = new Particle[(int)((kx - particleStep) * 2 / particleStep) + 1];
  667. int m = 0;
  668. for (float x = -kx + particleStep; x <= kx - particleStep; x += particleStep)
  669. {
  670. particles[m] = new Particle(new Vector3(x, -ky, 0), weight / n, 30f, 0.0f); m++;
  671. }
  672. gpucd.addObject(
  673. Vector3.Zero, Quaternion.Identity,
  674. Vector3.Zero, Vector3.Zero,
  675. particles, true);
  676. m = 0;
  677. for (float x = -kx + particleStep; x <= kx - particleStep; x += particleStep)
  678. {
  679. particles[m] = new Particle(new Vector3(x, ky, 0), weight / n, 30f, 0.0f); m++;
  680. }
  681. gpucd.addObject(
  682. Vector3.Zero, Quaternion.Identity,
  683. Vector3.Zero, Vector3.Zero,
  684. particles, true);
  685. m = 0;
  686. particles = new Particle[(int)((ky) * 2 / particleStep) + 1];
  687. for (float y = -ky; y <= ky; y += particleStep)
  688. {
  689. particles[m] = new Particle(new Vector3(-kx, y, 0), weight / n, 30f, 0.0f); m++;
  690. }
  691. gpucd.addObject(
  692. Vector3.Zero, Quaternion.Identity,
  693. Vector3.Zero, Vector3.Zero,
  694. particles, true);
  695. m = 0;
  696. for (float y = -ky; y <= ky; y += particleStep)
  697. {
  698. particles[m] = new Particle(new Vector3(kx, y, 0), weight / n, 30f, 0.0f); m++;
  699. }
  700. gpucd.addObject(
  701. Vector3.Zero, Quaternion.Identity,
  702. Vector3.Zero, Vector3.Zero,
  703. particles, true);
  704. }
  705. #endregion
  706. this.particles = getParticles();
  707. }
  708. }
  709. }