【问题标题】:Normal for surface of a cube in XNAXNA中立方体表面的法线
【发布时间】:2012-04-24 10:45:09
【问题描述】:

谁能帮忙。

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

或者,是否有一种自动方法来获取立方体的顶点,而无需手动输入每个顶点的所有值?我可能有几个模型要

任何帮助将不胜感激

【问题讨论】:

  • 顶点在三角形之间共享,所以你有 24 个,甚至更少。您有 36 个条目是三角形数组中的条目,每连续 3 个表示定义每个三角形的顶点的索引。

标签: xna cube normals vertices


【解决方案1】:

我不知道你为什么需要那个...因为当你加载一个模型时,它是计算出来的,在内部每个顶点都会有法线,...

反正很容易计算...

前三个索引定义人脸的第一个三角形,接下来的三个索引定义人脸的另一个三角形。

你只需要一个三角形来计算法线...

所以用三个索引访问veretex数组并得到三个点... A、B和C

现在您的法线是由该顶点形成的两个向量之间的叉积的结果。

 Vector3 Normal = Vector3.Cross(B-A, C-B);

如果正常后退或前进将取决于 A、B、C 顺序,可以是 CounterClockWise 或 ClockWise,但模型的每个三角形都将以一种方式排序。所以你会尝试并修复它

【讨论】:

    【解决方案2】:

    您可以编写一个 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;
        }
    

    【讨论】:

      猜你喜欢
      • 2016-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多