public TransformMatrix GetTransformMatrix() { if (IsValid) { return(_surfaceQuad.TransformMatrix); } return(TransformMatrix.GetIdentity()); }
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)); } }
/// <summary> /// This method can be called to render any necessary gizmos for debugging purposes. /// </summary> public void RenderGizmosDebug() { _sphereTree.RenderGizmosDebug(TransformMatrix.GetIdentity()); }