Skip to content

Commit

Permalink
Merge branch 'main' into pr/42
Browse files Browse the repository at this point in the history
  • Loading branch information
asny committed Nov 13, 2024
2 parents 2c2d63b + 2aa308f commit 84e30ec
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 54 deletions.
10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,14 @@ serde = ["dep:serde", "half/serde", "cgmath/serde"]
[dependencies]
cgmath = "0.18"
half = {version="2", features=["std", "num-traits", "zerocopy"]}
thiserror = "1"
reqwest = {version = "0.11", optional = true, default-features = false }
thiserror = "2"
reqwest = {version = "0.12", optional = true, default-features = false }
gltf = { version = "1", optional = true, features=["KHR_materials_ior", "KHR_materials_transmission"] }
wavefront_obj = { version = "10", optional = true }
stl_io = { version = "0.8.2", optional = true }
image = { version = "0.24", optional = true, default-features = false}
resvg = { version = "0.43.0", optional = true }
pcd-rs = { version = "0.10", optional = true, features = ["derive"] }
image = { version = "0.25", optional = true, default-features = false}
resvg = { version = "0.44.0", optional = true }
pcd-rs = { version = "0.12", optional = true, features = ["derive"] }
data-url = {version = "0.3", optional = true }
serde = {version= "1", optional = true, features = ["derive", "rc"] }

Expand Down
40 changes: 32 additions & 8 deletions src/camera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -567,12 +567,20 @@ impl Camera {
}

///
/// Returns the up direction of this camera (might not be orthogonal to the view direction).
/// Returns the up direction of this camera.
/// This will probably not be orthogonal to the view direction, use [up_orthogonal](Camera::up_orthogonal) instead if that is needed.
///
pub fn up(&self) -> &Vec3 {
&self.up
}

///
/// Returns the up direction of this camera that is orthogonal to the view direction.
///
pub fn up_orthogonal(&self) -> Vec3 {
self.right_direction().cross(self.view_direction())
}

///
/// Returns the view direction of this camera, ie. the direction the camera is looking.
///
Expand Down Expand Up @@ -605,11 +613,14 @@ impl Camera {

fn update_screen2ray(&mut self) {
let mut v = self.view;
v /= v[3][3];
if let ProjectionType::Perspective { .. } = self.projection_type {
v /= v[3][3];
v[3] = vec4(0.0, 0.0, 0.0, 1.0);
}
self.screen2ray = (self.projection * v).invert().unwrap();
self.screen2ray = (self.projection * v)
.invert()
.unwrap_or_else(|| Mat4::identity());
}

fn update_frustrum(&mut self) {
Expand Down Expand Up @@ -723,8 +734,17 @@ impl Camera {
}
}

///
/// Moves the camera towards the camera target by the amount delta while keeping the given minimum and maximum distance to the target.
///
pub fn zoom(&mut self, delta: f32, minimum_distance: f32, maximum_distance: f32) {
let target = self.target;
self.zoom_towards(&target, delta, minimum_distance, maximum_distance);
}

///
/// Moves the camera towards the given point by the amount delta while keeping the given minimum and maximum distance to the point.
/// Note that the camera target is also updated so that the view direction is the same.
///
pub fn zoom_towards(
&mut self,
Expand All @@ -741,11 +761,15 @@ impl Camera {

let position = *self.position();
let distance = point.distance(position);
let direction = (point - position).normalize();
let target = self.target;
let up = self.up;
let new_distance = (distance - delta).clamp(minimum_distance, maximum_distance);
let new_position = point - direction * new_distance;
self.set_view(new_position, target, up);
if distance > f32::EPSILON {
let delta_clamped =
distance - (distance - delta).clamp(minimum_distance, maximum_distance);
let v = (point - position) * delta_clamped / distance;
self.set_view(
self.position + v,
self.target + v - v.project_on(self.view_direction()),
self.up,
);
}
}
}
82 changes: 43 additions & 39 deletions src/io/img.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{io::RawAssets, texture::*, Error, Result};
use image::{io::Reader, *};
use image::*;
use std::io::Cursor;
use std::path::Path;

Expand All @@ -10,34 +10,13 @@ pub fn deserialize_img(path: impl AsRef<Path>, bytes: &[u8]) -> Result<Texture2D
.filter(|s| !s.starts_with("data:"))
.unwrap_or("default")
.to_owned();
let mut reader = Reader::new(Cursor::new(bytes))
let mut reader = ImageReader::new(Cursor::new(bytes))
.with_guessed_format()
.expect("Cursor io never fails");

if reader.format().is_none() {
reader.set_format(ImageFormat::from_path(path)?);
}
#[cfg(feature = "hdr")]
if reader.format() == Some(image::ImageFormat::Hdr) {
use image::codecs::hdr::*;
let decoder = HdrDecoder::new(&*bytes)?;
let metadata = decoder.metadata();
let img = decoder.read_image_native()?;
return Ok(Texture2D {
name,
data: TextureData::RgbF32(
img.iter()
.map(|rgbe| {
let Rgb(values) = rgbe.to_hdr();
[values[0], values[1], values[2]]
})
.collect::<Vec<_>>(),
),
width: metadata.width,
height: metadata.height,
..Default::default()
});
}
let img: DynamicImage = reader.decode()?;
let width = img.width();
let height = img.height();
Expand All @@ -61,6 +40,12 @@ pub fn deserialize_img(path: impl AsRef<Path>, bytes: &[u8]) -> Result<Texture2D
.map(|c| [c[0], c[1], c[2], c[3]])
.collect::<Vec<_>>(),
),
DynamicImage::ImageRgb32F(img) => TextureData::RgbF32(
img.into_raw()
.chunks(3)
.map(|c| [c[0], c[1], c[2]])
.collect::<Vec<_>>(),
),
_ => unimplemented!(),
};
Ok(Texture2D {
Expand Down Expand Up @@ -114,42 +99,42 @@ pub fn deserialize_svg(path: impl AsRef<Path>, bytes: &[u8]) -> Result<Texture2D
pub fn serialize_img(tex: &Texture2D, path: &Path) -> Result<RawAssets> {
#![allow(unreachable_code)]
#![allow(unused_variables)]
let format: image::ImageOutputFormat = match path.extension().unwrap().to_str().unwrap() {
let format: ImageFormat = match path.extension().unwrap().to_str().unwrap() {
"png" => {
#[cfg(not(feature = "png"))]
return Err(Error::FeatureMissing("png".to_string()));
#[cfg(feature = "png")]
image::ImageOutputFormat::Png
ImageFormat::Png
}
"jpeg" | "jpg" => {
#[cfg(not(feature = "jpeg"))]
return Err(Error::FeatureMissing("jpeg".to_string()));
#[cfg(feature = "jpeg")]
image::ImageOutputFormat::Jpeg(100)
ImageFormat::Jpeg
}
"bmp" => {
#[cfg(not(feature = "bmp"))]
return Err(Error::FeatureMissing("bmp".to_string()));
#[cfg(feature = "bmp")]
image::ImageOutputFormat::Bmp
ImageFormat::Bmp
}
"tga" => {
#[cfg(not(feature = "tga"))]
return Err(Error::FeatureMissing("tga".to_string()));
#[cfg(feature = "tga")]
image::ImageOutputFormat::Tga
ImageFormat::Tga
}
"tiff" | "tif" => {
#[cfg(not(feature = "tiff"))]
return Err(Error::FeatureMissing("tiff".to_string()));
#[cfg(feature = "tiff")]
image::ImageOutputFormat::Tiff
ImageFormat::Tiff
}
"gif" => {
#[cfg(not(feature = "gif"))]
return Err(Error::FeatureMissing("gif".to_string()));
#[cfg(feature = "gif")]
image::ImageOutputFormat::Gif
ImageFormat::Gif
}
_ => return Err(Error::FailedSerialize(path.to_str().unwrap().to_string())),
};
Expand All @@ -173,14 +158,29 @@ pub fn serialize_img(tex: &Texture2D, path: &Path) -> Result<RawAssets> {
)
.unwrap(),
),
TextureData::RgbaU8(data) => DynamicImage::ImageRgba8(
ImageBuffer::from_raw(
tex.width,
tex.height,
data.iter().flat_map(|v| *v).collect::<Vec<_>>(),
)
.unwrap(),
),
TextureData::RgbaU8(data) => {
if format == ImageFormat::Jpeg {
DynamicImage::ImageRgb8(
ImageBuffer::from_raw(
tex.width,
tex.height,
data.iter()
.flat_map(|v| [v[0], v[1], v[2]])
.collect::<Vec<_>>(),
)
.unwrap(),
)
} else {
DynamicImage::ImageRgba8(
ImageBuffer::from_raw(
tex.width,
tex.height,
data.iter().flat_map(|v| *v).collect::<Vec<_>>(),
)
.unwrap(),
)
}
}
_ => unimplemented!(),
};
let mut bytes: Vec<u8> = Vec::new();
Expand Down Expand Up @@ -212,7 +212,11 @@ mod test {

if format == "jpeg" || format == "jpg" {
if let crate::TextureData::RgbU8(data) = tex.data {
assert_eq!(data, vec![[4, 0, 0], [250, 0, 1], [0, 254, 1], [1, 2, 253]]);
// Jpeg is not lossless
assert_eq!(
data,
vec![[47, 0, 18], [227, 0, 0], [0, 245, 0], [15, 32, 255]]
);
} else {
panic!("Wrong texture data: {:?}", tex.data)
}
Expand Down
2 changes: 1 addition & 1 deletion src/io/pcd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub fn deserialize_pcd(raw_assets: &mut RawAssets, path: &PathBuf) -> Result<Sce
let z_index = schema.iter().position(|f| f.name == "z").unwrap();
let rgb_index = schema.iter().position(|f| f.name == "rgb");

let points = reader.collect::<pcd_rs::anyhow::Result<Vec<_>>>()?;
let points = reader.collect::<pcd_rs::Result<Vec<_>>>()?;
let positions = points
.iter()
.map(|p| {
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ pub enum Error {

#[cfg(feature = "pcd")]
#[error("error while parsing an .pcd file")]
Pcd(#[from] pcd_rs::anyhow::Error),
Pcd(#[from] pcd_rs::Error),

#[cfg(any(not(target_arch = "wasm32"), feature = "stl"))]
#[error("io error")]
Expand Down
Binary file modified test_data/test.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test_data/test.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test_data/test.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test_data/test.tga
Binary file not shown.

0 comments on commit 84e30ec

Please sign in to comment.