mirror of
https://codeberg.org/icewind/vbspview.git
synced 2026-06-04 02:34:10 +02:00
update threed
This commit is contained in:
parent
c625fa85eb
commit
7dec8aa2c6
9 changed files with 4997 additions and 550 deletions
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
|
|
@ -56,5 +56,5 @@ jobs:
|
||||||
- run: nix build .#${{ matrix.target }}
|
- run: nix build .#${{ matrix.target }}
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: vbspview-${{ matrix.asset_suffix }}
|
name: vbspview-${{ matrix.target }}
|
||||||
path: result/bin/vbspview${{ matrix.artifact_suffix }}
|
path: result/bin/vbspview${{ matrix.artifact_suffix }}
|
||||||
|
|
|
||||||
695
Cargo.lock
generated
695
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -6,9 +6,10 @@ authors = ["Robin Appelman <robin@icewind.nl>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
three-d = { version = "0.14.0", features = ["egui-gui"] }
|
three-d = { version = "0.16.3", features = ["egui-gui"] }
|
||||||
vbsp = { version = "0.2.0", git = "https://github.com/icewind1991/vbsp" }
|
three-d-asset = { version = "0.6" }
|
||||||
#vbsp = { version = "0.2.0", path = "../bsp" }
|
#vbsp = { version = "0.2.0", git = "https://github.com/icewind1991/vbsp" }
|
||||||
|
vbsp = { version = "0.2.0", path = "../bsp" }
|
||||||
miette = { version = "5.5.0", features = ["fancy"] }
|
miette = { version = "5.5.0", features = ["fancy"] }
|
||||||
thiserror = "1.0.37"
|
thiserror = "1.0.37"
|
||||||
delaunator = "1.0.1"
|
delaunator = "1.0.1"
|
||||||
|
|
|
||||||
35
flake.nix
35
flake.nix
|
|
@ -35,22 +35,24 @@
|
||||||
hostTarget = pkgs.hostPlatform.config;
|
hostTarget = pkgs.hostPlatform.config;
|
||||||
targets = ["x86_64-unknown-linux-musl" "x86_64-pc-windows-gnu" hostTarget];
|
targets = ["x86_64-unknown-linux-musl" "x86_64-pc-windows-gnu" hostTarget];
|
||||||
|
|
||||||
artifactSuffixForTarget = cross-naersk'.execSufficForTarget;
|
|
||||||
assetSuffixForTarget = target: "${builtins.replaceStrings ["-unknown" "-gnu" "-musl" "eabihf" "-pc"] ["" "" "" "" ""] target}${cross-naersk'.execSufficForTarget target}";
|
|
||||||
|
|
||||||
hostNaersk = naerskForTarget hostTarget;
|
hostNaersk = naerskForTarget hostTarget;
|
||||||
cross-naersk' = pkgs.callPackage cross-naersk {inherit naersk;};
|
cross-naersk' = pkgs.callPackage cross-naersk {inherit naersk;};
|
||||||
src = lib.sources.sourceByRegex (lib.cleanSource ./.) ["Cargo.*" "(src)(/.*)?"];
|
src = lib.sources.sourceByRegex (lib.cleanSource ./.) ["Cargo.*" "(src)(/.*)?"];
|
||||||
nearskOpt = {
|
nearskOpt = {
|
||||||
pname = "vbspview";
|
pname = "vbspview";
|
||||||
root = src;
|
root = src;
|
||||||
nativeBuildInputs = buildDependencies;
|
nativeBuildInputs = (buildDependencies pkgs) ++ (runtimeDependencies pkgs);
|
||||||
};
|
};
|
||||||
buildDependencies = with pkgs; [
|
crossOpts = {
|
||||||
freetype
|
crossArgs = {
|
||||||
pkg-config
|
"x86_64-unknown-linux-musl" = {
|
||||||
cmake
|
# targetNativeBuildInputs = buildDependencies;
|
||||||
fontconfig
|
# buildInputs = runtimeDependencies pkgs.pkgsCross.musl64;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
runtimeDependencies = pkgsForPlatform: with pkgsForPlatform; [
|
||||||
xorg.libX11
|
xorg.libX11
|
||||||
xorg.libXcursor
|
xorg.libXcursor
|
||||||
xorg.libXrandr
|
xorg.libXrandr
|
||||||
|
|
@ -59,12 +61,17 @@
|
||||||
egl-wayland
|
egl-wayland
|
||||||
libGL
|
libGL
|
||||||
];
|
];
|
||||||
|
buildDependencies = pkgsForPlatform: with pkgsForPlatform; [
|
||||||
|
fontconfig
|
||||||
|
freetype
|
||||||
|
pkg-config
|
||||||
|
cmake
|
||||||
|
];
|
||||||
|
|
||||||
buildMatrix = targets: {
|
buildMatrix = targets: {
|
||||||
include = builtins.map (target: {
|
include = builtins.map (target: {
|
||||||
inherit target;
|
inherit target;
|
||||||
artifact_suffix = artifactSuffixForTarget target;
|
artifact_suffix = cross-naersk'.execSufficForTarget target;
|
||||||
asset_suffix = assetSuffixForTarget target;
|
|
||||||
}) targets;
|
}) targets;
|
||||||
};
|
};
|
||||||
in rec {
|
in rec {
|
||||||
|
|
@ -72,9 +79,11 @@
|
||||||
vbspview = packages.${hostTarget};
|
vbspview = packages.${hostTarget};
|
||||||
check = hostNaersk.buildPackage (nearskOpt // {
|
check = hostNaersk.buildPackage (nearskOpt // {
|
||||||
mode = "check";
|
mode = "check";
|
||||||
|
buildInputs = buildDependencies pkgs;
|
||||||
});
|
});
|
||||||
clippy = hostNaersk.buildPackage (nearskOpt // {
|
clippy = hostNaersk.buildPackage (nearskOpt // {
|
||||||
mode = "clippy";
|
mode = "clippy";
|
||||||
|
buildInputs = buildDependencies pkgs;
|
||||||
});
|
});
|
||||||
default = vbspview;
|
default = vbspview;
|
||||||
};
|
};
|
||||||
|
|
@ -84,7 +93,7 @@
|
||||||
inherit targets;
|
inherit targets;
|
||||||
|
|
||||||
devShells.default = pkgs.mkShell {
|
devShells.default = pkgs.mkShell {
|
||||||
nativeBuildInputs = with pkgs; [
|
nativeBuildInputs = (with pkgs; [
|
||||||
pkgs.rust-bin.stable.latest.default
|
pkgs.rust-bin.stable.latest.default
|
||||||
bacon
|
bacon
|
||||||
cargo-edit
|
cargo-edit
|
||||||
|
|
@ -92,7 +101,7 @@
|
||||||
clippy
|
clippy
|
||||||
cargo-audit
|
cargo-audit
|
||||||
cargo-msrv
|
cargo-msrv
|
||||||
] ++ buildDependencies;
|
]) ++ (buildDependencies pkgs) ++ (runtimeDependencies pkgs);
|
||||||
|
|
||||||
LD_LIBRARY_PATH = with pkgs; "/run/opengl-driver/lib/:${lib.makeLibraryPath ([libGL libGLU])}";
|
LD_LIBRARY_PATH = with pkgs; "/run/opengl-driver/lib/:${lib.makeLibraryPath ([libGL libGLU])}";
|
||||||
};
|
};
|
||||||
|
|
|
||||||
101
src/bsp.rs
101
src/bsp.rs
|
|
@ -1,10 +1,12 @@
|
||||||
use crate::material::load_material_fallback;
|
use crate::material::load_material_fallback;
|
||||||
use crate::prop::load_props;
|
use crate::prop::load_props;
|
||||||
use crate::{Error, Loader};
|
use crate::{Error, Loader};
|
||||||
use cgmath::vec4;
|
use cgmath::Matrix4;
|
||||||
use std::collections::HashMap;
|
use itertools::Itertools;
|
||||||
use three_d::{CpuMesh, CpuModel, Mat4, Positions, Vec2, Vec3};
|
use std::collections::{HashMap, HashSet};
|
||||||
use vbsp::{Bsp, Face, Handle};
|
use three_d::{CpuModel, Positions, Vec3};
|
||||||
|
use three_d_asset::{Geometry, Primitive, TriMesh};
|
||||||
|
use vbsp::{Bsp, Handle};
|
||||||
|
|
||||||
pub fn load_map(data: &[u8], loader: &mut Loader) -> Result<Vec<CpuModel>, Error> {
|
pub fn load_map(data: &[u8], loader: &mut Loader) -> Result<Vec<CpuModel>, Error> {
|
||||||
let (world, bsp) = load_world(data, loader)?;
|
let (world, bsp) = load_world(data, loader)?;
|
||||||
|
|
@ -12,11 +14,6 @@ pub fn load_map(data: &[u8], loader: &mut Loader) -> Result<Vec<CpuModel>, Error
|
||||||
Ok(vec![world, props])
|
Ok(vec![world, props])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply_transform<C: Into<Vec3>>(coord: C, transform: Mat4) -> Vec3 {
|
|
||||||
let coord = coord.into();
|
|
||||||
(transform * vec4(coord.x, coord.y, coord.z, 1.0)).truncate()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn map_coords<C: Into<Vec3>>(vec: C) -> Vec3 {
|
pub fn map_coords<C: Into<Vec3>>(vec: C) -> Vec3 {
|
||||||
let vec = vec.into();
|
let vec = vec.into();
|
||||||
Vec3 {
|
Vec3 {
|
||||||
|
|
@ -29,66 +26,66 @@ pub fn map_coords<C: Into<Vec3>>(vec: C) -> Vec3 {
|
||||||
// 1 hammer unit is ~1.905cm
|
// 1 hammer unit is ~1.905cm
|
||||||
pub const UNIT_SCALE: f32 = 1.0 / (1.905 * 100.0);
|
pub const UNIT_SCALE: f32 = 1.0 / (1.905 * 100.0);
|
||||||
|
|
||||||
fn face_to_mesh(face: &Handle<Face>) -> CpuMesh {
|
fn model_to_model(model: Handle<vbsp::data::Model>, loader: &Loader) -> CpuModel {
|
||||||
let texture = face.texture();
|
let textures: HashSet<&str> = model.textures().map(|texture| texture.name()).collect();
|
||||||
let positions = face.vertex_positions().map(map_coords).collect();
|
let textures: Vec<&str> = textures.into_iter().collect();
|
||||||
let uvs = face
|
|
||||||
.vertex_positions()
|
let faces_by_texture: HashMap<&str, _> = model
|
||||||
.map(|pos| Vec2 {
|
.faces()
|
||||||
x: texture.u(pos),
|
.filter(|face| face.is_visible())
|
||||||
y: texture.v(pos),
|
.map(|face| (face.texture().name(), face))
|
||||||
})
|
.into_group_map();
|
||||||
|
|
||||||
|
let geometries: Vec<_> = faces_by_texture
|
||||||
|
.into_values()
|
||||||
|
.map(|faces| {
|
||||||
|
let positions: Vec<_> = faces
|
||||||
|
.iter()
|
||||||
|
.flat_map(|face| face.vertex_positions())
|
||||||
|
.map(map_coords)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let mut mesh = CpuMesh {
|
let uvs: Vec<_> = faces
|
||||||
|
.iter()
|
||||||
|
.flat_map(|face| {
|
||||||
|
let texture = face.texture();
|
||||||
|
face.vertex_positions()
|
||||||
|
.map(move |position| texture.uv(position))
|
||||||
|
})
|
||||||
|
.map(|uv| uv.into())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let mut mesh = TriMesh {
|
||||||
positions: Positions::F32(positions),
|
positions: Positions::F32(positions),
|
||||||
uvs: Some(uvs),
|
uvs: Some(uvs),
|
||||||
material_name: Some(texture.name().into()),
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
mesh.compute_normals();
|
mesh.compute_normals();
|
||||||
mesh.compute_tangents();
|
mesh.compute_tangents();
|
||||||
mesh
|
|
||||||
}
|
|
||||||
|
|
||||||
fn model_to_model(model: Handle<vbsp::data::Model>, loader: &Loader) -> CpuModel {
|
let texture = faces.first().unwrap().texture().name();
|
||||||
let mut faces_by_texture: HashMap<&str, Vec<_>> = HashMap::with_capacity(64);
|
let material_index = textures
|
||||||
for face in model.faces().filter(|face| face.is_visible()) {
|
.iter()
|
||||||
faces_by_texture
|
.enumerate()
|
||||||
.entry(face.texture().name())
|
.find_map(|(i, tex)| (*tex == texture).then_some(i));
|
||||||
.or_default()
|
|
||||||
.push(face)
|
|
||||||
}
|
|
||||||
|
|
||||||
let geometries = faces_by_texture
|
Primitive {
|
||||||
.values()
|
name: "".to_string(),
|
||||||
.map(|faces| {
|
transformation: Matrix4::from_scale(1.0),
|
||||||
let mut faces = faces.iter();
|
animations: vec![],
|
||||||
let first = faces.next().unwrap();
|
geometry: Geometry::Triangles(mesh),
|
||||||
let mut mesh = face_to_mesh(first);
|
material_index,
|
||||||
for face in faces {
|
|
||||||
let face_mesh = face_to_mesh(face);
|
|
||||||
if let Positions::F32(positions) = &mut mesh.positions {
|
|
||||||
positions.extend_from_slice(&face_mesh.positions.into_f32());
|
|
||||||
}
|
}
|
||||||
if let Some(uvs) = &mut mesh.uvs {
|
|
||||||
uvs.extend_from_slice(&face_mesh.uvs.unwrap());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mesh.compute_normals();
|
|
||||||
mesh
|
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let materials = faces_by_texture
|
let materials: Vec<_> = textures
|
||||||
.values()
|
.iter()
|
||||||
.map(|face| {
|
.map(|texture| load_material_fallback(texture, &["".into()], loader))
|
||||||
let texture = face.first().unwrap().texture();
|
|
||||||
load_material_fallback(texture.name(), &["".into()], loader)
|
|
||||||
})
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
CpuModel {
|
CpuModel {
|
||||||
|
name: "".to_string(),
|
||||||
geometries,
|
geometries,
|
||||||
materials,
|
materials,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,8 @@ use crate::loader::Loader;
|
||||||
use crate::Error;
|
use crate::Error;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use steamy_vdf::{Entry, Table};
|
use steamy_vdf::{Entry, Table};
|
||||||
use three_d::{Color, CpuMaterial, CpuTexture, TextureData};
|
use three_d::{CpuMaterial, CpuTexture, TextureData};
|
||||||
|
use three_d_asset::Srgba;
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
use vtf::vtf::VTF;
|
use vtf::vtf::VTF;
|
||||||
|
|
||||||
|
|
@ -16,7 +17,7 @@ pub fn load_material_fallback(name: &str, search_dirs: &[String], loader: &Loade
|
||||||
"failed to load material, falling back"
|
"failed to load material, falling back"
|
||||||
);
|
);
|
||||||
CpuMaterial {
|
CpuMaterial {
|
||||||
albedo: Color {
|
albedo: Srgba {
|
||||||
r: 255,
|
r: 255,
|
||||||
g: 0,
|
g: 0,
|
||||||
b: 255,
|
b: 255,
|
||||||
|
|
@ -61,7 +62,7 @@ pub fn load_material(
|
||||||
|
|
||||||
if material_type == "water" {
|
if material_type == "water" {
|
||||||
return Ok(CpuMaterial {
|
return Ok(CpuMaterial {
|
||||||
albedo: Color {
|
albedo: Srgba {
|
||||||
r: 82,
|
r: 82,
|
||||||
g: 180,
|
g: 180,
|
||||||
b: 217,
|
b: 217,
|
||||||
|
|
@ -109,7 +110,7 @@ pub fn load_material(
|
||||||
|
|
||||||
Ok(CpuMaterial {
|
Ok(CpuMaterial {
|
||||||
name: name.into(),
|
name: name.into(),
|
||||||
albedo: Color::WHITE,
|
albedo: Srgba::WHITE,
|
||||||
albedo_texture: Some(texture),
|
albedo_texture: Some(texture),
|
||||||
alpha_cutout: alpha_test.then_some(alpha_cutout),
|
alpha_cutout: alpha_test.then_some(alpha_cutout),
|
||||||
normal_texture: bump_map,
|
normal_texture: bump_map,
|
||||||
|
|
@ -159,16 +160,15 @@ fn resolve_vmt_patch(vmt: Table, loader: &Loader) -> Result<Table, Error> {
|
||||||
if let Some(Entry::Table(patch)) = vmt.get("patch") {
|
if let Some(Entry::Table(patch)) = vmt.get("patch") {
|
||||||
let include = patch
|
let include = patch
|
||||||
.get("include")
|
.get("include")
|
||||||
.expect("no include in patch")
|
.ok_or(Error::Other("no include in patch"))?
|
||||||
.as_value()
|
.as_str()
|
||||||
.expect("include is not a value")
|
.ok_or(Error::Other("include is not a string"))?;
|
||||||
.to_string();
|
|
||||||
let _replace = patch
|
let _replace = patch
|
||||||
.get("replace")
|
.get("replace")
|
||||||
.expect("no replace in patch")
|
.ok_or(Error::Other("no replace in patch"))?
|
||||||
.as_table()
|
.as_table()
|
||||||
.expect("replace is not a table");
|
.ok_or(Error::Other("replace is not a table"))?;
|
||||||
let included_raw = loader.load(&include)?.to_ascii_lowercase();
|
let included_raw = loader.load(include)?.to_ascii_lowercase();
|
||||||
|
|
||||||
// todo actually patch
|
// todo actually patch
|
||||||
parse_vdf(&included_raw)
|
parse_vdf(&included_raw)
|
||||||
|
|
|
||||||
51
src/prop.rs
51
src/prop.rs
|
|
@ -1,9 +1,9 @@
|
||||||
use crate::bsp::{apply_transform, map_coords};
|
use crate::bsp::map_coords;
|
||||||
use crate::material::load_material_fallback;
|
use crate::material::load_material_fallback;
|
||||||
use crate::{Error, Loader};
|
use crate::{Error, Loader};
|
||||||
use cgmath::{Matrix, SquareMatrix};
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use three_d::{CpuMaterial, CpuMesh, CpuModel, Mat4, Positions, Vec2, Vec3, Vec4};
|
use three_d::{CpuMaterial, CpuModel, Mat4, Positions, Vec2, Vec3, Vec4};
|
||||||
|
use three_d_asset::{Geometry, Primitive, TriMesh};
|
||||||
use tracing::warn;
|
use tracing::warn;
|
||||||
use vbsp::{Handle, StaticPropLump};
|
use vbsp::{Handle, StaticPropLump};
|
||||||
use vmdl::mdl::{Mdl, TextureInfo};
|
use vmdl::mdl::{Mdl, TextureInfo};
|
||||||
|
|
@ -35,18 +35,25 @@ pub fn load_props<'a, I: Iterator<Item = Handle<'a, StaticPropLump>>>(
|
||||||
})
|
})
|
||||||
.collect::<Result<_, _>>()?;
|
.collect::<Result<_, _>>()?;
|
||||||
|
|
||||||
let geometries = props.iter().flat_map(prop_to_meshes).collect();
|
let materials: HashMap<_, _> = props
|
||||||
|
|
||||||
let textures: HashMap<_, _> = props
|
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|prop| prop.model.textures())
|
.flat_map(|prop| prop.model.textures())
|
||||||
.map(|tex| (tex.name.as_str(), tex))
|
.map(|tex| (tex.name.as_str(), tex))
|
||||||
.collect();
|
.collect();
|
||||||
let materials: Vec<_> = textures
|
let materials: Vec<_> = materials.into_values().collect();
|
||||||
.into_values()
|
|
||||||
|
let geometries = props
|
||||||
|
.iter()
|
||||||
|
.flat_map(|prop| prop_to_meshes(prop, materials.as_slice()))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let materials: Vec<_> = materials
|
||||||
|
.into_iter()
|
||||||
.map(|tex| prop_texture_to_material(tex, loader))
|
.map(|tex| prop_texture_to_material(tex, loader))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
Ok(CpuModel {
|
Ok(CpuModel {
|
||||||
|
name: "props".into(),
|
||||||
geometries,
|
geometries,
|
||||||
materials,
|
materials,
|
||||||
})
|
})
|
||||||
|
|
@ -58,9 +65,11 @@ struct PropData {
|
||||||
skin: i32,
|
skin: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prop_to_meshes(prop: &PropData) -> impl Iterator<Item = CpuMesh> + '_ {
|
fn prop_to_meshes<'a>(
|
||||||
|
prop: &'a PropData,
|
||||||
|
textures: &'a [&TextureInfo],
|
||||||
|
) -> impl Iterator<Item = Primitive> + 'a {
|
||||||
let transform = prop.transform;
|
let transform = prop.transform;
|
||||||
let normal_transform = transform.invert().unwrap().transpose() * -1.0;
|
|
||||||
let model = &prop.model;
|
let model = &prop.model;
|
||||||
|
|
||||||
let skin = match model.skin_tables().nth(prop.skin as usize) {
|
let skin = match model.skin_tables().nth(prop.skin as usize) {
|
||||||
|
|
@ -75,16 +84,20 @@ fn prop_to_meshes(prop: &PropData) -> impl Iterator<Item = CpuMesh> + '_ {
|
||||||
let texture = skin
|
let texture = skin
|
||||||
.texture(mesh.material_index())
|
.texture(mesh.material_index())
|
||||||
.expect("texture out of bounds");
|
.expect("texture out of bounds");
|
||||||
|
let material_index = textures
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.find_map(|(i, texture_info)| (texture_info.name == texture).then_some(i));
|
||||||
|
|
||||||
let positions: Vec<Vec3> = mesh
|
let positions: Vec<Vec3> = mesh
|
||||||
.vertices()
|
.vertices()
|
||||||
.map(|vertex| map_coords(vertex.position))
|
.map(|vertex| map_coords(vertex.position))
|
||||||
.map(|v| apply_transform(v, transform))
|
// .map(|v| apply_transform(v, transform))
|
||||||
.collect();
|
.collect();
|
||||||
let normals: Vec<Vec3> = mesh
|
let normals: Vec<Vec3> = mesh
|
||||||
.vertices()
|
.vertices()
|
||||||
.map(|vertex| map_coords(vertex.normal))
|
.map(|vertex| map_coords(vertex.normal))
|
||||||
.map(|v| apply_transform(v, normal_transform))
|
// .map(|v| apply_transform(v, normal_transform))
|
||||||
.collect();
|
.collect();
|
||||||
let uvs: Vec<Vec2> = mesh
|
let uvs: Vec<Vec2> = mesh
|
||||||
.vertices()
|
.vertices()
|
||||||
|
|
@ -93,13 +106,21 @@ fn prop_to_meshes(prop: &PropData) -> impl Iterator<Item = CpuMesh> + '_ {
|
||||||
|
|
||||||
let tangents: Vec<Vec4> = mesh.tangents().map(|tangent| tangent.into()).collect();
|
let tangents: Vec<Vec4> = mesh.tangents().map(|tangent| tangent.into()).collect();
|
||||||
|
|
||||||
CpuMesh {
|
let geometry = Geometry::Triangles(TriMesh {
|
||||||
positions: Positions::F32(positions),
|
positions: Positions::F32(positions),
|
||||||
|
indices: Default::default(),
|
||||||
normals: Some(normals),
|
normals: Some(normals),
|
||||||
uvs: Some(uvs),
|
uvs: Some(uvs),
|
||||||
material_name: Some(texture.into()),
|
|
||||||
tangents: Some(tangents),
|
tangents: Some(tangents),
|
||||||
..Default::default()
|
colors: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
Primitive {
|
||||||
|
name: "".to_string(),
|
||||||
|
transformation: transform,
|
||||||
|
animations: vec![],
|
||||||
|
geometry,
|
||||||
|
material_index,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,17 +24,17 @@ impl<C: Control> Renderer<C> {
|
||||||
vec3(0.0, 1.0, 0.0),
|
vec3(0.0, 1.0, 0.0),
|
||||||
degrees(60.0),
|
degrees(60.0),
|
||||||
0.1,
|
0.1,
|
||||||
30.0,
|
45.0,
|
||||||
);
|
);
|
||||||
|
|
||||||
let ambient_lights = vec![AmbientLight {
|
let ambient_lights = vec![AmbientLight {
|
||||||
color: Color::WHITE,
|
color: Srgba::WHITE,
|
||||||
intensity: 0.2,
|
intensity: 0.2,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}];
|
}];
|
||||||
let directional_lights = vec![
|
let directional_lights = vec![
|
||||||
DirectionalLight::new(&context, 1.0, Color::WHITE, &vec3(0.0, -1.0, 0.0)),
|
DirectionalLight::new(&context, 1.0, Srgba::WHITE, &vec3(0.0, -1.0, 0.0)),
|
||||||
DirectionalLight::new(&context, 1.0, Color::WHITE, &vec3(0.0, 1.0, 0.0)),
|
DirectionalLight::new(&context, 1.0, Srgba::WHITE, &vec3(0.0, 1.0, 0.0)),
|
||||||
];
|
];
|
||||||
// let control = FirstPerson::new(0.1);
|
// let control = FirstPerson::new(0.1);
|
||||||
|
|
||||||
|
|
@ -68,11 +68,8 @@ impl<C: Control> Renderer<C> {
|
||||||
self.directional_lights[0].intensity = self.gui.directional_intensity;
|
self.directional_lights[0].intensity = self.gui.directional_intensity;
|
||||||
self.directional_lights[1].intensity = self.gui.directional_intensity;
|
self.directional_lights[1].intensity = self.gui.directional_intensity;
|
||||||
self.ambient_lights[0].intensity = self.gui.ambient_intensity;
|
self.ambient_lights[0].intensity = self.gui.ambient_intensity;
|
||||||
self.camera.set_perspective_projection(
|
self.camera
|
||||||
degrees(self.gui.fov),
|
.set_perspective_projection(degrees(self.gui.fov), 0.1, 45.0);
|
||||||
self.camera.z_near(),
|
|
||||||
self.camera.z_far(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let viewport = Viewport {
|
let viewport = Viewport {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue