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
|
|
@ -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
|
||||
Loading…
Add table
Add a link
Reference in a new issue