/// <summary>
        /// Get orientation of three points, where on point defines forward
        /// </summary>
        /// <param name="back">position vector of back marker</param>
        /// <param name="left">position vector of left marker</param>
        /// <param name="right">position vector of right marker</param>
        /// <returns>Quaternion rotation</returns>
        public static Quaternion GetOrientation(Vector3 forwardPoint, Vector3 leftPoint, Vector3 rightPoint)
        {
            Vector3 x = rightPoint - leftPoint;
            Vector3 z = forwardPoint - Vector3Helper.MidPoint(leftPoint, rightPoint);

            return(GetOrientationFromZY(z, Vector3.Cross(z, x)));
        }
        /// <summary>
        /// Prepare the markerset for joint localization
        /// </summary>
        /// <param name="labelMarkers">The list of labeled markers</param>
        /// <param name="newMarkers">a reference to the dictionary to be </param>
        /// <param name="prefix">Optional prefix of all markers</param>
        public void ProcessMarkers(out Dictionary <string, Vector3> newMarkers)
        {
            // sacrum can be defined by two markers
            if (sacrumBetween)
            {
                markers[m.bodyBase] =
                    Vector3Helper.MidPoint(markers[sacrumBetweenMarkers[0]],
                                           markers[sacrumBetweenMarkers[1]]);
            }

            //
            if (frontHeadBetween)
            {
                markers[m.head] =
                    Vector3Helper.MidPoint(markers[frontHeadBetweenMarkers[0]],
                                           markers[frontHeadBetweenMarkers[1]]);
            }

            if (markers[m.leftHip].IsNaN() ||
                markers[m.rightHip].IsNaN() ||
                markers[m.bodyBase].IsNaN()
                )
            {
                MissingEssentialMarkers(markers);
            }
            else
            {
                lastSACRUMknown = markers[m.bodyBase];
                lastRIASknown   = markers[m.rightHip];
                lastLIASknown   = markers[m.leftHip];
            }
            newMarkers = markers;
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="isRightAnkle"></param>
        /// <returns></returns>
        private Vector3 GetAnklePos(bool isRightAnkle)
        {
            //Stolen from Visual3d
            Vector3 x, z, M1, M2, M3, negateY = new Vector3(1f, -1f, 1f);
            Matrix4 R;

            if (isRightAnkle)
            {
                M1 = markers[m.rightOuterKnee];  //FLE
                M3 = markers[m.rightLowerKnee];  //TTC
                M2 = markers[m.rightOuterAnkle]; //FAL
            }
            else
            {
                M1 = markers[m.leftOuterKnee];  //FLE
                M3 = markers[m.leftLowerKnee];  //TTC
                M2 = markers[m.leftOuterAnkle]; //FAL
            }
            x = Vector3Helper.MidPoint(M1, M2) - M3;
            z = M2 - M1;
            float scalefactor = z.Length;

            R = Matrix4Helper.GetOrientationMatrix(x, z);
            Vector3 trans = new Vector3(
                -0.07675f * scalefactor,
                0.05482f * scalefactor,
                -0.02741f * scalefactor);

            if (!isRightAnkle)
            {
                Vector3.Multiply(ref trans, ref negateY, out trans);
            }
            return(Vector3.TransformVector(trans, R) + M2);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="isRightKnee"></param>
        /// <returns></returns>
        private Vector3 GetKneePos(bool isRightKnee)
        {
            Vector3 x, z, M1, M2, M3, negateY = new Vector3(1f, -1f, 1f);

            if (isRightKnee)
            {
                M1 = markers[m.rightOuterKnee];    //FLE
                M2 = markers[m.rightOuterAnkle];   //FAL
                M3 = markers[m.rightLowerKnee];    //TTC
            }
            else
            {
                M1 = markers[m.leftOuterKnee];    //FLE
                M2 = markers[m.leftOuterAnkle];   //FAL
                M3 = markers[m.leftLowerKnee];    //TTC
            }
            x = Vector3Helper.MidPoint(M1, M2) - M3;
            z = M1 - M2;
            float   scalingFactor = z.Length;
            Matrix4 R             = Matrix4Helper.GetOrientationMatrix(x, z);
            Vector3 trans         = new Vector3(
                -0.1033f * scalingFactor,
                -0.09814f * scalingFactor,
                0.0597f * scalingFactor);

            if (isRightKnee)
            {
                Vector3.Multiply(ref trans, ref negateY, out trans);
            }
            return(Vector3.TransformVector(trans, R) + M1);
        }
Esempio n. 5
0
        /// <summary>
        /// Prepare the markerset for Joint localization, predicts the
        /// </summary>
        /// <param name="labelMarkers">The list of labelmarkets</param>
        /// <param name="newMarkers">a reference to the dictionary to be </param>
        /// <param name="prefix">The possible prefix of all markers</param>
        public void ProcessMarkers(List <LabeledMarker> labelMarkers, out Dictionary <string, Vector3> newMarkers, string prefix)
        {
            var temp = markers;

            markers          = markersLastFrame;
            markersLastFrame = temp;
            markers.Clear();
            for (int i = 0; i < labelMarkers.Count; i++)
            {
                markers.Add(labelMarkers[i].Label, labelMarkers[i].Position.Convert());
            }

            foreach (var markername in m)
            {
                if (!markers.ContainsKey(markername))
                {
                    markers.Add(markername, Vector3Helper.NaN);
                }
            }
            // sacrum can be defined by two markers
            if (sacrumBetween)
            {
                markers[m.bodyBase] =
                    Vector3Helper.MidPoint(markers[sacrumBetweenMarkers[0]],
                                           markers[sacrumBetweenMarkers[1]]);
            }
            //
            if (frontHeadBetween)
            {
                markers[m.head] =
                    Vector3Helper.MidPoint(markers[frontHeadBetweenMarkers[0]],
                                           markers[frontHeadBetweenMarkers[1]]);
            }
            if (markers[m.leftHip].IsNaN() ||
                markers[m.rightHip].IsNaN() ||
                markers[m.bodyBase].IsNaN())
            {
                MissingEssientialMarkers(markers);
            }
            else
            {
                lastSACRUMknown = markers[m.bodyBase];
                lastRIASknown   = markers[m.rightHip];
                lastLIASknown   = markers[m.leftHip];
            }
            newMarkers = markers;
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="isRightHip"></param>
        /// <returns></returns>
        private Vector3 GetHipJoint(bool isRightHip)
        {
            // As described by Harrington et al. 2006
            // Prediction of the hip joint centre in adults, children, and patients with
            // cerebral palsy based on magnetic resonance imaging
            Vector3 ASISMid = Vector3Helper.MidPoint(markers[m.rightHip], markers[m.leftHip]);
            float   Z, X, Y,
                    pelvisDepth = (ASISMid - markers[m.bodyBase]).Length * 1000,
                    pelvisWidth = (markers[m.leftHip] - markers[m.rightHip]).Length * 1000;

            X = 0.33f * pelvisWidth - 7.3f;
            Y = -0.30f * pelvisWidth - 10.9f;
            Z = -0.24f * pelvisDepth - 9.9f;
            if (!isRightHip)
            {
                X = -X;
            }
            return(ASISMid + Vector3.Transform((new Vector3(X, Y, Z) / 1000), HipOrientation));
        }
        /// <summary>
        /// If any of the hip markers are missing, we predict them using the last position
        /// </summary>
        /// <param name="markers">The dictionary of markers</param>
        private void MissingEssentialMarkers(Dictionary <string, Vector3> markers)
        {
            Vector3 dirVec1, dirVec2, possiblePos1, possiblePos2,
                    sacrumLastFrame = lastSACRUMknown,
                    liasLastFrame   = lastLIASknown,
                    riasLastFrame   = lastRIASknown;

            Vector3 Sacrum = markers[m.bodyBase],
                    RIAS   = markers[m.rightHip],
                    LIAS   = markers[m.leftHip];

            bool s = !Sacrum.IsNaN(),
                 r = !RIAS.IsNaN(),
                 l = !LIAS.IsNaN();

            if (s)                                             // sacrum exists
            {
                if (r)                                         // sacrum and rias exist, lias missing
                {
                    dirVec1 = liasLastFrame - sacrumLastFrame; // vector from sacrum too lias in last frame
                    dirVec2 = liasLastFrame - riasLastFrame;
                    Quaternion between = Quaternion.Invert(
                        QuaternionHelper2.GetRotationBetween(
                            (RIAS - Sacrum), (riasLastFrame - sacrumLastFrame))
                        );
                    Vector3 transVec1 = Vector3.Transform(dirVec1, (between));
                    Vector3 transVec2 = Vector3.Transform(dirVec2, (between));
                    possiblePos1       = Sacrum + transVec1;                                                                                // add vector from sacrum to lias last frame to this frames sacrum
                    possiblePos2       = RIAS + transVec2;
                    markers[m.leftHip] = DidntMovedToMuch(markersLastFrame[m.leftHip], Vector3Helper.MidPoint(possiblePos1, possiblePos2)); // get mid point of possible positions
                }
                else if (l)                                                                                                                 // sacrum  and lias exists, rias missing
                {
                    dirVec1 = riasLastFrame - sacrumLastFrame;
                    dirVec2 = riasLastFrame - liasLastFrame;
                    Quaternion between = Quaternion.Invert(
                        QuaternionHelper2.GetRotationBetween(
                            (LIAS - Sacrum), (liasLastFrame - sacrumLastFrame))
                        );
                    Vector3 transVec1 = Vector3.Transform(dirVec1, (between));
                    Vector3 transVec2 = Vector3.Transform(dirVec2, (between));
                    possiblePos1        = Sacrum + transVec1;
                    possiblePos2        = LIAS + transVec2;
                    markers[m.rightHip] = DidntMovedToMuch(markersLastFrame[m.rightHip], Vector3Helper.MidPoint(possiblePos1, possiblePos2));
                }
                else // only sacrum exists, lias and rias missing
                {
                    markers[m.rightHip] = DidntMovedToMuch(markersLastFrame[m.rightHip], Sacrum + riasLastFrame - sacrumLastFrame);
                    markers[m.leftHip]  = DidntMovedToMuch(markersLastFrame[m.leftHip], Sacrum + liasLastFrame - sacrumLastFrame);
                }
            }
            else if (r) // rias exists, sacrum missing
            {
                if (l)  // rias and ias exists, sacrum missing
                {
                    dirVec1 = sacrumLastFrame - riasLastFrame;
                    dirVec2 = sacrumLastFrame - liasLastFrame;

                    Quaternion between = Quaternion.Invert(
                        QuaternionHelper2.GetRotationBetween(
                            (LIAS - RIAS), (liasLastFrame - riasLastFrame))
                        );
                    Vector3 transVec1 = Vector3.Transform(dirVec1, (between));
                    Vector3 transVec2 = Vector3.Transform(dirVec2, (between));
                    possiblePos1        = RIAS + transVec1;
                    possiblePos2        = LIAS + transVec2;
                    markers[m.bodyBase] = DidntMovedToMuch(markersLastFrame[m.bodyBase], Vector3Helper.MidPoint(possiblePos1, possiblePos2));
                }
                else // only rias exists, lias and sacrum missing
                {
                    markers[m.bodyBase] = DidntMovedToMuch(markersLastFrame[m.bodyBase], RIAS + sacrumLastFrame - riasLastFrame);
                    markers[m.leftHip]  = DidntMovedToMuch(markersLastFrame[m.leftHip], RIAS + liasLastFrame - riasLastFrame);
                }
            }
            else if (l) // only lias exists, rias and sacrum missing
            {
                markers[m.bodyBase] = DidntMovedToMuch(markersLastFrame[m.bodyBase], LIAS + sacrumLastFrame - liasLastFrame);
                markers[m.rightHip] = DidntMovedToMuch(markersLastFrame[m.rightHip], LIAS + riasLastFrame - liasLastFrame);
            }
            else // all markers missing
            {
                markers[m.bodyBase] = markersLastFrame[m.bodyBase];
                markers[m.rightHip] = markersLastFrame[m.rightHip];
                markers[m.leftHip]  = markersLastFrame[m.leftHip];
            }
        }
 private void Pelvis(Bone b)
 {
     b.Pos         = Vector3Helper.MidPoint(HipJointRight, HipJointLeft);
     b.Orientation = HipOrientation;
 }