[16] 螺旋面(Spire)图形的生成算法
顶点数据的生成
1 bool YfBuildSpireVertices 2 ( 3 Yreal radius, 4 Yreal assistRadius, 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 (stacks < 1 || slices < 3 || !pVerticesBuffer) 15 { 16 return false; 17 } 18 19 Yuint numVertices = 2 + stacks * 2; 20 //Yuint numTriangles = stacks * 2; 21 22 char* vertexPtr = (char*)pVerticesBuffer + vertexPos; 23 YsVector3* curVertexPtr = NULL; 24 Yuint nOffset = 0; 25 26 Yreal originOffsetY = 0.0f; 27 if (originPose == YE_ORIGIN_POSE_TOP) 28 { 29 originOffsetY = -height; 30 } 31 else if (originPose == YE_ORIGIN_POSE_CENTER) 32 { 33 originOffsetY = -height * 0.5f; 34 } 35 36 Yreal fAngle = YD_REAL_TWAIN_PI / slices; 37 38 Yreal angleXZ; 39 Yreal posX, posZ; 40 for (Yuint i = 0; i <= stacks; i++) 41 { 42 angleXZ = i * fAngle; 43 posX = yf_sin(angleXZ); 44 posZ = yf_cos(angleXZ); 45 nOffset = i * 2 * vertexStriding; 46 47 curVertexPtr = (YsVector3*)(vertexPtr + nOffset); 48 curVertexPtr->x = assistRadius * posX; 49 curVertexPtr->y = height * i * 1.0f / stacks + originOffsetY; 50 curVertexPtr->z = assistRadius * posZ; 51 52 nOffset += vertexStriding; 53 54 curVertexPtr = (YsVector3*)(vertexPtr + nOffset); 55 curVertexPtr->x = radius * posX; 56 curVertexPtr->y = height * i * 1.0f / stacks + originOffsetY; 57 curVertexPtr->z = radius * posZ; 58 } 59 60 return true; 61 }
三角形索引数据的生成
1 bool YfBuildSpireTriIndices 2 ( 3 Yuint stacks, 4 YeIndexType indexType, 5 Yuint indexStriding, 6 Yuint indexPos, 7 void* pTriIndicesBuffer 8 ) 9 { 10 if (stacks < 3 || !pTriIndicesBuffer) 11 { 12 return false; 13 } 14 15 Yuint numVertices = 2 + stacks * 2; 16 Yuint numTriangles = stacks * 2; 17 if (indexType == YE_INDEX_16_BIT && 18 numVertices > YD_MAX_UNSIGNED_INT16) 19 { 20 return false; 21 } 22 23 // 索引赋值 24 char* indexPtr = (char*)pTriIndicesBuffer + indexPos; 25 Yuint nOffset = 0; 26 if (indexType == YE_INDEX_16_BIT) 27 { 28 YsTriIndex16* triIndexPtr = NULL; 29 for (Yuint i = 0; i < stacks; i++) 30 { 31 nOffset = 2 * i * indexStriding; 32 triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset); 33 triIndexPtr->index0 = i*2; 34 triIndexPtr->index1 = i*2 + 1; 35 triIndexPtr->index2 = i*2 + 3; 36 37 nOffset += indexStriding; 38 triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset); 39 triIndexPtr->index0 = i*2; 40 triIndexPtr->index1 = i*2 + 3; 41 triIndexPtr->index2 = i*2 + 2; 42 } 43 } 44 else 45 { 46 YsTriIndex32* triIndexPtr = NULL; 47 for (Yuint i = 0; i < stacks; i++) 48 { 49 nOffset = 2 * i * indexStriding; 50 triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset); 51 triIndexPtr->index0 = i*2; 52 triIndexPtr->index1 = i*2 + 1; 53 triIndexPtr->index2 = i*2 + 3; 54 55 nOffset += indexStriding; 56 triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset); 57 triIndexPtr->index0 = i*2; 58 triIndexPtr->index1 = i*2 + 3; 59 triIndexPtr->index2 = i*2 + 2; 60 } 61 } 62 63 return true; 64 }
线框索引数据的生成
1 bool YfBuildSpireWireIndices 2 ( 3 Yuint stacks, 4 YeIndexType indexType, 5 Yuint indexStriding, 6 Yuint indexPos, 7 void* pWireIndicesBuffer 8 ) 9 { 10 if (stacks < 3 || !pWireIndicesBuffer) 11 { 12 return false; 13 } 14 15 Yuint numVertices = 2 + stacks * 2; 16 Yuint numLines = 1 + stacks * 3; 17 if (indexType == YE_INDEX_16_BIT && 18 numVertices > YD_MAX_UNSIGNED_INT16) 19 { 20 return false; 21 } 22 23 // 索引赋值 24 char* indexPtr = (char*)pWireIndicesBuffer + indexPos; 25 Yuint nOffset = 0; 26 if (indexType == YE_INDEX_16_BIT) 27 { 28 YsLineIndex16* lineIndexPtr = NULL; 29 for (Yuint i = 0; i < stacks; i++) 30 { 31 nOffset = (i * 3) * indexStriding; 32 lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset); 33 lineIndexPtr->index0 = i * 2; 34 lineIndexPtr->index1 = i * 2 + 1; 35 36 nOffset += indexStriding; 37 lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset); 38 lineIndexPtr->index0 = i * 2 + 2; 39 lineIndexPtr->index1 = i * 2; 40 41 nOffset += indexStriding; 42 lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset); 43 lineIndexPtr->index0 = i * 2 + 3; 44 lineIndexPtr->index1 = i * 2 + 1; 45 } 46 47 nOffset = (stacks * 3) * indexStriding; 48 lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset); 49 lineIndexPtr->index0 = stacks * 2; 50 lineIndexPtr->index1 = stacks * 2 + 1; 51 } 52 else 53 { 54 YsLineIndex32* lineIndexPtr = NULL; 55 for (Yuint i = 0; i < stacks; i++) 56 { 57 nOffset = (i * 3) * indexStriding; 58 lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset); 59 lineIndexPtr->index0 = i * 2; 60 lineIndexPtr->index1 = i * 2 + 1; 61 62 nOffset += indexStriding; 63 lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset); 64 lineIndexPtr->index0 = i * 2 + 2; 65 lineIndexPtr->index1 = i * 2; 66 67 nOffset += indexStriding; 68 lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset); 69 lineIndexPtr->index0 = i * 2 + 3; 70 lineIndexPtr->index1 = i * 2 + 1; 71 } 72 73 nOffset = (stacks * 3) * indexStriding; 74 lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset); 75 lineIndexPtr->index0 = stacks * 2; 76 lineIndexPtr->index1 = stacks * 2 + 1; 77 } 78 79 return true; 80 }