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
46 changes: 8 additions & 38 deletions src/data_processing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,43 +129,20 @@ pub fn generate_world_with_options(
let pb_batch_size: u64 = (elements_count as u64 / desired_updates).max(1);
let mut element_counter: u64 = 0;

// Pre-scan 3DMR-tagged elements first; 3DMR wins over Wikidata on conflict.
let three_dmr_prescan = if args.use_3d {
Some(crate::models_3d::three_dmr::prescan(
&elements,
args.rotation,
))
} else {
None
};
let models_3d_pipeline = args
.use_3d
.then(|| crate::models_3d::Models3dPipeline::prescan(&elements, args));
let empty_suppressed: HashSet<(&'static str, u64)> = HashSet::new();
let three_dmr_suppressed: &HashSet<(&'static str, u64)> = three_dmr_prescan
.as_ref()
.map(|p| &p.suppressed_ids)
.unwrap_or(&empty_suppressed);

// Wikidata pre-scan runs after 3DMR's, skipping any element 3DMR already claimed.
let wikidata_prescan = if args.use_3d {
Some(crate::models_3d::wikidata::prescan(
&elements,
three_dmr_suppressed,
args.rotation,
args.scale,
))
} else {
None
};
let wikidata_suppressed: &HashSet<(&'static str, u64)> = wikidata_prescan
let models_3d_suppressed: &HashSet<(&'static str, u64)> = models_3d_pipeline
.as_ref()
.map(|p| &p.suppressed_ids)
.map(|p| p.suppressed())
.unwrap_or(&empty_suppressed);

// Process all elements
for element in elements.into_iter() {
element_counter += 1;
let suppression_key = (element.kind(), element.id());
if three_dmr_suppressed.contains(&suppression_key)
|| wikidata_suppressed.contains(&suppression_key)
if models_3d_suppressed.contains(&suppression_key)
|| outline_suppression.contains(&suppression_key)
{
continue;
Expand Down Expand Up @@ -439,15 +416,8 @@ pub fn generate_world_with_options(
}

// Run after ground generation so anchor Y reflects the final terrain.
if let Some(prescan) = three_dmr_prescan.as_ref() {
if prescan.placement_count() > 0 {
crate::models_3d::three_dmr::place_three_dmr_models(&mut editor, args, prescan);
}
}
if let Some(prescan) = wikidata_prescan.as_ref() {
if prescan.placement_count() > 0 {
crate::models_3d::wikidata::place_wikidata_models(&mut editor, args, prescan);
}
if let Some(p) = models_3d_pipeline.as_ref() {
p.place(&mut editor, args);
}

// Save world
Expand Down
57 changes: 57 additions & 0 deletions src/models_3d/custom/client.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//! Shared HTTP fetch + on-disk cache for Arnis-hosted archetype models.

use reqwest::blocking::ClientBuilder;
use std::fs;
use std::io::Read;
use std::path::PathBuf;
use std::time::Duration;

const CACHE_SUBDIR: &str = "arnis/custom_models";
const REQUEST_TIMEOUT_SECS: u64 = 20;
const MAX_GLB_BYTES: u64 = 16 * 1024 * 1024;

pub(crate) fn cache_root() -> PathBuf {
dirs::cache_dir()
.map(|d| d.join(CACHE_SUBDIR))
.unwrap_or_else(|| PathBuf::from("./.arnis_custom_cache"))
}

pub(super) fn fetch_glb(url: &str, filename: &str) -> Result<Vec<u8>, String> {
let dir = cache_root();
let path = dir.join(filename);
if let Ok(bytes) = fs::read(&path) {
if !bytes.is_empty() {
return Ok(bytes);
}
}

let client = ClientBuilder::new()
.timeout(Duration::from_secs(REQUEST_TIMEOUT_SECS))
.user_agent(concat!(
"Arnis/",
env!("CARGO_PKG_VERSION"),
" (+https://github.com/louis-e/arnis)"
))
.build()
.map_err(|e| e.to_string())?;
let mut resp = client.get(url).send().map_err(|e| e.to_string())?;
if !resp.status().is_success() {
return Err(format!("HTTP {}", resp.status()));
}
if let Some(len) = resp.content_length() {
if len > MAX_GLB_BYTES {
return Err(format!(
"exceeds {MAX_GLB_BYTES}-byte cap (advertised {len})"
));
}
}
let mut buf: Vec<u8> = Vec::new();
let mut taken = (&mut resp).take(MAX_GLB_BYTES + 1);
taken.read_to_end(&mut buf).map_err(|e| e.to_string())?;
if buf.len() as u64 > MAX_GLB_BYTES {
return Err(format!("exceeds {MAX_GLB_BYTES}-byte cap"));
}
let _ = fs::create_dir_all(&dir);
let _ = fs::write(&path, &buf);
Ok(buf)
}
4 changes: 4 additions & 0 deletions src/models_3d/custom/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
//! Arnis-hosted archetype models triggered by OSM tags (stadiums, etc.).

pub(crate) mod client;
pub(crate) mod stadium;
Loading
Loading