Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file modified build_simple.sh
100644 → 100755
Empty file.
383 changes: 383 additions & 0 deletions docs/stories/2.2.camera-system-and-controls.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,383 @@
# Story 2.2: Camera System and Controls

## Status
Done

## Story
**As a** graphics programming learner,
**I want** interactive camera positioning with field-of-view and look-at controls,
**so that** I can explore scenes from different perspectives and understand camera mathematics in practice.

## Acceptance Criteria
1. Camera class encapsulates position, target, up vector, field-of-view, and image aspect ratio with clear mathematical representation
2. Look-at matrix generation follows standard computer graphics mathematics with educational documentation
3. Field-of-view to focal length conversion demonstrates practical camera optics calculations
4. Command-line parameter support allows easy camera adjustment without recompilation for experimentation
5. Camera ray generation produces correct world-space rays for any camera configuration with validation tests

## Tasks / Subtasks
- [x] Enhance Camera class with complete camera parameters (AC: 1)
- [x] Add position, target, up vector properties with validation
- [x] Add field-of-view and aspect ratio with range validation
- [x] Implement mathematical representation methods for educational output
- [x] Add camera parameter validation and clamping to safe ranges
- [x] Create educational console output explaining camera coordinate system
- [x] Implement look-at matrix generation (AC: 2)
- [x] Calculate camera basis vectors (forward, right, up) from position/target/up
- [x] Implement standard look-at matrix mathematics
- [x] Add educational documentation with mathematical derivation
- [x] Create ASCII diagram showing camera coordinate system
- [x] Test look-at matrix with various camera configurations
- [x] Add field-of-view to focal length conversion (AC: 3)
- [x] Implement FOV to focal length calculation with educational comments
- [x] Add practical camera optics explanations (35mm equivalent, etc.)
- [x] Create FOV visualization in console output
- [x] Test FOV calculations with common camera angles (30°, 45°, 60°, 90°)
- [x] Validate FOV impact on ray generation and image perspective
- [x] Implement command-line camera parameter support (AC: 4)
- [x] Add command-line parsing for camera position (--camera-pos x,y,z)
- [x] Add command-line parsing for camera target (--camera-target x,y,z)
- [x] Add command-line parsing for field-of-view (--fov degrees)
- [x] Add parameter validation and error reporting
- [x] Create help documentation for all camera parameters
- [x] Validate camera ray generation for all configurations (AC: 5)
- [x] Test ray generation with various camera positions and orientations
- [x] Validate ray directions match expected camera coordinate system
- [x] Test edge cases (camera pointing up/down, extreme FOV values)
- [x] Add mathematical validation tests for ray generation accuracy
- [x] Create visual test scenes to verify camera behavior

## Dev Notes

### Previous Story Insights
From Story 2.1 completion, the image generation system provides:
- Camera class foundation with basic ray generation capability
- Image class with 256×256 rendering, gamma correction, and PNG export
- Multi-ray pixel sampling infrastructure (65,536 rays per image)
- Educational performance monitoring with detailed timing analysis
- Mathematical validation framework with 1e-6 precision tolerance
- Existing camera-to-pixel coordinate transformation system

### Architecture Context

**Source:** [docs/architecture/components.md - Ray Tracing Engine Core]
- Camera system as part of core ray tracing operations with educational debugging
- `Camera::generate_ray()` method for primary ray generation from camera
- Educational transparency through EducationalMode controller integration

**Source:** [docs/architecture/core-workflows.md - Epic 2: Real-time Material Parameter Manipulation Workflow]
- Camera system supports visual feedback for educational learning
- Console output provides detailed mathematical breakdown of camera calculations
- Educational workflow emphasizes connection between camera mathematics and visual results

### Data Models Specifications

**Enhanced Camera Class Implementation:**
```cpp
class Camera {
public:
// Core camera parameters
Vector3 position; // Camera eye position in world space
Vector3 target; // Point camera is looking at
Vector3 up; // Up vector (typically (0,1,0))
float field_of_view_degrees; // Vertical FOV in degrees
float aspect_ratio; // Width/height ratio

// Derived camera properties (calculated from above)
Vector3 forward; // Camera forward direction (normalized)
Vector3 right; // Camera right direction (normalized)
Vector3 camera_up; // Camera up direction (normalized)
float focal_length; // 35mm equivalent focal length

Camera(Vector3 pos, Vector3 tgt, Vector3 up_vec, float fov_degrees, float aspect);

// Core camera functionality
Ray generate_ray(float pixel_x, float pixel_y, int image_width, int image_height) const;

// Camera coordinate system calculations
void calculate_camera_basis_vectors();
Matrix4x4 calculate_look_at_matrix() const;

// Field-of-view and optics calculations
float fov_to_focal_length(float fov_degrees, float sensor_width = 36.0f) const;
float focal_length_to_fov(float focal_length, float sensor_width = 36.0f) const;

// Educational mathematical explanations
void explain_camera_coordinate_system() const;
void explain_fov_calculations() const;
void print_camera_parameters() const;

// Parameter validation and clamping
bool validate_parameters() const;
void clamp_to_safe_ranges();

// Command-line parameter setting
void set_from_command_line_args(int argc, char* argv[]);
static void print_command_line_help();
};
```

**Matrix4x4 Class Implementation (Inline within camera.hpp):**
```cpp
class Matrix4x4 {
public:
float m[4][4]; // Row-major 4x4 matrix

Matrix4x4() {
// Initialize to identity matrix
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
m[i][j] = (i == j) ? 1.0f : 0.0f;
}
}
}

// Static factory method for look-at matrix creation
static Matrix4x4 look_at(const Vector3& eye, const Vector3& target, const Vector3& up) {
Vector3 forward = (target - eye).normalized();
Vector3 right = forward.cross(up).normalized();
Vector3 camera_up = right.cross(forward);

Matrix4x4 result;

// Build look-at matrix following standard computer graphics convention
result.m[0][0] = right.x; result.m[0][1] = camera_up.x; result.m[0][2] = -forward.x; result.m[0][3] = 0.0f;
result.m[1][0] = right.y; result.m[1][1] = camera_up.y; result.m[1][2] = -forward.y; result.m[1][3] = 0.0f;
result.m[2][0] = right.z; result.m[2][1] = camera_up.z; result.m[2][2] = -forward.z; result.m[2][3] = 0.0f;
result.m[3][0] = -right.dot(eye); result.m[3][1] = -camera_up.dot(eye); result.m[3][2] = forward.dot(eye); result.m[3][3] = 1.0f;

return result;
}

// Educational method to explain matrix construction
void explain_look_at_construction() const {
printf("=== Look-At Matrix Construction ===\n");
printf("Matrix layout (row-major):\n");
for(int i = 0; i < 4; i++) {
printf(" [%6.3f %6.3f %6.3f %6.3f]\n", m[i][0], m[i][1], m[i][2], m[i][3]);
}
printf("First 3 columns: camera basis vectors (right, up, -forward)\n");
printf("Last column: translation (camera position projected onto basis)\n");
}
};
```

**Look-At Matrix Mathematics:**
```cpp
// Standard look-at matrix calculation
Matrix4x4 Camera::calculate_look_at_matrix() const {
Vector3 forward = (target - position).normalized(); // Camera Z-axis (negative)
Vector3 right = forward.cross(up).normalized(); // Camera X-axis
Vector3 camera_up = right.cross(forward); // Camera Y-axis (orthogonal)

// Educational mathematical explanation printed to console
printf("Look-at matrix calculation:\n");
printf(" Forward: (%g,%g,%g)\n", forward.x, forward.y, forward.z);
printf(" Right: (%g,%g,%g)\n", right.x, right.y, right.z);
printf(" Up: (%g,%g,%g)\n", camera_up.x, camera_up.y, camera_up.z);

return Matrix4x4::look_at(position, target, up);
}
```

### Current Source Tree Structure
**Current Project State (Validated as of Story 2.1):**
```
src/
├── core/
│ ├── vector3.hpp (existing - mathematical operations)
│ ├── point3.hpp (existing - point arithmetic)
│ ├── ray.hpp (existing - ray representation)
│ ├── sphere.hpp (existing - ray-sphere intersection)
│ ├── point_light.hpp (existing - light source)
│ ├── camera.hpp (existing - MAJOR ENHANCEMENT needed)
│ ├── image.hpp (existing - image management with PNG)
│ └── stb_image_write.h (existing - PNG export library)
├── materials/
│ └── lambert.hpp (existing - Lambert BRDF)
└── main.cpp (existing - ENHANCEMENT needed for command-line args)

tests/
└── test_math_correctness.cpp (existing - ENHANCEMENT needed for camera validation)
```

**Files to be Modified:**
- src/core/camera.hpp (MAJOR enhancement with complete camera system)
- src/main.cpp (add command-line argument parsing for camera parameters)
- tests/test_math_correctness.cpp (add camera mathematical validation tests)

**New Dependencies Needed:**
- **Command-line argument parsing**: Simple manual argc/argv parsing (no external libraries). Implementation will use standard C string functions (strcmp, atof) for parameter recognition and value extraction. This follows the educational goal of minimal dependencies and transparency.
- **Matrix4x4 class**: Inline implementation within camera.hpp for look-at matrix calculations. Will provide basic 4x4 matrix with look_at static method for camera coordinate transformation. Educational console output will explain matrix calculations.

### Technical Implementation Details

**Source:** [docs/architecture/data-models.md - Vector3 (Enhanced with Educational Features)]
- Continue using Vector3 for camera position, target, and up vectors
- Maintain educational debugging capabilities with calculation tracking
- Use existing Vector3 validation methods for camera parameter verification

**Camera Coordinate System Mathematics:**
```cpp
// Camera basis vector calculation (educational implementation)
void Camera::calculate_camera_basis_vectors() {
// Calculate forward vector (from position to target)
forward = (target - position).normalized();

// Calculate right vector (cross product of forward and world up)
right = forward.cross(up).normalized();

// Calculate camera up vector (orthogonal to forward and right)
camera_up = right.cross(forward);

// Educational console output
printf("=== Camera Coordinate System ===\n");
printf("Position: (%g, %g, %g)\n", position.x, position.y, position.z);
printf("Target: (%g, %g, %g)\n", target.x, target.y, target.z);
printf("Forward: (%g, %g, %g)\n", forward.x, forward.y, forward.z);
printf("Right: (%g, %g, %g)\n", right.x, right.y, right.z);
printf("Up: (%g, %g, %g)\n", camera_up.x, camera_up.y, camera_up.z);
}
```

**Field-of-View to Focal Length Conversion:**
```cpp
float Camera::fov_to_focal_length(float fov_degrees, float sensor_width) const {
// Convert FOV to focal length using standard camera optics formula
float fov_radians = fov_degrees * (M_PI / 180.0f);
float focal_length = sensor_width / (2.0f * tan(fov_radians * 0.5f));

// Educational explanation
printf("FOV Conversion: %g° = %gmm focal length (35mm equivalent)\n",
fov_degrees, focal_length);

return focal_length;
}
```

**Command-Line Parameter Support:**
```cpp
// Example command-line usage:
// ./raytracer --camera-pos 0,0,5 --camera-target 0,0,0 --fov 45
void Camera::set_from_command_line_args(int argc, char* argv[]) {
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "--camera-pos") == 0 && i + 1 < argc) {
// Parse "x,y,z" format
parse_vector3_from_string(argv[i + 1], position);
} else if (strcmp(argv[i], "--camera-target") == 0 && i + 1 < argc) {
parse_vector3_from_string(argv[i + 1], target);
} else if (strcmp(argv[i], "--fov") == 0 && i + 1 < argc) {
field_of_view_degrees = atof(argv[i + 1]);
}
}

// Validate and clamp parameters after parsing
clamp_to_safe_ranges();
calculate_camera_basis_vectors();
}
```

### Educational Performance Monitoring

**Source:** [docs/architecture/testing-strategy.md - Mathematical Correctness Testing]
- Camera coordinate system validation with orthogonal basis vector testing
- Ray generation accuracy testing with known camera configurations
- FOV calculation validation against standard camera optics references
- Command-line parameter validation with edge case testing

**Camera Validation Implementation:**
```cpp
bool test_camera_coordinate_system() {
Camera camera(Vector3(0, 0, 5), Vector3(0, 0, 0), Vector3(0, 1, 0), 45.0f, 16.0f/9.0f);

// Validate basis vectors are orthogonal and normalized
float forward_right_dot = camera.forward.dot(camera.right);
float right_up_dot = camera.right.dot(camera.camera_up);
float up_forward_dot = camera.camera_up.dot(camera.forward);

assert(abs(forward_right_dot) < 1e-6); // Should be perpendicular
assert(abs(right_up_dot) < 1e-6); // Should be perpendicular
assert(abs(up_forward_dot) < 1e-6); // Should be perpendicular

assert(abs(camera.forward.length() - 1.0f) < 1e-6); // Should be normalized
assert(abs(camera.right.length() - 1.0f) < 1e-6); // Should be normalized
assert(abs(camera.camera_up.length() - 1.0f) < 1e-6); // Should be normalized

return true;
}
```

### File Locations
- Enhanced camera implementation: src/core/camera.hpp (major modifications)
- Command-line parsing integration: src/main.cpp (enhanced main function)
- Camera validation tests: tests/test_math_correctness.cpp (extended validation)

### Technical Constraints
- Educational console output for all camera calculations and transformations
- C++20/C++23 compatibility maintained with existing codebase
- Field-of-view range validation: [1°, 179°] with educational warnings
- Camera position validation: finite values with distance checks
- Look-at matrix following right-handed coordinate system conventions
- Mathematical precision: 1e-6 tolerance for orthogonality and normalization tests
- Command-line parameter format: comma-separated values for vectors
- Performance: Camera parameter changes should not require image regeneration setup

## Testing
**Test File Location:** tests/test_math_correctness.cpp
**Testing Framework:** Custom mathematical validation framework (extended from Story 2.1)
**Testing Standards:** Mathematical correctness validation with 1e-6 precision tolerance

**Story-Specific Testing Requirements:**
- Camera coordinate system orthogonality and normalization validation
- Look-at matrix mathematical correctness testing
- Field-of-view to focal length conversion accuracy
- Command-line parameter parsing and validation testing
- Ray generation accuracy across different camera configurations

**Concrete Test Scenarios:**
- Camera Basis Vectors: forward, right, up should form orthogonal normalized basis
- Look-at Matrix: camera pointing at (0,0,0) from (0,0,5) should generate expected matrix
- FOV Conversion: 45° FOV should convert to ~43.3mm focal length (35mm equivalent)
- Command-line Parsing: "--camera-pos 1,2,3" should set position to Vector3(1,2,3)
- Ray Generation: center pixel ray should point toward camera target
- Edge Cases: extreme FOV values (1°, 179°) should be handled gracefully
- Parameter Validation: invalid camera configurations should be detected and corrected

## Dev Agent Record
This section is populated by the development agent during implementation.

### Agent Model Used
Claude Sonnet 4 (claude-sonnet-4-20250514)

### Debug Log References
- Camera coordinate system validation with orthogonal basis vector testing
- Ray generation accuracy testing with known camera configurations
- FOV calculation validation against standard camera optics references
- Command-line parameter validation with edge case testing
- Mathematical validation tests added to test_math_correctness.cpp

### Completion Notes List
- Successfully enhanced Camera class with complete parameter set including derived properties (forward, right, camera_up, focal_length)
- Implemented Matrix4x4 class inline for look-at matrix calculations with educational output
- Added comprehensive parameter validation and clamping (FOV: 1°-179°, aspect ratio: 0.1-10.0)
- Command-line argument support fully functional: --camera-pos, --camera-target, --fov, --help
- Added 5 comprehensive camera validation test functions covering coordinate systems, ray generation, FOV calculations, edge cases, and command-line integration
- All 5 acceptance criteria fully implemented and tested
- All mathematical tests passing (✅ ALL MATHEMATICAL TESTS PASSED)

### File List
- src/core/camera.hpp (MAJOR ENHANCEMENT - added Matrix4x4 class, enhanced Camera with derived properties, validation methods, command-line support, educational output methods)
- src/main.cpp (ENHANCEMENT - added command-line argument parsing integration, help support)
- tests/test_math_correctness.cpp (ENHANCEMENT - added comprehensive camera validation test suite with 5 test functions)

## QA Results
Results from QA Agent QA review of the completed story implementation.

_To be populated by QA agent after implementation completion_

## Change Log
| Date | Version | Description | Author |
|------|---------|-------------|--------|
| 2025-08-20 | 1.0 | Initial story creation from Epic 2.2 requirements | Bob (Scrum Master) |
| 2025-08-20 | 1.1 | Added Dev Agent Record and QA Results sections for template compliance | Sarah (Product Owner) |
| 2025-08-20 | 1.2 | Clarified command-line parsing and Matrix4x4 implementation requirements | Sarah (Product Owner) |
Loading
Loading