zoukankan      html  css  js  c++  java
  • [6] 胶囊体(Capsule)图形的生成算法

     

    顶点数据的生成

     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 }


     

  • 相关阅读:
    技术人员如何创业《四》- 打造超强执行力团队(转载)
    技术人员如何创业《一》—— 产品及想法(转载)
    一页纸商业计划书 (Business Plan) 模板(转载)
    公司项目架构的演变过程
    腾讯云CentOS 6.6安装 Nginx
    创业公司一年工作总结
    启动tomcat时 错误: 代理抛出异常 : java.rmi.server.ExportException: Port already in use: 1099的解决办法
    windows下使用批处理脚本实现多个版本的JDK切换
    Java后端WebSocket的Tomcat实现
    微信开发学习总结(三)——开发微信公众号的最基本功能——普通消息的接收和回复
  • 原文地址:https://www.cnblogs.com/WhyEngine/p/3415241.html
Copyright © 2011-2022 走看看