Координаты мышки в 3д пространчтве

Работа с 2D и 3D графикой, видео, звуком.

Модератор: Mikle

Sneaks
Обычный пользователь
Обычный пользователь
 
Сообщения: 67
Зарегистрирован: 29.07.2006 (Сб) 12:08

Координаты мышки в 3д пространчтве

Сообщение Sneaks » 27.04.2023 (Чт) 11:23

Доброго времени суток.
Задача в принципе простая, но не могу решить)
В принципе все просто, у нас есть координаты камеры, по ней спокойно кидаем луч прямо. Допустим нам надо узнать координаты на горизонтальной плоскости, с высотой 0. у нас есть расстояние когда луч будет 0 и тут все сходится.
Как сделать отклонение, центр экрана это 0 градусов, соответственно левый край будет 45( фов=90, половина 45). Берем координаты мышки, перемножаем, получаем угол отклонения. Теперь надо луч из центра провернуть на два угла, отклонение по Х и У. В каком порядке и как правильно это сделать?
У меня вышло вот что:

Код: Выделить всё
      MatrixRotationY Mtrx2, vScr.x
      MatrixRotationYawPitchRoll Mtrx3, ugol, ugolH + vScr.z, 0
                 MatrixMultiply Mtrx2, Mtrx2, Mtrx3
        Vec3TransformCoord v, v, Mtrx2

И оно относительно правильно проворачивае, но есть постоянные отклонения, по Х. Около центра по Х в меньшую сторону и на углах в в большую. Начал лепить костыли, которые улучшают значения, но не решают. Вот решил спросить, может я изначально как то все не так сделал и есть легкие решения.

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Координаты мышки в 3д пространчтве

Сообщение Mikle » 27.04.2023 (Чт) 20:52

Sneaks писал(а):Берем координаты мышки, перемножаем, получаем угол отклонения.

Координаты мышки - это не угол, а тангенс угла. Если я правильно понял проблему, то в этом всё дело.
А вообще, можно же взять MatrixLookAtLH() прямо из камеры на плоскость бэкбуфера с координатами мыши.

Sneaks
Обычный пользователь
Обычный пользователь
 
Сообщения: 67
Зарегистрирован: 29.07.2006 (Сб) 12:08

Re: Координаты мышки в 3д пространчтве

Сообщение Sneaks » 28.04.2023 (Пт) 14:37

Код: Выделить всё
Public Sub DrowUnitUp()
Dim sdvigy As Single, sdvigx As Single
Dim v As D3DVECTOR, vX As D3DVECTOR, vZ As D3DVECTOR
Dim vScr As D3DVECTOR, vCam As D3DVECTOR
Dim Mtrx3 As D3DMATRIX
Dim Mtrx4 As D3DMATRIX
Dim Mtrx5 As D3DMATRIX

Dim GrX As Single, GrY As Single
Dim ugol As Single, ugolH As Single



screenx = Form1.ScaleWidth
screenY = Form1.ScaleHeight


GrX = MouseX / (screenx / FovX)
GrY = MouseY / (screenY / FovY)

FovX2 = FovX / 2

  iObj = 0
   
  Vec3Subtract vCam, Vec3(cam(3), cam(4), cam(5)), Vec3(cam(0), cam(1), cam(2))
  Vec3Subtract v, Vec3(0, 0, 1), Vec3(0, 0, 0)

  Vec3Normalize v, v
  Vec3Normalize vCam, vCam

 
  clcX = Int(GrX - FovX2)
  clcY = Int(GrY - (FovY / 2))
 
  iNX = (Abs(clcX) + Abs(clcY)) / 100
 
uNX = ((Abs(clcX) + Abs(clcY)) - FovX2) / 10

If clcX < 0 Then uNX = uNX * -1

  vScr.x = Sin(((GrX - (FovX / 2))) * Pi / 180#) ' 'óãîë îòêëîíåíèÿ ìûøêè ïî ãîðèçîíòó
  vScr.y = 0
  vScr.z = Sin((GrY - (FovY / 2)) * Pi / 180#) ' 'óãîë îòêëîíåíèÿ ìûøêè ïî âåðòèêàëè
 
If Abs(clcX) + Abs(clcY) > FovX2 Then 'êîñòûëü ëå÷èò óëèòàíèå ïî óãëàì

    uNX = ((Abs(clcX) + Abs(clcY)) - FovX2) / 10

    If clcX < 0 Then uNX = uNX * -1
 
    vScr.x = Sin(((GrX - FovX2) - uNX) * Pi / 180#)

End If
 
  ugol = Atn(vCam.x / vCam.z) 'óãîë êàìåðû ïî âåðòèêàëè
 
    If cam(5) < cam(2) Then ugol = ugol + Pi
 
Form1.List1.Clear
Form1.List1.AddItem Abs(clcX) + Abs(clcY)
Form1.List1.AddItem Abs(clcX)
Form1.List1.AddItem Abs(clcY)

Form1.List1.AddItem "Unx: " & uNX
Form1.List1.AddItem "iNX: " & iNX

      MatrixRotationY Mtrx5, ugol * -1 'ðàçâåðíóëè âåðòèêàëü íà ñåâåð

      Vec3TransformCoord vCam, vCam, Mtrx5
      Vec3Normalize vCam, vCam

  ugolH = Atn(vCam.y / vCam.z * -1) 'óãîë êàìåðû ïî âåðòèêàëè

      MatrixRotationY Mtrx2, vScr.x
      'MatrixRotationX Mtrx4, vScr.z
     
      MatrixRotationYawPitchRoll Mtrx3, ugol, ugolH + vScr.z, 0

      'MatrixRotationYawPitchRoll Mtrx3, ugol, ugolH, 0
                 MatrixMultiply Mtrx2, Mtrx2, Mtrx3

        Vec3TransformCoord v, v, Mtrx2

ds = cam(1) / (v.y * -1)

      MatrixTranslation Mtrx, v.x * ds + cam(0), v.y * ds + cam(1) + 5, v.z * ds + cam(2)

    d3dDevice.SetTransform D3DTS_WORLD, Mtrx

     d3dDevice.SetTexture 0, Nothing

  d3dDevice.SetFVF vFlag

  d3dDevice.DrawIndexedPrimitiveUp D3DPT_TRIANGLELIST, 0, 6, 2, VarPtr(IndUPmodel(0, iObj)), D3DFMT_INDEX16, VarPtr(VertUPmodel(0, iObj)), vSize
End Sub



Извиняюсь за кашу, все было на уровне эксперимента и сотни раз переделывалось и переписывалось.

Скидываю весь проект для того что бы можно было увидеть наглядно что точка плывет:
https://disk.yandex.ru/d/crL26ZTpqhdrBw
стрелки управление камерой, с шифтом управление цели камеры, PgUp PgDn управление по вертикали.
квадрат должен быть по центру мышки, и на верху.
Этот вариант с костылем на углах, без него на углах улетает на горизонтали
И еще, у меня почему то на разных аппаратах фов разный, на компе и ноуте подходит 76, на планшете 70. Думаю связанно с разрешением но пока не до этого) на правую кнопку мышки можно изменить логический фов

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Координаты мышки в 3д пространчтве

Сообщение Mikle » 29.04.2023 (Сб) 8:45

Sneaks писал(а):Извиняюсь за кашу, все было на уровне эксперимента и сотни раз переделывалось и переписывалось.

Думаешь, легко разобраться в таком коде.
Я когда-то писал демку с выбором мышкой точки на ландшафте, демку прилагаю, там при нажатых кнопках мыши курсор свободный.
Это ещё на DX8, придётся регистрировать dx8vb.dll. Но математика та же самая, только в матрице проекции Aspect имеет обратный смысл (не Width/Height, а Height/Width).
У вас нет доступа для просмотра вложений в этом сообщении.

Sneaks
Обычный пользователь
Обычный пользователь
 
Сообщения: 67
Зарегистрирован: 29.07.2006 (Сб) 12:08

Re: Координаты мышки в 3д пространчтве

Сообщение Sneaks » 29.04.2023 (Сб) 9:44

Спасибо

Sneaks
Обычный пользователь
Обычный пользователь
 
Сообщения: 67
Зарегистрирован: 29.07.2006 (Сб) 12:08

Re: Координаты мышки в 3д пространчтве

Сообщение Sneaks » 02.05.2023 (Вт) 10:11

Сделал как у тебя, мне твой вариант больше понравился.
Но проблема осталась, все ровно так же улетает.
Вывел то что проблема не как поворачивать луч, с этим все нормально, а в том как этот угол считать с экрана. У меня шаг градуса идет линейный, т.е. ширина экрана делить на 90. А видим мы в перспективе, и я так понял, есть некий рыбий глаз, который искажает.
Пока ищу решения в интернетах

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Координаты мышки в 3д пространчтве

Сообщение Mikle » 02.05.2023 (Вт) 10:53

Sneaks писал(а):У меня шаг градуса идет линейный, т.е. ширина экрана делить на 90. А видим мы в перспективе

Я же выше писал:
Координаты мышки - это не угол, а тангенс угла.

И я не понял, если ты сделал как у меня, то почему не улетает у меня.

Sneaks
Обычный пользователь
Обычный пользователь
 
Сообщения: 67
Зарегистрирован: 29.07.2006 (Сб) 12:08

Re: Координаты мышки в 3д пространчтве

Сообщение Sneaks » 02.05.2023 (Вт) 12:58

Код: Выделить всё
    vDir = vec3(-Sin(Angle) * Cos(Diff), Sin(Diff), Cos(Angle) * Cos(Diff))
    D3DXMatrixRotationX mDir, Diff
    D3DXMatrixRotationY Mtrx, Angle
    D3DXMatrixMultiply mDir, Mtrx, mDir
    D3DXMatrixTranspose mDir, mDir
    v = vec3(X, y, 0)
    D3DXVec3TransformCoord v, v, mDir
    D3DXVec3Add vDir, vDir, v

Это у тебя.
Своровал как у тебя я это - vDir = vec3(-Sin(Angle) * Cos(Diff), Sin(Diff), Cos(Angle) * Cos(Diff))
далее у тебя происходит магия которую я не могу понять, если не сложно объясни пожалуйста:
Код: Выделить всё
    v = vec3(X, y, 0)

х,у это координаты мышки на экране
Код: Выделить всё
    D3DXVec3TransformCoord v, v, mDir
    D3DXVec3Add vDir, vDir, v

как мы тут получили угол отклонения?

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Координаты мышки в 3д пространчтве

Сообщение Mikle » 02.05.2023 (Вт) 16:15

Я не работаю здесь с углами. Угла Angle и Diff - это поворот и наклон камеры, но не точки, куда указывает мышь, если в режиме свободного курсора. Далее только матрицы и вектора, никаких углов.
Это я получаю вектор направления камеры:
Код: Выделить всё
    vDir = vec3(-Sin(Angle) * Cos(Diff), Sin(Diff), Cos(Angle) * Cos(Diff))

Это расчёт матрицы, которая повернёт единичный вектор в направлении, как у камеры:
Код: Выделить всё
    D3DXMatrixRotationX mDir, Diff
    D3DXMatrixRotationY Mtrx, Angle
    D3DXMatrixMultiply mDir, Mtrx, mDir
    D3DXMatrixTranspose mDir, mDir

Это я беру вектор направления на пиксель, куда направлена мышь, в плоскости, перпендикулярной направлению камеры, умножаю его на вычисленную матрицу, прибавляю к вектору направления камеры, в результате получаю вектор из камеры на пиксель, куда направлена мышь, уже в мировом пространстве:
Код: Выделить всё
    v = vec3(x, y, 0)
    D3DXVec3TransformCoord v, v, mDir
    D3DXVec3Add vDir, vDir, v

А тут я нахожу точку пересечения этого вектора с ландшафтом и рисую в этой точке чайник:
Код: Выделить всё
  If LS.RayInterSector(v, CamPos, vDir) Then
    D3DXMatrixTranslation Mtrx, v.x, v.y, v.Z
    d3dDevice.SetTransform D3DTS_WORLD, Mtrx
    Teapot.DrawSubset 0&
  End If

Sneaks
Обычный пользователь
Обычный пользователь
 
Сообщения: 67
Зарегистрирован: 29.07.2006 (Сб) 12:08

Re: Координаты мышки в 3д пространчтве

Сообщение Sneaks » 03.05.2023 (Ср) 19:12

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

Я понял как работает твоя магия!! :)
Еще раз спасибо, я б наверное так и бился со своими углами :)

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Координаты мышки в 3д пространчтве

Сообщение Mikle » 03.05.2023 (Ср) 19:43

Твой метод тоже мог работать, только нужно было брать арктангенс от координат мыши, чтобы получить угол.
Но так проще.

Sneaks
Обычный пользователь
Обычный пользователь
 
Сообщения: 67
Зарегистрирован: 29.07.2006 (Сб) 12:08

Re: Координаты мышки в 3д пространчтве

Сообщение Sneaks » 03.05.2023 (Ср) 19:51

я переделал уже в арктангенс. Все так же улетало. Я думаю это связанно с линейностью координат мышки, соответственно с вводимым углом. Т.е. шаг равный, а в перспективе, в зависимости от дальности от центра, идет искажение и соответственно идет разногласие. Может если вводимый шаг сделать не линейным, а с учетом искажения, то можно, но твой вариант прост и безупречен)

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Координаты мышки в 3д пространчтве

Сообщение Mikle » 03.05.2023 (Ср) 19:57

Sneaks писал(а):если вводимый шаг сделать не линейным, а с учетом искажения, то можно

Так арктангенс - это и есть этот учёт. Просто координаты нужно сначала смасштабировать как у меня сделано изменение ScaleWidth и ScaleHeight.


Вернуться в Мультимедиа

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 24

    TopList