[6] 胶囊体(Capsule)图形的生成算法

时间:2023-03-09 08:25:19
[6] 胶囊体(Capsule)图形的生成算法

[6] 胶囊体(Capsule)图形的生成算法

[6] 胶囊体(Capsule)图形的生成算法

顶点数据的生成

 bool                        YfBuildCapsuleVertices
(
Yreal radius,
Yreal height,
Yuint slices,
Yuint stacks,
YeOriginPose originPose,
Yuint vertexStriding,
Yuint vertexPos,
void* pVerticesBuffer
)
{
Yuint halfStacks = stacks / ;
if (slices < || halfStacks < || !pVerticesBuffer)
{
return false;
} Yuint numVertices = slices * (halfStacks - ) * + ;
Yuint numHalfVertices = numVertices / ; // 顶点赋值
char* vertexPtr = (char*)pVerticesBuffer + vertexPos;
YsVector3* curVertexPtr = NULL; Yuint nOffset = ; 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* + height; // 胶囊体真正高度 // 最高顶点
{
nOffset = * 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 = ; j < slices; j++)
{
angleXZ = YD_REAL_TWAIN_PI * j / slices;
pSinList[j] = yf_sin(angleXZ);
pCosList[j] = yf_cos(angleXZ);
} for (Yuint i = ; i < halfStacks; i++)
{
Yreal angleY = YD_REAL_HALF_PI * i / (halfStacks - );
Yreal posY = radius * yf_cos(angleY);
Yreal radiusXZ = radius * yf_sin(angleY);
Yreal posX, posZ; for (Yuint j = ; j < slices; j++)
{
posX = radiusXZ * pSinList[j % slices];
posZ = radiusXZ * pCosList[j % slices]; nOffset = ( + (i - ) * slices + j) * vertexStriding;
curVertexPtr = (YsVector3*)(vertexPtr + nOffset);
curVertexPtr->x = posX;
curVertexPtr->y = posY + halfHeight + originOffsetY;
curVertexPtr->z = posZ; nOffset = (numHalfVertices + + (i - ) * 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 / ;
if (slices < || halfStacks < || !pTriIndicesBuffer)
{
return false;
} Yuint numVertices = slices * (halfStacks - ) * + ;
if (indexType == YE_INDEX_16_BIT &&
numVertices > YD_MAX_UNSIGNED_INT16)
{
return false;
}
Yuint numHalfVertices = numVertices / ;
Yuint numTriangles = slices * (halfStacks - ) * ; // 索引赋值
char* indexPtr = (char*)pTriIndicesBuffer + indexPos;
Yuint nOffset = ;
if (indexType == YE_INDEX_16_BIT)
{
YsTriIndex16* triIndexPtr = NULL; for (Yuint i = ; i < halfStacks - ; i++)
{
if (i == ) // 第一层
{
for (Yuint j = ; j < slices; j++)
{
nOffset = j * * indexStriding;
triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset);
triIndexPtr->index0 = ;
triIndexPtr->index1 = + j;
triIndexPtr->index2 = + (j + )%slices; nOffset += indexStriding;
triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset);
triIndexPtr->index0 = numHalfVertices;
triIndexPtr->index1 = numHalfVertices + + (j + )%slices;
triIndexPtr->index2 = numHalfVertices + + j;
}
}
else
{
for (Yuint j = ; j < slices; j++)
{
nOffset = ((i - )*slices* + slices* + j*) * indexStriding;
triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset);
triIndexPtr->index0 = + slices * (i - ) + j;
triIndexPtr->index1 = + slices * i + j;
triIndexPtr->index2 = + slices * (i - ) + (j + )%slices; nOffset += indexStriding;
triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset);
triIndexPtr->index0 = + slices * (i - ) + (j + )%slices;
triIndexPtr->index1 = + slices * i + j;
triIndexPtr->index2 = + slices * i + (j + )%slices; nOffset += indexStriding;
triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset);
triIndexPtr->index0 = numHalfVertices + + slices * (i - ) + j;
triIndexPtr->index1 = numHalfVertices + + slices * (i - ) + (j + )%slices;
triIndexPtr->index2 = numHalfVertices + + slices * i + (j + )%slices; nOffset += indexStriding;
triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset);
triIndexPtr->index0 = numHalfVertices + + slices * (i - ) + j;
triIndexPtr->index1 = numHalfVertices + + slices * i + (j + )%slices;
triIndexPtr->index2 = numHalfVertices + + slices * i + j;
}
}
} // 连接两个半球
for (Yuint j = ; j < slices; j++)
{
nOffset = ((halfStacks - )*slices* + slices* + j*) * indexStriding;
triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset);
triIndexPtr->index0 = + slices * (halfStacks - ) + j;
triIndexPtr->index1 = numHalfVertices + + slices * (halfStacks - ) + j;
triIndexPtr->index2 = + slices * (halfStacks - ) + (j + )%slices; nOffset += indexStriding;
triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset);
triIndexPtr->index0 = + slices * (halfStacks - ) + (j + )%slices;
triIndexPtr->index1 = numHalfVertices + + slices * (halfStacks - ) + j;
triIndexPtr->index2 = numHalfVertices + + slices * (halfStacks - ) + (j + )%slices;
}
}
else
{
YsTriIndex32* triIndexPtr = NULL; for (Yuint i = ; i < halfStacks - ; i++)
{
if (i == ) // 第一层
{
for (Yuint j = ; j < slices; j++)
{
nOffset = j * * indexStriding;
triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset);
triIndexPtr->index0 = ;
triIndexPtr->index1 = + j;
triIndexPtr->index2 = + (j + )%slices; nOffset += indexStriding;
triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset);
triIndexPtr->index0 = numHalfVertices;
triIndexPtr->index1 = numHalfVertices + + (j + )%slices;
triIndexPtr->index2 = numHalfVertices + (j + )%slices;
}
}
else
{
for (Yuint j = ; j < slices; j++)
{
nOffset = ((i - )*slices* + slices* + j*) * indexStriding;
triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset);
triIndexPtr->index0 = + slices * (i - ) + j;
triIndexPtr->index1 = + slices * i + j;
triIndexPtr->index2 = + slices * (i - ) + (j + )%slices; nOffset += indexStriding;
triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset);
triIndexPtr->index0 = + slices * (i - ) + (j + )%slices;
triIndexPtr->index1 = + slices * i + j;
triIndexPtr->index2 = + slices * i + j + ; nOffset += indexStriding;
triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset);
triIndexPtr->index0 = numHalfVertices + + slices * (i - ) + j;
triIndexPtr->index1 = numHalfVertices + + slices * (i - ) + (j + )%slices;
triIndexPtr->index2 = numHalfVertices + + slices * i + (j + )%slices; nOffset += indexStriding;
triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset);
triIndexPtr->index0 = numHalfVertices + + slices * (i - ) + j;
triIndexPtr->index1 = numHalfVertices + + slices * i + (j + )%slices;
triIndexPtr->index2 = numHalfVertices + + slices * i + j;
}
}
} // 连接两个半球
for (Yuint j = ; j < slices; j++)
{
nOffset = ((halfStacks - )*slices* + slices* + j*) * indexStriding;
triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset);
triIndexPtr->index0 = + slices * (halfStacks - ) + j;
triIndexPtr->index1 = numHalfVertices + + slices * (halfStacks - ) + j;
triIndexPtr->index2 = + slices * (halfStacks - ) + (j + )%slices; nOffset += indexStriding;
triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset);
triIndexPtr->index0 = + slices * (halfStacks - ) + (j + )%slices;
triIndexPtr->index1 = numHalfVertices + + slices * (halfStacks - ) + j;
triIndexPtr->index2 = numHalfVertices + + slices * (halfStacks - ) + (j + )%slices;
}
} return true;
}

线框索引数据的生成

 bool                        YfBuildCapsuleWireIndices
(
Yuint slices,
Yuint stacks,
YeIndexType indexType,
Yuint indexStriding,
Yuint indexPos,
void* pWireIndicesBuffer
)
{
Yuint halfStacks = stacks / ;
if (slices < || halfStacks < || !pWireIndicesBuffer)
{
return false;
} Yuint numVertices = slices * (halfStacks - ) * + ;
Yuint numLines = slices * (halfStacks - ) * + slices * ( * halfStacks - );
Yuint numHalfVertices = numVertices / ;
if (indexType == YE_INDEX_16_BIT &&
numVertices > YD_MAX_UNSIGNED_INT16)
{
return false;
} // 索引赋值
char* indexPtr = (char*)pWireIndicesBuffer + indexPos;
Yuint nOffset = ;
if (indexType == YE_INDEX_16_BIT)
{
YsLineIndex16* lineIndexPtr = NULL;
for (Yuint i = ; i < halfStacks; i++)
{
for (Yuint j = ; j < slices; j++)
{
nOffset = ((i - )*slices + j) * * indexStriding;
lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset);
lineIndexPtr->index0 = + (i - )*slices + j;
lineIndexPtr->index1 = + (i - )*slices + (j + )%slices; nOffset += indexStriding;
lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset);
lineIndexPtr->index0 = numHalfVertices + + (i - )*slices + j;
lineIndexPtr->index1 = numHalfVertices + + (i - )*slices + (j + )%slices;
}
} Yuint half = (halfStacks - ) * slices *;
for (Yuint j = ; j < slices; j++)
{
for (Yuint i = ; i < halfStacks - ; i++)
{
if (i == )
{
nOffset = (half + (halfStacks* - ) * j) * indexStriding;
lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset);
lineIndexPtr->index0 = ;
lineIndexPtr->index1 = + j; nOffset += indexStriding;
lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset);
lineIndexPtr->index0 = numHalfVertices;
lineIndexPtr->index1 = numHalfVertices + + j;
}
else
{
nOffset = (half + (halfStacks* - ) * j + i * ) * indexStriding;
lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset);
lineIndexPtr->index0 = + slices*(i - ) + j;
lineIndexPtr->index1 = + slices*i + j; nOffset += indexStriding;
lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset);
lineIndexPtr->index0 = numHalfVertices + + slices*(i - ) + j;
lineIndexPtr->index1 = numHalfVertices + + slices*i + j;
}
} nOffset = (half + (halfStacks* - ) * (j + ) - ) * indexStriding;
lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset);
lineIndexPtr->index0 = + slices * (halfStacks - ) + j;
lineIndexPtr->index1 = numHalfVertices + + slices * (halfStacks - ) + j;
}
}
else
{
YsLineIndex32* lineIndexPtr = NULL;
for (Yuint i= ; i < slices; i++)
{
YsLineIndex32* lineIndexPtr = NULL;
for (Yuint i = ; i < halfStacks; i++)
{
for (Yuint j = ; j < slices; j++)
{
nOffset = ((i - )*slices + j) * * indexStriding;
lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset);
lineIndexPtr->index0 = + (i - )*slices + j;
lineIndexPtr->index1 = + (i - )*slices + (j + )%slices; nOffset += indexStriding;
lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset);
lineIndexPtr->index0 = numHalfVertices + + (i - )*slices + j;
lineIndexPtr->index1 = numHalfVertices + + (i - )*slices + (j + )%slices;
}
} Yuint half = (halfStacks - ) * slices *;
for (Yuint j = ; j < slices; j++)
{
for (Yuint i = ; i < halfStacks - ; i++)
{
if (i == )
{
nOffset = (half + (halfStacks* - ) * j) * indexStriding;
lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset);
lineIndexPtr->index0 = ;
lineIndexPtr->index1 = + j; nOffset += indexStriding;
lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset);
lineIndexPtr->index0 = numHalfVertices;
lineIndexPtr->index1 = numHalfVertices + + j;
}
else
{
nOffset = (half + (halfStacks* - ) * j + i * ) * indexStriding;
lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset);
lineIndexPtr->index0 = + slices*(i - ) + j;
lineIndexPtr->index1 = + slices*i + j; nOffset += indexStriding;
lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset);
lineIndexPtr->index0 = numHalfVertices + + slices*(i - ) + j;
lineIndexPtr->index1 = numHalfVertices + + slices*i + j;
}
} nOffset = (half + (halfStacks* - ) * (j + ) - ) * indexStriding;
lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset);
lineIndexPtr->index0 = + slices * (halfStacks - ) + j;
lineIndexPtr->index1 = numHalfVertices + + slices * (halfStacks - ) + j;
}
}
} return true;
}