mirror of
https://github.com/Theaninova/mhlib.git
synced 2026-01-22 01:42:44 +00:00
cleanup
This commit is contained in:
@@ -1,46 +1,38 @@
|
||||
use crate::lwo::clips::collect_clip;
|
||||
use crate::lwo::mapping::{collect_discontinuous_mappings, collect_mappings};
|
||||
use crate::lwo::material::collect_material;
|
||||
use crate::lwo::surface::try_commit;
|
||||
use godot::builtin::{Array, Dictionary, Vector2, Vector3};
|
||||
use godot::engine::mesh::{ArrayFormat, PrimitiveType};
|
||||
use godot::engine::{ArrayMesh, Image, SurfaceTool};
|
||||
use godot::log::{godot_error, godot_warn};
|
||||
use crate::lwo::material::MaterialUvInfo;
|
||||
use crate::lwo::surface::IntermediateLayer;
|
||||
use godot::builtin::{Vector2, Vector3};
|
||||
use godot::engine::node::InternalMode;
|
||||
use godot::engine::{Image, MeshInstance3D, Node3D, PackedScene};
|
||||
use godot::log::{godot_error, godot_print, godot_warn};
|
||||
use godot::obj::{Gd, Share};
|
||||
use lightwave_3d::lwo2::tags::polygon_list::PolygonList;
|
||||
use lightwave_3d::lwo2::tags::Tag;
|
||||
use lightwave_3d::LightWaveObject;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
pub fn lightwave_to_gd(lightwave: LightWaveObject) -> Gd<ArrayMesh> {
|
||||
let mut mesh = ArrayMesh::new();
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub fn lightwave_to_gd(lightwave: LightWaveObject) -> Gd<PackedScene> {
|
||||
let mut materials = vec![];
|
||||
let mut images = HashMap::<u32, Gd<Image>>::new();
|
||||
|
||||
let mut points = Vec::<Vector3>::new();
|
||||
let mut uv_mappings = HashMap::<i32, HashMap<i32, Vector2>>::new();
|
||||
let mut weight_mappings = HashMap::<i32, HashMap<i32, f32>>::new();
|
||||
let mut polygons = Vec::<PolygonList>::new();
|
||||
let mut surfaces = HashMap::<i32, u16>::new();
|
||||
|
||||
let mut surface_materials = Vec::<u16>::new();
|
||||
let mut layers = vec![];
|
||||
|
||||
for tag in lightwave.data {
|
||||
match tag {
|
||||
Tag::Layer(layer) => {
|
||||
try_commit(
|
||||
&mut mesh,
|
||||
&mut points,
|
||||
&mut uv_mappings,
|
||||
&mut weight_mappings,
|
||||
&mut polygons,
|
||||
&mut surfaces,
|
||||
&mut surface_materials,
|
||||
);
|
||||
Tag::Layer(layer_tag) => {
|
||||
layers.push(IntermediateLayer {
|
||||
name: layer_tag.name.to_string(),
|
||||
parent: layer_tag.parent,
|
||||
id: layer_tag.number,
|
||||
pivot: Vector3 {
|
||||
x: layer_tag.pivot[0],
|
||||
y: layer_tag.pivot[1],
|
||||
z: layer_tag.pivot[2],
|
||||
},
|
||||
..IntermediateLayer::default()
|
||||
});
|
||||
}
|
||||
Tag::PointList(points_chunk) => {
|
||||
points = points_chunk
|
||||
layers.last_mut().unwrap().points = points_chunk
|
||||
.data
|
||||
.point_location
|
||||
.into_iter()
|
||||
@@ -54,12 +46,28 @@ pub fn lightwave_to_gd(lightwave: LightWaveObject) -> Gd<ArrayMesh> {
|
||||
Tag::DiscontinuousVertexMapping(vmad) => match &vmad.kind {
|
||||
b"TXUV" => {
|
||||
debug_assert!(vmad.data.mappings[0].values.len() == 2);
|
||||
collect_discontinuous_mappings(&mut uv_mappings, vmad, |uv| Vector2 {
|
||||
let name = vmad.name.to_string();
|
||||
|
||||
let layer = layers.last_mut().unwrap();
|
||||
let map = if let Some(mappings) =
|
||||
layer.uv_mappings.iter_mut().find(|(n, _)| n == &name)
|
||||
{
|
||||
mappings
|
||||
} else {
|
||||
layer.uv_mappings.push((name, HashMap::new()));
|
||||
layer.uv_mappings.last_mut().unwrap()
|
||||
};
|
||||
|
||||
collect_discontinuous_mappings(&mut map.1, vmad, |uv| Vector2 {
|
||||
x: uv[0],
|
||||
y: uv[1],
|
||||
})
|
||||
});
|
||||
}
|
||||
b"WGHT" => collect_discontinuous_mappings(&mut weight_mappings, vmad, |it| it[0]),
|
||||
b"WGHT" => collect_discontinuous_mappings(
|
||||
&mut layers.last_mut().unwrap().weight_mappings,
|
||||
vmad,
|
||||
|it| it[0],
|
||||
),
|
||||
x => godot_error!(
|
||||
"Not Implemented: Discontinuous Vertex Mapping: {}",
|
||||
String::from_utf8(x.to_vec()).unwrap()
|
||||
@@ -68,9 +76,25 @@ pub fn lightwave_to_gd(lightwave: LightWaveObject) -> Gd<ArrayMesh> {
|
||||
Tag::VertexMapping(vmap) => match &vmap.kind {
|
||||
b"TXUV" => {
|
||||
debug_assert!(vmap.data.mapping[0].value.len() == 2);
|
||||
collect_mappings(&mut uv_mappings, vmap, |uv| Vector2 { x: uv[0], y: uv[1] })
|
||||
let name = vmap.name.to_string();
|
||||
|
||||
let layer = layers.last_mut().unwrap();
|
||||
let map = if let Some(mappings) =
|
||||
layer.uv_mappings.iter_mut().find(|(n, _)| n == &name)
|
||||
{
|
||||
mappings
|
||||
} else {
|
||||
layer.uv_mappings.push((name, HashMap::new()));
|
||||
layer.uv_mappings.last_mut().unwrap()
|
||||
};
|
||||
|
||||
collect_mappings(&mut map.1, vmap, |uv| Vector2 { x: uv[0], y: uv[1] });
|
||||
}
|
||||
b"WGHT" => collect_mappings(&mut weight_mappings, vmap, |it| it[0]),
|
||||
b"WGHT" => collect_mappings(
|
||||
&mut layers.last_mut().unwrap().weight_mappings,
|
||||
vmap,
|
||||
|it| it[0],
|
||||
),
|
||||
x => godot_error!(
|
||||
"Not Implemented: Vertex Mapping: {}",
|
||||
String::from_utf8(x.to_vec()).unwrap()
|
||||
@@ -82,7 +106,11 @@ pub fn lightwave_to_gd(lightwave: LightWaveObject) -> Gd<ArrayMesh> {
|
||||
},*/
|
||||
b"SURF" => {
|
||||
for surf in ptag.data.mappings {
|
||||
surfaces.insert(surf.poly as i32, surf.tag);
|
||||
layers
|
||||
.last_mut()
|
||||
.unwrap()
|
||||
.surfaces
|
||||
.insert(surf.poly as i32, surf.tag);
|
||||
}
|
||||
}
|
||||
x => godot_warn!(
|
||||
@@ -92,14 +120,14 @@ pub fn lightwave_to_gd(lightwave: LightWaveObject) -> Gd<ArrayMesh> {
|
||||
},
|
||||
Tag::PolygonList(polygon_lists) => match &polygon_lists.kind {
|
||||
b"FACE" => {
|
||||
polygons = polygon_lists.data.polygons;
|
||||
layers.last_mut().unwrap().polygons = polygon_lists.data.polygons;
|
||||
}
|
||||
x => godot_warn!("{}", String::from_utf8(x.to_vec()).unwrap()),
|
||||
},
|
||||
Tag::ImageClip(clip) => collect_clip(&mut images, clip.data),
|
||||
Tag::SurfaceDefinition(surf) => {
|
||||
let mat = collect_material(surf.data, &images);
|
||||
materials.push(mat);
|
||||
godot_print!("Def: '{}' -> '{}'", surf.source, surf.name);
|
||||
materials.push(MaterialUvInfo::collect(surf.data, &images));
|
||||
}
|
||||
Tag::BoundingBox(_) => (),
|
||||
x => {
|
||||
@@ -108,34 +136,23 @@ pub fn lightwave_to_gd(lightwave: LightWaveObject) -> Gd<ArrayMesh> {
|
||||
}
|
||||
}
|
||||
|
||||
try_commit(
|
||||
&mut mesh,
|
||||
&mut points,
|
||||
&mut uv_mappings,
|
||||
&mut weight_mappings,
|
||||
&mut polygons,
|
||||
&mut surfaces,
|
||||
&mut surface_materials,
|
||||
);
|
||||
let mut out_mesh = ArrayMesh::new();
|
||||
for i in 0..mesh.get_surface_count() {
|
||||
let mut tool = SurfaceTool::new();
|
||||
let mut root_node = Node3D::new_alloc();
|
||||
|
||||
tool.create_from(mesh.share().upcast(), i);
|
||||
tool.generate_normals(false);
|
||||
tool.generate_tangents();
|
||||
for layer in layers {
|
||||
let mut instance = MeshInstance3D::new_alloc();
|
||||
instance.set_name(layer.name.clone().into());
|
||||
instance.set_mesh(layer.commit(&mut materials).upcast());
|
||||
|
||||
out_mesh.add_surface_from_arrays(
|
||||
PrimitiveType::PRIMITIVE_TRIANGLES,
|
||||
tool.commit_to_arrays(),
|
||||
Array::new(),
|
||||
Dictionary::new(),
|
||||
ArrayFormat::ARRAY_FORMAT_NORMAL,
|
||||
root_node.add_child(
|
||||
instance.share().upcast(),
|
||||
false,
|
||||
InternalMode::INTERNAL_MODE_DISABLED,
|
||||
);
|
||||
|
||||
if let Some(mat) = materials.get(surfaces[&(i as i32)] as usize) {
|
||||
out_mesh.surface_set_material(i, mat.share().upcast())
|
||||
}
|
||||
instance.set_owner(root_node.share().upcast());
|
||||
}
|
||||
out_mesh
|
||||
|
||||
let mut scene = PackedScene::new();
|
||||
scene.pack(root_node.share().upcast());
|
||||
root_node.queue_free();
|
||||
scene
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user