Необходимо создать камеру от 3-го лица, как это можно сделать?
Думаю нужно чтобы камера всегда была направлена на игрока, но как узнать координаты камеры?
Если не ошибаюсь то угол между камерой и игроком можно ухнать по этой формуле:
result := ArcTan2(y2 - y1, x2 - x1) * (180 / PI);
Помогите пожалуста!
Код благополучно был уведён от куда-то, не помню откуда, автор отзовись, спасибо за код.
OpenGL сначала код был под вид от первого лица, ну ту всё просто, ибо я пишу на кривом диалекте(подчти бейсик).
class CCamera
{
public:
Vector3D mPos;
Vector3D mView;
Vector3D mUp;
static float currentRotX;
static float lastRotX;
void Rotate_Position(float angle, float x, float y, float z);
void Move_Camera(float speed);
void Mouse_Move(int wndWidth, int wndHeight);
void Rotate_View(float speed);
void Position_Camera(float pos_x, float pos_y, float pos_z,
float view_x, float view_y, float view_z,
float up_x, float up_y, float up_z);
};
void CCamera::Position_Camera(float pos_x, float pos_y, float pos_z,
float view_x, float view_y, float view_z,
float up_x, float up_y, float up_z)
{
mPos = Vector3D(pos_x, pos_y, pos_z ); // set position
mView = Vector3D(view_x, view_y, view_z); // set view
mUp = Vector3D(up_x, up_y, up_z ); // set the up vector
}
void CCamera::Move_Camera(float speed)
{
Vector3D vVector = mView - mPos; // Get the view vector
// forward positive camera speed and backward negative camera speed.
mPos.x = mPos.x + vVector.x * speed;
mPos.z = mPos.z + vVector.z * speed;
mView.x = mView.x + vVector.x * speed;
mView.z = mView.z + vVector.z * speed;
}
void CCamera::Rotate_View(float speed)
{
Vector3D vVector = mView - mPos; // Get the view vector
mView.z = (float)(mPos.z + sin(speed)*vVector.x + cos(speed)*vVector.z);
mView.x = (float)(mPos.x + cos(speed)*vVector.x - sin(speed)*vVector.z);
}
void CCamera::Rotate_Position(float angle, float x, float y, float z)
{
Vector3D vVector = mPos - mView;
Vector3D AVector;
float SinA = sin(angle);
float CosA = cos(angle);
// Найдем новую позицию X для вращаемой точки
AVector.x = (CosA + (1 - CosA) * x * x)* vVector.x;
AVector.x += ((1 - CosA) * x * y - z * SinA)* vVector.y;
AVector.x += ((1 - CosA) * x * z + y * SinA)* vVector.z;
// Найдем позицию Y
AVector.y = ((1 - CosA) * x * y + z * SinA)* vVector.x;
AVector.y += (CosA + (1 - CosA) * y * y)* vVector.y;
AVector.y += ((1 - CosA) * y * z - x * SinA)* vVector.z;
// И позицию Z
AVector.z = ((1 - CosA) * x * z - y * SinA)* vVector.x;
AVector.z += ((1 - CosA) * y * z + x * SinA)* vVector.y;
AVector.z += (CosA + (1 - CosA) * z * z)* vVector.z;
mPos.x = mView.x + AVector.x;
mPos.y = mView.y + AVector.y;
mPos.z = mView.z + AVector.z;
}
void CCamera::Mouse_Move( int wndWidth, int wndHeight )
{
POINT mousePos;
int mid_x = wndWidth >> 1;
int mid_y = wndHeight >> 1;
float angle_y = 0.0f;
float angle_z = 0.0f;
currentRotX = 0.0f;
GetCursorPos(&mousePos); // Get the mouse cursor 2D x,y position
if( (mousePos.x == mid_x) && (mousePos.y == mid_y) ) return;
SetCursorPos(mid_x, mid_y); // Set the mouse cursor in the center of the window
// Get the direction from the mouse cursor, set a resonable maneuvering speed
angle_y += (float)( (mid_x - mousePos.x) ) / 1000;
angle_z += (float)( (mid_y - mousePos.y) ) / 1000;
lastRotX = 0.0f;
lastRotX = currentRotX; // Сохраняем последний угол вращения
// и используем заново currentRotX
// Если текущее вращение больше 1 градуса, обрежем его, чтобы не вращать слишком быстро
if(currentRotX > 1.0f)
{
currentRotX = 1.0f;
// врощаем на оставшийся угол
if(lastRotX != 1.0f)
{
// Чтобы найти ось, вокруг которой вращаться вверх и вниз, нужно
// найти вектор, перпендикулярный вектору взгляда камеры и
// вертикальному вектору.
// Это и будет наша ось. И прежде чем использовать эту ось,
// неплохо бы нормализовать её.
Vector3D vAxis = Cross(mView - mPos, mUp);
vAxis.Normalize();
// Вращаем камеру вокруг нашей оси на заданный угол
Rotate_Position(1.0f - lastRotX, vAxis.x, vAxis.y, vAxis.z);
}
}
// Если угол меньше -1.0f, убедимся, что вращение не продолжится
else if(currentRotX < -1.0f)
{
currentRotX = -1.0f;
if(lastRotX != -1.0f)
{
// Опять же вычисляем ось
Vector3D vAxis = Cross(mView - mPos, mUp);
vAxis.Normalize();
// Вращаем
Rotate_Position( -1.0f - lastRotX, vAxis.x, vAxis.y, vAxis.z);
}
}
// Если укладываемся в пределы 1.0f -1.0f - просто вращаем
else
{
Vector3D vAxis = Cross(mView - mPos, mUp);
vAxis.Normalize();
Rotate_Position(angle_z, vAxis.x, vAxis.y, vAxis.z);
}
// Всегда вращаем камеру вокруг Y-оси
Rotate_Position(angle_y, 0, 1, 0);
}
Спасибо!
Буду разбиратся в коде!
ну по хорошему камера сперва нужно составить список требований, к примеру было такое в моей практике:
- не должна проваливаться в стены - обладать физ. объемом
- не терять игрока из виду, трассировать видимость между объемом камеры и боксом игрока
- при определенном удалении смотреть на его bbox, при приближении к игроку смотреть на нужную часть тела
- демпфировать и игнорировать дрожание и прыжки игрока
- демпфировать скольжение объема камеры по поверхности и резкие препятствия возникающие между камерой и игроком
- в специальных случаях приближаться - удаляться(типа присел, прыгнул, залез на лестницу, и.т.д)
- поведение в катсценах
- дрожание при стрельбе от первого лица
- дрожание когда рядом чего то рушится
- и.т.д
вообщем тремя функциями не обойдешься, если делать по полной программе реальный такой навороченный класс, смотря какие у Вас задачи.
А как кстати делают, хотя нигде не видел, но наверно все же делают, чтоб при движении персонажа по лестнице камера не прыгала?
redbox, обычное сглаживание - новая позиция камеры вычисляется, но не присваивается, а делается что-то вроде
camPos *= 0.9;
camPos += (1 - 0.9)*newPos;
Внутри темы пока вопрос, вы бы хоть прокомментировали код который я дал.
PlatinumKiller
>>Внутри темы пока вопрос, вы бы хоть прокомментировали код который я дал.
Крутой код, полюбому. Пацан! :)
xDimka
+1
И вообще, мне кажется, что камера от третьего лица - дело неблагодарное.
Кстати, не забываем и про прицеливание ;)
1. Куда летит снаряд,
2. Где находится изображение снаряда (иногда модель смещают относительно положения прожектайла)
Logmh
окей, спасибо.
PlatinumKiller
Сперва надо бы разобраться с названием класса, и его назвать не CCamera, а скажем ClientView.
Под камерой все же, правильнее понимать класс в renderer, который содержит в себе матрицу вида, проекционную матрицу, данные для отсечения геометрии, и.т.д. Он бы у меня использовался и для вида от третьего лица, и для вида от первого лица, и для рендеринга отражений, мониторов наблюдения, и прочих вещей для которых перед рендерингом необходимо установить камеру.
ClientView - это взгляд некоего Client. Клиентом может быть игрок, npc, игрок через сеть, и.т.д, который владеет им, готовит для него данные и управляет им.
ClientView же из себя представляет собой некоторое количество функций для реализации п.3, как то: screen shakers, screen demphers, world collision, change 1st - 3rd view, и.т.д
Оптимальнее всего реализовать управление этим классом через lua-скрипт, а настройку отдельных настроечных величин вывести в консольные переменные.
xDimka
Спасибо, рассмотрю, но пока учиться надо.
знаю,что тема избитая,но у меня есть достаточно неплохой сорц
void CameraUpdate(ISceneNode* mesh)
{
scene::ISceneManager* sm = device->getSceneManager();
scene::ICameraSceneNode* camera = sm->getActiveCamera();
core::vector3df start = mesh->getPosition();
core::vector3df end = (camera->getTarget() - start);
end.normalize();
start -= end*100.0f;//100-это дистанция от обьекта до камеры
camera->setPosition(start);
}mesh - это меш,вокруг которого должно производится вращение
чтобы использовать его,вызывайте его вместо метода camera->setPosition тогда,когда меш должен менять позицию
пример использования скоро можно будет увидеть на irrphysx.at.ua (ближайшие 2-3 дня)
Код хороший, но у меня выдает кучу ошибок.... ну с ними я разберусь.... А как эту камеру использовать? как с ней устанавливать позицию,цель?
и что такое Vector3D - vector3df?
Traffic Magician
это
class Vector3D
{
public:
float x,y,z;
};
в моём коде.
Тема в архиве.