Как вычислить RELDX и RELDY для MJV_MovePerturb, чтобы объект следует за движением мыши в MUJOCOC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Как вычислить RELDX и RELDY для MJV_MovePerturb, чтобы объект следует за движением мыши в MUJOCO

Сообщение Anonymous »

Я реализую функцию перетаскивания в симуляторе Mujoco с использованием мыши. Цель: когда я нажимаю на объект и перемещаю мышь, объект должен двигаться точно с курсором. < /P>
Я использую mjv_moveperturb следующим образомQPointF deltaMouse = (event->position() - lastMousePosition) * devicePixelRatioF();

mjtNum deltaX = deltaMouse.x();
mjtNum deltaY = -deltaMouse.y();

mjtMouse perturbationType = event->modifiers() == Qt::ShiftModifier ? mjMOUSE_ROTATE_V : mjMOUSE_MOVE_H;
mjv_movePerturb(model, data, perturbationType, deltaX, deltaY, scene, perturb);
mjv_applyPerturbPose(model, data, perturb, 1);
< /code>
Deltamouse - это разница между текущими и предыдущими позициями мыши в пикселях. Перетаскивание работает частично: объект движется, но не соответствует движению мыши, смещение кажется неправильным и зависимым от Zoom. Из документации < /p>
// Move perturb object with mouse; action is mjtMouse.
MJAPI void mjv_movePerturb(const mjModel* m, const mjData* d, int action,
mjtNum reldx, mjtNum reldy,
const mjvScene* scn, mjvPerturb* pert)
< /code>
Мои вопросы: < /p>

В какой системе координат ожидается Reldx и Reldy? /> Сырая мышиная дельта в пикселях < /li>
Дельта от проецирования Click в 3D-координаты с помощью GluunProject < /li>
Delta из пересечения плоскости в мировой координате < /li>
< /ul>
Никто из них дает правильный «mesint». Как правильный способ вычислять RELDX и RELDY для MJV_MovePerturb?Vector3f SimulationViewport::computeDelta(QMouseEvent* event) {

Vector3f bodyTranslation = getBodyTranslation(dragSelection);
Matrix3f bodyRotation = getBodyRotationMatrix(dragSelection);
Vector3f cameraPos = getCameraInWorld();
calcDragPlaneVector();

// Intersection for current mouse position
Vector3f currentPos;
Vector3f projectedClick = projectClick( event->position().x() * devicePixelRatio(), event->position().y() * devicePixelRatio());
bool currBool = intersectRayAndPlane(cameraPos, (projectedClick - cameraPos).normalized(), bodyTranslation, dragPlaneVector, currentPos);

// Intersection for current mouse position
Vector3f previousPos;
Vector3f prevProjectedClick = projectClick(lastMousePosition.x() * devicePixelRatio(), lastMousePosition.y() * devicePixelRatio());
bool prevBool = intersectRayAndPlane(cameraPos, (prevProjectedClick - cameraPos).normalized(), bodyTranslation, dragPlaneVector, previousPos);

return (currBool && prevBool) ? (currentPos - previousPos).eval() : Vector3f::Zero();
}
< /code>
Vector3f SimulationViewport::projectClick(int x, int y) const{
GLdouble mvMatrix[16];
GLdouble projMatrix[16];
for(int i = 0; i < 16; ++i){
mvMatrix = static_cast(cameraTransformation);
projMatrix = static_cast(projection);
}

GLdouble tx, ty, tz;
gluUnProject(static_cast(x), static_cast(height - y), 1.0, mvMatrix, projMatrix, viewport, &tx, &ty, &tz);
return Vector3f(static_cast(tx), static_cast(ty), static_cast(tz));
}
< /code>
bool SimulationViewport::intersectRayAndPlane(const Vector3f& point, const Vector3f& v,
const Vector3f& plane, const Vector3f& n,
Vector3f& intersection) const{
Vector3f p = plane - point;
float denominator = n.dot(v);
if(denominator == 0.f)
return false;
float r = n.dot(p) / denominator;
if(r < 0.f)
return false;
intersection = v;
intersection *= r;
intersection += point;
return true;
}


Подробнее здесь: https://stackoverflow.com/questions/797 ... s-mouse-mo
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»