[13] 弧面(Arc)图形的生成算法
顶点数据的生成
1 bool YfBuildArcVertices 2 ( 3 Yreal radius, 4 Yreal degree, 5 Yreal height, 6 Yuint slices, 7 Yuint stacks, 8 YeOriginPose originPose, 9 Yuint vertexStriding, 10 Yuint vertexPos, 11 void* pVerticesBuffer 12 ) 13 { 14 if (degree < 0 || degree > 180 || !pVerticesBuffer) 15 { 16 return false; 17 } 18 if (slices < 2 || stacks < 3 || !pVerticesBuffer) 19 { 20 return false; 21 } 22 23 Yuint numVertices = slices * (stacks - 1) + 1; 24 25 char* vertexPtr = (char*)pVerticesBuffer + vertexPos; 26 YsVector3* curVertexPtr = NULL; 27 Yuint nOffset = 0; 28 29 Yreal originOffsetY = 0.0f; 30 if (originPose == YE_ORIGIN_POSE_TOP) 31 { 32 originOffsetY = -radius; 33 } 34 else if (originPose == YE_ORIGIN_POSE_BOTTOM) 35 { 36 originOffsetY = radius; 37 } 38 39 Yreal* pSinList = YD_NEW_ARRAY(Yreal, slices); 40 Yreal* pCosList = YD_NEW_ARRAY(Yreal, slices); 41 Yreal angleXZ; 42 for (Yuint j = 0; j < slices; j++) 43 { 44 angleXZ = YD_REAL_TWAIN_PI * j / slices; 45 pSinList[j] = yf_sin(angleXZ); 46 pCosList[j] = yf_cos(angleXZ); 47 } 48 49 // 赋值 50 { 51 Yreal radian = YD_DEGREE_TO_RADIAN(degree); 52 for (Yuint i = 0; i < stacks; i++) 53 { 54 if (i == 0) // 第一个顶点 55 { 56 nOffset = 0; 57 curVertexPtr = (YsVector3*)(vertexPtr + nOffset); 58 curVertexPtr->x = 0.0f; 59 curVertexPtr->y = radius + originOffsetY; 60 curVertexPtr->z = 0.0f; 61 continue; 62 } 63 64 Yreal angleY = radian * i / (stacks - 1); 65 Yreal posY = radius * yf_cos(angleY); 66 Yreal radiusXZ = radius * yf_sin(angleY); 67 Yreal posX, posZ; 68 69 for (Yuint j = 0; j < slices; j++) 70 { 71 posX = radiusXZ * pSinList[j % slices]; 72 posZ = radiusXZ * pCosList[j % slices]; 73 74 nOffset = (1 + (i - 1) * slices + j) * vertexStriding; 75 curVertexPtr = (YsVector3*)(vertexPtr + nOffset); 76 curVertexPtr->x = posX; 77 curVertexPtr->y = posY + originOffsetY; 78 curVertexPtr->z = posZ; 79 } 80 } 81 } 82 83 YD_SAFE_DELETE_ARRAY(pSinList); 84 YD_SAFE_DELETE_ARRAY(pCosList); 85 86 return true; 87 }
三角形索引数据的生成
1 bool YfBuildArcTriIndices 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 Yuint numTriangles = slices * (stacks - 2) * 2 + slices; 18 19 if (indexType == YE_INDEX_16_BIT && 20 numVertices > YD_MAX_UNSIGNED_INT16) 21 { 22 return false; 23 } 24 25 // 索引赋值 26 char* indexPtr = (char*)pTriIndicesBuffer + indexPos; 27 Yuint nOffset = 0; 28 if (indexType == YE_INDEX_16_BIT) 29 { 30 YsTriIndex16* triIndexPtr = NULL; 31 32 // 赋值 33 for (Yuint i = 0; i < stacks - 1; i++) 34 { 35 if (i == 0) // 第一层 36 { 37 for (Yuint j = 0; j < slices; j++) 38 { 39 nOffset = j * indexStriding; 40 triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset); 41 triIndexPtr->index0 = 0; 42 triIndexPtr->index1 = 1 + j; 43 triIndexPtr->index2 = 1 + (j + 1)%slices; 44 } 45 } 46 else 47 { 48 for (Yuint j = 0; j < slices; j++) 49 { 50 nOffset = ((i - 1)*slices * 2 + slices + j * 2) * indexStriding; 51 triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset); 52 triIndexPtr->index0 = 1 + slices * (i - 1) + j; 53 triIndexPtr->index1 = 1 + slices * i + j; 54 triIndexPtr->index2 = 1 + slices * (i - 1) + (j + 1)%slices; 55 56 nOffset += indexStriding; 57 triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset); 58 triIndexPtr->index0 = 1 + slices * (i - 1) + (j + 1)%slices; 59 triIndexPtr->index1 = 1 + slices * i + j; 60 triIndexPtr->index2 = 1 + slices * i + (j + 1)%slices; 61 } 62 } 63 } 64 } 65 else 66 { 67 YsTriIndex32* triIndexPtr = NULL; 68 69 // 赋值 70 for (Yuint i = 0; i < stacks - 1; i++) 71 { 72 if (i == 0) // 第一层 73 { 74 for (Yuint j = 0; j < slices; j++) 75 { 76 nOffset = j * indexStriding; 77 triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset); 78 triIndexPtr->index0 = 0; 79 triIndexPtr->index1 = 1 + j; 80 triIndexPtr->index2 = 1 + (j + 1)%slices; 81 } 82 } 83 else 84 { 85 for (Yuint j = 0; j < slices; j++) 86 { 87 nOffset = ((i - 1)*slices * 2 + slices + j * 2) * indexStriding; 88 triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset); 89 triIndexPtr->index0 = 1 + slices * (i - 1) + j; 90 triIndexPtr->index1 = 1 + slices * i + j; 91 triIndexPtr->index2 = 1 + slices * (i - 1) + (j + 1)%slices; 92 93 nOffset += indexStriding; 94 triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset); 95 triIndexPtr->index0 = 1 + slices * (i - 1) + (j + 1)%slices; 96 triIndexPtr->index1 = 1 + slices * i + j; 97 triIndexPtr->index2 = 1 + slices * i + (j + 1)%slices; 98 } 99 } 100 } 101 } 102 103 return true; 104 }
线框索引数据的生成
bool YfBuildArcWireIndices ( Yuint slices, Yuint stacks, YeIndexType indexType, Yuint indexStriding, Yuint indexPos, void* pWireIndicesBuffer ) { if (slices < 2 || !pWireIndicesBuffer) { return false; } Yuint numVertices = slices * (stacks - 1) + 1; Yuint numLines = slices * (stacks - 1) + slices * (stacks - 1); if (indexType == YE_INDEX_16_BIT && numVertices > YD_MAX_UNSIGNED_INT16) { return false; } // 索引赋值 char* indexPtr = (char*)pWireIndicesBuffer + indexPos; Yuint nOffset = 0; if (indexType == YE_INDEX_16_BIT) { YsLineIndex16* lineIndexPtr = NULL; // 行 for (Yuint j = 1; j < stacks; j++) { for (Yuint i = 0; i < slices; i++) { nOffset = ((j - 1)*slices + i) * indexStriding; lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset); lineIndexPtr->index0 = 1 + (j - 1)*slices + i; lineIndexPtr->index1 = 1 + (j - 1)*slices + (i + 1)%slices; } } // 列 Yuint half = slices * (stacks - 1); for (Yuint i = 0; i < slices; i++) { nOffset = (half + i) * indexStriding; lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset); lineIndexPtr->index0 = 0; lineIndexPtr->index1 = 1 + i; } half += slices; for (Yuint j = 1; j < stacks - 1; j++) { for (Yuint i = 0; i < slices; i++) { nOffset = (half + (j - 1)*slices + i) * indexStriding; lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset); lineIndexPtr->index0 = 1 + (j - 1)*slices + i; lineIndexPtr->index1 = 1 + j*slices + i; } } //// 列 //Yuint half = slices * (stacks - 1); //for (Yuint i = 0; i < slices; i++) //{ // for (Yuint j = 0; j < stacks - 2; j++) // { // nOffset = (half + (i*(stacks - 1) + j)) * indexStriding; // lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset); // if (j == 0) // { // lineIndexPtr->index0 = 0; // } // else // { // lineIndexPtr->index0 = 1 + (j - 1)*slices + i; // } // lineIndexPtr->index1 = 1 + j*slices + i; // } //} } else { YsLineIndex32* lineIndexPtr = NULL; // 行 for (Yuint j = 1; j < stacks; j++) { for (Yuint i = 0; i < slices; i++) { nOffset = ((j - 1)*slices + i) * indexStriding; lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset); lineIndexPtr->index0 = 1 + (j - 1)*slices + i; lineIndexPtr->index1 = 1 + (j - 1)*slices + (i + 1)%slices; } } // 列 Yuint half = slices * (stacks - 1); for (Yuint i = 0; i < slices; i++) { nOffset = (half + i) * indexStriding; lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset); lineIndexPtr->index0 = 0; lineIndexPtr->index1 = 1 + i; } half += slices; for (Yuint j = 1; j < stacks - 1; j++) { for (Yuint i = 0; i < slices; i++) { nOffset = (half + (j - 1)*slices + i) * indexStriding; lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset); lineIndexPtr->index0 = 1 + (j - 1)*slices + i; lineIndexPtr->index1 = 1 + j*slices + i; } } // 列 //Yuint half = slices * (stacks - 1); //for (Yuint i = 0; i < slices; i++) //{ // for (Yuint j = 0; j < stacks - 2; j++) // { // nOffset = (half + (i*(stacks - 1) + j)) * indexStriding; // lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset); // if (j == 0) // { // lineIndexPtr->index0 = 0; // } // else // { // lineIndexPtr->index0 = 1 + (j - 1)*slices + i; // } // lineIndexPtr->index1 = 1 + j*slices + i; // } //} } return true; }