我正在尝试广告牌,但是当我使用"newWorld"时,广告牌没有显示,我已经测试了它是否是我绘制广告牌的方式,但它不是,因为当我更改为它自己的本地世界时,它出现在屏幕上。
// Calculate the rotation that needs to be applied to the billboard model to face the current camera position using the arc tangent function.
XMFLOAT3 CarPos = XMFLOAT3(Billboards->GetPosition().x, Billboards->GetPosition().y, Billboards->GetPosition().z);
XMFLOAT3 CamPos = XMFLOAT3(fCam->GetEye().x, fCam->GetEye().y, fCam->GetEye().z);
float angle;
float BBrotation;
XMMATRIX newWorld = XMLoadFloat4x4(&Billboards->GetWorld());
angle = atan2(CarPos.x - CamPos.x, CarPos.z - CamPos.z) * (180 / XM_PI);
BBrotation = angle * 0.0174532925f;
XMMatrixRotationY(BBrotation);
XMMatrixTranslation(CarPos.x, CarPos.y, CarPos.z);
XMMATRIX bbRotMatix = XMMatrixRotationY(BBrotation);
XMMATRIX bbCarPos = XMMatrixTranslation(CarPos.x, CarPos.y, CarPos.z);
newWorld = bbCarPos + bbRotMatix;
XMMATRIX bilworld = XMLoadFloat4x4(&Billboards->GetWorld());
cb.World = XMMatrixTranspose(newWorld);
_pImmediateContext->UpdateSubresource(_pConstantBuffer, 0, nullptr, &cb, 0, 0);
Billboards->Draw(_pd3dDevice, _pImmediateContext, _pTreeRV, _pSpecRV);
Billboards->SetTranslation(30.0f, 0.0f, 0.0f);
Billboards->SetRotation(-90.0f, 0.0f, 0.0);
Directx Tool Kit 中的 SimpleMath DirectXMath 包装器具有右手广告牌函数,您可能会发现作为参考很有用。
inline Matrix Matrix::CreateBillboard( const Vector3& object, const Vector3& cameraPosition, const Vector3& cameraUp, const Vector3* cameraForward )
{
using namespace DirectX;
XMVECTOR O = XMLoadFloat3( &object );
XMVECTOR C = XMLoadFloat3( &cameraPosition );
XMVECTOR Z = XMVectorSubtract( O, C );
XMVECTOR N = XMVector3LengthSq( Z );
if ( XMVector3Less( N, g_XMEpsilon ) )
{
if ( cameraForward )
{
XMVECTOR F = XMLoadFloat3( cameraForward );
Z = XMVectorNegate( F );
}
else
Z = g_XMNegIdentityR2;
}
else
{
Z = XMVector3Normalize( Z );
}
XMVECTOR up = XMLoadFloat3( &cameraUp );
XMVECTOR X = XMVector3Cross( up, Z );
X = XMVector3Normalize( X );
XMVECTOR Y = XMVector3Cross( Z, X );
XMMATRIX M;
M.r[0] = X;
M.r[1] = Y;
M.r[2] = Z;
M.r[3] = XMVectorSetW( O, 1.f );
Matrix R;
XMStoreFloat4x4( &R, M );
return R;
}
inline Matrix Matrix::CreateConstrainedBillboard( const Vector3& object, const Vector3& cameraPosition, const Vector3& rotateAxis,
const Vector3* cameraForward, const Vector3* objectForward )
{
using namespace DirectX;
static const XMVECTORF32 s_minAngle = { 0.99825467075f, 0.99825467075f, 0.99825467075f, 0.99825467075f }; // 1.0 - XMConvertToRadians( 0.1f );
XMVECTOR O = XMLoadFloat3( &object );
XMVECTOR C = XMLoadFloat3( &cameraPosition );
XMVECTOR faceDir = XMVectorSubtract( O, C );
XMVECTOR N = XMVector3LengthSq( faceDir );
if (XMVector3Less(N, g_XMEpsilon))
{
if (cameraForward)
{
XMVECTOR F = XMLoadFloat3( cameraForward );
faceDir = XMVectorNegate( F );
}
else
faceDir = g_XMNegIdentityR2;
}
else
{
faceDir = XMVector3Normalize( faceDir );
}
XMVECTOR Y = XMLoadFloat3( &rotateAxis );
XMVECTOR X, Z;
XMVECTOR dot = XMVectorAbs( XMVector3Dot( Y, faceDir ) );
if ( XMVector3Greater( dot, s_minAngle ) )
{
if ( objectForward )
{
Z = XMLoadFloat3( objectForward );
dot = XMVectorAbs( XMVector3Dot( Y, Z ) );
if ( XMVector3Greater( dot, s_minAngle ) )
{
dot = XMVectorAbs( XMVector3Dot( Y, g_XMNegIdentityR2 ) );
Z = ( XMVector3Greater( dot, s_minAngle ) ) ? g_XMIdentityR0 : g_XMNegIdentityR2;
}
}
else
{
dot = XMVectorAbs( XMVector3Dot( Y, g_XMNegIdentityR2 ) );
Z = ( XMVector3Greater( dot, s_minAngle ) ) ? g_XMIdentityR0 : g_XMNegIdentityR2;
}
X = XMVector3Cross( Y, Z );
X = XMVector3Normalize( X );
Z = XMVector3Cross( X, Y );
Z = XMVector3Normalize( Z );
}
else
{
X = XMVector3Cross( Y, faceDir );
X = XMVector3Normalize( X );
Z = XMVector3Cross( X, Y );
Z = XMVector3Normalize( Z );
}
XMMATRIX M;
M.r[0] = X;
M.r[1] = Y;
M.r[2] = Z;
M.r[3] = XMVectorSetW( O, 1.f );
Matrix R;
XMStoreFloat4x4( &R, M );
return R;
}