Fix bug in shape definition

Previously, `points` would be reused and (for example)
rotated multiple times, rather than once by the desired
angle, which resulted in nonsensical variant order.

Now, variants with indices 0 to 3 correctly correspond
to rotations of 0, 90, 180 and 270 degrees.
main
copygirl 1 week ago
parent ad76ef1703
commit 4b064db838
  1. 1
      world/layers/matter.gd
  2. 28
      world/layers/shape.gd

@ -5,6 +5,7 @@ static var REGISTRY := Registry.new()
static var NONE := Matter.new("none") static var NONE := Matter.new("none")
static var PLASTIC := Matter.new("plastic") static var PLASTIC := Matter.new("plastic")
## Default matter to return when chunk or layer is not found.
static var DEFAULT := NONE static var DEFAULT := NONE
var id : int var id : int

@ -9,6 +9,7 @@ static func lookup(id: int) -> Shape:
static var EMPTY : Shape static var EMPTY : Shape
static var FULL : Shape static var FULL : Shape
## Default shape to return when chunk or layer is not found.
static var DEFAULT : Shape static var DEFAULT : Shape
var id : int var id : int
@ -34,6 +35,8 @@ func _init(base: Base, mirror: bool, angle: int, shape: Shape2D, points: PackedV
uvs.append((Vector2.ONE / 2) + point) uvs.append((Vector2.ONE / 2) + point)
## Represents a base shape, before it has been rotated and mirrored
## (if applicable) to create a number of variants based on that shape.
class Base: class Base:
static var EMPTY := Base.new("empty") static var EMPTY := Base.new("empty")
static var FULL := Base.new("full" , _rect()) static var FULL := Base.new("full" , _rect())
@ -60,28 +63,25 @@ class Base:
shape = _rotate(shape) # rotate by 90 degrees (swap x and y components) shape = _rotate(shape) # rotate by 90 degrees (swap x and y components)
variants.append(Shape.new(self, false, 0, shape, _points(shape))) variants.append(Shape.new(self, false, 0, shape, _points(shape)))
elif shape is Array: elif shape is Array:
# Convert points (pairs of ints) in array to convex shape. # Convert points (pairs of `int`s) in `Array` to convex shape.
var factor := float(shape.max()) var factor := float(shape.max())
var points := PackedVector2Array() var points_orig := PackedVector2Array() # untransformed points
for i in range(0, shape.size(), 2): for i in range(0, shape.size(), 2):
var point := Vector2(shape[i] / factor, shape[i + 1] / factor) var point := Vector2(shape[i] / factor, shape[i + 1] / factor)
points.append(point - (Vector2.ONE / 2)) # ensure shape is centered points_orig.append(point - (Vector2.ONE / 2)) # ensure shape is centered
# Add variations of the shape (rotated, mirrored), including the standard shape. # Add variations of the shape (rotated, mirrored), including the standard shape.
for mirror in [ false, true ] if mirrored else [ false ]: for mirror in [ false, true ] if mirrored else [ false ]:
if mirror:
# Mirror (flip) points along the X axis.
points = points.duplicate()
for i in points.size():
points[i] = points[i] * Transform2D.FLIP_X
for angle in [ 0, 90, 180, 270 ] if rotated else [ 0 ]: for angle in [ 0, 90, 180, 270 ] if rotated else [ 0 ]:
if angle != 0: var points := points_orig.duplicate() # transformed points
# Rotate points around the center. # Technically we could skip `duplicate()` if not mirrored and not rotated, but eh.
if mirror: # Mirror (flip) points along the X axis.
for i in points.size(): points[i] *= Transform2D.FLIP_X
if angle != 0: # Rotate points around the center.
var transform := Transform2D(deg_to_rad(angle), Vector2.ZERO) var transform := Transform2D(deg_to_rad(angle), Vector2.ZERO)
points = points.duplicate() for i in points.size(): points[i] *= transform
for i in points.size():
points[i] = points[i] * transform
var shape_points: PackedVector2Array var shape_points: PackedVector2Array
for point in points: shape_points.append(point * Block.SIZE) for point in points: shape_points.append(point * Block.SIZE)

Loading…
Cancel
Save