directx-11 - Directx3D 11 构建带有旋转和平移的世界矩阵
问题描述
我想使用 wasd 来控制场景中的汽车移动。使用w
和s
前后移动,a
旋转d
移动方向和小车方向。现在我可以使用 w 和 s 成功地向前和向后移动,并使用 a 和 d 来旋转我的车。但是,如果我同时按下 w 和 a,汽车只会在它的位置旋转,不再向前移动。
有谁知道错误在哪里?
#include "Car.h"
Car::Car()
{
}
Car::~Car()
{
if (mModel) {
delete mModel;
mModel = nullptr;
}
// if (mCamera) {
// delete mCamera;
// mCamera = nullptr;
// }
}
void Car::init(std::string modelPath)
{
mModel = new Model();
mModel->load(modelPath);
// mCamera = new Camera();
// mCamera->setPosition({ mPosition.x, mPosition.y, mPosition.z });
}
void Car::setPosition(XMFLOAT3& pos)
{
mPosition = pos;
// mCamera->setPosition({ mPosition.x, mPosition.y + 5, mPosition.z });
}
void Car::setProjection(XMMATRIX& proj)
{
mProjection = proj;
}
void Car::setView(XMMATRIX& view)
{
mView = view;
}
void Car::setPSConstantBuffer(PSConstantBuffer data)
{
mPSConstantData = data;
}
void Car::rebuildRUL()
{
XMVECTOR R = XMLoadFloat3(&mRight);
XMVECTOR U = XMLoadFloat3(&mUp);
XMVECTOR L = XMLoadFloat3(&mLook);
L = XMVector3Normalize(L);
U = XMVector3Normalize(XMVector3Cross(L, R));
R = XMVector3Cross(U, L);
XMStoreFloat3(&mRight, R);
XMStoreFloat3(&mUp, U);
XMStoreFloat3(&mLook, L);
}
void Car::update(float deltaTime)
{
// mSpeed += mAcceleration * deltaTime;
// walk(mSpeed * deltaTime * 0.0001f);
// mCamera->updateView();
// if (mMove) {
rebuildRUL();
// std::cout << mPosition.x << ", " << mPosition.y << ", " << mPosition.z << std::endl;
mWorld = mRotation * XMMatrixTranslation(mPosition.x, mPosition.y + 1, mPosition.z);
// mMove = false;
// }
}
void Car::walk(float distance)
{
// std::cout << "distance: " << distance << std::endl;
XMVECTOR s = XMVectorReplicate(distance);
XMVECTOR look = XMLoadFloat3(&mLook);
XMVECTOR pos = XMLoadFloat3(&mPosition);
XMStoreFloat3(&mPosition, XMVectorMultiplyAdd(s, look, pos));
// rebuildRUL();
}
void Car::strafe(float distance)
{
// std::cout << "strafe: " << distance << std::endl;
XMVECTOR s = XMVectorReplicate(distance);
XMVECTOR right = XMLoadFloat3(&mRight);
XMVECTOR pos = XMLoadFloat3(&mPosition);
XMStoreFloat3(&mPosition, XMVectorMultiplyAdd(s, right, pos));
// rebuildRUL();
}
void Car::turn(float angle)
{
std::cout << "angle: " << angle << std::endl;
static float totalAngle = 0.0f;
totalAngle += angle;
// if (totalAngle > 3.1410f / 4.0f) {
// totalAngle = 0.0f;
// }
XMMATRIX rot = XMMatrixRotationY(totalAngle);
mRotation = rot;
XMStoreFloat3(&mRight, XMVector3TransformNormal(XMLoadFloat3(&mRight), rot));
XMStoreFloat3(&mUp, XMVector3TransformNormal(XMLoadFloat3(&mUp), rot));
XMStoreFloat3(&mLook, XMVector3TransformNormal(XMLoadFloat3(&mLook), rot));
// rebuildRUL();
// strafe(angle);
}
void Car::draw()
{
mModel->updateMVP(
XMMatrixTranspose(mWorld),
XMMatrixTranspose(mView),
XMMatrixTranspose(mProjection)
);
mModel->updatePSConstantBuffer(mPSConstantData);
mModel->render();
}
void Car::processKeyboard(const bool* key_state, float delta)
{
if (key_state[VK_SHIFT]) {
mWalkSpeed = 20.0f;
} else {
mWalkSpeed = 1.0f;
}
if (key_state[VK_UP] || key_state[0x57]) {
walk(mWalkSpeed * delta * 0.005f);
// mAcceleration = 1.0f;
} else if (key_state[VK_DOWN] || key_state[0x53]) {
// mAcceleration = -1.0f;
walk(-mWalkSpeed * delta * 0.005f);
} else {
mAcceleration = 0;
}
if (key_state[VK_LEFT] || key_state[0x41]) {
// mRotation = - 10.0f;
turn(-mWalkSpeed * delta * 0.005f);
} else if (key_state[VK_RIGHT] || key_state[0x44]) {
// mRotation = 10.0f;
turn(mWalkSpeed * delta * 0.005f);
} else {
// turn(0);
}
}
void Car::processMouse(WPARAM btnState, int x, int y)
{
}
解决方案
推荐阅读
- python - [:,:,::-1] 和 [:,:,:] 有什么区别
- python - Python 和 Pandas:使用函数替换文本
- c++ - makefile : 如何链接目标文件
- ruby - 我对此(初学者)示例代码有很多疑问
- android - android中setNotificationPolicy和setInterruptionFilter的区别
- c# - 带有输入参数的 MVC 存储过程并使用实体框架获取输出
- java - 我如何实现一个泛型类,该类在java中调用指定接口的静态方法
- perl - 在“uniq”之后的“排序”中出现“不是数字”错误
- c# - 如何确保在处理图像之前完成上传
- apache-kafka - 使用 gRPC 微服务和 Kubernetes 进行路由