XNA中立方体表面的法线

时间:2012-04-24 10:45:09

标签: xna cube normals vertices

任何人都可以帮忙。

我有一个我在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 ,当我想到这个尺寸在我脑海中的立方体时,这些值对我来说似乎不对吗?

或者,是否有一种自动获取立方体顶点的方法,而无需手动输入每个顶点的所有值?

我可能有几个模特

非常感谢任何帮助

2 个答案:

答案 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;
    }