/// <summary> /// Intersects the ray, if intersection is closer than the one inside the record, /// sets the records with intersection information. /// </summary> /// <param name="ray"></param> /// <param name="record"></param> /// <returns></returns> public override bool Intersect(Ray ray, IntersectionRecord record) { float dist = 0f; Vector3 hitPt, n; n = mNormal; // because ray/plane intersection may flip the normal! if (!RayPlaneIntersection(ray, ref n, mD, ref dist)) { return(false); } /* * rectangle behind the ray or there are other closer intersections */ if ((dist < 0) || (dist > record.HitDistance)) { return(false); } hitPt = ray.Origin + (ray.Direction * dist); /* * Now need to decide inside or outside */ if (!InsidePolygon(hitPt)) { return(false); } record.UpdateRecord(dist, hitPt, n, ray, mMaterialIndex, GetResourceIndex()); return(true); }
/// <summary> /// Intersects the ray with the sphere. If intersection is closer than what is /// in the record, updates the record with new intersection information. /// </summary> /// <param name="ray"></param> /// <param name="record"></param> /// <returns></returns> public override bool Intersect(Ray ray, IntersectionRecord record) { Vector3 v1 = ray.Origin - mCenter; float b = 2f * Vector3.Dot(v1, ray.Direction); float c = v1.LengthSquared() - mRadiusSquared; float root = b * b - 4 * c; if (root < 0f) { return(false); } root = (float)Math.Sqrt(root); float t0 = 0.5f * (-b - root); float t1 = 0.5f * (-b + root); if ((t0 < 0) && (t1 < 0)) { return(false); } float dist; if (t0 < t1) { if (t0 > 0) { dist = t0; } else { dist = t1; } } else { if (t1 > 0) { dist = t1; } else { dist = t0; } } if (dist > record.HitDistance) { return(false); } // intersection found Vector3 pt = ray.Origin + dist * ray.Direction; Vector3 n = pt - mCenter; record.UpdateRecord(dist, pt, n, ray, mMaterialIndex, GetResourceIndex()); return(true); }
/// <summary> /// Intersects the ray, if intersection is closer than the one inside the record, /// sets the records with intersection information. /// </summary> /// <param name="ray"></param> /// <param name="record"></param> /// <returns></returns> public override bool Intersect(Ray ray, IntersectionRecord record) { float dist = 0f; Vector3 hitPt, n; n = mNormal; if (!RayPlaneIntersection(ray, ref n, mD, ref dist)) { return(false); } /* * rectangle behind the ray or there are other closer intersections */ if ((dist < 0) || (dist > record.HitDistance)) { return(false); } hitPt = ray.Origin + (ray.Direction * dist); /* * Now need to decide inside or outside */ float u, v, w; Vector3 v1 = mVertices[1] - hitPt; Vector3 v2 = mVertices[2] - hitPt; float areaPV1V2 = Vector3.Dot(mNormal, Vector3.Cross(v1, v2)); u = areaPV1V2 * mInvArea2; if ((u < 0f) || (u > 1f)) { return(false); } v1 = mVertices[0] - hitPt; float areaPV0V2 = Vector3.Dot(mNormal, Vector3.Cross(v2, v1)); v = areaPV0V2 * mInvArea2; if ((v < 0f) || (v > 1f)) { return(false); } w = 1 - u - v; if (w < 0f) { return(false); } /* * An actual hit */ record.UpdateBC(u, v, w); // now if we have per-vertex normal, use it! if (null != mNormalAtVertices) { n = u * mNormalAtVertices[0] + v * mNormalAtVertices[1] + w * mNormalAtVertices[2]; } // flip the normal if seeing the back face if (Vector3.Dot(n, ray.Direction) > 0f) { n = -n; } record.UpdateRecord(dist, hitPt, n, ray, mMaterialIndex, GetResourceIndex()); return(true); }
/// <summary> /// Intersects the ray, if intersection is closer than the one inside the record, /// sets the records with intersection information. /// </summary> /// <param name="ray"></param> /// <param name="record"></param> /// <returns></returns> public override bool Intersect(Ray ray, IntersectionRecord record) { float dist = 0f; Vector3 hitPt, n; n = mNormal; if (!RayPlaneIntersection(ray, ref n, mD, ref dist)) return false; /* * rectangle behind the ray or there are other closer intersections */ if ((dist < 0) || (dist > record.HitDistance)) return false; hitPt = ray.Origin + (ray.Direction * dist); /* * Now need to decide inside or outside */ float u, v, w; Vector3 v1 = mVertices[1] - hitPt; Vector3 v2 = mVertices[2] - hitPt; float areaPV1V2 = Vector3.Dot(mNormal, Vector3.Cross(v1, v2)); u = areaPV1V2 * mInvArea2; if ((u < 0f) || (u > 1f)) return false; v1 = mVertices[0] - hitPt; float areaPV0V2 = Vector3.Dot(mNormal, Vector3.Cross(v2, v1)); v = areaPV0V2 * mInvArea2; if ((v<0f) || (v>1f)) return false; w = 1 - u - v; if (w<0f) return false; /* * An actual hit */ record.UpdateBC(u, v, w); // now if we have per-vertex normal, use it! if (null != mNormalAtVertices) n = u * mNormalAtVertices[0] + v * mNormalAtVertices[1] + w * mNormalAtVertices[2]; // flip the normal if seeing the back face if (Vector3.Dot(n, ray.Direction) > 0f) n = -n; record.UpdateRecord(dist, hitPt, n, ray, mMaterialIndex, GetResourceIndex()); return true; }
/// <summary> /// Intersects the ray with the sphere. If intersection is closer than what is /// in the record, updates the record with new intersection information. /// </summary> /// <param name="ray"></param> /// <param name="record"></param> /// <returns></returns> public override bool Intersect(Ray ray, IntersectionRecord record) { Vector3 v1 = ray.Origin - mCenter; float b = 2f * Vector3.Dot(v1, ray.Direction); float c = v1.LengthSquared() - mRadiusSquared; float root = b * b - 4 * c; if (root < 0f) return false; root = (float) Math.Sqrt(root); float t0 = 0.5f * (-b - root); float t1 = 0.5f * (-b + root); if ((t0 < 0) && (t1 < 0)) return false; float dist; if (t0 < t1) { if (t0 > 0) dist = t0; else dist = t1; } else { if (t1 > 0) dist = t1; else dist = t0; } if (dist > record.HitDistance) return false; // intersection found Vector3 pt = ray.Origin + dist * ray.Direction; Vector3 n = pt - mCenter; record.UpdateRecord(dist, pt, n, ray, mMaterialIndex, GetResourceIndex()); return true; }
/// <summary> /// Intersects the ray, if intersection is closer than the one inside the record, /// sets the records with intersection information. /// </summary> /// <param name="ray"></param> /// <param name="record"></param> /// <returns></returns> public override bool Intersect(Ray ray, IntersectionRecord record) { float dist= 0f; Vector3 hitPt, n; n = mNormal; // because ray/plane intersection may flip the normal! if (!RayPlaneIntersection(ray, ref n, mD, ref dist)) return false; /* * rectangle behind the ray or there are other closer intersections */ if ((dist < 0) || (dist > record.HitDistance)) return false; hitPt = ray.Origin + (ray.Direction * dist); /* * Now need to decide inside or outside */ if (!InsidePolygon(hitPt)) return false; record.UpdateRecord(dist, hitPt, n, ray, mMaterialIndex, GetResourceIndex()); return true; }