init
This commit is contained in:
commit
f042e07ee7
|
@ -0,0 +1,105 @@
|
|||
# -*- mode: gitignore; -*-
|
||||
*~
|
||||
\#*\#
|
||||
/.emacs.desktop
|
||||
/.emacs.desktop.lock
|
||||
*.elc
|
||||
auto-save-list
|
||||
tramp
|
||||
.\#*
|
||||
|
||||
# Org-mode
|
||||
.org-id-locations
|
||||
*_archive
|
||||
|
||||
# flymake-mode
|
||||
*_flymake.*
|
||||
|
||||
# eshell files
|
||||
/eshell/history
|
||||
/eshell/lastdir
|
||||
|
||||
# elpa packages
|
||||
/elpa/
|
||||
|
||||
# reftex files
|
||||
*.rel
|
||||
|
||||
# AUCTeX auto folder
|
||||
/auto/
|
||||
|
||||
# cask packages
|
||||
.cask/
|
||||
dist/
|
||||
|
||||
# Flycheck
|
||||
flycheck_*.el
|
||||
|
||||
# server auth directory
|
||||
/server/
|
||||
|
||||
# projectiles files
|
||||
.projectile
|
||||
|
||||
# directory configuration
|
||||
.dir-locals.el
|
||||
.ccls-cache/
|
||||
|
||||
# network security
|
||||
/network-security.data
|
||||
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Linker output
|
||||
*.ilk
|
||||
*.map
|
||||
*.exp
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
*.idb
|
||||
*.pdb
|
||||
|
||||
# Kernel Module Compile Results
|
||||
*.mod*
|
||||
*.cmd
|
||||
.tmp_versions/
|
||||
modules.order
|
||||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
|
||||
build/
|
||||
.ccls-cache/
|
|
@ -0,0 +1,36 @@
|
|||
CXX := g++
|
||||
SRC_DIR := src
|
||||
BUILD_DIR := build
|
||||
TARGET := $(BUILD_DIR)/holst
|
||||
STD ?= c++23
|
||||
|
||||
CXXFLAGS := -std=$(STD) -Wall -Wextra -O2 -Iinclude
|
||||
LDFLAGS :=
|
||||
|
||||
# Source files and object files
|
||||
SRCS := $(shell find $(SRC_DIR) -name '*.cpp')
|
||||
OBJS := $(patsubst $(SRC_DIR)/%.cpp,$(BUILD_DIR)/%.o,$(SRCS))
|
||||
|
||||
# Default target
|
||||
all: $(TARGET)
|
||||
|
||||
# Link final executable
|
||||
$(TARGET): $(OBJS)
|
||||
@mkdir -p $(dir $@)
|
||||
$(CXX) $(OBJS) -o $@ $(LDFLAGS)
|
||||
|
||||
# Compile source files
|
||||
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp
|
||||
@mkdir -p $(dir $@)
|
||||
$(CXX) $(CXXFLAGS) -c $< -o $@
|
||||
|
||||
# Clean build files
|
||||
clean:
|
||||
rm -rf $(BUILD_DIR)
|
||||
|
||||
# Print configuration (debugging)
|
||||
print:
|
||||
@echo "Compiler: $(CXX)"
|
||||
@echo "Standard: $(STD)"
|
||||
@echo "Sources: $(SRCS)"
|
||||
@echo "Objects: $(OBJS)"
|
|
@ -0,0 +1,123 @@
|
|||
#+TITLE: Holst
|
||||
#+AUTHOR: Charles Kralapp
|
||||
#+OPTIONS: toc:nil num:nil
|
||||
|
||||
This project combines a raytracer and an N-body solar system simulation to learn modern C++ (C++03–C++23) through practical implementation.
|
||||
|
||||
* ✅ Project Goals
|
||||
- [ ] Simulate solar system using an N-body gravitational algorithm.
|
||||
- [ ] Implement a raytracer for rendering bodies and backgrounds.
|
||||
- [ ] Learn and demonstrate features from every major C++ standard.
|
||||
- [ ] Use open-source tooling: GNU Emacs, Org-mode, GCC, GNU Make.
|
||||
|
||||
* 🚀 Toolchain
|
||||
- Editor: Emacs + Org Mode
|
||||
- Compiler: GCC/g++
|
||||
- Build System: GNU Make (no CMake)
|
||||
- Version Control: Git (optional but recommended)
|
||||
|
||||
* 📚 C++ Learning Checklist
|
||||
|
||||
** C++03 (Baseline)
|
||||
- [ ] Classes & Constructors
|
||||
- [ ] Operator Overloading (`+`, `*`, `[]`)
|
||||
- [ ] Manual memory management (`new` / `delete`)
|
||||
- [ ] STL containers: `std::vector`, `std::map`
|
||||
- [ ] Function overloading
|
||||
- [ ] Templates (vector math, utility classes)
|
||||
- [ ] Pointers, references, and const correctness
|
||||
- [ ] Namespaces
|
||||
- [ ] RAII pattern with destructors
|
||||
- [ ] `std::string`, `std::stringstream`
|
||||
|
||||
** C++11 (Modern C++ begins)
|
||||
- [ ] `auto` type deduction
|
||||
- [ ] Range-based for loops
|
||||
- [ ] Lambda expressions
|
||||
- [ ] `nullptr`
|
||||
- [ ] `enum class`
|
||||
- [ ] Smart pointers: `std::unique_ptr`, `std::shared_ptr`
|
||||
- [ ] `override`, `final` specifiers
|
||||
- [ ] `move` semantics and rvalue references
|
||||
- [ ] `std::array`, `std::tuple`
|
||||
- [ ] Thread support: `std::thread`
|
||||
|
||||
** C++14 (Polish & convenience)
|
||||
- [ ] Generic lambdas (`auto` in lambda parameters)
|
||||
- [ ] `decltype(auto)` and improved return type inference
|
||||
- [ ] `std::make_unique`
|
||||
- [ ] Binary literals and digit separators (`0b1010`, `1'000'000`)
|
||||
- [ ] Relaxed constexpr functions
|
||||
- [ ] Using `auto` in lambda captures
|
||||
|
||||
** C++17 (Simpler and more expressive)
|
||||
- [ ] Structured bindings (`auto [x, y] = foo();`)
|
||||
- [ ] `if constexpr`
|
||||
- [ ] `std::optional`
|
||||
- [ ] `std::variant`, `std::any`
|
||||
- [ ] Inline variables
|
||||
- [ ] `std::string_view`
|
||||
- [ ] Filesystem support (`std::filesystem`)
|
||||
- [ ] Parallel algorithms (`std::execution`)
|
||||
|
||||
** C++20 (Huge leap forward)
|
||||
- [ ] Concepts (`template<typename T> requires`)
|
||||
- [ ] Ranges library: views, filters, transforms
|
||||
- [ ] `consteval` / `constinit`
|
||||
- [ ] Coroutines (`co_yield`, `co_return`)
|
||||
- [ ] Calendar and time utilities (`std::chrono::year_month_day`)
|
||||
- [ ] Modules (if supported by compiler/toolchain)
|
||||
- [ ] Expanded constexpr support (e.g., STL algorithms)
|
||||
|
||||
** C++23 (Final polish)
|
||||
- [ ] `std::expected` (like Rust's Result<T, E>)
|
||||
- [ ] `std::mdspan` for multidimensional array views
|
||||
- [ ] `explicit` lambdas
|
||||
- [ ] More constexpr in the standard library
|
||||
- [ ] `[[assume]]` attribute
|
||||
- [ ] Improved ranges (e.g., `views::repeat`, `zip`)
|
||||
|
||||
* 🛠 Project Milestones (use standards progressively)
|
||||
|
||||
** Milestone 1: Base Simulation Engine
|
||||
- [ ] Build N-body simulation using raw pointers (C++03)
|
||||
- [ ] Add `Vector3` class, `Body` class
|
||||
- [ ] Use `std::vector` and manual memory management
|
||||
|
||||
** Milestone 2: Modernization Pass 1
|
||||
- [ ] Convert raw pointers to smart pointers (C++11)
|
||||
- [ ] Add lambda-driven physics update loop
|
||||
- [ ] Use `enum class` for material types
|
||||
|
||||
** Milestone 3: Raytracer Core
|
||||
- [ ] Add ray-object intersection logic
|
||||
- [ ] Use `std::optional` for hit results (C++17)
|
||||
- [ ] Structured bindings for clean code
|
||||
|
||||
** Milestone 4: Optimization Pass
|
||||
- [ ] Parallel rendering with `std::execution::par` (C++17)
|
||||
- [ ] Use ranges and views to process pixels (C++20)
|
||||
|
||||
** Milestone 5: Error Handling & Final Touches
|
||||
- [ ] Use `std::expected` for config file errors or simulation errors (C++23)
|
||||
- [ ] Add diagnostics/metrics via coroutines or logging views
|
||||
- [ ] Final cleanup using `consteval`, `mdspan`, or advanced features
|
||||
|
||||
* 🧪 Testing Ideas
|
||||
- [ ] Unit tests for vector math and physics (can use C++11 `assert`)
|
||||
- [ ] Visual verification of orbits and raytraced scene
|
||||
- [ ] Compare numerical stability over long time steps
|
||||
|
||||
* 📂 Directory Layout (suggested)
|
||||
#+BEGIN_SRC
|
||||
project-root/
|
||||
├── Makefile
|
||||
├── README.org (this file)
|
||||
└─── src/
|
||||
├── main.cpp
|
||||
├── vec3.cpp / .h
|
||||
├── body.cpp / .h
|
||||
└─── raytracer/
|
||||
└── ray.cpp / .h ...
|
||||
#+END_SRC
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
#include "simulation.h"
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
|
||||
int main() {
|
||||
auto state = std::make_shared<SimulationState>();
|
||||
state->positions.push_back(Vec3(1.0, 2.0, 3.0));
|
||||
|
||||
std::thread sim(simulation_loop, state);
|
||||
std::thread render(render_loop);
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::seconds(2));
|
||||
running = false;
|
||||
|
||||
sim.join();
|
||||
render.join();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
#ifndef RING_BUFFER_H
|
||||
#define RING_BUFFER_H
|
||||
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <cstddef>
|
||||
|
||||
template <typename T, size_t Capacity>
|
||||
class RingBuffer {
|
||||
static_assert((Capacity & (Capacity - 1)) == 0, "Capacity must be power of 2");
|
||||
|
||||
private:
|
||||
std::array<T, Capacity> buffer;
|
||||
std::atomic<size_t> head = 0; // write index
|
||||
std::atomic<size_t> tail = 0; // read index
|
||||
|
||||
public:
|
||||
bool push(const T& item) {
|
||||
size_t current_head = head.load(std::memory_order_relaxed);
|
||||
size_t next_head = (current_head + 1) & (Capacity - 1);
|
||||
|
||||
if (next_head == tail.load(std::memory_order_acquire)) {
|
||||
return false; // buffer full
|
||||
}
|
||||
|
||||
buffer[current_head] = item;
|
||||
head.store(next_head, std::memory_order_release);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool pop(T& item) {
|
||||
size_t current_tail = tail.load(std::memory_order_relaxed);
|
||||
if (current_tail == head.load(std::memory_order_acquire)) {
|
||||
return false; // buffer empty
|
||||
}
|
||||
|
||||
item = buffer[current_tail];
|
||||
tail.store((current_tail + 1) & (Capacity - 1), std::memory_order_release);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool empty() const {
|
||||
return head.load() == tail.load();
|
||||
}
|
||||
|
||||
bool full() const {
|
||||
return ((head.load() + 1) & (Capacity - 1)) == tail.load();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,36 @@
|
|||
#include "simulation.h"
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
std::atomic<bool> running(true);
|
||||
RingBuffer<Vec3, 64> snapshot_buffer;
|
||||
|
||||
void simulation_loop(std::shared_ptr<SimulationState> state) {
|
||||
Vec3 velocity(0.01, 0.02, 0.03);
|
||||
|
||||
while (running) {
|
||||
// Update position
|
||||
for (auto &p : state->positions) {
|
||||
p += velocity;
|
||||
}
|
||||
|
||||
// Push latest position to buffer
|
||||
if (!snapshot_buffer.push(state->positions[0])) {
|
||||
std::cerr << "Snapshot buffer full, dropping frame\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void render_loop() {
|
||||
Vec3 latest;
|
||||
|
||||
while (running) {
|
||||
while (snapshot_buffer.pop(latest)) {
|
||||
std::cout << "[Render] ";
|
||||
latest.print();
|
||||
}
|
||||
// Optional: add very short pause to avoid spinning too fast
|
||||
std::this_thread::yield(); // cooperative multitasking
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef SIMULATION_H
|
||||
#define SIMULATION_H
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
#include "vec3.h"
|
||||
#include "ring_buffer.h"
|
||||
|
||||
struct SimulationState {
|
||||
std::vector<Vec3> positions;
|
||||
};
|
||||
|
||||
extern std::atomic<bool> running;
|
||||
extern RingBuffer<Vec3, 64> snapshot_buffer;
|
||||
|
||||
void simulation_loop(std::shared_ptr<SimulationState> state);
|
||||
void render_loop();
|
||||
|
||||
#endif
|
|
@ -0,0 +1,45 @@
|
|||
#ifndef VEC3_H
|
||||
#define VEC3_H
|
||||
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
|
||||
class Vec3 {
|
||||
std::array<double, 3> data;
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
Vec3() = default;
|
||||
Vec3(double x, double y, double z) : data{x, y, z} {}
|
||||
|
||||
// Named accessors (mutable)
|
||||
double& x() { return data[0]; }
|
||||
double& y() { return data[1]; }
|
||||
double& z() { return data[2]; }
|
||||
|
||||
// Named accessors (const)
|
||||
double x() const { return data[0]; }
|
||||
double y() const { return data[1]; }
|
||||
double z() const { return data[2]; }
|
||||
|
||||
// Arithmetic operators
|
||||
friend Vec3 operator+(const Vec3& a, const Vec3& b) {
|
||||
return Vec3(a.x() + b.x(),
|
||||
a.y() + b.y(),
|
||||
a.z() + b.z());
|
||||
}
|
||||
|
||||
Vec3& operator+=(const Vec3& other) {
|
||||
x() += other.x();
|
||||
y() += other.y();
|
||||
z() += other.z();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Debug print
|
||||
void print() const {
|
||||
std::cout << "(" << x() << ", " << y() << ", " << z() << ")\n";
|
||||
}
|
||||
};
|
||||
|
||||
#endif // VEC3_H
|
Loading…
Reference in New Issue