Форум: "Игры";
Текущий архив: 2009.02.22;
Скачать: [xml.tar.bz2];
ВнизПроблема с камерой Найти похожие ветки
← →
ElectriC © (2007-04-18 21:20) [0]Есть проблемка с камерой: Допустим, когда начинаешь вертеть мышкой по/против часовой стрелки, камера, как и положено поворачивается вверх/вниз/влево/вправо, но при этом она ещё начинает переворачивается по/против часовой стрелки? Не подскажите, в чём проблем-ка.
P.S. Или посоветуйте что нужно улучшить.
Код движение камеры мышкой:
...
Xi, Yi : Single;
Cursor : TPoint
...
GetCursorPos(Cursor);
SetCursorPos(800 div 2, 600 div 2);
Xi := Xi + (Cursor.X - 400)/100 * 0.1;
Yi := Yi - (300 - Cursor.Y)/100 * 0.1;
RotateLR(Xi);
RotateUD(Yi);
Xi := 0; Yi := 0;
...
Код модуля камеры:
SLCamera = packed record
CameraType : (FP, FREE);//камера для первого лица/свободная камера
View, Proj : TD3DMatrix;
Xi, Yi : Single;
LR, UD,
LK, PS : TD3DXVECTOR3;
end;
var D3DDevice : IDirect3DDevice9;
procedure GetViewMatrix;
var X, Y, Z : Single;
begin
with SLCamera do
begin
D3DXVec3Normalize(LK, LK);
D3DXVec3Cross (UD, LK, LR);
D3DXVec3Normalize(UD, UD);
D3DXVec3Cross (LR, UD, LK);
D3DXVec3Normalize(LR, LR);
X := -D3DXVec3Dot(LR, PS);
Y := -D3DXVec3Dot(UD, PS);
Z := -D3DXVec3Dot(LK, PS);
with View do
begin
m[0, 0] := LR.x;
m[0, 1] := UD.x;
m[0, 2] := LK.x;
m[0, 3] := 0.0;
m[1, 0] := LR.y;
m[1, 1] := UD.y;
m[1, 2] := LK.y;
m[1, 3] := 0.0;
m[2, 0] := LR.z;
m[2, 1] := UD.z;
m[2, 2] := LK.z;
m[2, 3] := 0.0;
m[3, 0] := X;
m[3, 1] := Y;
m[3, 2] := Z;
m[3, 3] := 1.0;
end;
D3DDevice.SetTransform(D3DTS_VIEW, View);
D3DXMatrixPerspectiveFovLH(Proj, D3DX_PI / 4, 1.0, 1.0, 1000.0);
D3DDevice.SetTransform(D3DTS_PROJECTION, Proj);
end;
end;
{ движение влево/вправо }
procedure MoveLR(Step : Single);
begin
with SLCamera do
case CameraType of
FP : PS := D3DXVECTOR3(PS.x + LR.x * Step, 0.0,
PS.z + LR.z * Step);
FREE : PS := D3DXVECTOR3(PS.x + LR.x * Step, PS.y + LR.y * Step,
PS.z + LR.z * Step);
end;
GetViewMatrix;
end;
{ движение вверх/вниз }
procedure MoveUD(Step : Single);
begin
with SLCamera do
If CameraType = FREE then
begin
PS.x := PS.x + UD.x * Step;
PS.y := PS.y + UD.y * Step;
PS.z := PS.z + UD.z * Step;
end;
GetViewMatrix;
end;
{ движение вперёд/назад }
procedure MoveFB(Step : Single);
begin
with SLCamera do
case CameraType of
FP : PS := D3DXVECTOR3(PS.x + LK.x * Step, 0.0, PS.z + LK.z * Step);
FREE : begin
PS.x := PS.x + LK.x * Step;
PS.y := PS.y + LK.y * Step;
PS.z := PS.z + LK.z * Step;
end;
end;
GetViewMatrix;
end;
{ поаорот влево/вправо }
procedure RotateLR(Step : Single);
var Mat : TD3DXMatrix;
begin
with SLCamera do
begin
case CameraType of
FP : D3DXMatrixRotationY (Mat, Step);
FREE : D3DXMatrixRotationAxis(Mat, UD, Step);
end;
D3DXVec3TransformCoord(LR, LR, Mat);
D3DXVec3TransformCoord(LK, LK, Mat);
end;
GetViewMatrix;
end;
{ поворот вверх/вниз }
procedure RotateUD(Step : Single);
var Mat : TD3DXMatrix;
begin
with SLCamera do
begin
D3DXMatrixRotationAxis(Mat, LR, Step);
D3DXVec3TransformCoord( UD, UD, Mat);
D3DXVec3TransformCoord( LK, LK, Mat);
end;
GetViewMatrix;
end;
{ поворот по/против часовой стрелки }
procedure RotateUC(Step : Single);
var Mat : TD3DXMatrix;
begin
with SLEngine.SLCamera do
If CameraType = FREE then
begin
D3DXMatrixRotationAxis(Mat, LK, Step);
D3DXVec3TransformCoord( LR, LR, Mat);
D3DXVec3TransformCoord( UD, UD, Mat);
end;
GetViewMatrix;
end;
end.
← →
Sapersky (2007-04-19 14:23) [1]В примерах к DX SDK не вращается - видимо из-за того, что вращение там делается через кватернионы. В DX8 это класс D3DUtil.CD3DArcBall.
В принципе, само по себе вращение не порок, оно присутствует в некоторых коммерческих CAD, например. Даже логично - крутим мышкой вокруг объекта -> поворачиваем объект относительно перпендикулярной экрану оси.
← →
ElectriC © (2007-04-19 15:57) [2]Понятно!
Последний вопрос: Как сделать поворот камеры вокруг какого-либо объекта,
например дома, как это сделано, допустим, в Sims"ах?
P.S. Использование нмжеприведённого кода не предлагать:
RotateLR( 0.02);
MoveLR (-0.02);
если ошибаюсь, то
RotateLR(-0.02);
MoveLR ( 0.02);
← →
Sapersky (2007-04-19 19:27) [3]Обычно формируют матрицу вращения относительно 0-й точки, потом умножают её на матрицу перемещения в точку, относительно которой нужно крутить.
Правда, в моём тесте для достижения нужного результата пришлось перемещать в обратном направлении. То ли у меня что-то напутано, то ли действительно так и есть.
← →
ElectriC © (2007-04-19 19:52) [4]Можешь написать исходный текст?
← →
Sapersky (2007-04-19 21:10) [5]Я так понял, что в [0] как раз и есть вращение камеры вокруг объекта (толком не вникал), а проблема в том, чтобы сделать вращение относительно произвольной точки.
Если нет... можно заранее подготовить видовую матрицу, направленную в 0 (тем же GetViewMatrix) и потом умножать её на матрицу вращения, полученную D3DXMatrixRotationAxis.
Матрица перемещения - D3DXMatrixTranslation. Потом ещё раз D3DXMatrixMultiply, потом SetTransform(D3DTS_VIEW, ...).
← →
ElectriC © (2007-04-20 00:32) [6]Спасибо, по-экспериментируем))
← →
ElectriC © (2007-04-20 15:04) [7]Чё т не выходит! Так можешь написать исходник процедуры, которая ворочает камеру вокруг точки, плиз!
← →
ElectriC © (2007-04-20 18:17) [8]...
← →
Sapersky (2007-04-20 18:44) [9]Нет у меня конкретной процедуры, нужно выдирать куски из разных мест, а это долго.
Умножаешь матрицы в правильном порядке? Т.е. порядок передачи параметров в функцию имеет значение.
И чем всё-таки CD3DArcBall не угодил? Хотя в примерах SDK он в основном применяется к матрице модели, фактически можно применять и к видовой. Рекомендация глобального характера - см. ветку про текстуры, качай книги по ссылкам, читай.
← →
ElectriC © (2007-04-29 21:51) [10]Я понял, что надо так (хотя и не работает):
LK : TD3DXVECTOR3;
procedure Axis(Step : Single);
var Mat : TD3DXMatrix;
begin
D3DXMatrixRotationAxis(Mat, LK, Step);
D3DXMatrixTranslation (Mat, Step, 0.0, 0.0);
D3DXMatrixMultiply (Mat, Mat, Mat);
Device.SetTransform ( D3DTS_VIEW, Mat);
end;
Или нет?
← →
ElectriC © (2007-04-29 23:05) [11]Лучше, наверное, будет этот код (и он тож не работает):
procedure Axis(Step : Single);
var matTrans, matRot, matWorld : TD3DXMatrix;
begin
D3DXMatrixTranslation(matTrans, 0.0, 0.0, 10.0);
D3DXMatrixRotationYawPitchRoll(matRot,
D3DXToRadian(Step),
0.0,
0.0);
matWorld.m[0, 0] := matRot.m[0, 0] * matTrans.m[0, 0];
matWorld.m[0, 1] := matRot.m[0, 1] * matTrans.m[0, 1];
matWorld.m[0, 2] := matRot.m[0, 2] * matTrans.m[0, 2];
matWorld.m[0, 3] := matRot.m[0, 3] * matTrans.m[0, 3];
matWorld.m[1, 0] := matRot.m[1, 0] * matTrans.m[1, 0];
matWorld.m[1, 1] := matRot.m[1, 1] * matTrans.m[1, 1];
matWorld.m[1, 2] := matRot.m[1, 2] * matTrans.m[1, 2];
matWorld.m[1, 3] := matRot.m[1, 3] * matTrans.m[1, 3];
matWorld.m[2, 0] := matRot.m[2, 0] * matTrans.m[2, 0];
matWorld.m[2, 1] := matRot.m[2, 1] * matTrans.m[2, 1];
matWorld.m[2, 2] := matRot.m[2, 2] * matTrans.m[2, 2];
matWorld.m[2, 3] := matRot.m[2, 3] * matTrans.m[2, 3];
matWorld.m[3, 0] := matRot.m[3, 0] * matTrans.m[3, 0];
matWorld.m[3, 1] := matRot.m[3, 1] * matTrans.m[3, 1];
matWorld.m[3, 2] := matRot.m[3, 2] * matTrans.m[3, 2];
matWorld.m[3, 3] := matRot.m[3, 3] * matTrans.m[3, 3];
Device.SetTransform(D3DTS_WORLD, matWorld);
end;
end;
Пробовал изменять Device.SetTransform(D3DTS_WORLD, matWorld) на
Device.SetTransform(D3DTS_VIEW, matWorld) => Объекты вообще исчезают(((
← →
ElectriC © (2007-04-30 11:29) [12]А, всё!!! Въехал наконец-то)))
Страницы: 1 вся ветка
Форум: "Игры";
Текущий архив: 2009.02.22;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.005 c