Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.144.212.145] |
|
Сообщ.
#1
,
|
|
|
Всем привет, нужна помощь.
Хочу реализовать в своей 3д игрушке вид от первого лица. Уже реализовал свободное перемещение камеры в 3д мире, допустим в космосе. Создал пробную 3д модель игрока (человечка) в Blender. Загружаю его в свою программу и располагаю чуть позади камеры LookAt, так чтобы камеры смотрела от лица человечка вперед. Все координаты камеры мне известны: cam.position.set ((float)x1, (float)y1, (float)z1); // Точка откуда смотрит камера cam.lookAt ((float)x2, (float)y2, (float)z2); // Точка куда смотрит камера cam.up.set((float)rx, (float)ry, (float)rz); // up вектор cam.update(); Камера в игре свободно перемещается и вращается вокруг осей. Координаты 3д модели допустим, камера смотрит из лица вперед: insPlayer.transform.setToTranslation((float)x1, (float)y1-4, (float)z1); Модель игрока располагается чуть позади камеры и должна перемещаться, летает в космосе вместе с ней. Вопрос в том, как сделать свободное вращение этой модели так же вокруг своих осей, зная указанные исходные данные. Т.е. например я поворачиваю камеру вверх на 60 градусов и соответственно 3д модель также должна повернуться вверх. Также должно быть и вращение вокруг оси куда смотрит камера и другие вращения. Поиск в интернете дал единственный вариант: использовать кватернионы. Т.е. как используя кватернионы, повернуть 3д модель так чтобы она лицевой стороной смотрела туда куда смотрит камера LookAt. Вот такой код у меня не работает правильно: insPlayer.transform.setToTranslation((float)x1, (float)y1-4, (float)z1+20); // Размещаем модель чуть позади камеры LookAt Vector3 pl_z = new Vector3 ((float)x2, (float)y2, (float)z2).nor(); // Нормализованный вектор куда смотрит камера Vector3 pl_y = new Vector3 ((float)rx, (float)ry, (float)rz).nor(); // Нормализованный up вектор камеры Vector3 pl_x = pl_z.crs(pl_y).nor(); // Нормализованный кросс продукт (вектор перпендикулярный двум предыдущим) Quaternion qy = new Quaternion(pl_y, y_ang); // Создаем кватернион вращения вокруг вертикальной оси, y_ang - угол вращения вокруг вектора pl_y Quaternion qz = new Quaternion(pl_z, z_ang); // Создаем кватернион вращения вокруг оси направления взгляда камеры, z_ang - угол вращения вокруг вектора pl_z Quaternion qx = new Quaternion(pl_x, x_ang); // Создаем кватернион вращения вокруг кросс продукта qy = qy.mul(qz); // Перемножаем кватернионы qy = qy.mul(qx); insPlayer.transform.translate (0, 4, 0); insPlayer.transform.rotate(qy); // Поворачиваем модель по кватерниону insPlayer.transform.translate (0, -4, 0); modelBatch.render(insPlayer); // Рисуем модель Может кто чем помочь? Какие есть мысли? Спасибо. |
Сообщ.
#2
,
|
|
|
Цитата egvos1 @ Модель игрока располагается чуть позади камеры и должна перемещаться, летает в космосе вместе с ней. Зачем нужна эта модель, если она всё равно позади камеры, её не видно? Цитата egvos1 @ Т.е. как используя кватернионы, повернуть 3д модель так чтобы она лицевой стороной смотрела туда куда смотрит камера LookAt. Кватернионы, может быть, был бы смысл использовать, если бы писать с нуля, но, если уже есть камера и её матрица, вычисленная с помощью LookAt, то достаточно просто взять матрицу, обратную этой, и применить её к модели, плюс сдвинуть её на сколько надо вдоль оси Z. |
Сообщ.
#3
,
|
|
|
Сорри, я только начинаю разбираться с OpenGL и 3д.
Как я могу получить матрицу LookAt? Как применить ее к модели? |
Сообщ.
#4
,
|
|
|
Я ни Джаву, ни LibGDX не знаю, там у камеры нет методов, типа GetMatrix?
Вообще, эта матрица и вручную не сложно вычисляется: Sub MatrixLookAtLH(MOut As D3DMATRIX, vEye As D3DVECTOR, vAt As D3DVECTOR, vUp As D3DVECTOR) Dim xAxis As D3DVECTOR, yAxis As D3DVECTOR, zAxis As D3DVECTOR, v As D3DVECTOR Vec3Subtract v, vAt, vEye Vec3Normalize zAxis, v Vec3Cross v, vUp, zAxis Vec3Normalize xAxis, v Vec3Cross yAxis, zAxis, xAxis MOut.m11 = xAxis.x MOut.m12 = yAxis.x MOut.m13 = zAxis.x MOut.m14 = 0 MOut.m21 = xAxis.y MOut.m22 = yAxis.y MOut.m23 = zAxis.y MOut.m24 = 0 MOut.m31 = xAxis.z MOut.m32 = yAxis.z MOut.m33 = zAxis.z MOut.m34 = 0 MOut.m41 = -Vec3Dot(xAxis, vEye) MOut.m42 = -Vec3Dot(yAxis, vEye) MOut.m43 = -Vec3Dot(zAxis, vEye) MOut.m44 = 1 End Sub Это бейсик, но, думаю, понятно. |
Сообщ.
#5
,
|
|
|
Цитата Зачем нужна эта модель, если она всё равно позади камеры, её не видно? Видно руки 3д человечка, выставленные вперед, в них будет оружие которое тоже будет видно снизу сбоку. Стандартный вид от первого лица как в любом зд шутере Цитата то достаточно просто взять матрицу, обратную этой, и применить её к модели А почему для поворота модели нужно брать обратную матрицу? |
Сообщ.
#6
,
|
|
|
Цитата egvos1 @ А почему для поворота модели нужно брать обратную матрицу? Потому, что трансформации камеры или мира - ровно противоположные вещи. Если модель движется вдоль вектора V, то это то же самое, что камера движется по направлению -V, то же самое работает и на вращения и прочие преобразования. Приведённая мной матрица заставляет камеру занимать указанную позицию, значит противоположная матрица будет заставлять занимать такую же позицию модель. |