202 lines
6 KiB
Nim
202 lines
6 KiB
Nim
# Copyright (c) 2018 Xored Software, Inc.
|
|
|
|
import math, godotbase, hashes
|
|
|
|
import internal/godotinternaltypes, internal/godotstrings
|
|
import godotcoretypes, gdnativeapi
|
|
|
|
{.push stackTrace: off.}
|
|
|
|
proc vec2*(): Vector2 {.inline, noinit.} =
|
|
Vector2()
|
|
|
|
proc vec2*(x, y: float32): Vector2 {.inline, noinit.} =
|
|
Vector2(x: x, y: y)
|
|
|
|
proc `$`*(self: Vector2): string {.inline, noinit.} =
|
|
$getGDNativeAPI().vector2AsString(self)
|
|
|
|
proc hash*(self: Vector2): Hash {.inline, noinit.} =
|
|
!$(self.x.hash() !& self.y.hash())
|
|
|
|
proc `+`*(self, other: Vector2): Vector2 {.inline, noinit.} =
|
|
Vector2(x: self.x + other.x, y: self.y + other.y)
|
|
|
|
proc `+=`*(self: var Vector2, other: Vector2) {.inline, noinit.} =
|
|
self.x += other.x
|
|
self.y += other.y
|
|
|
|
proc `-`*(self, other: Vector2): Vector2 {.inline, noinit.} =
|
|
Vector2(x: self.x - other.x, y: self.y - other.y)
|
|
|
|
proc `-=`*(self: var Vector2, other: Vector2) {.inline, noinit.} =
|
|
self.x -= other.x
|
|
self.y -= other.y
|
|
|
|
proc `*`*(self, other: Vector2): Vector2 {.inline, noinit.} =
|
|
Vector2(x: self.x * other.x, y: self.y * other.y)
|
|
|
|
proc `*=`*(self: var Vector2, other: Vector2) {.inline, noinit.} =
|
|
self.x *= other.x
|
|
self.y *= other.y
|
|
|
|
proc `*`*(self: Vector2, scalar: float32): Vector2 {.inline, noinit.} =
|
|
Vector2(x: self.x * scalar, y: self.y * scalar)
|
|
|
|
proc `*`*(scalar: float32, v: Vector2): Vector2 {.inline, noinit.} =
|
|
v * scalar
|
|
|
|
proc `*=`*(self: var Vector2, scalar: float32) {.inline, noinit.} =
|
|
self.x *= scalar
|
|
self.y *= scalar
|
|
|
|
proc `/`*(self, other: Vector2): Vector2 {.inline, noinit.} =
|
|
Vector2(x: self.x / other.x, y: self.y / other.y)
|
|
|
|
proc `/=`*(self: var Vector2, other: Vector2) {.inline, noinit.} =
|
|
self.x /= other.x
|
|
self.y /= other.y
|
|
|
|
proc `/`*(self: Vector2; scalar: float32): Vector2 {.inline, noinit.} =
|
|
Vector2(x: self.x / scalar, y: self.y / scalar)
|
|
|
|
proc `/=`*(self: var Vector2; scalar: float32) {.inline, noinit.} =
|
|
self = self / scalar
|
|
|
|
proc `==`*(self, other: Vector2): bool {.inline, noinit.} =
|
|
self.x == other.x and self.y == other.y
|
|
|
|
proc `<`*(self, other: Vector2): bool {.inline, noinit.} =
|
|
if self.x == other.x:
|
|
self.y < other.y
|
|
else:
|
|
self.x < other.x
|
|
|
|
proc `>`*(self, other: Vector2): bool {.inline, noinit.} =
|
|
if self.x == other.x:
|
|
self.y > other.y
|
|
else:
|
|
self.x > other.x
|
|
|
|
proc `-`*(self: Vector2): Vector2 {.inline, noinit.} =
|
|
Vector2(x: -self.x, y: -self.y)
|
|
|
|
proc length*(self: Vector2): float32 {.inline, noinit.} =
|
|
sqrt(self.x * self.x + self.y * self.y)
|
|
|
|
proc lengthSquared*(self: Vector2): float32 {.inline, noinit.} =
|
|
self.x * self.x + self.y * self.y
|
|
|
|
proc normalize*(self: var Vector2) {.inline.} =
|
|
var len = self.x * self.x + self.y * self.y
|
|
if len != 0:
|
|
len = sqrt(len)
|
|
self.x /= len
|
|
self.y /= len
|
|
|
|
proc normalized*(self: Vector2): Vector2 {.inline, noinit.} =
|
|
result = self
|
|
result.normalize()
|
|
|
|
proc angle*(self: Vector2): float32 {.inline, noinit.} =
|
|
arctan2(self.y, self.x)
|
|
|
|
proc isNormalized*(self: Vector2): bool {.inline, noinit.} =
|
|
isEqualApprox(self.lengthSquared(), 1.0)
|
|
|
|
proc distanceTo*(self, to: Vector2): float32 {.inline, noinit.} =
|
|
sqrt((self.x - to.x) * (self.x - to.x) + (self.y - to.y) * (self.y - to.y))
|
|
|
|
proc distanceSquaredTo*(self, to: Vector2): float32 {.inline, noinit.} =
|
|
(self.x - to.x) * (self.x - to.x) + (self.y - to.y) * (self.y - to.y)
|
|
|
|
proc dot*(a, b: Vector2): float32 {.inline, noinit.} =
|
|
a.x * b.x + a.y * b.y
|
|
|
|
proc cross*(a, b: Vector2): float32 {.inline, noinit.} =
|
|
a.x * b.y - a.y * b.x
|
|
|
|
proc cross*(self: Vector2, scalar: float32): Vector2 {.inline, noinit.} =
|
|
Vector2(x: scalar * self.y, y: -scalar * self.x)
|
|
|
|
proc angleTo*(self, to: Vector2): float32 {.noinit.} =
|
|
arctan2(cross(self, to), dot(self, to))
|
|
|
|
proc angleToPoint*(self, to: Vector2): float32 {.inline, noinit.} =
|
|
arctan2(self.y - to.y, self.x - to.x)
|
|
|
|
proc floor*(self: Vector2): Vector2 {.inline, noinit.} =
|
|
Vector2(x: floor(self.x), y: floor(self.y))
|
|
|
|
proc planeProject*(self: Vector2, d: float32,
|
|
vec: Vector2): Vector2 {.noinit.} =
|
|
vec - self * (self.dot(vec) - d)
|
|
|
|
proc project*(self, other: Vector2): Vector2 {.noinit.} =
|
|
self * (other.dot(self) / self.dot(self))
|
|
|
|
proc lerp*(self, b: Vector2; t: float32): Vector2 {.inline, noinit.} =
|
|
result = self
|
|
result.x += t * (b.x - self.x)
|
|
result.y += t * (b.y - self.y)
|
|
|
|
proc cubicInterpolate*(self, b, preA, postB: Vector2;
|
|
t: float32): Vector2 {.noinit.} =
|
|
let p0 = preA
|
|
let p1 = self
|
|
let p2 = b
|
|
let p3 = postB
|
|
|
|
let t2 = t * t
|
|
let t3 = t2 * t
|
|
|
|
result = 0.5'f32 * ((p1 * 2.0'f32)) +
|
|
(-p0 + p2) * t +
|
|
(2.0 * p0 - 5.0 * p1 + 4 * p2 - p3) * t2 +
|
|
(-p0 + 3.0 * p1 - 3.0 * p2 + p3) * t3
|
|
|
|
proc setRotation*(self: var Vector2, radians: float32) {.inline, noinit.} =
|
|
self.x = cos(radians)
|
|
self.y = sin(radians)
|
|
|
|
proc rotated*(self: Vector2; phi: float32): Vector2 {.inline, noinit.} =
|
|
result.setRotation(phi)
|
|
result *= self.length()
|
|
|
|
proc tangent*(self: Vector2): Vector2 {.inline, noinit.} =
|
|
Vector2(x: self.y, y: -self.x)
|
|
|
|
proc snapped*(self: Vector2; by: Vector2): Vector2 {.inline, noinit.} =
|
|
Vector2(x: stepify(self.x, by.x), y: stepify(self.y, by.y))
|
|
|
|
proc aspect*(self: Vector2): float32 {.inline, noinit.} =
|
|
self.x / self.y
|
|
|
|
proc slide*(self, n: Vector2): Vector2 {.noinit.} =
|
|
when not defined(release):
|
|
if not n.isNormalized():
|
|
printError("Normal not normalized in slide. " & getStackTrace())
|
|
return vec2()
|
|
result = self - n * self.dot(n)
|
|
|
|
proc reflect*(self, n: Vector2): Vector2 {.noinit.} =
|
|
when not defined(release):
|
|
if not n.isNormalized():
|
|
printError("Normal not normalized in bounce. " & getStackTrace())
|
|
return vec2()
|
|
result = 2.0 * n * self.dot(n) - self
|
|
|
|
proc bounce*(self, n: Vector2): Vector2 {.inline, noinit.} =
|
|
-self.reflect(n)
|
|
|
|
proc abs*(self: Vector2): Vector2 {.inline, noinit.} =
|
|
Vector2(x: abs(self.x), y: abs(self.y))
|
|
|
|
proc clamped*(self: Vector2; length: float32): Vector2 {.noinit.} =
|
|
let len = self.length()
|
|
result = self
|
|
if len > 0 and length < len:
|
|
result /= len
|
|
result *= length
|
|
|
|
{.pop.} # stackTrace: off
|