[6] 胶囊体(Capsule)图形的生成算法

 

顶点数据的生成

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

 

三角形索引数据的生成

 

  1 bool                        YfBuildCapsuleTriIndices
  2 (
  3     Yuint                   slices,
  4     Yuint                   stacks, 
  5     YeIndexType             indexType,
  6     Yuint                   indexStriding,  
  7     Yuint                   indexPos, 
  8     void*                   pTriIndicesBuffer
  9 )
 10 {
 11     Yuint halfStacks = stacks / 2;
 12     if (slices < 2 || halfStacks < 2 || !pTriIndicesBuffer)
 13     {
 14         return false;
 15     }
 16 
 17     Yuint numVertices  = slices * (halfStacks - 1) * 2 + 2;
 18     if (indexType == YE_INDEX_16_BIT && 
 19         numVertices > YD_MAX_UNSIGNED_INT16)
 20     {
 21         return false;
 22     }
 23     Yuint numHalfVertices = numVertices / 2;
 24     Yuint numTriangles    = slices * (halfStacks - 1) * 4;
 25 
 26     // 索引赋值
 27     char* indexPtr = (char*)pTriIndicesBuffer + indexPos;
 28     Yuint nOffset = 0;
 29     if (indexType == YE_INDEX_16_BIT)
 30     {
 31         YsTriIndex16* triIndexPtr = NULL;
 32 
 33         for (Yuint i = 0; i < halfStacks - 1; i++)
 34         {
 35             if (i == 0)                                 // 第一层
 36             {
 37                 for (Yuint j = 0; j < slices; j++)
 38                 {
 39                     nOffset = j * 2 * indexStriding;
 40                     triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset);
 41                     triIndexPtr->index0 = 0;
 42                     triIndexPtr->index1 = 1 + j;
 43                     triIndexPtr->index2 = 1 + (j + 1)%slices;
 44 
 45                     nOffset += indexStriding;
 46                     triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset);
 47                     triIndexPtr->index0 = numHalfVertices;
 48                     triIndexPtr->index1 = numHalfVertices + 1 + (j + 1)%slices;
 49                     triIndexPtr->index2 = numHalfVertices + 1 + j;
 50                 }
 51             }
 52             else
 53             {
 54                 for (Yuint j = 0; j < slices; j++)
 55                 {
 56                     nOffset = ((i - 1)*slices*4 + slices*2 + j*4) * indexStriding;
 57                     triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset);
 58                     triIndexPtr->index0 = 1 + slices * (i - 1) + j;
 59                     triIndexPtr->index1 = 1 + slices * i + j;
 60                     triIndexPtr->index2 = 1 + slices * (i - 1) + (j + 1)%slices;
 61 
 62                     nOffset += indexStriding;
 63                     triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset);
 64                     triIndexPtr->index0 = 1 + slices * (i - 1) + (j + 1)%slices;
 65                     triIndexPtr->index1 = 1 + slices * i + j;
 66                     triIndexPtr->index2 = 1 + slices * i + (j + 1)%slices;
 67 
 68                     nOffset += indexStriding;
 69                     triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset);
 70                     triIndexPtr->index0 = numHalfVertices + 1 + slices * (i - 1) + j;
 71                     triIndexPtr->index1 = numHalfVertices + 1 + slices * (i - 1) + (j + 1)%slices;
 72                     triIndexPtr->index2 = numHalfVertices + 1 + slices * i + (j + 1)%slices;
 73 
 74                     nOffset += indexStriding;
 75                     triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset);
 76                     triIndexPtr->index0 = numHalfVertices + 1 + slices * (i - 1) + j;
 77                     triIndexPtr->index1 = numHalfVertices + 1 + slices * i + (j + 1)%slices;
 78                     triIndexPtr->index2 = numHalfVertices + 1 + slices * i + j;
 79                 }
 80             }
 81         }
 82 
 83         // 连接两个半球
 84         for (Yuint j = 0; j < slices; j++)
 85         {
 86             nOffset = ((halfStacks - 2)*slices*4 + slices*2 + j*2) * indexStriding;
 87             triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset);
 88             triIndexPtr->index0 = 1 + slices  * (halfStacks - 2) + j;
 89             triIndexPtr->index1 = numHalfVertices + 1 + slices * (halfStacks - 2) + j;
 90             triIndexPtr->index2 = 1 + slices * (halfStacks - 2) + (j + 1)%slices;
 91 
 92             nOffset += indexStriding;
 93             triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset);
 94             triIndexPtr->index0 = 1 + slices * (halfStacks - 2) + (j + 1)%slices;
 95             triIndexPtr->index1 = numHalfVertices + 1 + slices * (halfStacks - 2) + j;
 96             triIndexPtr->index2 = numHalfVertices + 1 + slices * (halfStacks - 2) + (j + 1)%slices;
 97         }
 98     }
 99     else
100     {
101         YsTriIndex32* triIndexPtr = NULL;
102 
103         for (Yuint i = 0; i < halfStacks - 1; i++)
104         {
105             if (i == 0)                                 // 第一层
106             {
107                 for (Yuint j = 0; j < slices; j++)
108                 {
109                     nOffset = j * 2 * indexStriding;
110                     triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset);
111                     triIndexPtr->index0 = 0;
112                     triIndexPtr->index1 = 1 + j;
113                     triIndexPtr->index2 = 1 + (j + 1)%slices;
114 
115                     nOffset += indexStriding;
116                     triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset);
117                     triIndexPtr->index0 = numHalfVertices;
118                     triIndexPtr->index1 = numHalfVertices + 1 + (j + 1)%slices;
119                     triIndexPtr->index2 = numHalfVertices + (j + 1)%slices;
120                 }
121             }
122             else
123             {
124                 for (Yuint j = 0; j < slices; j++)
125                 {
126                     nOffset = ((i - 1)*slices*4 + slices*2 + j*4) * indexStriding;
127                     triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset);
128                     triIndexPtr->index0 = 1 + slices * (i - 1) + j;
129                     triIndexPtr->index1 = 1 + slices * i + j;
130                     triIndexPtr->index2 = 1 + slices * (i - 1) + (j + 1)%slices;
131 
132                     nOffset += indexStriding;
133                     triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset);
134                     triIndexPtr->index0 = 1 + slices * (i - 1) + (j + 1)%slices;
135                     triIndexPtr->index1 = 1 + slices * i + j;
136                     triIndexPtr->index2 = 1 + slices * i + j + 1;
137 
138                     nOffset += indexStriding;
139                     triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset);
140                     triIndexPtr->index0 = numHalfVertices + 1 + slices * (i - 1) + j;
141                     triIndexPtr->index1 = numHalfVertices + 1 + slices * (i - 1) + (j + 1)%slices;
142                     triIndexPtr->index2 = numHalfVertices + 1 + slices * i + (j + 1)%slices;
143 
144                     nOffset += indexStriding;
145                     triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset);
146                     triIndexPtr->index0 = numHalfVertices + 1 + slices * (i - 1) + j;
147                     triIndexPtr->index1 = numHalfVertices + 1 + slices * i + (j + 1)%slices;
148                     triIndexPtr->index2 = numHalfVertices + 1 + slices * i + j;
149                 }
150             }
151         }
152 
153         // 连接两个半球
154         for (Yuint j = 0; j < slices; j++)
155         {
156             nOffset = ((halfStacks - 2)*slices*4 + slices*2 + j*2) * indexStriding;
157             triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset);
158             triIndexPtr->index0 = 1 + slices  * (halfStacks - 2) + j;
159             triIndexPtr->index1 = numHalfVertices + 1 + slices * (halfStacks - 2) + j;
160             triIndexPtr->index2 = 1 + slices * (halfStacks - 2) + (j + 1)%slices;
161 
162             nOffset += indexStriding;
163             triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset);
164             triIndexPtr->index0 = 1 + slices * (halfStacks - 2) + (j + 1)%slices;
165             triIndexPtr->index1 = numHalfVertices + 1 + slices * (halfStacks - 2) + j;
166             triIndexPtr->index2 = numHalfVertices + 1 + slices * (halfStacks - 2) + (j + 1)%slices;
167         }
168     }
169 
170     return true;
171 }     

 

线框索引数据的生成

  1 bool                        YfBuildCapsuleWireIndices
  2 (
  3     Yuint                   slices,
  4     Yuint                   stacks, 
  5     YeIndexType             indexType,
  6     Yuint                   indexStriding,  
  7     Yuint                   indexPos, 
  8     void*                   pWireIndicesBuffer
  9 )
 10 {
 11     Yuint halfStacks = stacks / 2;
 12     if (slices < 2 || halfStacks < 2 || !pWireIndicesBuffer)
 13     {
 14         return false;
 15     }
 16 
 17     Yuint numVertices  = slices * (halfStacks - 1) * 2 + 2;
 18     Yuint numLines     = slices * (halfStacks - 1) * 2 + slices * (2 * halfStacks - 1);
 19     Yuint numHalfVertices = numVertices / 2;
 20     if (indexType == YE_INDEX_16_BIT && 
 21         numVertices > YD_MAX_UNSIGNED_INT16)
 22     {
 23         return false;
 24     }
 25 
 26     // 索引赋值
 27     char* indexPtr = (char*)pWireIndicesBuffer + indexPos;
 28     Yuint nOffset = 0;
 29     if (indexType == YE_INDEX_16_BIT)
 30     {
 31         YsLineIndex16* lineIndexPtr = NULL;
 32         for (Yuint i = 1; i < halfStacks; i++)
 33         {
 34             for (Yuint j = 0; j < slices; j++)
 35             {
 36                 nOffset = ((i - 1)*slices + j) * 2 * indexStriding;
 37                 lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset);
 38                 lineIndexPtr->index0 = 1 + (i - 1)*slices + j;
 39                 lineIndexPtr->index1 = 1 + (i - 1)*slices + (j + 1)%slices;
 40 
 41                 nOffset += indexStriding;
 42                 lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset);
 43                 lineIndexPtr->index0 = numHalfVertices + 1 + (i - 1)*slices + j;
 44                 lineIndexPtr->index1 = numHalfVertices + 1 + (i - 1)*slices + (j + 1)%slices;
 45             }
 46         }
 47 
 48         Yuint half = (halfStacks - 1) * slices *2;
 49         for (Yuint j = 0; j < slices; j++)
 50         {
 51             for (Yuint i = 0; i < halfStacks - 1; i++)
 52             {
 53                 if (i == 0)
 54                 {
 55                     nOffset = (half + (halfStacks*2 - 1) * j) * indexStriding;
 56                     lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset);
 57                     lineIndexPtr->index0 = 0;
 58                     lineIndexPtr->index1 = 1 + j;
 59 
 60                     nOffset += indexStriding;
 61                     lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset);
 62                     lineIndexPtr->index0 = numHalfVertices;
 63                     lineIndexPtr->index1 = numHalfVertices + 1 + j;
 64                 }
 65                 else
 66                 {
 67                     nOffset = (half + (halfStacks*2 - 1) * j + i * 2) * indexStriding;
 68                     lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset);
 69                     lineIndexPtr->index0 = 1 + slices*(i - 1) + j;
 70                     lineIndexPtr->index1 = 1 + slices*i + j;
 71 
 72                     nOffset += indexStriding;
 73                     lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset);
 74                     lineIndexPtr->index0 = numHalfVertices + 1 + slices*(i - 1) + j;
 75                     lineIndexPtr->index1 = numHalfVertices + 1 + slices*i + j;                    
 76                 }
 77             }
 78 
 79             nOffset = (half + (halfStacks*2 - 1) * (j + 1) - 1) * indexStriding;
 80             lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset);
 81             lineIndexPtr->index0 = 1 + slices  * (halfStacks - 2) + j;
 82             lineIndexPtr->index1 = numHalfVertices + 1 + slices * (halfStacks - 2) + j;
 83         }
 84     }
 85     else
 86     {
 87         YsLineIndex32* lineIndexPtr = NULL;
 88         for (Yuint i= 0; i < slices; i++)
 89         {
 90             YsLineIndex32* lineIndexPtr = NULL;
 91             for (Yuint i = 1; i < halfStacks; i++)
 92             {
 93                 for (Yuint j = 0; j < slices; j++)
 94                 {
 95                     nOffset = ((i - 1)*slices + j) * 2 * indexStriding;
 96                     lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset);
 97                     lineIndexPtr->index0 = 1 + (i - 1)*slices + j;
 98                     lineIndexPtr->index1 = 1 + (i - 1)*slices + (j + 1)%slices;
 99 
100                     nOffset += indexStriding;
101                     lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset);
102                     lineIndexPtr->index0 = numHalfVertices + 1 + (i - 1)*slices + j;
103                     lineIndexPtr->index1 = numHalfVertices + 1 + (i - 1)*slices + (j + 1)%slices;
104                 }
105             }
106 
107             Yuint half = (halfStacks - 1) * slices *2;
108             for (Yuint j = 0; j < slices; j++)
109             {
110                 for (Yuint i = 0; i < halfStacks - 1; i++)
111                 {
112                     if (i == 0)
113                     {
114                         nOffset = (half + (halfStacks*2 - 1) * j) * indexStriding;
115                         lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset);
116                         lineIndexPtr->index0 = 0;
117                         lineIndexPtr->index1 = 1 + j;
118 
119                         nOffset += indexStriding;
120                         lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset);
121                         lineIndexPtr->index0 = numHalfVertices;
122                         lineIndexPtr->index1 = numHalfVertices + 1 + j;
123                     }
124                     else
125                     {
126                         nOffset = (half + (halfStacks*2 - 1) * j + i * 2) * indexStriding;
127                         lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset);
128                         lineIndexPtr->index0 = 1 + slices*(i - 1) + j;
129                         lineIndexPtr->index1 = 1 + slices*i + j;
130 
131                         nOffset += indexStriding;
132                         lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset);
133                         lineIndexPtr->index0 = numHalfVertices + 1 + slices*(i - 1) + j;
134                         lineIndexPtr->index1 = numHalfVertices + 1 + slices*i + j;                    
135                     }
136                 }
137 
138                 nOffset = (half + (halfStacks*2 - 1) * (j + 1) - 1) * indexStriding;
139                 lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset);
140                 lineIndexPtr->index0 = 1 + slices  * (halfStacks - 2) + j;
141                 lineIndexPtr->index1 = numHalfVertices + 1 + slices * (halfStacks - 2) + j;
142             }
143         }
144     }
145 
146     return true;
147 }

 


 

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