ok , so this seems to be non trivial from my brief research.
There is a proposed solution here which in turn links to a wiki listing which links to a NASA paper!
In the following code I am averaging both position and rotation in my Update method
The position averaging is working
The rotation averaging is not
List<Vector3> posList = new List<Vector3>();
private Vector3 posAverage;
private Vector3 newPos;
List<Quaternion> rotList= new List<Quaternion>();
private Quaternion rotAverage;
private Quaternion newRot;
//Global variable which holds the amount of rotations which
//need to be averaged.
int addAmount = 0;
//Global variable which represents the additive quaternion
Quaternion addedRotation = Quaternion.identity;
//The averaged rotational value
Quaternion averageRotation;
void Update()
{
//target is a reference to another GameObject I am following
//newRot is a global Vector3
//newRot is a global Quaternion
//posList is a global List of Vector3 objects
Vector3 targetPosition = target.TransformPoint(new Vector3(0, 0, 0));
newPos = targetPosition;
newRot= target.transform.rotation;
if (posList.Count >= 10)
{
posAverage = new Vector3(posList.Average(x => x.x), posList.Average(x => x.y), posList.Average(x => x.z));
//Loop through all the rotational values.
foreach (Quaternion singleRotation in rotList)
{
//Temporary values
float w;
float x;
float y;
float z;
//Amount of separate rotational values so far
addAmount++;
float addDet = 1.0f / (float)addAmount;
addedRotation.w += singleRotation.w;
w = addedRotation.w * addDet;
addedRotation.x += singleRotation.x;
x = addedRotation.x * addDet;
addedRotation.y += singleRotation.y;
y = addedRotation.y * addDet;
addedRotation.z += singleRotation.z;
z = addedRotation.z * addDet;
//Normalize. Note: experiment to see whether you
//can skip this step.
float D = 1.0f / (w * w + x * x + y * y + z * z);
w *= D;
x *= D;
y *= D;
z *= D;
//The result is valid right away, without
//first going through the entire array.
averageRotation = new Quaternion(x, y, z, w);
}
posList.RemoveAt(0);
rotList.RemoveAt(0);
}
posList.Add(newPos);
rotList.Add(newRot);
transform.position = posAverage;
transform.rotation = averageRotation;
}