I am looking for solution of following problem:
I am using Optitrack Motive to track the markers that i weared on my finger and using Unity to create 3d objects.
And middleVR (free edition) for 3d classes.
If i move my finger, i will see the 3d object for finger move with my finger too. It works.
But if i sometimes rotate my finger 90 degrees or 180 degrees, the 3d finger object will jump to the opposite site and rotates 180 degrees back...
I am using the class of the 3rd party code to give die tracking transform to my unity (finger) objects directly, i am sure about it.
But i am not sure that the function which reads the position and rotation data to my finger objects will prevent that problem in my video...because it also uses EulerAngles function...
In the 3rd party code is the following function of the class to read the data from Motive:
Code: Select all
// Unpack RigidBody data
private static void ReadRigidBody(Byte[] b, ref int offset, OptiTrackRigidBody rb)
{
try
{
int[] iData = new int[100];
float[] fData = new float[100];
// RB ID
Buffer.BlockCopy(b, offset, iData, 0, 4); offset += 4;
//int iSkelID = iData[0] >> 16; // hi 16 bits = ID of bone's parent skeleton
//int iBoneID = iData[0] & 0xffff; // lo 16 bits = ID of bone
rb.ID = iData[0]; // already have it from data descriptions
// RB pos
float[] pos = new float[3];
Buffer.BlockCopy(b, offset, pos, 0, 4 * 3); offset += 4 * 3;
rb.position.x = pos[0]; rb.position.y = pos[1]; rb.position.z = pos[2];
// RB ori
float[] ori = new float[4];
Buffer.BlockCopy(b, offset, ori, 0, 4 * 4); offset += 4 * 4;
rb.orientation.x = ori[0]; rb.orientation.y = ori[1]; rb.orientation.z = ori[2]; rb.orientation.w = ori[3];
Buffer.BlockCopy(b, offset, iData, 0, 4); offset += 4;
int nMarkers = iData[0];
Buffer.BlockCopy(b, offset, fData, 0, 4 * 3 * nMarkers); offset += 4 * 3 * nMarkers;
Buffer.BlockCopy(b, offset, iData, 0, 4 * nMarkers); offset += 4 * nMarkers;
Buffer.BlockCopy(b, offset, fData, 0, 4 * nMarkers); offset += 4 * nMarkers;
Buffer.BlockCopy(b, offset, fData, 0, 4); offset += 4;
} catch (Exception e)
{
Debug.LogError(e.ToString());
}
}
Code: Select all
public Vector3 getPosition(int rigidbodyIndex)
{
if(OptitrackManagement.DirectMulticastSocketClient.IsInit())
{
DataStream networkData = OptitrackManagement.DirectMulticastSocketClient.GetDataStream();
Vector3 pos = origin + networkData.getRigidbody(rigidbodyIndex).position * scale;
pos.x = -pos.x; // not really sure if this is the best way to do it
//pos.y = pos.y; // these may change depending on your configuration and calibration
//pos.z = -pos.z;
return pos;
}
else
{
return Vector3.zero;
}
}
public Quaternion getOrientation(int rigidbodyIndex)
{
// should add a way to filter it
if(OptitrackManagement.DirectMulticastSocketClient.IsInit())
{
DataStream networkData = OptitrackManagement.DirectMulticastSocketClient.GetDataStream();
Quaternion rot = networkData.getRigidbody(rigidbodyIndex).orientation;
// change the handedness from motive
//rot = new Quaternion(rot.z, rot.y, rot.x, rot.w); // depending on calibration
// Invert pitch and yaw
Vector3 euler = rot.eulerAngles;
rot.eulerAngles = new Vector3(euler.x, -euler.y, euler.z); // these may change depending on your calibration
return rot;
}
else
{
return Quaternion.identity;
}
}
Code: Select all
// Update is called once per frame
void Update () {
Vector3 pos = OptiTrackManager.Instance.getPosition(rigidbodyIndex);
Quaternion rot = OptiTrackManager.Instance.getOrientation(rigidbodyIndex);
rot = rot * Quaternion.Euler(rotationOffset);
this.transform.position = pos;
this.transform.rotation = rot;
}
Video for problem:
http://de.tinypic.com/player.php?v=dqmx ... hf0Xvntmko
Have your any idea about my problem?
Thank your!
regards,
Carvin