Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
extension SKWarpGeometryGrid {
func deform(at contactPoint: float2, radius: Float) -> SKWarpGeometryGrid {
// Make a copy of current grid positions.
let currentPositions: [float2] = {
var positions = [float2](repeating: .zero, count: vertexCount)
(0..<vertexCount).forEach({ positions[$0] = destPosition(at: $0) })
return positions
}()
// Move some of the positions in the grid close to contact point.
let destination = currentPositions.map { (gridPoint) -> float2 in
let contactDistance = gridPoint.distance(to: contactPoint)
guard contactDistance <= Float(radius) else { return gridPoint }
// If contact was very close to the grid point, move it a little bit further away from the contact point.
let gridPointChangeFactor = (Float(radius) - contactDistance) / Float(radius)
let maxDeformation: Float = 0.1
let gridPointDistanceChange = Float(maxDeformation) * gridPointChangeFactor // vector length
// Limit angle, as otherwise the edges of the crater are too far away from the center of the node.
let angleToCenter = contactPoint.angle(to: float2(x: 0.5, y: 0.5))
let maxAngleOffset = Float.pi / 4.0
let minAngle = angleToCenter - maxAngleOffset
let maxAngle = angleToCenter + maxAngleOffset
var gridPointOffsetAngle = contactPoint.angle(to: gridPoint)
gridPointOffsetAngle = min(max(gridPointOffsetAngle, minAngle), maxAngle)
return float2(x: gridPoint.x + gridPointDistanceChange * cos(gridPointOffsetAngle), y: gridPoint.y + gridPointDistanceChange * sin(gridPointOffsetAngle))
}
return replacingByDestinationPositions(positions: destination)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment