[6] 胶囊体(Capsule)图形的生成算法
2013-11-09 08:29
211 查看
顶点数据的生成
bool YfBuildCapsuleVertices ( Yreal radius, Yreal height, Yuint slices, Yuint stacks, YeOriginPose originPose, Yuint vertexStriding, Yuint vertexPos, void* pVerticesBuffer ) { Yuint halfStacks = stacks / 2; if (slices < 2 || halfStacks < 2 || !pVerticesBuffer) { return false; } Yuint numVertices = slices * (halfStacks - 1) * 2 + 2; Yuint numHalfVertices = numVertices / 2; // 顶点赋值 char* vertexPtr = (char*)pVerticesBuffer + vertexPos; YsVector3* curVertexPtr = NULL; Yuint nOffset = 0; Yreal originOffsetY = 0.0f; if (originPose == YE_ORIGIN_POSE_TOP) { originOffsetY = -radius - height*0.5f; } else if (originPose == YE_ORIGIN_POSE_BOTTOM) { originOffsetY = radius + height*0.5f; } Yreal halfHeight = height * 0.5f; Yreal tallness = radius*2 + height; // 胶囊体真正高度 // 最高顶点 { nOffset = 0 * vertexStriding; curVertexPtr = (YsVector3*)(vertexPtr + nOffset); curVertexPtr->x = 0.0f; curVertexPtr->y = halfHeight + radius + originOffsetY; curVertexPtr->z = 0.0f; } // 最底顶点 { nOffset = numHalfVertices * vertexStriding; curVertexPtr = (YsVector3*)(vertexPtr + nOffset); curVertexPtr->x = 0.0f; curVertexPtr->y = -halfHeight - radius + originOffsetY; curVertexPtr->z = 0.0f; } Yreal* pSinList = YD_NEW_ARRAY(Yreal, slices); Yreal* pCosList = YD_NEW_ARRAY(Yreal, slices); Yreal angleXZ; for (Yuint j = 0; j < slices; j++) { angleXZ = YD_REAL_TWAIN_PI * j / slices; pSinList[j] = yf_sin(angleXZ); pCosList[j] = yf_cos(angleXZ); } for (Yuint i = 1; i < halfStacks; i++) { Yreal angleY = YD_REAL_HALF_PI * i / (halfStacks - 1); Yreal posY = radius * yf_cos(angleY); Yreal radiusXZ = radius * yf_sin(angleY); Yreal posX, posZ; for (Yuint j = 0; j < slices; j++) { posX = radiusXZ * pSinList[j % slices]; posZ = radiusXZ * pCosList[j % slices]; nOffset = (1 + (i - 1) * slices + j) * vertexStriding; curVertexPtr = (YsVector3*)(vertexPtr + nOffset); curVertexPtr->x = posX; curVertexPtr->y = posY + halfHeight + originOffsetY; curVertexPtr->z = posZ; nOffset = (numHalfVertices + 1 + (i - 1) * slices + j) * vertexStriding; curVertexPtr = (YsVector3*)(vertexPtr + nOffset); curVertexPtr->x = posX; curVertexPtr->y = -posY - halfHeight + originOffsetY; curVertexPtr->z = posZ; } } YD_SAFE_DELETE_ARRAY(pSinList); YD_SAFE_DELETE_ARRAY(pCosList); return true; }
三角形索引数据的生成
bool YfBuildCapsuleTriIndices ( Yuint slices, Yuint stacks, YeIndexType indexType, Yuint indexStriding, Yuint indexPos, void* pTriIndicesBuffer ) { Yuint halfStacks = stacks / 2; if (slices < 2 || halfStacks < 2 || !pTriIndicesBuffer) { return false; } Yuint numVertices = slices * (halfStacks - 1) * 2 + 2; if (indexType == YE_INDEX_16_BIT && numVertices > YD_MAX_UNSIGNED_INT16) { return false; } Yuint numHalfVertices = numVertices / 2; Yuint numTriangles = slices * (halfStacks - 1) * 4; // 索引赋值 char* indexPtr = (char*)pTriIndicesBuffer + indexPos; Yuint nOffset = 0; if (indexType == YE_INDEX_16_BIT) { YsTriIndex16* triIndexPtr = NULL; for (Yuint i = 0; i < halfStacks - 1; i++) { if (i == 0) // 第一层 { for (Yuint j = 0; j < slices; j++) { nOffset = j * 2 * indexStriding; triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset); triIndexPtr->index0 = 0; triIndexPtr->index1 = 1 + j; triIndexPtr->index2 = 1 + (j + 1)%slices; nOffset += indexStriding; triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset); triIndexPtr->index0 = numHalfVertices; triIndexPtr->index1 = numHalfVertices + 1 + (j + 1)%slices; triIndexPtr->index2 = numHalfVertices + 1 + j; } } else { for (Yuint j = 0; j < slices; j++) { nOffset = ((i - 1)*slices*4 + slices*2 + j*4) * indexStriding; triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset); triIndexPtr->index0 = 1 + slices * (i - 1) + j; triIndexPtr->index1 = 1 + slices * i + j; triIndexPtr->index2 = 1 + slices * (i - 1) + (j + 1)%slices; nOffset += indexStriding; triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset); triIndexPtr->index0 = 1 + slices * (i - 1) + (j + 1)%slices; triIndexPtr->index1 = 1 + slices * i + j; triIndexPtr->index2 = 1 + slices * i + (j + 1)%slices; nOffset += indexStriding; triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset); triIndexPtr->index0 = numHalfVertices + 1 + slices * (i - 1) + j; triIndexPtr->index1 = numHalfVertices + 1 + slices * (i - 1) + (j + 1)%slices; triIndexPtr->index2 = numHalfVertices + 1 + slices * i + (j + 1)%slices; nOffset += indexStriding; triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset); triIndexPtr->index0 = numHalfVertices + 1 + slices * (i - 1) + j; triIndexPtr->index1 = numHalfVertices + 1 + slices * i + (j + 1)%slices; triIndexPtr->index2 = numHalfVertices + 1 + slices * i + j; } } } // 连接两个半球 for (Yuint j = 0; j < slices; j++) { nOffset = ((halfStacks - 2)*slices*4 + slices*2 + j*2) * indexStriding; triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset); triIndexPtr->index0 = 1 + slices * (halfStacks - 2) + j; triIndexPtr->index1 = numHalfVertices + 1 + slices * (halfStacks - 2) + j; triIndexPtr->index2 = 1 + slices * (halfStacks - 2) + (j + 1)%slices; nOffset += indexStriding; triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset); triIndexPtr->index0 = 1 + slices * (halfStacks - 2) + (j + 1)%slices; triIndexPtr->index1 = numHalfVertices + 1 + slices * (halfStacks - 2) + j; triIndexPtr->index2 = numHalfVertices + 1 + slices * (halfStacks - 2) + (j + 1)%slices; } } else { YsTriIndex32* triIndexPtr = NULL; for (Yuint i = 0; i < halfStacks - 1; i++) { if (i == 0) // 第一层 { for (Yuint j = 0; j < slices; j++) { nOffset = j * 2 * indexStriding; triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset); triIndexPtr->index0 = 0; triIndexPtr->index1 = 1 + j; triIndexPtr->index2 = 1 + (j + 1)%slices; nOffset += indexStriding; triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset); triIndexPtr->index0 = numHalfVertices; triIndexPtr->index1 = numHalfVertices + 1 + (j + 1)%slices; triIndexPtr->index2 = numHalfVertices + (j + 1)%slices; } } else { for (Yuint j = 0; j < slices; j++) { nOffset = ((i - 1)*slices*4 + slices*2 + j*4) * indexStriding; triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset); triIndexPtr->index0 = 1 + slices * (i - 1) + j; triIndexPtr->index1 = 1 + slices * i + j; triIndexPtr->index2 = 1 + slices * (i - 1) + (j + 1)%slices; nOffset += indexStriding; triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset); triIndexPtr->index0 = 1 + slices * (i - 1) + (j + 1)%slices; triIndexPtr->index1 = 1 + slices * i + j; triIndexPtr->index2 = 1 + slices * i + j + 1; nOffset += indexStriding; triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset); triIndexPtr->index0 = numHalfVertices + 1 + slices * (i - 1) + j; triIndexPtr->index1 = numHalfVertices + 1 + slices * (i - 1) + (j + 1)%slices; triIndexPtr->index2 = numHalfVertices + 1 + slices * i + (j + 1)%slices; nOffset += indexStriding; triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset); triIndexPtr->index0 = numHalfVertices + 1 + slices * (i - 1) + j; triIndexPtr->index1 = numHalfVertices + 1 + slices * i + (j + 1)%slices; triIndexPtr->index2 = numHalfVertices + 1 + slices * i + j; } } } // 连接两个半球 for (Yuint j = 0; j < slices; j++) { nOffset = ((halfStacks - 2)*slices*4 + slices*2 + j*2) * indexStriding; triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset); triIndexPtr->index0 = 1 + slices * (halfStacks - 2) + j; triIndexPtr->index1 = numHalfVertices + 1 + slices * (halfStacks - 2) + j; triIndexPtr->index2 = 1 + slices * (halfStacks - 2) + (j + 1)%slices; nOffset += indexStriding; triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset); triIndexPtr->index0 = 1 + slices * (halfStacks - 2) + (j + 1)%slices; triIndexPtr->index1 = numHalfVertices + 1 + slices * (halfStacks - 2) + j; triIndexPtr->index2 = numHalfVertices + 1 + slices * (halfStacks - 2) + (j + 1)%slices; } } return true; }
线框索引数据的生成
bool YfBuildCapsuleWireIndices ( Yuint slices, Yuint stacks, YeIndexType indexType, Yuint indexStriding, Yuint indexPos, void* pWireIndicesBuffer ) { Yuint halfStacks = stacks / 2; if (slices < 2 || halfStacks < 2 || !pWireIndicesBuffer) { return false; } Yuint numVertices = slices * (halfStacks - 1) * 2 + 2; Yuint numLines = slices * (halfStacks - 1) * 2 + slices * (2 * halfStacks - 1); Yuint numHalfVertices = numVertices / 2; 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 i = 1; i < halfStacks; i++) { for (Yuint j = 0; j < slices; j++) { nOffset = ((i - 1)*slices + j) * 2 * indexStriding; lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset); lineIndexPtr->index0 = 1 + (i - 1)*slices + j; lineIndexPtr->index1 = 1 + (i - 1)*slices + (j + 1)%slices; nOffset += indexStriding; lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset); lineIndexPtr->index0 = numHalfVertices + 1 + (i - 1)*slices + j; lineIndexPtr->index1 = numHalfVertices + 1 + (i - 1)*slices + (j + 1)%slices; } } Yuint half = (halfStacks - 1) * slices *2; for (Yuint j = 0; j < slices; j++) { for (Yuint i = 0; i < halfStacks - 1; i++) { if (i == 0) { nOffset = (half + (halfStacks*2 - 1) * j) * indexStriding; lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset); lineIndexPtr->index0 = 0; lineIndexPtr->index1 = 1 + j; nOffset += indexStriding; lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset); lineIndexPtr->index0 = numHalfVertices; lineIndexPtr->index1 = numHalfVertices + 1 + j; } else { nOffset = (half + (halfStacks*2 - 1) * j + i * 2) * indexStriding; lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset); lineIndexPtr->index0 = 1 + slices*(i - 1) + j; lineIndexPtr->index1 = 1 + slices*i + j; nOffset += indexStriding; lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset); lineIndexPtr->index0 = numHalfVertices + 1 + slices*(i - 1) + j; lineIndexPtr->index1 = numHalfVertices + 1 + slices*i + j; } } nOffset = (half + (halfStacks*2 - 1) * (j + 1) - 1) * indexStriding; lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset); lineIndexPtr->index0 = 1 + slices * (halfStacks - 2) + j; lineIndexPtr->index1 = numHalfVertices + 1 + slices * (halfStacks - 2) + j; } } else { YsLineIndex32* lineIndexPtr = NULL; for (Yuint i= 0; i < slices; i++) { YsLineIndex32* lineIndexPtr = NULL; for (Yuint i = 1; i < halfStacks; i++) { for (Yuint j = 0; j < slices; j++) { nOffset = ((i - 1)*slices + j) * 2 * indexStriding; lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset); lineIndexPtr->index0 = 1 + (i - 1)*slices + j; lineIndexPtr->index1 = 1 + (i - 1)*slices + (j + 1)%slices; nOffset += indexStriding; lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset); lineIndexPtr->index0 = numHalfVertices + 1 + (i - 1)*slices + j; lineIndexPtr->index1 = numHalfVertices + 1 + (i - 1)*slices + (j + 1)%slices; } } Yuint half = (halfStacks - 1) * slices *2; for (Yuint j = 0; j < slices; j++) { for (Yuint i = 0; i < halfStacks - 1; i++) { if (i == 0) { nOffset = (half + (halfStacks*2 - 1) * j) * indexStriding; lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset); lineIndexPtr->index0 = 0; lineIndexPtr->index1 = 1 + j; nOffset += indexStriding; lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset); lineIndexPtr->index0 = numHalfVertices; lineIndexPtr->index1 = numHalfVertices + 1 + j; } else { nOffset = (half + (halfStacks*2 - 1) * j + i * 2) * indexStriding; lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset); lineIndexPtr->index0 = 1 + slices*(i - 1) + j; lineIndexPtr->index1 = 1 + slices*i + j; nOffset += indexStriding; lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset); lineIndexPtr->index0 = numHalfVertices + 1 + slices*(i - 1) + j; lineIndexPtr->index1 = numHalfVertices + 1 + slices*i + j; } } nOffset = (half + (halfStacks*2 - 1) * (j + 1) - 1) * indexStriding; lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset); lineIndexPtr->index0 = 1 + slices * (halfStacks - 2) + j; lineIndexPtr->index1 = numHalfVertices + 1 + slices * (halfStacks - 2) + j; } } } return true; }
相关文章推荐
- [6] 胶囊体(Capsule)图形的生成算法
- [9] 圆环(Ring)图形的生成算法
- [18] 螺旋楼梯(Spiral Stairs)图形的生成算法
- [20] 鼓状物(Drum)图形的生成算法
- [9] 圆环(Ring)图形的生成算法
- 【计算机图形学】基本图形元素:直线的生成算法
- 【计算机图形学】基本图形元素:圆的生成算法
- 基本图形生成算法注记
- [9] 圆环(Ring)图形的生成算法
- [5] 柱台(Cylinder)图形的生成算法
- [10] 圆管(Pipe)图形的生成算法
- 基本图形生成算法注记
- [11] 楔形体(Wedge)图形的生成算法
- 计算机图形学第五章---基本图形生成算法
- [14] 齿轮(Gear Wheel)图形的生成算法
- 基本图形生成算法
- [16] 螺旋面(Spire)图形的生成算法
- [12] 扇形体(Fan)图形的生成算法
- 图形生成算法:多边形的扫描转换与区域填充算法
- [13] 弧面(Arc)图形的生成算法