#region File Description
//-----------------------------------------------------------------------------
// TrianglePickingProcessor.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion
#region Using Statements
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
using Microsoft.Xna.Framework.Content.Pipeline.Processors;
#endregion
namespace WindowsGame1
{
///
/// Custom content pipeline processor attaches vertex position information to
/// a model, which can be used at runtime to implement per-triangle picking.
/// It derives from the built-in ModelProcessor, and overrides the Process
/// method, using this to attach custom data to the model Tag property.
///
[ContentProcessor(DisplayName="PickerProcessor")]
public class TrianglePickingProcessor : ModelProcessor
{
List vertices = new List();
///
/// The main method in charge of processing the content.
///
public override ModelContent Process(NodeContent input,
ContentProcessorContext context)
{
// Look up the input vertex positions.
FindVertices(input);
// Chain to the base ModelProcessor class.
ModelContent model = base.Process(input, context);
// You can store any type of object in the model Tag property. This
// sample only uses built-in types such as string, Vector3, BoundingSphere,
// dictionaries, and arrays, which the content pipeline knows how to
// serialize by default. We could also attach custom data types here, but
// then we would have to provide a ContentTypeWriter and ContentTypeReader
// implementation to tell the pipeline how to serialize our custom type.
//
// We are setting our model Tag to a dictionary that maps strings to
// objects, and then storing two different kinds of custom data into that
// dictionary. This is a useful pattern because it allows processors to
// combine many different kinds of information inside the single Tag value.
Dictionary tagData = new Dictionary();
model.Tag = tagData;
// Store vertex information in the tag data, as an array of Vector3.
tagData.Add("Vertices", vertices.ToArray());
// Also store a custom bounding sphere.
tagData.Add("BoundingSphere", BoundingSphere.CreateFromPoints(vertices));
return model;
}
///
/// Helper for extracting a list of all the vertex positions in a model.
///
void FindVertices(NodeContent node)
{
// Is this node a mesh?
MeshContent mesh = node as MeshContent;
if (mesh != null)
{
// Look up the absolute transform of the mesh.
Matrix absoluteTransform = mesh.AbsoluteTransform;
// Loop over all the pieces of geometry in the mesh.
foreach (GeometryContent geometry in mesh.Geometry)
{
// Loop over all the indices in this piece of geometry.
// Every group of three indices represents one triangle.
foreach (int index in geometry.Indices)
{
// Look up the position of this vertex.
Vector3 vertex = geometry.Vertices.Positions[index];
// Transform from local into world space.
// -- We do not want to do this, because when we do comparisons on our mouse array, we transform it
// -- into local model space.
//vertex = Vector3.Transform(vertex, absoluteTransform);
// Store this vertex.
vertices.Add(vertex);
}
}
}
// Recursively scan over the children of this node.
foreach (NodeContent child in node.Children)
{
FindVertices(child);
}
}
}
}