From d2ab30e7a69bfe7efda63ae75812207377917bd3 Mon Sep 17 00:00:00 2001
From: miepzerino <o.skotnik@gmail.com>
Date: Sun, 30 Mar 2025 18:50:27 +0000
Subject: [PATCH] Merge branch 'Flexalon-UI-Layouts' into develop
---
Assets/Flexalon/Runtime/Core/FlexalonMath.cs | 540 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 540 insertions(+), 0 deletions(-)
diff --git a/Assets/Flexalon/Runtime/Core/FlexalonMath.cs b/Assets/Flexalon/Runtime/Core/FlexalonMath.cs
new file mode 100644
index 0000000..bf03681
--- /dev/null
+++ b/Assets/Flexalon/Runtime/Core/FlexalonMath.cs
@@ -0,0 +1,540 @@
+using UnityEngine;
+
+namespace Flexalon
+{
+ /// <summary> Common math help functions. </summary>
+ public static class Math
+ {
+ public static readonly float MaxValue = 999999f;
+ public static readonly Vector3 MaxVector = new Vector3(MaxValue, MaxValue, MaxValue);
+
+ /// <summary> Returns the opposite direction. </summary>
+ /// <param name="direction"> The direction to get the opposite of. </param>
+ /// <returns> The opposite direction. </returns>
+ public static Direction GetOppositeDirection(Direction direction)
+ {
+ switch (direction)
+ {
+ case Direction.PositiveX: return Direction.NegativeX;
+ case Direction.NegativeX: return Direction.PositiveX;
+ case Direction.PositiveY: return Direction.NegativeY;
+ case Direction.NegativeY: return Direction.PositiveY;
+ case Direction.PositiveZ: return Direction.NegativeZ;
+ case Direction.NegativeZ: return Direction.PositiveZ;
+ default: return Direction.PositiveX;
+ }
+ }
+
+ /// <summary> Returns the opposite direction. </summary>
+ /// <param name="direction"> The direction to get the opposite of. </param>
+ /// <returns> The opposite direction. </returns>
+ public static Direction GetOppositeDirection(int direction)
+ {
+ return GetOppositeDirection((Direction)direction);
+ }
+
+ /// <summary> Returns the axis of a direction. </summary>
+ /// <param name="direction"> The direction to get the axis of. </param>
+ /// <returns> The axis of the direction. </returns>
+ public static Axis GetAxisFromDirection(Direction direction)
+ {
+ switch (direction)
+ {
+ case Direction.PositiveX: return Axis.X;
+ case Direction.NegativeX: return Axis.X;
+ case Direction.PositiveY: return Axis.Y;
+ case Direction.NegativeY: return Axis.Y;
+ case Direction.PositiveZ: return Axis.Z;
+ case Direction.NegativeZ: return Axis.Z;
+ default: return Axis.X;
+ }
+ }
+
+ /// <summary> Returns the axis of a direction. </summary>
+ /// <param name="direction"> The direction to get the axis of. </param>
+ /// <returns> The axis of the direction. </returns>
+ public static Axis GetAxisFromDirection(int direction)
+ {
+ return GetAxisFromDirection((Direction)direction);
+ }
+
+ /// <summary> Returns the positive and negative directions of an axis. </summary>
+ /// <param name="axis"> The axis to get the directions of. </param>
+ /// <returns> The positive and negative directions of the axis. </returns>
+ public static (Direction, Direction) GetDirectionsFromAxis(Axis axis)
+ {
+ switch (axis)
+ {
+ case Axis.X: return (Direction.PositiveX, Direction.NegativeX);
+ case Axis.Y: return (Direction.PositiveY, Direction.NegativeY);
+ case Axis.Z: return (Direction.PositiveZ, Direction.NegativeZ);
+ default: return (Direction.PositiveX, Direction.NegativeX);
+ }
+ }
+
+ /// <summary> Returns the positive and negative directions of an axis. </summary>
+ /// <param name="axis"> The axis to get the directions of. </param>
+ /// <returns> The positive and negative directions of the axis. </returns>
+ public static (Direction, Direction) GetDirectionsFromAxis(int axis)
+ {
+ return GetDirectionsFromAxis((Axis)axis);
+ }
+
+ /// <summary> Returns the positive direction of an axis. </summary>
+ /// <param name="axis"> The axis to get the direction of. </param>
+ /// <returns> The positive direction of the axis. </returns>
+ public static float GetPositiveFromDirection(Direction direction)
+ {
+ switch (direction)
+ {
+ case Direction.PositiveX:
+ case Direction.PositiveY:
+ case Direction.PositiveZ:
+ return 1;
+ default:
+ return -1;
+ }
+ }
+
+ /// <summary> Returns the positive direction of an axis. </summary>
+ /// <param name="axis"> The axis to get the direction of. </param>
+ /// <returns> The positive direction of the axis. </returns>
+ public static float GetPositiveFromDirection(int direction)
+ {
+ return GetPositiveFromDirection((Direction)direction);
+ }
+
+ /// <summary> Returns a unit vector in the direction. </summary>
+ /// <param name="direction"> The direction to get the vector of. </param>
+ /// <returns> A unit vector in the direction. </returns>
+ public static Vector3 GetVectorFromDirection(Direction direction)
+ {
+ switch (direction)
+ {
+ case Direction.PositiveX:
+ return Vector3.right;
+ case Direction.PositiveY:
+ return Vector3.up;
+ case Direction.PositiveZ:
+ return Vector3.forward;
+ case Direction.NegativeX:
+ return Vector3.left;
+ case Direction.NegativeY:
+ return Vector3.down;
+ case Direction.NegativeZ:
+ return Vector3.back;
+ }
+
+ return Vector3.zero;
+ }
+
+ /// <summary> Returns a unit vector in the direction. </summary>
+ /// <param name="direction"> The direction to get the vector of. </param>
+ /// <returns> A unit vector in the direction. </returns>
+ public static Vector3 GetVectorFromDirection(int direction)
+ {
+ return GetVectorFromDirection((Direction)direction);
+ }
+
+ /// <summary> Returns a unit vector in the positive direction of axis. </summary>
+ /// <param name="axis"> The axis to get the vector of. </param>
+ /// <returns> A unit vector in the axis. </returns>
+ public static Vector3 GetVectorFromAxis(Axis axis)
+ {
+ switch (axis)
+ {
+ case Axis.X:
+ return Vector3.right;
+ case Axis.Y:
+ return Vector3.up;
+ case Axis.Z:
+ return Vector3.forward;
+ }
+
+ return Vector3.zero;
+ }
+
+ /// <summary> Returns a unit vector in the positive direction of axis. </summary>
+ /// <param name="axis"> The axis to get the vector of. </param>
+ /// <returns> A unit vector in the axis. </returns>
+ public static Vector3 GetVectorFromAxis(int axis)
+ {
+ return GetVectorFromAxis((Axis)axis);
+ }
+
+ /// <summary> Returns the other two axes. </summary>
+ /// <param name="axis"> The axis to get the other two axes of. </param>
+ /// <returns> The other two axes. </returns>
+ public static (Axis, Axis) GetOtherAxes(Axis axis)
+ {
+ switch (axis)
+ {
+ case Axis.X: return (Axis.Y, Axis.Z);
+ case Axis.Y: return (Axis.X, Axis.Z);
+ default: return (Axis.X, Axis.Y);
+ }
+ }
+
+ /// <summary> Returns the other two axes. </summary>
+ /// <param name="axis"> The axis to get the other two axes of. </param>
+ /// <returns> The other two axes. </returns>
+ public static (int, int) GetOtherAxes(int axis)
+ {
+ var other = GetOtherAxes((Axis)axis);
+ return ((int)other.Item1, (int)other.Item2);
+ }
+
+ /// <summary> Given two axes, returns the third axis. </summary>
+ /// <param name="axis1"> The first axis. </param>
+ /// <param name="axis2"> The second axis. </param>
+ /// <returns> The third axis. </returns>
+ public static Axis GetThirdAxis(Axis axis1, Axis axis2)
+ {
+ var otherAxes = GetOtherAxes(axis1);
+ return (otherAxes.Item1 == axis2) ? otherAxes.Item2 : otherAxes.Item1;
+ }
+
+ /// <summary> Given two axes, returns the third axis. </summary>
+ /// <param name="axis1"> The first axis. </param>
+ /// <param name="axis2"> The second axis. </param>
+ /// <returns> The third axis. </returns>
+ public static int GetThirdAxis(int axis1, int axis2)
+ {
+ return (int) GetThirdAxis((Axis)axis1, (Axis)axis2);
+ }
+
+ /// <summary> Returns the axes of a plane. </summary>
+ /// <param name="plane"> The plane to get the axes of. </param>
+ /// <returns> The axes of the plane. </returns>
+ public static (Axis, Axis) GetPlaneAxes(Plane plane)
+ {
+ switch (plane)
+ {
+ case Plane.XY: return (Axis.X, Axis.Y);
+ case Plane.XZ: return (Axis.X, Axis.Z);
+ default: return (Axis.Z, Axis.Y);
+ }
+ }
+
+ /// <summary> Returns the axes of a plane. </summary>
+ /// <param name="plane"> The plane to get the axes of. </param>
+ /// <returns> The axes of the plane. </returns>
+ public static (int, int) GetPlaneAxesInt(Plane plane)
+ {
+ var axes = GetPlaneAxes(plane);
+ return ((int)axes.Item1, (int)axes.Item2);
+ }
+
+ /// <summary> Multiplies each component of two vectors. </summary>
+ /// <param name="a"> The first vector. </param>
+ /// <param name="b"> The second vector. </param>
+ /// <returns> The multiplied vector. </returns>
+ public static Vector3 Mul(Vector3 a, Vector3 b)
+ {
+ a.x *= b.x;
+ a.y *= b.y;
+ a.z *= b.z;
+ return a;
+ }
+
+ /// <summary> Divides each component of two vectors. </summary>
+ /// <param name="a"> The divided vector. </param>
+ /// <param name="b"> The divisor vector. </param>
+ /// <returns> The divided vector. </returns>
+ public static Vector3 Div(Vector3 a, Vector3 b)
+ {
+ a.x /= b.x;
+ a.y /= b.y;
+ a.z /= b.z;
+ return a;
+ }
+
+ /// <summary> Rotates a bounds around the origin and returns a new bounds
+ /// that encapsulates all of the rotated corners. </summary>
+ /// <param name="bounds"> The bounds to rotate. </param>
+ /// <param name="rotation"> The rotation to rotate the bounds by. </param>
+ /// <returns> The new bounds. </returns>
+ public static Bounds RotateBounds(Bounds bounds, Quaternion rotation)
+ {
+ if (rotation == Quaternion.identity) return bounds;
+
+ var rotatedCenter = rotation * bounds.center;
+ var p1 = rotation * bounds.max;
+ var p2 = rotation * new Vector3(bounds.max.x, bounds.max.y, bounds.min.z);
+ var p3 = rotation * new Vector3(bounds.max.x, bounds.min.y, bounds.max.z);
+ var p4 = rotation * new Vector3(bounds.max.x, bounds.min.y, bounds.min.z);
+ var p5 = rotation * new Vector3(bounds.min.x, bounds.max.y, bounds.max.z);
+ var p6 = rotation * new Vector3(bounds.min.x, bounds.max.y, bounds.min.z);
+ var p7 = rotation * new Vector3(bounds.min.x, bounds.min.y, bounds.max.z);
+ var p8 = rotation * bounds.min;
+
+ var rotatedBounds = new Bounds(rotatedCenter, Vector3.zero);
+ rotatedBounds.Encapsulate(p1);
+ rotatedBounds.Encapsulate(p2);
+ rotatedBounds.Encapsulate(p3);
+ rotatedBounds.Encapsulate(p4);
+ rotatedBounds.Encapsulate(p5);
+ rotatedBounds.Encapsulate(p6);
+ rotatedBounds.Encapsulate(p7);
+ rotatedBounds.Encapsulate(p8);
+ return rotatedBounds;
+ }
+
+ /// <summary> Creates rotated and scaled bounds at center. </summary>
+ /// <param name="center"> The center of the bounds. </param>
+ /// <param name="size"> The size of the bound before rotation. </param>
+ /// <param name="rotation"> The rotation to apply to the size. </param>
+ public static Bounds CreateRotatedBounds(Vector3 center, Vector3 size, Quaternion rotation)
+ {
+ if (rotation == Quaternion.identity) return new Bounds(center, size);
+ var bounds = RotateBounds(new Bounds(Vector3.zero, size), rotation);
+ bounds.center = center;
+ return bounds;
+ }
+
+ /// <summary> Scales a bounds by multiplying the center and size by 'scale'. </summary>
+ /// <param name="bounds"> The bounds to scale. </param>
+ /// <param name="scale"> The scale to scale the bounds by. </param>
+ /// <returns> The scaled bounds. </returns>
+ public static Bounds ScaleBounds(Bounds bounds, Vector3 scale)
+ {
+ bounds.center = Math.Mul(bounds.center, scale);
+ bounds.size = Math.Mul(bounds.size, scale);
+ return bounds;
+ }
+
+ /// <summary> Determines the aligned position in a size. </summary>
+ /// <param name="size"> The size to align to. </param>
+ /// <param name="align"> The alignment. </param>
+ /// <returns> The aligned position. </returns>
+ public static float Align(float size, Align align)
+ {
+ if (align == global::Flexalon.Align.Start)
+ {
+ return -size * 0.5f;
+ }
+ else if (align == global::Flexalon.Align.End)
+ {
+ return size * 0.5f;
+ }
+
+ return 0;
+ }
+
+ /// <summary> Determines the aligned position in a size for an axis. </summary>
+ /// <param name="size"> The size to align to. </param>
+ /// <param name="axis"> The axis to align to. </param>
+ /// <param name="align"> The alignment. </param>
+ /// <returns> The aligned position. </returns>
+ public static float Align(Vector3 size, int axis, Align align)
+ {
+ return Align(size[axis], align);
+ }
+
+ /// <summary> Determines the aligned position in a size. </summary>
+ /// <param name="size"> The size to align to. </param>
+ /// <param name="horizontal"> The horizontal alignment. </param>
+ /// <param name="vertical"> The vertical alignment. </param>
+ /// <param name="depth"> The depth alignment. </param>
+ /// <returns> The aligned position. </returns>
+ public static Vector3 Align(Vector3 size, Align horizontal, Align vertical, Align depth)
+ {
+ return new Vector3(
+ Align(size, 0, horizontal),
+ Align(size, 1, vertical),
+ Align(size, 2, depth));
+ }
+
+ /// <summary> Aligns a child size to a parent size. </summary>
+ /// <param name="childSize"> The size of the child. </param>
+ /// <param name="parentSize"> The size of the parent. </param>
+ /// <param name="parentAlign"> The alignment of the parent. </param>
+ /// <param name="childAlign"> The pivot of the child. </param>
+ /// <returns> The aligned position of the child. </returns>
+ public static float Align(float childSize, float parentSize, Align parentAlign, Align childAlign)
+ {
+ return Align(parentSize, parentAlign) - Align(childSize, childAlign);
+ }
+
+ /// <summary> Aligns a child size to a parent size. </summary>
+ /// <param name="childSize"> The size of the child. </param>
+ /// <param name="parentSize"> The size of the parent. </param>
+ /// <param name="align"> The alignment of the parent and child. </param>
+ /// <returns> The aligned position of the child. </returns>
+ public static float Align(float childSize, float parentSize, Align align)
+ {
+ return Align(childSize, parentSize, align, align);
+ }
+
+ /// <summary> Aligns a child size to a parent size on an axis. </summary>
+ /// <param name="childSize"> The size of the child. </param>
+ /// <param name="parentSize"> The size of the parent. </param>
+ /// <param name="axis"> The axis to align on. </param>
+ /// <param name="align"> The alignment of the parent and child. </param>
+ /// <returns> The aligned position of the child. </returns>
+ public static float Align(Vector3 childSize, Vector3 parentSize, int axis, Align align)
+ {
+ return Align(childSize[axis], parentSize[axis], align);
+ }
+
+ /// <summary> Aligns a child size to a parent size on an axis. </summary>
+ /// <param name="childSize"> The size of the child. </param>
+ /// <param name="parentSize"> The size of the parent. </param>
+ /// <param name="axis"> The axis to align on. </param>
+ /// <param name="align"> The alignment of the parent and child. </param>
+ /// <returns> The aligned position of the child. </returns>
+ public static float Align(Vector3 childSize, Vector3 parentSize, Axis axis, Align align)
+ {
+ return Align(childSize, parentSize, (int)axis, align);
+ }
+
+ /// <summary> Aligns a child size to a parent size on an axis. </summary>
+ /// <param name="childSize"> The size of the child. </param>
+ /// <param name="parentSize"> The size of the parent. </param>
+ /// <param name="axis"> The axis to align on. </param>
+ /// <param name="parentAlign"> The alignment of the parent. </param>
+ /// <param name="childAlign"> The pivot of the child. </param>
+ /// <returns> The aligned position of the child. </returns>
+ public static float Align(Vector3 childSize, Vector3 parentSize, int axis, Align parentAlign, Align childAlign)
+ {
+ return Align(childSize[axis], parentSize[axis], parentAlign, childAlign);
+ }
+
+ /// <summary> Aligns a child size to a parent size on an axis. </summary>
+ /// <param name="childSize"> The size of the child. </param>
+ /// <param name="parentSize"> The size of the parent. </param>
+ /// <param name="axis"> The axis to align on. </param>
+ /// <param name="parentAlign"> The alignment of the parent. </param>
+ /// <param name="childAlign"> The pivot of the child. </param>
+ /// <returns> The aligned position of the child. </returns>
+ public static float Align(Vector3 childSize, Vector3 parentSize, Axis axis, Align parentAlign, Align childAlign)
+ {
+ return Align(childSize, parentSize, (int)axis, parentAlign, childAlign);
+ }
+
+ /// <summary> Aligns a child size to a parent size on all axes. </summary>
+ /// <param name="childSize"> The size of the child. </param>
+ /// <param name="parentSize"> The size of the parent. </param>
+ /// <param name="parentHorizontal"> The horizontal alignment of the parent. </param>
+ /// <param name="parentVertical"> The vertical alignment of the parent. </param>
+ /// <param name="parentDepth"> The depth alignment of the parent. </param>
+ /// <param name="childHorizontal"> The horizontal pivot of the child. </param>
+ /// <param name="childVertical"> The vertical pivot of the child. </param>
+ /// <param name="childDepth"> The depth pivot of the child. </param>
+ /// <returns> The aligned position of the child. </returns>
+ public static Vector3 Align(Vector3 childSize, Vector3 parentSize, Align parentHorizontal, Align parentVertical, Align parentDepth, Align childHorizontal, Align childVertical, Align childDepth)
+ {
+ return Align(parentSize, parentHorizontal, parentVertical, parentDepth) -
+ Align(childSize, childHorizontal, childVertical, childDepth);
+ }
+
+ /// <summary> Aligns a child size to a parent size on all axes. </summary>
+ /// <param name="childSize"> The size of the child. </param>
+ /// <param name="parentSize"> The size of the parent. </param>
+ /// <param name="horizontal"> The horizontal alignment of the parent and child. </param>
+ /// <param name="vertical"> The vertical alignment of the parent and child. </param>
+ /// <param name="depth"> The depth alignment of the parent and child. </param>
+ /// <returns> The aligned position of the child. </returns>
+ public static Vector3 Align(Vector3 childSize, Vector3 parentSize, Align horizontal, Align vertical, Align depth)
+ {
+ return Align(parentSize, horizontal, vertical, depth) -
+ Align(childSize, horizontal, vertical, depth);
+ }
+
+ /// <summary> Given the bounds of a component, creates a bounds for the node respecting the
+ /// size types. Aspect ratio is preserved when possible. </summary>
+ /// <param name="componentBounds"> The bounds of the component. </param>
+ /// <param name="node"> The node to measure the bounds for. </param>
+ /// <param name="size"> The size of the node. </param>
+ /// <param name="min"> The minimum size of the node. </param>
+ /// <param name="max"> The maximum size of the node. </param>
+ /// <returns> The bounds of the node. </returns>
+ public static Bounds MeasureComponentBounds(Bounds componentBounds, FlexalonNode node, Vector3 size, Vector3 min, Vector3 max)
+ {
+ componentBounds.size = Vector3.Max(componentBounds.size, Vector3.one * 0.0001f);
+ var bounds = componentBounds;
+
+ bool componentX = node.GetSizeType(Axis.X) == SizeType.Component;
+ bool componentY = node.GetSizeType(Axis.Y) == SizeType.Component;
+ bool componentZ = node.GetSizeType(Axis.Z) == SizeType.Component;
+
+ var scale = (componentX && componentY && componentZ) ? 1 :
+ Mathf.Min(
+ componentX ? float.MaxValue : size.x / bounds.size.x,
+ componentY ? float.MaxValue : size.y / bounds.size.y,
+ componentZ ? float.MaxValue : size.z / bounds.size.z);
+
+ var maxScale = Mathf.Min(max.x / bounds.size.x, max.y / bounds.size.y, max.z / bounds.size.z);
+ var minScale = Mathf.Max(min.x / bounds.size.x, min.y / bounds.size.y, min.z / bounds.size.z);
+ var clampedScale = Mathf.Clamp(scale, minScale, maxScale);
+ var clampedSize = Math.Clamp(size, min, max);
+
+ bounds.size = new Vector3(
+ componentX ? bounds.size.x * clampedScale : clampedSize.x,
+ componentY ? bounds.size.y * clampedScale : clampedSize.y,
+ componentZ ? bounds.size.z * clampedScale : clampedSize.z);
+
+ bounds.center = Math.Mul(bounds.center, Math.Div(bounds.size, componentBounds.size));
+ return bounds;
+ }
+
+ /// <summary> Given the bounds of a component, creates a bounds for the node respecting the
+ /// size types. Aspect ratio is preserved for X and Y when possible. </summary>
+ /// <param name="componentBounds"> The bounds of the component. </param>
+ /// <param name="node"> The node to measure the bounds for. </param>
+ /// <param name="size"> The size of the node. </param>
+ /// <param name="min"> The minimum size of the node. </param>
+ /// <param name="max"> The maximum size of the node. </param>
+ /// <returns> The bounds of the node. </returns>
+ public static Bounds MeasureComponentBounds2D(Bounds componentBounds, FlexalonNode node, Vector3 size, Vector3 min, Vector3 max)
+ {
+ componentBounds.size = Vector3.Max(componentBounds.size, Vector3.one * 0.0001f);
+ var bounds = componentBounds;
+
+ bool componentX = node.GetSizeType(Axis.X) == SizeType.Component;
+ bool componentY = node.GetSizeType(Axis.Y) == SizeType.Component;
+
+ var scale = (componentX && componentY) ? 1 :
+ Mathf.Min(
+ componentX ? float.MaxValue : size.x / bounds.size.x,
+ componentY ? float.MaxValue : size.y / bounds.size.y);
+
+ var maxScale = Mathf.Min(max.x / bounds.size.x, max.y / bounds.size.y);
+ var minScale = Mathf.Max(min.x / bounds.size.x, min.y / bounds.size.y);
+ var clampedScale = Mathf.Clamp(scale, minScale, maxScale);
+ var clampedSize = Math.Clamp(size, min, max);
+
+ bounds.size = new Vector3(
+ componentX ? bounds.size.x * clampedScale : clampedSize.x,
+ componentY ? bounds.size.y * clampedScale : clampedSize.y,
+ clampedSize.z);
+
+ bounds.center = Math.Mul(bounds.center, Math.Div(bounds.size, componentBounds.size));
+ return bounds;
+ }
+
+ /// <summary> Applies absolute value of to each vector component. </summary>
+ /// <param name="v"> The vector to apply absolute value to. </param>
+ /// <returns> The vector with absolute value applied. </returns>
+ public static Vector3 Abs(Vector3 v)
+ {
+ v.x = Mathf.Abs(v.x);
+ v.y = Mathf.Abs(v.y);
+ v.z = Mathf.Abs(v.z);
+ return v;
+ }
+
+ /// <summary> Clamps value of to each vector component between min and max. </summary>
+ /// <param name="v"> The vector to clamp. </param>
+ /// <param name="min"> The minimum value. </param>
+ /// <param name="max"> The maximum value. </param>
+ /// <returns> The clamped vector. </returns>
+ public static Vector3 Clamp(Vector3 v, Vector3 min, Vector3 max)
+ {
+ v.x = Mathf.Clamp(v.x, min.x, max.x);
+ v.y = Mathf.Clamp(v.y, min.y, max.y);
+ v.z = Mathf.Clamp(v.z, min.z, max.z);
+ return v;
+ }
+ }
+}
\ No newline at end of file
--
Gitblit v1.10.0