[19] 半球形(Hemisphere)图形的生成算法


顶点数据的生成

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

三角形索引数据的生成

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

线框索引数据的生成

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


 

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