Принимая среднее из нескольких векторов 3 - PullRequest
0 голосов
/ 26 февраля 2019

Так что я работаю с камерой глубины, которая работает как Kinect.(это не Kinect).и с Nuitrack позади этого для отслеживания скелета.Однако позиция, которую он возвращает для игрока, шаткая.Когда он стоит совершенно неподвижно, он возвращает числа, которые могут увеличиваться или уменьшаться до примерно 10.

Пример: пользователь стоит так неподвижно, как может, и данные возвращают позицию 100 в первом и следующем кадрах.102, потом 97, потом снова 100, потом 106 и т. Д. Он возвращает эти позиции в обновлении, и мы используем его для перемещения изображения вместе с ним.(таким образом, пользователь управляет изображением) Но, как вы могли ожидать, это изображение движется очень шатко из-за противоречивых данных.Согласно Nuitrack, это правильно, и сам пользователь должен найти решение для этого.enter image description here

Я пытался прыгать с одной позиции на другую, но это заставляет его чувствовать себя менее интерактивным, потому что, как только я нахожусь в точке, где дрессировка действительно гладкая, она имеетогромная задержкаЯ также пытался использовать только новые данные позиции, если они отличаются, скажем, 4 пикселя от предыдущей позиции, которую дал мне Nuitrack, это работает немного лучше, но приводит к скачкам изображения, даже если я его перелистываю.Использование этой функции:

foreach (User user in frame.Users)
        {
            if (Vector3.Distance(_lastPos, user.Proj.ToVector3()) >4f)
            {
                Vector3 final = ((_lastPos + user.Proj.ToVector3()) /2);
                userData.Add(new UserData(user.ID, user.Real.ToVector3(), final));
                _lastPos = user.Proj.ToVector3();
            }
            else
            {
                userData.Add(new UserData(user.ID, user.Real.ToVector3(), _lastPos));
            }

И функция lerp:

float _userX = user.ProjPosition.x * (_cameraPos.x *2)- _cameraPos.x;
            Vector3 _newPos = new Vector3(_userX, _basketPos.y, _basketPos.z);
            _basketPrefab.transform.position = Vector3.Lerp(_basketPrefab.transform.position, _newPos, Time.deltaTime * 30f);

РЕДАКТИРОВАТЬ: Кто-нибудь еще?

1 Ответ

0 голосов
/ 26 февраля 2019

Вы можете попытаться сохранить список последних n позиций, а затем рассчитать среднее значение этих позиций, сложив их вместе, используя 0.5f (половинное значение) как t.Затем вы можете увеличить уровень «сглаживания», снова сопоставляя ранее зафиксированные позиции друг с другом, делая его более плавным с каждой итерацией.Каждая итерация, однако, заставляет его чувствовать себя немного вялым, и нужно найти баланс между плавным и реактивным.

(пример не проверен).

List<Quaternion> lastPosition = new List<Quaternion>(); //Keep a list of the last positions
int smoothing = 16; //Max amount of smoothing, higher means more positions will be used for the smoothness
enum SmoothingLevels { None, Mild, Moderate, Severe, Extreme } //Level of smoothness you want to use
SmoothingLevels smoothingLevel;
Vector3 pos;

//remove the oldest entry from the list 
if(lastPosition.Count > 0)
{
    lastPosition.RemoveAt(0);
}

//Add the newest data to the list
while (lastPosition.Count < smoothing)
{
    lastPosition.Add(transform.position);
}

Vector3 vecA = lastPosition[0];
Vector3 vecB = lastPosition[1];
Vector3 vecC = lastPosition[2];
Vector3 vecD = lastPosition[3];
Vector3 vecE = lastPosition[4];
Vector3 vecF = lastPosition[5];
Vector3 vecG = lastPosition[6];
Vector3 vecH = lastPosition[7];
Vector3 vecI = lastPosition[8];
Vector3 vecJ = lastPosition[9];
Vector3 vecK = lastPosition[10];
Vector3 vecL = lastPosition[11];
Vector3 vecM = lastPosition[12];
Vector3 vecN = lastPosition[13];
Vector3 vecO = lastPosition[14];
Vector3 vecP = lastPosition[15];

//Lerp each subsequent position by t 0.5 to get the average position of the two.
//This is the base smoothing, where smoothing is low and responsiveness is high
Vector3 vecAB = Vector3.Lerp(vecA, vecB, 0.5f);
Vector3 vecCD = Vector3.Lerp(vecC, vecD, 0.5f);
Vector3 vecEF = Vector3.Lerp(vecE, vecF, 0.5f);
Vector3 vecGH = Vector3.Lerp(vecG, vecH, 0.5f);
Vector3 vecIJ = Vector3.Lerp(vecI, vecJ, 0.5f);
Vector3 vecKL = Vector3.Lerp(vecK, vecL, 0.5f);
Vector3 vecMN = Vector3.Lerp(vecM, vecN, 0.5f);
Vector3 vecOP = Vector3.Lerp(vecO, vecP, 0.5f);

//moderate smoothing, Lerp the previously lerped position again with each other to increase the smoothness
Vector3 vecABCD = Vector3.Lerp(vecAB, vecCD, 0.5f);
Vector3 vecEFGH = Vector3.Lerp(vecEF, vecGH, 0.5f);
Vector3 vecIJKL = Vector3.Lerp(vecIJ, vecKL, 0.5f);
Vector3 vecMNOP = Vector3.Lerp(vecMN, vecOP, 0.5f);

//Severe smoothing, High smoothness, lower responsiveness
Vector3 vecABCDEFGH = Vector3.Lerp(vecABCD, vecEFGH, 0.5f);
Vector3 vecIJKLMNOP = Vector3.Lerp(vecIJKL, vecMNOP, 0.5f);

//Extreme smoothing, this will take the average of all 16 positions. Very smooth, feels really sluggish
Vector3 vecABCDEFGHIJKLMNOP = Vector3.Lerp(vecABCDEFGH, vecIJKLMNOP, 0.5f);
switch (smoothingLevel)
{
    case SmoothingLevels.None:
        pos = transform.position;
        break;
    case SmoothingLevels.Mild:
        pos = vecOP;
        break;
    case SmoothingLevels.Moderate:
        pos = vecMNOP;
        break;
    case SmoothingLevels.Severe:
        pos = vecIJKLMNOP;
        break;
    case SmoothingLevels.Extreme:
        pos = vecABCDEFGHIJKLMNOP;
        break;
}

//apply pos to your target object
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...