#include #include class Camera { public: Camera() { reset(); } ~Camera() { } void reset() { m_cameraViewUp = DirectX::XMFLOAT3(0.0f, 1.0f, 0.0f); m_cameraViewDirection = DirectX::XMFLOAT3(0.0f, 0.0f, -1.0f); m_cameraViewPosition = DirectX::XMFLOAT3(0.0f, 0.0f, 3.0f); } void translate(float us, float vs, float ws) { // RHS coordinate system U, V, W DirectX::XMVECTOR w = DirectX::XMVectorScale(DirectX::XMLoadFloat3(&m_cameraViewDirection), -1.0f); DirectX::XMVECTOR v = DirectX::XMLoadFloat3(&m_cameraViewUp); DirectX::XMVECTOR u = DirectX::XMVector3Normalize(DirectX::XMVector3Cross(v, w)); DirectX::XMVECTOR p = XMLoadFloat3(&m_cameraViewPosition); DirectX::XMVECTOR wScaled = DirectX::XMVectorScale(u, us); DirectX::XMVECTOR vScaled = DirectX::XMVectorScale(v, vs); DirectX::XMVECTOR uScaled = DirectX::XMVectorScale(w, ws); DirectX::XMStoreFloat3(&m_cameraViewPosition, DirectX::XMVectorAdd(p, DirectX::XMVectorAdd(uScaled, DirectX::XMVectorAdd(vScaled, wScaled)))); } void rotateAroundU(float theta) { // RHS coordinate system U, V, W DirectX::XMVECTOR w = DirectX::XMVectorScale(DirectX::XMLoadFloat3(&m_cameraViewDirection), -1.0f); DirectX::XMVECTOR v = DirectX::XMLoadFloat3(&m_cameraViewUp); DirectX::XMVECTOR u = DirectX::XMVector3Normalize(DirectX::XMVector3Cross(v, w)); float cosTheta = std::cos(theta); float sinTheta = std::sin(theta); // Rodriguez rotation of W around U DirectX::XMVECTOR wNew = DirectX::XMVectorAdd( DirectX::XMVectorScale(w, cosTheta), DirectX::XMVectorScale(DirectX::XMVector3Normalize(DirectX::XMVector3Cross(u, w)), sinTheta)); // Rodriguez rotation of V around U DirectX::XMVECTOR vNew = DirectX::XMVectorAdd( DirectX::XMVectorScale(v, cosTheta), DirectX::XMVectorScale(DirectX::XMVector3Normalize(DirectX::XMVector3Cross(u, v)), sinTheta)); // Compute and store new view direction (-W) DirectX::XMStoreFloat3(&m_cameraViewDirection, DirectX::XMVectorScale(wNew, -1.0f)); // Store new up vector DirectX::XMStoreFloat3(&m_cameraViewUp, vNew); } void rotateAroundV(float theta) { // RHS coordinate system U, V, W DirectX::XMVECTOR w = DirectX::XMVectorScale(DirectX::XMLoadFloat3(&m_cameraViewDirection), -1.0f); DirectX::XMVECTOR v = DirectX::XMLoadFloat3(&m_cameraViewUp); DirectX::XMVECTOR u = DirectX::XMVector3Normalize(DirectX::XMVector3Cross(v, w)); float cosTheta = std::cos(theta); float sinTheta = std::sin(theta); // Rodriguez rotation of W around V DirectX::XMVECTOR wNew = DirectX::XMVectorAdd( DirectX::XMVectorScale(w, cosTheta), DirectX::XMVectorScale(DirectX::XMVector3Normalize(DirectX::XMVector3Cross(v, w)), sinTheta)); // Compute and store new view direction (-W) DirectX::XMStoreFloat3(&m_cameraViewDirection, DirectX::XMVectorScale(wNew, -1.0f)); } void rotateAroundW(float theta) { // RHS coordinate system U, V, W DirectX::XMVECTOR w = DirectX::XMVectorScale(DirectX::XMLoadFloat3(&m_cameraViewDirection), -1.0f); DirectX::XMVECTOR v = DirectX::XMLoadFloat3(&m_cameraViewUp); DirectX::XMVECTOR u = DirectX::XMVector3Normalize(DirectX::XMVector3Cross(v, w)); float cosTheta = std::cos(theta); float sinTheta = std::sin(theta); // Rodriguez rotation of V around W DirectX::XMVECTOR vNew = DirectX::XMVectorAdd( DirectX::XMVectorScale(v, cosTheta), DirectX::XMVectorScale(DirectX::XMVector3Normalize(DirectX::XMVector3Cross(w, v)), sinTheta)); // Store new up vector DirectX::XMStoreFloat3(&m_cameraViewUp, vNew); } const DirectX::XMFLOAT3& getViewUp() { return m_cameraViewUp; } const DirectX::XMFLOAT3& getViewPosition() { return m_cameraViewPosition; } const DirectX::XMFLOAT3& getViewDirection() { return m_cameraViewDirection; } void storeCamera(std::string cameraFilename) { std::ofstream outfile(cameraFilename.c_str(), std::ios::out | std::ios::binary); outfile.write(reinterpret_cast(&m_cameraViewUp), sizeof(DirectX::XMFLOAT3)); outfile.write(reinterpret_cast(&m_cameraViewDirection), sizeof(DirectX::XMFLOAT3)); outfile.write(reinterpret_cast(&m_cameraViewPosition), sizeof(DirectX::XMFLOAT3)); outfile.close(); } void loadCamera(std::string cameraFilename) { std::ifstream infile(cameraFilename.c_str(), std::ios::out | std::ios::binary); infile.read(reinterpret_cast(&m_cameraViewUp), sizeof(DirectX::XMFLOAT3)); infile.read(reinterpret_cast(&m_cameraViewDirection), sizeof(DirectX::XMFLOAT3)); infile.read(reinterpret_cast(&m_cameraViewPosition), sizeof(DirectX::XMFLOAT3)); infile.close(); } protected: DirectX::XMFLOAT3 m_cameraViewUp; // Y DirectX::XMFLOAT3 m_cameraViewDirection; // -Z DirectX::XMFLOAT3 m_cameraViewPosition; // P float m_fovY; };