Moon surface map
This commit is contained in:
1 parent
0e8134aa59
commit
f8b515e198
36 files changed
+1710
-222
No files matched your search
@@ -10,7 +10,7 @@ use std::time::Instant;
|
||||
use clap::{Args, Parser, Subcommand};
|
||||
use resolved::gpu::AdapterChoice;
|
||||
use resolved::{
|
||||
CameraTier, EarthTexture, Fidelity, Frame, LightingTier, Renderer, RendererOptions,
|
||||
CameraTier, EarthTexture, Fidelity, Frame, LightingTier, MoonTexture, Renderer, RendererOptions,
|
||||
};
|
||||
|
||||
use crate::scene_file::SceneFile;
|
||||
@@ -60,8 +60,8 @@ struct RenderArgs {
|
||||
#[arg(long, value_name = "FRAMES")]
|
||||
timings: Option<usize>,
|
||||
/// Directory of data the tiers need (earth/bmng-2004-MM.jpg from
|
||||
/// scripts/fetch-earth.sh). Without it: RESOLVED_DATA, then ./data, then the
|
||||
/// repository's data/.
|
||||
/// scripts/fetch-earth.sh, moon/wac-hapke-643.png from scripts/fetch-moon.py).
|
||||
/// Without it: RESOLVED_DATA, then ./data, then the repository's data/.
|
||||
#[arg(long, value_name = "DIR")]
|
||||
data: Option<PathBuf>,
|
||||
/// Directory of astrokit's kernels, for scenes given by epoch. Without it:
|
||||
@@ -108,15 +108,28 @@ fn data_directories(explicit: Option<&Path>) -> Vec<PathBuf> {
|
||||
|
||||
/// The Earth image for `month` (1-12), from the first data directory that has it.
|
||||
fn earth_image(data: Option<&Path>, month: u32) -> Result<PathBuf, String> {
|
||||
let name = format!("earth/bmng-2004-{month:02}.jpg");
|
||||
data_file(
|
||||
data,
|
||||
&format!("earth/bmng-2004-{month:02}.jpg"),
|
||||
"fetch-earth.sh",
|
||||
)
|
||||
}
|
||||
|
||||
/// `name` from the first data directory that has it; the error names `script`, which
|
||||
/// makes it.
|
||||
fn data_file(data: Option<&Path>, name: &str, script: &str) -> Result<PathBuf, String> {
|
||||
let tried = data_directories(data);
|
||||
tried.iter().map(|dir| dir.join(&name)).find(|p| p.is_file()).ok_or_else(|| {
|
||||
let tried: Vec<_> = tried.iter().map(|d| d.display().to_string()).collect();
|
||||
format!(
|
||||
"lighting L1 needs {name} (run scripts/fetch-earth.sh, or pass --data DIR); looked in {}",
|
||||
tried.join(", ")
|
||||
)
|
||||
})
|
||||
tried
|
||||
.iter()
|
||||
.map(|dir| dir.join(name))
|
||||
.find(|p| p.is_file())
|
||||
.ok_or_else(|| {
|
||||
let tried: Vec<_> = tried.iter().map(|d| d.display().to_string()).collect();
|
||||
format!(
|
||||
"lighting L1 needs {name} (run scripts/{script}, or pass --data DIR); looked in {}",
|
||||
tried.join(", ")
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn render(args: &RenderArgs) -> Result<(), String> {
|
||||
@@ -141,6 +154,18 @@ fn render(args: &RenderArgs) -> Result<(), String> {
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let moon_texture = if args.lighting >= LightingTier::L1 {
|
||||
let image = data_file(
|
||||
args.data.as_deref(),
|
||||
"moon/wac-hapke-643.png",
|
||||
"fetch-moon.py",
|
||||
)?;
|
||||
Some(Arc::new(
|
||||
MoonTexture::load(&image).map_err(|e| e.to_string())?,
|
||||
))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let texturing = start.elapsed();
|
||||
|
||||
let options = RendererOptions {
|
||||
@@ -155,6 +180,7 @@ fn render(args: &RenderArgs) -> Result<(), String> {
|
||||
camera: args.camera,
|
||||
},
|
||||
earth_texture,
|
||||
moon_texture,
|
||||
appearance: file.appearance(),
|
||||
read_radiance: false,
|
||||
profile: timings.is_some(),
|
||||
@@ -189,11 +215,11 @@ fn render(args: &RenderArgs) -> Result<(), String> {
|
||||
println!("adapter {}", renderer.adapter_info().name);
|
||||
println!("tiers {} {}", args.lighting, args.camera);
|
||||
println!(
|
||||
"setup {:.1} ms (includes the Earth texture's upload)",
|
||||
"setup {:.1} ms (includes the Earth and Moon maps' upload)",
|
||||
setup.as_secs_f64() * 1e3
|
||||
);
|
||||
println!(
|
||||
"earth {:.1} ms (texture decode)",
|
||||
"maps {:.1} ms (Earth and Moon image decode)",
|
||||
texturing.as_secs_f64() * 1e3
|
||||
);
|
||||
println!(
|
||||
|
||||
@@ -33,6 +33,9 @@ pub struct SceneFile {
|
||||
pub moon: Option<[f64; 3]>,
|
||||
/// Earth-fixed to inertial rotation, if not given by `epoch`; identity by default.
|
||||
pub earth_attitude: Option<[f64; 4]>,
|
||||
/// Moon-fixed to inertial rotation, if not given by `epoch`; by default the Moon
|
||||
/// faces Earth (`Scene::moon_facing_earth`, within about 10 degrees).
|
||||
pub moon_attitude: Option<[f64; 4]>,
|
||||
/// Earth's and the Moon's albedo.
|
||||
#[serde(default)]
|
||||
pub appearance: AppearanceFile,
|
||||
@@ -242,8 +245,12 @@ impl SceneFile {
|
||||
#[cfg(feature = "astrokit")]
|
||||
fn bodies(&self, targets: Vec<Target>, kernels: Option<&Path>) -> Result<Scene> {
|
||||
if let Some(epoch) = &self.epoch {
|
||||
if self.sun.is_some() || self.moon.is_some() || self.earth_attitude.is_some() {
|
||||
return Err("give either epoch or sun, moon and earth_attitude, not both".into());
|
||||
if self.sun.is_some()
|
||||
|| self.moon.is_some()
|
||||
|| self.earth_attitude.is_some()
|
||||
|| self.moon_attitude.is_some()
|
||||
{
|
||||
return Err("give either epoch or sun, moon and the attitudes, not both".into());
|
||||
}
|
||||
let epoch: hifitime::Epoch =
|
||||
epoch.parse().map_err(|e| format!("epoch {epoch:?}: {e}"))?;
|
||||
@@ -274,6 +281,11 @@ impl SceneFile {
|
||||
.unwrap_or_else(UnitQuaternion::identity),
|
||||
sun: Vector3::from(sun),
|
||||
moon: Vector3::from(moon),
|
||||
moon_attitude: self
|
||||
.moon_attitude
|
||||
.map(quaternion)
|
||||
.transpose()?
|
||||
.unwrap_or_else(|| Scene::moon_facing_earth(Vector3::from(moon))),
|
||||
targets,
|
||||
})
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user