mirror of
https://codeberg.org/icewind/vbspview.git
synced 2026-06-03 10:14:10 +02:00
merge props
This commit is contained in:
parent
1b477dfb40
commit
9231de3741
1 changed files with 55 additions and 27 deletions
82
src/main.rs
82
src/main.rs
|
|
@ -100,12 +100,13 @@ fn main() -> Result<(), Error> {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut model = Model::new_with_material(&context, &cpu_mesh, material.clone())?;
|
let model = Model::new_with_material(&context, &cpu_mesh, material.clone())?;
|
||||||
// model.set_transformation(Mat4::from_angle_x(degrees(-90.0)));
|
|
||||||
let props = bsp
|
let props = bsp
|
||||||
.static_props()
|
.static_props()
|
||||||
.map(|prop| load_prop(&loader, prop, &context, material.clone()))
|
.map(|prop| load_prop(&loader, prop))
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
let merged_props = merge_meshes(props);
|
||||||
|
let props_model = Model::new_with_material(&context, &merged_props, material)?;
|
||||||
|
|
||||||
let mut lights = Lights {
|
let mut lights = Lights {
|
||||||
ambient: Some(AmbientLight {
|
ambient: Some(AmbientLight {
|
||||||
|
|
@ -209,13 +210,11 @@ fn main() -> Result<(), Error> {
|
||||||
&camera,
|
&camera,
|
||||||
&lights,
|
&lights,
|
||||||
)?;
|
)?;
|
||||||
for prop in &props {
|
props_model.render_with_material(
|
||||||
prop.render_with_material(
|
&NormalMaterial::from_physical_material(&model.material),
|
||||||
&NormalMaterial::from_physical_material(&model.material),
|
&camera,
|
||||||
&camera,
|
&lights,
|
||||||
&lights,
|
)?;
|
||||||
)?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
DebugType::DEPTH => {
|
DebugType::DEPTH => {
|
||||||
let mut depth_material = DepthMaterial::default();
|
let mut depth_material = DepthMaterial::default();
|
||||||
|
|
@ -260,6 +259,15 @@ fn main() -> Result<(), Error> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn map_coords<C: Into<[f32; 3]>>(vec: C) -> [f32; 3] {
|
||||||
|
let vec = vec.into();
|
||||||
|
[
|
||||||
|
-vec[0] * UNIT_SCALE,
|
||||||
|
vec[2] * UNIT_SCALE,
|
||||||
|
vec[1] * UNIT_SCALE,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
// 1 hammer unit is ~1.905cm
|
// 1 hammer unit is ~1.905cm
|
||||||
const UNIT_SCALE: f32 = 1.0 / (1.905 * 100.0);
|
const UNIT_SCALE: f32 = 1.0 / (1.905 * 100.0);
|
||||||
|
|
||||||
|
|
@ -273,8 +281,7 @@ fn model_to_mesh(model: Handle<vbsp::data::Model>) -> CPUMesh {
|
||||||
.map(|verts| Either::Left(verts))
|
.map(|verts| Either::Left(verts))
|
||||||
.unwrap_or_else(|| Either::Right(face.triangulate().flat_map(|verts| verts)))
|
.unwrap_or_else(|| Either::Right(face.triangulate().flat_map(|verts| verts)))
|
||||||
})
|
})
|
||||||
.flat_map(<[f32; 3]>::from)
|
.flat_map(map_coords)
|
||||||
.map(|c| c * UNIT_SCALE)
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let mut mesh = CPUMesh {
|
let mut mesh = CPUMesh {
|
||||||
|
|
@ -287,23 +294,17 @@ fn model_to_mesh(model: Handle<vbsp::data::Model>) -> CPUMesh {
|
||||||
mesh
|
mesh
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_prop<M: Material>(
|
fn load_prop(loader: &Loader, prop: Handle<StaticPropLump>) -> Result<CPUMesh, Error> {
|
||||||
loader: &Loader,
|
let mut mesh = load_prop_mesh(loader, prop.model())?;
|
||||||
prop: Handle<StaticPropLump>,
|
let translation = Mat4::from_translation(map_coords(prop.origin).into());
|
||||||
context: &Context,
|
|
||||||
material: M,
|
|
||||||
) -> Result<Model<M>, Error> {
|
|
||||||
let mesh = load_prop_mesh(loader, prop.model())?;
|
|
||||||
let mut model = Model::new_with_material(context, &mesh, material)?;
|
|
||||||
let translation = Mat4::from_translation(<[f32; 3]>::from(prop.origin * UNIT_SCALE).into());
|
|
||||||
let rotation = Mat4::from(Euler {
|
let rotation = Mat4::from(Euler {
|
||||||
x: degrees(prop.angles[0]),
|
x: degrees(prop.angles[0]),
|
||||||
y: degrees(prop.angles[1]),
|
y: degrees(prop.angles[1]),
|
||||||
z: degrees(prop.angles[2]),
|
z: degrees(prop.angles[2]),
|
||||||
});
|
});
|
||||||
let world = Mat4::from_angle_x(degrees(-90.0));
|
mesh.transform(&rotation);
|
||||||
model.set_transformation(translation);
|
mesh.transform(&translation);
|
||||||
Ok(model)
|
Ok(mesh)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip(loader))]
|
#[tracing::instrument(skip(loader))]
|
||||||
|
|
@ -320,12 +321,12 @@ fn prop_to_mesh(model: &vmdl::Model) -> CPUMesh {
|
||||||
let positions: Vec<f32> = model
|
let positions: Vec<f32> = model
|
||||||
.vertices()
|
.vertices()
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|vertex| vertex.position.iter().map(|pos| pos * UNIT_SCALE))
|
.flat_map(|v| map_coords(v.position))
|
||||||
.collect();
|
.collect();
|
||||||
let normals: Vec<f32> = model
|
let normals: Vec<f32> = model
|
||||||
.vertices()
|
.vertices()
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|vertex| vertex.normal.iter())
|
.flat_map(|vertex| map_coords(vertex.normal))
|
||||||
.collect();
|
.collect();
|
||||||
let indices = Indices::U32(
|
let indices = Indices::U32(
|
||||||
model
|
model
|
||||||
|
|
@ -334,10 +335,37 @@ fn prop_to_mesh(model: &vmdl::Model) -> CPUMesh {
|
||||||
.collect(),
|
.collect(),
|
||||||
);
|
);
|
||||||
|
|
||||||
CPUMesh {
|
let mut mesh = CPUMesh {
|
||||||
positions,
|
positions,
|
||||||
normals: Some(normals),
|
normals: Some(normals),
|
||||||
indices: Some(indices),
|
indices: Some(indices),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
};
|
||||||
|
mesh.compute_normals();
|
||||||
|
mesh
|
||||||
|
}
|
||||||
|
|
||||||
|
fn merge_meshes<I: IntoIterator<Item = CPUMesh>>(meshes: I) -> CPUMesh {
|
||||||
|
let mut positions = Vec::new();
|
||||||
|
let mut normals = Vec::new();
|
||||||
|
let mut indices = Vec::new();
|
||||||
|
|
||||||
|
for mesh in meshes {
|
||||||
|
mesh.validate().expect("invalid mesh");
|
||||||
|
let offset = positions.len() as u32 / 3;
|
||||||
|
positions.extend_from_slice(&mesh.positions);
|
||||||
|
normals.extend_from_slice(&mesh.normals.unwrap());
|
||||||
|
if let Indices::U32(mesh_indices) = mesh.indices.unwrap() {
|
||||||
|
indices.extend(mesh_indices.into_iter().map(|index| index + offset));
|
||||||
|
} else {
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CPUMesh {
|
||||||
|
positions,
|
||||||
|
normals: Some(normals),
|
||||||
|
indices: Some(Indices::U32(indices)),
|
||||||
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue