pushing camera eigen update, and other fixes
This commit is contained in:
@@ -1,60 +1,106 @@
|
||||
#ifndef camera_hpp
|
||||
#define camera_hpp
|
||||
|
||||
#include <unordered_map>
|
||||
#include <fstream>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <array>
|
||||
#include "../vectorlogic/vec2.hpp"
|
||||
#include "../vectorlogic/vec3.hpp"
|
||||
#include "../vectorlogic/vec4.hpp"
|
||||
#include "../timing_decorator.hpp"
|
||||
#include "../output/frame.hpp"
|
||||
#include "../noise/pnoise2.hpp"
|
||||
#include "../vecmat/mat4.hpp"
|
||||
#include "../vecmat/mat3.hpp"
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include "../../eigen/Eigen/Dense"
|
||||
#include <cmath>
|
||||
#include "../basicdefines.hpp"
|
||||
#include <cfloat>
|
||||
|
||||
using Eigen::Vector3f;
|
||||
using Eigen::Matrix3f;
|
||||
|
||||
struct Camera {
|
||||
Ray3f posfor;
|
||||
Vec3f up;
|
||||
Vector3f origin;
|
||||
Vector3f direction;
|
||||
Vector3f up;
|
||||
float fov;
|
||||
Camera(Vec3f pos, Vec3f viewdir, Vec3f up, float fov = 80) : posfor(Ray3f(pos, viewdir)), up(up), fov(fov) {}
|
||||
|
||||
Camera(const Vector3f& pos, const Vector3f& viewdir, const Vector3f& up, float fov = 80)
|
||||
: origin(pos), direction(viewdir), up(up.normalized()), fov(fov) {}
|
||||
|
||||
void rotateYaw(float angle) {
|
||||
float cosA = cos(angle);
|
||||
float sinA = sin(angle);
|
||||
|
||||
Vec3f right = posfor.direction.cross(up).normalized();
|
||||
posfor.direction = posfor.direction * cosA + right * sinA;
|
||||
posfor.direction = posfor.direction.normalized();
|
||||
Vector3f right = direction.cross(up).normalized();
|
||||
|
||||
// Rotate around up vector (yaw)
|
||||
Matrix3f rotation;
|
||||
rotation = Eigen::AngleAxisf(angle, up);
|
||||
direction = rotation * direction;
|
||||
}
|
||||
|
||||
void rotatePitch(float angle) {
|
||||
float cosA = cos(angle);
|
||||
float sinA = sin(angle);
|
||||
// Clamp pitch to avoid gimbal lock
|
||||
Vector3f right = direction.cross(up).normalized();
|
||||
|
||||
Vec3f right = posfor.direction.cross(up).normalized();
|
||||
posfor.direction = posfor.direction * cosA + up * sinA;
|
||||
posfor.direction = posfor.direction.normalized();
|
||||
// Rotate around right vector (pitch)
|
||||
Matrix3f rotation;
|
||||
rotation = Eigen::AngleAxisf(angle, right);
|
||||
direction = rotation * direction;
|
||||
direction.normalize();
|
||||
|
||||
up = right.cross(posfor.direction).normalized();
|
||||
// Recalculate up vector to maintain orthogonality
|
||||
up = right.cross(direction).normalized();
|
||||
}
|
||||
|
||||
Vec3f forward() const {
|
||||
return (posfor.direction - posfor.origin).normalized();
|
||||
Vector3f forward() const {
|
||||
return direction.normalized();
|
||||
}
|
||||
|
||||
Vec3f right() const {
|
||||
Vector3f right() const {
|
||||
return forward().cross(up).normalized();
|
||||
}
|
||||
|
||||
float fovRad() const {
|
||||
return fov * (M_PI / 180);
|
||||
return fov * (M_PI / 180.0f);
|
||||
}
|
||||
|
||||
// Additional useful methods
|
||||
void moveForward(float distance) {
|
||||
origin += forward() * distance;
|
||||
}
|
||||
|
||||
void moveRight(float distance) {
|
||||
origin += right() * distance;
|
||||
}
|
||||
|
||||
void moveUp(float distance) {
|
||||
origin += up * distance;
|
||||
}
|
||||
|
||||
// Get view matrix (lookAt matrix)
|
||||
Eigen::Matrix4f getViewMatrix() const {
|
||||
Vector3f f = forward();
|
||||
Vector3f r = right();
|
||||
Vector3f u = up;
|
||||
|
||||
Eigen::Matrix4f view = Eigen::Matrix4f::Identity();
|
||||
|
||||
view(0, 0) = r.x(); view(0, 1) = r.y(); view(0, 2) = r.z();
|
||||
view(1, 0) = u.x(); view(1, 1) = u.y(); view(1, 2) = u.z();
|
||||
view(2, 0) = -f.x(); view(2, 1) = -f.y(); view(2, 2) = -f.z();
|
||||
|
||||
view(0, 3) = -r.dot(origin);
|
||||
view(1, 3) = -u.dot(origin);
|
||||
view(2, 3) = f.dot(origin);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
// Get projection matrix (perspective)
|
||||
Eigen::Matrix4f getProjectionMatrix(float aspectRatio, float nearPlane = 0.1f, float farPlane = 100.0f) const {
|
||||
float fovrad = fovRad();
|
||||
float tanHalfFov = tan(fovrad / 2.0f);
|
||||
|
||||
Eigen::Matrix4f projection = Eigen::Matrix4f::Zero();
|
||||
|
||||
projection(0, 0) = 1.0f / (aspectRatio * tanHalfFov);
|
||||
projection(1, 1) = 1.0f / tanHalfFov;
|
||||
projection(2, 2) = -(farPlane + nearPlane) / (farPlane - nearPlane);
|
||||
projection(3, 2) = -1.0f;
|
||||
projection(2, 3) = -(2.0f * farPlane * nearPlane) / (farPlane - nearPlane);
|
||||
|
||||
return projection;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user