Hey guys,
I have been stuck on trying to get this method desired but unsure if it can be done.
Basically, I have a gameobject that has 4 markers. I want the gameobject position and rotation to be determined by the position of the 4 markers (so the markers are sort of like object guides).
I have got close with the script below but it is missing a rotation and not sure how I can get the last rotation.
If anyone knows of how to get the final rotation or an easier way i would greatly appreciate the help.
public Transform centerobject;
public Transform sphere1;
public Transform sphere2;
public Transform sphere3;
public Transform RotationPointer;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
var xpos = centerobject.transform.position.x;
var ypos = centerobject.transform.position.y;
var zpos = centerobject.transform.position.z;
xpos = (sphere1.transform.position.x + sphere2.transform.position.x + sphere3.transform.position.x ) / 3;
ypos = (sphere1.transform.position.y + sphere2.transform.position.y + sphere3.transform.position.y )/ 3;
zpos = (sphere1.transform.position.z + sphere2.transform.position.z + sphere3.transform.position.z ) / 3;
centerobject.transform.position = new Vector3(xpos, ypos, zpos);
centerobject.LookAt(RotationPointer);
}
}
Looks like you are trying to just do averages.
Your vector:
centerobject.transform.position = (sphere1.transform.position + sphere2.transform.position + sphere3.transform.position) / 3.0f;
Quaternions:
//Get an average (mean) from more then two quaternions (with two, slerp would be used).
//Note: this only works if all the quaternions are relatively close together.
//Usage:
//-Cumulative is an external Vector4 which holds all the added x y z and w components.
//-newRotation is the next rotation to be added to the average pool
//-firstRotation is the first quaternion of the array to be averaged
//-addAmount holds the total amount of quaternions which are currently added
//This function returns the current average quaternion
public static Quaternion AverageQuaternion(ref Vector4 cumulative, Quaternion newRotation, Quaternion firstRotation, int addAmount){
float w = 0.0f;
float x = 0.0f;
float y = 0.0f;
float z = 0.0f;
//Before we add the new rotation to the average (mean), we have to check whether the quaternion has to be inverted. Because
//q and -q are the same rotation, but cannot be averaged, we have to make sure they are all the same.
if(!Math3d.AreQuaternionsClose(newRotation, firstRotation)){
newRotation = Math3d.InverseSignQuaternion(newRotation);
}
//Average the values
float addDet = 1f/(float)addAmount;
cumulative.w += newRotation.w;
w = cumulative.w * addDet;
cumulative.x += newRotation.x;
x = cumulative.x * addDet;
cumulative.y += newRotation.y;
y = cumulative.y * addDet;
cumulative.z += newRotation.z;
z = cumulative.z * addDet;
//note: if speed is an issue, you can skip the normalization step
return NormalizeQuaternion(x, y, z, w);
}
public static Quaternion NormalizeQuaternion(float x, float y, float z, float w){
float lengthD = 1.0f / (w*w + x*x + y*y + z*z);
w *= lengthD;
x *= lengthD;
y *= lengthD;
z *= lengthD;
return new Quaternion(x, y, z, w);
}
//Changes the sign of the quaternion components. This is not the same as the inverse.
public static Quaternion InverseSignQuaternion(Quaternion q){
return new Quaternion(-q.x, -q.y, -q.z, -q.w);
}
//Returns true if the two input quaternions are close to each other. This can
//be used to check whether or not one of two quaternions which are supposed to
//be very similar but has its component signs reversed (q has the same rotation as
//-q)
public static bool AreQuaternionsClose(Quaternion q1, Quaternion q2){
float dot = Quaternion.Dot(q1, q2);
if(dot < 0.0f){
return false;
}
else{
return true;
}
}