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:
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;