XNA L08–Amazing XNA Utilities

801 views

Published on

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
801
On SlideShare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
48
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

XNA L08–Amazing XNA Utilities

  1. 1. Mohammad Shaker mohammadshaker.com @ZGTRShaker 2011, 2012, 2013, 2014 XNA Game Development L08 – Amazing XNA Utilities
  2. 2. Collision Detection
  3. 3. Collision Detection determines whether two objects overlap and therefore have collided in your virtual world.
  4. 4. Collision Detection Accurate collision detection is fundamental to a solid game engine.
  5. 5. Your cars would drive off the road, your people would walk through buildings, and your camera would travel through cement walls :D
  6. 6. Collision Detection • Microsoft Book, Chapter 18, Page: 285
  7. 7. Collision Detection • XNA has two main types for implementing collision detection
  8. 8. Collision Detection • XNA has two main types for implementing collision detection – BoundingBox
  9. 9. Collision Detection • XNA has two main types for implementing collision detection – BoundingBox – BoundingSphere
  10. 10. Collision Detection • XNA has two main types for implementing collision detection – BoundingBox • a box will better suit a rectangular high-rise building – BoundingSphere
  11. 11. Collision Detection • XNA has two main types for implementing collision detection – BoundingBox • a box will better suit a rectangular high-rise building – BoundingSphere • a bounding sphere offers a better fit for rounded objects such as a domed arena
  12. 12. Collision Detection – BoundingSphere
  13. 13. Collision Detection – BoundingSphere
  14. 14. Collision Detection – BoundingSphere
  15. 15. Collision Detection – BoundingSphere
  16. 16. Collision Detection • CONTAINMENT TYPE – BoundingBox – BoundingSphere
  17. 17. Collision Detection • CONTAINMENT TYPE – BoundingBox – BoundingSphere
  18. 18. Collision Detection • CONTAINMENT TYPE – BoundingBox – BoundingSphere
  19. 19. Collision Detection BOUNDING BOX
  20. 20. Collision Detection - BOUNDING BOX • Initializing the Bounding BOX • Intersects() common overloads BoundingBox boundingBox = new BoundingBox(Vector3 min, Vector3 max); public bool Intersects(BoundingBox box); public bool Intersects(BoundingSphere sphere);
  21. 21. Collision Detection - BOUNDING BOX • Comparing one bounding box with another: • Comparing a bounding box with a bounding sphere: • Comparing a bounding box with a single three-dimensional position: public void Contains(ref BoundingBox box, out ContainmentType result); public void Contains(ref BoundingSphere sphere, out ContainmentType result); public void Contains(ref Vector3 point, out ContainmentType result);
  22. 22. Collision Detection BOUNDING SPHERE
  23. 23. Collision Detection - BOUNDING SPHERE • Initializing the Bounding Sphere • Intersects() Common Overloads • Contains() public BoundingSphere(Vector3 center, float radius); public bool Intersects(BoundingBox box); public bool Intersects(BoundingSphere sphere); public void Contains(ref BoundingSphere sphere,out ContainmentType result); public void Contains(ref BoundingBox box, out ContainmentType result); public void Contains(ref Vector3 point, out ContainmentType result);
  24. 24. Collision Detection - BOUNDING SPHERE • Initializing the Bounding Sphere • Intersects() Common Overloads • Contains() public bool Intersects(BoundingBox box); public bool Intersects(BoundingSphere sphere); public void Contains(ref BoundingSphere sphere,out ContainmentType result); public void Contains(ref BoundingBox box, out ContainmentType result); public void Contains(ref Vector3 point, out ContainmentType result); a three-dimensional position public BoundingSphere(Vector3 center, float radius);
  25. 25. Collision Detection • Different sphere groups for varying levels of efficiency and accuracy
  26. 26. Collision Detection • Microsoft, Collision Detection, P: 290 - 304
  27. 27. Check it out in “App1-CollisionDetection- Micosoft”
  28. 28. Collision Detection Apress book, Chapter 13, Page 367
  29. 29. Collision Detection
  30. 30. Collision Detection • Also, because the default model processor doesn’t generate a bounding box (AABB) volume, we need to generate one for the model
  31. 31. Collision Detection • Avoid testing the collision with each mesh of the model, by creating a global bounding sphere (or global bounding Box) for the entire model!
  32. 32. Collision Detection • Usage of bounding spheres is emphasized because spheres are easier to update and transform than bounding boxes
  33. 33. EARLY WARNING SYSTEMS Don’t check a 200 miles sphere collision with you! Rbwhitaker web site: http://rbwhitaker.wikidot.com/collision-detection
  34. 34. Collision Detection • Approximation
  35. 35. Collision Detection • Approximation
  36. 36. Collision Detection • Approximation
  37. 37. Collision Detection • Approximation When to use What?
  38. 38. Collision Detection • Approximation A better way to combine both approaches
  39. 39. Collision Detection hierarchical modeling
  40. 40. Collision Detection
  41. 41. Collision Detection
  42. 42. Collision Detection
  43. 43. Collision Detection In hierarchical model you would use both the large sphere, and the small spheres.
  44. 44. Collision Detection Quad Tree Approach
  45. 45. Collision Detection Example in XNA private bool IsCollision(Model model1, Matrix world1, Model model2, Matrix world2) { for (int meshIndex1 = 0; meshIndex1 < model1.Meshes.Count; meshIndex1++) { BoundingSphere sphere1 = model1.Meshes[meshIndex1].BoundingSphere; sphere1 = sphere1.Transform(world1); for (int meshIndex2 = 0; meshIndex2 < model2.Meshes.Count; meshIndex2++) { BoundingSphere sphere2 = model2.Meshes[meshIndex2].BoundingSphere; sphere2 = sphere2.Transform(world2); if (sphere1.Intersects(sphere2)) return true; } } return false; }
  46. 46. Collision Detection Example in XNA “App2-CollisionDetection-WebSite”
  47. 47. XNA With Windows Form App/ WPF App For more info, go to: http://www.codeproject.com/KB/game/XNA_And_Beyond.aspx
  48. 48. XNA With Windows Form App • 2 WAYS! – 2D Graphics (Professional) – Windows Forms (Ordinary)
  49. 49. XNA With Windows Form App • 2 WAYS! – 2D Graphics (Professional) • See the appendix for full tutorial pdf – Windows Forms (Ordinary)
  50. 50. XNA With Windows Form App • 2 WAYS! – 2D Graphics (Professional) • See the appendix for full tutorial pdf – Windows Forms (Ordinary) • Use the appended project directly
  51. 51. XNA With Windows Form App • 2 WAYS! – 2D Graphics (Professional) • See the appendix for full tutorial pdf – Windows Forms (Ordinary) • Use the appended project directly • OR, do it your self as the following slides
  52. 52. XNA With Windows Form App • Windows Forms! (See the template project in appendix)
  53. 53. XNA With Windows Form App • Steps – Add new Form in the same XNA Project (“Form1”); – Add Panel to the form you have just created (“Form1”); – Add to the top of “Form1” public IntPtr PanelHandle { get { return this.panel1.IsHandleCreated? this.panel1.Handle : IntPtr.Zero; } }
  54. 54. XNA With Windows Form App • Now, In Game1 class do the following – Add the following at the top (using, renaming namespace) – Create a reference to Form1 to handle the instance at runtime;using SysWinForms = System.Windows.Forms; Form1 myForm;
  55. 55. XNA With Windows Form App • Now, In Game1 class do the following – Add the following two methods – Create a reference to Form1 to handle the instance at runtime; – Initialize void myForm_HandleDestroyed(object sender, EventArgs e) { this.Exit(); } void gameWindowForm_Shown(object sender, EventArgs e) { ((SysWinForms.Form)sender).Hide(); }
  56. 56. XNA With Windows Form App • Now, In Game1 class do the following – Add the following code to Initialize() method – Create a reference to Form1 to handle the instance at runtime; – Initialize protected override void Initialize() { SysWinForms.Form gameWindowForm = (SysWinForms.Form)SysWinForms.Form.FromHandle(this.Window.Handle); gameWindowForm.Shown += new EventHandler(gameWindowForm_Shown); this.myForm = new Form1(); myForm.HandleDestroyed += new EventHandler(myForm_HandleDestroyed); myForm.Show(); base.Initialize(); }
  57. 57. XNA With Windows Form App • Now, In Game1 class do the following – Add the following code to Draw() method so it looks like this protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); base.Draw(gameTime); // This one will do the trick we are looking for! this.GraphicsDevice.Present(null, null, myForm.PanelHandle); }
  58. 58. XNA With Windows Form App • Now, ctrl+F5 and u r good to go!
  59. 59. 2D and 3D Combined
  60. 60. 2D and 3D Combined
  61. 61. 2D and 3D Combined
  62. 62. 2D and 3D Combined
  63. 63. 2D and 3D Combined
  64. 64. 2D and 3D Combined
  65. 65. 2D and 3D Combined Begin Method (SpriteSortMode, BlendState, SamplerState, DepthStencilState, RasterizerState, Effect, Matrix) Begin Method () Begin Method (SpriteSortMode, BlendState) Begin Method (SpriteSortMode, BlendState, SamplerState, DepthStencilState, RasterizerState) Begin Method (SpriteSortMode, BlendState, SamplerState, DepthStencilState, RasterizerState, Effect) sortMode Sprite drawing order. blendState Blending options. samplerState Texture sampling options. depthStencilState Depth and stencil options. rasterizerState Rasterization options. effect Effect state options. transformMatrix Transformation matrix for scale, rotate, translate options.
  66. 66. 2D and 3D Combined • SpriteSortMode
  67. 67. 2D and 3D Combined • BlendState • See more: http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.blend.aspx
  68. 68. 2D and 3D Combined • BlendState
  69. 69. 2D and 3D Combined • BlendState
  70. 70. 2D and 3D Combined • BlendState
  71. 71. 2D and 3D Combined spriteBatch.Begin(); spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque); • finally! change SpriteBatch From • To
  72. 72. 2D and 3D Combined spriteBatch.Begin(); spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque); • finally! change SpriteBatch From • To
  73. 73. 2D and 3D Combined spriteBatch.Begin(); spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend); • finally! change SpriteBatch From • To
  74. 74. 2D and 3D Combined spriteBatch.Begin(); spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend); • finally! change SpriteBatch From • To
  75. 75. Viewports & Split Screen Games
  76. 76. Viewports & Split Screen Games • Base Project • “App1-Viewports”
  77. 77. Viewports & Split Screen Games • Viewports
  78. 78. Viewports & Split Screen Games • Viewports – Multiple ones So, What’s the idea is all about?!
  79. 79. Viewports & Split Screen Games • Viewports – Multiple ones Multiple “Camera”s
  80. 80. Viewports & Split Screen Games • Viewports – Multiple ones Multiple “LookAt()”s
  81. 81. Viewports & Split Screen Games • Global Scope private Matrix topView = Matrix.CreateLookAt(new Vector3(0, 0, 4), new Vector3(0, 0, 0), new Vector3(0, 0.001f, 1f)); private Matrix frontView = Matrix.CreateLookAt(new Vector3(0, 4, 0), new Vector3(0, 0, 0), Vector3.UnitZ); private Matrix sideView = Matrix.CreateLookAt(new Vector3(4, 0, 0), new Vector3(0, 0, 0), Vector3.UnitZ); private Matrix perspectiveView = Matrix.CreateLookAt(new Vector3(4, 4, 4), new Vector3(0, 0, 0), Vector3.UnitZ); private Viewport topViewport; private Viewport sideViewport; private Viewport frontViewport; private Viewport perspectiveViewport;
  82. 82. private Matrix topView = Matrix.CreateLookAt(new Vector3(0, 0, 4), new Vector3(0, 0, 0), new Vector3(0, 0.001f, 1f)); private Matrix frontView = Matrix.CreateLookAt(new Vector3(0, 4, 0), new Vector3(0, 0, 0), Vector3.UnitZ); private Matrix sideView = Matrix.CreateLookAt(new Vector3(4, 0, 0), new Vector3(0, 0, 0), Vector3.UnitZ); private Matrix perspectiveView = Matrix.CreateLookAt(new Vector3(4, 4, 4), new Vector3(0, 0, 0), Vector3.UnitZ); private Viewport topViewport; private Viewport sideViewport; private Viewport frontViewport; private Viewport perspectiveViewport; Matrix.CreateLookAt(CameraPosition, CameraTarget, CameraUp); Viewports & Split Screen Games
  83. 83. LookAt()
  84. 84. • Initialize() protected override void Initialize() { base.Initialize(); int ViewportWidth = 200; int ViewportHeight = 200; Viewport defaultViewport = GraphicsDevice.Viewport; topViewport = defaultViewport; topViewport.X = 0; topViewport.Y = 0; topViewport.Width = ViewportWidth; topViewport.Height = ViewportHeight; topViewport.MinDepth = 0; topViewport.MaxDepth = 1; sideViewport = defaultViewport; sideViewport.X = ViewportWidth; sideViewport.Y = 0; sideViewport.Width = ViewportWidth; sideViewport.Height = ViewportHeight; sideViewport.MinDepth = 0; sideViewport.MaxDepth = 1; frontViewport = defaultViewport; frontViewport.X = 0; frontViewport.Y = ViewportHeight; frontViewport.Width = ViewportWidth; frontViewport.Height = ViewportHeight; frontViewport.MinDepth = 0; frontViewport.MaxDepth = 1; perspectiveViewport = defaultViewport; perspectiveViewport.X = ViewportWidth; perspectiveViewport.Y = ViewportHeight; perspectiveViewport.Width = ViewportWidth; perspectiveViewport.Height = ViewportHeight; perspectiveViewport.MinDepth = 0; perspectiveViewport.MaxDepth = 1; } Viewports & Split Screen Games
  85. 85. Viewports & Split Screen Games • Initialize() protected override void Initialize() { base.Initialize(); int ViewportWidth = 200; int ViewportHeight = 200; Viewport defaultViewport = GraphicsDevice.Viewport; topViewport = defaultViewport; topViewport.X = 0; topViewport.Y = 0; topViewport.Width = ViewportWidth; topViewport.Height = ViewportHeight; topViewport.MinDepth = 0; topViewport.MaxDepth = 1; sideViewport = defaultViewport; sideViewport.X = ViewportWidth; sideViewport.Y = 0; sideViewport.Width = ViewportWidth; sideViewport.Height = ViewportHeight; sideViewport.MinDepth = 0; sideViewport.MaxDepth = 1; frontViewport = defaultViewport; frontViewport.X = 0; frontViewport.Y = ViewportHeight; frontViewport.Width = ViewportWidth; frontViewport.Height = ViewportHeight; frontViewport.MinDepth = 0; frontViewport.MaxDepth = 1; perspectiveViewport = defaultViewport; perspectiveViewport.X = ViewportWidth; perspectiveViewport.Y = ViewportHeight; perspectiveViewport.Width = ViewportWidth; perspectiveViewport.Height = ViewportHeight; perspectiveViewport.MinDepth = 0; perspectiveViewport.MaxDepth = 1; }
  86. 86. • Initialize() protected override void Initialize() { base.Initialize(); int ViewportWidth = 200; int ViewportHeight = 200; Viewport defaultViewport = GraphicsDevice.Viewport; topViewport = defaultViewport; topViewport.X = 0; topViewport.Y = 0; topViewport.Width = ViewportWidth; topViewport.Height = ViewportHeight; topViewport.MinDepth = 0; topViewport.MaxDepth = 1; sideViewport = defaultViewport; sideViewport.X = ViewportWidth; sideViewport.Y = 0; sideViewport.Width = ViewportWidth; sideViewport.Height = ViewportHeight; sideViewport.MinDepth = 0; sideViewport.MaxDepth = 1; frontViewport = defaultViewport; frontViewport.X = 0; frontViewport.Y = ViewportHeight; frontViewport.Width = ViewportWidth; frontViewport.Height = ViewportHeight; frontViewport.MinDepth = 0; frontViewport.MaxDepth = 1; perspectiveViewport = defaultViewport; perspectiveViewport.X = ViewportWidth; perspectiveViewport.Y = ViewportHeight; perspectiveViewport.Width = ViewportWidth; perspectiveViewport.Height = ViewportHeight; perspectiveViewport.MinDepth = 0; perspectiveViewport.MaxDepth = 1; } Viewports & Split Screen Games
  87. 87. • Initialize() protected override void Initialize() { base.Initialize(); int ViewportWidth = 200; int ViewportHeight = 200; Viewport defaultViewport = GraphicsDevice.Viewport; topViewport = defaultViewport; topViewport.X = 0; topViewport.Y = 0; topViewport.Width = ViewportWidth; topViewport.Height = ViewportHeight; topViewport.MinDepth = 0; topViewport.MaxDepth = 1; sideViewport = defaultViewport; sideViewport.X = ViewportWidth; sideViewport.Y = 0; sideViewport.Width = ViewportWidth; sideViewport.Height = ViewportHeight; sideViewport.MinDepth = 0; sideViewport.MaxDepth = 1; frontViewport = defaultViewport; frontViewport.X = 0; frontViewport.Y = ViewportHeight; frontViewport.Width = ViewportWidth; frontViewport.Height = ViewportHeight; frontViewport.MinDepth = 0; frontViewport.MaxDepth = 1; perspectiveViewport = defaultViewport; perspectiveViewport.X = ViewportWidth; perspectiveViewport.Y = ViewportHeight; perspectiveViewport.Width = ViewportWidth; perspectiveViewport.Height = ViewportHeight; perspectiveViewport.MinDepth = 0; perspectiveViewport.MaxDepth = 1; } Viewports & Split Screen Games
  88. 88. Viewports & Split Screen Games
  89. 89. Viewports & Split Screen Games
  90. 90. Viewports & Split Screen Games
  91. 91. Viewports & Split Screen Games
  92. 92. Viewports & Split Screen Games
  93. 93. Viewports & Split Screen Games
  94. 94. Viewports & Split Screen Games • Draw()protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); Viewport original = graphics.GraphicsDevice.Viewport; graphics.GraphicsDevice.Viewport = topViewport; //GraphicsDevice.Clear(Color.Black); DrawModel(model, world, topView, projection); graphics.GraphicsDevice.Viewport = sideViewport; //GraphicsDevice.Clear(Color.Black); DrawModel(model, world, sideView, projection); graphics.GraphicsDevice.Viewport = frontViewport; //GraphicsDevice.Clear(Color.Black); DrawModel(model, world, frontView, projection); graphics.GraphicsDevice.Viewport = perspectiveViewport; //GraphicsDevice.Clear(Color.Black); DrawModel(model, world, perspectiveView, projection); GraphicsDevice.Viewport = original; base.Draw(gameTime); }
  95. 95. Viewports & Split Screen Games • Draw()protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); Viewport original = graphics.GraphicsDevice.Viewport; graphics.GraphicsDevice.Viewport = topViewport; //GraphicsDevice.Clear(Color.Black); DrawModel(model, world, topView, projection); graphics.GraphicsDevice.Viewport = sideViewport; //GraphicsDevice.Clear(Color.Black); DrawModel(model, world, sideView, projection); graphics.GraphicsDevice.Viewport = frontViewport; //GraphicsDevice.Clear(Color.Black); DrawModel(model, world, frontView, projection); graphics.GraphicsDevice.Viewport = perspectiveViewport; //GraphicsDevice.Clear(Color.Black); DrawModel(model, world, perspectiveView, projection); GraphicsDevice.Viewport = original; base.Draw(gameTime); }
  96. 96. Viewports & Split Screen Games • Draw()protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); Viewport original = graphics.GraphicsDevice.Viewport; graphics.GraphicsDevice.Viewport = topViewport; //GraphicsDevice.Clear(Color.Black); DrawModel(model, world, topView, projection); graphics.GraphicsDevice.Viewport = sideViewport; //GraphicsDevice.Clear(Color.Black); DrawModel(model, world, sideView, projection); graphics.GraphicsDevice.Viewport = frontViewport; //GraphicsDevice.Clear(Color.Black); DrawModel(model, world, frontView, projection); graphics.GraphicsDevice.Viewport = perspectiveViewport; //GraphicsDevice.Clear(Color.Black); DrawModel(model, world, perspectiveView, projection); GraphicsDevice.Viewport = original; base.Draw(gameTime); }
  97. 97. Viewports & Split Screen Games • Draw()protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); Viewport original = graphics.GraphicsDevice.Viewport; graphics.GraphicsDevice.Viewport = topViewport; //GraphicsDevice.Clear(Color.Black); DrawModel(model, world, topView, projection); graphics.GraphicsDevice.Viewport = sideViewport; //GraphicsDevice.Clear(Color.Black); DrawModel(model, world, sideView, projection); graphics.GraphicsDevice.Viewport = frontViewport; //GraphicsDevice.Clear(Color.Black); DrawModel(model, world, frontView, projection); graphics.GraphicsDevice.Viewport = perspectiveViewport; //GraphicsDevice.Clear(Color.Black); DrawModel(model, world, perspectiveView, projection); GraphicsDevice.Viewport = original; base.Draw(gameTime); }
  98. 98. Viewports & Split Screen Games • Draw()protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); Viewport original = graphics.GraphicsDevice.Viewport; graphics.GraphicsDevice.Viewport = topViewport; //GraphicsDevice.Clear(Color.Black); DrawModel(model, world, topView, projection); graphics.GraphicsDevice.Viewport = sideViewport; //GraphicsDevice.Clear(Color.Black); DrawModel(model, world, sideView, projection); graphics.GraphicsDevice.Viewport = frontViewport; //GraphicsDevice.Clear(Color.Black); DrawModel(model, world, frontView, projection); graphics.GraphicsDevice.Viewport = perspectiveViewport; //GraphicsDevice.Clear(Color.Black); DrawModel(model, world, perspectiveView, projection); GraphicsDevice.Viewport = original; base.Draw(gameTime); }
  99. 99. Viewports & Split Screen Games • “App2-ViewportsFinished”
  100. 100. Picking Objects
  101. 101. Picking Objects • How to pick?!
  102. 102. Picking Objects • How to pick?!
  103. 103. Picking Objects public Ray CalculateRay(Vector2 mouseLocation, Matrix view, Matrix projection, Viewport viewport) { Vector3 nearPoint = viewport.Unproject( new Vector3(mouseLocation.X, mouseLocation.Y, 0.0f), projection, view, Matrix.Identity); Vector3 farPoint = viewport.Unproject( new Vector3(mouseLocation.X, mouseLocation.Y, 1.0f), projection, view, Matrix.Identity); Vector3 direction = farPoint - nearPoint; direction.Normalize(); return new Ray(nearPoint, direction); }
  104. 104. Picking Objects public bool Intersects(Vector2 mouseLocation, Model model, Matrix world, Matrix view, Matrix projection, Viewport viewport) { for (int index = 0; index < model.Meshes.Count; index++) { BoundingSphere sphere = model.Meshes[index].BoundingSphere; sphere = sphere.Transform(world); float? distance = IntersectDistance(sphere, mouseLocation, view, projection, viewport); if (distance != null) { return true; } } return false; }
  105. 105. Picking Objects public float? IntersectDistance(BoundingSphere sphere, Vector2 mouseLocation, Matrix view, Matrix projection, Viewport viewport) { Ray mouseRay = CalculateRay(mouseLocation, view, projection, viewport); return mouseRay.Intersects(sphere); }
  106. 106. Picking Objects • “App-Picking”
  107. 107. Take a Look on my other courses @ http://www.slideshare.net/ZGTRZGTR Available courses to the date of this slide:
  108. 108. http://www.mohammadshaker.com mohammadshakergtr@gmail.com https://twitter.com/ZGTRShaker @ZGTRShaker https://de.linkedin.com/pub/mohammad-shaker/30/122/128/ http://www.slideshare.net/ZGTRZGTR https://www.goodreads.com/user/show/11193121-mohammad-shaker https://plus.google.com/u/0/+MohammadShaker/ https://www.youtube.com/channel/UCvJUfadMoEaZNWdagdMyCRA http://mohammadshakergtr.wordpress.com/

×