TrianglePickingProcessor.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // TrianglePickingProcessor.cs
  4. //
  5. // Microsoft XNA Community Game Platform
  6. // Copyright (C) Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #endregion
  9. #region Using Statements
  10. using System.Collections.Generic;
  11. using Microsoft.Xna.Framework;
  12. using Microsoft.Xna.Framework.Content.Pipeline;
  13. using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
  14. using Microsoft.Xna.Framework.Content.Pipeline.Processors;
  15. #endregion
  16. namespace TrianglePickingPipeline
  17. {
  18. /// <summary>
  19. /// Custom content pipeline processor attaches vertex position information to
  20. /// a model, which can be used at runtime to implement per-triangle picking.
  21. /// It derives from the built-in ModelProcessor, and overrides the Process
  22. /// method, using this to attach custom data to the model Tag property.
  23. /// </summary>
  24. [ContentProcessor]
  25. public class TrianglePickingProcessor : ModelProcessor
  26. {
  27. List<Vector3> vertices = new List<Vector3>();
  28. /// <summary>
  29. /// The main method in charge of processing the content.
  30. /// </summary>
  31. public override ModelContent Process(NodeContent input,
  32. ContentProcessorContext context)
  33. {
  34. // Chain to the base ModelProcessor class.
  35. ModelContent model = base.Process(input, context);
  36. // Look up the input vertex positions.
  37. FindVertices(input);
  38. // You can store any type of object in the model Tag property. This
  39. // sample only uses built-in types such as string, Vector3, BoundingSphere,
  40. // dictionaries, and arrays, which the content pipeline knows how to
  41. // serialize by default. We could also attach custom data types here, but
  42. // then we would have to provide a ContentTypeWriter and ContentTypeReader
  43. // implementation to tell the pipeline how to serialize our custom type.
  44. //
  45. // We are setting our model Tag to a dictionary that maps strings to
  46. // objects, and then storing two different kinds of custom data into that
  47. // dictionary. This is a useful pattern because it allows processors to
  48. // combine many different kinds of information inside the single Tag value.
  49. Dictionary<string, object> tagData = new Dictionary<string, object>();
  50. model.Tag = tagData;
  51. // Store vertex information in the tag data, as an array of Vector3.
  52. tagData.Add("Vertices", vertices.ToArray());
  53. // Also store a custom bounding sphere.
  54. tagData.Add("BoundingSphere", BoundingSphere.CreateFromPoints(vertices));
  55. return model;
  56. }
  57. /// <summary>
  58. /// Helper for extracting a list of all the vertex positions in a model.
  59. /// </summary>
  60. void FindVertices(NodeContent node)
  61. {
  62. // Is this node a mesh?
  63. MeshContent mesh = node as MeshContent;
  64. if (mesh != null)
  65. {
  66. // Look up the absolute transform of the mesh.
  67. Matrix absoluteTransform = mesh.AbsoluteTransform;
  68. // Loop over all the pieces of geometry in the mesh.
  69. foreach (GeometryContent geometry in mesh.Geometry)
  70. {
  71. // Loop over all the indices in this piece of geometry.
  72. // Every group of three indices represents one triangle.
  73. foreach (int index in geometry.Indices)
  74. {
  75. // Look up the position of this vertex.
  76. Vector3 vertex = geometry.Vertices.Positions[index];
  77. // Transform from local into world space.
  78. vertex = Vector3.Transform(vertex, absoluteTransform);
  79. // Store this vertex.
  80. vertices.Add(vertex);
  81. }
  82. }
  83. }
  84. // Recursively scan over the children of this node.
  85. foreach (NodeContent child in node.Children)
  86. {
  87. FindVertices(child);
  88. }
  89. }
  90. }
  91. }