Вопрос:

Перетаскивание 3D-рычага (в зависимости от ориентации и угла обзора)

c++ algorithm math 3d unreal-engine4

197 просмотра

2 ответа

905 Репутация автора

В моем проекте (C ++ / UE4) у меня торчащая из пола сетка рычага. Удерживая левую кнопку мыши на этом рычаге и двигая мышь, можно начать операцию перетаскивания. Эта операция перетаскивания отвечает за вычисление движений двухмерной дельта-мыши и использование этих данных для поворота рычага * в локальном пространстве * , который может вращаться только на одной оси (отрицательной или положительной, но все же только на одной оси).

Но что, если вместо того, чтобы находиться перед рычагом, я на самом деле за ним? Что если я на одной из его сторон? Что если рычаг торчит из стены, а не из пола? ... Как сделать так, чтобы движения мыши фактически поворачивали рычаг на угол, под которым он виден, независимо от его ориентации?


Для дальнейшего объяснения ...
Вот список сценариев и то, как я бы хотел, чтобы мышь управляла ими:

Когда рычаг находится на ЭТАЖЕ, и вы находитесь ВПЕРЕДИ этого:

  • Если вы двигаете мышь ВВЕРХ (-Y), она должна поворачиваться в сторону от камеры
  • Если вы перемещаете мышь ВНИЗ (+ Y), она должна поворачиваться к камере

Когда рычаг на ЭТАЖЕ, и вы позади него:

  • Если вы двигаете мышь ВВЕРХ (-Y), она должна поворачиваться в сторону от камеры
    (которая противоположна направлению в мировом пространстве, когда вы находитесь перед ней)
  • Если вы перемещаете мышь ВНИЗ (+ Y), она должна поворачиваться в сторону камеры
    (которая противоположна направлению в мировом пространстве, когда вы находитесь перед ней)

Когда рычаг на ЭТАЖЕ, а вы рядом с ним:

  • Если вы перемещаете мышь влево (-X), она должна поворачиваться влево влево
    (в противоположном направлении, когда вы находитесь на другой стороне от нее)
  • Если вы передвинете мышь вправо (+ X), она должна повернуться вправо от камеры
    (в противоположном направлении, когда вы находитесь на другой стороне от нее)

Когда рычаг на стене, и вы находитесь в передней части этого:

  • Если вы двигаете мышь ВВЕРХ, она должна вращаться ВВЕРХ (к небу)
  • Если вы перемещаете мышь ВНИЗ, она должна вращаться ВНИЗ (к полу)

Когда рычаг на стене и вы рядом с ним:

  • То же самое, что когда оно на стене, а ты перед ним

ПОЖАЛУЙСТА, ОБРАТИТЕ ВНИМАНИЕ, если это вообще поможет, то, что UE4 имеет встроенные 2D / 3D векторные математические функции, а также простые способы проецировать и выводить координаты в / из мира 3D или 2D-экрана. Из-за этого я всегда знаю точные мировые и экранные координаты местоположения мыши, положение поворота (основания) рычага и положение ручки (вверху) рычага, а также количество (дельта), которое мышь переместил каждый кадр.

Автор: RectangleEquals Источник Размещён: 28.06.2016 04:54

Ответы (2)


1 плюс

9947 Репутация автора

Получите поворот рычага (точка вокруг него вращается) и спроецируйте его на координаты экрана. Затем при первом щелчке вы сохраняете координаты щелчка.

Теперь, когда вам нужно узнать, каким образом вращать, вы вычисляете скалярное произведение между векторным шарниром для первого щелчка и векторным шарниром в текущем местоположении (вы должны нормализовать векторы перед точечным произведением). Это дает вам (угол) перемещения мыши, и вы можете использовать ее (взять arccos (значение), чтобы получить угол), чтобы переместить рычаг в 3d. Это будет немного странно, поскольку угол на экране не совпадает с углом проекции, но его легче контролировать (если вы перемещаете мышь на 90 градусов, рычаг перемещается на 90 градусов, даже если они не выровнены должным образом). Поиграйте с настройкой и посмотрите, что лучше всего подходит для вашего проекта.

Еще один способ сделать это: при первом щелчке вы сохраняете точку конца рычага (или даже лучше точку, где вы щелкнули по рычагу) в трехмерном пространстве. Вы используете плоскость проекции камеры, чтобы переместить точку в 3d (вы можете использовать вектор вверх камеры, после того, как вы сделаете ее ортогональной к направлению обзора камеры, а затем возьмете вектор пересечения направления обзора, чтобы получить правильное направление). Вы применяете дельта-движения мыши к точке, затем проецируете ее в плоскость вращения и перемещаете рычаг, чтобы выровнять точку по проекции (математика аналогична приведенной выше, просто используйте 3d-точки вместо проекций экрана) ,

Внимание: это не работает, если камера находится очень близко к плоскости вращения, так как не всегда ясно, должен ли рычаг двигаться вперед или назад.

Я не эксперт по unreal-engine4 (просто учусь сам), но все это основополагающая векторная математика и должна поддерживаться хорошо. Ознакомьтесь с точечным продуктом и перекрестным продуктом в Википедии, так как они очень полезны для такого рода уловок.

Автор: Sorin Размещён: 28.06.2016 08:38

0 плюса

5230 Репутация автора

Вот один из подходов:

  1. Когда пользователь нажимает на рычаг, предположим, что существует плоскость, проходящая через ось рычага, нормаль которой совпадает с направлением от камеры к оси. Вычислите точку пересечения луча курсора и этой плоскости.

    FVector rayOrigin;
    FVector rayDirection;
    FVector cameraPosition;
    FVector leverPivotPosition;
    
    FVector planeNormal = (leverPivotPosition-cameraPosition).GetSafeNormal(0.0001f);
    
    float t = ((leverPivotPosition - rayOrigin) | planeNormal) / (planeNormal | rayDirection);
    
    FVector planeHitPosition = rayOrigin + rayDirection * t;
    
  2. Сделайте скалярную проекцию этого на местную верхнюю / нижнюю ось рычага. Давайте предположим, что это локальная ось вверх / вниз:

    FVector leverLocalUpDirectionNormalized;
    
    float scalarPosition = planeHitPosition | leverLocalUpDirectionNormalized;
    
  3. Затем в каждом кадре, где рычаг удерживается, рассчитайте новый scalarPositionдля этого кадра. При scalarPositionувеличении между рамами рычаг должен вращаться так, чтобы он двигался к верхней стороне рычага. При уменьшении между рамами рычаг должен вращаться в направлении нижней части рычага.

Автор: Ruzihm Размещён: 11.06.2019 10:25
Вопросы из категории :
32x32