mirror of
https://codeberg.org/icewind/vbsp.git
synced 2026-06-03 10:44:07 +02:00
serde entity parsing
This commit is contained in:
parent
84a66e06a3
commit
f6e2a200ca
14 changed files with 682 additions and 1088 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -1,8 +1,8 @@
|
|||
use crate::error::UnsupportedLumpVersion;
|
||||
use crate::{lzma_decompress_with_header, BspError, FixedString, Vector};
|
||||
use crate::{lzma_decompress_with_header, Angles, BspError, FixedString, Vector};
|
||||
use binrw::{BinRead, BinReaderExt, BinResult, Endian};
|
||||
use bitflags::bitflags;
|
||||
use cgmath::{Deg, Quaternion, Rotation3};
|
||||
use cgmath::Quaternion;
|
||||
use std::borrow::Cow;
|
||||
use std::io::{Cursor, Read, Seek};
|
||||
use std::mem::size_of;
|
||||
|
|
@ -121,7 +121,7 @@ pub struct StaticPropLumps {
|
|||
#[derive(Debug, Clone)]
|
||||
pub struct StaticPropLump {
|
||||
pub origin: Vector,
|
||||
angles: [f32; 3],
|
||||
angles: Angles,
|
||||
pub prop_type: u16,
|
||||
pub first_leaf: u16,
|
||||
pub leaf_count: u16,
|
||||
|
|
@ -140,10 +140,7 @@ pub struct StaticPropLump {
|
|||
impl StaticPropLump {
|
||||
/// Get the rotation of the prop as quaternion
|
||||
pub fn rotation(&self) -> Quaternion<f32> {
|
||||
// angles are applied in roll, pitch, yaw order
|
||||
Quaternion::from_angle_y(Deg(self.angles[1]))
|
||||
* Quaternion::from_angle_x(Deg(self.angles[0]))
|
||||
* Quaternion::from_angle_z(Deg(self.angles[2]))
|
||||
self.angles.as_quaternion()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -209,7 +206,7 @@ impl From<StaticPropLumpFlagsV6> for StaticPropLumpFlags {
|
|||
#[derive(BinRead)]
|
||||
struct StaticPropLumpV6 {
|
||||
pub origin: Vector,
|
||||
pub angles: [f32; 3],
|
||||
pub angles: Angles,
|
||||
pub prop_type: u16,
|
||||
pub first_leaf: u16,
|
||||
pub leaf_count: u16,
|
||||
|
|
@ -249,7 +246,7 @@ bitflags! {
|
|||
#[derive(BinRead)]
|
||||
struct StaticPropLumpV10 {
|
||||
pub origin: Vector,
|
||||
pub angles: [f32; 3],
|
||||
pub angles: Angles,
|
||||
pub prop_type: u16,
|
||||
pub first_leaf: u16,
|
||||
pub leaf_count: u16,
|
||||
|
|
|
|||
|
|
@ -10,13 +10,17 @@ pub use self::game::*;
|
|||
pub use self::prop::PropPlacement;
|
||||
pub use self::vector::*;
|
||||
use crate::bspfile::LumpType;
|
||||
use crate::error::EntityParseError;
|
||||
use crate::{BspResult, StringError};
|
||||
use arrayvec::ArrayString;
|
||||
use binrw::error::CustomError;
|
||||
use binrw::{BinRead, BinResult, Endian};
|
||||
use bitflags::bitflags;
|
||||
use bv::BitVec;
|
||||
use cgmath::{Deg, Quaternion, Rotation3};
|
||||
use num_enum::{TryFromPrimitive, TryFromPrimitiveError};
|
||||
use serde::de::{Error, Unexpected};
|
||||
use serde::{Deserialize, Deserializer};
|
||||
use std::borrow::Cow;
|
||||
use std::cmp::min;
|
||||
use std::fmt;
|
||||
|
|
@ -24,6 +28,7 @@ use std::fmt::{Debug, Display, Formatter};
|
|||
use std::io::{Cursor, Read, Seek};
|
||||
use std::mem::{align_of, size_of};
|
||||
use std::ops::Index;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Mutex;
|
||||
use zip::result::ZipError;
|
||||
use zip::ZipArchive;
|
||||
|
|
@ -531,3 +536,42 @@ where
|
|||
err: Box::new(e),
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, BinRead)]
|
||||
pub struct Angles {
|
||||
pitch: f32,
|
||||
yaw: f32,
|
||||
roll: f32,
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for Angles {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let str = <&str>::deserialize(deserializer)?;
|
||||
str.parse()
|
||||
.map_err(|_| D::Error::invalid_value(Unexpected::Other(str), &"a list of angles"))
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Angles {
|
||||
type Err = EntityParseError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut floats = s.split(' ').map(f32::from_str);
|
||||
let pitch = floats.next().ok_or(EntityParseError::ElementCount)??;
|
||||
let yaw = floats.next().ok_or(EntityParseError::ElementCount)??;
|
||||
let roll = floats.next().ok_or(EntityParseError::ElementCount)??;
|
||||
Ok(Angles { pitch, yaw, roll })
|
||||
}
|
||||
}
|
||||
|
||||
impl Angles {
|
||||
fn as_quaternion(&self) -> Quaternion<f32> {
|
||||
// angles are applied in roll, pitch, yaw order
|
||||
Quaternion::from_angle_y(Deg(self.yaw))
|
||||
* Quaternion::from_angle_x(Deg(self.pitch))
|
||||
* Quaternion::from_angle_z(Deg(self.roll))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::{Handle, PropDynamic, PropDynamicOverride, StaticPropLump, Vector};
|
||||
use cgmath::{Deg, Quaternion, Rotation3};
|
||||
use cgmath::Quaternion;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PropPlacement<'a> {
|
||||
|
|
@ -22,17 +22,14 @@ impl<'a> Handle<'a, StaticPropLump> {
|
|||
}
|
||||
}
|
||||
|
||||
fn rotation(angles: [f32; 3]) -> Quaternion<f32> {
|
||||
Quaternion::from_angle_y(Deg(angles[1]))
|
||||
* Quaternion::from_angle_x(Deg(angles[0]))
|
||||
* Quaternion::from_angle_z(Deg(angles[2]))
|
||||
}
|
||||
|
||||
impl<'a> PropDynamic<'a> {
|
||||
pub fn as_prop_placement(&self) -> PropPlacement<'a> {
|
||||
if self.model.contains("slide_large") | self.model.contains("resup") {
|
||||
// dbg!(self);
|
||||
}
|
||||
PropPlacement {
|
||||
model: self.model,
|
||||
rotation: rotation(self.angles),
|
||||
rotation: self.angles.as_quaternion(),
|
||||
scale: self.scale,
|
||||
origin: self.origin,
|
||||
skin: 0,
|
||||
|
|
@ -44,7 +41,7 @@ impl<'a> PropDynamicOverride<'a> {
|
|||
pub fn as_prop_placement(&self) -> PropPlacement<'a> {
|
||||
PropPlacement {
|
||||
model: self.model,
|
||||
rotation: rotation(self.angles),
|
||||
rotation: self.angles.as_quaternion(),
|
||||
scale: self.scale,
|
||||
origin: self.origin,
|
||||
skin: 0,
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
use crate::error::EntityParseError;
|
||||
use binrw::BinRead;
|
||||
use cgmath::Vector3;
|
||||
use serde::de::{Error, Unexpected};
|
||||
use serde::{Deserialize, Deserializer};
|
||||
use std::cmp::Ordering;
|
||||
use std::fmt::Debug;
|
||||
use std::ops::{Add, Mul, Sub};
|
||||
use std::str::FromStr;
|
||||
|
||||
#[derive(Debug, Clone, Copy, BinRead)]
|
||||
#[derive(Debug, Clone, Copy, BinRead, Default)]
|
||||
pub struct Vector {
|
||||
pub x: f32,
|
||||
pub y: f32,
|
||||
|
|
@ -110,3 +112,14 @@ impl From<Vector> for Vector3<f32> {
|
|||
Vector3::new(v.x, v.y, v.z)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for Vector {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let str = <&str>::deserialize(deserializer)?;
|
||||
str.parse()
|
||||
.map_err(|_| D::Error::invalid_value(Unexpected::Other(str), &"a vector"))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue