Advertisement
PaleoCrafter

RayTracer - The Scala way

May 28th, 2015
321
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 1.71 KB | None | 0 0
  1. case class Ray(start: Vector3, end: Vector3) {
  2.   def traceSide(cuboid: AxisAlignedCuboid, side: EnumFacing): Option[Hit] = {
  3.     val (plane, coord) = side match {
  4.       case DOWN => (VPlane.XZ, cuboid.min.y)
  5.       case UP => (VPlane.XZ, cuboid.max.y)
  6.       case NORTH => (VPlane.XY, cuboid.min.z)
  7.       case SOUTH => (VPlane.XY, cuboid.max.z)
  8.       case WEST => (VPlane.YZ, cuboid.min.x)
  9.       case EAST => (VPlane.YZ, cuboid.max.x)
  10.     }
  11.     start.intercept(plane)(end, coord) match {
  12.       case Some(hit) =>
  13.         val (hitA, hitB) = plane.extractDefining(hit)
  14.         val (minA, minB) = plane.extractDefining(cuboid.min)
  15.         val (maxA, maxB) = plane.extractDefining(cuboid.max)
  16.         if (!MathUtils.between(minA, hitA, maxA) || !MathUtils.between(minB, hitB, maxB))
  17.           None
  18.         else
  19.           Some(Hit(hit, hit.distanceSq(start), Some(cuboid), side))
  20.       case _ => None
  21.     }
  22.   }
  23.  
  24.   def traceCuboid(cuboid: AxisAlignedCuboid): Option[Hit] = values map (traceSide(cuboid, _)) minBy {
  25.     case Some(hit) => hit.distanceSq
  26.     case _ => Double.MaxValue
  27.   }
  28.  
  29.   def traceCuboids(cuboids: Seq[AxisAlignedCuboid]): Option[Hit] = cuboids map traceCuboid minBy {
  30.     case Some(hit) => hit.distanceSq
  31.     case _ => Double.MaxValue
  32.   }
  33.  
  34.   def traceCuboids(pos: BlockPos, cuboids: Seq[AxisAlignedCuboid]): Option[BlockHit] = traceCuboids(cuboids) map {
  35.     _.blockHit(pos)
  36.   }
  37.  
  38.   def trace(world: World): Option[Hit] =
  39.     world.rayTraceBlocks(start, end, true, false, true) match {
  40.       case null => None
  41.       case mop if mop.typeOfHit == MovingObjectType.MISS => None
  42.       case mop =>
  43.         val hit: Vector3 = mop.hitVec
  44.         Some(Hit(hit, hit.distanceSq(start), None, mop.sideHit))
  45.     }
  46. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement