예제 #1
0
 TEST(HitPointInterval, ShouldComputeIntersectionOfEmptyAndNonEmptyIntervals) {
   HitPointInterval interval1, interval2;
   HitPoint hitPoint(box, 5, Vector3d(), Vector3d());
   interval2.add(hitPoint);
   HitPointInterval intersectionInterval = interval1 & interval2;
   ASSERT_TRUE(intersectionInterval.min() == HitPoint::undefined());
   ASSERT_TRUE(intersectionInterval.max() == HitPoint::undefined());
 }
예제 #2
0
 TEST(HitPointInterval, ShouldComputeUnionOfEmptyAndNonEmptyIntervals) {
   HitPointInterval interval1, interval2;
   HitPoint hitPoint(box, 5, Vector3d(), Vector3d());
   interval2.add(hitPoint);
   HitPointInterval unionInterval = interval1 | interval2;
   
   ASSERT_TRUE(unionInterval.min() == hitPoint);
   ASSERT_TRUE(unionInterval.max() == hitPoint);
 }
예제 #3
0
 TEST(HitPointInterval, ShouldTransformInterval) {
   HitPointInterval interval;
   HitPoint hitPoint1(box, 2, Vector3d(1, 0, 0), Vector3d(0, 1, 0));
   HitPoint hitPoint2(box, 3, Vector3d(2, 0, 0), Vector3d(0, 1, 0));
   interval.add(hitPoint1, hitPoint2);
   
   Matrix4d pointMatrix = Matrix3d::rotateZ(1_radians);
   Matrix3d normalMatrix = Matrix3d::rotateX(1_radians);
   
   HitPointInterval transformed = interval.transform(pointMatrix, normalMatrix);
   ASSERT_EQ(Vector3d(pointMatrix * Vector4d(1, 0, 0)), transformed.min().point());
 }
예제 #4
0
 TEST(HitPointInterval, ShouldComputeCompositeOfIntervals) {
   HitPointInterval interval1, interval2;
   HitPoint hitPoint1(box, 2, Vector3d(), Vector3d());
   HitPoint hitPoint2(box, 3, Vector3d(), Vector3d());
   HitPoint hitPoint3(box, 4, Vector3d(), Vector3d());
   HitPoint hitPoint4(box, 5, Vector3d(), Vector3d());
   interval1.add(hitPoint1, hitPoint2);
   interval2.add(hitPoint3, hitPoint4);
   HitPointInterval compositeInterval = interval1 + interval2;
   
   ASSERT_TRUE(compositeInterval.min() == hitPoint1);
   ASSERT_TRUE(compositeInterval.max() == hitPoint4);
 }
예제 #5
0
 TEST(HitPointInterval, ShouldReturnEmptyIntersectionIfIntervalsDontOverlap) {
   HitPointInterval interval1, interval2;
   HitPoint hitPoint1(box, 2, Vector3d(), Vector3d());
   HitPoint hitPoint2(box, 3, Vector3d(), Vector3d());
   HitPoint hitPoint3(box, 4, Vector3d(), Vector3d());
   HitPoint hitPoint4(box, 5, Vector3d(), Vector3d());
   interval1.add(hitPoint1, hitPoint2);
   interval2.add(hitPoint3, hitPoint4);
   HitPointInterval intersectionInterval = interval1 & interval2;
   
   ASSERT_TRUE(intersectionInterval.min() == HitPoint::undefined());
   ASSERT_TRUE(intersectionInterval.max() == HitPoint::undefined());
 }
예제 #6
0
 TEST(HitPointInterval, ShouldComputeIntersectionOfTwoNonEmptyIntervals) {
   HitPointInterval interval1, interval2;
   HitPoint hitPoint1(box, 2, Vector3d(), Vector3d());
   HitPoint hitPoint2(box, 5, Vector3d(), Vector3d());
   HitPoint hitPoint3(box, 4, Vector3d(), Vector3d());
   HitPoint hitPoint4(box, 7, Vector3d(), Vector3d());
   interval1.add(hitPoint1, hitPoint2);
   interval2.add(hitPoint3, hitPoint4);
   HitPointInterval intersectionInterval = interval1 & interval2;
   
   ASSERT_TRUE(intersectionInterval.min() == hitPoint3);
   ASSERT_TRUE(intersectionInterval.max() == hitPoint2);
 }
예제 #7
0
const Primitive* ConvexOperation::intersect(const Rayd& ray, HitPointInterval& hitPoints, State& state) const {
  if (!boundingBoxIntersects(ray)) {
    state.miss("ConvexOperation, bounding box miss");
    return nullptr;
  }
  
  // unlike the intersection methods for box, sphere, etc, convexIntersect()
  // only returns a single (closest) hitpoint. So we need to shoot a ray in the
  // opposite direction as well.
  
  // calculate hitpoint in ray direction
  if (convexIntersect(ray, hitPoints)) {
    // if it's a hit, do it again in the opposite direction
    HitPointInterval opposite;
    // If we double the hit distance and take the longest possible length in
    // the bounding box, we should be beyond the other side of the object
    Rayd oppositeRay(
      ray.at(hitPoints.min().distance() * 2.0 + boundingBox().size().length()),
      -ray.direction()
    );
    
    // fire!
    convexIntersect(oppositeRay, opposite);
    HitPoint oppositePoint = opposite.min();
    // now, we have to project that point on the opposite side back to the
    // original ray to find the real distance value
    oppositePoint.setDistance(ray.projectedDistance(oppositePoint.point()));
    
    // add it to the interval
    hitPoints.add(oppositePoint);
    // and merge both points into a single interval. we can do that, since this
    // is by definition a convex object, so there can be only a single interval
    hitPoints = hitPoints.merged();
    
    auto hitPoint = hitPoints.minWithPositiveDistance();
    if (hitPoint.isUndefined()) {
      return nullptr;
      state.miss("ConvexOperation, ray miss");
    } else {
      state.hit("ConvexOperation");

      hitPoints.setPrimitive(this);
      return this;
    }
  }
  state.miss("ConvexOperation, ray miss");
  return nullptr;
}
예제 #8
0
 TEST(HitPointInterval, ShouldComputeMergedInterval) {
   HitPointInterval interval;
   HitPoint hitPoint1(box, 2, Vector3d(), Vector3d());
   HitPoint hitPoint2(box, 3, Vector3d(), Vector3d());
   HitPoint hitPoint3(box, 4, Vector3d(), Vector3d());
   HitPoint hitPoint4(box, 5, Vector3d(), Vector3d());
   interval.add(hitPoint1, hitPoint2);
   interval.add(hitPoint3, hitPoint4);
   
   interval = interval.merged();
   ASSERT_EQ(2ul, interval.points().size());
   ASSERT_TRUE(interval.min() == hitPoint1);
   ASSERT_TRUE(interval.max() == hitPoint4);
 }
예제 #9
0
 TEST(HitPointInterval, ShouldComputeIntersectionOfTwoEmptyIntervals) {
   HitPointInterval interval1, interval2;
   HitPointInterval intersectionInterval = interval1 & interval2;
   ASSERT_TRUE(intersectionInterval.min() == HitPoint::undefined());
   ASSERT_TRUE(intersectionInterval.max() == HitPoint::undefined());
 }
예제 #10
0
 TEST(HitPointInterval, ShouldSetClosestAndFarthestHitPointWhenOnlyOneHitPointIsAdded) {
   HitPointInterval interval;
   HitPoint hitPoint(box, 5, Vector3d(), Vector3d());
   interval.add(hitPoint);
   ASSERT_TRUE(interval.min() == interval.max());
 }
예제 #11
0
 TEST(HitPointInterval, ShouldReturnFarthestHitPoint) {
   HitPointInterval interval;
   HitPoint hitPoint(box, 5, Vector3d(), Vector3d());
   interval.add(hitPoint);
   ASSERT_TRUE(hitPoint == interval.max());
 }
예제 #12
0
 TEST(HitPointInterval, ShouldReturnUndefinedFarthestHitPointOnEmptyInterval) {
   HitPointInterval interval;
   const HitPoint& i = interval.max();
   ASSERT_TRUE(i == HitPoint::undefined());
 }
예제 #13
0
 TEST(HitPointInterval, ShouldAddTwoHitPointsAsPair) {
   HitPointInterval interval;
   interval.add(HitPoint(), HitPoint());
 }
예제 #14
0
 TEST(HitPointInterval, ShouldAddSingleHitPoint) {
   HitPointInterval interval;
   interval.add(HitPoint());
 }