Hello, everyone
I want to do the same too. But i cant find a solution how to read the position of a single Marker from Motive to Unity. Has anyone good idea for my problem?
@heath789 : have your find a solution for your problem?
Thank your!
Streaming Individual Markers
Re: Streaming Individual Markers
I realize the thread is inactive for some time, but maybe some folks will find this helpful, regarding Hanowde's question concerning Unity3D, since I also had this question rectently:
There is a very simple way of adding this functionality in the official Optitrack Untiy Plugin (I'm referring to version 1.0.1 here, but I expect you will get this done in future releases in a similar way):
In Assets/OptiTrack/Scripts/OptitrackStreamingClient.cs, there is a method called OnNatNetFrameReceived, where you get NatNetClient.NativeFrameReceivedEventArgs eventArgs as an argument. The class already implements doing most of the marshalling for you, although it is not used by the plugin (yet?), giving you an sFrameOfMocapData struct, which contains the fields OtherMarkersCount and OtherMarkers. I added a list of OptitrackMarkerState to the OptitrackStreamingClient class like this
and added this to the OnNatNetFrameReceived method, just above the code where updating of rigid bodies is done:
Works like a charm for me. You can also go ahead and implement an editor script so you have the markers drawn in the Unity scene view, use OptitrackRigidBodyEditor.cs as a reference, it isn't too hard.
There is a very simple way of adding this functionality in the official Optitrack Untiy Plugin (I'm referring to version 1.0.1 here, but I expect you will get this done in future releases in a similar way):
In Assets/OptiTrack/Scripts/OptitrackStreamingClient.cs, there is a method called OnNatNetFrameReceived, where you get NatNetClient.NativeFrameReceivedEventArgs eventArgs as an argument. The class already implements doing most of the marshalling for you, although it is not used by the plugin (yet?), giving you an sFrameOfMocapData struct, which contains the fields OtherMarkersCount and OtherMarkers. I added a list of OptitrackMarkerState to the OptitrackStreamingClient class like this
Code: Select all
private List<OptitrackMarkerState> m_latestOtherMarkerStates = new List<OptitrackMarkerState>();
Code: Select all
sFrameOfMocapData frame = eventArgs.MarshaledFrame;
//Debug.Log( "labeled: " + frame.LabeledMarkerCount + ", other: " + frame.OtherMarkerCount + ", sets: " + frame.MarkerSetCount );
float[] vec = new float[3 * frame.OtherMarkerCount];
System.Runtime.InteropServices.Marshal.Copy( frame.OtherMarkers, vec, 0, vec.Length );
m_latestOtherMarkerStates.Clear();
for( int i = 0; i < frame.OtherMarkerCount; i++ )
{
OptitrackMarkerState state = new OptitrackMarkerState();
state.Position = new Vector3( -vec[i * 3 + 0], vec[i * 3 + 1], vec[i * 3 + 2] );
//TODO: where do i get the size from?
state.Size = 0.01f;
m_latestOtherMarkerStates.Add( state );
//Debug.Log( "marker #" + i + ": [" + vec[i * 3 + 0] + ", " + vec[i * 3 + 1] + ", " + vec[i * 3 + 2] );
}
-
- Posts: 2
- Joined: Mon Mar 05, 2018 12:18 am
Re: Streaming Individual Markers
Hello,
thanks for your code- I'm trying to show the individual markers in unity to better align our assets to the optitrack's rigidbodies. We edited the script following your directions but we get 2 errors in the unity console:
ArgumentNullException: Argument cannot be null.
Parameter name: src
System.Runtime.InteropServices.Marshal.Copy (IntPtr source, System.Single[] destination, Int32 startIndex, Int32 length) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.InteropServices/Marshal.cs:191)
OptitrackStreamingClient.OnNatNetFrameReceived (System.Object sender, NaturalPoint.NatNetLib.NativeFrameReceivedEventArgs eventArgs) (at Assets/OptiTrack/Scripts/OptitrackStreamingClient.cs:512)
UnityEngine.Debug:LogException(Exception, Object)
OptitrackStreamingClient:OnNatNetFrameReceived(Object, NativeFrameReceivedEventArgs) (at Assets/OptiTrack/Scripts/OptitrackStreamingClient.cs:603)
and
OptitrackStreamingClient: OnNatNetFrameReceived encountered an exception.
UnityEngine.Debug:LogError(Object, Object)
OptitrackStreamingClient:OnNatNetFrameReceived(Object, NativeFrameReceivedEventArgs) (at Assets/OptiTrack/Scripts/OptitrackStreamingClient.cs:602)
the code is supposed to show x,y,z position for each marker in the consolle, right?
Any hint is really appreciated-
Thank you!
thanks for your code- I'm trying to show the individual markers in unity to better align our assets to the optitrack's rigidbodies. We edited the script following your directions but we get 2 errors in the unity console:
ArgumentNullException: Argument cannot be null.
Parameter name: src
System.Runtime.InteropServices.Marshal.Copy (IntPtr source, System.Single[] destination, Int32 startIndex, Int32 length) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.InteropServices/Marshal.cs:191)
OptitrackStreamingClient.OnNatNetFrameReceived (System.Object sender, NaturalPoint.NatNetLib.NativeFrameReceivedEventArgs eventArgs) (at Assets/OptiTrack/Scripts/OptitrackStreamingClient.cs:512)
UnityEngine.Debug:LogException(Exception, Object)
OptitrackStreamingClient:OnNatNetFrameReceived(Object, NativeFrameReceivedEventArgs) (at Assets/OptiTrack/Scripts/OptitrackStreamingClient.cs:603)
and
OptitrackStreamingClient: OnNatNetFrameReceived encountered an exception.
UnityEngine.Debug:LogError(Object, Object)
OptitrackStreamingClient:OnNatNetFrameReceived(Object, NativeFrameReceivedEventArgs) (at Assets/OptiTrack/Scripts/OptitrackStreamingClient.cs:602)
the code is supposed to show x,y,z position for each marker in the consolle, right?
Any hint is really appreciated-
Thank you!
- Attachments
-
- Screenshot 2018-03-05 15.23.42.jpg (225.11 KiB) Viewed 5279 times
Re: Streaming Individual Markers
So I had the same problem as you guys and I was able to figure out what caused it.
By getting rid of this line, I didn't get any further errors:
Sadly, the streaming stopped too, so now I have to figure out the next steps.
Furthermore I have written a getMarkerState method and a script for displaying all unassigned markers, which I can share if anyone needs it.
By getting rid of this line, I didn't get any further errors:
Code: Select all
[...]
float[] vec = new float[3 * frame.OtherMarkerCount];
//TODO: Fix this line!
//System.Runtime.InteropServices.Marshal.Copy(frame.OtherMarkers, vec, 0, vec.Length);
[...]
Furthermore I have written a getMarkerState method and a script for displaying all unassigned markers, which I can share if anyone needs it.
Re: Streaming Individual Markers
Okay, I found a solution, that works for me; code below.
The problem was, that the marshalling expected a double or an int value array, but was given a float array. So I changed the arraytype of vec to double and later typecasted them to float for the Vector3 position.
However, I would still get the error, so I figured out, that if I didn't get any unlabeled markers from Motive, my src value would be 0, which throws the exception. As soon as markers were streamed everything worked. By adding a quick check whether there are any unlabeled markers, everything works as intended.
TL;DR: Copy the code below and add it to the OnNatNetFrameReceived method, just above the code where updating of rigid bodies is done (as shown by Iko79 above).
The problem was, that the marshalling expected a double or an int value array, but was given a float array. So I changed the arraytype of vec to double and later typecasted them to float for the Vector3 position.
However, I would still get the error, so I figured out, that if I didn't get any unlabeled markers from Motive, my src value would be 0, which throws the exception. As soon as markers were streamed everything worked. By adding a quick check whether there are any unlabeled markers, everything works as intended.
TL;DR: Copy the code below and add it to the OnNatNetFrameReceived method, just above the code where updating of rigid bodies is done (as shown by Iko79 above).
Code: Select all
// Update unlabeled Markers
sFrameOfMocapData frame = eventArgs.MarshaledFrame;
Debug.Log( "labeled: " + frame.LabeledMarkerCount + ", other: " + frame.OtherMarkerCount + ", sets: " + frame.MarkerSetCount );
//if no unlabeled Markers are recieved, skip this step
if (frame.OtherMarkerCount < 1)
{
double[] vec = new double[3 * frame.OtherMarkerCount];
Marshal.Copy(frame.OtherMarkers, vec, 0, vec.Length);
m_latestOtherMarkerStates.Clear();
for (int i = 0; i < frame.OtherMarkerCount; i++)
{
OptitrackMarkerState state = new OptitrackMarkerState();
state.Position = new Vector3((float)-vec[i * 3 + 0], (float)vec[i * 3 + 1], (float)vec[i * 3 + 2]);
state.Size = 0.01f;
m_latestOtherMarkerStates.Add(state);
Debug.Log("marker #" + i + ": [" + vec[i * 3 + 0] + ", " + vec[i * 3 + 1] + ", " + vec[i * 3 + 2]);
}
}