CCD implementation for hitting ground

Former-commit-id: 786f0b4551b32be44767eac627dc247df3773968
Former-commit-id: 6ff2be7b31c91a581125c5682055776047660195
This commit is contained in:
Song Minjae
2016-05-02 00:42:04 +09:00
parent f3050736be
commit 6171b44170
9 changed files with 1152 additions and 319 deletions

View File

@@ -8,6 +8,7 @@ import net.torvald.terrarum.tileproperties.TilePropCodex
import net.torvald.spriteanimation.SpriteAnimation
import com.jme3.math.FastMath
import net.torvald.terrarum.tileproperties.TileNameCode
import org.dyn4j.geometry.ChainedVector2
import org.dyn4j.geometry.Vector2
import org.newdawn.slick.GameContainer
import org.newdawn.slick.Graphics
@@ -26,19 +27,21 @@ open class ActorWithBody constructor() : Actor(), Visible {
var baseHitboxW: Int = 0
var baseHitboxH: Int = 0
@Transient private val map: GameMap = Terrarum.game.map
/**
* Velocity vector (broken down by axes) for newtonian sim.
* Acceleration: used in code like:
* veloY += 3.0
* +3.0 is acceleration. You __accumulate__ acceleration to the velocity.
*/
val velocity = Vector2(0.0, 0.0)
val velocity = ChainedVector2(0.0, 0.0)
var veloX: Double
get() = velocity.x
set(value) { velocity.set(value, veloY) }
set(value) { velocity.x = value }
var veloY: Double
get() = velocity.y
set(value) { velocity.set(veloX, value) }
set(value) { velocity.y = value }
@Transient private val VELO_HARD_LIMIT = 10000.0
var grounded = false
@@ -106,7 +109,7 @@ open class ActorWithBody constructor() : Actor(), Visible {
*/
@Transient private val SI_TO_GAME_VEL = METER / Terrarum.TARGET_FPS
@Transient private var gravitation: Double = 0.toDouble()
@Transient private var gravitation: Vector2 = map.gravitation
@Transient private val DRAG_COEFF = 1.0
@Transient private val CONTACT_AREA_TOP = 0
@@ -135,8 +138,6 @@ open class ActorWithBody constructor() : Actor(), Visible {
*/
@Transient val INVINCIBILITY_TIME: Int = 500
@Transient private val map: GameMap
@Transient private val MASS_DEFAULT: Double = 60.0
internal val physSleep: Boolean
@@ -154,8 +155,10 @@ open class ActorWithBody constructor() : Actor(), Visible {
@Transient val DYNAMIC = 2
@Transient val STATIC = 3
private val SLEEP_THRE = 0.05
init {
map = Terrarum.game.map
}
/**
@@ -243,10 +246,13 @@ open class ActorWithBody constructor() : Actor(), Visible {
//}
//else {
// compensate for colliding
updateHorizontalCollision()
updateVerticalCollision()
//updateHorizontalCollision()
//updateVerticalCollision()
adjustHit()
applyNormalForce()
setHorizontalFriction()
if (isPlayerNoClip) setVerticalFriction()
//}
// apply our compensation to actual hitbox
@@ -273,16 +279,19 @@ open class ActorWithBody constructor() : Actor(), Visible {
* weight; gravitational force in action
* W = mass * G (9.8 [m/s^2])
*/
val W = gravitation * mass
val W: Vector2 = gravitation * mass
/**
* Drag of atmosphere
* D = Cd (drag coefficient) * 0.5 * rho (density) * V^2 (velocity) * A (area)
*/
val A = scale * scale
val D = DRAG_COEFF * 0.5 * 1.292 * veloY * veloY * A
// TODO replace 1.292 with fluid tile density
val A: Double = scale * scale
val D: Vector2 = velocity.copy().toVector() * DRAG_COEFF * 0.5 * 1.292 * A
veloY += clampCeil(
(W - D) / mass * SI_TO_GAME_ACC * G_MUL_PLAYABLE_CONST, VELO_HARD_LIMIT)
//veloY += (W - D) / mass * SI_TO_GAME_ACC
val V: Vector2 = (W - D) / mass * SI_TO_GAME_ACC
veloX += V.x
veloY += V.y
}
}
@@ -298,6 +307,18 @@ open class ActorWithBody constructor() : Actor(), Visible {
}
}
private fun setVerticalFriction() {
val friction = BASE_FRICTION * tileFriction.tileFrictionToMult()
if (veloY < 0) {
veloY += friction
if (veloY > 0) veloY = 0.0 // compensate overshoot
}
else if (veloY > 0) {
veloY -= friction
if (veloY < 0) veloY = 0.0 // compensate overshoot
}
}
private fun updateVerticalCollision() {
if (!isNoCollideWorld) {
if (veloY >= 0) { // check downward
@@ -451,6 +472,67 @@ open class ActorWithBody constructor() : Actor(), Visible {
nextHitbox.setPosition(newX, newY)
}
/**
* nextHitbox must NOT altered before this method is called!
*/
private fun adjustHit() {
val delta: Vector2 = Vector2(hitbox.toVector() - nextHitbox.toVector()) // we need to traverse back, so may as well negate at the first place
delta *= SLEEP_THRE // CCD delta
while (isColliding(CONTACT_AREA_LEFT) || isColliding(CONTACT_AREA_RIGHT)
|| isColliding(CONTACT_AREA_TOP) || isColliding(CONTACT_AREA_BOTTOM)
) {
// CCD to the 'delta'
nextHitbox.translate(delta)
}
}
private fun applyNormalForce() {
if (!isNoCollideWorld) {
if (gravitation.y != 0.0) {
if (veloY > SLEEP_THRE && isColliding(CONTACT_AREA_BOTTOM, 0, 1)) {
veloY = 0.0
grounded = (gravitation.y > 0)
}
else if (veloY < -SLEEP_THRE && isColliding(CONTACT_AREA_TOP, 0, -1)) {
veloY = 0.0
grounded = (gravitation.y < 0)
}
else {
grounded = false
}
}
else {
if ((veloY > SLEEP_THRE && isColliding(CONTACT_AREA_BOTTOM, 0, 1))
|| (veloY < -SLEEP_THRE && isColliding(CONTACT_AREA_TOP, 0, -1))
) {
veloY = 0.0
}
}
if (gravitation.x != 0.0) {
if (veloX > SLEEP_THRE && isColliding(CONTACT_AREA_BOTTOM, 1, 0)) {
veloX = 0.0
grounded = (gravitation.x > 0)
}
else if (veloX < -SLEEP_THRE && isColliding(CONTACT_AREA_TOP, -1, 0)) {
veloY = 0.0
grounded = (gravitation.x < 0)
}
else {
grounded = false
}
}
else {
if ((veloX > SLEEP_THRE && isColliding(CONTACT_AREA_RIGHT, 1, 0))
|| (veloX < -SLEEP_THRE && isColliding(CONTACT_AREA_LEFT, -1, 0))
) {
veloX = 0.0
}
}
}
}
private fun elasticReflectX() {
if (veloX != 0.0 && (veloX * elasticity).abs() > 0.5) {
veloX = -veloX * elasticity
@@ -619,35 +701,6 @@ open class ActorWithBody constructor() : Actor(), Visible {
return density
}
/**
* Get highest fluid resistance value from tiles that the body occupies.
* @return
*/
private val fluidResistance: Int
get() {
var resistance = 0
//get highest fluid density
val tilePosXStart = (nextHitbox.posX / TSIZE).roundToInt()
val tilePosYStart = (nextHitbox.posY / TSIZE).roundToInt()
val tilePosXEnd = (nextHitbox.hitboxEnd.x / TSIZE).roundToInt()
val tilePosYEnd = (nextHitbox.hitboxEnd.y / TSIZE).roundToInt()
for (y in tilePosYStart..tilePosYEnd) {
for (x in tilePosXStart..tilePosXEnd) {
val tile = map.getTileFromTerrain(x, y)
if (TilePropCodex.getProp(tile).isFluid) {
val thisResistance = TilePropCodex.getProp(tile).movementResistance
if (thisResistance > resistance) resistance = thisResistance
}
}
}
return resistance
}
fun Int.resistanceToMult(): Double = 1.0 / (1 + this / 16.0)
private fun clampHitbox() {
hitbox.setPositionFromPoint(
clampW(hitbox.pointedX), clampH(hitbox.pointedY))

View File

@@ -1,6 +1,8 @@
package net.torvald.terrarum.gameactors
import net.torvald.point.Point2d
import org.dyn4j.geometry.ChainedVector2
import org.dyn4j.geometry.Vector2
/**
* Created by minjaesong on 16-01-15.
@@ -54,6 +56,18 @@ class Hitbox(x1: Double, y1: Double, width: Double, height: Double) {
this.height = height
}
fun translate(x: Double, y: Double) {
setPosition(posX + x, posY + y)
}
fun translate(vec: ChainedVector2) {
translate(vec.x, vec.y)
}
fun translate(vec: Vector2) {
translate(vec.x, vec.y)
}
fun setPosition(x1: Double, y1: Double) {
hitboxStart = Point2d(x1, y1)
hitboxEnd = Point2d(x1 + width, y1 + height)
@@ -112,4 +126,8 @@ class Hitbox(x1: Double, y1: Double, width: Double, height: Double) {
val centeredY: Double
get() = (hitboxStart.y + hitboxEnd.y) * 0.5f
fun toVector(): Vector2 {
return Vector2(posX, posY)
}
}

View File

@@ -322,10 +322,12 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
if (isFuncDown(input, EnumKeyFunc.MOVE_RIGHT) && !isFuncDown(input, EnumKeyFunc.MOVE_LEFT)) {
walkHorizontal(false, AXIS_POSMAX)
prevHMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_RIGHT)
} else if (isFuncDown(input, EnumKeyFunc.MOVE_LEFT) && !isFuncDown(input, EnumKeyFunc.MOVE_RIGHT)) {
} // ↓F, ↑S
else if (isFuncDown(input, EnumKeyFunc.MOVE_LEFT) && !isFuncDown(input, EnumKeyFunc.MOVE_RIGHT)) {
walkHorizontal(true, AXIS_POSMAX)
prevHMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_LEFT)
} else if (isFuncDown(input, EnumKeyFunc.MOVE_LEFT) && isFuncDown(input, EnumKeyFunc.MOVE_RIGHT)) {
} // ↓F, ↓S
else if (isFuncDown(input, EnumKeyFunc.MOVE_LEFT) && isFuncDown(input, EnumKeyFunc.MOVE_RIGHT)) {
if (prevHMoveKey == KeyMap.getKeyCode(EnumKeyFunc.MOVE_LEFT)) {
walkHorizontal(false, AXIS_POSMAX)
prevHMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_RIGHT)
@@ -333,8 +335,7 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
walkHorizontal(true, AXIS_POSMAX)
prevHMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_LEFT)
}
}// ↓F, ↓S
// ↓F, ↑S
}
}
/**
@@ -346,15 +347,16 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
walkVertical(axisY > 0, AXIS_POSMAX)
}
} else {
// ↑E
// ↓D
// ↑E, ↓D
if (isFuncDown(input, EnumKeyFunc.MOVE_DOWN) && !isFuncDown(input, EnumKeyFunc.MOVE_UP)) {
walkVertical(false, AXIS_POSMAX)
prevVMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_DOWN)
} else if (isFuncDown(input, EnumKeyFunc.MOVE_UP) && !isFuncDown(input, EnumKeyFunc.MOVE_DOWN)) {
} // ↓E, ↑D
else if (isFuncDown(input, EnumKeyFunc.MOVE_UP) && !isFuncDown(input, EnumKeyFunc.MOVE_DOWN)) {
walkVertical(true, AXIS_POSMAX)
prevVMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_UP)
} else if (isFuncDown(input, EnumKeyFunc.MOVE_UP) && isFuncDown(input, EnumKeyFunc.MOVE_DOWN)) {
} // ↓E, ↓D
else if (isFuncDown(input, EnumKeyFunc.MOVE_UP) && isFuncDown(input, EnumKeyFunc.MOVE_DOWN)) {
if (prevVMoveKey == KeyMap.getKeyCode(EnumKeyFunc.MOVE_UP)) {
walkVertical(false, AXIS_POSMAX)
prevVMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_DOWN)
@@ -362,10 +364,7 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
walkVertical(true, AXIS_POSMAX)
prevVMoveKey = KeyMap.getKeyCode(EnumKeyFunc.MOVE_UP)
}
}// ↓E
// ↓D
// ↓E
// ↑D
}
}
}

View File

@@ -1,6 +1,7 @@
package net.torvald.terrarum.gamemap
import org.dyn4j.geometry.Vector2
import org.newdawn.slick.SlickException
class GameMap
@@ -32,7 +33,7 @@ constructor(//properties
//public World physWorld = new World( new Vec2(0, -TerrarumMain.game.gravitationalAccel) );
//physics
/** \[m / s^2\] */
var gravitation: Double = 9.8
var gravitation: Vector2 = Vector2(0.0, 9.8)
/** RGB in Integer */
var globalLight: Int = 0
val worldTime: WorldTime

View File

@@ -21,7 +21,6 @@ class TileProp {
var density: Int = 0
var isFluid: Boolean = false
var movementResistance: Int = 0
var isSolid: Boolean = false

View File

@@ -85,8 +85,6 @@ class TilePropCodex {
prop.isWallable = boolVal(record, "wall")
prop.isFallable = boolVal(record, "fall")
if (prop.isFluid) prop.movementResistance = intVal(record, "movr")
print(formatNum3(prop.id) + ":" + formatNum2(prop.damage))
println("\t" + prop.name)
}

View File

@@ -1,122 +1,122 @@
"id";"dmg";"name" ; "opacity";"strength";"dsty";"fluid";"movr";"solid";"wall"; "lumcolor";"drop";"ddmg";"fall";"friction"
"0"; "0";"TILE_AIR" ; "8396808"; "0"; "1"; "0"; "0"; "0"; "0"; "0"; "0"; "0"; "0";"4"
"1"; "0";"TILE_STONE" ; "33587232"; "25";"2400"; "0"; "0"; "1"; "1"; "0"; "1"; "0"; "0";"16"
"1"; "1";"TILE_STONE_QUARRIED" ; "33587232"; "25";"2400"; "0"; "0"; "1"; "1"; "0"; "1"; "1"; "0";"16"
"2"; "0";"TILE_DIRT" ; "33587232"; "6";"1400"; "0"; "0"; "1"; "1"; "0"; "2"; "0"; "0";"16"
"2"; "1";"TILE_GRASS" ; "33587232"; "6";"1400"; "0"; "0"; "1"; "1"; "0"; "2"; "1"; "0";"16"
"3"; "0";"TILE_PLANK_NORMAL" ; "33587232"; "12"; "740"; "0"; "0"; "1"; "1"; "0"; "3"; "0"; "0";"16"
"3"; "1";"TILE_PLANK_EBONY" ; "33587232"; "12";"1200"; "0"; "0"; "1"; "1"; "0"; "3"; "1"; "0";"16"
"3"; "2";"TILE_PLANK_BIRCH" ; "33587232"; "12"; "670"; "0"; "0"; "1"; "1"; "0"; "3"; "2"; "0";"16"
"3"; "3";"TILE_PLANK_BLOODROSE" ; "33587232"; "12"; "900"; "0"; "0"; "1"; "1"; "0"; "3"; "3"; "0";"16"
"4"; "0";"TILE_TRUNK_NORMAL" ; "33587232"; "12"; "740"; "0"; "0"; "1"; "0"; "0"; "3"; "0"; "0";"16"
"4"; "1";"TILE_TRUNK_EBONY" ; "33587232"; "12";"1200"; "0"; "0"; "1"; "0"; "0"; "3"; "1"; "0";"16"
"4"; "2";"TILE_TRUNK_BIRCH" ; "33587232"; "12"; "670"; "0"; "0"; "1"; "0"; "0"; "3"; "2"; "0";"16"
"4"; "3";"TILE_TRUNK_BLOODROSE" ; "33587232"; "12"; "900"; "0"; "0"; "1"; "0"; "0"; "3"; "3"; "0";"16"
"5"; "0";"TILE_SAND" ; "33587232"; "6";"2400"; "0"; "0"; "1"; "0"; "0"; "5"; "0"; "1";"16"
"5"; "1";"TILE_SAND_WHITE" ; "33587232"; "6";"2400"; "0"; "0"; "1"; "0"; "0"; "5"; "1"; "1";"16"
"5"; "2";"TILE_SAND_RED" ; "33587232"; "6";"2400"; "0"; "0"; "1"; "0"; "0"; "5"; "2"; "1";"16"
"5"; "3";"TILE_SAND_DESERT" ; "33587232"; "6";"2400"; "0"; "0"; "1"; "0"; "0"; "5"; "3"; "1";"16"
"5"; "4";"TILE_SAND_BLACK" ; "33587232"; "6";"2400"; "0"; "0"; "1"; "0"; "0"; "5"; "4"; "1";"16"
"5"; "5";"TILE_SAND_GREEN" ; "33587232"; "6";"2400"; "0"; "0"; "1"; "0"; "0"; "5"; "5"; "1";"16"
"6"; "0";"TILE_GRAVEL" ; "33587232"; "6";"2400"; "0"; "0"; "1"; "0"; "0"; "6"; "0"; "1";"16"
"6"; "1";"TILE_GRAVEL_GREY" ; "33587232"; "6";"2400"; "0"; "0"; "1"; "0"; "0"; "6"; "1"; "1";"16"
"7"; "0";"TILE_ORE_MALACHITE" ; "33587232"; "25";"2400"; "0"; "0"; "1"; "0"; "0"; "7"; "0"; "0";"16"
"7"; "1";"TILE_ORE_HEMATITE" ; "33587232"; "25";"2400"; "0"; "0"; "1"; "0"; "0"; "7"; "1"; "0";"16"
"7"; "2";"TILE_ORE_NATURAL_GOLD" ; "33587232"; "25";"2400"; "0"; "0"; "1"; "0"; "0"; "7"; "2"; "0";"16"
"7"; "3";"TILE_ORE_NATURAL_SILVER" ; "33587232"; "25";"2400"; "0"; "0"; "1"; "0"; "0"; "7"; "3"; "0";"16"
"7"; "4";"TILE_ORE_RUTILE" ; "33587232"; "25";"2400"; "0"; "0"; "1"; "0"; "0"; "7"; "4"; "0";"16"
"7"; "5";"TILE_ORE_AURICHALCUMITE" ; "33587232"; "25";"2400"; "0"; "0"; "1"; "0"; "0"; "7"; "5"; "0";"16"
"8"; "0";"TILE_GEM_RUBY" ; "33587232"; "25";"2400"; "0"; "0"; "1"; "0"; "0"; "8"; "0"; "0";"16"
"8"; "1";"TILE_GEM_EMERALD" ; "33587232"; "25";"2400"; "0"; "0"; "1"; "0"; "0"; "8"; "1"; "0";"16"
"8"; "2";"TILE_GEM_SAPPHIRE" ; "33587232"; "25";"2400"; "0"; "0"; "1"; "0"; "0"; "8"; "2"; "0";"16"
"8"; "3";"TILE_GEM_TOPAZ" ; "33587232"; "25";"2400"; "0"; "0"; "1"; "0"; "0"; "8"; "3"; "0";"16"
"8"; "4";"TILE_GEM_DIAMOND" ; "33587232"; "25";"2400"; "0"; "0"; "1"; "0"; "0"; "8"; "4"; "0";"16"
"8"; "5";"TILE_GEM_AMETHYST" ; "33587232"; "25";"2400"; "0"; "0"; "1"; "0"; "0"; "8"; "5"; "0";"16"
"9"; "0";"TILE_SNOW" ; "33587232"; "6"; "500"; "0"; "0"; "1"; "1"; "0"; "9"; "0"; "0";"16"
"9"; "1";"TILE_ICE_FRAGILE" ; "13644813"; "1"; "930"; "0"; "0"; "1"; "0"; "0"; "9"; "1"; "0";"16"
"9"; "2";"TILE_ICE_NATURAL" ; "27289626"; "25"; "930"; "0"; "0"; "1"; "1"; "0"; "9"; "2"; "0"; "8"
"9"; "3";"TILE_ICE_CLEAR_MAGICAL" ; "33587232"; "25";"3720"; "0"; "0"; "1"; "1"; "19955770"; "9"; "3"; "0"; "8"
"10"; "0";"TILE_PLATFORM_STONE" ; "8396808"; "1"; "N/A"; "0"; "0"; "0"; "0"; "0"; "10"; "0"; "0";"16"
"10"; "1";"TILE_PLATFORM_WOODEN" ; "8396808"; "1"; "N/A"; "0"; "0"; "0"; "0"; "0"; "10"; "1"; "0";"16"
"10"; "2";"TILE_PLATFORM_EBONY" ; "8396808"; "1"; "N/A"; "0"; "0"; "0"; "0"; "0"; "10"; "2"; "0";"16"
"10"; "3";"TILE_PLATFORM_BIRCH" ; "8396808"; "1"; "N/A"; "0"; "0"; "0"; "0"; "0"; "10"; "3"; "0";"16"
"10"; "4";"TILE_PLATFORM_BLOODROSE" ; "8396808"; "1"; "N/A"; "0"; "0"; "0"; "0"; "0"; "10"; "4"; "0";"16"
"11"; "0";"TILE_TORCH" ; "8396808"; "0"; "N/A"; "0"; "0"; "0"; "0"; "267518016"; "11"; "0"; "0";"16"
"11"; "1";"TILE_TORCH_FROST" ; "8396808"; "0"; "N/A"; "0"; "0"; "0"; "0"; "81916159"; "11"; "1"; "0";"16"
"12"; "0";"TILE_TORCH" ; "8396808"; "0"; "N/A"; "0"; "0"; "0"; "0"; "0"; "11"; "0"; "0";"16"
"12"; "1";"TILE_TORCH_FROST" ; "8396808"; "0"; "N/A"; "0"; "0"; "0"; "0"; "0"; "11"; "1"; "0";"16"
"13"; "0";"TILE_ILLUMINATOR_WHITE" ; "8396808"; "0"; "N/A"; "0"; "0"; "1"; "1"; "246656235"; "13"; "0"; "0";"16"
"13"; "1";"TILE_ILLUMINATOR_YELLOW" ; "8396808"; "0"; "N/A"; "0"; "0"; "1"; "1"; "246656000"; "13"; "1"; "0";"16"
"13"; "2";"TILE_ILLUMINATOR_ORANGE" ; "8396808"; "0"; "N/A"; "0"; "0"; "1"; "1"; "246602752"; "13"; "2"; "0";"16"
"13"; "3";"TILE_ILLUMINATOR_RED" ; "8396808"; "0"; "N/A"; "0"; "0"; "1"; "1"; "246415360"; "13"; "3"; "0";"16"
"13"; "4";"TILE_ILLUMINATOR_FUCHSIA" ; "8396808"; "0"; "N/A"; "0"; "0"; "1"; "1"; "246415543"; "13"; "4"; "0";"16"
"13"; "5";"TILE_ILLUMINATOR_PURPLE" ; "8396808"; "0"; "N/A"; "0"; "0"; "1"; "1"; "191889643"; "13"; "5"; "0";"16"
"13"; "6";"TILE_ILLUMINATOR_BLUE" ; "8396808"; "0"; "N/A"; "0"; "0"; "1"; "1"; "235"; "13"; "6"; "0";"16"
"13"; "7";"TILE_ILLUMINATOR_CYAN" ; "8396808"; "0"; "N/A"; "0"; "0"; "1"; "1"; "207083"; "13"; "7"; "0";"16"
"13"; "8";"TILE_ILLUMINATOR_GREEN" ; "8396808"; "0"; "N/A"; "0"; "0"; "1"; "1"; "68364288"; "13"; "8"; "0";"16"
"13"; "9";"TILE_ILLUMINATOR_GREEN_DARK";"8396808"; "0"; "N/A"; "0"; "0"; "1"; "1"; "33660928"; "13"; "9"; "0";"16"
"13"; "10";"TILE_ILLUMINATOR_BROWN" ; "8396808"; "0"; "N/A"; "0"; "0"; "1"; "1"; "89161728"; "13"; "10"; "0";"16"
"13"; "11";"TILE_ILLUMINATOR_TAN" ; "8396808"; "0"; "N/A"; "0"; "0"; "1"; "1"; "157392948"; "13"; "11"; "0";"16"
"13"; "12";"TILE_ILLUMINATOR_GREY_LIGHT";"8396808"; "0"; "N/A"; "0"; "0"; "1"; "1"; "198374589"; "13"; "12"; "0";"16"
"13"; "13";"TILE_ILLUMINATOR_GREY_MED"; "8396808"; "0"; "N/A"; "0"; "0"; "1"; "1"; "122803317"; "13"; "13"; "0";"16"
"13"; "14";"TILE_ILLUMINATOR_GREY_DARK"; "8396808"; "0"; "N/A"; "0"; "0"; "1"; "1"; "68224065"; "13"; "14"; "0";"16"
"13"; "15";"TILE_ILLUMINATOR_BLACK" ; "8396808"; "0"; "N/A"; "0"; "0"; "1"; "1"; "116392191"; "13"; "15"; "0";"16"
"14"; "0";"TILE_ILLUMINATOR_WHITE" ; "33587232"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "0"; "0";"16"
"14"; "1";"TILE_ILLUMINATOR_YELLOW" ; "33587232"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "1"; "0";"16"
"14"; "2";"TILE_ILLUMINATOR_ORANGE" ; "33587232"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "2"; "0";"16"
"14"; "3";"TILE_ILLUMINATOR_RED" ; "33587232"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "3"; "0";"16"
"14"; "4";"TILE_ILLUMINATOR_FUCHSIA" ; "33587232"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "4"; "0";"16"
"14"; "5";"TILE_ILLUMINATOR_PURPLE" ; "33587232"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "5"; "0";"16"
"14"; "6";"TILE_ILLUMINATOR_BLUE" ; "33587232"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "6"; "0";"16"
"14"; "7";"TILE_ILLUMINATOR_CYAN" ; "33587232"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "7"; "0";"16"
"14"; "8";"TILE_ILLUMINATOR_GREEN" ; "33587232"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "8"; "0";"16"
"14"; "9";"TILE_ILLUMINATOR_GREEN_DARK";"33587232"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "9"; "0";"16"
"14"; "10";"TILE_ILLUMINATOR_BROWN" ; "33587232"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "10"; "0";"16"
"14"; "11";"TILE_ILLUMINATOR_TAN" ; "33587232"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "11"; "0";"16"
"14"; "12";"TILE_ILLUMINATOR_GREY_LIGHT";"33587232"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "12"; "0";"16"
"14"; "13";"TILE_ILLUMINATOR_GREY_MED"; "33587232"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "13"; "0";"16"
"14"; "14";"TILE_ILLUMINATOR_GREY_DARK";"33587232"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "14"; "0";"16"
"14"; "15";"TILE_ILLUMINATOR_BLACK" ; "33587232"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "15"; "0";"16"
"15"; "0";"TILE_SANDSTONE" ; "33587232"; "25";"1900"; "0"; "0"; "1"; "1"; "0"; "15"; "0"; "0";"16"
"15"; "1";"TILE_SANDSTONE_WHITE" ; "33587232"; "25";"1900"; "0"; "0"; "1"; "1"; "0"; "15"; "1"; "0";"16"
"15"; "2";"TILE_SANDSTONE_RED" ; "33587232"; "25";"1900"; "0"; "0"; "1"; "1"; "0"; "15"; "2"; "0";"16"
"15"; "3";"TILE_SANDSTONE_DESERT" ; "33587232"; "25";"1900"; "0"; "0"; "1"; "1"; "0"; "15"; "3"; "0";"16"
"15"; "4";"TILE_SANDSTONE_BLACK" ; "33587232"; "25";"1900"; "0"; "0"; "1"; "1"; "0"; "15"; "4"; "0";"16"
"15"; "5";"TILE_SANDSTONE_BLACK" ; "33587232"; "25";"1900"; "0"; "0"; "1"; "1"; "0"; "15"; "5"; "0";"16"
"16"; "0";"TILE_LANTERN_IRON_REGULAR"; "8396808"; "0"; "N/A"; "0"; "0"; "0"; "0"; "267619480"; "16"; "0"; "0";"16"
"254"; "0";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "48"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"254"; "1";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "48"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"254"; "2";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "48"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"254"; "3";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "48"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"254"; "4";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "48"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"254"; "5";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "48"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"254"; "6";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "48"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"254"; "7";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "48"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"254"; "8";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "48"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"254"; "9";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "48"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"254"; "10";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "48"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"254"; "11";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "48"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"254"; "12";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "48"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"254"; "13";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "48"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"254"; "14";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "48"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"254"; "15";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "48"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"255"; "0";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "1";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "2";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "3";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "4";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "5";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "6";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "7";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "8";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "9";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "10";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "11";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "12";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "13";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "14";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "15";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"256"; "0";"TILE_NULL" ; "0"; "-1";"2600"; "0"; "0"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"id";"dmg";"name" ; "opacity";"strength";"dsty";"fluid";"solid";"wall"; "lumcolor";"drop";"ddmg";"fall";"friction"
"0"; "0";"TILE_AIR" ; "8396808"; "0"; "1"; "1"; "0"; "0"; "0"; "0"; "0"; "0";"4"
"1"; "0";"TILE_STONE" ; "33587232"; "25";"2400"; "0"; "1"; "1"; "0"; "1"; "0"; "0";"16"
"1"; "1";"TILE_STONE_QUARRIED" ; "33587232"; "25";"2400"; "0"; "1"; "1"; "0"; "1"; "1"; "0";"16"
"2"; "0";"TILE_DIRT" ; "33587232"; "6";"1400"; "0"; "1"; "1"; "0"; "2"; "0"; "0";"16"
"2"; "1";"TILE_GRASS" ; "33587232"; "6";"1400"; "0"; "1"; "1"; "0"; "2"; "1"; "0";"16"
"3"; "0";"TILE_PLANK_NORMAL" ; "33587232"; "12"; "740"; "0"; "1"; "1"; "0"; "3"; "0"; "0";"16"
"3"; "1";"TILE_PLANK_EBONY" ; "33587232"; "12";"1200"; "0"; "1"; "1"; "0"; "3"; "1"; "0";"16"
"3"; "2";"TILE_PLANK_BIRCH" ; "33587232"; "12"; "670"; "0"; "1"; "1"; "0"; "3"; "2"; "0";"16"
"3"; "3";"TILE_PLANK_BLOODROSE" ; "33587232"; "12"; "900"; "0"; "1"; "1"; "0"; "3"; "3"; "0";"16"
"4"; "0";"TILE_TRUNK_NORMAL" ; "33587232"; "12"; "740"; "0"; "1"; "0"; "0"; "3"; "0"; "0";"16"
"4"; "1";"TILE_TRUNK_EBONY" ; "33587232"; "12";"1200"; "0"; "1"; "0"; "0"; "3"; "1"; "0";"16"
"4"; "2";"TILE_TRUNK_BIRCH" ; "33587232"; "12"; "670"; "0"; "1"; "0"; "0"; "3"; "2"; "0";"16"
"4"; "3";"TILE_TRUNK_BLOODROSE" ; "33587232"; "12"; "900"; "0"; "1"; "0"; "0"; "3"; "3"; "0";"16"
"5"; "0";"TILE_SAND" ; "33587232"; "6";"2400"; "0"; "1"; "0"; "0"; "5"; "0"; "1";"16"
"5"; "1";"TILE_SAND_WHITE" ; "33587232"; "6";"2400"; "0"; "1"; "0"; "0"; "5"; "1"; "1";"16"
"5"; "2";"TILE_SAND_RED" ; "33587232"; "6";"2400"; "0"; "1"; "0"; "0"; "5"; "2"; "1";"16"
"5"; "3";"TILE_SAND_DESERT" ; "33587232"; "6";"2400"; "0"; "1"; "0"; "0"; "5"; "3"; "1";"16"
"5"; "4";"TILE_SAND_BLACK" ; "33587232"; "6";"2400"; "0"; "1"; "0"; "0"; "5"; "4"; "1";"16"
"5"; "5";"TILE_SAND_GREEN" ; "33587232"; "6";"2400"; "0"; "1"; "0"; "0"; "5"; "5"; "1";"16"
"6"; "0";"TILE_GRAVEL" ; "33587232"; "6";"2400"; "0"; "1"; "0"; "0"; "6"; "0"; "1";"16"
"6"; "1";"TILE_GRAVEL_GREY" ; "33587232"; "6";"2400"; "0"; "1"; "0"; "0"; "6"; "1"; "1";"16"
"7"; "0";"TILE_ORE_MALACHITE" ; "33587232"; "25";"2400"; "0"; "1"; "0"; "0"; "7"; "0"; "0";"16"
"7"; "1";"TILE_ORE_HEMATITE" ; "33587232"; "25";"2400"; "0"; "1"; "0"; "0"; "7"; "1"; "0";"16"
"7"; "2";"TILE_ORE_NATURAL_GOLD" ; "33587232"; "25";"2400"; "0"; "1"; "0"; "0"; "7"; "2"; "0";"16"
"7"; "3";"TILE_ORE_NATURAL_SILVER" ; "33587232"; "25";"2400"; "0"; "1"; "0"; "0"; "7"; "3"; "0";"16"
"7"; "4";"TILE_ORE_RUTILE" ; "33587232"; "25";"2400"; "0"; "1"; "0"; "0"; "7"; "4"; "0";"16"
"7"; "5";"TILE_ORE_AURICHALCUMITE" ; "33587232"; "25";"2400"; "0"; "1"; "0"; "0"; "7"; "5"; "0";"16"
"8"; "0";"TILE_GEM_RUBY" ; "33587232"; "25";"2400"; "0"; "1"; "0"; "0"; "8"; "0"; "0";"16"
"8"; "1";"TILE_GEM_EMERALD" ; "33587232"; "25";"2400"; "0"; "1"; "0"; "0"; "8"; "1"; "0";"16"
"8"; "2";"TILE_GEM_SAPPHIRE" ; "33587232"; "25";"2400"; "0"; "1"; "0"; "0"; "8"; "2"; "0";"16"
"8"; "3";"TILE_GEM_TOPAZ" ; "33587232"; "25";"2400"; "0"; "1"; "0"; "0"; "8"; "3"; "0";"16"
"8"; "4";"TILE_GEM_DIAMOND" ; "33587232"; "25";"2400"; "0"; "1"; "0"; "0"; "8"; "4"; "0";"16"
"8"; "5";"TILE_GEM_AMETHYST" ; "33587232"; "25";"2400"; "0"; "1"; "0"; "0"; "8"; "5"; "0";"16"
"9"; "0";"TILE_SNOW" ; "33587232"; "6"; "500"; "0"; "1"; "1"; "0"; "9"; "0"; "0";"16"
"9"; "1";"TILE_ICE_FRAGILE" ; "13644813"; "1"; "930"; "0"; "1"; "0"; "0"; "9"; "1"; "0";"16"
"9"; "2";"TILE_ICE_NATURAL" ; "27289626"; "25"; "930"; "0"; "1"; "1"; "0"; "9"; "2"; "0"; "8"
"9"; "3";"TILE_ICE_CLEAR_MAGICAL" ; "33587232"; "25";"3720"; "0"; "1"; "1"; "19955770"; "9"; "3"; "0"; "8"
"10"; "0";"TILE_PLATFORM_STONE" ; "8396808"; "1"; "N/A"; "0"; "0"; "0"; "0"; "10"; "0"; "0";"16"
"10"; "1";"TILE_PLATFORM_WOODEN" ; "8396808"; "1"; "N/A"; "0"; "0"; "0"; "0"; "10"; "1"; "0";"16"
"10"; "2";"TILE_PLATFORM_EBONY" ; "8396808"; "1"; "N/A"; "0"; "0"; "0"; "0"; "10"; "2"; "0";"16"
"10"; "3";"TILE_PLATFORM_BIRCH" ; "8396808"; "1"; "N/A"; "0"; "0"; "0"; "0"; "10"; "3"; "0";"16"
"10"; "4";"TILE_PLATFORM_BLOODROSE" ; "8396808"; "1"; "N/A"; "0"; "0"; "0"; "0"; "10"; "4"; "0";"16"
"11"; "0";"TILE_TORCH" ; "8396808"; "0"; "N/A"; "0"; "0"; "0"; "267518016"; "11"; "0"; "0";"16"
"11"; "1";"TILE_TORCH_FROST" ; "8396808"; "0"; "N/A"; "0"; "0"; "0"; "81916159"; "11"; "1"; "0";"16"
"12"; "0";"TILE_TORCH" ; "8396808"; "0"; "N/A"; "0"; "0"; "0"; "0"; "11"; "0"; "0";"16"
"12"; "1";"TILE_TORCH_FROST" ; "8396808"; "0"; "N/A"; "0"; "0"; "0"; "0"; "11"; "1"; "0";"16"
"13"; "0";"TILE_ILLUMINATOR_WHITE" ; "8396808"; "0"; "N/A"; "0"; "1"; "1"; "246656235"; "13"; "0"; "0";"16"
"13"; "1";"TILE_ILLUMINATOR_YELLOW" ; "8396808"; "0"; "N/A"; "0"; "1"; "1"; "246656000"; "13"; "1"; "0";"16"
"13"; "2";"TILE_ILLUMINATOR_ORANGE" ; "8396808"; "0"; "N/A"; "0"; "1"; "1"; "246602752"; "13"; "2"; "0";"16"
"13"; "3";"TILE_ILLUMINATOR_RED" ; "8396808"; "0"; "N/A"; "0"; "1"; "1"; "246415360"; "13"; "3"; "0";"16"
"13"; "4";"TILE_ILLUMINATOR_FUCHSIA" ; "8396808"; "0"; "N/A"; "0"; "1"; "1"; "246415543"; "13"; "4"; "0";"16"
"13"; "5";"TILE_ILLUMINATOR_PURPLE" ; "8396808"; "0"; "N/A"; "0"; "1"; "1"; "191889643"; "13"; "5"; "0";"16"
"13"; "6";"TILE_ILLUMINATOR_BLUE" ; "8396808"; "0"; "N/A"; "0"; "1"; "1"; "235"; "13"; "6"; "0";"16"
"13"; "7";"TILE_ILLUMINATOR_CYAN" ; "8396808"; "0"; "N/A"; "0"; "1"; "1"; "207083"; "13"; "7"; "0";"16"
"13"; "8";"TILE_ILLUMINATOR_GREEN" ; "8396808"; "0"; "N/A"; "0"; "1"; "1"; "68364288"; "13"; "8"; "0";"16"
"13"; "9";"TILE_ILLUMINATOR_GREEN_DARK";"8396808"; "0"; "N/A"; "0"; "1"; "1"; "33660928"; "13"; "9"; "0";"16"
"13"; "10";"TILE_ILLUMINATOR_BROWN" ; "8396808"; "0"; "N/A"; "0"; "1"; "1"; "89161728"; "13"; "10"; "0";"16"
"13"; "11";"TILE_ILLUMINATOR_TAN" ; "8396808"; "0"; "N/A"; "0"; "1"; "1"; "157392948"; "13"; "11"; "0";"16"
"13"; "12";"TILE_ILLUMINATOR_GREY_LIGHT";"8396808"; "0"; "N/A"; "0"; "1"; "1"; "198374589"; "13"; "12"; "0";"16"
"13"; "13";"TILE_ILLUMINATOR_GREY_MED"; "8396808"; "0"; "N/A"; "0"; "1"; "1"; "122803317"; "13"; "13"; "0";"16"
"13"; "14";"TILE_ILLUMINATOR_GREY_DARK"; "8396808"; "0"; "N/A"; "0"; "1"; "1"; "68224065"; "13"; "14"; "0";"16"
"13"; "15";"TILE_ILLUMINATOR_BLACK" ; "8396808"; "0"; "N/A"; "0"; "1"; "1"; "116392191"; "13"; "15"; "0";"16"
"14"; "0";"TILE_ILLUMINATOR_WHITE" ; "33587232"; "0"; "N/A"; "0"; "1"; "1"; "0"; "13"; "0"; "0";"16"
"14"; "1";"TILE_ILLUMINATOR_YELLOW" ; "33587232"; "0"; "N/A"; "0"; "1"; "1"; "0"; "13"; "1"; "0";"16"
"14"; "2";"TILE_ILLUMINATOR_ORANGE" ; "33587232"; "0"; "N/A"; "0"; "1"; "1"; "0"; "13"; "2"; "0";"16"
"14"; "3";"TILE_ILLUMINATOR_RED" ; "33587232"; "0"; "N/A"; "0"; "1"; "1"; "0"; "13"; "3"; "0";"16"
"14"; "4";"TILE_ILLUMINATOR_FUCHSIA" ; "33587232"; "0"; "N/A"; "0"; "1"; "1"; "0"; "13"; "4"; "0";"16"
"14"; "5";"TILE_ILLUMINATOR_PURPLE" ; "33587232"; "0"; "N/A"; "0"; "1"; "1"; "0"; "13"; "5"; "0";"16"
"14"; "6";"TILE_ILLUMINATOR_BLUE" ; "33587232"; "0"; "N/A"; "0"; "1"; "1"; "0"; "13"; "6"; "0";"16"
"14"; "7";"TILE_ILLUMINATOR_CYAN" ; "33587232"; "0"; "N/A"; "0"; "1"; "1"; "0"; "13"; "7"; "0";"16"
"14"; "8";"TILE_ILLUMINATOR_GREEN" ; "33587232"; "0"; "N/A"; "0"; "1"; "1"; "0"; "13"; "8"; "0";"16"
"14"; "9";"TILE_ILLUMINATOR_GREEN_DARK";"33587232"; "0"; "N/A"; "0"; "1"; "1"; "0"; "13"; "9"; "0";"16"
"14"; "10";"TILE_ILLUMINATOR_BROWN" ; "33587232"; "0"; "N/A"; "0"; "1"; "1"; "0"; "13"; "10"; "0";"16"
"14"; "11";"TILE_ILLUMINATOR_TAN" ; "33587232"; "0"; "N/A"; "0"; "1"; "1"; "0"; "13"; "11"; "0";"16"
"14"; "12";"TILE_ILLUMINATOR_GREY_LIGHT";"33587232"; "0"; "N/A"; "0"; "1"; "1"; "0"; "13"; "12"; "0";"16"
"14"; "13";"TILE_ILLUMINATOR_GREY_MED"; "33587232"; "0"; "N/A"; "0"; "1"; "1"; "0"; "13"; "13"; "0";"16"
"14"; "14";"TILE_ILLUMINATOR_GREY_DARK";"33587232"; "0"; "N/A"; "0"; "1"; "1"; "0"; "13"; "14"; "0";"16"
"14"; "15";"TILE_ILLUMINATOR_BLACK" ; "33587232"; "0"; "N/A"; "0"; "1"; "1"; "0"; "13"; "15"; "0";"16"
"15"; "0";"TILE_SANDSTONE" ; "33587232"; "25";"1900"; "0"; "1"; "1"; "0"; "15"; "0"; "0";"16"
"15"; "1";"TILE_SANDSTONE_WHITE" ; "33587232"; "25";"1900"; "0"; "1"; "1"; "0"; "15"; "1"; "0";"16"
"15"; "2";"TILE_SANDSTONE_RED" ; "33587232"; "25";"1900"; "0"; "1"; "1"; "0"; "15"; "2"; "0";"16"
"15"; "3";"TILE_SANDSTONE_DESERT" ; "33587232"; "25";"1900"; "0"; "1"; "1"; "0"; "15"; "3"; "0";"16"
"15"; "4";"TILE_SANDSTONE_BLACK" ; "33587232"; "25";"1900"; "0"; "1"; "1"; "0"; "15"; "4"; "0";"16"
"15"; "5";"TILE_SANDSTONE_BLACK" ; "33587232"; "25";"1900"; "0"; "1"; "1"; "0"; "15"; "5"; "0";"16"
"16"; "0";"TILE_LANTERN_IRON_REGULAR"; "8396808"; "0"; "N/A"; "0"; "0"; "0"; "267619480"; "16"; "0"; "0";"16"
"254"; "0";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"254"; "1";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"254"; "2";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"254"; "3";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"254"; "4";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"254"; "5";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"254"; "6";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"254"; "7";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"254"; "8";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"254"; "9";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"254"; "10";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"254"; "11";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"254"; "12";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"254"; "13";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"254"; "14";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"254"; "15";"TILE_LAVA" ;"260301048"; "100";"2600"; "1"; "0"; "0"; "205574144"; "N/A"; "N/A"; "0";"16"
"255"; "0";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "1";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "2";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "3";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "4";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "5";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "6";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "7";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "8";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "9";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "10";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "11";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "12";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "13";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "14";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "15";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"256"; "0";"TILE_NULL" ; "0"; "-1";"2600"; "0"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
# Friction: 0: frictionless, <16: slippery, 16: regular, >16: sticky
# Opacity/Lumcolor: 40-step RGB
# Solid: whether the tile has full collision
Can't render this file because it contains an unexpected character in line 1 and column 18.

View File

@@ -0,0 +1,873 @@
/*
* Copyright (c) 2010-2015 William Bittle http://www.dyn4j.org/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
* and the following disclaimer in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of dyn4j nor the names of its contributors may be used to endorse or
* promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Kotlin translated and modified code Copyright (c) 2016 Torvald aka skyhi14.
*/
package org.dyn4j.geometry
import org.dyn4j.Epsilon
/**
* This class represents a vector or point in 2D space.
*
*
* The operations [ChainedVector2.setMagnitude], [ChainedVector2.getNormalized],
* [ChainedVector2.project], and [ChainedVector2.normalize] require the [ChainedVector2]
* to be non-zero in length.
*
*
* Some methods also return the vector to facilitate chaining. For example:
*
* Vector a = new Vector();
* a.zero().plus(1, 2).times(2);
*
* In this Kotlin code, you can use regular operations like + - * /.
*
* |operator |function |
* |-----------|------------|
* |a + b |a.plus(b) | equivalent of plusAssign
* |a - b |a.minus(b) | equivalent of minusAssign
* |a * b |a.times(b) | equivalent of timesAssign
* |a / b |a.div(b) | equivalent of divAssign
* |a dot b |a.dot(b) | equivalent of dotAssign
* |a cross b |a.cross(b) | equivalent of crossAssign
* |!a |negate(a) |
* |a rotate th|a.rotate(th)| equivalent of rotateAssign
*
* @author William Bittle
* *
* @version 3.1.11
* *
* @since 1.0.0
*/
class ChainedVector2 {
/** The magnitude of the x component of this [ChainedVector2] */
var x: Double = 0.toDouble()
/** The magnitude of the y component of this [ChainedVector2] */
var y: Double = 0.toDouble()
/** Default constructor. */
constructor() {
}
/**
* Copy constructor.
* @param vector the [ChainedVector2] to copy from
*/
constructor(vector: ChainedVector2) {
this.x = vector.x
this.y = vector.y
}
/**
* Optional constructor.
* @param x the x component
* *
* @param y the y component
*/
constructor(x: Double, y: Double) {
this.x = x
this.y = y
}
/**
* Optional constructor.
* @param vector non-chainable Vector2
*/
constructor(vector: Vector2) {
this.x = vector.x
this.y = vector.y
}
/**
* Creates a [ChainedVector2] from the first point to the second point.
* @param x1 the x coordinate of the first point
* *
* @param y1 the y coordinate of the first point
* *
* @param x2 the x coordinate of the second point
* *
* @param y2 the y coordinate of the second point
*/
constructor(x1: Double, y1: Double, x2: Double, y2: Double) {
this.x = x2 - x1
this.y = y2 - y1
}
/**
* Creates a [ChainedVector2] from the first point to the second point.
* @param p1 the first point
* *
* @param p2 the second point
*/
constructor(p1: ChainedVector2, p2: ChainedVector2) {
this.x = p2.x - p1.x
this.y = p2.y - p1.y
}
/**
* Creates a unit length vector in the given direction.
* @param direction the direction in radians
* *
* @since 3.0.1
*/
constructor(direction: Double) {
this.x = Math.cos(direction)
this.y = Math.sin(direction)
}
/**
* Returns a copy of this [ChainedVector2].
* @return [ChainedVector2]
*/
fun copy(): ChainedVector2 {
return ChainedVector2(this.x, this.y)
}
/**
* Returns the distance from this point to the given point.
* @param x the x coordinate of the point
* *
* @param y the y coordinate of the point
* *
* @return double
*/
fun distance(x: Double, y: Double): Double {
//return Math.hypot(this.x - x, this.y - y);
val dx = this.x - x
val dy = this.y - y
return Math.sqrt(dx * dx + dy * dy)
}
/**
* Returns the distance from this point to the given point.
* @param point the point
* *
* @return double
*/
fun distance(point: ChainedVector2): Double {
//return Math.hypot(this.x - point.x, this.y - point.y);
val dx = this.x - point.x
val dy = this.y - point.y
return Math.sqrt(dx * dx + dy * dy)
}
/**
* Returns the distance from this point to the given point squared.
* @param x the x coordinate of the point
* *
* @param y the y coordinate of the point
* *
* @return double
*/
fun distanceSquared(x: Double, y: Double): Double {
//return (this.x - x) * (this.x - x) + (this.y - y) * (this.y - y);
val dx = this.x - x
val dy = this.y - y
return dx * dx + dy * dy
}
/**
* Returns the distance from this point to the given point squared.
* @param point the point
* *
* @return double
*/
fun distanceSquared(point: ChainedVector2): Double {
//return (this.x - point.x) * (this.x - point.x) + (this.y - point.y) * (this.y - point.y);
val dx = this.x - point.x
val dy = this.y - point.y
return dx * dx + dy * dy
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
override fun hashCode(): Int {
val prime = 31
var result = 1
var temp: Long
temp = java.lang.Double.doubleToLongBits(x)
result = prime * result + (temp xor temp.ushr(32)).toInt()
temp = java.lang.Double.doubleToLongBits(y)
result = prime * result + (temp xor temp.ushr(32)).toInt()
return result
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
override fun equals(obj: Any?): Boolean {
if (obj == null) return false
if (obj === this) return true
if (obj is ChainedVector2) {
return this.x == obj.x && this.y == obj.y
}
return false
}
/**
* Returns true if the x and y components of this [ChainedVector2]
* are the same as the given [ChainedVector2].
* @param vector the [ChainedVector2] to compare to
* *
* @return boolean
*/
fun equals(vector: ChainedVector2?): Boolean {
if (vector == null) return false
if (this === vector) {
return true
}
else {
return this.x == vector.x && this.y == vector.y
}
}
/**
* Returns true if the x and y components of this [ChainedVector2]
* are the same as the given x and y components.
* @param x the x coordinate of the [ChainedVector2] to compare to
* *
* @param y the y coordinate of the [ChainedVector2] to compare to
* *
* @return boolean
*/
fun equals(x: Double, y: Double): Boolean {
return this.x == x && this.y == y
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
override fun toString(): String {
val sb = StringBuilder()
sb.append("(").append(this.x).append(", ").append(this.y).append(")")
return sb.toString()
}
/**
* Sets this [ChainedVector2] to the given [ChainedVector2].
* @param vector the [ChainedVector2] to set this [ChainedVector2] to
* *
* @return [ChainedVector2] this vector
*/
fun set(vector: ChainedVector2): ChainedVector2 {
this.x = vector.x
this.y = vector.y
return this
}
/**
* Sets this [ChainedVector2] to the given [ChainedVector2].
* @param x the x component of the [ChainedVector2] to set this [ChainedVector2] to
* *
* @param y the y component of the [ChainedVector2] to set this [ChainedVector2] to
* *
* @return [ChainedVector2] this vector
*/
fun set(x: Double, y: Double): ChainedVector2 {
this.x = x
this.y = y
return this
}
/**
* Returns the x component of this [ChainedVector2].
* @return [ChainedVector2]
*/
val xComponent: ChainedVector2
get() = ChainedVector2(this.x, 0.0)
/**
* Returns the y component of this [ChainedVector2].
* @return [ChainedVector2]
*/
val yComponent: ChainedVector2
get() = ChainedVector2(0.0, this.y)
/**
* Returns the magnitude of this [ChainedVector2].
* @return double
*/
// the magnitude is just the pathagorean theorem
val magnitude: Double
get() = Math.sqrt(this.x * this.x + this.y * this.y)
/**
* Returns the magnitude of this [ChainedVector2] squared.
* @return double
*/
val magnitudeSquared: Double
get() = this.x * this.x + this.y * this.y
/**
* Sets the magnitude of the [ChainedVector2].
* @param magnitude the magnitude
* *
* @return [ChainedVector2] this vector
*/
fun setMagnitude(magnitude: Double): ChainedVector2 {
// check the given magnitude
if (Math.abs(magnitude) <= Epsilon.E) {
this.x = 0.0
this.y = 0.0
return this
}
// is this vector a zero vector?
if (this.isZero) {
return this
}
// get the magnitude
var mag = Math.sqrt(this.x * this.x + this.y * this.y)
// normalize and multiply by the new magnitude
mag = magnitude / mag
this.x *= mag
this.y *= mag
return this
}
/**
* Returns the direction of this [ChainedVector2]
* as an angle in radians.
* @return double angle in radians [-, ]
*/
val direction: Double
get() = Math.atan2(this.y, this.x)
/**
* Sets the direction of this [ChainedVector2].
* @param angle angle in radians
* *
* @return [ChainedVector2] this vector
*/
fun setDirection(angle: Double): ChainedVector2 {
//double magnitude = Math.hypot(this.x, this.y);
val magnitude = Math.sqrt(this.x * this.x + this.y * this.y)
this.x = magnitude * Math.cos(angle)
this.y = magnitude * Math.sin(angle)
return this
}
/**
* Adds the given [ChainedVector2] to this [ChainedVector2].
* @param vector the [ChainedVector2]
* *
* @return [ChainedVector2] this vector
*/
operator fun plus(vector: ChainedVector2): ChainedVector2 {
this.x += vector.x
this.y += vector.y
return this
}
/**
* Adds the given [ChainedVector2] to this [ChainedVector2].
* @param x the x component of the [ChainedVector2]
* *
* @param y the y component of the [ChainedVector2]
* *
* @return [ChainedVector2] this vector
*/
fun plus(x: Double, y: Double): ChainedVector2 {
this.x += x
this.y += y
return this
}
/**
* Adds this [ChainedVector2] and the given [ChainedVector2] returning
* a new [ChainedVector2] containing the result.
* @param vector the [ChainedVector2]
* *
* @return [ChainedVector2]
*/
fun sum(vector: ChainedVector2): ChainedVector2 {
return ChainedVector2(this.x + vector.x, this.y + vector.y)
}
/**
* Adds this [ChainedVector2] and the given [ChainedVector2] returning
* a new [ChainedVector2] containing the result.
* @param x the x component of the [ChainedVector2]
* *
* @param y the y component of the [ChainedVector2]
* *
* @return [ChainedVector2]
*/
fun sum(x: Double, y: Double): ChainedVector2 {
return ChainedVector2(this.x + x, this.y + y)
}
/**
* Subtracts the given [ChainedVector2] from this [ChainedVector2].
* @param vector the [ChainedVector2]
* *
* @return [ChainedVector2] this vector
*/
operator fun minus(vector: ChainedVector2): ChainedVector2 {
this.x -= vector.x
this.y -= vector.y
return this
}
/**
* Subtracts the given [ChainedVector2] from this [ChainedVector2].
* @param x the x component of the [ChainedVector2]
* *
* @param y the y component of the [ChainedVector2]
* *
* @return [ChainedVector2] this vector
*/
fun minus(x: Double, y: Double): ChainedVector2 {
this.x -= x
this.y -= y
return this
}
/**
* Subtracts the given [ChainedVector2] from this [ChainedVector2] returning
* a new [ChainedVector2] containing the result.
* @param vector the [ChainedVector2]
* *
* @return [ChainedVector2]
*/
fun difference(vector: ChainedVector2): ChainedVector2 {
return ChainedVector2(this.x - vector.x, this.y - vector.y)
}
/**
* Subtracts the given [ChainedVector2] from this [ChainedVector2] returning
* a new [ChainedVector2] containing the result.
* @param x the x component of the [ChainedVector2]
* *
* @param y the y component of the [ChainedVector2]
* *
* @return [ChainedVector2]
*/
fun difference(x: Double, y: Double): ChainedVector2 {
return ChainedVector2(this.x - x, this.y - y)
}
/**
* Creates a [ChainedVector2] from this [ChainedVector2] to the given [ChainedVector2].
* @param vector the [ChainedVector2]
* *
* @return [ChainedVector2]
*/
fun to(vector: ChainedVector2): ChainedVector2 {
return ChainedVector2(vector.x - this.x, vector.y - this.y)
}
/**
* Creates a [ChainedVector2] from this [ChainedVector2] to the given [ChainedVector2].
* @param x the x component of the [ChainedVector2]
* *
* @param y the y component of the [ChainedVector2]
* *
* @return [ChainedVector2]
*/
fun to(x: Double, y: Double): ChainedVector2 {
return ChainedVector2(x - this.x, y - this.y)
}
/**
* Multiplies this [ChainedVector2] by the given scalar.
* @param scalar the scalar
* *
* @return [ChainedVector2] this vector
*/
operator fun times(scalar: Double): ChainedVector2 {
this.x *= scalar
this.y *= scalar
return this
}
/**
* Multiplies this [ChainedVector2] by the given scalar.
* @param scalar the scalar
* *
* @return [ChainedVector2] this vector
*/
operator fun div(scalar: Double): ChainedVector2 {
this.x /= scalar
this.y /= scalar
return this
}
/**
* Multiplies this [ChainedVector2] by the given scalar returning
* a new [ChainedVector2] containing the result.
* @param scalar the scalar
* *
* @return [ChainedVector2]
*/
infix fun product(scalar: Double): ChainedVector2 {
return ChainedVector2(this.x * scalar, this.y * scalar)
}
/**
* Returns the dot product of the given [ChainedVector2]
* and this [ChainedVector2].
* @param vector the [ChainedVector2]
* *
* @return double
*/
infix fun dot(vector: ChainedVector2): Double {
return this.x * vector.x + this.y * vector.y
}
/**
* Returns the dot product of the given [ChainedVector2]
* and this [ChainedVector2].
* @param x the x component of the [ChainedVector2]
* *
* @param y the y component of the [ChainedVector2]
* *
* @return double
*/
fun dot(x: Double, y: Double): Double {
return this.x * x + this.y * y
}
/**
* Returns the cross product of the this [ChainedVector2] and the given [ChainedVector2].
* @param vector the [ChainedVector2]
* *
* @return double
*/
infix fun cross(vector: ChainedVector2): Double {
return this.x * vector.y - this.y * vector.x
}
/**
* Returns the cross product of the this [ChainedVector2] and the given [ChainedVector2].
* @param x the x component of the [ChainedVector2]
* *
* @param y the y component of the [ChainedVector2]
* *
* @return double
*/
fun cross(x: Double, y: Double): Double {
return this.x * y - this.y * x
}
/**
* Returns the cross product of this [ChainedVector2] and the z value of the right [ChainedVector2].
* @param z the z component of the [ChainedVector2]
* *
* @return [ChainedVector2]
*/
infix fun cross(z: Double): ChainedVector2 {
return ChainedVector2(-1.0 * this.y * z, this.x * z)
}
/**
* Returns true if the given [ChainedVector2] is orthogonal (perpendicular)
* to this [ChainedVector2].
*
*
* If the dot product of this vector and the given vector is
* zero then we know that they are perpendicular
* @param vector the [ChainedVector2]
* *
* @return boolean
*/
fun isOrthogonal(vector: ChainedVector2): Boolean {
return if (Math.abs(this.x * vector.x + this.y * vector.y) <= Epsilon.E) true else false
}
/**
* Returns true if the given [ChainedVector2] is orthogonal (perpendicular)
* to this [ChainedVector2].
*
*
* If the dot product of this vector and the given vector is
* zero then we know that they are perpendicular
* @param x the x component of the [ChainedVector2]
* *
* @param y the y component of the [ChainedVector2]
* *
* @return boolean
*/
fun isOrthogonal(x: Double, y: Double): Boolean {
return if (Math.abs(this.x * x + this.y * y) <= Epsilon.E) true else false
}
/**
* Returns true if this [ChainedVector2] is the zero [ChainedVector2].
* @return boolean
*/
val isZero: Boolean
get() = Math.abs(this.x) <= Epsilon.E && Math.abs(this.y) <= Epsilon.E
/**
* Negates this [ChainedVector2].
* @return [ChainedVector2] this vector
*/
operator fun not() = negate()
/**
* Negates this [ChainedVector2].
* @return [ChainedVector2] this vector
*/
fun negate(): ChainedVector2 {
this.x *= -1.0
this.y *= -1.0
return this
}
/**
* Returns a [ChainedVector2] which is the negative of this [ChainedVector2].
* @return [ChainedVector2]
*/
val negative: ChainedVector2
get() = ChainedVector2(-this.x, -this.y)
/**
* Sets the [ChainedVector2] to the zero [ChainedVector2]
* @return [ChainedVector2] this vector
*/
fun zero(): ChainedVector2 {
this.x = 0.0
this.y = 0.0
return this
}
/**
* Rotates about the origin.
* @param theta the rotation angle in radians
* *
* @return [ChainedVector2] this vector
*/
infix fun rotate(theta: Double): ChainedVector2 {
val cos = Math.cos(theta)
val sin = Math.sin(theta)
val x = this.x
val y = this.y
this.x = x * cos - y * sin
this.y = x * sin + y * cos
return this
}
/**
* Rotates the [ChainedVector2] about the given coordinates.
* @param theta the rotation angle in radians
* *
* @param x the x coordinate to rotate about
* *
* @param y the y coordinate to rotate about
* *
* @return [ChainedVector2] this vector
*/
fun rotate(theta: Double, x: Double, y: Double): ChainedVector2 {
this.x -= x
this.y -= y
this.rotate(theta)
this.x += x
this.y += y
return this
}
/**
* Rotates the [ChainedVector2] about the given point.
* @param theta the rotation angle in radians
* *
* @param point the point to rotate about
* *
* @return [ChainedVector2] this vector
*/
fun rotate(theta: Double, point: ChainedVector2): ChainedVector2 {
return this.rotate(theta, point.x, point.y)
}
/**
* Projects this [ChainedVector2] onto the given [ChainedVector2].
* @param vector the [ChainedVector2]
* *
* @return [ChainedVector2] the projected [ChainedVector2]
*/
fun project(vector: ChainedVector2): ChainedVector2 {
val dotProd = this.dot(vector)
var denominator = vector.dot(vector)
if (denominator <= Epsilon.E) return ChainedVector2()
denominator = dotProd / denominator
return ChainedVector2(denominator * vector.x, denominator * vector.y)
}
/**
* Returns the right-handed normal of this vector.
* @return [ChainedVector2] the right hand orthogonal [ChainedVector2]
*/
val rightHandOrthogonalVector: ChainedVector2
get() = ChainedVector2(-this.y, this.x)
/**
* Sets this vector to the right-handed normal of this vector.
* @return [ChainedVector2] this vector
* *
* @see .getRightHandOrthogonalVector
*/
fun right(): ChainedVector2 {
val temp = this.x
this.x = -this.y
this.y = temp
return this
}
/**
* Returns the left-handed normal of this vector.
* @return [ChainedVector2] the left hand orthogonal [ChainedVector2]
*/
val leftHandOrthogonalVector: ChainedVector2
get() = ChainedVector2(this.y, -this.x)
/**
* Sets this vector to the left-handed normal of this vector.
* @return [ChainedVector2] this vector
* *
* @see .getLeftHandOrthogonalVector
*/
fun left(): ChainedVector2 {
val temp = this.x
this.x = this.y
this.y = -temp
return this
}
/**
* Returns a unit [ChainedVector2] of this [ChainedVector2].
*
*
* This method requires the length of this [ChainedVector2] is not zero.
* @return [ChainedVector2]
*/
val normalized: ChainedVector2
get() {
var magnitude = this.magnitude
if (magnitude <= Epsilon.E) return ChainedVector2()
magnitude = 1.0 / magnitude
return ChainedVector2(this.x * magnitude, this.y * magnitude)
}
/**
* Converts this [ChainedVector2] into a unit [ChainedVector2] and returns
* the magnitude before normalization.
*
*
* This method requires the length of this [ChainedVector2] is not zero.
* @return double
*/
fun normalize(): Double {
val magnitude = Math.sqrt(this.x * this.x + this.y * this.y)
if (magnitude <= Epsilon.E) return 0.0
val m = 1.0 / magnitude
this.x *= m
this.y *= m
//return 1.0 / m;
return magnitude
}
/**
* Returns the smallest angle between the given [ChainedVector2]s.
*
*
* Returns the angle in radians in the range - to .
* @param vector the [ChainedVector2]
* *
* @return angle in radians [-, ]
*/
fun getAngleBetween(vector: ChainedVector2): Double {
val a = Math.atan2(vector.y, vector.x) - Math.atan2(this.y, this.x)
if (a > Math.PI) return a - 2.0 * Math.PI
if (a < -Math.PI) return a + 2.0 * Math.PI
return a
}
fun toVector(): Vector2 {
return Vector2(x, y)
}
companion object {
/** A vector representing the x-axis; this vector should not be changed at runtime; used internally */
internal val X_AXIS = ChainedVector2(1.0, 0.0)
/** A vector representing the y-axis; this vector should not be changed at runtime; used internally */
internal val Y_AXIS = ChainedVector2(0.0, 1.0)
/**
* Returns a new [ChainedVector2] given the magnitude and direction.
* @param magnitude the magnitude of the [ChainedVector2]
* *
* @param direction the direction of the [ChainedVector2] in radians
* *
* @return [ChainedVector2]
*/
fun create(magnitude: Double, direction: Double): ChainedVector2 {
val x = magnitude * Math.cos(direction)
val y = magnitude * Math.sin(direction)
return ChainedVector2(x, y)
}
/**
* The triple product of [ChainedVector2]s is defined as:
*
* a x (b x c)
*
* However, this method performs the following triple product:
*
* (a x b) x c
*
* this can be simplified to:
*
* -a * (b c) + b * (a c)
*
* or:
*
* b * (a c) - a * (b c)
*
* @param a the a [ChainedVector2] in the above equation
* *
* @param b the b [ChainedVector2] in the above equation
* *
* @param c the c [ChainedVector2] in the above equation
* *
* @return [ChainedVector2]
*/
fun tripleProduct(a: ChainedVector2, b: ChainedVector2, c: ChainedVector2): ChainedVector2 {
// expanded version of above formula
val r = ChainedVector2()
// perform a.dot(c)
val ac = a.x * c.x + a.y * c.y
// perform b.dot(c)
val bc = b.x * c.x + b.y * c.y
// perform b * a.dot(c) - a * b.dot(c)
r.x = b.x * ac - a.x * bc
r.y = b.y * ac - a.y * bc
return r
}
}
}

View File

@@ -38,23 +38,24 @@ import org.dyn4j.Epsilon
* to be non-zero in length.
*
*
* Some methods also return the vector to facilitate chaining. For example:
*
* Vector a = new Vector();
* a.zero().plus(1, 2).times(2);
* Chaining is not available.
*
* In this Kotlin code, you can use regular operations like + - * /.
*
* |operator|function|
* |--------|--------|
* |a + b|a.plus(b)|
* |a - b|a.minus(b)|
* |a * b|a.times(b)|
* |a / b|a.div(b)|
* |a dot b|a.dot(b)|
* |a cross b|a.cross(b)|
* |!a|negate(a)|
* |a rotate th|a.rotate(th)|
* |operator |function |
* |-----------|------------|
* |a + b |Vector(a).plus(b) |
* |a - b |Vector(a).minus(b) |
* |a * b |Vector(a).times(b) |
* |a / b |Vector(a).div(b) |
* |a += b |Vector(a).plusAssign(b)|
* |a -= b |Vector(a).minusAssign(b)|
* |a *= b |Vector(a).timesAssign(b)|
* |a /= b |Vector(a).divAssign(b)|
* |a dot b |Vector(a).dot(b) |
* |a cross b |Vector(a).cross(b) |
* |!a |Vector(negate(a) |
* |a rotate th|Vector(a).rotate(th)|
*
* @author William Bittle
* *
@@ -370,47 +371,12 @@ class Vector2 {
* @return [Vector2] this vector
*/
operator fun plus(vector: Vector2): Vector2 {
this.x += vector.x
this.y += vector.y
return this
}
/**
* Adds the given [Vector2] to this [Vector2].
* @param x the x component of the [Vector2]
* *
* @param y the y component of the [Vector2]
* *
* @return [Vector2] this vector
*/
fun plus(x: Double, y: Double): Vector2 {
this.x += x
this.y += y
return this
}
/**
* Adds this [Vector2] and the given [Vector2] returning
* a new [Vector2] containing the result.
* @param vector the [Vector2]
* *
* @return [Vector2]
*/
fun sum(vector: Vector2): Vector2 {
return Vector2(this.x + vector.x, this.y + vector.y)
}
/**
* Adds this [Vector2] and the given [Vector2] returning
* a new [Vector2] containing the result.
* @param x the x component of the [Vector2]
* *
* @param y the y component of the [Vector2]
* *
* @return [Vector2]
*/
fun sum(x: Double, y: Double): Vector2 {
return Vector2(this.x + x, this.y + y)
operator fun plusAssign(vector: Vector2) {
this.x += vector.x
this.y += vector.y
}
/**
@@ -420,47 +386,12 @@ class Vector2 {
* @return [Vector2] this vector
*/
operator fun minus(vector: Vector2): Vector2 {
this.x -= vector.x
this.y -= vector.y
return this
}
/**
* Subtracts the given [Vector2] from this [Vector2].
* @param x the x component of the [Vector2]
* *
* @param y the y component of the [Vector2]
* *
* @return [Vector2] this vector
*/
fun minus(x: Double, y: Double): Vector2 {
this.x -= x
this.y -= y
return this
}
/**
* Subtracts the given [Vector2] from this [Vector2] returning
* a new [Vector2] containing the result.
* @param vector the [Vector2]
* *
* @return [Vector2]
*/
fun difference(vector: Vector2): Vector2 {
return Vector2(this.x - vector.x, this.y - vector.y)
}
/**
* Subtracts the given [Vector2] from this [Vector2] returning
* a new [Vector2] containing the result.
* @param x the x component of the [Vector2]
* *
* @param y the y component of the [Vector2]
* *
* @return [Vector2]
*/
fun difference(x: Double, y: Double): Vector2 {
return Vector2(this.x - x, this.y - y)
operator fun minusAssign(vector: Vector2) {
this.x -= vector.x
this.y -= vector.y
}
/**
@@ -473,18 +404,6 @@ class Vector2 {
return Vector2(vector.x - this.x, vector.y - this.y)
}
/**
* Creates a [Vector2] from this [Vector2] to the given [Vector2].
* @param x the x component of the [Vector2]
* *
* @param y the y component of the [Vector2]
* *
* @return [Vector2]
*/
fun to(x: Double, y: Double): Vector2 {
return Vector2(x - this.x, y - this.y)
}
/**
* Multiplies this [Vector2] by the given scalar.
* @param scalar the scalar
@@ -492,9 +411,12 @@ class Vector2 {
* @return [Vector2] this vector
*/
operator fun times(scalar: Double): Vector2 {
return Vector2(this.x * scalar, this.y * scalar)
}
operator fun timesAssign(scalar: Double) {
this.x *= scalar
this.y *= scalar
return this
}
/**
@@ -504,9 +426,12 @@ class Vector2 {
* @return [Vector2] this vector
*/
operator fun div(scalar: Double): Vector2 {
return Vector2(this.x / scalar, this.y / scalar)
}
operator fun divAssign(scalar: Double) {
this.x /= scalar
this.y /= scalar
return this
}
/**
@@ -626,9 +551,7 @@ class Vector2 {
* @return [Vector2] this vector
*/
fun negate(): Vector2 {
this.x *= -1.0
this.y *= -1.0
return this
return Vector2(x * -1.0, y * -1.0)
}
/**
@@ -659,40 +582,9 @@ class Vector2 {
val sin = Math.sin(theta)
val x = this.x
val y = this.y
this.x = x * cos - y * sin
this.y = x * sin + y * cos
return this
}
/**
* Rotates the [Vector2] about the given coordinates.
* @param theta the rotation angle in radians
* *
* @param x the x coordinate to rotate about
* *
* @param y the y coordinate to rotate about
* *
* @return [Vector2] this vector
*/
fun rotate(theta: Double, x: Double, y: Double): Vector2 {
this.x -= x
this.y -= y
this.rotate(theta)
this.x += x
this.y += y
return this
}
/**
* Rotates the [Vector2] about the given point.
* @param theta the rotation angle in radians
* *
* @param point the point to rotate about
* *
* @return [Vector2] this vector
*/
fun rotate(theta: Double, point: Vector2): Vector2 {
return this.rotate(theta, point.x, point.y)
val newX = x * cos - y * sin
val newY = x * sin + y * cos
return Vector2(newX, newY)
}
/**