[13] 弧面(Arc)图形的生成算法


顶点数据的生成

 1 bool                        YfBuildArcVertices
 2 (
 3     Yreal                   radius, 
 4     Yreal                   degree, 
 5     Yreal                   height, 
 6     Yuint                   slices,
 7     Yuint                   stacks, 
 8     YeOriginPose            originPose,
 9     Yuint                   vertexStriding, 
10     Yuint                   vertexPos,
11     void*                   pVerticesBuffer
12 )
13 {
14     if (degree < 0 || degree > 180 || !pVerticesBuffer)
15     {
16         return false;
17     }
18     if (slices < 2 || stacks < 3 || !pVerticesBuffer)
19     {
20         return false;
21     }
22 
23     Yuint numVertices  = slices * (stacks - 1) + 1;
24 
25     char* vertexPtr = (char*)pVerticesBuffer + vertexPos;
26     YsVector3* curVertexPtr = NULL;
27     Yuint nOffset = 0;
28 
29     Yreal originOffsetY = 0.0f;
30     if (originPose == YE_ORIGIN_POSE_TOP)
31     {
32         originOffsetY = -radius;
33     }
34     else if (originPose == YE_ORIGIN_POSE_BOTTOM)
35     {
36         originOffsetY = radius;
37     }
38 
39     Yreal* pSinList = YD_NEW_ARRAY(Yreal, slices);
40     Yreal* pCosList = YD_NEW_ARRAY(Yreal, slices);
41     Yreal angleXZ;
42     for (Yuint j = 0; j < slices; j++)
43     {
44         angleXZ = YD_REAL_TWAIN_PI * j / slices;
45         pSinList[j] = yf_sin(angleXZ);
46         pCosList[j] = yf_cos(angleXZ);
47     }
48 
49     // 赋值
50     {
51         Yreal radian = YD_DEGREE_TO_RADIAN(degree);
52         for (Yuint i = 0; i < stacks; i++)
53         {
54             if (i == 0)                         // 第一个顶点
55             {
56                 nOffset = 0;            
57                 curVertexPtr = (YsVector3*)(vertexPtr + nOffset);
58                 curVertexPtr->x = 0.0f;
59                 curVertexPtr->y = radius + originOffsetY;
60                 curVertexPtr->z = 0.0f;
61                 continue;
62             }
63 
64             Yreal angleY = radian * i / (stacks - 1);
65             Yreal posY = radius * yf_cos(angleY);
66             Yreal radiusXZ = radius * yf_sin(angleY);
67             Yreal posX, posZ;
68 
69             for (Yuint j = 0; j < slices; j++)
70             {
71                 posX = radiusXZ * pSinList[j % slices];
72                 posZ = radiusXZ * pCosList[j % slices];
73 
74                 nOffset = (1 + (i - 1) * slices + j) * vertexStriding; 
75                 curVertexPtr = (YsVector3*)(vertexPtr + nOffset);
76                 curVertexPtr->x = posX;
77                 curVertexPtr->y = posY + originOffsetY;
78                 curVertexPtr->z = posZ;
79             }
80         }
81     }
82 
83     YD_SAFE_DELETE_ARRAY(pSinList);
84     YD_SAFE_DELETE_ARRAY(pCosList);
85 
86     return true;
87 }

三角形索引数据的生成

  1 bool                        YfBuildArcTriIndices
  2 (
  3     Yuint                   slices,
  4     Yuint                   stacks,
  5     YeIndexType             indexType,
  6     Yuint                   indexStriding, 
  7     Yuint                   indexPos,
  8     void*                   pTriIndicesBuffer
  9 )
 10 {
 11     if (slices < 2 || stacks < 3 || !pTriIndicesBuffer)
 12     {
 13         return false;
 14     }
 15 
 16     Yuint numVertices  = slices * (stacks - 1) + 1;
 17     Yuint numTriangles = slices * (stacks - 2) * 2 + slices;
 18 
 19     if (indexType == YE_INDEX_16_BIT && 
 20         numVertices > YD_MAX_UNSIGNED_INT16)
 21     {
 22         return false;
 23     }
 24 
 25     // 索引赋值
 26     char* indexPtr = (char*)pTriIndicesBuffer + indexPos;
 27     Yuint nOffset = 0;
 28     if (indexType == YE_INDEX_16_BIT)
 29     {
 30         YsTriIndex16* triIndexPtr = NULL;
 31 
 32         // 赋值
 33         for (Yuint i = 0; i < stacks - 1; i++)
 34         {
 35             if (i == 0)                                 // 第一层
 36             {
 37                 for (Yuint j = 0; j < slices; j++)
 38                 {
 39                     nOffset = j * indexStriding;
 40                     triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset);
 41                     triIndexPtr->index0 = 0;
 42                     triIndexPtr->index1 = 1 + j;
 43                     triIndexPtr->index2 = 1 + (j + 1)%slices;
 44                 }
 45             }
 46             else
 47             {
 48                 for (Yuint j = 0; j < slices; j++)
 49                 {
 50                     nOffset = ((i - 1)*slices * 2 + slices + j * 2) * indexStriding;
 51                     triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset);
 52                     triIndexPtr->index0 = 1 + slices * (i - 1) + j;
 53                     triIndexPtr->index1 = 1 + slices * i + j;
 54                     triIndexPtr->index2 = 1 + slices * (i - 1) + (j + 1)%slices;
 55 
 56                     nOffset += indexStriding;
 57                     triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset);
 58                     triIndexPtr->index0 = 1 + slices * (i - 1) + (j + 1)%slices;
 59                     triIndexPtr->index1 = 1 + slices * i + j;
 60                     triIndexPtr->index2 = 1 + slices * i + (j + 1)%slices;
 61                 }
 62             }
 63         }
 64     }
 65     else
 66     {
 67         YsTriIndex32* triIndexPtr = NULL;
 68 
 69         // 赋值
 70         for (Yuint i = 0; i < stacks - 1; i++)
 71         {
 72             if (i == 0)                                 // 第一层
 73             {
 74                 for (Yuint j = 0; j < slices; j++)
 75                 {
 76                     nOffset = j * indexStriding;
 77                     triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset);
 78                     triIndexPtr->index0 = 0;
 79                     triIndexPtr->index1 = 1 + j;
 80                     triIndexPtr->index2 = 1 + (j + 1)%slices;
 81                 }
 82             }
 83             else
 84             {
 85                 for (Yuint j = 0; j < slices; j++)
 86                 {
 87                     nOffset = ((i - 1)*slices * 2 + slices + j * 2) * indexStriding;
 88                     triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset);
 89                     triIndexPtr->index0 = 1 + slices * (i - 1) + j;
 90                     triIndexPtr->index1 = 1 + slices * i + j;
 91                     triIndexPtr->index2 = 1 + slices * (i - 1) + (j + 1)%slices;
 92 
 93                     nOffset += indexStriding;
 94                     triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset);
 95                     triIndexPtr->index0 = 1 + slices * (i - 1) + (j + 1)%slices;
 96                     triIndexPtr->index1 = 1 + slices * i + j;
 97                     triIndexPtr->index2 = 1 + slices * i + (j + 1)%slices;
 98                 }
 99             }
100         }
101     }
102 
103     return true;
104 }  

线框索引数据的生成

bool                        YfBuildArcWireIndices
(
    Yuint                   slices,
    Yuint                   stacks,
    YeIndexType             indexType,
    Yuint                   indexStriding,  
    Yuint                   indexPos,
    void*                   pWireIndicesBuffer
)
{
    if (slices < 2 || !pWireIndicesBuffer)
    {
        return false;
    }

    Yuint numVertices = slices * (stacks - 1) + 1;
    Yuint numLines    = slices * (stacks - 1) + slices * (stacks - 1);
    if (indexType == YE_INDEX_16_BIT && 
        numVertices > YD_MAX_UNSIGNED_INT16)
   {
        return false;
    }

    // 索引赋值
    char* indexPtr = (char*)pWireIndicesBuffer + indexPos;
    Yuint nOffset = 0;
    if (indexType == YE_INDEX_16_BIT)
    {
        YsLineIndex16* lineIndexPtr = NULL;

        //
        for (Yuint j = 1; j < stacks; j++)
        {
            for (Yuint i = 0; i < slices; i++)
            {
                nOffset = ((j - 1)*slices + i) * indexStriding;
                lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset);
                lineIndexPtr->index0 = 1 + (j - 1)*slices + i;
                lineIndexPtr->index1 = 1 + (j - 1)*slices + (i + 1)%slices;
            }
        }

        //
        Yuint half = slices * (stacks - 1);
        for (Yuint i = 0; i < slices; i++)
        {
            nOffset = (half + i) * indexStriding;
            lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset);
            lineIndexPtr->index0 = 0;
            lineIndexPtr->index1 = 1 + i;
        }
        half += slices;

        for (Yuint j = 1; j < stacks - 1; j++)
        {
            for (Yuint i = 0; i < slices; i++)
            {
                nOffset = (half + (j - 1)*slices + i) * indexStriding;
                lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset);
                lineIndexPtr->index0 = 1 + (j - 1)*slices + i;
                lineIndexPtr->index1 = 1 + j*slices + i;
            }
        }

        //// 列
        //Yuint half = slices * (stacks - 1);
        //for (Yuint i = 0; i < slices; i++)                 
        //{
        //    for (Yuint j = 0; j < stacks - 2; j++)         
        //    {
        //        nOffset = (half + (i*(stacks - 1) + j)) * indexStriding;
        //        lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset);
        //        if (j == 0)
        //        {
        //            lineIndexPtr->index0 = 0;
        //        }
        //        else
        //        {
        //            lineIndexPtr->index0 = 1 + (j - 1)*slices + i;
        //        }

        //        lineIndexPtr->index1 = 1 + j*slices + i;
        //    }
        //}
    }
    else
    {
        YsLineIndex32* lineIndexPtr = NULL;

        //
        for (Yuint j = 1; j < stacks; j++)                 
       {
            for (Yuint i = 0; i < slices; i++)         
            {
                nOffset = ((j - 1)*slices + i) * indexStriding;
                lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset);
                lineIndexPtr->index0 = 1 + (j - 1)*slices + i;
                lineIndexPtr->index1 = 1 + (j - 1)*slices + (i + 1)%slices;
            }
        }

        //
        Yuint half = slices * (stacks - 1);
        for (Yuint i = 0; i < slices; i++)
        {
            nOffset = (half + i) * indexStriding;
            lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset);
            lineIndexPtr->index0 = 0;
            lineIndexPtr->index1 = 1 + i;
        }
        half += slices;

        for (Yuint j = 1; j < stacks - 1; j++)
        {
            for (Yuint i = 0; i < slices; i++)
            {
                nOffset = (half + (j - 1)*slices + i) * indexStriding;
                lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset);
                lineIndexPtr->index0 = 1 + (j - 1)*slices + i;
                lineIndexPtr->index1 = 1 + j*slices + i;
            }
        }

        ////Yuint half = slices * (stacks - 1);
        //for (Yuint i = 0; i < slices; i++)                 
        //{
        //    for (Yuint j = 0; j < stacks - 2; j++)         
        //    {
        //        nOffset = (half + (i*(stacks - 1) + j)) * indexStriding;
        //        lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset);
        //        if (j == 0)
        //        {
        //            lineIndexPtr->index0 = 0;
        //        }
        //        else
        //        {
        //            lineIndexPtr->index0 = 1 + (j - 1)*slices + i;
        //        }

        //        lineIndexPtr->index1 = 1 + j*slices + i;
        //    }
        //}
    }

    return true;
}


 

原文地址:https://www.cnblogs.com/WhyEngine/p/3415254.html