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

2025-10-15 22:26:24

顶点数据的生成

1 bool YfBuildCapsuleVertices

2 (

3 Yreal radius,

4 Yreal height,

5 Yuint slices,

6 Yuint stacks,

7 YeOriginPose originPose,

8 Yuint vertexStriding,

9 Yuint vertexPos,

10 void* pVerticesBuffer

11 )

12 {

13 Yuint halfStacks = stacks / 2;

14 if (slices < 2 || halfStacks < 2 || !pVerticesBuffer)

15 {

16 return false;

17 }

18

19 Yuint numVertices = slices * (halfStacks - 1) * 2 + 2;

20 Yuint numHalfVertices = numVertices / 2;

21

22 // 顶点赋值

23 char* vertexPtr = (char*)pVerticesBuffer + vertexPos;

24 YsVector3* curVertexPtr = NULL;

25

26 Yuint nOffset = 0;

27

28 Yreal originOffsetY = 0.0f;

29 if (originPose == YE_ORIGIN_POSE_TOP)

30 {

31 originOffsetY = -radius - height*0.5f;

32 }

33 else if (originPose == YE_ORIGIN_POSE_BOTTOM)

34 {

35 originOffsetY = radius + height*0.5f;

36 }

37

38 Yreal halfHeight = height * 0.5f;

39 Yreal tallness = radius*2 + height; // 胶囊体真正高度

40

41 // 最高顶点

42 {

43 nOffset = 0 * vertexStriding;

44 curVertexPtr = (YsVector3*)(vertexPtr + nOffset);

45 curVertexPtr->x = 0.0f;

46 curVertexPtr->y = halfHeight + radius + originOffsetY;

47 curVertexPtr->z = 0.0f;

48 }

49 // 最底顶点

50 {

51 nOffset = numHalfVertices * vertexStriding;

52 curVertexPtr = (YsVector3*)(vertexPtr + nOffset);

53 curVertexPtr->x = 0.0f;

54 curVertexPtr->y = -halfHeight - radius + originOffsetY;

55 curVertexPtr->z = 0.0f;

56 }

57

58 Yreal* pSinList = YD_NEW_ARRAY(Yreal, slices);

59 Yreal* pCosList = YD_NEW_ARRAY(Yreal, slices);

60 Yreal angleXZ;

61 for (Yuint j = 0; j < slices; j++)

62 {

63 angleXZ = YD_REAL_TWAIN_PI * j / slices;

64 pSinList[j] = yf_sin(angleXZ);

65 pCosList[j] = yf_cos(angleXZ);

66 }

67

68 for (Yuint i = 1; i < halfStacks; i++)

69 {

70 Yreal angleY = YD_REAL_HALF_PI * i / (halfStacks - 1);

71 Yreal posY = radius * yf_cos(angleY);

72 Yreal radiusXZ = radius * yf_sin(angleY);

73 Yreal posX, posZ;

74

75 for (Yuint j = 0; j < slices; j++)

76 {

77 posX = radiusXZ * pSinList[j % slices];

78 posZ = radiusXZ * pCosList[j % slices];

79

80 nOffset = (1 + (i - 1) * slices + j) * vertexStriding;

81 curVertexPtr = (YsVector3*)(vertexPtr + nOffset);

82 curVertexPtr->x = posX;

83 curVertexPtr->y = posY + halfHeight + originOffsetY;

84 curVertexPtr->z = posZ;

85

86 nOffset = (numHalfVertices + 1 + (i - 1) * slices + j) * vertexStriding;

87 curVertexPtr = (YsVector3*)(vertexPtr + nOffset);

88 curVertexPtr->x = posX;

89 curVertexPtr->y = -posY - halfHeight + originOffsetY;

90 curVertexPtr->z = posZ;

91 }

92 }

93

94 YD_SAFE_DELETE_ARRAY(pSinList);

95 YD_SAFE_DELETE_ARRAY(pCosList);

96

97 return true;

98 }

三角形索引数据的生成

1 bool YfBuildCapsuleTriIndices

2 (

3 Yuint slices,

4 Yuint stacks,

5 YeIndexType indexType,

6 Yuint indexStriding,

7 Yuint indexPos,

8 void* pTriIndicesBuffer

9 )

10 {

11 Yuint halfStacks = stacks / 2;

12 if (slices < 2 || halfStacks < 2 || !pTriIndicesBuffer)

13 {

14 return false;

15 }

16

17 Yuint numVertices = slices * (halfStacks - 1) * 2 + 2;

18 if (indexType == YE_INDEX_16_BIT &&

19 numVertices > YD_MAX_UNSIGNED_INT16)

20 {

21 return false;

22 }

23 Yuint numHalfVertices = numVertices / 2;

24 Yuint numTriangles = slices * (halfStacks - 1) * 4;

25

26 // 索引赋值

27 char* indexPtr = (char*)pTriIndicesBuffer + indexPos;

28 Yuint nOffset = 0;

29 if (indexType == YE_INDEX_16_BIT)

30 {

31 YsTriIndex16* triIndexPtr = NULL;

32

33 for (Yuint i = 0; i < halfStacks - 1; i++)

34 {

35 if (i == 0) // 第一层

36 {

37 for (Yuint j = 0; j < slices; j++)

38 {

39 nOffset = j * 2 * indexStriding;

40 triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset);

41 triIndexPtr->index0 = 0;

42 triIndexPtr->index1 = 1 + j;

43 triIndexPtr->index2 = 1 + (j + 1)%slices;

44

45 nOffset += indexStriding;

46 triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset);

47 triIndexPtr->index0 = numHalfVertices;

48 triIndexPtr->index1 = numHalfVertices + 1 + (j + 1)%slices;

49 triIndexPtr->index2 = numHalfVertices + 1 + j;

50 }

51 }

52 else

53 {

54 for (Yuint j = 0; j < slices; j++)

55 {

56 nOffset = ((i - 1)*slices*4 + slices*2 + j*4) * indexStriding;

57 triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset);

58 triIndexPtr->index0 = 1 + slices * (i - 1) + j;

59 triIndexPtr->index1 = 1 + slices * i + j;

60 triIndexPtr->index2 = 1 + slices * (i - 1) + (j + 1)%slices;

61

62 nOffset += indexStriding;

63 triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset);

64 triIndexPtr->index0 = 1 + slices * (i - 1) + (j + 1)%slices;

65 triIndexPtr->index1 = 1 + slices * i + j;

66 triIndexPtr->index2 = 1 + slices * i + (j + 1)%slices;

67

68 nOffset += indexStriding;

69 triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset);

70 triIndexPtr->index0 = numHalfVertices + 1 + slices * (i - 1) + j;

71 triIndexPtr->index1 = numHalfVertices + 1 + slices * (i - 1) + (j + 1)%slices;

72 triIndexPtr->index2 = numHalfVertices + 1 + slices * i + (j + 1)%slices;

73

74 nOffset += indexStriding;

75 triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset);

76 triIndexPtr->index0 = numHalfVertices + 1 + slices * (i - 1) + j;

77 triIndexPtr->index1 = numHalfVertices + 1 + slices * i + (j + 1)%slices;

78 triIndexPtr->index2 = numHalfVertices + 1 + slices * i + j;

79 }

80 }

81 }

82

83 // 连接两个半球

84 for (Yuint j = 0; j < slices; j++)

85 {

86 nOffset = ((halfStacks - 2)*slices*4 + slices*2 + j*2) * indexStriding;

87 triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset);

88 triIndexPtr->index0 = 1 + slices * (halfStacks - 2) + j;

89 triIndexPtr->index1 = numHalfVertices + 1 + slices * (halfStacks - 2) + j;

90 triIndexPtr->index2 = 1 + slices * (halfStacks - 2) + (j + 1)%slices;

91

92 nOffset += indexStriding;

93 triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset);

94 triIndexPtr->index0 = 1 + slices * (halfStacks - 2) + (j + 1)%slices;

95 triIndexPtr->index1 = numHalfVertices + 1 + slices * (halfStacks - 2) + j;

96 triIndexPtr->index2 = numHalfVertices + 1 + slices * (halfStacks - 2) + (j + 1)%slices;

97 }

98 }

99 else

100 {

101 YsTriIndex32* triIndexPtr = NULL;

102

103 for (Yuint i = 0; i < halfStacks - 1; i++)

104 {

105 if (i == 0) // 第一层

106 {

107 for (Yuint j = 0; j < slices; j++)

108 {

109 nOffset = j * 2 * indexStriding;

110 triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset);

111 triIndexPtr->index0 = 0;

112 triIndexPtr->index1 = 1 + j;

113 triIndexPtr->index2 = 1 + (j + 1)%slices;

114

115 nOffset += indexStriding;

116 triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset);

117 triIndexPtr->index0 = numHalfVertices;

118 triIndexPtr->index1 = numHalfVertices + 1 + (j + 1)%slices;

119 triIndexPtr->index2 = numHalfVertices + (j + 1)%slices;

120 }

121 }

122 else

123 {

124 for (Yuint j = 0; j < slices; j++)

125 {

126 nOffset = ((i - 1)*slices*4 + slices*2 + j*4) * indexStriding;

127 triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset);

128 triIndexPtr->index0 = 1 + slices * (i - 1) + j;

129 triIndexPtr->index1 = 1 + slices * i + j;

130 triIndexPtr->index2 = 1 + slices * (i - 1) + (j + 1)%slices;

131

132 nOffset += indexStriding;

133 triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset);

134 triIndexPtr->index0 = 1 + slices * (i - 1) + (j + 1)%slices;

135 triIndexPtr->index1 = 1 + slices * i + j;

136 triIndexPtr->index2 = 1 + slices * i + j + 1;

137

138 nOffset += indexStriding;

139 triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset);

140 triIndexPtr->index0 = numHalfVertices + 1 + slices * (i - 1) + j;

141 triIndexPtr->index1 = numHalfVertices + 1 + slices * (i - 1) + (j + 1)%slices;

142 triIndexPtr->index2 = numHalfVertices + 1 + slices * i + (j + 1)%slices;

143

144 nOffset += indexStriding;

145 triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset);

146 triIndexPtr->index0 = numHalfVertices + 1 + slices * (i - 1) + j;

147 triIndexPtr->index1 = numHalfVertices + 1 + slices * i + (j + 1)%slices;

148 triIndexPtr->index2 = numHalfVertices + 1 + slices * i + j;

149 }

150 }

151 }

152

153 // 连接两个半球

154 for (Yuint j = 0; j < slices; j++)

155 {

156 nOffset = ((halfStacks - 2)*slices*4 + slices*2 + j*2) * indexStriding;

157 triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset);

158 triIndexPtr->index0 = 1 + slices * (halfStacks - 2) + j;

159 triIndexPtr->index1 = numHalfVertices + 1 + slices * (halfStacks - 2) + j;

160 triIndexPtr->index2 = 1 + slices * (halfStacks - 2) + (j + 1)%slices;

161

162 nOffset += indexStriding;

163 triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset);

164 triIndexPtr->index0 = 1 + slices * (halfStacks - 2) + (j + 1)%slices;

165 triIndexPtr->index1 = numHalfVertices + 1 + slices * (halfStacks - 2) + j;

166 triIndexPtr->index2 = numHalfVertices + 1 + slices * (halfStacks - 2) + (j + 1)%slices;

167 }

168 }

169

170 return true;

171 }

线框索引数据的生成

1 bool YfBuildCapsuleWireIndices

2 (

3 Yuint slices,

4 Yuint stacks,

5 YeIndexType indexType,

6 Yuint indexStriding,

7 Yuint indexPos,

8 void* pWireIndicesBuffer

9 )

10 {

11 Yuint halfStacks = stacks / 2;

12 if (slices < 2 || halfStacks < 2 || !pWireIndicesBuffer)

13 {

14 return false;

15 }

16

17 Yuint numVertices = slices * (halfStacks - 1) * 2 + 2;

18 Yuint numLines = slices * (halfStacks - 1) * 2 + slices * (2 * halfStacks - 1);

19 Yuint numHalfVertices = numVertices / 2;

20 if (indexType == YE_INDEX_16_BIT &&

21 numVertices > YD_MAX_UNSIGNED_INT16)

22 {

23 return false;

24 }

25

26 // 索引赋值

27 char* indexPtr = (char*)pWireIndicesBuffer + indexPos;

28 Yuint nOffset = 0;

29 if (indexType == YE_INDEX_16_BIT)

30 {

31 YsLineIndex16* lineIndexPtr = NULL;

32 for (Yuint i = 1; i < halfStacks; i++)

33 {

34 for (Yuint j = 0; j < slices; j++)

35 {

36 nOffset = ((i - 1)*slices + j) * 2 * indexStriding;

37 lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset);

38 lineIndexPtr->index0 = 1 + (i - 1)*slices + j;

39 lineIndexPtr->index1 = 1 + (i - 1)*slices + (j + 1)%slices;

40

41 nOffset += indexStriding;

42 lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset);

43 lineIndexPtr->index0 = numHalfVertices + 1 + (i - 1)*slices + j;

44 lineIndexPtr->index1 = numHalfVertices + 1 + (i - 1)*slices + (j + 1)%slices;

45 }

46 }

47

48 Yuint half = (halfStacks - 1) * slices *2;

49 for (Yuint j = 0; j < slices; j++)

50 {

51 for (Yuint i = 0; i < halfStacks - 1; i++)

52 {

53 if (i == 0)

54 {

55 nOffset = (half + (halfStacks*2 - 1) * j) * indexStriding;

56 lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset);

57 lineIndexPtr->index0 = 0;

58 lineIndexPtr->index1 = 1 + j;

59

60 nOffset += indexStriding;

61 lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset);

62 lineIndexPtr->index0 = numHalfVertices;

63 lineIndexPtr->index1 = numHalfVertices + 1 + j;

64 }

65 else

66 {

67 nOffset = (half + (halfStacks*2 - 1) * j + i * 2) * indexStriding;

68 lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset);

69 lineIndexPtr->index0 = 1 + slices*(i - 1) + j;

70 lineIndexPtr->index1 = 1 + slices*i + j;

71

72 nOffset += indexStriding;

73 lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset);

74 lineIndexPtr->index0 = numHalfVertices + 1 + slices*(i - 1) + j;

75 lineIndexPtr->index1 = numHalfVertices + 1 + slices*i + j;

76 }

77 }

78

79 nOffset = (half + (halfStacks*2 - 1) * (j + 1) - 1) * indexStriding;

80 lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset);

81 lineIndexPtr->index0 = 1 + slices * (halfStacks - 2) + j;

82 lineIndexPtr->index1 = numHalfVertices + 1 + slices * (halfStacks - 2) + j;

83 }

84 }

85 else

86 {

87 YsLineIndex32* lineIndexPtr = NULL;

88 for (Yuint i= 0; i < slices; i++)

89 {

90 YsLineIndex32* lineIndexPtr = NULL;

91 for (Yuint i = 1; i < halfStacks; i++)

92 {

93 for (Yuint j = 0; j < slices; j++)

94 {

95 nOffset = ((i - 1)*slices + j) * 2 * indexStriding;

96 lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset);

97 lineIndexPtr->index0 = 1 + (i - 1)*slices + j;

98 lineIndexPtr->index1 = 1 + (i - 1)*slices + (j + 1)%slices;

99

100 nOffset += indexStriding;

101 lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset);

102 lineIndexPtr->index0 = numHalfVertices + 1 + (i - 1)*slices + j;

103 lineIndexPtr->index1 = numHalfVertices + 1 + (i - 1)*slices + (j + 1)%slices;

104 }

105 }

106

107 Yuint half = (halfStacks - 1) * slices *2;

108 for (Yuint j = 0; j < slices; j++)

109 {

110 for (Yuint i = 0; i < halfStacks - 1; i++)

111 {

112 if (i == 0)

113 {

114 nOffset = (half + (halfStacks*2 - 1) * j) * indexStriding;

115 lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset);

116 lineIndexPtr->index0 = 0;

117 lineIndexPtr->index1 = 1 + j;

118

119 nOffset += indexStriding;

120 lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset);

121 lineIndexPtr->index0 = numHalfVertices;

122 lineIndexPtr->index1 = numHalfVertices + 1 + j;

123 }

124 else

125 {

126 nOffset = (half + (halfStacks*2 - 1) * j + i * 2) * indexStriding;

127 lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset);

128 lineIndexPtr->index0 = 1 + slices*(i - 1) + j;

129 lineIndexPtr->index1 = 1 + slices*i + j;

130

131 nOffset += indexStriding;

132 lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset);

133 lineIndexPtr->index0 = numHalfVertices + 1 + slices*(i - 1) + j;

134 lineIndexPtr->index1 = numHalfVertices + 1 + slices*i + j;

135 }

136 }

137

138 nOffset = (half + (halfStacks*2 - 1) * (j + 1) - 1) * indexStriding;

139 lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset);

140 lineIndexPtr->index0 = 1 + slices * (halfStacks - 2) + j;

141 lineIndexPtr->index1 = numHalfVertices + 1 + slices * (halfStacks - 2) + j;

142 }

143 }

144 }

145

146 return true;

147 }

转载于:https://my.oschina.net/abcijkxyz/blog/723574