From 1c274c949e15271e117f8317eaf69de04ac15d2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thea=20Sch=C3=B6bl?= Date: Wed, 10 May 2023 00:28:42 +0200 Subject: [PATCH] implement envelope --- rust/lightwave/README.md | 10 +++---- rust/lightwave/src/lwo2/sub_tags/mod.rs | 1 + rust/lightwave/src/lwo2/sub_tags/plugin.rs | 16 +++++++++++ rust/lightwave/src/lwo2/tags/envelope.rs | 21 ++------------ rust/lightwave/src/lwo2/tags/image_clip.rs | 32 ++++++++++++++++++++-- 5 files changed, 53 insertions(+), 27 deletions(-) create mode 100644 rust/lightwave/src/lwo2/sub_tags/plugin.rs diff --git a/rust/lightwave/README.md b/rust/lightwave/README.md index bd472b8..15d4df3 100644 --- a/rust/lightwave/README.md +++ b/rust/lightwave/README.md @@ -27,7 +27,7 @@ Progress: About 90% ([LWO2 Spec](http://static.lightwave3d.com/sdk/2015/html/fil | Discontinuous Vertex Mapping | `VMAD` | ✅ | | Vertex Map Parameter | `VMPA` | ✅ | | [Envelope Definition](#envelope-subchunks) | `ENVL` | ✅ | -| [Image (-Sequence)](#clip-subchunks) | `CLIP` | 🚧 | +| [Image (-Sequence)](#clip-subchunks) | `CLIP` | ✅ | | [Surface Definition](#surface-subchunks) | `SURF` | 🚧 | | Bounding Box | `BBOX` | ✅ | | Description Line | `DESC` | ✅ | @@ -54,7 +54,7 @@ Progress: About 90% ([LWO2 Spec](http://static.lightwave3d.com/sdk/2015/html/fil |----------------------|--------|--------| | Still Image | `STIL` | ✅ | | Image Sequence | `ISEQ` | ✅ | -| Plugin Animation | `ANIM` | ❌ | +| Plugin Animation | `ANIM` | ✅ | | Reference (Clone) | `XREF` | ✅ | | Flag (Undocumented) | `FLAG` | ⚠️ | | Color-cycling Still | `STCC` | ✅ | @@ -68,9 +68,9 @@ Progress: About 90% ([LWO2 Spec](http://static.lightwave3d.com/sdk/2015/html/fil | Saturation | `SATR` | ✅ | | Hue | `HUE` | ✅ | | Gamma Correction | `GAMM` | ✅ | -| Negative | `NEGA` | ❌ | -| Plugin Image Filters | `IFLT` | ❌ | -| Plugin Pixel Filters | `PFLT` | ❌ | +| Negative | `NEGA` | ✅ | +| Plugin Image Filters | `IFLT` | ✅ | +| Plugin Pixel Filters | `PFLT` | ✅ | ### Surface Subchunks diff --git a/rust/lightwave/src/lwo2/sub_tags/mod.rs b/rust/lightwave/src/lwo2/sub_tags/mod.rs index ba2e010..929f109 100644 --- a/rust/lightwave/src/lwo2/sub_tags/mod.rs +++ b/rust/lightwave/src/lwo2/sub_tags/mod.rs @@ -3,6 +3,7 @@ use binrw::binread; pub mod blocks; pub mod surface_parameters; +pub mod plugin; #[binread] #[br(import(_length: u32))] diff --git a/rust/lightwave/src/lwo2/sub_tags/plugin.rs b/rust/lightwave/src/lwo2/sub_tags/plugin.rs new file mode 100644 index 0000000..4654e81 --- /dev/null +++ b/rust/lightwave/src/lwo2/sub_tags/plugin.rs @@ -0,0 +1,16 @@ +use binrw::{binread, NullString, PosValue}; + +#[binread] +#[br(import(length: u32))] +#[derive(Debug)] +pub struct PluginServerNameAndData { + #[br(temp)] + start_pos: PosValue<()>, + #[br(align_after = 2)] + pub server_name: NullString, + pub flags: u16, + #[br(temp)] + end_pos: PosValue<()>, + #[br(count = length as u64 - (end_pos.pos - start_pos.pos))] + pub parameters: Vec, +} diff --git a/rust/lightwave/src/lwo2/tags/envelope.rs b/rust/lightwave/src/lwo2/tags/envelope.rs index d58a206..63c5f1b 100644 --- a/rust/lightwave/src/lwo2/tags/envelope.rs +++ b/rust/lightwave/src/lwo2/tags/envelope.rs @@ -2,6 +2,7 @@ use crate::binrw_helpers::until_size_limit; use crate::iff::SubChunk; use crate::lwo2::vx; use binrw::{binread, NullString, PosValue}; +use crate::lwo2::sub_tags::plugin::PluginServerNameAndData; #[binread] #[br(import(length: u32))] @@ -31,7 +32,7 @@ pub enum EnvelopeSubChunk { #[br(magic(b"SPAN"))] IntervalInterpolation(SubChunk), #[br(magic(b"CHAN"))] - PluginChannelModifiers(SubChunk), + PluginChannelModifiers(SubChunk), #[br(magic(b"NAME"))] ChannelName(SubChunk), } @@ -46,24 +47,6 @@ pub struct PluginChannelName { pub channel_name: NullString, } -/// Channel modifiers can be associated with an envelope. Each channel chunk contains the name of -/// the plug-in and some flag bits. Only the first flag bit is defined; if set, the plug-in is -/// disabled. The data that follows this, if any, is owned by the plug-in. -#[binread] -#[br(import(length: u32))] -#[derive(Debug)] -pub struct PluginChannelModifiers { - #[br(temp)] - start_pos: PosValue<()>, - #[br(align_after = 2)] - pub server_name: NullString, - pub flags: u16, - #[br(temp)] - end_pos: PosValue<()>, - #[br(count = length as u64 - (end_pos.pos - start_pos.pos))] - pub parameters: Vec, -} - /// Defines the interpolation between the most recent KEY chunk and the KEY immediately before it in /// time. The type identifies the interpolation algorithm and can be STEP, LINE, TCB /// (Kochanek-Bartels), HERM (Hermite), BEZI (1D Bezier) or BEZ2 (2D Bezier). diff --git a/rust/lightwave/src/lwo2/tags/image_clip.rs b/rust/lightwave/src/lwo2/tags/image_clip.rs index 4559ecd..587cbac 100644 --- a/rust/lightwave/src/lwo2/tags/image_clip.rs +++ b/rust/lightwave/src/lwo2/tags/image_clip.rs @@ -1,7 +1,8 @@ use crate::binrw_helpers::until_size_limit; use crate::iff::SubChunk; -use crate::lwo2::sub_tags::ValueEnvelope; -use binrw::{binread, NullString}; +use crate::lwo2::sub_tags::plugin::PluginServerNameAndData; +use crate::lwo2::sub_tags::{EnableState, ValueEnvelope}; +use binrw::{binread, NullString, PosValue}; /// Describes an image or a sequence of images. Surface definitions specify images by referring to /// CLIP chunks. The term "clip" is used to describe these because they can be numbered sequences @@ -24,6 +25,8 @@ pub enum ImageClipSubChunk { StillImage(SubChunk), #[br(magic(b"ISEQ"))] ImageSequence(SubChunk), + #[br(magic(b"ANIM"))] + PluginAnimation(SubChunk), #[br(magic(b"XREF"))] Reference(SubChunk), #[br(magic(b"FLAG"))] @@ -46,10 +49,33 @@ pub enum ImageClipSubChunk { Brightness(SubChunk), #[br(magic(b"SATR"))] Saturation(SubChunk), - #[br(magic(b"HUE"))] // TODO: Typo? Docs say it's just "HUE" + #[br(magic(b"HUE\0"))] Hue(SubChunk), #[br(magic(b"GAMM"))] GammaCorrection(SubChunk), + #[br(magic(b"NEGA"))] + Negative(SubChunk), + #[br(magic(b"IFLT"))] + PluginImageFilters(SubChunk), + #[br(magic(b"PFLT"))] + PluginPixelFilters(SubChunk), +} + +#[binread] +#[br(import(_length: u32))] +#[derive(Debug)] +pub struct PluginAnimation { + #[br(temp)] + start_pos: PosValue<()>, + #[br(align_after = 2)] + pub file_name: NullString, + #[br(align_after = 2)] + pub server_name: NullString, + pub flags: u16, + #[br(temp)] + end_pos: PosValue<()>, + #[br(count = end_pos.pos - start_pos.pos)] + pub data: Vec, } /// Contains the color space of the texture. If the flag is 0, then the color space is contained