/// <summary>
/// Rotate a Point around an axis
/// usage:
/// Vector3 position = ExtRotation.RotatePointAroundAxis(pivotPosition, pointToRotate, pivotUp, _rotateAxis * TimeEditor.deltaTime);
/// </summary>
public static Vector3 RotatePointAroundAxis(Vector3 pivotPoint, Vector3 pointToRotate, Vector3 upNormalized, Vector3 rotationAxis)
{
Vector3 vectorDirector = pointToRotate - pivotPoint;
Vector3 finalPoint = RotateWithMatrix(pivotPoint, vectorDirector, upNormalized, rotationAxis);
return (finalPoint);
}
/// <summary>
/// Rotate a vectorDirector around an axis
/// usage:
/// Vector3 vectorDirector = ExtRotation.RotateVectorAroundAxis(pivotPoint, vectorDirector, pivotUp, _rotateAxis * TimeEditor.deltaTime);
/// </summary>
public static Vector3 RotateVectorAroundAxis(Vector3 pivotPoint, Vector3 vectorDirector, Vector3 upNormalized, Vector3 rotationAxis)
{
Vector3 finalPoint = RotateWithMatrix(pivotPoint, vectorDirector, upNormalized, rotationAxis);
return (finalPoint - pivotPoint);
}
private static Vector3 RotateWithMatrix(Vector3 pivotPoint, Vector3 vectorDirector, Vector3 upNormalized, Vector3 rotationAxis)
{
Quaternion constrainRotation = TurretLookRotation(vectorDirector, upNormalized); //constrain rotation from up !!
//create a TRS matrix from point & rotation
Matrix4x4 rotationMatrix = Matrix4x4.TRS(pivotPoint, constrainRotation, Vector3.one);
Vector3 projectedForward = ExtVector3.ProjectAOnB(vectorDirector, rotationMatrix.ForwardFast());
Vector3 projectedUp = ExtVector3.ProjectAOnB(vectorDirector, upNormalized);
float distanceForward = projectedForward.magnitude;
float distanceUp = projectedUp.magnitude;
if (ExtVector3.DotProduct(upNormalized, vectorDirector) < 0)
{
distanceUp *= -1;
}
//rotate matrix in x, y & z
rotationMatrix = Matrix4x4.TRS(pivotPoint, constrainRotation * Quaternion.Euler(rotationAxis), Vector3.one);
Vector3 finalPoint = rotationMatrix.MultiplyPoint3x4(new Vector3(0, distanceUp, distanceForward));
return finalPoint;
}
public static Quaternion TurretLookRotation(Vector3 approximateForward, Vector3 exactUp)
{
Quaternion rotateZToUp = Quaternion.LookRotation(exactUp, -approximateForward);
Quaternion rotateYToZ = Quaternion.Euler(90f, 0f, 0f);
return rotateZToUp * rotateYToZ;
}
public static Vector3 ProjectAOnB(Vector3 A, Vector3 B)
{
float sqrMag = DotProduct(B, B);
if (sqrMag < Mathf.Epsilon)
{
return (Vector3.zero);
}
else
{
var dot = DotProduct(A, B);
return new Vector3(B.x * dot / sqrMag,
B.y * dot / sqrMag,
B.z * dot / sqrMag);
}
}
public static float DotProduct(Vector3 a, Vector3 b)
{
return (a.x * b.x + a.y * b.y + a.z * b.z);
}