pushing this home.

This commit is contained in:
Yggdrasil75
2025-12-29 14:57:29 -05:00
parent 1a4ad39642
commit bc55db2c74
4 changed files with 180 additions and 40 deletions

125
h.cpp
View File

@@ -1,29 +1,114 @@
#include "util/grid/gridtest.hpp"
#include <random>
#include <memory>
#include "util/output/bmpwriter.hpp"
int main() {
VoxelRenderer renderer;
// Function to create a randomized voxel grid
std::unique_ptr<VoxelGrid> createRandomizedGrid(int width, int height, int depth, float density = 0.2f) {
auto grid = std::make_unique<VoxelGrid>(width, height, depth);
// Simple test
// std::cout << "Voxel Grid: " << renderer.getGrid().getWidth() << "x"
// << renderer.getGrid().getHeight() << "x"
// << renderer.getGrid().getDepth() << std::endl;
// Set up random number generation
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<float> dist(0.0f, 1.0f);
std::uniform_real_distribution<float> colorDist(0.2f, 1.0f);
// Test ray from center
Vec3f rayOrigin(5, 5, -5);
Vec3f rayDir(0, 0, 1);
Vec3f hitPos, hitNormal, hitColor;
if (renderer.getGrid().rayCast(rayOrigin, rayDir, 20.0f, hitPos, hitNormal, hitColor)) {
std::cout << "Test ray hit at: " << hitPos.x << ", "
<< hitPos.y << ", " << hitPos.z << std::endl;
std::cout << "Hit color: " << hitColor.r << ", "
<< hitColor.g << ", " << hitColor.b << std::endl;
} else {
std::cout << "Test ray missed" << std::endl;
// Fill grid with random active voxels
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
for (int z = 0; z < depth; z++) {
if (dist(gen) < density) {
// Random color
Vec3f color(colorDist(gen), colorDist(gen), colorDist(gen));
grid->set(x, y, z, true, color);
}
}
}
}
// Render a simple 100x100 "image"
renderer.render(100, 100);
return grid;
}
// Create a simple structure to hold camera position and orientation
struct CameraPose {
Vec3f position;
Vec3f target;
Vec3f up;
};
int main() {
// Create a randomized voxel grid (15x15x15 with 20% density)
const int gridSize = 128;
auto grid = createRandomizedGrid(gridSize, gridSize, gridSize, 0.2f);
// Create a renderer with our custom grid
VoxelRenderer renderer;
renderer.getGrid() = *grid; // Replace the default test pattern
// Define 6 camera positions (looking at the center from each axis direction)
std::vector<CameraPose> cameraPoses = {
// Front (looking along negative Z)
{Vec3f(0, 0, -gridSize * 2), Vec3f(0, 0, 0), Vec3f(0, 1, 0)},
// Back (looking along positive Z)
{Vec3f(0, 0, gridSize * 2), Vec3f(0, 0, 0), Vec3f(0, 1, 0)},
// Right (looking along positive X)
{Vec3f(gridSize * 2, 0, 0), Vec3f(0, 0, 0), Vec3f(0, 1, 0)},
// Left (looking along negative X)
{Vec3f(-gridSize * 2, 0, 0), Vec3f(0, 0, 0), Vec3f(0, 1, 0)},
// Top (looking along negative Y)
{Vec3f(0, gridSize * 2, 0), Vec3f(0, 0, 0), Vec3f(0, 0, -1)},
// Bottom (looking along positive Y)
{Vec3f(0, -gridSize * 2, 0), Vec3f(0, 0, 0), Vec3f(0, 0, 1)}
};
// Render settings
const int screenWidth = 400;
const int screenHeight = 400;
// Vector to store all frames
std::vector<frame> frames;
std::cout << "Rendering voxel grid from 6 directions..." << std::endl;
// Render from each camera position
for (size_t i = 0; i < cameraPoses.size(); i++) {
auto& pose = cameraPoses[i];
// Update camera position
renderer.getCamera().position = pose.position;
// Calculate forward direction (from position to target)
Vec3f forward = (pose.target - pose.position).normalized();
// Set camera orientation
renderer.getCamera().forward = forward;
renderer.getCamera().up = pose.up;
std::cout << "Rendering view " << (i+1) << "/6 from position ("
<< pose.position.x << ", " << pose.position.y << ", " << pose.position.z << ")" << std::endl;
// Render and add to frames vector
frames.push_back(renderer.renderToFrame(screenWidth, screenHeight));
}
// Print frame information
std::cout << "\nRendering complete!" << std::endl;
std::cout << "Number of frames created: " << frames.size() << std::endl;
for (size_t i = 0; i < frames.size(); i++) {
std::cout << "Frame " << (i+1) << ": " << frames[i] << std::endl;
}
// Optional: Save frames to files if your frame class supports it
for (size_t i = 0; i < frames.size(); i++) {
std::string filename = "output/voxel_view_" + std::to_string(i+1) + ".bmp";
BMPWriter::saveBMP(filename, frames[i]);
}
return 0;
}

View File

@@ -5,7 +5,7 @@
#include <vector>
#include <iostream>
#include <algorithm>
#include <corecrt_math_defines.h>
#include "../output/frame.hpp"
struct Voxel {
bool active;
@@ -14,10 +14,10 @@ struct Voxel {
class VoxelGrid {
private:
int width, height, depth;
std::vector<Voxel> voxels;
public:
int width, height, depth;
std::vector<Voxel> voxels;
VoxelGrid(int w, int h, int d) : width(w), height(h), depth(d) {
voxels.resize(w * h * d);
// Initialize all voxels as inactive
@@ -70,7 +70,7 @@ public:
Vec3f& hitPos, Vec3f& hitNormal, Vec3f& hitColor) const {
// Initialize step directions
Vec3i step;
Vec3f step;
Vec3f tMax, tDelta;
// Current voxel coordinates
@@ -203,15 +203,20 @@ public:
// Simple renderer using ray casting
class VoxelRenderer {
private:
VoxelGrid grid;
Camera camera;
public:
VoxelGrid grid;
Camera camera;
VoxelRenderer() : grid(20, 20, 20) {
grid.createTestPattern();
}
void render(int screenWidth, int screenHeight) {
// Render to a frame object
frame renderToFrame(int screenWidth, int screenHeight) {
// Create a frame with RGBA format for color + potential transparency
frame renderedFrame(screenWidth, screenHeight, frame::colormap::RGBA);
float aspectRatio = float(screenWidth) / float(screenHeight);
// Get matrices
@@ -219,6 +224,15 @@ public:
Mat4f view = camera.getViewMatrix();
Mat4f invViewProj = (projection * view).inverse();
// Get reference to frame data for direct pixel writing
std::vector<uint8_t>& frameData = const_cast<std::vector<uint8_t>&>(renderedFrame.getData());
// Background color (dark gray)
Vec3f backgroundColor(0.1f, 0.1f, 0.1f);
// Simple light direction
Vec3f lightDir = Vec3f(1, 1, -1).normalized();
for (int y = 0; y < screenHeight; y++) {
for (int x = 0; x < screenWidth; x++) {
// Convert screen coordinates to normalized device coordinates
@@ -242,21 +256,58 @@ public:
Vec3f rayEnd = Vec3f(rayEndWorld.x, rayEndWorld.y, rayEndWorld.z);
Vec3f rayDir = (rayEnd - rayStart).normalized();
// Perform ray casting (use camera position as ray origin)
// Perform ray casting
Vec3f hitPos, hitNormal, hitColor;
if (grid.rayCast(camera.position, rayDir, 100.0f, hitPos, hitNormal, hitColor)) {
// Simple lighting
Vec3f lightDir = Vec3f(1, 1, -1).normalized();
float diffuse = std::max(static_cast<float>(hitNormal.dot(lightDir)), 0.2f);
bool hit = grid.rayCast(camera.position, rayDir, 100.0f, hitPos, hitNormal, hitColor);
// Output pixel (simplified - in real OpenGL, set pixel color)
// Calculate pixel index in frame data
int pixelIndex = (y * screenWidth + x) * 4; // 4 channels for RGBA
if (hit) {
// Simple lighting
float diffuse = std::max(hitNormal.dot(lightDir), 0.2f);
// Apply lighting to color
Vec3f finalColor = hitColor * diffuse;
// Clamp color values to [0, 1]
finalColor.x = std::max(0.0f, std::min(1.0f, finalColor.x));
finalColor.y = std::max(0.0f, std::min(1.0f, finalColor.y));
finalColor.z = std::max(0.0f, std::min(1.0f, finalColor.z));
// Convert to 8-bit RGB and set pixel
frameData[pixelIndex] = static_cast<uint8_t>(finalColor.x * 255); // R
frameData[pixelIndex + 1] = static_cast<uint8_t>(finalColor.y * 255); // G
frameData[pixelIndex + 2] = static_cast<uint8_t>(finalColor.z * 255); // B
frameData[pixelIndex + 3] = 255; // A (fully opaque)
// Debug: mark center pixel with a crosshair
if (x == screenWidth/2 && y == screenHeight/2) {
// White crosshair for center
frameData[pixelIndex] = 255;
frameData[pixelIndex + 1] = 255;
frameData[pixelIndex + 2] = 255;
std::cout << "Center ray hit at: " << hitPos.x << ", "
<< hitPos.y << ", " << hitPos.z << std::endl;
}
} else {
// Background color
frameData[pixelIndex] = static_cast<uint8_t>(backgroundColor.x * 255);
frameData[pixelIndex + 1] = static_cast<uint8_t>(backgroundColor.y * 255);
frameData[pixelIndex + 2] = static_cast<uint8_t>(backgroundColor.z * 255);
frameData[pixelIndex + 3] = 255; // A
}
}
}
return renderedFrame;
}
// Overload for backward compatibility (calls the new method and discards frame)
void render(int screenWidth, int screenHeight) {
frame tempFrame = renderToFrame(screenWidth, screenHeight);
// Optional: print info about the rendered frame
std::cout << "Rendered frame: " << tempFrame << std::endl;
}
void rotateCamera(float yaw, float pitch) {
@@ -268,4 +319,7 @@ public:
}
Camera& getCamera() { return camera; }
// Get reference to the voxel grid (for testing/debugging)
VoxelGrid& getGrid() { return grid; }
};

View File

@@ -63,11 +63,11 @@ public:
return crossProduct.length() / direction.length();
}
Ray3 transform(const class Mat4<T>& matrix) const {
Vec3<T> transformedOrigin = matrix.transformPoint(origin);
Vec3<T> transformedDirection = matrix.transformDirection(direction);
return Ray3<T>(transformedOrigin, transformedDirection.normalized());
}
// Ray3 transform(const Mat4<T>& matrix) const {
// Vec3<T> transformedOrigin = matrix.transformPoint(origin);
// Vec3<T> transformedDirection = matrix.transformDirection(direction);
// return Ray3<T>(transformedOrigin, transformedDirection.normalized());
// }
std::string toString() const {
return "Ray3(origin: " + origin.toString() + ", direction: " + direction.toString() + ")";

View File

@@ -5,6 +5,7 @@
#include <algorithm>
#include <string>
#include <ostream>
#include <cstdint>
template<typename T>
class Vec3 {
@@ -14,7 +15,7 @@ public:
Vec3() : x(0), y(0), z(0) {}
Vec3(T x, T y, T z) : x(x), y(y), z(z) {}
Vec3(T scalar) : x(scalar), y(scalar), z(scalar) {}
Vec3(float[3] acd) : x(acd[0]), y(acd[1]), z(acd[2]) {}
Vec3(float acd[3]) : x(acd[0]), y(acd[1]), z(acd[2]) {}
Vec3(const class Vec2& vec2, T z = 0);
@@ -127,7 +128,7 @@ public:
return x * other.x + y * other.y + z * other.z;
}
Vec3& cross(const Vec3& other) const {
Vec3 cross(const Vec3& other) const {
return Vec3(
y * other.z - z * other.y,
z * other.x - x * other.z,