예제 #1
0
    public static Vector3 GetVecWithoutYRot(Vector3 coords)
    {
        SphericalCoords sphCoords = CartesianToSpherical(coords);

        sphCoords.theta = 0;
        return(sphCoords.ToCartesian());
    }
예제 #2
0
    private void FillKNNTrees(KNNBone rootBone, bool ignoreRotation, bool bothHandsInFeatureVec, string headBoneName, string rHandBoneName, string lHandBoneName, float slidingWindowSizeInMS, float slidingWindowOffsetInMS, float pollingRate, List <int> lHandTreeNodes, List <int> rHandTreeNodes, List <float[]> lHandTreePoints, List <float[]> rHandTreePoints)
    {
        float sourceFrameTime     = bvhParser.frameTime;
        float targetFrameTime     = 1.0f / pollingRate;
        float totalTime           = bvhParser.frames * sourceFrameTime;
        int   totalNewFrames      = (int)(totalTime / targetFrameTime);
        float slidingWindowOffset = slidingWindowOffsetInMS / 1000.0f;
        float slidingWindowSize   = slidingWindowSizeInMS / 1000.0f;

        int totalWindows     = (int)((totalTime - (slidingWindowSize)) / (slidingWindowOffset));
        int framesPerWindow  = (int)((slidingWindowSize) / targetFrameTime);
        int nrOfFeatures     = bothHandsInFeatureVec ? 18 : 9;
        int featureVecLength = nrOfFeatures * framesPerWindow;

        setToFrame(0, true, true, true);

        for (int currentWindow = 0; currentWindow < totalWindows; currentWindow++)
        {
            float[] lHandPoints = new float[featureVecLength];
            float[] rHandPoints = new float[featureVecLength];

            for (int currFrame = 0; currFrame < framesPerWindow; currFrame++)
            {
                float startTime   = slidingWindowOffset * (float)currentWindow;
                float sourceFrame = getSourceFrameFromTargetTime(sourceFrameTime, startTime + (float)currFrame * targetFrameTime);
                setToFrame(sourceFrame, true, true, true);
                Vector3 rHandPosition = root.Find(rHandBoneName).position;
                Vector3 lHandPosition = root.Find(lHandBoneName).position;

                if (sourceFrame >= 1.0f)
                {
                    setToFrame(sourceFrame - 1.0f, true, true, true);
                }

                Vector3 prevRHandPosition = root.Find(rHandBoneName).position;
                Vector3 prevLHandPosition = root.Find(lHandBoneName).position;

                if (sourceFrame >= 2.0f)
                {
                    setToFrame(sourceFrame - 2.0f, true, true, true);
                }

                Vector3 prevPrevRHandPosition = root.Find(rHandBoneName).position;
                Vector3 prevPrevLHandPosition = root.Find(lHandBoneName).position;

                Vector3 lHandVelocity = (lHandPosition - prevLHandPosition) / sourceFrameTime;
                Vector3 rHandVelocity = (rHandPosition - prevRHandPosition) / sourceFrameTime;

                Vector3 prevLHandVelocity = (prevLHandPosition - prevPrevLHandPosition) / sourceFrameTime;
                Vector3 prevRHandVelocity = (prevRHandPosition - prevPrevRHandPosition) / sourceFrameTime;

                Vector3 lHandAcceleration = (lHandVelocity - prevLHandVelocity) / sourceFrameTime;
                Vector3 rHandAcceleration = (rHandVelocity - prevRHandVelocity) / sourceFrameTime;

                if (ignoreRotation)
                {
                    SphericalCoords rHandSpPosition = SphericalCoords.CartesianToSpherical(rHandPosition);
                    SphericalCoords lHandSpPosition = SphericalCoords.CartesianToSpherical(lHandPosition);

                    float rHandAngle = rHandSpPosition.theta * Mathf.Rad2Deg;
                    float lHandAngle = lHandSpPosition.theta * Mathf.Rad2Deg;

                    //rotate velocity and acceleration angle around "theta"
                    lHandVelocity = Quaternion.AngleAxis(lHandAngle, Vector3.up) * lHandVelocity;
                    rHandVelocity = Quaternion.AngleAxis(rHandAngle, Vector3.up) * rHandVelocity;

                    lHandAcceleration = Quaternion.AngleAxis(lHandAngle, Vector3.up) * lHandAcceleration;
                    rHandAcceleration = Quaternion.AngleAxis(rHandAngle, Vector3.up) * rHandAcceleration;

                    rHandSpPosition.theta = 0;
                    lHandSpPosition.theta = 0;

                    rHandPosition = rHandSpPosition.ToCartesian();
                    lHandPosition = lHandSpPosition.ToCartesian();
                }


                int pointOffset = currFrame * nrOfFeatures;
                lHandPoints[pointOffset]     = lHandPosition.x;
                lHandPoints[pointOffset + 1] = lHandPosition.y;
                lHandPoints[pointOffset + 2] = lHandPosition.z;

                lHandPoints[pointOffset + 3] = lHandVelocity.x;
                lHandPoints[pointOffset + 4] = lHandVelocity.y;
                lHandPoints[pointOffset + 5] = lHandVelocity.z;

                lHandPoints[pointOffset + 6] = lHandAcceleration.x;
                lHandPoints[pointOffset + 7] = lHandAcceleration.y;
                lHandPoints[pointOffset + 8] = lHandAcceleration.z;

                rHandPoints[pointOffset]     = rHandPosition.x;
                rHandPoints[pointOffset + 1] = rHandPosition.y;
                rHandPoints[pointOffset + 2] = rHandPosition.z;

                rHandPoints[pointOffset + 3] = rHandVelocity.x;
                rHandPoints[pointOffset + 4] = rHandVelocity.y;
                rHandPoints[pointOffset + 5] = rHandVelocity.z;

                rHandPoints[pointOffset + 6] = rHandAcceleration.x;
                rHandPoints[pointOffset + 7] = rHandAcceleration.y;
                rHandPoints[pointOffset + 8] = rHandAcceleration.z;

                if (bothHandsInFeatureVec)
                {
                    lHandPoints[pointOffset + 9]  = rHandPosition.x;
                    lHandPoints[pointOffset + 10] = rHandPosition.y;
                    lHandPoints[pointOffset + 11] = rHandPosition.z;

                    lHandPoints[pointOffset + 12] = rHandVelocity.x;
                    lHandPoints[pointOffset + 13] = rHandVelocity.y;
                    lHandPoints[pointOffset + 14] = rHandVelocity.z;

                    lHandPoints[pointOffset + 15] = rHandAcceleration.x;
                    lHandPoints[pointOffset + 16] = rHandAcceleration.y;
                    lHandPoints[pointOffset + 17] = rHandAcceleration.z;

                    rHandPoints[pointOffset + 9]  = lHandPosition.x;
                    rHandPoints[pointOffset + 10] = lHandPosition.y;
                    rHandPoints[pointOffset + 11] = lHandPosition.z;

                    rHandPoints[pointOffset + 12] = lHandVelocity.x;
                    rHandPoints[pointOffset + 13] = lHandVelocity.y;
                    rHandPoints[pointOffset + 14] = lHandVelocity.z;

                    rHandPoints[pointOffset + 15] = lHandAcceleration.x;
                    rHandPoints[pointOffset + 16] = lHandAcceleration.y;
                    rHandPoints[pointOffset + 17] = lHandAcceleration.z;
                }
            }
            int lastPositionSourceIndex = (int)((currentWindow * slidingWindowOffset + slidingWindowSize) / sourceFrameTime);

            setToFrame(lastPositionSourceIndex, true, true, true);
            rootBone.AddRotationsFromTransform(root);

            lHandTreePoints.Add(lHandPoints); lHandTreeNodes.Add(lHandTreeNodes.Count);
            rHandTreePoints.Add(rHandPoints); rHandTreeNodes.Add(rHandTreeNodes.Count);
        }
    }
예제 #3
0
    public void SetSkeletonFromHandPos(KDTree <float, int> tree, LinkedList <FeatureItem> features, string handName, int k)
    {
        float[]   featureVec    = new float[featureVectorLength];
        Transform headTransform = rootBone.transform.Find("LowerBack/Spine/Spine1/Neck/Neck1/Head");
        Transform neckTransform = rootBone.transform.Find("LowerBack/Spine/Spine1/Neck/Neck1/Head");

        rootBone.transform.position -= headTransform.position;

        float handTargetSpPositionAngle = SphericalCoords.GetYRotFromVec(features.Last().position) * Mathf.Rad2Deg;

        var currFeatureContainer = features.Last;

        Debug.Assert(featureVectorLength % 9 == 0);
        for (int i = 0; i < featureVectorLength / 9; i++)
        {
            FeatureItem currFeatureItem = currFeatureContainer.Value;

            Vector3 handPos = currFeatureItem.position;
            Vector3 handVel = currFeatureItem.velocity;
            Vector3 handAcc = currFeatureItem.acceleration;

            if (ignoreRotation)
            {
                float handYRotValue = SphericalCoords.GetYRotFromVec(handPos) * Mathf.Rad2Deg;

                SphericalCoords sphCoords = SphericalCoords.CartesianToSpherical(handPos);
                sphCoords.theta = 0;
                Vector3 outVec = sphCoords.ToCartesian();

                handPos = Quaternion.AngleAxis(handYRotValue, Vector3.up) * handPos;
                handVel = Quaternion.AngleAxis(handYRotValue, Vector3.up) * handVel;
                handAcc = Quaternion.AngleAxis(handYRotValue, Vector3.up) * handAcc;
            }

            int startIndex = 9 * i;
            featureVec[startIndex]     = handPos.x;
            featureVec[startIndex + 1] = handPos.y;
            featureVec[startIndex + 2] = handPos.z;

            featureVec[startIndex + 3] = handVel.x;
            featureVec[startIndex + 4] = handVel.y;
            featureVec[startIndex + 5] = handVel.z;

            featureVec[startIndex + 6] = handAcc.x;
            featureVec[startIndex + 7] = handAcc.y;
            featureVec[startIndex + 8] = handAcc.z;

            if (currFeatureContainer.Previous != null)
            {
                currFeatureContainer = currFeatureContainer.Previous;
            }
        }

        Tuple <float[], int>[] poseIndices = tree.NearestNeighbors(featureVec, k);

        int index = poseIndices[0].Item2;

        RotationIndex[] rotations = new RotationIndex[poseIndices.Length];

        for (int i = 0; i < poseIndices.Length; i++)
        {
            double        distance = Metrics.WeightedL2Norm(poseIndices[i].Item1, featureVec);
            RotationIndex currIdx  = new RotationIndex(poseIndices[i].Item2, (float)(1.0 / distance));
            rotations[i] = currIdx;
        }

        rootBone.SetToRotations(rotations);
        //rootBone.SetToRotation(index);

        Transform       handTransform                = rootBone.transform.Find(handName);
        SphericalCoords handTransformSpPosition      = SphericalCoords.CartesianToSpherical(handTransform.position - headTransform.position);
        float           handTransformSpPositionAngle = handTransformSpPosition.theta * Mathf.Rad2Deg;

        rootBone.transform.localRotation *= Quaternion.Euler(0, -handTargetSpPositionAngle + handTransformSpPositionAngle, 0);
    }