23 Commits

Author SHA1 Message Date
yggdrasil75
35c8a71102 renderingbranch 2026-03-07 11:17:51 -05:00
Yggdrasil75
3d96e569c8 I fixed this so removing. 2026-03-04 14:36:31 -05:00
Yggdrasil75
31fb9ffedb asdf 2026-03-04 14:34:40 -05:00
Yggdrasil75
4478bc1845 pushing a star 2026-03-04 14:07:05 -05:00
yggdrasil75
83989e955e fixes 2026-03-04 05:41:51 -05:00
Yggdrasil75
494ee931df pushing this, might need some fixes still 2026-03-03 14:55:36 -05:00
Yggdrasil75
d36d00bc13 some memory changes and an attempt at fillplanet 2026-03-03 13:03:45 -05:00
Yggdrasil75
a0afac9c18 asdf 2026-03-03 06:05:15 -05:00
yggdrasil75
565646e13e pushing this back. 2026-03-02 21:22:40 -05:00
Yggdrasil75
14158fae83 fixed interpolating breaking stuff 2026-03-02 14:01:00 -05:00
Yggdrasil75
4f0dba5eb4 pushing this, lots of fun things to try. 2026-03-02 13:53:13 -05:00
Yggdrasil75
926ffe18cd fixed some rendering 2026-02-27 08:45:26 -05:00
yggdrasil75
b4a7f536bc asdfasdfasdf 2026-02-27 05:47:50 -05:00
yggdrasil75
06d5b383e5 woops 2026-02-26 15:19:52 -05:00
Yggdrasil75
18aa8f06b7 bunch of planet sim changes 2026-02-26 14:03:12 -05:00
Yggdrasil75
fdd5553d20 pushing 2026-02-24 15:01:08 -05:00
Yggdrasil75
e99bbc08af pushing home 2026-02-23 15:00:58 -05:00
Yggdrasil75
c7eb5739f4 some speed test changes 2026-02-23 08:18:07 -05:00
yggdrasil75
2c993995e8 making a proper widget. 2026-02-22 21:07:20 -05:00
yggdrasil75
cb0b8b7643 woops 2026-02-21 11:13:45 -05:00
yggdrasil75
dc36b93e4f some changes for speed and usability with the fast version 2026-02-21 11:05:11 -05:00
Yggdrasil75
2768b6849e some g2 changes. 2026-02-20 13:20:53 -05:00
Yggdrasil75
4f227df1d7 lots of performance changes to g3. reverted to voxel grid from mesh. 2026-02-20 13:20:29 -05:00
13 changed files with 3968 additions and 669 deletions

View File

@@ -7,7 +7,7 @@ STB_DIR := ./stb
# Compiler and flags
CXX := g++
BASE_CXXFLAGS = -std=c++23 -O3 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends -I$(STB_DIR)
BASE_CXXFLAGS = -std=c++23 -O3 -fopenmp -march=native -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends -I$(STB_DIR) -g
BASE_CXXFLAGS += `pkg-config --cflags glfw3`
CFLAGS = $(BASE_CXXFLAGS)
LDFLAGS := -L./imgui -limgui -lGL
@@ -34,7 +34,7 @@ endif
CXXFLAGS = $(BASE_CXXFLAGS) $(SIMD_CXXFLAGS)
# Source files
SRC := $(SRC_DIR)/g3etest.cpp
SRC := $(SRC_DIR)/materialtest.cpp
#SRC := $(SRC_DIR)/g2chromatic2.cpp
SRC += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp
SRC += $(IMGUI_DIR)/backends/imgui_impl_glfw.cpp $(IMGUI_DIR)/backends/imgui_impl_opengl3.cpp

View File

@@ -31,9 +31,9 @@ struct defaults {
bool slowRender = false;
bool globalIllumination = true;
bool useLod = true;
int rayCount = 3;
int rayCount = 5;
int reflectCount = 3;
int lodDist = 500;
int lodDist = 50000;
float lodDropoff = 0.1;
PNoise2 noise = PNoise2(42);
@@ -82,6 +82,12 @@ std::vector<double> renderFrameTimes;
int frameHistoryIndex = 0;
bool firstFrameMeasured = false;
// Stats update timer
std::chrono::steady_clock::time_point lastStatsUpdate;
const std::chrono::seconds STATS_UPDATE_INTERVAL(10);
std::string cachedStats;
bool statsNeedUpdate = true;
Scene scene;
bool meshNeedsUpdate = false;
@@ -182,38 +188,45 @@ void addStar(const defaults& config, const stardefaults& starconf, Octree<int>&
meshNeedsUpdate = true;
}
void updateStatsCache(Octree<int>& grid) {
std::stringstream gridstats;
grid.printStats(gridstats);
cachedStats = gridstats.str();
lastStatsUpdate = std::chrono::steady_clock::now();
statsNeedUpdate = false;
}
void livePreview(Octree<int>& grid, defaults& config, const Camera& cam) {
std::lock_guard<std::mutex> lock(PreviewMutex);
updatePreview = true;
if (meshNeedsUpdate) {
scene.clear();
std::shared_ptr<Mesh> planetMesh = grid.generateMesh(1, config.meshIsoLevel, pow(config.meshResolution, 2));
std::shared_ptr<Mesh> starMesh = grid.generateMesh(2, config.meshIsoLevel, config.meshResolution);
// if (meshNeedsUpdate) {
// scene.clear();
// std::shared_ptr<Mesh> planetMesh = grid.generateMesh(1, config.meshIsoLevel, pow(config.meshResolution, 2));
// std::shared_ptr<Mesh> starMesh = grid.generateMesh(2, config.meshIsoLevel, config.meshResolution);
scene.addMesh(planetMesh);
scene.addMesh(starMesh);
// scene.addMesh(planetMesh);
// scene.addMesh(starMesh);
// planetMesh.setResolution(config.meshResolution);
// planetMesh.setIsoLevel(config.meshIsoLevel);
// planetMesh.update(grid);
meshNeedsUpdate = false;
}
// // planetMesh.setResolution(config.meshResolution);
// // planetMesh.setIsoLevel(config.meshIsoLevel);
// // planetMesh.update(grid);
// meshNeedsUpdate = false;
// }
auto renderStart = std::chrono::high_resolution_clock::now();
frame currentPreviewFrame;
currentPreviewFrame = scene.render(cam, config.outWidth, config.outHeight, 0.1f, 10000.0f, frame::colormap::RGB);
// currentPreviewFrame = scene.render(cam, config.outWidth, config.outHeight, 0.1f, 10000.0f, frame::colormap::RGB);
// grid.setLODMinDistance(config.lodDist);
// grid.setLODFalloff(config.lodDropoff);
// if (config.slowRender) {
// currentPreviewFrame = grid.renderFrame(cam, config.outWidth, config.outHeight, frame::colormap::RGB, config.rayCount, config.reflectCount, config.globalIllumination, config.useLod);
// } else {
// currentPreviewFrame = grid.fastRenderFrame(cam, config.outWidth, config.outHeight, frame::colormap::RGB);
// }
grid.setLODMinDistance(config.lodDist);
grid.setLODFalloff(config.lodDropoff);
if (config.slowRender) {
currentPreviewFrame = grid.renderFrame(cam, config.outWidth, config.outHeight, frame::colormap::RGB, config.rayCount, config.reflectCount, config.globalIllumination, config.useLod);
} else {
currentPreviewFrame = grid.fastRenderFrame(cam, config.outWidth, config.outHeight, frame::colormap::RGB);
}
auto renderEnd = std::chrono::high_resolution_clock::now();
renderFrameTime = std::chrono::duration<double>(renderEnd - renderStart).count();
@@ -330,7 +343,7 @@ int main() {
defaults config;
PointType minBound(-config.gridSizecube, -config.gridSizecube, -config.gridSizecube);
PointType maxBound(config.gridSizecube, config.gridSizecube, config.gridSizecube);
Octree<int> grid(minBound, maxBound, 16, 16);
Octree<int> grid(minBound, maxBound, 8, 32);
bool gridInitialized = false;
float ghalf = config.gridSizecube / 2.f;
@@ -505,22 +518,22 @@ int main() {
ImGui::ColorEdit3("Color", sphereConf.color);
ImGui::Separator();
ImGui::Text("Marching Cubes Config");
if (ImGui::SliderInt("Mesh Resolution", &config.meshResolution, 1, 64)) {
meshNeedsUpdate = true;
}
if (ImGui::SliderFloat("Iso Level", &config.meshIsoLevel, 0.01f, 1.0f)) {
meshNeedsUpdate = true;
}
ImGui::Separator();
ImGui::Checkbox("Is Light", &sphereConf.light);
// if(sphereConf.light) {
// ImGui::DragFloat("Emittance", &sphereConf.emittance, 0.1f, 0.0f, 100.0f);
// ImGui::Text("Marching Cubes Config");
// if (ImGui::SliderInt("Mesh Resolution", &config.meshResolution, 1, 64)) {
// meshNeedsUpdate = true;
// }
// ImGui::SliderFloat("Reflection", &sphereConf.reflection, 0.0f, 1.0f);
// ImGui::SliderFloat("Refraction", &sphereConf.refraction, 0.0f, 1.0f);
// ImGui::Checkbox("Fill Inside", &sphereConf.fillInside);
// if (ImGui::SliderFloat("Iso Level", &config.meshIsoLevel, 0.01f, 1.0f)) {
// meshNeedsUpdate = true;
// }
// ImGui::Separator();
// ImGui::Checkbox("Is Light", &sphereConf.light);
if(sphereConf.light) {
ImGui::DragFloat("Emittance", &sphereConf.emittance, 0.1f, 0.0f, 100.0f);
}
ImGui::SliderFloat("Reflection", &sphereConf.reflection, 0.0f, 1.0f);
ImGui::SliderFloat("Refraction", &sphereConf.refraction, 0.0f, 1.0f);
ImGui::Checkbox("Fill Inside", &sphereConf.fillInside);
if (ImGui::CollapsingHeader("Star/Sun Parameters", ImGuiTreeNodeFlags_DefaultOpen)) {
ImGui::Checkbox("Enable Star", &starConf.enabled);
@@ -564,8 +577,56 @@ int main() {
fluidUI.renderUI();
}
scene.drawSceneWindow("Planet Preview", cam, 0.01, 1000);
scene.drawGridStats();
// scene.drawSceneWindow("Planet Preview", cam, 0.01, 1000);
// scene.drawGridStats();
{
ImGui::Begin("Planet Preview");
if (worldPreview) {
if (gridInitialized) {
livePreview(grid, config, cam);
}
}
if (gridInitialized && textureInitialized) {
ImGui::Image((void*)(intptr_t)textu, ImVec2(config.outWidth, config.outHeight));
} else if (gridInitialized) {
ImGui::Text("Preview not generated yet");
} else {
ImGui::Text("No grid generated");
}
ImGui::Text("Render Performance:");
if (renderFPS > 0) {
// Color code based on FPS
ImVec4 fpsColor = ImVec4(1.0f, 1.0f, 0.0f, 1.0f);
// if (renderFPS >= 30.0) {
// fpsColor = ImVec4(0.0f, 1.0f, 0.0f, 1.0f); // Green for good FPS
// } else if (renderFPS >= 15.0) {
// fpsColor = ImVec4(1.0f, 1.0f, 0.0f, 1.0f); // Yellow for okay FPS
// } else {
// fpsColor = ImVec4(1.0f, 0.0f, 0.0f, 1.0f); // Red for poor FPS
// }
ImGui::TextColored(fpsColor, "FPS: %.1f", renderFPS);
ImGui::Text("Frame time: %.1f ms", avgRenderFrameTime * 1000.0);
// Simple progress bar for frame time
ImGui::Text("%.1f/100 ms", avgRenderFrameTime * 1000.0);
// Show latest frame time
ImGui::Text("Latest: %.1f ms", renderFrameTime * 1000.0);
}
ImGui::Separator();
if (gridInitialized) {
auto now = std::chrono::steady_clock::now();
if ((now - lastStatsUpdate) > STATS_UPDATE_INTERVAL) updateStatsCache(grid);
ImGui::TextUnformatted(cachedStats.c_str());
}
ImGui::End();
}
{
ImGui::Begin("controls");
@@ -759,19 +820,18 @@ int main() {
ImGui::Separator();
ImGui::Checkbox("Continuous Preview", &worldPreview);
// ImGui::Checkbox("Continuous Preview", &worldPreview);
// Removed Raytracing specific controls (Global Illum, LOD) as they don't apply to raster mesh
// ImGui::Checkbox("update Preview", &worldPreview);
// ImGui::Checkbox("Use Slower renderer", &config.slowRender);
// if (config.slowRender) {
// ImGui::InputInt("Rays per pixel", &config.rayCount);
// ImGui::InputInt("Max reflections", &config.reflectCount);
// }
// ImGui::InputFloat("Lod dropoff", &config.lodDropoff);
// ImGui::InputInt("lod minimum Distance", &config.lodDist);
// ImGui::Checkbox("use Global illumination", &config.globalIllumination);
// ImGui::Checkbox("use Lod", &config.useLod);
ImGui::Checkbox("update Preview", &worldPreview);
ImGui::Checkbox("Use Slower renderer", &config.slowRender);
if (config.slowRender) {
ImGui::InputInt("Rays per pixel", &config.rayCount);
ImGui::InputInt("Max reflections", &config.reflectCount);
}
ImGui::InputFloat("Lod dropoff", &config.lodDropoff);
ImGui::InputInt("lod minimum Distance", &config.lodDist);
ImGui::Checkbox("use Global illumination", &config.globalIllumination);
ImGui::Checkbox("use Lod", &config.useLod);
ImGui::End();
}

207
tests/materialtest.cpp Normal file
View File

@@ -0,0 +1,207 @@
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <cmath>
// Include Eigen and project headers
#include "../eigen/Eigen/Dense"
#include "../util/grid/camera.hpp"
#include "../util/grid/grid3eigen.hpp"
#include "../util/output/frame.hpp"
#include "../util/output/bmpwriter.hpp"
#include "../util/output/aviwriter.hpp"
#include "../util/timing_decorator.hpp"
#include "../util/timing_decorator.cpp"
// Helper function to create a solid volume of voxels with material properties
void createBox(Octree<int>& octree, const Eigen::Vector3f& center, const Eigen::Vector3f& size,
const Eigen::Vector3f& albedo, float emission = 0.0f,
float roughness = 0.8f, float metallic = 0.0f, float transmission = 0.0f, float ior = 1.45f) {
float step = 0.1f; // Voxel spacing
Eigen::Vector3f halfSize = size / 2.0f;
Eigen::Vector3f minB = center - halfSize;
Eigen::Vector3f maxB = center + halfSize;
for (float x = minB.x(); x <= maxB.x(); x += step) {
for (float y = minB.y(); y <= maxB.y(); y += step) {
for (float z = minB.z(); z <= maxB.z(); z += step) {
Eigen::Vector3f pos(x, y, z);
// .set(data, pos, visible, albedo, size, active, objectId, subId, emission, roughness, metallic, transmission, ior)
octree.set(1, pos, true, albedo, step, true, -1, 0, emission, roughness, metallic, transmission, ior);
}
}
}
}
// Helper function to create a checkerboard pattern volume
void createCheckerBox(Octree<int>& octree, const Eigen::Vector3f& center, const Eigen::Vector3f& size,
const Eigen::Vector3f& color1, const Eigen::Vector3f& color2, float checkerSize) {
float step = 0.1f;
Eigen::Vector3f halfSize = size / 2.0f;
Eigen::Vector3f minB = center - halfSize;
Eigen::Vector3f maxB = center + halfSize;
for (float x = minB.x(); x <= maxB.x(); x += step) {
for (float y = minB.y(); y <= maxB.y(); y += step) {
for (float z = minB.z(); z <= maxB.z(); z += step) {
Eigen::Vector3f pos(x, y, z);
// Use floor to correctly handle negative coordinates for the repeating pattern
int cx = static_cast<int>(std::floor(x / checkerSize));
int cy = static_cast<int>(std::floor(y / checkerSize));
int cz = static_cast<int>(std::floor(z / checkerSize));
// 3D Checkerboard logic
bool isEven = ((cx + cy + cz) % 2 == 0);
Eigen::Vector3f albedo = isEven ? color1 : color2;
octree.set(1, pos, true, albedo, step, true, -1, 0, 0.0f, 0.8f, 0.1f, 0.0f, 1.0f);
}
}
}
}
int main() {
std::cout << "Initializing Octree..." << std::endl;
// 1. Initialize Octree bounds
Eigen::Vector3f minBound(-10.0f, -10.0f, -10.0f);
Eigen::Vector3f maxBound(10.0f, 10.0f, 10.0f);
Octree<int> octree(minBound, maxBound, 8, 16);
// Set a dark background to emphasize the PBR light emission
octree.setBackgroundColor(Eigen::Vector3f(0.02f, 0.02f, 0.02f));
octree.setSkylight(Eigen::Vector3f(0.01f, 0.01f, 0.01f));
std::cout << "Building scene..." << std::endl;
// 2a. Build Room (Floor and 4 Walls)
Eigen::Vector3f cLightGray(0.8f, 0.8f, 0.8f);
Eigen::Vector3f cDarkGray(0.2f, 0.2f, 0.2f);
float chkSize = 1.0f;
// Floor (Bounds: Z from -0.7 to -0.5)
// The boxes sit exactly on Z = -0.5
createCheckerBox(octree, Eigen::Vector3f(0.0f, 0.0f, -0.6f), Eigen::Vector3f(14.4f, 14.4f, 0.2f), cLightGray, cDarkGray, chkSize);
// Walls (Bounds: X/Y inner boundaries at +/- 7.0, rising from Z=-0.5 up to Z=7.5)
createCheckerBox(octree, Eigen::Vector3f( 7.1f, 0.0f, 3.5f), Eigen::Vector3f(0.2f, 14.4f, 8.0f), cLightGray, cDarkGray, chkSize); // +X
createCheckerBox(octree, Eigen::Vector3f(-7.1f, 0.0f, 3.5f), Eigen::Vector3f(0.2f, 14.4f, 8.0f), cLightGray, cDarkGray, chkSize); // -X
createCheckerBox(octree, Eigen::Vector3f( 0.0f, 7.1f, 3.5f), Eigen::Vector3f(14.0f, 0.2f, 8.0f), cLightGray, cDarkGray, chkSize); // +Y
createCheckerBox(octree, Eigen::Vector3f( 0.0f, -7.1f, 3.5f), Eigen::Vector3f(14.0f, 0.2f, 8.0f), cLightGray, cDarkGray, chkSize); // -Y
// 2b. Create the 3x3 material sampler grid inside the room
Eigen::Vector3f cRed(1.0f, 0.1f, 0.1f);
Eigen::Vector3f cBlue(0.1f, 0.1f, 1.0f);
Eigen::Vector3f cPurple(0.6f, 0.1f, 0.8f);
Eigen::Vector3f size(1.0f, 1.0f, 1.0f);
float sp = 2.0f; // spacing between cubes
// --- LAYER 1: Metals ---
// (metallic = 1.0, slight roughness for blurry reflections, transmission = 0.0)
createBox(octree, Eigen::Vector3f(-sp, -sp, 0.0f), size, cRed, 0.0f, 0.15f, 1.0f, 0.0f, 1.45f);
createBox(octree, Eigen::Vector3f( 0, -sp, 0.0f), size, cBlue, 0.0f, 0.15f, 1.0f, 0.0f, 1.45f);
createBox(octree, Eigen::Vector3f( sp, -sp, 0.0f), size, cPurple, 0.0f, 0.15f, 1.0f, 0.0f, 1.45f);
// --- LAYER 2: Opaque & Highly Refractive ---
// (metallic = 0.0, very low roughness. transmission = 0.0 for opacity, ior = 2.4 for extreme diamond-like reflection)
createBox(octree, Eigen::Vector3f(-sp, 0, 0.0f), size, cRed, 0.0f, 0.05f, 0.0f, 0.0f, 2.4f);
createBox(octree, Eigen::Vector3f( 0, 0, 0.0f), size, cBlue, 0.0f, 0.05f, 0.0f, 0.0f, 2.4f);
createBox(octree, Eigen::Vector3f( sp, 0, 0.0f), size, cPurple, 0.0f, 0.05f, 0.0f, 0.0f, 2.4f);
// --- LAYER 3: Clear Glass ---
// (metallic = 0.0, near-zero roughness, transmission = 1.0 for full transparency, ior = 1.5 for glass)
createBox(octree, Eigen::Vector3f(-sp, sp, 0.0f), size, cRed, 0.0f, 0.01f, 0.0f, 1.0f, 1.5f);
createBox(octree, Eigen::Vector3f( 0, sp, 0.0f), size, cBlue, 0.0f, 0.01f, 0.0f, 1.0f, 1.5f);
createBox(octree, Eigen::Vector3f( sp, sp, 0.0f), size, cPurple, 0.0f, 0.01f, 0.0f, 1.0f, 1.5f);
// White Light Box (Above)
// Placed near the ceiling (Z=7.4), made large (8x8) to cast soft shadows evenly over the whole 3x3 grid
createBox(octree, Eigen::Vector3f(0.0f, 0.0f, 7.4f), Eigen::Vector3f(8.0f, 8.0f, 0.2f), Eigen::Vector3f(1.0f, 1.0f, 1.0f), 15.0f);
std::cout << "Optimizing and Generating LODs..." << std::endl;
octree.generateLODs();
octree.printStats();
// 3. Setup video rendering
int width = 512;
int height = 512;
// --- Video Animation Parameters ---
const float fps = 30.0f;
const float durationPerSegment = 10.0f; // Seconds to travel between each view
const int framesPerSegment = static_cast<int>(fps * durationPerSegment);
const int video_samples = 100; // Samples per pixel for each video frame
const int video_bounces = 5; // Ray bounces for each video frame
struct View {
std::string name;
Eigen::Vector3f origin;
Eigen::Vector3f up;
};
// Define the keyframe camera views for the animation
std::vector<View> views = {
{"-Y", Eigen::Vector3f( 0.0f, -6.8f, 1.0f), Eigen::Vector3f(0.0f, 0.0f, 1.0f)},
{"+X", Eigen::Vector3f( 6.8f, 0.0f, 1.0f), Eigen::Vector3f(0.0f, 0.0f, 1.0f)},
{"+Y", Eigen::Vector3f( 0.0f, 6.8f, 1.0f), Eigen::Vector3f(0.0f, 0.0f, 1.0f)},
{"-X", Eigen::Vector3f(-6.8f, 0.0f, 1.0f), Eigen::Vector3f(0.0f, 0.0f, 1.0f)},
{"+Z", Eigen::Vector3f( 0.0f, 0.0f, 7.3f), Eigen::Vector3f(0.0f, 1.0f, 0.0f)} // Top-down view
};
Eigen::Vector3f target(0.0f, 0.0f, 0.5f); // The camera will always look at this point
// --- Main Animation and Rendering Loop ---
std::vector<frame> videoFrames;
const int totalFrames = framesPerSegment * views.size();
videoFrames.reserve(totalFrames);
int frameCounter = 0;
std::cout << "\nStarting video render..." << std::endl;
std::cout << "Total frames to render: " << totalFrames << std::endl;
for (size_t i = 0; i < views.size(); ++i) {
const View& startView = views[i];
const View& endView = views[(i + 1) % views.size()]; // Loop back to the first view at the end
std::cout << "\nAnimating segment: " << startView.name << " -> " << endView.name << std::endl;
for (int j = 0; j < framesPerSegment; ++j) {
frameCounter++;
float t = static_cast<float>(j) / static_cast<float>(framesPerSegment);
// Interpolate camera position (origin) linearly
Eigen::Vector3f currentOrigin = startView.origin * (1.0f - t) + endView.origin * t;
// Interpolate camera orientation (up vector) and normalize
Eigen::Vector3f currentUp = (startView.up * (1.0f - t) + endView.up * t).normalized();
Camera cam;
cam.origin = currentOrigin;
cam.up = currentUp;
cam.direction = (target - cam.origin).normalized();
std::cout << "Rendering video frame " << frameCounter << "/" << totalFrames << "..." << std::endl;
frame out = octree.renderFrame(cam, height, width, frame::colormap::RGB, video_samples, video_bounces, false, true);
videoFrames.push_back(std::move(out)); // Use std::move for efficiency
}
}
// --- Save the final video ---
std::cout << "\nAll frames rendered. Saving video file..." << std::endl;
std::string videoFilename = "output/material_test_video.avi";
if (AVIWriter::saveAVIFromCompressedFrames(videoFilename, std::move(videoFrames), width, height, fps)) {
std::cout << "Video saved successfully to " << videoFilename << std::endl;
} else {
std::cerr << "Error: Failed to save video!" << std::endl;
}
std::cout << "\nRender complete!" << std::endl;
return 0;
}

582
tests/planet.cpp Normal file
View File

@@ -0,0 +1,582 @@
#ifndef PLANET_CPP
#define PLANET_CPP
#include "../util/sim/planet.hpp"
#include "../util/grid/camera.hpp"
#include "../util/noise/pnoise2.hpp"
#include "../util/noise/pnoise.cpp"
class planetSimUI {
private:
planetsim sim;
Camera cam;
bool isRunning = false;
// Texture Management
GLuint textu = 0;
std::mutex PreviewMutex;
bool updatePreview = false;
bool textureInitialized = false;
frame currentPreviewFrame;
int outWidth = 1024;
int outHeight = 1024;
float fps = 60;
int rayCount = 3;
int reflectCount = 4;
bool slowRender = false;
float lodDist = 1024.0f;
float lodDropoff = 0.001f;
float maxViewDistance = 4096;
bool globalIllumination = false;
bool useLod = true;
std::map<int, bool> keyStates;
float deltaTime = 0.16f;
bool orbitEquator = false;
float rotationRadius = 2500;
float angle = 0.0f;
const float ω = (std::pow(M_PI, 2) / 30) / 10;
bool tectonicGenned = false;
bool doFixPlates = true;
bool platesUseCellular = false;
std::chrono::steady_clock::time_point lastStatsUpdate;
std::string cachedStats;
bool statsNeedUpdate = true;
float framerate = 60.0;
enum class DebugColorMode {
BASE,
PLATES,
NOISE,
RESERVED
};
DebugColorMode currentColorMode = DebugColorMode::BASE;
enum class DebugMapMode {
NONE,
BASE,
NOISE,
TECTONIC,
TECTONICCOLOR,
CURRENT
};
DebugMapMode currentMapMode = DebugMapMode::NONE;
GLuint mapTexture = 0;
frame mapFrame;
public:
planetSimUI() {
cam.origin = v3(4000, 4000, 4000);
cam.direction = (v3(0,0,0) - cam.origin).normalized();
cam.up = v3(0,1,0);
cam.fov = 60;
cam.rotationSpeed = M_1_PI;
}
~planetSimUI() {
if (textu != 0) {
glDeleteTextures(1, &textu);
}
if (mapTexture != 0) {
glDeleteTextures(1, &mapTexture);
}
sim.grid.clear();
}
void renderUI(GLFWwindow* window) {
handleCameraControls(window);
ImGui::Begin("Planet Simulation");
if (ImGui::BeginTable("MainLayout", 2, ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersOuter)) {
ImGui::TableSetupColumn("Controls", ImGuiTableColumnFlags_WidthStretch, 0.3f);
ImGui::TableSetupColumn("Preview", ImGuiTableColumnFlags_WidthStretch, 0.7f);
ImGui::TableNextColumn();
renderControlsPanel();
ImGui::TableNextColumn();
renderPreviewPanel();
ImGui::EndTable();
}
ImGui::End();
}
void handleCameraControls(GLFWwindow* window) {
if (orbitEquator) {
angle += cam.rotationSpeed * deltaTime * ω;
cam.origin[0] = sim.config.center[0] + rotationRadius * cosf(angle);
cam.origin[1] = sim.config.center[1];
cam.origin[2] = sim.config.center[2] + rotationRadius * sinf(angle);
v3 target(sim.config.center);
cam.direction = (target - cam.origin).normalized();
}
glfwPollEvents();
for (int i = GLFW_KEY_SPACE; i <= GLFW_KEY_LAST; i++) {
keyStates[i] = (glfwGetKey(window, i) == GLFW_PRESS);
}
if (keyStates[GLFW_KEY_W]) cam.moveForward(deltaTime);
if (keyStates[GLFW_KEY_S]) cam.moveBackward(deltaTime);
if (keyStates[GLFW_KEY_A]) cam.moveLeft(deltaTime);
if (keyStates[GLFW_KEY_D]) cam.moveRight(deltaTime);
if (keyStates[GLFW_KEY_Z]) cam.moveUp(deltaTime);
if (keyStates[GLFW_KEY_X]) cam.moveDown(deltaTime);
if (keyStates[GLFW_KEY_Q]) cam.rotateYaw(deltaTime);
if (keyStates[GLFW_KEY_R]) cam.rotateYaw(-deltaTime);
}
void renderControlsPanel() {
ImGui::BeginChild("ControlsScroll", ImVec2(0, 0), true);
if (ImGui::CollapsingHeader("Base Configuration", ImGuiTreeNodeFlags_DefaultOpen)) {
ImGui::DragFloat("Radius", &sim.config.radius, 1.0f, 10.0f, 10000.0f);
ImGui::InputInt("Surface Points", &sim.config.surfacePoints);
ImGui::DragFloat("Voxel Size", &sim.config.voxelSize, 0.1f, 0.1f, 100.0f);
ImGui::ColorEdit3("Base Color", sim.config.color.data());
ImGui::Separator();
if (ImGui::Button("1. Generate Fib Sphere", ImVec2(-1, 40))) {
sim.generateFibSphere();
applyDebugColorMode();
}
ImGui::Text("Current Step: %d", sim.config.currentStep);
ImGui::Text("Nodes: %zu", sim.config.surfaceNodes.size());
ImGui::InputFloat("Noise strength", &sim.config.noiseStrength, 0.01, 1, "%.4f");
}
if (ImGui::CollapsingHeader("Physics Parameters")) {
ImGui::DragFloat("Gravity (G)", &sim.config.G_ATTRACTION, 0.1f);
ImGui::DragFloat("Time Step", &sim.config.TIMESTEP, 0.001f, 0.0001f, 0.1f);
ImGui::DragFloat("Viscosity", &sim.config.dampingFactor, 0.001f, 0.0f, 1.0f);
ImGui::DragFloat("Pressure Stiffness", &sim.config.pressureStiffness, 10.0f);
}
if (ImGui::CollapsingHeader("Tectonic Simulation")) {
ImGui::DragInt("Num Plates", &sim.config.numPlates, 1, 1, 100);
ImGui::DragInt("Smoothing Passes", &sim.config.smoothingPasses, 1, 0, 10);
ImGui::DragFloat("Mountain Height", &sim.config.mountHeight, 1.0f, 0.0f, 1000.0f);
ImGui::DragFloat("Valley Depth", &sim.config.valleyDepth, 1.0f, -1000.0f, 0.0f);
ImGui::DragFloat("Transform Roughness", &sim.config.transformRough, 1.0f, 0.0f, 500.0f);
ImGui::DragInt("Stress Passes", &sim.config.stressPasses, 1, 0, 20);
ImGui::DragFloat("Max Elevation Ratio", &sim.config.maxElevationRatio, 1.0f, 0.0f, 1.0f);
ImGui::Checkbox("Fix Boundaries", &doFixPlates);
ImGui::Checkbox("use Cellular", &platesUseCellular);
if (ImGui::Button("2. Simulate Tectonics", ImVec2(-1, 40))) {
simulateTectonics();
}
}
if (ImGui::CollapsingHeader("Celestial Bodies")) {
///TODO: add controls for moon, star.
if (ImGui::Button("Add Star", ImVec2(-1, 40))) {
sim.addStar();
}
}
if (ImGui::CollapsingHeader("Fillings")) {
if (ImGui::Button("Interpolate surface", ImVec2(-1, 40))) {
interpolateSurface();
}
if (ImGui::Button("Fill Planet", ImVec2(-1, 40))) {
fillPlanet();
}
}
if (ImGui::CollapsingHeader("Debug Views")) {
ImGui::Text("3D Planet Color Mode:");
bool colorChanged = false;
if (ImGui::RadioButton("Base Color", currentColorMode == DebugColorMode::BASE)) {
currentColorMode = DebugColorMode::BASE;
colorChanged = true;
}
ImGui::SameLine();
if (ImGui::RadioButton("Plates", currentColorMode == DebugColorMode::PLATES)) {
currentColorMode = DebugColorMode::PLATES;
colorChanged = true;
}
if (ImGui::RadioButton("Noise", currentColorMode == DebugColorMode::NOISE)) {
currentColorMode = DebugColorMode::NOISE;
colorChanged = true;
}
ImGui::SameLine();
if (ImGui::RadioButton("Reserved", currentColorMode == DebugColorMode::RESERVED)) {
currentColorMode = DebugColorMode::RESERVED;
colorChanged = true;
}
if (colorChanged) {
applyDebugColorMode();
}
ImGui::Separator();
ImGui::Text("2D Height Map Mode:");
bool mapChanged = false;
if (ImGui::RadioButton("None", currentMapMode == DebugMapMode::NONE)) {
currentMapMode = DebugMapMode::NONE;
mapChanged = true;
}
ImGui::SameLine();
if (ImGui::RadioButton("Base Pos", currentMapMode == DebugMapMode::BASE)) {
currentMapMode = DebugMapMode::BASE;
mapChanged = true;
}
ImGui::SameLine();
if (ImGui::RadioButton("Noise Pos", currentMapMode == DebugMapMode::NOISE)) {
currentMapMode = DebugMapMode::NOISE;
mapChanged = true;
}
if (!tectonicGenned) ImGui::BeginDisabled();
ImGui::SameLine();
if (ImGui::RadioButton("Tectonic Pos", currentMapMode == DebugMapMode::TECTONIC)) {
currentMapMode = DebugMapMode::TECTONIC;
mapChanged = true;
}
if (ImGui::RadioButton("Tectonic Color", currentMapMode == DebugMapMode::TECTONICCOLOR)) {
currentMapMode = DebugMapMode::TECTONICCOLOR;
mapChanged = true;
}
ImGui::SameLine();
if (!tectonicGenned) ImGui::EndDisabled();
if (ImGui::RadioButton("Current Pos", currentMapMode == DebugMapMode::CURRENT)) {
currentMapMode = DebugMapMode::CURRENT;
mapChanged = true;
}
if (ImGui::Button("Refresh Map", ImVec2(-1, 24))) {
mapChanged = true;
generateDebugMap(currentMapMode);
}
if (mapChanged && currentMapMode != DebugMapMode::NONE) {
generateDebugMap(currentMapMode);
}
if (currentMapMode != DebugMapMode::NONE && mapTexture != 0) {
float availWidth = ImGui::GetContentRegionAvail().x;
ImGui::Image((void*)(intptr_t)mapTexture, ImVec2(availWidth, availWidth * 0.5f));
}
}
if (ImGui::CollapsingHeader("Camera Controls", ImGuiTreeNodeFlags_DefaultOpen)) {
ImGui::DragFloat3("Origin", cam.origin.data());
ImGui::DragFloat3("Direction", cam.direction.data(), 0.0001f, -1.0f, 1.0f);
ImGui::DragFloat("Movement Speed", &cam.movementSpeed, 0.1f, 1.0f, 500.0f);
ImGui::DragFloat("Rotation Speed", &cam.rotationSpeed, M_1_PI, M_1_PI, M_PI);
ImGui::InputFloat("Rotation Distance", &rotationRadius, 10, 100);
ImGui::InputFloat("Max Framerate", &framerate, 1, 10);
ImGui::Checkbox("Use Slower Render", &slowRender);
if (ImGui::Button("Focus on Planet")) {
v3 target(sim.config.center);
v3 newDir = (target - cam.origin).normalized();
cam.direction = newDir;
}
if (ImGui::Button(orbitEquator ? "Stop Equator" : "Orbit Equator")) orbitEquator = !orbitEquator;
}
updateStatsCache();
ImGui::TextUnformatted(cachedStats.c_str());
ImGui::EndChild();
}
void renderPreviewPanel() {
ImGui::BeginChild("PreviewChild", ImVec2(0, 0), true, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
livePreview();
if (textureInitialized) {
float aspect = (float)currentPreviewFrame.getWidth() / (float)currentPreviewFrame.getHeight();
float availWidth = ImGui::GetContentRegionAvail().x;
ImGui::Image((void*)(intptr_t)textu, ImVec2(availWidth, availWidth / aspect));
}
ImGui::EndChild();
}
void applyDebugColorMode() {
if (sim.config.surfaceNodes.empty()) return;
float minNoise = std::numeric_limits<float>::max();
float maxNoise = std::numeric_limits<float>::lowest();
int minSub = std::numeric_limits<int>::max();
int maxSub = std::numeric_limits<int>::lowest();
for (const auto& p : sim.config.surfaceNodes) {
if (p.noiseDisplacement < minNoise) minNoise = p.noiseDisplacement;
if (p.noiseDisplacement > maxNoise) maxNoise = p.noiseDisplacement;
}
int snf = 0;
int inf = 0;
for (auto& p : sim.config.surfaceNodes) {
v3 color = p.originColor.cast<float>();
switch (currentColorMode) {
case DebugColorMode::PLATES:
if (p.plateID != -1 && p.plateID < sim.plates.size()) {
color = sim.plates[p.plateID].debugColor;
} else {
color = v3(0.5f, 0.5f, 0.5f);
}
break;
case DebugColorMode::NOISE: {
float t = 0.5f;
if (maxNoise > minNoise) t = (p.noiseDisplacement - minNoise) / (maxNoise - minNoise);
color = v3(t, t, t);
break;
}
case DebugColorMode::BASE:
default:
color = p.originColor.cast<float>();
break;
}
if (!sim.grid.setColor(p.currentPos, color)) {
snf++;
}
// sim.grid.update(p.currentPos, p.currentPos, p, true, color, sim.config.voxelSize, true, -2, false, 0.0f, 0.0f, 0.0f);
}
for (auto& p : sim.config.interpolatedNodes) {
v3 color = p.originColor.cast<float>();
switch (currentColorMode) {
case DebugColorMode::PLATES:
if (p.plateID != -1 && p.plateID < sim.plates.size()) {
color = sim.plates[p.plateID].debugColor;
} else {
color = v3(0.5f, 0.5f, 0.5f);
}
break;
case DebugColorMode::NOISE: {
float t = 0.5f;
if (maxNoise > minNoise) t = (p.noiseDisplacement - minNoise) / (maxNoise - minNoise);
color = v3(t, t, t);
break;
}
case DebugColorMode::BASE:
default:
color = p.originColor.cast<float>();
break;
}
if (!sim.grid.setColor(p.currentPos, color)) {
inf++;
}
// sim.grid.update(p.currentPos, p.currentPos, p, true, color, sim.config.voxelSize, true, -2, false, 0.0f, 0.0f, 0.0f);
}
if (snf > 0 || inf > 0) {
std::cout << snf << " original nodes failed to set" << std::endl;
std::cout << inf << " interpolated nodes failed to set" << std::endl;
}
}
void generateDebugMap(DebugMapMode mode) {
if (mode == DebugMapMode::NONE || sim.config.surfaceNodes.empty()) return;
int w = 512;
int h = 348;
std::vector<float> depths(w * h, -1.0f);
float minD = std::numeric_limits<float>::max();
float maxD = std::numeric_limits<float>::lowest();
for (const auto& p : sim.config.surfaceNodes) {
v3 pos;
switch(mode) {
case DebugMapMode::BASE:
pos = p.altPos->originalPos.cast<float>();
break;
case DebugMapMode::NOISE:
pos = p.altPos->noisePos.cast<float>();
break;
case DebugMapMode::TECTONIC:
pos = p.altPos->tectonicPos.cast<float>();
break;
case DebugMapMode::CURRENT:
default:
pos = p.currentPos;
break;
}
float d = pos.norm();
if (d < minD) minD = d;
if (d > maxD) maxD = d;
}
for (const auto& p : sim.config.surfaceNodes) {
v3 pos;
switch(mode) {
case DebugMapMode::BASE:
pos = p.altPos->originalPos.cast<float>();
break;
case DebugMapMode::NOISE:
pos = p.altPos->noisePos.cast<float>();
break;
case DebugMapMode::TECTONIC:
pos = p.altPos->tectonicPos.cast<float>();
break;
case DebugMapMode::TECTONICCOLOR:
pos = sim.plates[p.plateID].debugColor;
break;
case DebugMapMode::CURRENT:
default:
pos = p.currentPos;
break;
}
float d = pos.norm();
v3 n = p.altPos->originalPos.cast<float>().normalized();
float u = 0.5f + std::atan2(n.z(), n.x()) / (2.0f * static_cast<float>(M_PI));
float v = 0.5f - std::asin(n.y()) / static_cast<float>(M_PI);
int px = std::clamp(static_cast<int>(u * w), 0, w - 1);
int py = std::clamp(static_cast<int>(v * h), 0, h - 1);
float normalizedD = (maxD > minD) ? (d - minD) / (maxD - minD) : 0.5f;
for (int dy = -1; dy <= 1; dy++) {
for (int dx = -1; dx <= 1; dx++) {
int nx = px + dx;
int ny = py + dy;
if (nx < 0) nx += w;
if (nx >= w) nx -= w;
if (ny >= 0 && ny < h) {
int idx = ny * w + nx;
if (depths[idx] < 0.0f || normalizedD > depths[idx]) {
depths[idx] = normalizedD;
}
}
}
}
}
for (int i = 0; i < w * h; i++) {
if (depths[i] < 0.0f) depths[i] = 0.0f;
}
std::vector<uint8_t> pixels(w * h * 3);
for (int i = 0; i < w * h; i++) {
uint8_t val = static_cast<uint8_t>(depths[i] * 255.0f);
pixels[i * 3 + 0] = val;
pixels[i * 3 + 1] = val;
pixels[i * 3 + 2] = val;
}
mapFrame = frame(w, h, frame::colormap::RGB);
mapFrame.setData(pixels);
if (mapTexture == 0) {
glGenTextures(1, &mapTexture);
}
glBindTexture(GL_TEXTURE_2D, mapTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, mapFrame.getData().data());
}
void applyNoise(const NoisePreviewState& noiseState) {
TIME_FUNCTION;
auto triplanarNoise = [&](const Eigen::Vector3f& pos) -> float {
PNoise2 gen(noiseState.masterSeed);
Eigen::Vector3f n = pos.normalized();
Eigen::Vector3f blend = n.cwiseAbs();
float sum = blend.x() + blend.y() + blend.z();
blend /= sum;
Eigen::Vector3f offsetPos = pos + Eigen::Vector3f(noiseState.offset[0], noiseState.offset[1], 0.0f);
float vXY = sim.evaluate2DStack(Eigen::Vector2f(offsetPos.x(), offsetPos.y()), noiseState, gen);
float vXZ = sim.evaluate2DStack(Eigen::Vector2f(offsetPos.x(), offsetPos.z()), noiseState, gen);
float vYZ = sim.evaluate2DStack(Eigen::Vector2f(offsetPos.y(), offsetPos.z()), noiseState, gen);
// Blend results
return vYZ * blend.x() + vXZ * blend.y() + vXY * blend.z();
};
sim._applyNoise(triplanarNoise);
applyDebugColorMode();
}
void livePreview() {
std::lock_guard<std::mutex> lock(PreviewMutex);
updatePreview = true;
sim.grid.setLODMinDistance(lodDist);
sim.grid.setLODFalloff(lodDropoff);
sim.grid.setMaxDistance(maxViewDistance);
float invFrameRate = 1 / framerate;
if (slowRender) {
currentPreviewFrame = sim.grid.renderFrameTimed(cam, outHeight, outWidth, frame::colormap::RGB, invFrameRate, reflectCount, globalIllumination, useLod);
} else {
currentPreviewFrame = sim.grid.fastRenderFrame(cam, outHeight, outWidth, frame::colormap::RGB);
}
if (textu == 0) {
glGenTextures(1, &textu);
}
glBindTexture(GL_TEXTURE_2D, textu);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, currentPreviewFrame.getWidth(), currentPreviewFrame.getHeight(),
0, GL_RGB, GL_UNSIGNED_BYTE, currentPreviewFrame.getData().data());
updatePreview = false;
textureInitialized = true;
}
void resetView() {
cam.origin = Vector3f(sim.config.gridSizeCube, sim.config.gridSizeCube, sim.config.gridSizeCube);
Vector3f center(sim.config.gridSizeCube / 2.0f, sim.config.gridSizeCube / 2.0f, sim.config.gridSizeCube / 2.0f);
cam.lookAt(center);
}
void simulateTectonics() {
currentColorMode = DebugColorMode::PLATES;
sim.assignSeeds();
sim.buildAdjacencyList();
if (platesUseCellular) {
sim.growPlatesCellular();
} else sim.growPlatesRandom();
if (doFixPlates) sim.fixBoundaries();
sim.extraplateste();
sim.boundaryStress();
sim.finalizeApplyResults();
applyDebugColorMode();
tectonicGenned = true;
if(currentMapMode != DebugMapMode::NONE) generateDebugMap(currentMapMode);
}
void interpolateSurface() {
sim.interpolateSurface();
applyDebugColorMode();
}
void fillPlanet() {
sim.fillPlanet();
}
void updateStatsCache() {
std::stringstream gridstats;
sim.grid.printStats(gridstats);
cachedStats = gridstats.str();
lastStatsUpdate = std::chrono::steady_clock::now();
statsNeedUpdate = false;
}
};
#endif

133
tests/ptest.cpp Normal file
View File

@@ -0,0 +1,133 @@
#include <iostream>
#include <vector>
#include <string>
#include <GLFW/glfw3.h>
#include "imgui.h"
#include "imgui_impl_glfw.h"
#include "imgui_impl_opengl3.h"
#include "../util/noise/pnoise.cpp"
#include "planet.cpp"
#include "../util/basicdefines.hpp"
void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
glViewport(0, 0, width, height);
}
static void glfw_error_callback(int error, const char* description)
{
fprintf(stderr, "GLFW Error %d: %s\n", error, description);
}
int main() {
glfwSetErrorCallback(glfw_error_callback);
if (!glfwInit())
return -1;
#if defined(IMGUI_IMPL_OPENGL_ES2)
// GL ES 2.0 + GLSL 100 (WebGL 1.0)
const char* glsl_version = "#version 100";
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
#elif defined(IMGUI_IMPL_OPENGL_ES3)
// GL ES 3.0 + GLSL 300 es (WebGL 2.0)
const char* glsl_version = "#version 300 es";
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
#elif defined(__APPLE__)
// GL 3.2 + GLSL 150
const char* glsl_version = "#version 150";
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required on Mac
#else
// GL 3.0 + GLSL 130
const char* glsl_version = "#version 130";
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
//glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only
//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // 3.0+ only
#endif
bool application_not_closed = true;
GLFWwindow* window = glfwCreateWindow((int)(1280), (int)(800), "StupidSim", nullptr, nullptr);
if (window == nullptr) {
glfwTerminate();
return 1;
}
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
(void)io;
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
ImGui::StyleColorsDark();
ImGuiStyle& style = ImGui::GetStyle();
ImGui_ImplGlfw_InitForOpenGL(window, true);
#ifdef __EMSCRIPTEN__
ImGui_ImplGlfw_InstallEmscriptenCallbacks(window, "#canvas");
#endif
ImGui_ImplOpenGL3_Init(glsl_version);
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
planetSimUI planetApp;
NoisePreviewState noiseState;
if (noiseState.layers.empty()) {
NoiseLayer defaultLayer;
strcpy(defaultLayer.name, "Base Terrain");
defaultLayer.type = NoiseType::Fractal;
noiseState.layers.push_back(defaultLayer);
}
updateNoiseTexture(noiseState);
while (!glfwWindowShouldClose(window)) {
glfwPollEvents();
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
ImGui::GetMainViewport();
drawNoiseLab(noiseState);
planetApp.renderUI(window);
ImGui::Begin("Integration Control");
ImGui::Text("Bridge: Noise Lab -> Planet Sim");
ImGui::Separator();
ImGui::TextColored(ImVec4(0.5f, 0.8f, 1.0f, 1.0f), "Current Noise Layers: %zu", noiseState.layers.size());
if (ImGui::Button("APPLY CURRENT NOISE TO PLANET", ImVec2(-1, 50))) {
planetApp.applyNoise(noiseState);
}
ImGui::End();
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
glfwSwapBuffers(window);
}
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
glfwDestroyWindow(window);
glfwTerminate();
FunctionTimer::printStats(FunctionTimer::Mode::ENHANCED);
return 0;
}

View File

@@ -27,42 +27,24 @@ constexpr int Dim2 = 2;
template<typename T>
class Grid2 {
public:
using PointType = Eigen::Matrix<float, Dim2, 1>; // Eigen::Vector2f
using PointType = Eigen::Matrix<float, Dim2, 1>;
using BoundingBox = std::pair<PointType, PointType>;
// Shape for 2D is usually a Circle or a Square (AABB)
enum class Shape {
CIRCLE,
SQUARE
};
struct NodeData {
T data;
PointType position;
int objectId;
bool active;
bool visible;
float size; // Radius or half-width
Eigen::Vector4f color; // RGBA
// Physics properties
float temperature;
float conductivity;
float specific_heat;
float density;
float next_temperature; // For double-buffering simulation
Shape shape;
float size;
Eigen::Vector4f color;
NodeData(const T& data, const PointType& pos, bool visible, Eigen::Vector4f color, float size = 1.0f,
bool active = true, int objectId = -1, Shape shape = Shape::SQUARE)
: data(data), position(pos), objectId(objectId), active(active), visible(visible),
color(color), size(size), shape(shape),
temperature(0.0f), conductivity(1.0f), specific_heat(1.0f), density(1.0f), next_temperature(0.0f) {}
color(color), size(size) {}
NodeData() : objectId(-1), active(false), visible(false), size(0.0f),
color(0,0,0,0), shape(Shape::SQUARE),
temperature(0.0f), conductivity(1.0f), specific_heat(1.0f), density(1.0f), next_temperature(0.0f) {}
NodeData() : objectId(-1), active(false), visible(false), size(0.0f), color(0,0,0,0) {}
// Helper for Square bounds
BoundingBox getSquareBounds() const {
@@ -74,7 +56,7 @@ public:
struct QuadNode {
BoundingBox bounds;
std::vector<std::shared_ptr<NodeData>> points;
std::array<std::unique_ptr<QuadNode>, 4> children; // 4 quadrants
std::array<std::unique_ptr<QuadNode>, 4> children;
PointType center;
bool isLeaf;
@@ -106,35 +88,19 @@ private:
Eigen::Vector4f backgroundColor_ = {0.0f, 0.0f, 0.0f, 0.0f};
PNoise2 noisegen;
// Determine quadrant: 0:SW, 1:SE, 2:NW, 3:NE
uint8_t getQuadrant(const PointType& point, const PointType& center) const {
uint8_t quad = 0;
if (point.x() >= center.x()) quad |= 1; // Right
if (point.y() >= center.y()) quad |= 2; // Top
return quad;
return (point.x() >= center.x()) | ((point.y() >= center.y()) << 1);
}
BoundingBox createChildBounds(const QuadNode* node, uint8_t quad) const {
PointType childMin, childMax;
PointType center = node->center;
// X axis
if (quad & 1) { // Right
childMin.x() = center.x();
childMax.x() = node->bounds.second.x();
} else { // Left
childMin.x() = node->bounds.first.x();
childMax.x() = center.x();
}
childMin[0] = (quad & 1) ? center[0] : node->bounds.first[0];
childMax[0] = (quad & 1) ? node->bounds.second[0] : center[0];
// Y axis
if (quad & 2) { // Top
childMin.y() = center.y();
childMax.y() = node->bounds.second.y();
} else { // Bottom
childMin.y() = node->bounds.first.y();
childMax.y() = center.y();
}
childMin[1] = (quad & 2) ? center[1] : node->bounds.first[1];
childMax[1] = (quad & 2) ? node->bounds.second[1] : center[1];
return {childMin, childMax};
}

File diff suppressed because it is too large Load Diff

93
util/jsonhelper.hpp Normal file
View File

@@ -0,0 +1,93 @@
#ifndef JSONHELPER_HPP
#define JSONHELPER_HPP
#include <string>
#include <vector>
#include <cctype>
namespace JsonHelper {
// Helper to get string value between quotes
inline std::string parseString(const std::string& json, const std::string& key) {
size_t pos = json.find("\"" + key + "\"");
if (pos == std::string::npos) return "";
pos = json.find(":", pos);
if (pos == std::string::npos) return "";
size_t start = json.find("\"", pos);
if (start == std::string::npos) return "";
size_t end = json.find("\"", start + 1);
if (end == std::string::npos) return "";
return json.substr(start + 1, end - start - 1);
}
// Helper to get raw non-string value (int, float, bool)
inline std::string parseRaw(const std::string& json, const std::string& key) {
size_t pos = json.find("\"" + key + "\"");
if (pos == std::string::npos) return "";
pos = json.find(":", pos);
if (pos == std::string::npos) return "";
pos++; // skip ':'
while (pos < json.length() && std::isspace(json[pos])) pos++;
size_t end = pos;
while (end < json.length() && json[end] != ',' && json[end] != '}' && json[end] != ']' && !std::isspace(json[end])) end++;
return json.substr(pos, end - pos);
}
inline int parseInt(const std::string& json, const std::string& key, int defaultVal = 0) {
std::string raw = parseRaw(json, key);
if (raw.empty()) return defaultVal;
try { return std::stoi(raw); } catch(...) { return defaultVal; }
}
inline float parseFloat(const std::string& json, const std::string& key, float defaultVal = 0.0f) {
std::string raw = parseRaw(json, key);
if (raw.empty()) return defaultVal;
try { return std::stof(raw); } catch(...) { return defaultVal; }
}
inline bool parseBool(const std::string& json, const std::string& key, bool defaultVal = false) {
std::string raw = parseRaw(json, key);
if (raw.empty()) return defaultVal;
return raw == "true" || raw == "1";
}
// Helper to extract JSON objects out of a JSON array
inline std::vector<std::string> parseArray(const std::string& json, const std::string& key) {
std::vector<std::string> items;
size_t pos = json.find("\"" + key + "\"");
if (pos == std::string::npos) return items;
pos = json.find(":", pos);
if (pos == std::string::npos) return items;
pos = json.find("[", pos);
if (pos == std::string::npos) return items;
int depth = 0;
size_t start = 0;
bool inString = false;
for (size_t i = pos + 1; i < json.length(); ++i) {
if (json[i] == '"' && (i == 0 || json[i-1] != '\\')) {
inString = !inString;
}
if (!inString) {
if (json[i] == '{') {
if (depth == 0) start = i;
depth++;
} else if (json[i] == '}') {
depth--;
if (depth == 0) {
items.push_back(json.substr(start, i - start + 1));
}
} else if (json[i] == ']') {
if (depth == 0) break;
}
}
}
return items;
}
}
#endif

View File

@@ -6,8 +6,11 @@
#include <cstring>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <sstream>
#include "./pnoise2.hpp"
#include "../jsonhelper.hpp"
#include "../timing_decorator.hpp"
#include "../../imgui/imgui.h"
#include <GLFW/glfw3.h>
@@ -194,11 +197,94 @@ inline void updateNoiseTexture(NoisePreviewState& state) {
state.needsUpdate = false;
}
inline void saveNoiseState(const NoisePreviewState& state, const std::string& filename) {
std::ofstream out(filename);
if (!out) return;
out << "{\n";
out << " \"masterSeed\": " << state.masterSeed << ",\n";
out << " \"offsetX\": " << state.offset[0] << ",\n";
out << " \"offsetY\": " << state.offset[1] << ",\n";
out << " \"layers\": [\n";
for (size_t i = 0; i < state.layers.size(); ++i) {
const auto& l = state.layers[i];
out << " {\n";
out << " \"enabled\": " << (l.enabled ? "true" : "false") << ",\n";
out << " \"name\": \"" << l.name << "\",\n";
out << " \"type\": " << (int)l.type << ",\n";
out << " \"blend\": " << (int)l.blend << ",\n";
out << " \"seedOffset\": " << l.seedOffset << ",\n";
out << " \"scale\": " << l.scale << ",\n";
out << " \"strength\": " << l.strength << ",\n";
out << " \"octaves\": " << l.octaves << ",\n";
out << " \"persistence\": " << l.persistence << ",\n";
out << " \"lacunarity\": " << l.lacunarity << ",\n";
out << " \"ridgeOffset\": " << l.ridgeOffset << "\n";
out << " }" << (i < state.layers.size() - 1 ? "," : "") << "\n";
}
out << " ]\n";
out << "}\n";
}
inline void loadNoiseState(NoisePreviewState& state, const std::string& filename) {
std::ifstream in(filename);
if (!in) return;
std::stringstream buffer;
buffer << in.rdbuf();
std::string json = buffer.str();
state.masterSeed = JsonHelper::parseInt(json, "masterSeed", 1337);
state.offset[0] = JsonHelper::parseFloat(json, "offsetX", 0.0f);
state.offset[1] = JsonHelper::parseFloat(json, "offsetY", 0.0f);
auto layerStrs = JsonHelper::parseArray(json, "layers");
state.layers.clear();
for (const auto& lStr : layerStrs) {
NoiseLayer l;
l.enabled = JsonHelper::parseBool(lStr, "enabled", true);
std::string name = JsonHelper::parseString(lStr, "name");
if (!name.empty()) {
std::strncpy(l.name, name.c_str(), 31);
l.name[31] = '\0';
}
l.type = (NoiseType)JsonHelper::parseInt(lStr, "type", 0);
l.blend = (BlendMode)JsonHelper::parseInt(lStr, "blend", 0);
l.seedOffset = JsonHelper::parseInt(lStr, "seedOffset", 0);
l.scale = JsonHelper::parseFloat(lStr, "scale", 0.02f);
l.strength = JsonHelper::parseFloat(lStr, "strength", 1.0f);
l.octaves = JsonHelper::parseInt(lStr, "octaves", 4);
l.persistence = JsonHelper::parseFloat(lStr, "persistence", 0.5f);
l.lacunarity = JsonHelper::parseFloat(lStr, "lacunarity", 2.0f);
l.ridgeOffset = JsonHelper::parseFloat(lStr, "ridgeOffset", 1.0f);
state.layers.push_back(l);
}
state.needsUpdate = true;
}
inline void drawNoiseLab(NoisePreviewState& noiseState) {
ImGui::Begin("2D Noise Lab");
// Master Controls
bool changed = false;
static char filenameBuffer[128] = "output/noise_preset.json";
ImGui::InputText("File", filenameBuffer, sizeof(filenameBuffer));
ImGui::SameLine();
if (ImGui::Button("Save JSON")) {
saveNoiseState(noiseState, filenameBuffer);
}
ImGui::SameLine();
if (ImGui::Button("Load JSON")) {
loadNoiseState(noiseState, filenameBuffer);
changed = true;
}
ImGui::Separator();
changed |= ImGui::InputInt("Master Seed", &noiseState.masterSeed);
changed |= ImGui::DragFloat2("Pan Offset", noiseState.offset, 1.0f);
@@ -254,7 +340,7 @@ inline void drawNoiseLab(NoisePreviewState& noiseState) {
}
if (open) {
ImGui::Checkbox("##enabled", &layer.enabled);
if (ImGui::Checkbox("##enabled", &layer.enabled)) changed = true;
ImGui::SameLine();
ImGui::InputText("##name", layer.name, 32);

View File

@@ -9,6 +9,7 @@
#include <limits>
#include "../../eigen/Eigen/Core"
#include "../timing_decorator.hpp"
#include "../basicdefines.hpp"
class PNoise2 {
private:

383
util/sim/elementcontent.hpp Normal file
View File

@@ -0,0 +1,383 @@
#ifndef ELEMENTS
#define ELEMENTS
#include <array>
struct BaseElementProps {
float density; // kg/m^3
float meltingPoint; // Kelvin
float boilingPoint; // Kelvin
float specificHeat; // J/(kg*K)
float electronegativity; // Pauling scale
};
static const std::array<BaseElementProps, 118> ELEMENT_DB = {{
// 1: Hydrogen
{0.08988f, 14.01f, 20.28f, 14304.0f, 2.20f},
// 2: Helium
{0.1785f, 0.95f, 4.22f, 5193.0f, 0.0f}, // No electronegativity, using 0
// 3: Lithium
{534.0f, 453.69f, 1560.0f, 3582.0f, 0.98f},
// 4: Beryllium
{1850.0f, 1560.0f, 2742.0f, 1825.0f, 1.57f},
// 5: Boron
{2340.0f, 2349.0f, 4200.0f, 1026.0f, 2.04f},
// 6: Carbon
{2267.0f, 4000.0f, 4300.0f, 709.0f, 2.55f},
// 7: Nitrogen
{1.2506f, 63.15f, 77.36f, 1040.0f, 3.04f},
// 8: Oxygen
{1.429f, 54.36f, 90.2f, 918.0f, 3.44f},
// 9: Fluorine
{1.696f, 53.53f, 85.03f, 824.0f, 3.98f},
// 10: Neon
{0.9002f, 24.56f, 27.07f, 1030.0f, 0.0f}, // No electronegativity
// 11: Sodium
{968.0f, 370.87f, 1156.0f, 1228.0f, 0.93f},
// 12: Magnesium
{1738.0f, 923.0f, 1363.0f, 1023.0f, 1.31f},
// 13: Aluminium
{2700.0f, 933.47f, 2792.0f, 897.0f, 1.61f},
// 14: Silicon
{2329.0f, 1687.0f, 3538.0f, 705.0f, 1.9f},
// 15: Phosphorus
{1823.0f, 317.3f, 550.0f, 769.0f, 2.19f},
// 16: Sulfur
{2070.0f, 388.36f, 717.87f, 710.0f, 2.58f},
// 17: Chlorine
{3.2f, 171.6f, 239.11f, 479.0f, 3.16f},
// 18: Argon
{1.784f, 83.8f, 87.3f, 520.0f, 0.0f}, // No electronegativity
// 19: Potassium
{890.0f, 336.53f, 1032.0f, 757.0f, 0.82f},
// 20: Calcium
{1550.0f, 1115.0f, 1757.0f, 647.0f, 1.0f},
// 21: Scandium
{2985.0f, 1814.0f, 3109.0f, 568.0f, 1.36f},
// 22: Titanium
{4506.0f, 1941.0f, 3560.0f, 523.0f, 1.54f},
// 23: Vanadium
{6110.0f, 2183.0f, 3680.0f, 489.0f, 1.63f},
// 24: Chromium
{7150.0f, 2180.0f, 2944.0f, 449.0f, 1.66f},
// 25: Manganese
{7210.0f, 1519.0f, 2334.0f, 479.0f, 1.55f},
// 26: Iron
{7874.0f, 1811.0f, 3134.0f, 449.0f, 1.83f},
// 27: Cobalt
{8900.0f, 1768.0f, 3200.0f, 421.0f, 1.88f},
// 28: Nickel
{8908.0f, 1728.0f, 3186.0f, 444.0f, 1.91f},
// 29: Copper
{8960.0f, 1357.77f, 2835.0f, 385.0f, 1.9f},
// 30: Zinc
{7140.0f, 692.88f, 1180.0f, 388.0f, 1.65f},
// 31: Gallium
{5910.0f, 302.9146f, 2673.0f, 371.0f, 1.81f},
// 32: Germanium
{5323.0f, 1211.4f, 3106.0f, 320.0f, 2.01f},
// 33: Arsenic
{5727.0f, 1090.0f, 887.0f, 329.0f, 2.18f}, // Sublimes at 887K
// 34: Selenium
{4810.0f, 453.0f, 958.0f, 321.0f, 2.55f},
// 35: Bromine
{3102.8f, 265.8f, 332.0f, 474.0f, 2.96f},
// 36: Krypton
{3.749f, 115.79f, 119.93f, 248.0f, 3.0f},
// 37: Rubidium
{1532.0f, 312.46f, 961.0f, 363.0f, 0.82f},
// 38: Strontium
{2640.0f, 1050.0f, 1655.0f, 301.0f, 0.95f},
// 39: Yttrium
{4472.0f, 1799.0f, 3609.0f, 298.0f, 1.22f},
// 40: Zirconium
{6520.0f, 2128.0f, 4682.0f, 278.0f, 1.33f},
// 41: Niobium
{8570.0f, 2750.0f, 5017.0f, 265.0f, 1.6f},
// 42: Molybdenum
{10280.0f, 2896.0f, 4912.0f, 251.0f, 2.16f},
// 43: Technetium
{11000.0f, 2430.0f, 4538.0f, 0.0f, 1.9f}, // No specific heat data
// 44: Ruthenium
{12450.0f, 2607.0f, 4423.0f, 238.0f, 2.2f},
// 45: Rhodium
{12410.0f, 2237.0f, 3968.0f, 243.0f, 2.28f},
// 46: Palladium
{12023.0f, 1828.05f, 3236.0f, 244.0f, 2.2f},
// 47: Silver
{10490.0f, 1234.93f, 2435.0f, 235.0f, 1.93f},
// 48: Cadmium
{8650.0f, 594.22f, 1040.0f, 232.0f, 1.69f},
// 49: Indium
{7310.0f, 429.75f, 2345.0f, 233.0f, 1.78f},
// 50: Tin
{7265.0f, 505.08f, 2875.0f, 228.0f, 1.96f},
// 51: Antimony
{6697.0f, 903.78f, 1860.0f, 207.0f, 2.05f},
// 52: Tellurium
{6240.0f, 722.66f, 1261.0f, 202.0f, 2.1f},
// 53: Iodine
{4933.0f, 386.85f, 457.4f, 214.0f, 2.66f},
// 54: Xenon
{5.894f, 161.4f, 165.03f, 158.0f, 2.6f},
// 55: Caesium
{1930.0f, 301.59f, 944.0f, 242.0f, 0.79f},
// 56: Barium
{3510.0f, 1000.0f, 2170.0f, 204.0f, 0.89f},
// 57: Lanthanum
{6162.0f, 1193.0f, 3737.0f, 195.0f, 1.1f},
// 58: Cerium
{6770.0f, 1068.0f, 3716.0f, 192.0f, 1.12f},
// 59: Praseodymium
{6770.0f, 1208.0f, 3793.0f, 193.0f, 1.13f},
// 60: Neodymium
{7010.0f, 1297.0f, 3347.0f, 190.0f, 1.14f},
// 61: Promethium
{7260.0f, 1315.0f, 3273.0f, 0.0f, 1.13f}, // No specific heat data
// 62: Samarium
{7520.0f, 1345.0f, 2067.0f, 197.0f, 1.17f},
// 63: Europium
{5244.0f, 1099.0f, 1802.0f, 182.0f, 1.2f},
// 64: Gadolinium
{7900.0f, 1585.0f, 3546.0f, 236.0f, 1.2f},
// 65: Terbium
{8230.0f, 1629.0f, 3503.0f, 182.0f, 1.2f},
// 66: Dysprosium
{8540.0f, 1680.0f, 2840.0f, 170.0f, 1.22f},
// 67: Holmium
{8790.0f, 1734.0f, 2993.0f, 165.0f, 1.23f},
// 68: Erbium
{9066.0f, 1802.0f, 3141.0f, 168.0f, 1.24f},
// 69: Thulium
{9320.0f, 1818.0f, 2223.0f, 160.0f, 1.25f},
// 70: Ytterbium
{6900.0f, 1097.0f, 1469.0f, 155.0f, 1.1f},
// 71: Lutetium
{9841.0f, 1925.0f, 3675.0f, 154.0f, 1.27f},
// 72: Hafnium
{13310.0f, 2506.0f, 4876.0f, 144.0f, 1.3f},
// 73: Tantalum
{16690.0f, 3290.0f, 5731.0f, 140.0f, 1.5f},
// 74: Tungsten
{19250.0f, 3695.0f, 6203.0f, 132.0f, 2.36f},
// 75: Rhenium
{21020.0f, 3459.0f, 5869.0f, 137.0f, 1.9f},
// 76: Osmium
{22590.0f, 3306.0f, 5285.0f, 130.0f, 2.2f},
// 77: Iridium
{22560.0f, 2719.0f, 4701.0f, 131.0f, 2.2f},
// 78: Platinum
{21450.0f, 2041.4f, 4098.0f, 133.0f, 2.28f},
// 79: Gold
{19300.0f, 1337.33f, 3129.0f, 129.0f, 2.54f},
// 80: Mercury
{13534.0f, 234.43f, 629.88f, 140.0f, 2.0f},
// 81: Thallium
{11850.0f, 577.0f, 1746.0f, 129.0f, 1.62f},
// 82: Lead
{11340.0f, 600.61f, 2022.0f, 129.0f, 2.33f}, // Using 4+ value
// 83: Bismuth
{9780.0f, 544.7f, 1837.0f, 122.0f, 2.02f},
// 84: Polonium
{9196.0f, 527.0f, 1235.0f, 0.0f, 2.0f}, // No specific heat data
// 85: Astatine
{8930.0f, 575.0f, 610.0f, 0.0f, 2.2f}, // Approx density, no specific heat
// 86: Radon
{9.73f, 202.0f, 211.3f, 94.0f, 2.2f},
// 87: Francium
{2480.0f, 281.0f, 890.0f, 0.0f, 0.79f}, // Approx values
// 88: Radium
{5500.0f, 973.0f, 2010.0f, 94.0f, 0.9f},
// 89: Actinium
{10000.0f, 1323.0f, 3471.0f, 120.0f, 1.1f},
// 90: Thorium
{11700.0f, 2115.0f, 5061.0f, 113.0f, 1.3f},
// 91: Protactinium
{15370.0f, 1841.0f, 4300.0f, 0.0f, 1.5f}, // No specific heat data
// 92: Uranium
{19100.0f, 1405.3f, 4404.0f, 116.0f, 1.38f},
// 93: Neptunium
{20450.0f, 917.0f, 4273.0f, 0.0f, 1.36f}, // No specific heat data
// 94: Plutonium
{19850.0f, 912.5f, 3501.0f, 0.0f, 1.28f}, // No specific heat data
// 95: Americium
{12000.0f, 1449.0f, 2880.0f, 0.0f, 1.13f}, // No specific heat data
// 96: Curium
{13510.0f, 1613.0f, 3383.0f, 0.0f, 1.28f}, // No specific heat data
// 97: Berkelium
{14780.0f, 1259.0f, 2900.0f, 0.0f, 1.3f}, // No specific heat data
// 98: Californium
{15100.0f, 1173.0f, 1743.0f, 0.0f, 1.3f}, // No specific heat data
// 99: Einsteinium
{8840.0f, 1133.0f, 1269.0f, 0.0f, 1.3f}, // No specific heat data
// 100: Fermium
{9700.0f, 1125.0f, 1800.0f, 0.0f, 1.3f}, // Estimated values
// 101: Mendelevium
{10300.0f, 1100.0f, 0.0f, 0.0f, 1.3f}, // Estimated
// 102: Nobelium
{9900.0f, 1100.0f, 0.0f, 0.0f, 1.3f}, // Estimated
// 103: Lawrencium
{14400.0f, 1900.0f, 0.0f, 0.0f, 1.3f}, // Estimated
// 104: Rutherfordium
{17000.0f, 2400.0f, 5800.0f, 0.0f, 0.0f}, // Estimated
// 105: Dubnium
{21600.0f, 0.0f, 0.0f, 0.0f, 0.0f}, // Estimated
// 106: Seaborgium
{23500.0f, 0.0f, 0.0f, 0.0f, 0.0f}, // Estimated
// 107: Bohrium
{26500.0f, 0.0f, 0.0f, 0.0f, 0.0f}, // Estimated
// 108: Hassium
{28000.0f, 0.0f, 0.0f, 0.0f, 0.0f}, // Estimated
// 109: Meitnerium
{27500.0f, 0.0f, 0.0f, 0.0f, 0.0f}, // Estimated
// 110: Darmstadtium
{26500.0f, 0.0f, 0.0f, 0.0f, 0.0f}, // Estimated
// 111: Roentgenium
{23000.0f, 0.0f, 0.0f, 0.0f, 0.0f}, // Estimated
// 112: Copernicium
{14000.0f, 283.0f, 340.0f, 0.0f, 0.0f}, // Estimated
// 113: Nihonium
{16000.0f, 700.0f, 1400.0f, 0.0f, 0.0f}, // Estimated
// 114: Flerovium
{11400.0f, 284.0f, 0.0f, 0.0f, 0.0f}, // Estimated
// 115: Moscovium
{13500.0f, 700.0f, 1400.0f, 0.0f, 0.0f}, // Estimated
// 116: Livermorium
{12900.0f, 700.0f, 1100.0f, 0.0f, 0.0f}, // Estimated
// 117: Tennessine
{7200.0f, 700.0f, 883.0f, 0.0f, 0.0f}, // Estimated
// 118: Oganesson
{7000.0f, 325.0f, 450.0f, 0.0f, 0.0f} // Estimated
}};
struct PointProperties {
float weight = 0.0f; // Total mass
float density = 0.0f; // Mass / Volume
float meltingPoint = 0.0f;
float boilingPoint = 0.0f;
float specificHeat = 0.0f;
float electronegativity = 0.0f;
};
struct elementContent {
float hydrogen = 0.0f;
float helium = 0.0f;
float lithium = 0.0f;
float beryllium = 0.0f;
float boron = 0.0f;
float carbon = 0.0f;
float nitrogen = 0.0f;
float oxygen = 0.0f;
float fluorine = 0.0f;
float neon = 0.0f;
float sodium = 0.0f;
float magnesium = 0.0f;
float aluminum = 0.0f;
float silicon = 0.0f;
float phosporus = 0.0f;
float sulfur = 0.0f;
float chlorine = 0.0f;
float argon = 0.0f;
float potassium = 0.0f;
float calcium = 0.0f;
float scandium = 0.0f;
float titanium = 0.0f;
float vanadium = 0.0f;
float chromium = 0.0f;
float manganese = 0.0f;
float iron = 0.0f;
float cobalt = 0.0f;
float nickel = 0.0f;
float copper = 0.0f;
float zinc = 0.0f;
float gallium = 0.0f;
float germanium = 0.0f;
float arsenic = 0.0f;
float selenium = 0.0f;
float bromine = 0.0f;
float krypton = 0.0f;
float rubidium = 0.0f;
float strontium = 0.0f;
float yttrium = 0.0f;
float zirconium = 0.0f;
float niobium = 0.0f;
float molybdenum = 0.0f;
float technetium = 0.0f;
float ruthenium = 0.0f;
float rhodium = 0.0f;
float palladium = 0.0f;
float silver = 0.0f;
float cadmium = 0.0f;
float indium = 0.0f;
float tin = 0.0f;
float antimony = 0.0f;
float tellurium = 0.0f;
float iodine = 0.0f;
float xenon = 0.0f;
float caesium = 0.0f;
float barium = 0.0f;
float lanthanum = 0.0f;
float cerium = 0.0f;
float praseodymium = 0.0f;
float neodymium = 0.0f;
float promethium = 0.0f;
float samarium = 0.0f;
float europium = 0.0f;
float gadolinium = 0.0f;
float terbium = 0.0f;
float dysprosium = 0.0f;
float holmium = 0.0f;
float erbium = 0.0f;
float thulium = 0.0f;
float ytterbium = 0.0f;
float lutetium = 0.0f;
float hafnium = 0.0f;
float tantalum = 0.0f;
float tungsten = 0.0f;
float rhenium = 0.0f;
float osmium = 0.0f;
float iridium = 0.0f;
float platinum = 0.0f;
float gold = 0.0f;
float mercury = 0.0f;
float thallium = 0.0f;
float lead = 0.0f;
float bismuth = 0.0f;
float polonium = 0.0f;
float astatine = 0.0f;
float radon = 0.0f;
float francium = 0.0f;
float radium = 0.0f;
float actinium = 0.0f;
float thorium = 0.0f;
float protactinium = 0.0f;
float uranium = 0.0f;
float neptunium = 0.0f;
float plutonium = 0.0f;
float americium = 0.0f;
float curium = 0.0f;
float berkelium = 0.0f;
float californium = 0.0f;
float einsteinium = 0.0f;
float fermium = 0.0f;
float mendelevium = 0.0f;
float nobelium = 0.0f;
float lawrencium = 0.0f;
float rutherfordium = 0.0f;
float dubnium = 0.0f;
float seaborgium = 0.0f;
float bohrium = 0.0f;
float hassium = 0.0f;
float meitnerium = 0.0f;
float darmstadtium = 0.0f;
float roentgenium = 0.0f;
float cpernicium = 0.0f;
float nihnium = 0.0f;
float flerovium = 0.0f;
float moscovium = 0.0f;
float livermorium = 0.0f;
float tennessine = 0.0f;
float oganesson = 0.0f;
};
#endif

1026
util/sim/planet.hpp Normal file

File diff suppressed because it is too large Load Diff