pushing camera eigen update, and other fixes

This commit is contained in:
Yggdrasil75
2026-01-27 16:11:09 -05:00
parent e0764318b4
commit c0d15a0b9f
3 changed files with 160 additions and 71 deletions

View File

@@ -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;
}
};

View File

@@ -4,12 +4,14 @@
#include "../../eigen/Eigen/Dense"
#include "../timing_decorator.hpp"
#include "../output/frame.hpp"
#include "camera.hpp"
#include <vector>
#include <array>
#include <memory>
#include <algorithm>
#include <limits>
#include <cmath>
#include <functional>
#ifdef SSE
#include <immintrin.h>
@@ -35,8 +37,8 @@ public:
float refraction;
float reflection;
NodeData(const T& data, const PointType& pos, Eigen::Vector3f color, float size = 0.01f, bool active = true) :
data(data), position(pos), active(active), color(color), size(size) {}
NodeData(const T& data, const PointType& pos, bool visible, Eigen::Vector3f color, float size = 0.01f, bool active = true) :
data(data), position(pos), active(active), visible(visible), color(color), size(size) {}
};
struct OctreeNode {
@@ -120,7 +122,7 @@ private:
if (node->isLeaf) {
node->points.emplace_back(pointData);
if (node->points.size() > maxPointsPerNode && depth < maxDepth) {
splitNode(node,depth);
splitNode(node, depth);
}
return true;
} else {
@@ -254,8 +256,8 @@ public:
root_(std::make_unique<OctreeNode>(minBound, maxBound)), maxPointsPerNode(maxPointsPerNode),
maxDepth(maxDepth), size(0) {}
bool set(const T& data, const PointType& pos, Eigen::Vector3f color, float size, bool active) {
auto pointData = std::make_shared<NodeData>(data, pos, color, size, active);
bool set(const T& data, const PointType& pos, bool visible, Eigen::Vector3f color, float size, bool active) {
auto pointData = std::make_shared<NodeData>(data, pos, visible, color, size, active);
if (insertRecursive(root_.get(), pointData, 0)) {
size++;
return true;
@@ -324,9 +326,12 @@ public:
}
return hits;
}
frame renderFrame(const PointType& origin, PointType& dir, PointType& up, PointType& right, int height,
int width, frame::colormap colorformat = frame::colormap::RGB) {
frame renderFrame(const Camera& cam, int height, int width, frame::colormap colorformat = frame::colormap::RGB) {
PointType origin = cam.origin;
PointType dir = cam.direction.normalized();
PointType up = cam.up.normalized();
PointType right = cam.right();
frame outFrame(width, height, colorformat);
std::vector<uint8_t> colorBuffer;
@@ -340,12 +345,11 @@ public:
}
colorBuffer.resize(width * height * channels);
PointType viewDir = dir.normalized();
PointType upn = up.normalized();
PointType rightn = right.normalized();
float aspect = static_cast<float>(width) / height;
float tanfovy = 1.f;
float tanfovx = tanfovy * aspect;
float fovRad = cam.fovRad();
float tanHalfFov = tan(fovRad * 0.5f);
float tanfovy = tanHalfFov;
float tanfovx = tanHalfFov * aspect;
const Eigen::Vector3f defaultColor(0.1f, 0.2f, 0.4f);
@@ -355,7 +359,7 @@ public:
float px = (2.0f * (x + 0.5f) / width - 1.0f) * tanfovx;
float py = (1.0f - 2.0f * (y + 0.5f) / height) * tanfovy;
PointType rayDir = viewDir + (rightn * px) + (upn * py);
PointType rayDir = dir + (right * px) + (up * py);
rayDir.normalize();
std::vector<std::shared_ptr<NodeData>> hits = voxelTraverse(