From cbf4d5df09c094f1fcdef3c25daaeb7075eb60ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thea=20Sch=C3=B6bl?= Date: Wed, 10 May 2023 00:45:09 +0200 Subject: [PATCH] gradient texture --- rust/lightwave/README.md | 18 ++--- .../lwo2/sub_tags/blocks/gradient_texture.rs | 68 +++++++++++++++++++ .../lightwave/src/lwo2/sub_tags/blocks/mod.rs | 17 ++++- .../sub_tags/blocks/procedural_texture.rs | 0 .../src/lwo2/sub_tags/blocks/shaders.rs | 11 +++ rust/lightwave/src/lwo2/sub_tags/mod.rs | 12 +++- 6 files changed, 113 insertions(+), 13 deletions(-) create mode 100644 rust/lightwave/src/lwo2/sub_tags/blocks/gradient_texture.rs create mode 100644 rust/lightwave/src/lwo2/sub_tags/blocks/procedural_texture.rs create mode 100644 rust/lightwave/src/lwo2/sub_tags/blocks/shaders.rs diff --git a/rust/lightwave/README.md b/rust/lightwave/README.md index 15d4df3..e6d13a0 100644 --- a/rust/lightwave/README.md +++ b/rust/lightwave/README.md @@ -108,8 +108,8 @@ Progress: About 90% ([LWO2 Spec](http://static.lightwave3d.com/sdk/2015/html/fil Ordinal Strings: * ✅ [Image Texture Map](#image-texture-map) `IMAP` * ❌ [Procedural Texture](#procedural-texture) `PROC` -* ❌ [Gradient Texture](#gradient-texture) `GRAD` -* ❌ Shader Plugin `SHDR` +* ✅ [Gradient Texture](#gradient-texture) `GRAD` +* ✅ [Shader Plugin](#shaders) `SHDR` #### Shared @@ -158,16 +158,16 @@ Ordinal Strings: | Chunk | Tag | Status | |----------------|-------------------|--------| -| Parameter Name | `PNAM` | ❌ | -| Item Name | `INAM` | ❌ | -| Gradient Range | `GRST`
`GREN` | ❌ | -| Repeat Mode | `GRPT` | ❌ | -| Key Values | `FKEY` | ❌ | -| Key Parameters | `IKEY` | ❌ | +| Parameter Name | `PNAM` | ✅ | +| Item Name | `INAM` | ✅ | +| Gradient Range | `GRST`
`GREN` | ✅ | +| Repeat Mode | `GRPT` | ✅ | +| Key Values | `FKEY` | ✅ | +| Key Parameters | `IKEY` | ✅ | #### Shaders | Chunk | Tag | Status | |------------------|--------|--------| -| Shader Algorithm | `FUNC` | ❌ | +| Shader Algorithm | `FUNC` | ✅ | diff --git a/rust/lightwave/src/lwo2/sub_tags/blocks/gradient_texture.rs b/rust/lightwave/src/lwo2/sub_tags/blocks/gradient_texture.rs new file mode 100644 index 0000000..7555b72 --- /dev/null +++ b/rust/lightwave/src/lwo2/sub_tags/blocks/gradient_texture.rs @@ -0,0 +1,68 @@ +use crate::iff::SubChunk; +use crate::lwo2::sub_tags::Name; +use binrw::binread; + +#[binread] +#[derive(Debug)] +pub enum GradientTextureSubChunk { + #[br(magic(b"PNAM"))] + ParameterName(SubChunk), + #[br(magic(b"INAM"))] + ItemName(SubChunk), + #[br(magic(b"GRST"))] + GradientRangeStart(SubChunk), + #[br(magic(b"GREN"))] + GradientRangeEnd(SubChunk), + #[br(magic(b"GRPT"))] + RepeatMode(SubChunk), + #[br(magic(b"FKEY"))] + KeyValues(SubChunk), + #[br(magic(b"IKEY"))] + KeyParameters(SubChunk), +} + +/// The repeat mode. This is currently undefined. +#[binread] +#[br(import(length: u32))] +#[derive(Debug)] +pub struct KeyParameters { + #[br(count = length / 2)] + pub repeat_mode: Vec, +} + +/// The transfer function is defined by an array of keys, each with an input value and an RGBA +/// output vector. Given an input value, the gradient can be evaluated by selecting the keys whose +/// positions bracket the value and interpolating between their outputs. If the input value is lower +/// than the first key or higher than the last key, the gradient value is the value of the closest +/// key. +#[binread] +#[br(import(length: u32))] +#[derive(Debug)] +pub struct KeyValues { + #[br(count = length / 18)] + pub key_values: Vec, +} + +#[binread] +#[derive(Debug)] +pub struct KeyValue { + pub input: f32, + pub output: [f32; 4], +} + +/// The start and end of the input range. These values only affect the display of the gradient +/// in the user interface. They don't affect rendering. +#[binread] +#[br(import(_length: u32))] +#[derive(Debug)] +pub struct GradientRange { + pub name: f32, +} + +/// The repeat mode. This is currently undefined. +#[binread] +#[br(import(_length: u32))] +#[derive(Debug)] +pub struct RepeatMode { + pub repeat_mode: u16, +} diff --git a/rust/lightwave/src/lwo2/sub_tags/blocks/mod.rs b/rust/lightwave/src/lwo2/sub_tags/blocks/mod.rs index 15411f7..688de19 100644 --- a/rust/lightwave/src/lwo2/sub_tags/blocks/mod.rs +++ b/rust/lightwave/src/lwo2/sub_tags/blocks/mod.rs @@ -1,11 +1,16 @@ use crate::binrw_helpers::until_size_limit; use crate::iff::SubChunk; +use crate::lwo2::sub_tags::blocks::gradient_texture::GradientTextureSubChunk; use crate::lwo2::sub_tags::blocks::image_texture::SurfaceBlockImageTextureSubChunk; +use crate::lwo2::sub_tags::blocks::shaders::ShaderAlgorithm; use crate::lwo2::sub_tags::EnableState; use crate::lwo2::vx; use binrw::binread; +pub mod gradient_texture; pub mod image_texture; +pub mod procedural_texture; +pub mod shaders; pub mod texture_mapping; #[binread] @@ -21,9 +26,17 @@ pub enum SurfaceBlocks { #[br(magic(b"PROC"))] ProceduralTexture, #[br(magic(b"GRAD"))] - GradientTexture, + GradientTexture { + header: SubChunk, + #[br(parse_with = until_size_limit(length as u64 - (header.length as u64 + 2 + 4)))] + attributes: Vec, + }, #[br(magic(b"SHDR"))] - ShaderPlugin, + ShaderPlugin { + header: SubChunk, + #[br(magic(b"FUNC"))] + algorithm: SubChunk, + }, } #[binread] diff --git a/rust/lightwave/src/lwo2/sub_tags/blocks/procedural_texture.rs b/rust/lightwave/src/lwo2/sub_tags/blocks/procedural_texture.rs new file mode 100644 index 0000000..e69de29 diff --git a/rust/lightwave/src/lwo2/sub_tags/blocks/shaders.rs b/rust/lightwave/src/lwo2/sub_tags/blocks/shaders.rs new file mode 100644 index 0000000..c3d07a0 --- /dev/null +++ b/rust/lightwave/src/lwo2/sub_tags/blocks/shaders.rs @@ -0,0 +1,11 @@ +use binrw::{binread, NullString}; + +#[binread] +#[br(import(length: u32))] +#[derive(Debug)] +pub struct ShaderAlgorithm { + #[br(align_after = 2)] + pub algorithm_name: NullString, + #[br(count = length - (algorithm_name.len() as u32 + 1))] + pub data: Vec, +} diff --git a/rust/lightwave/src/lwo2/sub_tags/mod.rs b/rust/lightwave/src/lwo2/sub_tags/mod.rs index 929f109..098cf8a 100644 --- a/rust/lightwave/src/lwo2/sub_tags/mod.rs +++ b/rust/lightwave/src/lwo2/sub_tags/mod.rs @@ -1,9 +1,9 @@ use crate::lwo2::vx; -use binrw::binread; +use binrw::{binread, NullString}; pub mod blocks; -pub mod surface_parameters; pub mod plugin; +pub mod surface_parameters; #[binread] #[br(import(_length: u32))] @@ -14,6 +14,14 @@ pub struct VectorEnvelope { pub envelope: u32, } +#[binread] +#[br(import(_length: u32))] +#[derive(Debug)] +pub struct Name { + #[br(align_after = 2)] + pub name: NullString, +} + #[binread] #[br(import(_length: u32))] #[derive(Debug)]