12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- #if UNITY_EDITOR
- using UnityEngine;
- namespace O3DWB
- {
- public static class AxisAlignment
- {
- #region Public Static Functions
- public static void AlignObjectAxis(GameObject gameObject, CoordinateSystemAxis alignmentAxis, Vector3 destinationAxis)
- {
- Transform objectTransform = gameObject.transform;
- objectTransform.rotation = CalculateRotationQuaternionForAxisAlignment(objectTransform.rotation, alignmentAxis, destinationAxis);
- }
- public static void AlignObjectAxis(GameObject gameObject, AxisAlignmentSettings adjustmentSettings, Vector3 destinationAxis)
- {
- if (adjustmentSettings.IsEnabled)
- {
- Transform objectTransform = gameObject.transform;
- objectTransform.rotation = CalculateRotationQuaternionForAxisAlignment(objectTransform.rotation, adjustmentSettings.AlignmentAxis, destinationAxis);
- }
- }
- public static Quaternion CalculateRotationQuaternionForAxisAlignment(Quaternion currentRotation, CoordinateSystemAxis alignmentAxis, Vector3 destinationAxis)
- {
- TransformMatrix rotationMatrix = TransformMatrix.GetIdentity();
- rotationMatrix.Rotation = currentRotation;
- Vector3 axisToAlign = CoordinateSystemAxes.GetLocalVector(alignmentAxis, rotationMatrix);
- bool isAlignmentAxisNegative = CoordinateSystemAxes.IsNegativeAxis(alignmentAxis);
- // Already aligned?
- bool pointsInSameDirection;
- bool isAlignedWithDestinationAxis = destinationAxis.IsAlignedWith(axisToAlign, out pointsInSameDirection);
- if (isAlignedWithDestinationAxis && pointsInSameDirection) return currentRotation;
- if (!isAlignedWithDestinationAxis)
- {
- Vector3 rotationAxis = Vector3.Cross(axisToAlign, destinationAxis);
- rotationAxis.Normalize();
- return Quaternion.AngleAxis(axisToAlign.AngleWith(destinationAxis), rotationAxis) * currentRotation;
- }
- else
- {
- // If this point is reached, it means the axis is aligned with the destination axis but points in the opposite
- // direction. In this case we can not use the cross product, so we will have to regenerate the axes.
- Vector3 newRightAxis, newUpAxis, newLookAxis;
- if (alignmentAxis == CoordinateSystemAxis.PositiveRight || alignmentAxis == CoordinateSystemAxis.NegativeRight)
- {
- newRightAxis = destinationAxis;
- if (isAlignmentAxisNegative) newRightAxis *= -1.0f;
- bool worldUpPointsSameDirAsRightAxis;
- if (newRightAxis.IsAlignedWith(Vector3.up, out worldUpPointsSameDirAsRightAxis)) newLookAxis = worldUpPointsSameDirAsRightAxis ? Vector3.forward : Vector3.back;
- else newLookAxis = Vector3.Cross(newRightAxis, Vector3.up);
- if (isAlignmentAxisNegative) newLookAxis *= -1.0f;
- newUpAxis = Vector3.Cross(newLookAxis, newRightAxis);
- }
- if (alignmentAxis == CoordinateSystemAxis.PositiveUp || alignmentAxis == CoordinateSystemAxis.NegativeUp)
- {
- newUpAxis = destinationAxis;
- if (isAlignmentAxisNegative) newUpAxis *= -1.0f;
- bool worldUpPointsSameDirAsUpAxis;
- if (newUpAxis.IsAlignedWith(Vector3.up, out worldUpPointsSameDirAsUpAxis)) newLookAxis = worldUpPointsSameDirAsUpAxis ? Vector3.forward : Vector3.back;
- else newLookAxis = Vector3.Cross(newUpAxis, Vector3.up);
- if (isAlignmentAxisNegative) newLookAxis *= -1.0f;
- }
- else
- {
- newLookAxis = destinationAxis;
- if (isAlignmentAxisNegative) newLookAxis *= -1.0f;
- bool worldUpPointsSameDirAsLookAxis;
- if (newLookAxis.IsAlignedWith(Vector3.up, out worldUpPointsSameDirAsLookAxis)) newUpAxis = worldUpPointsSameDirAsLookAxis ? Vector3.forward : Vector3.back;
- else newUpAxis = Vector3.Cross(newLookAxis, Vector3.up);
- if (isAlignmentAxisNegative) newUpAxis *= -1.0f;
- }
- // Normalize the axes which were calculated
- newUpAxis.Normalize();
- newLookAxis.Normalize();
- // Now use the axes to calculate the rotation quaternion
- return Quaternion.LookRotation(newLookAxis, newUpAxis);
- }
- }
- #endregion
- }
- }
- #endif
|