[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 }