Implement Vector2 and Rect2 procs
This allows compiler to inline/optimize them, which cannot be done if these procs are invoked via GDNative API.
This commit is contained in:
parent
0aab6e17ef
commit
d11856377e
7 changed files with 346 additions and 148 deletions
|
|
@ -1,4 +1,4 @@
|
|||
version = "0.7.5"
|
||||
version = "0.7.6"
|
||||
author = "Xored Software, Inc."
|
||||
description = "Godot Engine bindings"
|
||||
license = "MIT"
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import math
|
|||
import godotbase, vector3, quats
|
||||
import godotcoretypes
|
||||
|
||||
{.push stackTrace: off.}
|
||||
|
||||
proc setCells*(basis: var Basis, xx, xy, xz, yx, yy, yz, zx, zy, zz: float32) =
|
||||
basis.elements[0].x = xx
|
||||
basis.elements[0].y = xy
|
||||
|
|
@ -449,3 +451,5 @@ proc rotate*(self: var Vector3; axis: Vector3; phi: float32) =
|
|||
proc rotated*(self: Vector3; axis: Vector3; phi: float32): Vector3 =
|
||||
result = self
|
||||
result.rotate(axis, phi)
|
||||
|
||||
{.pop.} # stackTrace: off
|
||||
|
|
@ -1,30 +1,61 @@
|
|||
# Copyright (c) 2018 Xored Software, Inc.
|
||||
|
||||
import math
|
||||
import math, godotinternal
|
||||
|
||||
# math helpers
|
||||
|
||||
{.push stackTrace: off.}
|
||||
const EPSILON = 0.00001'f32
|
||||
proc isEqualApprox*(a, b: float32): bool {.inline.} =
|
||||
proc isEqualApprox*(a, b: float32): bool {.inline, noinit.} =
|
||||
abs(a - b) < EPSILON
|
||||
|
||||
proc isEqualApprox*(a, b: float64): bool {.inline.} =
|
||||
proc isEqualApprox*(a, b: float64): bool {.inline, noinit.} =
|
||||
abs(a - b) < EPSILON
|
||||
|
||||
proc sign*(a: float32): float32 {.inline.} =
|
||||
proc sign*(a: float32): float32 {.inline, noinit.} =
|
||||
if a < 0: -1.0'f32 else: 1.0'f32
|
||||
|
||||
proc sign*(a: float64): float64 {.inline.} =
|
||||
proc sign*(a: float64): float64 {.inline, noinit.} =
|
||||
if a < 0: -1.0'f64 else: 1.0'f64
|
||||
|
||||
proc stepify*(value, step: float64): float64 =
|
||||
proc stepify*(value, step: float64): float64 {.inline, noinit.} =
|
||||
if step != 0'f64:
|
||||
floor(value / step + 0.5'f64) * step
|
||||
else:
|
||||
value
|
||||
|
||||
proc stepify*(value, step: float32): float32 =
|
||||
proc stepify*(value, step: float32): float32 {.inline, noinit.} =
|
||||
if step != 0'f32:
|
||||
floor(value / step + 0.5'f32) * step
|
||||
else:
|
||||
value
|
||||
|
||||
proc min*(x, y: float32): float32 {.inline, noinit.} =
|
||||
if x <= y: x else: y
|
||||
|
||||
proc abs*(x: float32): float32 {.inline, noinit.} =
|
||||
if x < 0.0: -x else: x
|
||||
|
||||
proc max*(x, y: float32): float32 {.inline, noinit.} =
|
||||
if y <= x: x else: y
|
||||
|
||||
{.pop.} # stackTrace: off
|
||||
|
||||
template printWarning*(warning: typed) =
|
||||
## Prints ``warning`` to Godot log, adding filename and line information.
|
||||
let (filename, line) = instantiationInfo()
|
||||
godotPrintWarning(cstring($warning), cstring"", cstring(filename), line.cint)
|
||||
|
||||
template printError*(error: typed) =
|
||||
## Prints ``error`` to Godot log, adding filename and line information.
|
||||
let (filename, line) = instantiationInfo()
|
||||
godotPrintError(cstring($error), cstring"", cstring(filename), line.cint)
|
||||
|
||||
proc print*(parts: varargs[string, `$`]) =
|
||||
## Prints concatenated ``parts`` to Godot log.
|
||||
var combined = ""
|
||||
for v in parts:
|
||||
combined.add(v)
|
||||
var s = combined.toGodotString()
|
||||
godotPrint(s)
|
||||
s.deinit()
|
||||
|
|
|
|||
|
|
@ -4,41 +4,145 @@ import vector2
|
|||
import internal.godotinternaltypes, internal.godotstrings
|
||||
import godotcoretypes, gdnativeapi
|
||||
|
||||
proc initRect2*(pos, size: Vector2): Rect2 {.inline.} =
|
||||
{.push stackTrace: off.}
|
||||
|
||||
proc initRect2*(): Rect2 {.inline, noinit.} =
|
||||
Rect2()
|
||||
|
||||
proc initRect2*(pos, size: Vector2): Rect2 {.inline, noinit.} =
|
||||
Rect2(position: pos, size: size)
|
||||
|
||||
proc initRect2*(x, y, sizeX, sizeY: float32): Rect2 {.inline.} =
|
||||
proc initRect2*(x, y, sizeX, sizeY: float32): Rect2 {.inline, noinit.} =
|
||||
Rect2(position: vec2(x, y), size: vec2(sizeX, sizeY))
|
||||
|
||||
proc `$`*(self: Rect2): string {.inline.} =
|
||||
$getGDNativeAPI().rect2AsString(self)
|
||||
|
||||
proc area*(self: Rect2): float32 {.inline.} =
|
||||
getGDNativeAPI().rect2GetArea(self)
|
||||
proc area*(self: Rect2): float32 {.inline, noinit.} =
|
||||
self.size.x * self.size.y
|
||||
|
||||
proc intersects*(a, b: Rect2): bool {.inline.} =
|
||||
getGDNativeAPI().rect2Intersects(a, b)
|
||||
proc intersects*(a, b: Rect2): bool {.inline, noinit.} =
|
||||
if a.position.x >= (b.position.x + b.size.x):
|
||||
return false
|
||||
if a.position.x + a.size.x <= b.position.x:
|
||||
return false
|
||||
if a.position.y >= (b.position.y + b.size.y):
|
||||
return false
|
||||
if a.position.y + a.size.y <= b.position.y:
|
||||
return false
|
||||
result = true
|
||||
|
||||
proc encloses*(a, b: Rect2): bool {.inline.} =
|
||||
getGDNativeAPI().rect2Encloses(a, b)
|
||||
proc distanceTo*(self: Rect2, p: Vector2): float32 {.noinit.} =
|
||||
var inside = true
|
||||
if p.x < self.position.x:
|
||||
let d = self.position.x - p.x
|
||||
result = d
|
||||
inside = false
|
||||
if p.y < self.position.y:
|
||||
let d = self.position.y - p.y
|
||||
result = if inside: d else: min(result, d)
|
||||
inside = false
|
||||
if p.x >= (self.position.x + self.size.x):
|
||||
let d = p.x - (self.position.x + self.size.x)
|
||||
result = if inside: d else: min(result, d)
|
||||
inside = false
|
||||
if p.y >= (self.position.y + self.size.y):
|
||||
let d = p.y - (self.position.y + self.size.y)
|
||||
result = if inside: d else: min(result, d)
|
||||
inside = false
|
||||
|
||||
proc hasNoArea*(self: Rect2): bool {.inline.} =
|
||||
getGDNativeAPI().rect2HasNoArea(self)
|
||||
if inside:
|
||||
result = 0'f32
|
||||
|
||||
proc clip*(self, b: Rect2): Rect2 {.inline.} =
|
||||
getGDNativeAPI().rect2Clip(self, b)
|
||||
proc encloses*(a, b: Rect2): bool {.inline, noinit.} =
|
||||
b.position.x >= a.position.x and b.position.y >= a.position.y and
|
||||
(b.position.x + b.size.x) < (a.position.x + a.size.x) and
|
||||
(b.position.y + b.size.y) < (a.position.y + a.size.y)
|
||||
|
||||
proc merge*(self, b: Rect2): Rect2 {.inline.} =
|
||||
getGDNativeAPI().rect2Merge(self, b)
|
||||
proc hasNoArea*(self: Rect2): bool {.inline, noinit.} =
|
||||
self.size.x <= 0 or self.size.y <= 0
|
||||
|
||||
proc contains*(self: Rect2; point: Vector2): bool {.inline.} =
|
||||
getGDNativeAPI().rect2HasPoint(self, point)
|
||||
proc clip*(self, b: Rect2): Rect2 {.inline, noinit.} =
|
||||
if not self.intersects(b):
|
||||
return initRect2()
|
||||
|
||||
proc grow*(self: Rect2; by: float32): Rect2 {.inline.} =
|
||||
getGDNativeAPI().rect2Grow(self, by)
|
||||
result = self
|
||||
|
||||
proc expand*(self: Rect2; to: Vector2): Rect2 {.inline.} =
|
||||
getGDNativeAPI().rect2Expand(self, to)
|
||||
result.position.x = max(b.position.x, self.position.x)
|
||||
result.position.y = max(b.position.y, self.position.y)
|
||||
|
||||
proc `==`*(a, b: Rect2): bool {.inline.} =
|
||||
getGDNativeAPI().rect2OperatorEqual(a, b)
|
||||
let bEnd = b.position + b.size
|
||||
let selfEnd = self.position + self.size
|
||||
|
||||
result.size.x = min(bEnd.x, selfEnd.x) - result.position.x
|
||||
result.size.y = min(bEnd.y, selfEnd.y) - result.position.y
|
||||
|
||||
proc merge*(self, b: Rect2): Rect2 {.inline, noinit.} =
|
||||
result.position.x = min(b.position.x, self.position.x)
|
||||
result.position.y = min(b.position.y, self.position.y)
|
||||
|
||||
result.size.x = max(b.position.x + b.size.x, self.position.x + self.size.x)
|
||||
result.size.y = max(b.position.y + b.size.y, self.position.y + self.size.y)
|
||||
result.size -= result.position
|
||||
|
||||
proc contains*(self: Rect2; point: Vector2): bool {.inline, noinit.} =
|
||||
if point.x < self.position.x:
|
||||
return false
|
||||
if point.y < self.position.y:
|
||||
return false
|
||||
|
||||
if point.x >= self.position.x + self.size.x:
|
||||
return false
|
||||
if point.y >= self.position.y + self.size.y:
|
||||
return false
|
||||
|
||||
result = true
|
||||
|
||||
proc grow*(self: Rect2; by: float32): Rect2 {.inline, noinit.} =
|
||||
## Returns Rect2 enlarged by the specified size in every direction.
|
||||
result = self
|
||||
|
||||
result.position.x -= by
|
||||
result.position.y -= by
|
||||
|
||||
result.size.x += by * 2
|
||||
result.size.y += by * 2
|
||||
|
||||
proc growIndividual*(self: Rect2, left, top: float32,
|
||||
right, bottom: float32): Rect2 {.inline, noinit.} =
|
||||
result = self
|
||||
result.position.x -= left
|
||||
result.position.y -= top
|
||||
result.size.x += left + right
|
||||
result.size.y += top + bottom
|
||||
|
||||
proc expandTo*(self: var Rect2, to: Vector2) {.inline.} =
|
||||
var startPoint = self.position
|
||||
var endPoint = self.position + self.size
|
||||
|
||||
if to.x < startPoint.x:
|
||||
startPoint.x = to.x
|
||||
if to.y < startPoint.y:
|
||||
startPoint.y = to.y
|
||||
|
||||
if to.x > endPoint.x:
|
||||
endPoint.x = to.x
|
||||
if to.y > endPoint.y:
|
||||
endPoint.y = to.y
|
||||
|
||||
self.position = startPoint
|
||||
self.size = endPoint - startPoint
|
||||
|
||||
proc expand*(self: Rect2; to: Vector2): Rect2 {.inline, noinit.} =
|
||||
result = self
|
||||
result.expandTo(to)
|
||||
|
||||
proc abs*(self: Rect2): Rect2 {.inline, noinit.} =
|
||||
Rect2(position: vec2(self.position.x + min(self.size.x, 0'f32),
|
||||
self.position.y + min(self.size.y, 0'f32)),
|
||||
size: abs(self.size))
|
||||
|
||||
proc `==`*(a, b: Rect2): bool {.inline, noinit.} =
|
||||
a.position == b.position and a.size == b.size
|
||||
|
||||
{.pop.} # stackTrace: off
|
||||
|
|
@ -1,125 +1,199 @@
|
|||
# Copyright (c) 2018 Xored Software, Inc.
|
||||
|
||||
import math, godotbase
|
||||
|
||||
import internal.godotinternaltypes, internal.godotstrings
|
||||
import godotcoretypes, gdnativeapi
|
||||
|
||||
proc vec2*(): Vector2 {.inline.} =
|
||||
{.push stackTrace: off.}
|
||||
|
||||
proc vec2*(): Vector2 {.inline, noinit.} =
|
||||
Vector2()
|
||||
|
||||
proc vec2*(x, y: float32): Vector2 {.inline.} =
|
||||
proc vec2*(x, y: float32): Vector2 {.inline, noinit.} =
|
||||
Vector2(x: x, y: y)
|
||||
|
||||
proc `$`*(self: Vector2): string {.inline.} =
|
||||
proc `$`*(self: Vector2): string {.inline, noinit.} =
|
||||
$getGDNativeAPI().vector2AsString(self)
|
||||
|
||||
proc normalized*(self: Vector2): Vector2 {.inline.} =
|
||||
getGDNativeAPI().vector2Normalized(self)
|
||||
proc `+`*(self, other: Vector2): Vector2 {.inline, noinit.} =
|
||||
Vector2(x: self.x + other.x, y: self.y + other.y)
|
||||
|
||||
proc length*(self: Vector2): float32 {.inline.} =
|
||||
getGDNativeAPI().vector2Length(self)
|
||||
proc `+=`*(self: var Vector2, other: Vector2) {.inline, noinit.} =
|
||||
self.x += other.x
|
||||
self.y += other.y
|
||||
|
||||
proc angle*(self: Vector2): float32 {.inline.} =
|
||||
getGDNativeAPI().vector2Angle(self)
|
||||
proc `-`*(self, other: Vector2): Vector2 {.inline, noinit.} =
|
||||
Vector2(x: self.x - other.x, y: self.y - other.y)
|
||||
|
||||
proc lengthSquared*(self: Vector2): float32 {.inline.} =
|
||||
getGDNativeAPI().vector2LengthSquared(self)
|
||||
proc `-=`*(self: var Vector2, other: Vector2) {.inline, noinit.} =
|
||||
self.x -= other.x
|
||||
self.y -= other.y
|
||||
|
||||
proc isNormalized*(self: Vector2): bool {.inline.} =
|
||||
getGDNativeAPI().vector2IsNormalized(self)
|
||||
proc `*`*(self, other: Vector2): Vector2 {.inline, noinit.} =
|
||||
Vector2(x: self.x * other.x, y: self.y * other.y)
|
||||
|
||||
proc distanceTo*(self, to: Vector2): float32 {.inline.} =
|
||||
getGDNativeAPI().vector2DistanceTo(self, to)
|
||||
proc `*=`*(self: var Vector2, other: Vector2) {.inline, noinit.} =
|
||||
self.x *= other.x
|
||||
self.y *= other.y
|
||||
|
||||
proc distanceSquaredTo*(self, to: Vector2): float32 {.inline.} =
|
||||
getGDNativeAPI().vector2DistanceSquaredTo(self, to)
|
||||
proc `*`*(self: Vector2, scalar: float32): Vector2 {.inline, noinit.} =
|
||||
Vector2(x: self.x * scalar, y: self.y * scalar)
|
||||
|
||||
proc angleTo*(self, to: Vector2): float32 {.inline.} =
|
||||
getGDNativeAPI().vector2AngleTo(self, to)
|
||||
proc `*`*(scalar: float32, v: Vector2): Vector2 {.inline, noinit.} =
|
||||
v * scalar
|
||||
|
||||
proc angleToPoint*(self, to: Vector2): float32 {.inline.} =
|
||||
getGDNativeAPI().vector2AngleToPoint(self, to)
|
||||
proc `*=`*(self: var Vector2, scalar: float32) {.inline, noinit.} =
|
||||
self.x *= scalar
|
||||
self.y *= scalar
|
||||
|
||||
proc lerp*(self, b: Vector2; t: float32): Vector2 {.inline.} =
|
||||
getGDNativeAPI().vector2LinearInterpolate(self, b, t)
|
||||
proc `/`*(self, other: Vector2): Vector2 {.inline, noinit.} =
|
||||
Vector2(x: self.x / other.x, y: self.y / other.y)
|
||||
|
||||
proc cubicInterpolate*(self, b, preA, postB: Vector2;
|
||||
t: float32): Vector2 {.inline.} =
|
||||
getGDNativeAPI().vector2CubicInterpolate(self, b, preA, postB, t)
|
||||
proc `/=`*(self: var Vector2, other: Vector2) {.inline, noinit.} =
|
||||
self.x /= other.x
|
||||
self.y /= other.y
|
||||
|
||||
proc rotated*(self: Vector2; phi: float32): Vector2 {.inline.} =
|
||||
getGDNativeAPI().vector2Rotated(self, phi)
|
||||
proc `/`*(self: Vector2; scalar: float32): Vector2 {.inline, noinit.} =
|
||||
Vector2(x: self.x / scalar, y: self.y / scalar)
|
||||
|
||||
proc tangent*(self: Vector2): Vector2 {.inline.} =
|
||||
getGDNativeAPI().vector2Tangent(self)
|
||||
|
||||
proc floor*(self: Vector2): Vector2 {.inline.} =
|
||||
getGDNativeAPI().vector2Floor(self)
|
||||
|
||||
proc snapped*(self: Vector2; by: Vector2): Vector2 {.inline.} =
|
||||
getGDNativeAPI().vector2Snapped(self, by)
|
||||
|
||||
proc aspect*(self: Vector2): float32 {.inline.} =
|
||||
getGDNativeAPI().vector2Aspect(self)
|
||||
|
||||
proc dot*(a, b: Vector2): float32 {.inline.} =
|
||||
getGDNativeAPI().vector2Dot(a, b)
|
||||
|
||||
proc slide*(self, n: Vector2): Vector2 {.inline.} =
|
||||
getGDNativeAPI().vector2Slide(self, n)
|
||||
|
||||
proc bounce*(self, n: Vector2): Vector2 {.inline.} =
|
||||
getGDNativeAPI().vector2Bounce(self, n)
|
||||
|
||||
proc reflect*(self, n: Vector2): Vector2 {.inline.} =
|
||||
getGDNativeAPI().vector2Reflect(self, n)
|
||||
|
||||
proc abs*(self: Vector2): Vector2 {.inline.} =
|
||||
getGDNativeAPI().vector2Abs(self)
|
||||
|
||||
proc clamped*(self: Vector2; length: float32): Vector2 {.inline.} =
|
||||
getGDNativeAPI().vector2Clamped(self, length)
|
||||
|
||||
proc `+`*(self, other: Vector2): Vector2 {.inline.} =
|
||||
getGDNativeAPI().vector2OperatorAdd(self, other)
|
||||
|
||||
proc `+=`*(self: var Vector2, other: Vector2) {.inline.} =
|
||||
self = self + other
|
||||
|
||||
proc `-`*(self, other: Vector2): Vector2 =
|
||||
getGDNativeAPI().vector2OperatorSubtract(self, other)
|
||||
|
||||
proc `-=`*(self: var Vector2, other: Vector2) {.inline.} =
|
||||
self = self - other
|
||||
|
||||
proc `*`*(self, other: Vector2): Vector2 =
|
||||
getGDNativeAPI().vector2OperatorMultiplyVector(self, other)
|
||||
|
||||
proc `*=`*(self: var Vector2, other: Vector2) {.inline.} =
|
||||
self = self * other
|
||||
|
||||
proc `*`*(self: Vector2, scalar: float32): Vector2 =
|
||||
getGDNativeAPI().vector2OperatorMultiplyScalar(self, scalar)
|
||||
|
||||
proc `*=`*(self: var Vector2, scalar: float32) {.inline.} =
|
||||
self = self * scalar
|
||||
|
||||
proc `/`*(self, other: Vector2): Vector2 =
|
||||
getGDNativeAPI().vector2OperatorDivideVector(self, other)
|
||||
|
||||
proc `/=`*(self: var Vector2, other: Vector2) {.inline.} =
|
||||
self = self / other
|
||||
|
||||
proc `/`*(self: Vector2; scalar: float32): Vector2 =
|
||||
getGDNativeAPI().vector2OperatorDivideScalar(self, scalar)
|
||||
|
||||
proc `/=`*(self: var Vector2; scalar: float32) {.inline.} =
|
||||
proc `/=`*(self: var Vector2; scalar: float32) {.inline, noinit.} =
|
||||
self = self / scalar
|
||||
|
||||
proc `==`*(self, other: Vector2): bool {.inline.} =
|
||||
getGDNativeAPI().vector2OperatorEqual(self, other)
|
||||
proc `==`*(self, other: Vector2): bool {.inline, noinit.} =
|
||||
self.x == other.x and self.y == other.y
|
||||
|
||||
proc `<`*(self, other: Vector2): bool {.inline.} =
|
||||
getGDNativeAPI().vector2OperatorLess(self, other)
|
||||
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.} =
|
||||
getGDNativeAPI().vector2OperatorNeg(self)
|
||||
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
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
import math
|
||||
import godotbase, godotcoretypes
|
||||
|
||||
{.push stackTrace: off.}
|
||||
|
||||
proc vec3*(): Vector3 {.inline.} =
|
||||
Vector3()
|
||||
|
||||
|
|
@ -233,3 +235,5 @@ proc cubicInterpolate*(self, b, preA, postB: Vector3;
|
|||
(-p0 + p2) * t +
|
||||
(2.0 * p0 - 5.0 * p1 + 4 * p2 - p3) * t2 +
|
||||
(-p0 + 3.0 * p1 - 3.0 * p2 + p3) * t3)
|
||||
|
||||
{.pop.} # stackTrace: off
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import tables, typetraits, macros
|
||||
import gdnativeapi
|
||||
import core.godotcoretypes
|
||||
import core.godotcoretypes, core.godotbase
|
||||
import core.vector2, core.rect2,
|
||||
core.vector3, core.transform2d,
|
||||
core.planes, core.quats, core.aabb,
|
||||
|
|
@ -92,25 +92,6 @@ type
|
|||
proc isFinalized*(obj: NimGodotObject): bool {.inline.} =
|
||||
obj.isFinalized
|
||||
|
||||
template printWarning*(warning: typed) =
|
||||
## Prints ``warning`` to Godot log, adding filename and line information.
|
||||
let (filename, line) = instantiationInfo()
|
||||
godotPrintWarning(cstring($warning), cstring"", cstring(filename), line.cint)
|
||||
|
||||
template printError*(error: typed) =
|
||||
## Prints ``error`` to Godot log, adding filename and line information.
|
||||
let (filename, line) = instantiationInfo()
|
||||
godotPrintError(cstring($error), cstring"", cstring(filename), line.cint)
|
||||
|
||||
proc print*(parts: varargs[string, `$`]) =
|
||||
## Prints concatenated ``parts`` to Godot log.
|
||||
var combined = ""
|
||||
for v in parts:
|
||||
combined.add(v)
|
||||
var s = combined.toGodotString()
|
||||
godotPrint(s)
|
||||
s.deinit()
|
||||
|
||||
var classRegistry {.threadvar.}: TableRef[cstring, ObjectInfo]
|
||||
var classRegistryStatic* {.compileTime.}: TableRef[cstring, ObjectInfo]
|
||||
## Compile-time variable used for implementation of several procedures
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue