Files
bluflame/hgplus/obliterator/C/camera.h
2026-04-18 22:31:51 +02:00

140 lines
4.7 KiB
C++

#include <DirectXMath.h>
#include <fstream>
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<char*>(&m_cameraViewUp), sizeof(DirectX::XMFLOAT3));
outfile.write(reinterpret_cast<char*>(&m_cameraViewDirection), sizeof(DirectX::XMFLOAT3));
outfile.write(reinterpret_cast<char*>(&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<char*>(&m_cameraViewUp), sizeof(DirectX::XMFLOAT3));
infile.read(reinterpret_cast<char*>(&m_cameraViewDirection), sizeof(DirectX::XMFLOAT3));
infile.read(reinterpret_cast<char*>(&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;
};