C++ DirectX矩阵:相对于面方向的变换(如FPS中)
我接受了别人的建议,但没有达到我的目的:C++ DirectX矩阵:相对于面方向的变换(如FPS中),c++,matrix,directx,directx-11,directxtk,C++,Matrix,Directx,Directx 11,Directxtk,我接受了别人的建议,但没有达到我的目的: M=inverse(inverse(M)*rotation_matrix); 这是我的更新代码: void TestApp::Update(float dt) { DirectX::SimpleMath::Matrix rotation = Matrix::CreateFromYawPitchRoll(rot.y, rot.x, 0.0f); //Rotation Matrix DirectX::SimpleMath::
M=inverse(inverse(M)*rotation_matrix);
这是我的更新代码:
void TestApp::Update(float dt) {
DirectX::SimpleMath::Matrix rotation =
Matrix::CreateFromYawPitchRoll(rot.y, rot.x, 0.0f); //Rotation Matrix
DirectX::SimpleMath::Matrix position =
Matrix::CreateTranslation(pos); //Postion Matrix
m_view =
DirectX::XMMatrixInverse(nullptr, DirectX::XMMatrixMultiply(
DirectX::XMMatrixInverse(nullptr, position), rotation)); //This uses the advice
//m_view is the Camera/View Matrix
for (int i = 0; i < 256; ++i) {
if (GetAsyncKeyState(i)) {
if (i == 87) { // W
pos.z += dt * playerSpeed; //Move Forward
continue;
}
else if (i == 68) { //D
pos.x -= dt * playerSpeed; //Move Right
continue;
}
else if(i == 83){//S
pos.z -= dt * playerSpeed; //Move Backwards
continue;
}
else if (i == 65) { // A
pos.x += dt * playerSpeed; //Move Left
continue;
}
else if (i == VK_NUMPAD8) {
rot.x -= dt;
continue;
}
else if (i == VK_NUMPAD4) {
rot.y += dt;
}
else if (i == VK_NUMPAD5) {
rot.x += dt;
continue;
}
else if (i == VK_NUMPAD6) {
rot.y -= dt;
}
}
}
void TestApp::Update(float dt){
DirectX::SimpleMath::矩阵旋转=
矩阵::CreateFromYawPitchRoll(rot.y,rot.x,0.0f);//旋转矩阵
DirectX::SimpleMath::矩阵位置=
矩阵::CreateTransformation(pos);//位置矩阵
m_视图=
DirectX::XMMatrixInverse(nullptr,DirectX::XMMatrixMultiply(
DirectX::XMMatrixInverse(nullptr,position),rotation));//这使用通知
//m_view是摄影机/视图矩阵
对于(int i=0;i<256;++i){
if(GetAsyncKeyState(i)){
如果(i==87){//W
pos.z+=dt*playerSpeed;//向前移动
继续;
}
如果(i==68){//D
pos.x-=dt*playerSpeed;//向右移动
继续;
}
如果(i==83){//S
pos.z-=dt*playerSpeed;//向后移动
继续;
}
如果(i==65){//A
pos.x+=dt*playerSpeed;//向左移动
继续;
}
else if(i==VK_NUMPAD8){
rot.x-=dt;
继续;
}
else if(i==VK_numpa4){
rot.y+=dt;
}
else if(i==VK_NUMPAD5){
rot.x+=dt;
继续;
}
else if(i==VK_NUMPAD6){
rot.y-=dt;
}
}
}
这个动作做得很好,但旋转不确定。它绕着世界原点旋转,不像FPS相机。有什么帮助吗
我正在使用DirectX 11和DirectX工具包。模型渲染精细,向前、向后、向左、向右移动,就像FPS相机一样工作,但它是围绕世界原点(0,0)旋转的.这里是一个使用OpenGL而不是Direct X的旧游戏引擎的片段。您可能需要调整坐标系的利手性,但基本原则仍然适用。在3D环境中处理运动时,相机、玩家或世界对象体验的运动应该通过
开关来完成ode>语句,而不是一堆if-else
语句
请看一下OpenGL游戏引擎中的旋转运动片段
void Player::move( Action action, float fDeltaTime ) {
v3LookDirection = m_v3LookCenter - m_v3Position;
switch( action ) {
case MOVING_FORWARD: {
// ... code here ...
}
case MOVING_BACK: {
// ... code here ...
}
case MOVING_RIGHT: {
// ... code here ...
}
case MOVING_LEFT: {
// ... code here ...
}
case LOOKING_LEFT: {
/*float fSin = -sin( fDeltaTime * m_fAngularSpeed );
float fCos = cos( fDeltaTime * m_fAngularSpeed );
m_v3LookCenter.m_fX = m_v3Position.m_fX + (-fSin * v3LookDirection.m_fZ + fCos * v3LookDirection.m_fX );
m_v3LookCenter.m_fZ = m_v3Position.m_fZ + ( fCos * v3LookDirection.m_fZ + fSin * v3LookDirection.m_fX );
break;*/
// Third Person
float fSin = sin( fDeltaTime * m_fAngularSpeed );
float fCos = -cos( fDeltaTime * m_fAngularSpeed );
m_v3Position.m_fX = m_v3LookCenter.m_fX + (-fSin * v3LookDirection.m_fZ + fCos * v3LookDirection.m_fX );
m_v3Position.m_fZ = m_v3LookCenter.m_fZ + ( fCos * v3LookDirection.m_fZ + fSin * v3LookDirection.m_fX );
break;
}
case LOOKING_RIGHT: {
/*float fSin = sin( fDeltaTime * m_fAngularSpeed );
float fCos = cos( fDeltaTime * m_fAngularSpeed );
m_v3LookCenter.m_fX = m_v3Position.m_fX + (-fSin * v3LookDirection.m_fZ + fCos * v3LookDirection.m_fX );
m_v3LookCenter.m_fZ = m_v3Position.m_fZ + ( fCos * v3LookDirection.m_fZ + fSin * v3LookDirection.m_fX );
break;*/
// Third Person
float fSin = -sin( fDeltaTime * m_fAngularSpeed );
float fCos = -cos( fDeltaTime * m_fAngularSpeed );
m_v3Position.m_fX = m_v3LookCenter.m_fX + (-fSin * v3LookDirection.m_fZ + fCos * v3LookDirection.m_fX );
m_v3Position.m_fZ = m_v3LookCenter.m_fZ + ( fCos * v3LookDirection.m_fZ + fSin * v3LookDirection.m_fX );
break;
}
case LOOKING_UP: {
m_v3LookCenter.m_fY -= fDeltaTime * m_fAngularSpeed * m_MouseLookState;
// Check Maximum Values
if ( m_v3LookCenter.m_fY > (m_v3Position.m_fY + m_fMaxUp ) ) {
m_v3LookCenter.m_fY = m_v3Position.m_fY + m_fMaxUp;
} else if ( m_v3LookCenter.m_fY < (m_v3Position.m_fY - m_fMaxDown) ) {
m_v3LookCenter.m_fY = m_v3Position.m_fY - m_fMaxDown;
}
break;
}
} // switch
}
也在Scene::update()中
这也被绑定到与messageHandler()一起工作的GameOGL
类中
我不打算在这里展示。这是一个由近5万行代码组成的中大型项目。在这里显示每个工件太大了,所以请不要问,因为这个引擎中的所有东西都集成在一起了。我刚才也展示了用于旋转运动的基本数学如果通过按键或鼠标移动调用它
现在你必须记住这一点,因为它很重要。你看到的实际计算来自于执行旋转的Player
类,你可能无法直接使用。如果坐标系的利手性不同于此处使用的利手性,你将不得不使用适当的trig函数进行适当的旋转用正确的符号协调轴成员,以确保计算正确。当惯用手发生变化时,所暗示的旋转轴以及旋转的初始方向也会发生变化。3D数学不是很有趣吗
编辑
哦,我还注意到您正在使用DirectX的
::CreateFromYawPitchRoll()
创建旋转矩阵;这没关系,但使用标准Euler角度的旋转时需要小心。如果同时开始以多个角度旋转,则最终会遇到万向节锁。为避免在三维旋转中使用万向节锁问题,最好使用四元数
数学对他们来说有点难理解,它们是什么的概念并不难理解,但使用它们实际上相当简单,而且计算效率也非常高。许多数学库都包含它们;DirectX的数学库应该包含它们,开源GLM
数学库也应该包含它们,OpenGL&GLSL。如果你不确定万向节锁和四元数,你可以通过谷歌搜索来查找这些主题;那里有很多关于它们的信息。高级3D…嗯哼…4D数学不是很有趣吗?你说它从世界原点角度旋转,比如“如果你站在旋转木马的边缘,你看着中心”
我想你希望你的物体从它自己的中心旋转
解决方案是旋转对象,然后应用位置矩阵
这是负责任的
m_view =
DirectX::XMMatrixInverse(nullptr, DirectX::XMMatrixMultiply(
DirectX::XMMatrixInverse(nullptr, position), rotation))
我认为解决方法应该是在旋转后应用位置
在OpenGl中,您将在模型矩阵上应用旋转
glm::mat4 MVP矩阵=投影*视图*模型
可以旋转视图或模型矩阵,并获得两种不同的结果
我不知道你的代码和DirectX一般,但也许你应该颠倒2
m_view =
DirectX::XMMatrixInverse(nullptr, DirectX::XMMatrixMultiply(
DirectX::XMMatrixInverse(nullptr, rotation), position))
看一看
m_view =
DirectX::XMMatrixInverse(nullptr, DirectX::XMMatrixMultiply(
DirectX::XMMatrixInverse(nullptr, position), rotation))
m_view =
DirectX::XMMatrixInverse(nullptr, DirectX::XMMatrixMultiply(
DirectX::XMMatrixInverse(nullptr, rotation), position))