[1] 平面(Plane)图形的生成算法
顶点数据的生成
1 bool YfBuildPlaneVertices 2 ( 3 Yreal width, 4 Yreal length, 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 (slices < 2 || stacks < 2 || !pVerticesBuffer) 15 { 16 return false; 17 } 18 19 // 顶点赋值 20 char* vertexPtr = (char*)pVerticesBuffer + vertexPos; 21 YsVector3* curVertexPtr = NULL; 22 Yuint nOffset = 0; 23 24 Yreal xStep = width / slices; 25 Yreal zStep = length / stacks; 26 YsVector3 vOrigin; 27 if (originPose == YE_ORIGIN_POSE_CENTER) 28 { 29 vOrigin.x = -width * 0.5f; 30 vOrigin.z = -length * 0.5f; 31 } 32 33 for (Yuint j = 0; j < stacks; j++) // Z方向 34 { 35 for (Yuint i = 0; i < slices; i++) // X方向 36 { 37 nOffset = (j*slices + i) * vertexStriding; 38 curVertexPtr = (YsVector3*)(vertexPtr + nOffset); 39 curVertexPtr->x = vOrigin.x + i*xStep; 40 curVertexPtr->y = height; 41 curVertexPtr->z = vOrigin.z + j*zStep; 42 } 43 } 44 45 return true; 46 }
三角形索引数据的生成
1 bool YfBuildPlaneTriIndices 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 < 2 || !pTriIndicesBuffer) 12 { 13 return false; 14 } 15 16 Yuint numVertices = slices * stacks; 17 if (indexType == YE_INDEX_16_BIT && 18 numVertices > YD_MAX_UNSIGNED_INT16) 19 { 20 return false; 21 } 22 23 Yuint numTriangles = (slices - 1) * (stacks - 1) * 2; 24 25 char* indexPtr = (char*)pTriIndicesBuffer + indexPos; 26 Yuint nOffset = 0; 27 28 if (indexType == YE_INDEX_16_BIT) 29 { 30 YsTriIndex16* triIndexPtr = NULL; 31 32 for (Yuint j = 0; j < stacks - 1; j++) // Z方向 33 { 34 for (Yuint i = 0; i < slices - 1; i++) // X方向 35 { 36 nOffset = (2 * (j*(slices - 1) + i)) * indexStriding; 37 triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset); 38 triIndexPtr->index0 = j*slices + i; 39 triIndexPtr->index1 = (j + 1)*slices + i + 1; 40 triIndexPtr->index2 = j*slices + i + 1; 41 42 nOffset += indexStriding; 43 triIndexPtr = (YsTriIndex16*)(indexPtr + nOffset); 44 triIndexPtr->index0 = j*slices + i; 45 triIndexPtr->index1 = (j + 1)*slices + i; 46 triIndexPtr->index2 = (j + 1)*slices + i + 1; 47 } 48 } 49 } 50 else 51 { 52 YsTriIndex32* triIndexPtr = NULL; 53 54 for (Yuint j = 0; j < stacks - 1; j++) // Z方向 55 { 56 for (Yuint i = 0; i < slices - 1; i++) // X方向 57 { 58 nOffset = (2 * (j*(slices - 1) + i)) * indexStriding; 59 triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset); 60 triIndexPtr->index0 = j*slices + i; 61 triIndexPtr->index1 = (j + 1)*slices + i + 1; 62 triIndexPtr->index2 = j*slices + i + 1; 63 64 nOffset += indexStriding; 65 triIndexPtr = (YsTriIndex32*)(indexPtr + nOffset); 66 triIndexPtr->index0 = j*slices + i; 67 triIndexPtr->index1 = (j + 1)*slices + i; 68 triIndexPtr->index2 = (j + 1)*slices + i + 1; 69 } 70 } 71 } 72 73 return true; 74 }
线框索引数据的生成
1 bool YfBuildPlaneWireIndices 2 ( 3 Yuint slices, 4 Yuint stacks, 5 YeIndexType indexType, 6 Yuint indexStriding, 7 Yuint indexPos, 8 void* pWireIndicesBuffer 9 ) 10 { 11 if (slices < 2 || stacks < 2 || !pWireIndicesBuffer) 12 { 13 return false; 14 } 15 16 Yuint numVertices = slices * stacks; 17 if (indexType == YE_INDEX_16_BIT && 18 numVertices > YD_MAX_UNSIGNED_INT16) 19 { 20 return false; 21 } 22 23 Yuint numLines = slices * (stacks - 1) +(slices - 1) * stacks; 24 25 char* indexPtr = (char*)pWireIndicesBuffer + indexPos; 26 Yuint nOffset = 0; 27 28 if (indexType == YE_INDEX_16_BIT) 29 { 30 YsLineIndex16* lineIndexPtr = NULL; 31 32 // 行 33 for (Yuint j = 0; j < stacks; j++) 34 { 35 for (Yuint i = 0; i < slices - 1; i++) 36 { 37 nOffset = ((j*(slices - 1) + i)) * indexStriding; 38 lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset); 39 lineIndexPtr->index0 = j*slices + i; 40 lineIndexPtr->index1 = j*slices + i + 1; 41 } 42 } 43 44 // 列 45 Yuint half = (slices - 1) * stacks; 46 for (Yuint i = 0; i < slices; i++) 47 { 48 for (Yuint j = 0; j < stacks - 1; j++) 49 { 50 nOffset = (half + (i*(stacks - 1) + j)) * indexStriding; 51 lineIndexPtr = (YsLineIndex16*)(indexPtr + nOffset); 52 lineIndexPtr->index0 = j*slices + i; 53 lineIndexPtr->index1 = (j + 1)*slices + i; 54 } 55 } 56 } 57 else 58 { 59 YsLineIndex32* lineIndexPtr = NULL; 60 61 // 行 62 for (Yuint j = 0; j < stacks; j++) 63 { 64 for (Yuint i = 0; i < slices - 1; i++) 65 { 66 nOffset = ((j*(slices - 1) + i)) * indexStriding; 67 lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset); 68 lineIndexPtr->index0 = j*slices + i; 69 lineIndexPtr->index1 = j*slices + i + 1; 70 } 71 } 72 73 // 列 74 Yuint half = (slices - 1) * stacks; 75 for (Yuint i = 0; i < slices; i++) 76 { 77 for (Yuint j = 0; j < stacks - 1; j++) 78 { 79 nOffset = (half + (i*(stacks - 1) + j)) * indexStriding; 80 lineIndexPtr = (YsLineIndex32*)(indexPtr + nOffset); 81 lineIndexPtr->index0 = j*slices + i; 82 lineIndexPtr->index1 = (j + 1)*slices + i; 83 } 84 } 85 } 86 87 return true; 88 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?