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