【问题标题】:How to correctly create the vertices for this type of wiresphere?如何为这种类型的线球正确创建顶点?
【发布时间】:2020-08-03 18:44:46
【问题描述】:

我目前正在尝试创建一个如下所示的线球:

我想出了如下代码:

using SharpDX;
using SharpDX.Direct3D11;
using System;
using System.Collections.Generic;

namespace VoidwalkerEngine.Framework.DirectX.Rendering
{
    public static class Wireframe
    {
        public static ModelMesh GenerateWireframeSphere(Device device, Vector3 location, float radius)
        {
            float pi = (float)Math.PI;
            List<Vertex> vertices = new List<Vertex>();
            float twoPi = 2 * pi;
            float angleStep = twoPi / 16f;
            for (float angle = 0f; angle <= twoPi; angle += angleStep)
            {
                float x = radius * (float)Math.Sin(angle);
                float y = radius * (float)Math.Cos(angle);
                float z = 0;
                vertices.Add(new Vertex(location.X + x, location.Y + y, location.Z + z));
            }
            for (float angle = 0f; angle <= twoPi; angle += angleStep)
            {
                float x = radius * (float)Math.Sin(angle);
                float y = 0;
                float z = radius * (float)Math.Cos(angle);
                vertices.Add(new Vertex(location.X + x, location.Y + y, location.Z + z));
            }
            for (float angle = 0f; angle <= twoPi; angle += angleStep)
            {
                float x = 0;
                float y = radius * (float)Math.Sin(angle);
                float z = radius * (float)Math.Cos(angle);
                vertices.Add(new Vertex(location.X + x, location.Y + y, location.Z + z));
            }
            ModelMesh mesh = new ModelMesh(device, vertices.ToArray());
            return mesh;
        }
    }
}

这会产生一个看起来像这样的球体(使用 LineStrip):

如您所见,圆圈并不完整,不仅如此,还有一条额外的线将顶部环连接到中间环。我觉得这实际上是使用 LineStrip 的副作用。如果我改用 LineList,我的代码会导致:

好多了,但我缺少部分。 LineList 显然是要走的路,但我不知道如何正确更新我的代码以添加那些缺失的线段。有谁知道怎么做?

【问题讨论】:

  • 我发现我做错了什么。我目前正在完全重写。一旦我完成它,我会在这里上传它作为答案。我有一个大笨蛋。
  • 虽然不适用于C#,但这里的逻辑与DebugDraw中的球体相同。
  • @ChuckWalbourn 嘿,感谢您发表评论。我遇到的问题是,出于某种原因,我忘记了需要将每个顶点链接到它之前的顶点。基本上,我需要在每个循环的零索引之后的每个顶点之后注入一个重复的顶点。这样就解决了问题。我还需要在每个循环结束时“咬尾巴”;基本上有最后一个索引循环回到 0 索引。一会儿我会在这里放一个编码示例。

标签: c# geometry rendering directx-11


【解决方案1】:

我能够弄清楚这一点。答案是我相当愚蠢。我忘记了我需要将顶点链接在一起,以及环回并“咬住”每个环的尾巴。这是解决方案:

using SharpDX;
using SharpDX.Direct3D11;
using System;

namespace VoidwalkerEngine.Framework.DirectX.Rendering
{
    public static class Wireframe
    {
        public static ModelMesh GenerateWireframeSphere(Device device, Vector3 location, float radius)
        {
            float pi = (float)Math.PI;
            Vertex[] vertices = new Vertex[96];
            float twoPi = 2 * pi;
            float angleStep = twoPi / 16f;
            int iterator = 0;
            /**
             * 1st Ring
             */
            int firstIndex = 0;
            for (float angle = 0f; angle <= twoPi; angle += angleStep)
            {
                if (iterator > firstIndex + 1)
                {
                    vertices[iterator] = vertices[iterator++ - 1];
                }
                float x = radius * (float)Math.Sin(angle);
                float y = radius * (float)Math.Cos(angle);
                float z = 0;
                vertices[iterator++] = new Vertex(location.X + x, location.Y + y, location.Z + z);
            }
            vertices[iterator] = vertices[iterator++ - 1];
            vertices[iterator++] = vertices[firstIndex];
            /**
             * 2nd Ring
             */
            firstIndex = iterator;
            for (float angle = 0f; angle <= twoPi; angle += angleStep)
            {
                if (iterator > firstIndex + 1)
                {
                    vertices[iterator] = vertices[iterator++ - 1];
                }
                float x = radius * (float)Math.Sin(angle);
                float y = 0;
                float z = radius * (float)Math.Cos(angle);
                vertices[iterator++] = new Vertex(location.X + x, location.Y + y, location.Z + z);
            }
            vertices[iterator] = vertices[iterator++ - 1];
            vertices[iterator++] = vertices[firstIndex];
            /**
             * 3rd Ring
             */
            firstIndex = iterator;
            for (float angle = 0f; angle <= twoPi; angle += angleStep)
            {
                if (iterator > firstIndex + 1)
                {
                    vertices[iterator] = vertices[iterator++ - 1];
                }
                float x = 0;
                float y = radius * (float)Math.Sin(angle);
                float z = radius * (float)Math.Cos(angle);
                vertices[iterator++] = new Vertex(location.X + x, location.Y + y, location.Z + z);
            }
            vertices[iterator] = vertices[iterator++ - 1];
            vertices[iterator++] = vertices[firstIndex];
            return new ModelMesh(device, vertices);
        }
    }
}

还有一张显示结果的图片:

需要注意的是,这个球体的分辨率是静态的,因为在上面的示例中,我没有根据尺寸计算动态分辨率。这样做还需要调整数组的大小。因此,如果您最终使用它,请注意限制,切换到列表而不是数组,或者完成添加动态分辨率所需的少量工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-31
    • 2012-02-23
    • 1970-01-01
    相关资源
    最近更新 更多