This is the code to extract vertices:
Code: Select all
private List<Vector3> GetVerticesModel(float p_Scale)
{
List<Vector3> _points = new List<Vector3>();
foreach (ModelMesh modelMesh in m_XnaModel.Meshes)
{
foreach (ModelMeshPart part in modelMesh.MeshParts)
{
VertexPositionNormalTextureBinormalTangent[] _vertices = new VertexPositionNormalTextureBinormalTangent[part.VertexBuffer.VertexCount];
part.VertexBuffer.GetData<VertexPositionNormalTextureBinormalTangent>(_vertices);
foreach (VertexPositionNormalTextureBinormalTangent vertices in _vertices)
{
_points.Add(Vector3.Transform(vertices.Position, Matrix.CreateScale(p_Scale)));
}
}
}
return _points;
}
This is the definition of my custom vertex (VertexPositionNormalTextureBinormalTangent)
Code: Select all
public struct VertexPositionNormalTextureBinormalTangent : IVertexType
{
Vector3 vertexPosition;
Vector3 vertexNormal;
Vector2 vertexTextureCoordinate;
Vector3 vertexBinormal;
Vector3 vertexTangent;
public readonly static VertexDeclaration VertexDeclaration = new VertexDeclaration
(
new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
new VertexElement(12, VertexElementFormat.Vector3, VertexElementUsage.Normal, 0),
new VertexElement(24, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0),
new VertexElement(32, VertexElementFormat.Vector3, VertexElementUsage.Binormal, 0),
new VertexElement(44, VertexElementFormat.Vector3, VertexElementUsage.Tangent, 0)
);
public VertexPositionNormalTextureBinormalTangent(Vector3 pos, Vector3 normal, Vector2 textureCoordinate, Vector3 binormal, Vector3 tangent)
{
vertexPosition = pos;
vertexNormal = normal;
vertexTextureCoordinate = textureCoordinate;
vertexBinormal = binormal;
vertexTangent = tangent;
}
public Vector3 Position
{
get { return vertexPosition; }
set { vertexPosition = value; }
}
VertexDeclaration IVertexType.VertexDeclaration
{
get { return VertexDeclaration; }
}
}
And finally, my custom model processor. As you will see i create for each model the same vertex channel in output to match my custom vertex. If the model hasn't the vertex channel i need, i create it without any data. This isn't a good thing, but it's just an example to make you understand, you'll modify the code for computing all data you need, like binormal or tangent.
Code: Select all
[ContentProcessor(DisplayName = "CustomImporter.ModelImporter")]
public class ModelImporter : ModelProcessor
{
static IList<string> acceptableVertexChannelNames =
new string[]
{
VertexChannelNames.Normal(0),
VertexChannelNames.TextureCoordinate(0),
VertexChannelNames.Binormal(0),
VertexChannelNames.Tangent(0)
};
protected override void ProcessVertexChannel(GeometryContent geometry, int vertexChannelIndex, ContentProcessorContext context)
{
String vertexChannelName = geometry.Vertices.Channels[vertexChannelIndex].Name;
if (!geometry.Vertices.Channels.Contains(acceptableVertexChannelNames[0]))
{
Vector3[] _tc = new Vector3[geometry.Vertices.VertexCount];
geometry.Vertices.Channels.Add(acceptableVertexChannelNames[0], typeof(Vector3), _tc);
}
if (!geometry.Vertices.Channels.Contains(acceptableVertexChannelNames[1]))
{
Vector2[] _nr = new Vector2[geometry.Vertices.VertexCount];
geometry.Vertices.Channels.Add(acceptableVertexChannelNames[1], typeof(Vector2), _nr);
}
if (!geometry.Vertices.Channels.Contains(acceptableVertexChannelNames[2]))
{
Vector3[] _bn = new Vector3[geometry.Vertices.VertexCount];
geometry.Vertices.Channels.Add(acceptableVertexChannelNames[2], typeof(Vector3), _bn);
}
if (!geometry.Vertices.Channels.Contains(acceptableVertexChannelNames[3]))
{
Vector3[] _tn = new Vector3[geometry.Vertices.VertexCount];
geometry.Vertices.Channels.Add(acceptableVertexChannelNames[3], typeof(Vector3), _tn);
}
if (acceptableVertexChannelNames.Contains(vertexChannelName))
{
base.ProcessVertexChannel(geometry, vertexChannelIndex, context);
}
else
{
geometry.Vertices.Channels.Remove(vertexChannelName);
}
}
}
Hope this helps!
Fax3D