[3] 球(Sphere)图形的生成算法


顶点数据的生成

 

 1 bool                        YfBuildSphereVertices
 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 - 2) + 2;
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             else if (i == stacks - 1)           // 最后一个顶点
58             {        
59                 nOffset = (numVertices - 1) * vertexStriding; 
60                 curVertexPtr = (YsVector3*)(vertexPtr + nOffset);
61                 curVertexPtr->x = 0.0f;
62                 curVertexPtr->y = -radius + originOffsetY;
63                 curVertexPtr->z = 0.0f;
64                 continue;
65             }
66 
67             Yreal angleY = YD_REAL_PI * i / (stacks - 1);
68             Yreal posY = radius * yf_cos(angleY);
69             Yreal radiusXZ = radius * yf_sin(angleY);
70             Yreal posX, posZ;
71 
72             for (Yuint j = 0; j < slices; j++)
73             {
74                 posX = radiusXZ * pSinList[j];
75                 posZ = radiusXZ * pCosList[j];
76                 nOffset = ((i - 1) * slices + j + 1) * vertexStriding; 
77                 curVertexPtr = (YsVector3*)(vertexPtr + nOffset);
78                 curVertexPtr->x = posX;
79                 curVertexPtr->y = posY + originOffsetY;
80                 curVertexPtr->z = posZ;
81             }
82         }
83     }
84 
85     YD_SAFE_DELETE_ARRAY(pSinList);
86     YD_SAFE_DELETE_ARRAY(pCosList);
87 
88     return true;
89 }     

 

三角形索引数据的生成

 

  1 bool                        YfBuildSphereTriIndices
  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 - 2) + 2;
 17     Yuint numTriangles = slices * (stacks - 2) * 2;
 18     if (indexType == YE_INDEX_16_BIT && 
 19         numVertices > YD_MAX_UNSIGNED_INT16)
 20     {
 21         return false;
 22     }
 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 if (i == stacks - 2)                   // 最后一层
 45             {
 46                 for (Yuint j = 0; j < slices; j++)
 47                 {
 48                     nOffset = (numTriangles - slices + j) * indexStriding;
 49                     triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset);
 50                     triIndexPtr->index0 = numVertices - 1;
 51                     triIndexPtr->index1 = numVertices - 1 - slices + (j + 1)%slices;
 52                     triIndexPtr->index2 = numVertices - 1 - slices + j;
 53                 }
 54             }
 55             else
 56             {
 57                 for (Yuint j = 0; j < slices; j++)
 58                 {
 59                     nOffset = ((i - 1)*slices * 2 + slices + j * 2) * indexStriding;
 60                     triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset);
 61                     triIndexPtr->index0 = 1 + slices * (i - 1) + j;
 62                     triIndexPtr->index1 = 1 + slices * i + j;
 63                     triIndexPtr->index2 = 1 + slices * (i - 1) + (j + 1)%slices;
 64 
 65                     nOffset += indexStriding;
 66                     triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset);
 67                     triIndexPtr->index0 = 1 + slices * (i - 1) + (j + 1)%slices;
 68                     triIndexPtr->index1 = 1 + slices * i + j;
 69                     triIndexPtr->index2 = 1 + slices * i + (j + 1)%slices;
 70                 }
 71             }
 72         }
 73     }
 74     else
 75     {
 76         YsTriIndex32* triIndexPtr = NULL;
 77 
 78         // 赋值
 79         for (Yuint i = 0; i < stacks - 1; i++)
 80         {
 81             if (i == 0)                                 // 第一层
 82             {
 83                 for (Yuint j = 0; j < slices; j++)
 84                 {
 85                     nOffset = j * indexStriding;
 86                     triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset);
 87                     triIndexPtr->index0 = 0;
 88                     triIndexPtr->index1 = 1 + j;
 89                     triIndexPtr->index2 = 1 + (j + 1)%slices;
 90                 }
 91             }
 92             else if (i == stacks - 2)                   // 最后一层
 93             {
 94                 for (Yuint j = 0; j < slices; j++)
 95                 {
 96                     nOffset = (numTriangles - slices + j) * indexStriding;
 97                     triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset);
 98                     triIndexPtr->index0 = numVertices - 1;
 99                     triIndexPtr->index1 = numVertices - 1 - slices + (j + 1)%slices;
100                     triIndexPtr->index2 = numVertices - 1 - slices + j;
101                 }
102             }
103             else
104             {
105                 for (Yuint j = 0; j < slices; j++)
106                 {
107                     nOffset = ((i - 1)*slices * 2 + slices + j * 2) * indexStriding;
108                     triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset);
109                     triIndexPtr->index0 = 1 + slices * (i - 1) + j;
110                     triIndexPtr->index1 = 1 + slices * i + j;
111                     triIndexPtr->index2 = 1 + slices * (i - 1) + (j + 1)%slices;
112 
113                     nOffset += indexStriding;
114                     triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset);
115                     triIndexPtr->index0 = 1 + slices * (i - 1) + (j + 1)%slices;
116                     triIndexPtr->index1 = 1 + slices * i + j;
117                     triIndexPtr->index2 = 1 + slices * i + (j + 1)%slices;
118                 }
119             }
120         }
121     }
122 
123     return true;
124 }  

 

线框索引数据的生成

  1 bool                        YfBuildSphereWireIndices
  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 - 2) + 2;
 17     if (indexType == YE_INDEX_16_BIT && 
 18         numVertices > YD_MAX_UNSIGNED_INT16)
 19     {
 20         return false;
 21     }
 22     Yuint numLines = slices * (stacks - 2) + slices * (stacks - 1);
 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 - 1; 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         //
 44         Yuint half = slices * (stacks - 2);
 45         for (Yuint i = 0; i < slices; i++)                 
 46         {
 47             for (Yuint j = 0; j < stacks - 1; j++)         
 48             {
 49                 nOffset = (half + (i*(stacks - 1) + j)) * indexStriding;
 50                 lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset);
 51                 if (j == 0)
 52                 {
 53                     lineIndexPtr->index0 = 0;
 54                 }
 55                 else
 56                 {
 57                     lineIndexPtr->index0 = 1 + (j - 1)*slices + i;
 58                 }
 59                 if (j == stacks - 2)
 60                 {
 61                     lineIndexPtr->index1 = numVertices - 1;
 62                 }
 63                 else
 64                 {
 65                     lineIndexPtr->index1 = 1 + j*slices + i;
 66                 }
 67             }
 68         }
 69     }
 70     else
 71     {
 72         YsLineIndex32* lineIndexPtr = NULL;
 73 
 74         //
 75         for (Yuint j = 1; j < stacks - 1; j++)                 
 76         {
 77             for (Yuint i = 0; i < slices; i++)         
 78             {
 79                 nOffset = ((j - 1)*slices + i) * indexStriding;
 80                 lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset);
 81                 lineIndexPtr->index0 = 1 + j*slices + i;
 82                 lineIndexPtr->index1 = 1 + j*slices + (i + 1)%slices;
 83             }
 84         }
 85 
 86         //
 87         Yuint half = slices * (stacks - 2);
 88         for (Yuint i = 0; i < slices; i++)                 
 89         {
 90             for (Yuint j = 0; j < stacks - 1; j++)         
 91             {
 92                 nOffset = (half + (i*(stacks - 1) + j)) * indexStriding;
 93                 lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset);
 94                 if (j == 0)
 95                 {
 96                     lineIndexPtr->index0 = 0;
 97                 }
 98                 else
 99                 {
100                     lineIndexPtr->index0 = 1 + (j - 1)*slices + i;
101                 }
102                 if (j == stacks - 2)
103                 {
104                     lineIndexPtr->index1 = numVertices - 1;
105                 }
106                 else
107                 {
108                     lineIndexPtr->index1 = 1 + j*slices + i;
109                 }
110             }
111         }
112     }
113 
114     return true;
115 }

 


 

posted on 2013-11-09 08:10  叶飞影  阅读(1837)  评论(0编辑  收藏  举报