star-3d

Surface structuring for efficient 3D geometric queries
git clone git://git.meso-star.fr/star-3d.git
Log | Files | Refs | README | LICENSE

commit bdc9d040617eb14b891abfb5b2816a1f8cc70236
parent af4bd70e24d11df5c83fb85bc0612a382ff405b4
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Thu, 18 Jan 2018 15:09:33 +0100

Setup the sphere "uv" on ray intersection

Diffstat:
Msrc/s3d_geometry.c | 23+++++++++++++++++++----
Msrc/s3d_scene_view.c | 39+++++++++++++++++++++------------------
2 files changed, 40 insertions(+), 22 deletions(-)

diff --git a/src/s3d_geometry.c b/src/s3d_geometry.c @@ -138,6 +138,7 @@ void geometry_rtc_sphere_intersect(void* data, RTCRay& ray, size_t item) { float v[3]; + float cos_theta; float A, B, C, D, Q, rcpA, t0, t1; struct geometry* geom = (struct geometry*)data; struct sphere sphere; @@ -157,8 +158,6 @@ geometry_rtc_sphere_intersect(void* data, RTCRay& ray, size_t item) t1 = 0.5f * rcpA * (-B + Q); if(ray.tnear < t0 && t0 < ray.tfar) { - ray.u = 0.0f; /* TODO */ - ray.v = 0.0f; /* TODO */ ray.tfar = t0; ray.geomID = geom->irtc; ray.primID = (unsigned)item; @@ -167,8 +166,6 @@ geometry_rtc_sphere_intersect(void* data, RTCRay& ray, size_t item) f3_sub(ray.Ng, ray.Ng, sphere.pos); } if(ray.tnear < t1 && t1 < ray.tfar) { - ray.u = 0.0f; /* TODO */ - ray.v = 0.0f; /* TODO */ ray.tfar = t1; ray.geomID = geom->irtc; ray.primID = (unsigned) item; @@ -176,6 +173,24 @@ geometry_rtc_sphere_intersect(void* data, RTCRay& ray, size_t item) f3_add(ray.Ng, ray.Ng, ray.org); f3_sub(ray.Ng, ray.Ng, sphere.pos); } + + /* Compute the parametric coordinate */ + f3_normalize(ray.Ng, ray.Ng); + cos_theta = ray.Ng[2]; + ray.v = (1.f - cos_theta) * 0.5f; + if(absf(cos_theta) == 1) { + ray.u = 0; + } else if(eq_epsf(ray.Ng[0], 0.f, 1.e-6f)) { + ray.u = ray.Ng[1] > 0 ? 0.25f : 0.75f; + } else { + double phi = atan(ray.Ng[1] / ray.Ng[0]); + if(ray.Ng[0] < 0) { + phi = phi + PI; + } else if(ray.Ng[1] < 0) { + phi = 2*PI + phi; + } + ray.u = (float)(phi / (2*PI)); + } } void diff --git a/src/s3d_scene_view.c b/src/s3d_scene_view.c @@ -140,23 +140,6 @@ hit_setup(struct s3d_scene_view* scnview, const RTCRay* ray, struct s3d_hit* hit f3_set(hit->normal, ray->Ng); hit->distance = ray->tfar; - hit->uv[0] = ray->u; - hit->uv[1] = ray->v; - w = 1.f - hit->uv[0] - hit->uv[1]; - ASSERT(w <= 1.f); /* This may not occurs */ - if(w < 0.f) { /* Handle precision error */ - if(hit->uv[0] > hit->uv[1]) hit->uv[0] += w; - else hit->uv[1] += w; - w = 0.f; - } - - /* Embree stores on the u and v ray parameters the barycentric coordinates of - * the hit with respect to the second and third triangle vertices, - * respectively. The following code computes the barycentric coordinates of - * the hit for the first and second triangle vertices */ - hit->uv[1] = hit->uv[0]; - hit->uv[0] = w; - if((unsigned)ray->instID == RTC_INVALID_GEOMETRY_ID) { struct geometry* geom_shape; ASSERT((unsigned)ray->geomID < darray_geom_size_get(&scnview->embree2geoms)); @@ -201,6 +184,27 @@ hit_setup(struct s3d_scene_view* scnview, const RTCRay* ray, struct s3d_hit* hit ASSERT(((struct geometry*)hit->prim.shape__)->type == GEOM_MESH ||((struct geometry*)hit->prim.shape__)->type == GEOM_SPHERE); + + hit->uv[0] = ray->u; + hit->uv[1] = ray->v; + + if(((struct geometry*)hit->prim.shape__)->type == GEOM_MESH) { + w = 1.f - hit->uv[0] - hit->uv[1]; + ASSERT(w <= 1.f); /* This may not occurs */ + if(w < 0.f) { /* Handle precision error */ + if(hit->uv[0] > hit->uv[1]) hit->uv[0] += w; + else hit->uv[1] += w; + w = 0.f; + } + + /* Embree stores on the u and v ray parameters the barycentric coordinates of + * the hit with respect to the second and third triangle vertices, + * respectively. The following code computes the barycentric coordinates of + * the hit for the first and second triangle vertices */ + hit->uv[1] = hit->uv[0]; + hit->uv[0] = w; + } + /* Flip geometric normal with respect to the flip surface flag */ flip_surface ^= ((struct geometry*)hit->prim.shape__)->flip_surface; if(flip_surface) f3_minus(hit->normal, hit->normal); @@ -1284,7 +1288,6 @@ s3d_scene_view_sample ASSERT(pgeom); geom = *pgeom; } - ASSERT(geom->type == GEOM_MESH); /* Find the sampled primitive */ primitive->shape__ = geom;