从源头看Dust3d | (六)material

2021SC@SDUSC

Snapshot

1.Snapshot.h

class Snapshot
{
public:
    std::map<QString, QString> canvas;
    std::map<QString, std::map<QString, QString>> nodes;
    std::map<QString, std::map<QString, QString>> edges;
    std::map<QString, std::map<QString, QString>> parts;
    std::map<QString, std::map<QString, QString>> components;
    std::map<QString, QString> rootComponent;
    std::map<QString, std::map<QString, QString>> motions;
    std::vector<std::pair<std::map<QString, QString>, std::vector<std::pair<std::map<QString, QString>, std::vector<std::map<QString, QString>>>>>> materials; // std::pair<Material attributes, layers>  layer: std::pair<Layer attributes, maps>

    void resolveBoundingBox(QRectF *mainProfile, QRectF *sideProfile, const QString &partId=QString()) const;
};

     Snapshot类中包含8个公有变量,一个公有函数。snapshot表示一张快照,Dust3d需要从快照中提取出信息,在三维空间中进行还原。

2.Snapshot.cpp

     Snapshot.cpp实现的是通过快照中每个节点的位置信息和半径,来形成包围盒足以在三维世界中容纳快照中的物体。

     快照中需要包含每个节点的位置信息和大小信息(半径)

void Snapshot::resolveBoundingBox(QRectF *mainProfile, QRectF *sideProfile, const QString &partId) const
{
    float left = 0;
    bool leftFirstTime = true;
    float right = 0;
    bool rightFirstTime = true;
    float top = 0;
    bool topFirstTime = true;
    float bottom = 0;
    bool bottomFirstTime = true;
    float zLeft = 0;
    bool zLeftFirstTime = true;
    float zRight = 0;
    bool zRightFirstTime = true;
    //nodes:map中的节点
    for (const auto &nodeIt: nodes) {
        if (!partId.isEmpty() && partId != valueOfKeyInMapOrEmpty(nodeIt.second, "partId"))
        //如果partId为空或不在快照中
            continue;
        float radius = valueOfKeyInMapOrEmpty(nodeIt.second, "radius").toFloat();
        float x = valueOfKeyInMapOrEmpty(nodeIt.second, "x").toFloat();
        float y = valueOfKeyInMapOrEmpty(nodeIt.second, "y").toFloat();
        float z = valueOfKeyInMapOrEmpty(nodeIt.second, "z").toFloat();
/*util.cpp
         QString valueOfKeyInMapOrEmpty(const std::map<QString, QString> &map, const QString &key)
{
    auto it = map.find(key);
    if (it == map.end())
        return QString();
    return it->second;
} 
*/
        if (leftFirstTime || x - radius < left) {
            //第一次向左或者x-radius出了left的边界
            //把左边界进行拓展
            left = x - radius;
            leftFirstTime = false;
        }
        if (topFirstTime || y - radius < top) {
            //同理拓展上边界
            top = y - radius;
            topFirstTime = false;
        }
        if (rightFirstTime || x + radius > right) {
            //拓展右边界
            right = x + radius;
            rightFirstTime = false;
        }
        if (bottomFirstTime || y + radius > bottom) {
            //拓展下边界
            bottom = y + radius;
            bottomFirstTime = false;
        }
        if (zLeftFirstTime || z - radius < zLeft) {
            //拓展前边界
            zLeft = z - radius;
            zLeftFirstTime = false;
        }
        if (zRightFirstTime || z + radius > zRight) {
            //拓展后边界
            zRight = z + radius;
            zRightFirstTime = false;
        }
    }
    *mainProfile = QRectF(QPointF(left, top), QPointF(right, bottom));
    *sideProfile = QRectF(QPointF(zLeft, top), QPointF(zRight, bottom));
    //还原包围盒的大小,能够容纳快照中的节点
}

Material 材质 

1.material.h

     material.h中包含:

          (1)结构体MaterialTextures,结构体中含有QImage类的指针

          (2)函数initializeMaterialTexturesFromSnapshot,在material.cpp中进行详细说明

struct MaterialTextures
{
    const QImage *textureImages[(int)TextureType::Count - 1] = {nullptr};
};

void initializeMaterialTexturesFromSnapshot(const Snapshot &snapshot,
    const QUuid &materialId,
    MaterialTextures &materialTextures,
    float &tileScale);

#endif

2.material.cpp

     主要介绍了函数 initializeMaterialTexturesFromSnapshot

输入结果
快照snapshot函数无返回值,函数运行结束后可以使

materialTextures.textureImages中的image与imageId一一对应

材质的序号materialId
纹理materialTextures
材质块的大小tileScale
void initializeMaterialTexturesFromSnapshot(const Snapshot &snapshot,
    const QUuid &materialId,
    MaterialTextures &materialTextures,
    float &tileScale)
{
    QString materialIdString = materialId.toString();
    for (const auto &materialItem: snapshot.materials) {
        if (materialIdString != valueOfKeyInMapOrEmpty(materialItem.first, "id"))
            continue;
        //找到materialId所对应的material
        for (const auto &layer: materialItem.second) 
        {
            //FIXME: Only support one layer currently
            auto findTileScale = layer.first.find("tileScale");
            if (findTileScale != layer.first.end())
            //如果找到了tileScale
                tileScale = findTileScale->second.toFloat();
            for (const auto &mapItem: layer.second) 
            {
                auto textureType = TextureTypeFromString(valueOfKeyInMapOrEmpty(mapItem, "for").toUtf8().constData());
                if (textureType != TextureType::None) 
                {
                    int index = (int)textureType - 1;
                    if (index >= 0 && index < (int)TextureType::Count - 1)
                     {
                        if ("imageId" == valueOfKeyInMapOrEmpty(mapItem, "linkDataType")) 
                        {
                            auto imageIdString = valueOfKeyInMapOrEmpty(mapItem, "linkData");
                            materialTextures.textureImages[index] = ImageForever::get(QUuid(imageIdString));
                            //得到所对应的image

                        }
                    }
                }
            }
            break;
        }
        break;
    }
}

      函数内部涉及的ImageForever::get函数:通过id找到对应的image

const QImage *ImageForever::get(const QUuid &id)
{
    QMutexLocker locker(&g_mapMutex);
    auto findResult = g_foreverMap.find(id);
    if (findResult == g_foreverMap.end())
        return nullptr;
    return findResult->second.image;
} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值