我试图使用C#和XNA 4.0遍历FBX模型的顶点。我认为如果我可以访问顶点,那么我将能够自己访问其他部分,例如面法线,边缘,PolygonVertexIndex
等。
我发现Jon Watte的一篇文章讨论了如何使用XNA 3.0做到这一点, Extracting Vertices and Triangles from an XNA Model 但他使用的3.0结构似乎并不存在于4.0中。
特别是,他访问这样的顶点:
Vector3[] a = new Vector3[myModelMeshPart.NumVertices];
myModelMesh.VertexBuffer.GetData<Vector3>(myModelMeshPart.StreamOffset + myModelMeshPart.BaseVertex * myModelMeshPart.VertexStride,
a, 0, myModelMeshPart.NumVertices, myModelMeshPart.VertexStride);
但在XNA 4中,VertexBuffer
似乎不是MeshModel
的属性。
有人可以指导我对Model
个顶点的基本迭代吗?
谢谢。
@ user2340634感谢您的回复 我的尝试使用了远远低于实际的顶点数 我想我不知道如何使用VertexBuffer。你能否对这段代码发表评论?
private void getVerts(Model mdl)
{
foreach (ModelMesh mm in mdl.Meshes)
{
foreach (ModelMeshPart mp in mm.MeshParts)
{
VertexBuffer vb = mp.VertexBuffer;
short[] s = new short[mp.PrimitiveCount * 3];
IndexBuffer ib = mp.IndexBuffer;
ib.GetData<short>(mp.StartIndex * 2, s, 0, mp.PrimitiveCount * 3);
Vector3[] v = new Vector3[4];
VertexPositionNormalTexture[] vert = new VertexPositionNormalTexture[4];
mp.VertexBuffer.GetData<VertexPositionNormalTexture>(vert, 0, mp.NumVertices);
for (int i = 0; i < v.Length; i++)
{
v[i] = vert[i].Position;
trace("(" + v[i].X.ToString() + ", " + v[i].Y.ToString() + ", " + v[i].Z.ToString() + ")");
}
}
}
}
你有一个可以迭代到顶点的工作样本吗?
答案 0 :(得分:2)
“模型”没有“VertexBuffer”。 “ModelMesh”也没有“VertexBuffer”。但是,我发现“ModelMeshPart”确实有“VertexBuffer”。我也是第一次从.fbx中提取数据。我们在项目中包含的任何模型都必须存储在ModelMeshPart中。那不是那么糟糕。 .fbx中的整个网格可以被视为一个部分。
答案 1 :(得分:0)
modModel = Content.Load<Model>("Cube1");
foreach (ModelMesh modmModel in modModel.Meshes)
{
foreach (ModelMeshPart mmpModel in modmModel.MeshParts)
{
modelExtractor = new ModelExtractor(mmpModel, new Vector3[mmpModel.NumVertices * 2], new VertexPositionColor[mmpModel.NumVertices]);
modelExtractor.ExtractVertices();
}
}
for (int a = 0; a < modelExtractor.ArrVectors.Length; a++)
{
Console.WriteLine(modelExtractor.ArrVectors[a]);
}
vertexBuffer = new VertexBuffer(GraphicsDevice, typeof(VertexPositionColor), modelExtractor.VpcVertices.Length, BufferUsage.None);
vertexBuffer.SetData(modelExtractor.VpcVertices);
这是来自主类。这就是我将Model转换为ModelMeshPart的方法。在从.fbx中提取数据之前,我没有创建顶点缓冲区。 for循环(及其内部的代码行)通过将提取的顶点数据写入控制台窗口来为其提供列表。
private ModelMeshPart mmpModel;
private Vector3[] arrVectors;
private VertexPositionColor[] vpcVertices;
这些是我的ModelExtractor类的字段。它们通过以下方法使用。
public void ExtractVertices()
{
this.mmpModel.VertexBuffer.GetData<Vector3>(this.arrVectors);
for (int a = 0; a < vpcVertices.Length; a += 2)
{
this.vpcVertices[a].Position.X = arrVectors[a].X;
this.vpcVertices[a].Position.Y = arrVectors[a].Y;
this.vpcVertices[a].Position.Z = arrVectors[a].Z;
}
}
我提取了“Vector3”类型的数据。 .fbx中的每个顶点都有一个用于posistion的Vector3和另一个用于法线的顶点。只有这样我才能将组件中的位置组件从Vector3s数组移动到VertexPositionColors数组。请注意,for循环将“a”增加2而不是1.这样我就可以跳过法线的Vector3s。
答案 2 :(得分:0)
这是我的解决方案(如果模型有几个部分,你必须循环使用它们)
public static void ModelData(Model model)
{
ModelMeshPart part = model.Meshes[0].MeshParts[0];
VertexPositionNormalTexture[] vertices = new VertexPositionNormalTexture[part.VertexBuffer.VertexCount];
part.VertexBuffer.GetData<VertexPositionNormalTexture>(vertices);
ushort[] drawOrder = new ushort[part.IndexBuffer.IndexCount];
part.IndexBuffer.GetData<ushort>(drawOrder);
}