从源头看Dust3d | (四)Boundingboxmesh包围盒网格结构

2021SC@SDUSC

1.buildBoundingBoxMeshEdges函数

   此函数根据输入的元素为元组的容器boxes的引用以及指针edgeVerticesNum来生成构建包围盒网格结构的边顶点信息。

//包围盒网格结构
ShaderVertex *buildBoundingBoxMeshEdges(const std::vector<std::tuple<QVector3D, QVector3D, float, float, QColor>> &boxes,
        int *edgeVerticesNum)
{
    //tuple为元组,boxes是元素为元组的容器
    int numPerItem = 12 * 2;
    //包围盒有12条边,一条边关联着两个顶点
    *edgeVerticesNum = boxes.size() * numPerItem;
    
    auto generateForBox = [&](const std::tuple<QVector3D, QVector3D, float, float, QColor> &box, ShaderVertex *vertices) {
        const auto &headPosition = std::get<0>(box);
        const auto &tailPosition = std::get<1>(box);
        float headRadius = std::get<2>(box);
        float tailRadius = std::get<3>(box);
        const auto &color = std::get<4>(box);
        //元组中元素分别代表头节点、尾节点位置,头节点半径,尾节点半径以及颜色
        QVector3D direction = tailPosition - headPosition;
        QVector3D cutNormal = direction.normalized();
        QVector3D baseNormal = choosenBaseAxis(cutNormal);
        //util.cpp,baseNormal是与cutNormal最近似垂直的坐标
        QVector3D u = QVector3D::crossProduct(cutNormal, baseNormal).normalized();
        //u、cutNormal、baseNormal相互垂直
        QVector3D v = QVector3D::crossProduct(u, cutNormal).normalized();
        //u、v、cutNormal相互垂直
        auto uHeadFactor = u * headRadius;
        auto vHeadFactor = v * headRadius;
        auto uTailFactor = u * tailRadius;
        auto vTailFactor = v * tailRadius;
        const std::vector<QVector2D> cutFaceTemplate = {QVector2D((float)-1.0, (float)-1.0),
            QVector2D((float)1.0, (float)-1.0),
            QVector2D((float)1.0,  (float)1.0),
            QVector2D((float)-1.0,  (float)1.0)
        };
        std::vector<QVector3D> resultHeadCut;
        for (const auto &t: cutFaceTemplate) {
            resultHeadCut.push_back(uHeadFactor * t.x() + vHeadFactor * t.y());
        }
        std::vector<QVector3D> resultTailCut;
        for (const auto &t: cutFaceTemplate) {
            resultTailCut.push_back(uTailFactor * t.x() + vTailFactor * t.y());
        }
        //各延伸出四个方向
        std::vector<QVector3D> headRing;
        std::vector<QVector3D> tailRing;
        std::vector<QVector3D> finalizedPoints;
        for (const auto &it: resultHeadCut) {
            headRing.push_back(it + headPosition);
        }
        for (const auto &it: resultTailCut) {
            tailRing.push_back(it + tailPosition);
        }
        //以头节点和尾节点为中心延伸四个方向
        for (size_t i = 0; i < headRing.size(); ++i) {
            finalizedPoints.push_back(headRing[i]);
            finalizedPoints.push_back(headRing[(i + 1) % headRing.size()]);
        }
        for (size_t i = 0; i < tailRing.size(); ++i) {
            finalizedPoints.push_back(tailRing[i]);
            finalizedPoints.push_back(tailRing[(i + 1) % tailRing.size()]);
        }
        for (size_t i = 0; i < headRing.size(); ++i) {
            finalizedPoints.push_back(headRing[i]);
            finalizedPoints.push_back(tailRing[i]);
        }
        //向finalizedPoints中添加网格信息
        for (size_t i = 0; i < finalizedPoints.size(); ++i) {
            const auto &sourcePosition = finalizedPoints[i];
            ShaderVertex &currentVertex = vertices[i];
            currentVertex.posX = sourcePosition.x();
            currentVertex.posY = sourcePosition.y();
            currentVertex.posZ = sourcePosition.z();
            currentVertex.texU = 0;
            currentVertex.texV = 0;
            currentVertex.colorR = color.redF();
            currentVertex.colorG = color.greenF();
            currentVertex.colorB = color.blueF();
            currentVertex.normX = 0;
            currentVertex.normY = 1;
            currentVertex.normZ = 0;
            currentVertex.metalness = Model::m_defaultMetalness;
            currentVertex.roughness = Model::m_defaultRoughness;
            currentVertex.tangentX = 0;
            currentVertex.tangentY = 0;
            currentVertex.tangentZ = 0;
        }
        //为currentVertex加入坐标、uv、颜色、法向等信息
    };
    
    ShaderVertex *edgeVertices = new ShaderVertex[*edgeVerticesNum];
    int vertexIndex = 0;
    for (const auto &box: boxes) {
        generateForBox(box, &edgeVertices[vertexIndex]);
        vertexIndex += numPerItem;
    }
    //将包围盒中的信息整合在一起
    *edgeVerticesNum = vertexIndex;
    
    return edgeVertices;
}

  

 

       函数中使用到了util.cpp中的choosenBaseAxis函数,此函数的作用是返回x、y、z轴中与输入向量最接近垂直的轴向。具体如下:

QVector3D choosenBaseAxis(const QVector3D &layoutDirection)
{
    const std::vector<QVector3D> axisList = {
        QVector3D(1, 0, 0),
        QVector3D(0, 1, 0),
        QVector3D(0, 0, 1),
    };
    std::vector<std::pair<float, size_t>> dots;
    for (size_t i = 0; i < axisList.size(); ++i) {
        dots.push_back(std::make_pair(qAbs(QVector3D::dotProduct(layoutDirection, axisList[i])), i));
    }
    //求layoutDirection在各坐标轴的分量,存到dots中
    return axisList[std::min_element(dots.begin(), dots.end(), [](const std::pair<float, size_t> &first,
            const std::pair<float, size_t> &second) {
        return first.first < second.first;
    })->second];
    //返回layoutDirection分量最小的坐标轴(与其最垂直)
}

      函数的返回值类型为ShaderVertex结构的指针,便于之后与渲染管线进行交互,关于ShaderVertex结构体的介绍如下:

typedef struct
{
    GLfloat posX;
    GLfloat posY;
    GLfloat posZ;
    GLfloat normX;
    GLfloat normY;
    GLfloat normZ;
    GLfloat colorR;
    GLfloat colorG;
    GLfloat colorB;
    GLfloat texU;
    GLfloat texV;
    GLfloat metalness;
    GLfloat roughness;
    GLfloat tangentX;
    GLfloat tangentY;
    GLfloat tangentZ;
    GLfloat alpha = 1.0;
} ShaderVertex;
结构体ShaderVertex
位置信息posX、posY、posZ
法线信息normX、normY、normZ
颜色信息colorR、colorG、colorB、透明度alpha
贴图信息texU、texV
材质信息metalness、roughness
切线信息tangentX、tangentY、tangentZ

 

2.buildBoundingBoxMesh函数

      此函数使用了上述buildBoundingBoxMeshEdges函数对包围盒的网格结构进行了构造,然后通过model.h的构造函数:

Model(ShaderVertex *triangleVertices, int vertexNum, ShaderVertex *edgeVertices=nullptr, int edgeVertexCount=0);

对网格进行了构造

Model *buildBoundingBoxMesh(const std::vector<std::tuple<QVector3D, QVector3D, float, float, QColor>> &boxes)
{
    int edgeVerticesNum = 0;
    ShaderVertex *edgeVertices = buildBoundingBoxMeshEdges(boxes, &edgeVerticesNum);
    return new Model(nullptr, 0, edgeVertices, edgeVerticesNum);
}

关于model.h的详情介绍可关注:Dust3D项目实训3_10.17_Starrismup的博客-CSDN博客2021SC@SDUSC目录分析概括model.h分析三维模型构造三角面的结构体模型类model.cpp分析分析概括基于上周分析的object类的基础上,本周继续进行modle模块的分析,主要分析modle.h与modle.cpp。model.h分析三维模型构造三角面的结构体struct TriangulatedFace{//结构体:三角面 int indices[3];//三位索引 QColor color;//颜色};模型..https://blog.csdn.net/Starrismup/article/details/120817901?spm=1001.2014.3001.5501

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值