【开发日志】2022.10.18 ZENO----ray_triangle_intersect

C++时钟获取 

C++计时器(用于计算算法运行时间等)_KiraFenvy的博客-CSDN博客_c++计时器

【c/c++】linux时间获取与时间转换函数总结_shuaixio的博客-CSDN博客_linux c++ 获取系统时间


素材(1611496个三角形的越野车)

3a0997ba125f4440b7c5257b64455c56.png


什么都不开

e8aeacf9ad79480099773732e89d5bcb.png

30000us 


开小彭老师的parallel

71e070a0d3b54426b5b5c23246e50f64.png

static std::optional<float> ray_triangle_intersect(
    zeno::PrimitiveObject *prim,
    zeno::vec3f const &ray_pos,
    zeno::vec3f const &ray_dir
) {
    auto &tris = prim->tris;
    auto &verts = prim->verts;
    auto &pos = ray_pos;
    auto &dir = ray_dir;
    std::optional<float> res = std::nullopt;
    std::mutex mtx;
    int tribase = prim->tris.size();
    bool is_poly = prim->polys.size() > 0;
    if (is_poly) {
        std::vector<int> scansum(prim->polys.size());

        auto redsum = zeno::parallel_exclusive_scan_sum(prim->polys.begin(), prim->polys.end(),
        scansum.begin(), [&] (auto &ind) {
            return ind[1] >= 3 ? ind[1] - 2 : 0;
        });
        prim->tris.resize(tribase + redsum);
        for(int i = 0;i < prim->polys.size();i++){
            auto [start, len] = prim->polys[i];
            if (len >= 3) {
                int scanbase = scansum[i] + tribase;
                prim->tris[scanbase++] = zeno::vec3f(prim->loops[start], prim->loops[start + 1], prim->loops[start + 2]);
                for (int j = 3; j < len; j++) {
                    prim->tris[scanbase++] =
                        zeno::vec3f(prim->loops[start], prim->loops[start + j - 1], prim->loops[start + j]);
                }
            }
        }
    }

    zeno::parallel_for((size_t)0, prim->tris.size(), [&](size_t i){
        auto nor = zeno::cross(verts[tris[i][1]]- verts[tris[i][0]], verts[tris[i][2]] - verts[tris[i][0]]);
        auto normal = nor * (1.0f / zeno::dot(nor, nor));

        auto distance = zeno::dot(normal, verts[tris[i][0]]);

        float nd = zeno::dot(dir, normal);
        float pn = zeno::dot(pos, normal);

        float t = (distance - pn) / nd;

        if (t >= 0.0f) {
            auto p = pos + dir * t; //p:ray在三角形所在平面上的投影

            auto ap = p - verts[tris[i][0]];
            auto bp = p - verts[tris[i][1]];
            auto cp = p - verts[tris[i][2]];

            zeno::vec3f ab = verts[tris[i][1]] - verts[tris[i][0]];
            zeno::vec3f ac = verts[tris[i][2]] - verts[tris[i][0]];
            zeno::vec3f bc = verts[tris[i][2]] - verts[tris[i][1]];
            zeno::vec3f cb = verts[tris[i][1]] - verts[tris[i][2]];
            zeno::vec3f ca = verts[tris[i][0]] - verts[tris[i][2]];

            zeno::vec3f v = ab - Project(ab, cb);
            float a = 1.0f - (zeno::dot(v, ap) / zeno::dot(v, ab));

            v = bc - Project(bc, ac);
            float b = 1.0f - (zeno::dot(v, bp) / zeno::dot(v, bc));

            v = ca - Project(ca, ab);
            float c = 1.0f - (zeno::dot(v, cp) / zeno::dot(v, ca));

            if (a >= 0.0f && a <= 1.0f && b >= 0.0f && b <= 1.0f && c >= 0.0f && c <= 1.0f) {
                std::lock_guard<std::mutex> _(mtx);
                if (res.has_value()) {
                    float v = res.value();
                    if (t < v) {
                        res = t;
                    }
                } else {
                    res = t;
                }
            }
        }
    });
    if (is_poly) {
        prim->tris.resize(tribase);
    }
    return res;
}
if (zeno::objectGetBoundingBox(ptr, bmin, bmax) ){
    if (auto ret = ray_box_intersect(bmin, bmax, ro, rd)) {
        if (ret.has_value() && ret.value() > min_t) {
            continue;
        }
        if (auto prim = dynamic_cast<zeno::PrimitiveObject*>(ptr)) {
            if (prim->tris.size() == 0 && prim->polys.size() == 0) {
                min_t = ret.value();
                name = key;
                continue;
            }
            auto start = std::chrono::steady_clock::now();
            if(auto rett = ray_triangle_intersect(prim,ro,rd)) {
                float t = *rett;
                if (t < min_t) {
                    min_t = t;
                    name = key;
                }
            }
            std::chrono::duration<double> diff = std::chrono::steady_clock::now()-start;
            auto us = std::chrono::duration_cast<std::chrono::microseconds>(diff).count();
            zeno::log_info("diff:{} us", us);
        }
    }
}

69d96338c9e7466a8c8c4d3590f40018.png

 5000us


开tbb 

d6dab9fef189414190e44ff894725083.png

static std::optional<float> ray_triangle_intersect(
    zeno::PrimitiveObject *prim,
    zeno::vec3f const &ray_pos,
    zeno::vec3f const &ray_dir
) {
    auto &tris = prim->tris;
    auto &verts = prim->verts;
    auto &pos = ray_pos;
    auto &dir = ray_dir;
    tbb::concurrent_vector<float> ts;

    tbb::parallel_for(tbb::blocked_range<size_t>(0, prim->tris.size()),
    [&](tbb::blocked_range<size_t> r) {
    for (size_t i = r.begin(); i < r.end(); i++) {
        auto nor = zeno::cross(verts[tris[i][1]]- verts[tris[i][0]], verts[tris[i][2]] - verts[tris[i][0]]);
        auto normal = nor * (1.0f / zeno::dot(nor, nor));

        auto distance = zeno::dot(normal, verts[tris[i][0]]);

        float nd = zeno::dot(dir, normal);
        float pn = zeno::dot(pos, normal);

        float t = (distance - pn) / nd;

        if (t >= 0.0f) {
            auto p = pos + dir * t; //p:ray在三角形所在平面上的投影

            auto ap = p - verts[tris[i][0]];
            auto bp = p - verts[tris[i][1]];
            auto cp = p - verts[tris[i][2]];

            zeno::vec3f ab = verts[tris[i][1]] - verts[tris[i][0]];
            zeno::vec3f ac = verts[tris[i][2]] - verts[tris[i][0]];
            zeno::vec3f bc = verts[tris[i][2]] - verts[tris[i][1]];
            zeno::vec3f cb = verts[tris[i][1]] - verts[tris[i][2]];
            zeno::vec3f ca = verts[tris[i][0]] - verts[tris[i][2]];

            zeno::vec3f v = ab - Project(ab, cb);
            float a = 1.0f - (zeno::dot(v, ap) / zeno::dot(v, ab));

            v = bc - Project(bc, ac);
            float b = 1.0f - (zeno::dot(v, bp) / zeno::dot(v, bc));

            v = ca - Project(ca, ab);
            float c = 1.0f - (zeno::dot(v, cp) / zeno::dot(v, ca));

            if (a >= 0.0f && a <= 1.0f && b >= 0.0f && b <= 1.0f && c >= 0.0f && c <= 1.0f) {
                ts.push_back(t);
            }
        }
    }
    });
    if (ts.empty()) {
        return std::nullopt;
    } else {
        float min_t = ts[0];
        for (auto t: ts) {
            if (t < min_t) {
                min_t = t;
            }
        }
        return min_t;
    }
}
if (zeno::objectGetBoundingBox(ptr, bmin, bmax) ){
    if (auto ret = ray_box_intersect(bmin, bmax, ro, rd)) {
        if (ret.has_value() && ret.value() > min_t) {
            continue;
        }
        auto start = std::chrono::steady_clock::now();
        if (auto prim = dynamic_cast<zeno::PrimitiveObject*>(ptr)) {
            if(auto rett = ray_triangle_intersect(prim,ro,rd)) {
                float t = *rett;
                if (t < min_t) {
                    min_t = t;
                    name = key;
                }
            }
        }
        std::chrono::duration<double> diff = std::chrono::steady_clock::now()-start;
        auto ms = std::chrono::duration_cast<std::chrono::microseconds>(diff).count();
        zeno::log_info("diff:{} ms", ms);
    }
}

4219c96cddbd42d7af960f3d1f8213c6.png

(这里us打成ms了,应该是3000us)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值