blob: 0561b6867b2eec32db25c1e89e609c3b4a05c784 [file] [log] [blame] [raw]
package li.cil.oc.util
import net.minecraftforge.common.util.ForgeDirection
import scala.collection.mutable
object RotationHelper {
def fromYaw(yaw: Float) = {
(yaw / 360 * 4).round & 3 match {
case 0 => ForgeDirection.SOUTH
case 1 => ForgeDirection.WEST
case 2 => ForgeDirection.NORTH
case 3 => ForgeDirection.EAST
}
}
def toLocal(pitch: ForgeDirection, yaw: ForgeDirection, value: ForgeDirection) =
translationFor(pitch, yaw)(value.ordinal)
def toGlobal(pitch: ForgeDirection, yaw: ForgeDirection, value: ForgeDirection) =
inverseTranslationFor(pitch, yaw)(value.ordinal)
def translationFor(pitch: ForgeDirection, yaw: ForgeDirection) =
translationCache.synchronized(translationCache.
getOrElseUpdate(pitch, mutable.Map.empty).
getOrElseUpdate(yaw, translations(pitch.ordinal)(yaw.ordinal - 2)))
def inverseTranslationFor(pitch: ForgeDirection, yaw: ForgeDirection) =
inverseTranslationCache.synchronized(inverseTranslationCache.
getOrElseUpdate(pitch, mutable.Map.empty).
getOrElseUpdate(yaw, {
val t = translationFor(pitch, yaw)
t.indices.
map(ForgeDirection.getOrientation).
map(t.indexOf).
map(ForgeDirection.getOrientation).
toArray
}))
// ----------------------------------------------------------------------- //
private val translationCache = mutable.Map.empty[ForgeDirection, mutable.Map[ForgeDirection, Array[ForgeDirection]]]
private val inverseTranslationCache = mutable.Map.empty[ForgeDirection, mutable.Map[ForgeDirection, Array[ForgeDirection]]]
/**
* Translates forge directions based on the block's pitch and yaw. The base
* forward direction is facing south with no pitch. The outer array is for
* the three different pitch states, the inner for the four different yaw
* states.
*/
private val translations = Array(
// Pitch = Down
Array(
// Yaw = North
Array(D.south, D.north, D.up, D.down, D.east, D.west, D.unknown),
// Yaw = South
Array(D.south, D.north, D.down, D.up, D.west, D.east, D.unknown),
// Yaw = West
Array(D.south, D.north, D.west, D.east, D.up, D.down, D.unknown),
// Yaw = East
Array(D.south, D.north, D.east, D.west, D.down, D.up, D.unknown)),
// Pitch = Up
Array(
// Yaw = North
Array(D.north, D.south, D.down, D.up, D.east, D.west, D.unknown),
// Yaw = South
Array(D.north, D.south, D.up, D.down, D.west, D.east, D.unknown),
// Yaw = West
Array(D.north, D.south, D.west, D.east, D.down, D.up, D.unknown),
// Yaw = East
Array(D.north, D.south, D.east, D.west, D.up, D.down, D.unknown)),
// Pitch = Forward (North|East|South|West)
Array(
// Yaw = North
Array(D.down, D.up, D.south, D.north, D.east, D.west, D.unknown),
// Yaw = South
Array(D.down, D.up, D.north, D.south, D.west, D.east, D.unknown),
// Yaw = West
Array(D.down, D.up, D.west, D.east, D.south, D.north, D.unknown),
// Yaw = East
Array(D.down, D.up, D.east, D.west, D.north, D.south, D.unknown)))
/** Shortcuts for forge directions to make the above more readable. */
private object D {
val down = ForgeDirection.DOWN
val up = ForgeDirection.UP
val north = ForgeDirection.NORTH
val south = ForgeDirection.SOUTH
val west = ForgeDirection.WEST
val east = ForgeDirection.EAST
val unknown = ForgeDirection.UNKNOWN
}
}