Closed blackccpie closed 5 years ago
If you don't need precise visibility, things are rather easy to implement.
You can shoot rays as in ordinal ray tracing with orthographic or perspective camera, then mark the visibility for hit surface(face ID and vertex ID can be looked up using Trianglntersection::prim_id
)
If you need precise visibility for a given camera pose, you need to implement something like this: https://www.cg.tuwien.ac.at/research/publications/2006/WONKA-2006-GVS/
or for more general situation: http://jcgt.org/published/0003/04/02/
@syoyo : thanks for these pointers, I'll have a look, and maybe get back to you if I still don't make it.
Regards
Hi @syoyo, I tried implementing your first solution (I don't need precise visibility), by casting rays to each triangle centroid on the target mesh. At first rays origin was set to the origin of the coordinate frame, and the result seemed consistent. But then I tried to set the rays origin elsewhere, and I started to have a lot of rays not hitting any face, which should not happen by design if the rays are oriented to target triangle centroids. I tried to reproduce the problem in a small sample code targetting only one of my mesh's triangle:
std::vector<float3> vertices = {
{ -0.0211979f, 0.1272f, 0.00915278f },
{ -0.0144471f, 0.128935f, 0.00903509f },
{ -0.0143059f, 0.128197f, 0.00333856f }
};
uint3 face = { 0, 1, 2 };
float3 face_center = { vertices[0].x + vertices[1].x + vertices[2].x / 3.f,
vertices[0].y + vertices[1].y + vertices[2].y / 3.f,
vertices[0].z + vertices[1].z + vertices[2].z / 3.f };
nanort::BVHBuildOptions<float> options;
nanort::TriangleMesh<float> triangle_mesh( reinterpret_cast<float*>( vertices.data() ), reinterpret_cast<uint32_t*>( &face ), /* stride */sizeof(float) * 3 );
nanort::TriangleSAHPred<float> triangle_pred( reinterpret_cast<float*>( vertices.data() ), reinterpret_cast<uint32_t*>( &face ), /* stride */sizeof(float) * 3 );
nanort::BVHAccel<float> accel;
auto ret = accel.Build( 1, triangle_mesh, triangle_pred, options );
assert(ret);
nanort::BVHTraceOptions trace_options;
nanort::TriangleIntersection<float> isect;
nanort::TriangleIntersector<> triangle_intersector( reinterpret_cast<float*>( vertices.data() ),
reinterpret_cast<uint32_t*>( &face ),
/* stride */sizeof(float) * 3 );
float3 cam_pos = { 0.f, 0.f, 0.f };
nanort::Ray<float> ray;
const float far = 1.e+30f;
ray.min_t = 0.f;
ray.max_t = far;
ray.org[0] = cam_pos.x;
ray.org[1] = cam_pos.y;
ray.org[2] = cam_pos.z;
float3 dir;
dir[0] = face_center.x - cam_pos.x;
dir[1] = face_center.y - cam_pos.y;
dir[2] = face_center.z - cam_pos.z;
dir.normalize();
ray.dir[0] = dir[0];
ray.dir[1] = dir[1];
ray.dir[2] = dir[2];
auto hit = accel.Traverse( ray, triangle_intersector, &isect, trace_options );
if( hit )
{
std::cout << "hit!" << std::endl;
}
else
{
std::cout << "no hit!" << std::endl;
}
If I execute this code, the face is hit, but if a set the camera pos to { 0.f, 0.f, 0.5f }
for example, then I've got no hit.
Could you help me finding out what I'm doing wrong?
Thx for your help
You need parenthesis to compute face center.
float3 face_center = { (vertices[0].x + vertices[1].x + vertices[2].x) / 3.f,
(vertices[0].y + vertices[1].y + vertices[2].y) / 3.f,
(vertices[0].z + vertices[1].z + vertices[2].z) / 3.f };
@syoyo : my mistake, thanks for the hint, now that works nicely.
Regards
Hi,
I'm looking for a lightweight library to compute visible vertices of a 3D model given camera pose. Sorry if my question may seem obvious, but I'm wondering if nanort is the right tool for that purpose, and if there are useful sample codes I can have a look at?
Thanks for your help,
Albert