C++时钟获取
C++计时器(用于计算算法运行时间等)_KiraFenvy的博客-CSDN博客_c++计时器
【c/c++】linux时间获取与时间转换函数总结_shuaixio的博客-CSDN博客_linux c++ 获取系统时间
素材(1611496个三角形的越野车)
什么都不开
30000us
开小彭老师的parallel
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);
}
}
}
5000us
开tbb
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);
}
}
(这里us打成ms了,应该是3000us)