|
|
@ -72,21 +72,20 @@ public partial class Grid : Area3D |
|
|
|
/// </summary> |
|
|
|
/// </summary> |
|
|
|
public Transform3D Snap(Transform3D transform, Vector3 normal, Item item) |
|
|
|
public Transform3D Snap(Transform3D transform, Vector3 normal, Item item) |
|
|
|
{ |
|
|
|
{ |
|
|
|
var inverseTransform = GlobalTransform.AffineInverse(); |
|
|
|
|
|
|
|
var inverseBasis = GlobalBasis.Inverse(); |
|
|
|
|
|
|
|
var halfSize = (Vector3)item.Size * StepSize / 2; |
|
|
|
var halfSize = (Vector3)item.Size * StepSize / 2; |
|
|
|
|
|
|
|
|
|
|
|
// Get grid-local values of the global transform and normal. |
|
|
|
// Get grid-local values of the global transform and normal. |
|
|
|
var pos = inverseTransform * transform.Origin; |
|
|
|
var inverse = GlobalTransform.AffineInverse(); |
|
|
|
var basis = inverseBasis * transform.Basis; |
|
|
|
var pos = inverse * transform.Origin; |
|
|
|
normal = inverseBasis * normal; |
|
|
|
var basis = inverse.Basis * transform.Basis; |
|
|
|
|
|
|
|
normal = inverse.Basis * normal; |
|
|
|
|
|
|
|
|
|
|
|
// Snap rotation to nearest axis. |
|
|
|
// Snap rotation to nearest axis. |
|
|
|
basis = Basis.FromEuler(basis.GetEuler().Snapped(Tau / 4)); |
|
|
|
basis = Basis.FromEuler(basis.GetEuler().Snapped(Tau / 4)); |
|
|
|
|
|
|
|
|
|
|
|
// Offset / "push out" by half of the item's size. |
|
|
|
// Offset / "push out" by half of the item's size. |
|
|
|
var offsetAxis = (int)(normal * basis).Abs().MaxAxisIndex(); |
|
|
|
var axis = (normal * basis).Abs().MaxAxisIndex(); |
|
|
|
pos += halfSize[offsetAxis] * normal; |
|
|
|
pos += halfSize[(int)axis] * normal; |
|
|
|
|
|
|
|
|
|
|
|
// Snap the position to the grid. |
|
|
|
// Snap the position to the grid. |
|
|
|
var halfOff = basis * halfSize.PosMod(1.0f); |
|
|
|
var halfOff = basis * halfSize.PosMod(1.0f); |
|
|
|