PageRenderTime 16ms CodeModel.GetById 3ms RepoModel.GetById 0ms app.codeStats 0ms

/XNALib/XNAUtils.cs

#
C# | 210 lines | 171 code | 38 blank | 1 comment | 6 complexity | e8f5286ac86b261133614b6fb8b41bfe MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using Microsoft.Xna.Framework;
  5. using Microsoft.Xna.Framework.Audio;
  6. using Microsoft.Xna.Framework.Content;
  7. using Microsoft.Xna.Framework.Graphics;
  8. using Microsoft.Xna.Framework.Input;
  9. using Microsoft.Xna.Framework.Storage;
  10. namespace XNALib
  11. {
  12. public static class XNAUtils
  13. {
  14. public static BoundingBox TransformBoundingBox(BoundingBox origBox, Matrix matrix)
  15. {
  16. Vector3 origCorner1 = origBox.Min;
  17. Vector3 origCorner2 = origBox.Max;
  18. Vector3 transCorner1 = Vector3.Transform(origCorner1, matrix);
  19. Vector3 transCorner2 = Vector3.Transform(origCorner2, matrix);
  20. return new BoundingBox(transCorner1, transCorner2);
  21. }
  22. public static BoundingSphere TransformBoundingSphere(BoundingSphere originalBoundingSphere, Matrix transformationMatrix)
  23. {
  24. Vector3 trans;
  25. Vector3 scaling;
  26. Quaternion rot;
  27. transformationMatrix.Decompose(out scaling, out rot, out trans);
  28. float maxScale = scaling.X;
  29. if (maxScale < scaling.Y)
  30. maxScale = scaling.Y;
  31. if (maxScale < scaling.Z)
  32. maxScale = scaling.Z;
  33. float transformedSphereRadius = originalBoundingSphere.Radius * maxScale;
  34. Vector3 transformedSphereCenter = Vector3.Transform(originalBoundingSphere.Center, transformationMatrix);
  35. BoundingSphere transformedBoundingSphere = new BoundingSphere(transformedSphereCenter, transformedSphereRadius);
  36. return transformedBoundingSphere;
  37. }
  38. public static Model LoadModelWithBoundingSphere(out Matrix[] modelTransforms, string asset, ContentManager content)
  39. {
  40. Model newModel = content.Load<Model>(asset);
  41. modelTransforms = new Matrix[newModel.Bones.Count];
  42. newModel.CopyAbsoluteBoneTransformsTo(modelTransforms);
  43. BoundingSphere completeBoundingSphere = new BoundingSphere();
  44. foreach (ModelMesh mesh in newModel.Meshes)
  45. {
  46. BoundingSphere origMeshSphere = mesh.BoundingSphere;
  47. BoundingSphere transMeshSphere = XNAUtils.TransformBoundingSphere(origMeshSphere, modelTransforms[mesh.ParentBone.Index]);
  48. completeBoundingSphere = BoundingSphere.CreateMerged(completeBoundingSphere, transMeshSphere);
  49. }
  50. newModel.Tag = completeBoundingSphere;
  51. return newModel;
  52. }
  53. public static Matrix[] AutoScale(Model model, float requestedSize)
  54. {
  55. BoundingSphere bSphere = (BoundingSphere)model.Tag;
  56. float originalSize = bSphere.Radius * 2;
  57. float scalingFactor = requestedSize / originalSize;
  58. model.Root.Transform = model.Root.Transform * Matrix.CreateScale(scalingFactor);
  59. Matrix[] modelTransforms = new Matrix[model.Bones.Count];
  60. model.CopyAbsoluteBoneTransformsTo(modelTransforms);
  61. return modelTransforms;
  62. }
  63. public static void DrawBoundingBox(BoundingBox bBox, GraphicsDevice device, BasicEffect basicEffect, Matrix worldMatrix, Matrix viewMatrix, Matrix projectionMatrix)
  64. {
  65. Vector3 v1 = bBox.Min;
  66. Vector3 v2 = bBox.Max;
  67. VertexPositionColor[] cubeLineVertices = new VertexPositionColor[8];
  68. cubeLineVertices[0] = new VertexPositionColor(v1, Color.White);
  69. cubeLineVertices[1] = new VertexPositionColor(new Vector3(v2.X, v1.Y, v1.Z), Color.Red);
  70. cubeLineVertices[2] = new VertexPositionColor(new Vector3(v2.X, v1.Y, v2.Z), Color.Green);
  71. cubeLineVertices[3] = new VertexPositionColor(new Vector3(v1.X, v1.Y, v2.Z), Color.Blue);
  72. cubeLineVertices[4] = new VertexPositionColor(new Vector3(v1.X, v2.Y, v1.Z), Color.White);
  73. cubeLineVertices[5] = new VertexPositionColor(new Vector3(v2.X, v2.Y, v1.Z), Color.Red);
  74. cubeLineVertices[6] = new VertexPositionColor(v2, Color.Green);
  75. cubeLineVertices[7] = new VertexPositionColor(new Vector3(v1.X, v2.Y, v2.Z), Color.Blue);
  76. short[] cubeLineIndices = { 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 };
  77. basicEffect.World = worldMatrix;
  78. basicEffect.View = viewMatrix;
  79. basicEffect.Projection = projectionMatrix;
  80. basicEffect.VertexColorEnabled = true;
  81. device.RenderState.FillMode = FillMode.Solid;
  82. basicEffect.Begin();
  83. foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
  84. {
  85. pass.Begin();
  86. device.VertexDeclaration = new VertexDeclaration(device, VertexPositionColor.VertexElements);
  87. device.DrawUserIndexedPrimitives<VertexPositionColor>(PrimitiveType.LineList, cubeLineVertices, 0, 8, cubeLineIndices, 0, 12);
  88. pass.End();
  89. }
  90. basicEffect.End();
  91. }
  92. public static void DrawSphereSpikes(BoundingSphere sphere, GraphicsDevice device, BasicEffect basicEffect, Matrix worldMatrix, Matrix viewMatrix, Matrix projectionMatrix)
  93. {
  94. Vector3 up = sphere.Center + sphere.Radius * Vector3.Up;
  95. Vector3 down = sphere.Center + sphere.Radius * Vector3.Down;
  96. Vector3 right = sphere.Center + sphere.Radius * Vector3.Right;
  97. Vector3 left = sphere.Center + sphere.Radius * Vector3.Left;
  98. Vector3 forward = sphere.Center + sphere.Radius * Vector3.Forward;
  99. Vector3 back = sphere.Center + sphere.Radius * Vector3.Backward;
  100. VertexPositionColor[] sphereLineVertices = new VertexPositionColor[6];
  101. sphereLineVertices[0] = new VertexPositionColor(up, Color.White);
  102. sphereLineVertices[1] = new VertexPositionColor(down, Color.White);
  103. sphereLineVertices[2] = new VertexPositionColor(left, Color.White);
  104. sphereLineVertices[3] = new VertexPositionColor(right, Color.White);
  105. sphereLineVertices[4] = new VertexPositionColor(forward, Color.White);
  106. sphereLineVertices[5] = new VertexPositionColor(back, Color.White);
  107. basicEffect.World = worldMatrix;
  108. basicEffect.View = viewMatrix;
  109. basicEffect.Projection = projectionMatrix;
  110. basicEffect.VertexColorEnabled = true;
  111. basicEffect.Begin();
  112. foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
  113. {
  114. pass.Begin();
  115. device.VertexDeclaration = new VertexDeclaration(device, VertexPositionColor.VertexElements);
  116. device.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.LineList, sphereLineVertices, 0, 3);
  117. pass.End();
  118. }
  119. basicEffect.End();
  120. }
  121. public static VertexPositionColor[] VerticesFromVector3List(List<Vector3> pointList, Color color)
  122. {
  123. VertexPositionColor[] vertices = new VertexPositionColor[pointList.Count];
  124. int i = 0;
  125. foreach (Vector3 p in pointList)
  126. vertices[i++] = new VertexPositionColor(p, color);
  127. return vertices;
  128. }
  129. public static BoundingBox CreateBoxFromSphere(BoundingSphere sphere)
  130. {
  131. float radius = sphere.Radius * (float)Math.Sqrt(2.0) / 2.0f;
  132. Vector3 outerPoint = new Vector3(radius, radius, radius);
  133. Vector3 p1 = sphere.Center - outerPoint;
  134. Vector3 p2 = sphere.Center + outerPoint;
  135. return new BoundingBox(p1, p2);
  136. }
  137. public static T[] Reshape2Dto1D<T>(T[,] array2D)
  138. {
  139. int width = array2D.GetLength(0);
  140. int height = array2D.GetLength(1);
  141. T[] array1D = new T[width * height];
  142. int i = 0;
  143. for (int z = 0; z < height; z++)
  144. for (int x = 0; x < width; x++)
  145. array1D[i++] = array2D[x, z];
  146. return array1D;
  147. }
  148. public static T[,] Reshape1Dto2D<T>(T[] vertices, int width, int height)
  149. {
  150. T[,] vertexArray = new T[width, height];
  151. int i = 0;
  152. for (int h = 0; h < height; h++)
  153. for (int w = 0; w < width; w++)
  154. vertexArray[w, h] = vertices[i++];
  155. return vertexArray;
  156. }
  157. public static Ray CreateRayFrom2D(GraphicsDevice graphicsDevice, Vector2 point, Matrix projection, Matrix view, Matrix world)
  158. {
  159. Vector3 rayNear = graphicsDevice.Viewport.Unproject(
  160. new Vector3(point.X, point.Y, 0f),
  161. projection, view, Matrix.Identity);
  162. Vector3 rayFar = graphicsDevice.Viewport.Unproject(
  163. new Vector3(point.X, point.Y, 1f),
  164. projection, view, world);
  165. Vector3 direction = rayFar - rayNear;
  166. direction.Normalize();
  167. //Debug.WriteLine(string.Format("start:{0}, direction:{1}", rayNear, direction));
  168. Ray ray = new Ray(rayNear, direction);
  169. return ray;
  170. }
  171. }
  172. }