任何人都可以帮忙。
我有一个我在3DS Max中制作的立方体。我不知道立方体的尺寸。有没有办法获得立方体面的每个三角形的顶点?我试图获得立方体的一个面的法线,以确定它指向哪个方向。因此,如果我可以确定顶点我可以得到面的法线,如果我有3个顶点,V1,V2和V3,按逆时针顺序排序,我可以通过计算得到正常方向(V2 - V1)x(V3 - V1),其中x是两个向量的叉积。
我查看了我的模型.fbx文件,我可以在那里看到许多值: 顶点:* 24 { a:-15,-12.5,0,15,-12.5,0,-15,12.5,0,15,12.5,0,-15,-12.5,0.5,15,-12.5,0.5,-15 ,12.5,0.5,15,12.5,0.5}
PolygonVertexIndex:* 36 { a:0,2,-4,3,1,-1,4,5,-8,7,6,-5,0,1,-6,5,4,-1,1,3,-8 ,7,5,-2,3,2,-7,6,7,-4,2,0,-5,4,6,-3}
这些是我的模型顶点吗? 另外,我假设 Vertices: * 24 将是我的顶点列表,但为什么只有24?一个立方体不应该有36个顶点吗?最后,如果我的顶点的坐标是 PolygonVertexIndex: * 36 ,当我想到这个尺寸在我脑海中的立方体时,这些值对我来说似乎不对吗?
或者,是否有一种自动获取立方体顶点的方法,而无需手动输入每个顶点的所有值?
我可能有几个模特非常感谢任何帮助
答案 0 :(得分:1)
我无法理解为什么你需要那个......因为当你加载一个模型时,它会被计算出来,内部每个顶点都会有正常的,......
无论如何,很容易计算...
三个第一个索引定义一个面的第一个三角形,接下来的三个,另一个面的三角形。
您只需要一个三角形来计算正常...
因此,使用三个索引访问veretex数组并得到三个点... A,B和C
现在,您的法线是由该顶点形成的两个向量之间的叉积的结果。
Vector3 Normal = Vector3.Cross(B-A, C-B);
如果正常返回或前进将取决于A,B,C顺序,可以是CounterClockWise或ClockWise,但模型的每个三角形都将以一种方式排序。所以你将尝试并修复它
答案 1 :(得分:0)
你可以写一个XNA程序,它可以毫不费力地读取你的法线。
但是,如果您仍想计算它们,请使用从FFWD获取的此C#代码作为指南。检查URL以获得有关优缺点的更详细讨论。就个人而言,我对结果并不满意,但暂时还是有效的。当然,由于这段代码与FFWD相关(Unity的XNA API实现),它与XNA完全不匹配,但数学保持不变。
/// <summary>
/// Recalculates the normals.
/// Implementation adapted from http://devmaster.net/forums/topic/1065-calculating-normals-of-a-mesh/
/// </summary>
public void RecalculateNormals()
{
Vector3[] newNormals = new Vector3[_vertices.Length];
// _triangles is a list of vertex indices,
// with each triplet referencing the three vertices of the corresponding triangle
for (int i = 0; i < _triangles.Length; i = i + 3)
{
Vector3[] v = new Vector3[]
{
_vertices[_triangles[i]],
_vertices[_triangles[i + 1]],
_vertices[_triangles[i + 2]]
};
Vector3 normal = Vector3.Cross(v[1] - v[0], v[2] - v[0]);
for (int j = 0; j < 3; ++j)
{
Vector3 a = v[(j+1) % 3] - v[j];
Vector3 b = v[(j+2) % 3] - v[j];
float weight = (float)Math.Acos(Vector3.Dot(a, b) / (a.magnitude * b.magnitude));
newNormals[_triangles[i + j]] += weight * normal;
}
}
foreach (Vector3 normal in newNormals)
{
normal.Normalize();
}
normals = newNormals;
}