use crate::map::Map;
use crate::prelude::Vector3;
use crate::vmf::{block_to_solid, ToLower};
use crate::StrType;
use std::borrow::Cow;
use vmf_parser_nom::ast::Vmf;
use super::*;
fn make_shape<'a>(
shape: &str, bounds: &Bounds, sides: u32, mats: [&'a Material<'a>; 6],
options: &'a SolidOptions,
) -> OneOrVec<Solid<'a>> {
let spike_bounds = &bounds;
match shape {
"cube" => OneOrVec::One(cube(bounds, mats[..].try_into().unwrap(), options)),
"wedge" => OneOrVec::One(wedge(bounds, mats[..].try_into().unwrap(), options)),
"spike" => spike(spike_bounds, sides, mats[..].try_into().unwrap(), options),
"cylinder" => cylinder(bounds, sides, mats[..].try_into().unwrap(), options),
"sphere" => sphere(bounds, sides, mats[..].try_into().unwrap(), options),
str => panic!("unkown shape {}", str),
}
}
#[test]
#[ignore]
fn test_frustum_cone() {
let dev_person = Material::new(Cow::Borrowed("DEV/DEV_MEASUREWALL01C"));
let mats = [&dev_person; 3];
let options = &SolidOptions::default().allow_frac();
let mut map = Map::default();
let top = ellipse_verts(Vector3::new(512.0, 512.0, 512.0), 256.0, 256.0, 32, options);
let bottom = ellipse_verts(Vector3::new(0.0, 0.0, 0.0), 1024.0, 512.0, 32, options);
let solid = Solid::new(prism(top, bottom, false, mats, options).collect::<Vec<_>>());
map.add_solid(solid);
let top = ellipse_verts(Vector3::new(0.0, 0.0, 0.0), 1024.0, 512.0, 32, options);
let bottom = ellipse_verts(Vector3::new(512.0, 512.0, -512.0), 256.0, 256.0, 32, options);
let solid = Solid::new(prism(top, bottom, false, mats, options).collect::<Vec<_>>());
map.add_solid(solid);
let top = ellipse_verts(Vector3::new(0.0, 0.0, 512.0), 1024.0, 0.0, 32, options);
let bottom = ellipse_verts(Vector3::new(0.0, 0.0, 0.0), 256.0, 256.0, 32, options);
let solid = Solid::new(prism(top, bottom, false, mats, options).skip(1).collect::<Vec<_>>());
map.add_solid(solid);
let mut map = Map::default();
let top = ellipse_verts(Vector3::new(0.0, 0.0, 512.0), 5120.0, 0.0, 32, options);
let bottom = ellipse_verts(Vector3::new(0.0, 0.0, 0.0), 128.0, 512.0, 32, options);
let solid = Solid::new(prism(top, bottom, false, mats, options).skip(1).collect::<Vec<_>>());
map.add_solid(solid);
write_test_vmf(map.to_lower());
panic!("worked")
}
#[test]
#[ignore]
fn frustum_cone_doc_test() {
let dev_person = Material::new(Cow::Borrowed("DEV/DEV_MEASUREWALL01C"));
let mats = [&dev_person; 3];
let options = &SolidOptions::default();
let mut map = Map::default();
map.options.cordon = Some(crate::generation::Bounds::new(
Vector3::new(-5120.0, -5120.0, -5120.0),
Vector3::new(5120.0, 5120.0, 5120.0),
));
map.defaults_l4d2();
map.entities[0].props[0].value = "0 0 2048".into();
dbg!(&map.entities[0].props[0]);
let top = ellipse_verts(Vector3::new(0.0, 0.0, 256.0), 256.0, 256.0, 32, options);
let bottom = ellipse_verts(Vector3::new(0.0, 0.0, -256.0), 256.0, 256.0, 32, options);
let solid = Solid::new(prism(top, bottom, false, mats, options).collect::<Vec<_>>());
map.add_solid(solid);
let top = ellipse_verts(Vector3::new(0.0, 0.0, 256.0), 128.0, 128.0, 32, options);
let bottom = ellipse_verts(Vector3::new(0.0, 0.0, -256.0), 256.0, 256.0, 32, options);
let solid = Solid::new(prism(top, bottom, false, mats, options).collect::<Vec<_>>());
map.add_solid(solid);
let top = std::iter::repeat(Vector3::new(0.0, 0.0, 256.0));
let bottom = ellipse_verts(Vector3::new(0.0, 0.0, -256.0), 256.0, 256.0, 16, options);
let solid = Solid::new(prism(top, bottom, false, mats, options).collect::<Vec<_>>());
map.add_solid(solid);
let top = ellipse_verts(Vector3::new(0.0, 0.0, 256.0), 256.0, 256.0, 16, options);
let bottom = std::iter::repeat(Vector3::new(0.0, 0.0, -256.0));
let solid = Solid::new(prism(top, bottom, false, mats, options).collect::<Vec<_>>());
map.add_solid(solid);
let top = ellipse_verts(Vector3::new(512.0, 512.0, 512.0), 256.0, 256.0, 32, options);
let bottom = ellipse_verts(Vector3::new(0.0, 0.0, 0.0), 1024.0, 512.0, 32, options);
let solid = Solid::new(prism(top, bottom, false, mats, options).collect::<Vec<_>>());
map.add_solid(solid);
let top = ellipse_verts(Vector3::new(512.0, 512.0, 512.0), 256.0, 256.0, 32, options);
let bottom = ellipse_verts(Vector3::new(0.0, 0.0, 0.0), 1024.0, 512.0, 32, options);
let solid = Solid::new(prism(top, bottom, true, mats, options).collect::<Vec<_>>());
map.add_solid(solid);
let vmf = map.to_lower();
write_test_vmf(vmf);
panic!("worked")
}
#[test]
#[ignore]
fn shape_test() {
let dev_person = Material::new(Cow::Borrowed("DEV/DEV_MEASUREWALL01C"));
let mats = [&dev_person; 6];
const CELL_SIZE: i32 = 512;
let shapes = ["cube", "wedge", "spike", "cylinder", "sphere"];
let sides = [3, 4, 8, 16];
let sizes = [512, 256, 128, 64, 32, 16];
let options = SolidOptions::default();
let mut x = -1;
let mut y = -1;
let mut z;
let mut map = Map::default();
for shape in shapes {
for num_sides in sides {
z = 0;
for size in sizes {
z += 0;
let x = (x + CELL_SIZE * 2 - size * 2) as f32;
let y = (CELL_SIZE / 2 + y - size / 2) as f32;
let z = (CELL_SIZE / 2 + z - size / 2) as f32;
let min = Vector3::new(x, y, z);
let max = min.clone() + size as f32;
let bounds = Bounds::new(min, max);
map.add_solid2(make_shape(shape, &bounds, num_sides, mats, &options));
}
x += CELL_SIZE * 2;
}
x = 0;
y += CELL_SIZE;
}
write_test_vmf(map.to_lower());
panic!("worked")
}
fn write_test_vmf(vmf: Vmf<StrType<'_>>) {
const OUTPUT_PATH: &str =
"/home/redram/.local/share/Steam/steamapps/common/Left 4 Dead 2/custom/maps/output2.vmf";
_ = std::fs::remove_file(OUTPUT_PATH);
let mut output =
std::fs::OpenOptions::new().write(true).create(true).open(OUTPUT_PATH).unwrap();
use std::io::Write;
writeln!(output, "{}", vmf).unwrap();
}
#[ignore]
#[test]
fn sphere_test() {
dbg!();
let mut map = Map::default();
let options = SolidOptions { world_align: false, ..SolidOptions::default() };
let mats = [
&Material::new(Cow::Borrowed("tools/toolsnodraw")),
&Material::new(Cow::Borrowed("tools/toolsnodraw")),
&Material::new(Cow::Borrowed("DEV/DEV_MEASUREWALL01C")),
];
for solid in sphere(
&Bounds::new(Vector3::new(-256.0, -256.0, 0.0), Vector3::new(256.0, 256.0, 512.0)),
8,
mats,
&options,
)
.into_vec()
{
map.add_solid(solid);
}
write_test_vmf(map.to_lower());
panic!("done")
}
#[ignore]
#[test]
fn sphere_disp_test() {
dbg!();
const TRUTH_PATH: &str = "/home/redram/Documents/disp_test.vmf";
let truth_input = std::fs::read_to_string(TRUTH_PATH).unwrap();
let truth_vmf =
vmf_parser_nom::parse::<&str, vmf_parser_nom::error::VerboseError<_>>(&truth_input)
.unwrap();
let block = &truth_vmf.blocks[3].blocks[0];
let truth_sphere = block_to_solid(block);
let mut map = Map::default();
let options = SolidOptions { world_align: false, power: 3, ..SolidOptions::default() };
let mats = [
&Material::new(Cow::Borrowed("DEV/DEV_MEASUREWALL01C")),
];
const SIZE_X: f32 = 512.0;
const SIZE_Y: f32 = 1024.0;
const SIZE_Z: f32 = 128.0;
let sphere = sphere_disp(
&Bounds::new(Vector3::new(0.0, 0.0, 0.0), Vector3::new(SIZE_X, SIZE_Y, SIZE_Z)),
mats,
&options,
);
let sphere = sphere.into_vec()[0].clone();
map.add_solid(sphere.clone());
let vmf = map.to_lower();
write_test_vmf(vmf);
let mut i = 0;
for (truth, output) in truth_sphere.sides.iter().zip(sphere.sides.iter()) {
let truth_normals = &truth.disp.as_ref().unwrap().normals;
let output_normals = &output.disp.as_ref().unwrap().normals;
for (truth, output) in truth_normals.inner.iter().zip(output_normals.inner.iter()) {
if i % 15 == 0 {
eprintln!();
}
let truth = [
truth.x.is_sign_negative() as usize,
truth.y.is_sign_negative() as usize,
truth.z.is_sign_negative() as usize,
];
let output = [
output.x.is_sign_negative() as usize,
output.y.is_sign_negative() as usize,
output.z.is_sign_negative() as usize,
];
for (t, o) in truth.into_iter().zip(output) {
if t == o {
print!("_");
} else {
print!("{}", &"+-"[o..o + 1]);
}
}
print!(" ");
i += 1;
}
}
unimplemented!("cube stretched to sphere as disp")
}
#[test]
fn sphere2() {
unimplemented!("cube stretch to sphere as brush")
}
#[ignore]
#[test]
fn test_order() {
dbg!();
let mut map = Map::default();
let options = SolidOptions { world_align: false, power: 3, ..SolidOptions::default() };
let mats = [
&Material::new(Cow::Borrowed("DEV/DEV_MEASUREWALL01C")),
];
const SIZE: f32 = 128.0;
let sphere = sphere_disp(
&Bounds::new(Vector3::new(-SIZE, -SIZE, -SIZE), Vector3::new(SIZE, SIZE, SIZE)),
mats,
&options,
);
let mut sphere = sphere.into_vec()[0].clone();
for side in sphere.sides.iter_mut() {
dbg!(&(side.disp.as_ref()).unwrap().bottom_right);
let mut i = 0f32;
let side_normal = side.plane.normal();
let normals = &mut side.disp.as_mut().unwrap().normals;
for normal in normals.inner.iter_mut() {
*normal = side_normal.clone();
}
let distances = &mut side.disp.as_mut().unwrap().distances;
for distance in distances.inner.iter_mut() {
*distance = i;
i += 1.0 + i.sqrt();
}
}
map.add_solid(sphere.clone());
let vmf = map.to_lower();
write_test_vmf(vmf);
unimplemented!("test order")
}