diff --git a/rust/lightwave/README.md b/rust/lightwave/README.md index 4d98514..4145081 100644 --- a/rust/lightwave/README.md +++ b/rust/lightwave/README.md @@ -1,4 +1,161 @@ # LightWave 3D Rust Parser -* [LWO2 Spec](http://static.lightwave3d.com/sdk/2015/html/filefmts/lwo2.html) - * Progress: about 90% (?) complete, so most things should load. \ No newline at end of file +## LightWave Object (LWO2) + +Progress: About 90% ([LWO2 Spec](http://static.lightwave3d.com/sdk/2015/html/filefmts/lwo2.html)) + +| Chunk | Tag | Status | +|--------------------------------------------|--------|--------| +| Layer | `LAYR` | ✅ | +| Point List | `PNTS` | ✅ | +| Vertex Mapping | `VMAP` | ✅ | +| Polygon List | `POLS` | ✅ | +| Tag Strings | `TAGS` | ✅ | +| Polygon Tag Mapping | `PTAG` | ✅ | +| Discontinuous Vertex Mapping | `VMAD` | ✅ | +| Vertex Map Parameter | `VMPA` | ✅ | +| [Envelope Definition](#envelope-subchunks) | `ENVL` | ❌ | +| [Image (-Sequence)](#clip-subchunks) | `CLIP` | 🚧 | +| [Surface Definition](#surface-subchunks) | `SURF` | 🚧 | +| Bounding Box | `BBOX` | ✅ | +| Description Line | `DESC` | ❌ | +| Commentary Text | `TEXT` | ❌ | +| Thumbnail Icon Image | `ICON` | ❌ | + + +### Envelope Subchunks + +| Chunk | Tag | Status | +|--------------------------|--------|--------| +| Envelope Type | `TYPE` | ❌ | +| Pre-Behavior | `PRE` | ❌ | +| Post-Behavior | `POST` | ❌ | +| Keyframe Time and Value | `KEY` | ❌ | +| Interval Interpolation | `SPAN` | ❌ | +| Plugin Channel Modifiers | `CHAN` | ❌ | +| Channel Name | `NAME` | ❌ | + + +### Clip Subchunks + +| Chunk | Tag | Status | +|----------------------|--------|--------| +| Still Image | `STIL` | ✅ | +| Image Sequence | `ISEQ` | ✅ | +| Plugin Animation | `ANIM` | ❌ | +| Reference (Clone) | `XREF` | ✅ | + | Flag (Undocumented) | `FLAG` | 🚧 | +| Color-cycling Still | `STCC` | ✅ | +| Time | `TIME` | ✅ | +| Color Space RGB | `CLRS` | ✅ | +| Color Space Alpha | `CLRA` | ✅ | +| Image Filtering | `FILT` | ✅ | +| Image Dithering | `DITH` | ✅ | +| Contrast | `CONT` | ✅ | +| Brightness | `BRIT` | ✅ | +| Saturation | `SATR` | ✅ | +| Hue | `HUE` | ✅ | +| Gamma Correction | `GAMM` | ✅ | +| Negative | `NEGA` | ❌ | +| Plugin Image Filters | `IFLT` | ❌ | +| Plugin Pixel Filters | `PFLT` | ❌ | + + +### Surface Subchunks + +### Basic Surface Parameters + +| Chunk | Tag | Status | +|-----------------------------------|----------------------------------------------------------|--------| +| Base Color | `COLR` | ✅ | +| Base Shading Values | `DIFF`
`LUMI`
`SPEC`
`REFL`
`TRAN`
`TRNL` | ✅ | +| Specular Glossiness | `GLOS` | ✅ | +| Diffuse Sharpness | `SHRP` | ✅ | +| Bump Intensity | `BUMP` | ✅ | +| Polygon Sidedness | `SIDE` | ✅ | +| Max Smoothing Angle | `SMAN` | ✅ | +| Reflection Options | `RFOP` | ✅ | +| Reflection Map Image | `RIMG` | ✅ | +| Reflection Map Image Seam Angle | `RSAN` | ❌ | +| Reflection Blurring | `RBLR` | ❌ | +| Refractive Index | `RIND` | ❌ | +| Transparency Options | `TROP` | ❌ | +| Refraction Map Image | `TIMG` | ❌ | +| Refraction Blurring | `TBLR` | ✅ | +| Color Highlights | `CLRH` | ✅ | +| Color Filter | `CLRF` | ✅ | +| Additive Transparency | `ADRT` | ✅ | +| Glow Effect | `GLOW` | ❌ | +| Render Outlines | `LINE` | ❌ | +| Alpha Mode | `ALPH` | ❌ | +| Vertex Color Map | `VCOL` | ❌ | +| [Surface Blocks](#surface-blocks) | `BLOK` | 🚧 | + +### Surface Blocks + +Ordinal Strings: +* ✅ [Image Texture Map](#image-texture-map) `IMAP` +* ❌ [Procedural Texture](#procedural-texture) `PROC` +* ❌ [Gradient Texture](#gradient-texture) `GRAD` +* ❌ Shader Plugin `SHDR` + +#### Shared + +| Chunk | Tag | Status | +|-------------------------|--------|--------| +| Texture Channel | `CHAN` | ✅ | +| Enable State | `ENAB` | ✅ | +| Opacity | `OPAC` | ✅ | +| Displacement Axis | `AXIS` | ✅ | +| Negative (Undocumented) | `NEGA` | 🚧 | + +#### Texture Mapping + +| Chunk | Tag | Status | +|---------------------|----------------------------|--------| +| Positioning | `CNTR`
`SIZE`
`ROTA` | ✅ | +| Reference Object | `OREF` | ✅ | +| Falloff | `FALL` | ✅ | +| Coordinate System | `CSYS` | ✅ | + +#### Image Texture Map + +| Chunk | Tag | Status | +|-------------------------------------|------------------|--------| +| [Texture Mapping](#texture-mapping) | `TMAP` | ✅ | +| Projection Mode | `PROJ` | ✅ | +| Major Axis | `AXIS` | ✅ | +| Image Map | `IMAG` | ✅ | +| Image Wrap Options | `WRAP` | ✅ | +| Image Wrap Amount | `WRPW`
`WRPH` | ✅ | +| UV Vertex Map | `VMAP` | ✅ | +| Antialiasing Strength | `AAST` | ✅ | +| Pixel Blending | `PIXB` | ✅ | +| Sticky Projection | `STCK` | ✅ | +| Texture Ampliture | `TAMP` | ✅ | + +#### Procedural Texture + +| Chunk | Tag | Status | +|--------------------------|--------|--------| +| Axis | `AXIS` | ❌ | +| Basic Value | `VALU` | ❌ | +| Algorithm and Parameters | `FUNC` | ❌ | + +#### Gradient Texture + +| Chunk | Tag | Status | +|----------------|-------------------|--------| +| 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` | ❌ | diff --git a/rust/lightwave/src/binrw_helpers.rs b/rust/lightwave/src/binrw_helpers.rs index 664c6c6..3504faf 100644 --- a/rust/lightwave/src/binrw_helpers.rs +++ b/rust/lightwave/src/binrw_helpers.rs @@ -1,8 +1,13 @@ use crate::lwo2::vx; -use binrw::{BinRead, BinResult, Endian}; +use binrw::{binread, BinRead, BinResult, Endian}; use std::io::{Read, Seek}; use std::iter::from_fn; +#[binread] +#[br(assert(false, "Not implemented yet"))] +#[derive(Debug)] +pub struct BinReadTodo(); + pub fn until_size_limit( limit: u64, ) -> impl Fn(&mut R, Endian, Arg) -> BinResult diff --git a/rust/lightwave/src/lwo2/sub_tags/mod.rs b/rust/lightwave/src/lwo2/sub_tags/mod.rs index f779d4f..c06d870 100644 --- a/rust/lightwave/src/lwo2/sub_tags/mod.rs +++ b/rust/lightwave/src/lwo2/sub_tags/mod.rs @@ -1,11 +1,49 @@ -use binrw::binread; use crate::lwo2::sub_tags::envelope_type::EnvelopeType; +use crate::lwo2::vx; +use binrw::binread; pub mod envelope_type; +pub mod surface_block_image_texture; +pub mod surface_blocks; +pub mod surface_parameters; +pub mod texture_mapping; #[binread] #[derive(Debug)] pub enum SubTag { #[br(magic(b"TYPE"))] - EnvelopeType(EnvelopeType) + EnvelopeType(EnvelopeType), +} + +#[binread] +#[br(import(_length: u32))] +#[derive(Debug)] +pub struct VectorEnvelope { + pub base_color: [f32; 3], + #[br(parse_with = vx)] + pub envelope: u32, +} + +#[binread] +#[br(import(_length: u32))] +#[derive(Debug)] +pub struct ValueEnvelope { + pub value: f32, + #[br(parse_with = vx)] + pub envelope: u32, +} + +#[binread] +#[br(import(_length: u32))] +#[derive(Debug)] +pub struct VxReference { + #[br(parse_with = vx)] + pub texture_image: u32, +} + +#[binread] +#[br(import(_length: u32))] +#[derive(Debug)] +pub struct EnableState { + pub enable: u16, } diff --git a/rust/lightwave/src/lwo2/sub_tags/surface_block_image_texture.rs b/rust/lightwave/src/lwo2/sub_tags/surface_block_image_texture.rs new file mode 100644 index 0000000..76269e4 --- /dev/null +++ b/rust/lightwave/src/lwo2/sub_tags/surface_block_image_texture.rs @@ -0,0 +1,108 @@ +use crate::iff::SubChunk; +use crate::lwo2::sub_tags::texture_mapping::TextureMapping; +use crate::lwo2::sub_tags::{ValueEnvelope, VxReference}; +use crate::lwo2::vx; +use binrw::{binread, NullString}; + +#[binread] +#[derive(Debug)] +pub enum SurfaceBlockImageTextureSubChunk { + #[br(magic(b"TMAP"))] + TextureMapping(SubChunk), + #[br(magic(b"PROJ"))] + ProjectionMode(SubChunk), + #[br(magic(b"AXIS"))] + MajorAxis(SubChunk), + #[br(magic(b"IMAG"))] + ImageMap(SubChunk), + #[br(magic(b"WRAP"))] + ImageWrapOptions(SubChunk), + #[br(magic(b"WRPW"))] + ImageWrapAmountWidth(SubChunk), + #[br(magic(b"WRPH"))] + ImageWrapAmountHeight(SubChunk), + #[br(magic(b"VMAP"))] + UvVertexMap(SubChunk), + #[br(magic(b"AAST"))] + AntialiasingStrength(SubChunk), + #[br(magic(b"PIXB"))] + PixelBlending(SubChunk), + #[br(magic(b"TAMP"))] + TextureAmplitude(SubChunk), +} + +/// The major axis used for planar, cylindrical and spherical projections. The value is 0, 1 or 2 +/// for the X, Y or Z axis. +#[binread] +#[br(import(_length: u32))] +#[derive(Debug)] +pub struct MajorAxis { + pub texture_axis: u16, +} + +/// Pixel blending enlarges the sample filter when it would otherwise be smaller than a single +/// image map pixel. If the low-order flag bit is set, then pixel blending is enabled. +#[binread] +#[br(import(_length: u32))] +#[derive(Debug)] +pub struct PixelBlending { + pub flags: u16, +} + +/// The low bit of the flags word is an enable flag for texture antialiasing. The antialiasing +/// strength is proportional to the width of the sample filter, so larger values sample a larger +/// area of the image. +#[binread] +#[br(import(_length: u32))] +#[derive(Debug)] +pub struct AntialiasingStrength { + pub flags: u16, + pub strength: f32, +} + +#[binread] +#[br(import(_length: u32))] +#[derive(Debug)] +pub struct UvMap { + #[br(align_after = 2)] + pub txuv_map_name: NullString, +} + +#[binread] +#[br(import(_length: u32))] +#[derive(Debug)] +pub struct ImageWrapAmount { + pub cycles: f32, + #[br(parse_with = vx)] + pub envelope: u32, +} + +#[binread] +#[br(import(_length: u32))] +#[derive(Debug)] +pub struct ImageWrapOptions { + pub width_wrap: ImageWrapType, + pub height_wrap: ImageWrapType, +} + +#[binread] +#[br(repr = u16)] +#[derive(Debug)] +pub enum ImageWrapType { + Reset = 0, + Repeat = 1, + Mirror = 2, + Edge = 3, +} + +#[binread] +#[br(repr = u16, import(_length: u32))] +#[derive(Debug)] +pub enum ProjectionMode { + Planar = 0, + Cylindrical = 1, + Spherical = 2, + Cubic = 3, + FrontProjection = 4, + UV = 5, +} diff --git a/rust/lightwave/src/lwo2/sub_tags/surface_blocks.rs b/rust/lightwave/src/lwo2/sub_tags/surface_blocks.rs new file mode 100644 index 0000000..046b3b2 --- /dev/null +++ b/rust/lightwave/src/lwo2/sub_tags/surface_blocks.rs @@ -0,0 +1,122 @@ +use crate::binrw_helpers::until_size_limit; +use crate::iff::SubChunk; +use crate::lwo2::sub_tags::surface_block_image_texture::SurfaceBlockImageTextureSubChunk; +use crate::lwo2::sub_tags::EnableState; +use crate::lwo2::vx; +use binrw::{binread, PosValue}; + +#[binread] +#[br(import(length: u32))] +#[derive(Debug)] +pub struct SurfaceBlocks { + #[br(temp)] + start_pos: PosValue<()>, + pub ordinal: OrdinalString, + pub header: SubChunk, + #[br(temp)] + end_pos: PosValue<()>, + #[br(if(matches!(ordinal, OrdinalString::ImageMapTexture)))] + #[br(parse_with = until_size_limit(length as u64 - (end_pos.pos - start_pos.pos)))] + pub attributes: Vec, +} + +#[binread] +#[br(import(length: u32))] +#[derive(Debug)] +pub struct SurfaceBlockHeader { + #[br(pad_before = 2)] + #[br(parse_with = until_size_limit(length as u64 - 4))] + pub block_attributes: Vec, +} + +#[binread] +#[derive(Debug)] +pub enum SurfaceBlockHeaderSubChunk { + #[br(magic(b"CHAN"))] + Channel(SubChunk), + #[br(magic(b"ENAB"))] + EnabledState(SubChunk), + #[br(magic(b"OPAC"))] + Opacity(SubChunk), + #[br(magic(b"AXIS"))] + DisplacementAxis(SubChunk), + #[br(magic(b"NEGA"))] + Negative(SubChunk), +} + +#[binread] +#[br(import(_length: u32))] +#[derive(Debug)] +pub enum OrdinalString { + #[br(magic(b"IMAP"))] + ImageMapTexture, + #[br(magic(b"PROC"))] + ProceduralTexture, + #[br(magic(b"GRAD"))] + GradientTexture, + #[br(magic(b"SHDR"))] + ShaderPlugin, +} + +#[binread] +#[br(import(_length: u32))] +#[derive(Debug)] +pub struct DisplacementAxis { + pub displacement_axis: u16, +} + +#[binread] +#[br(import(_length: u32))] +#[derive(Debug)] +pub struct Opacity { + pub kind: OpacityType, + pub opacity: f32, + #[br(parse_with = vx)] + pub envelope: u32, +} + +#[binread] +#[br(repr = u16)] +#[derive(Debug)] +pub enum OpacityType { + Normal = 0, + Subtractive = 1, + Difference = 2, + Multiply = 3, + Divide = 4, + Alpha = 5, + TextureDisplacement = 6, + Additive = 7, +} + +#[binread] +#[br(import(_length: u32))] +#[derive(Debug)] +pub struct Channel { + pub texture_channel: TextureChannel, +} + +#[binread] +#[derive(Debug)] +pub enum TextureChannel { + #[br(magic(b"COLR"))] + Color, + #[br(magic(b"DIFF"))] + Diffuse, + #[br(magic(b"LUMI"))] + Luminosity, + #[br(magic(b"SPEC"))] + Specular, + #[br(magic(b"GLOS"))] + Glossy, + #[br(magic(b"REFL"))] + Reflectivity, + #[br(magic(b"TRAN"))] + Transparency, + #[br(magic(b"RIND"))] + RefractiveIndex, + #[br(magic(b"TRNL"))] + Translucency, + #[br(magic(b"BUMP"))] + Bump, +} diff --git a/rust/lightwave/src/lwo2/sub_tags/surface_parameters.rs b/rust/lightwave/src/lwo2/sub_tags/surface_parameters.rs new file mode 100644 index 0000000..1512e92 --- /dev/null +++ b/rust/lightwave/src/lwo2/sub_tags/surface_parameters.rs @@ -0,0 +1,71 @@ +use crate::iff::SubChunk; +use crate::lwo2::sub_tags::surface_blocks::SurfaceBlocks; +use crate::lwo2::sub_tags::{ValueEnvelope, VectorEnvelope, VxReference}; +use binrw::binread; + +#[binread] +#[derive(Debug)] +pub enum SurfaceParameterSubChunk { + #[br(magic(b"COLR"))] + BaseColor(SubChunk), + #[br(magic(b"DIFF"))] + BaseShadingValueDiffuse(SubChunk), + #[br(magic(b"LUMI"))] + BaseShadingValueLuminosity(SubChunk), + #[br(magic(b"SPEC"))] + BaseShadingValueSpecular(SubChunk), + #[br(magic(b"REFL"))] + BaseShadingValueReflectivity(SubChunk), + #[br(magic(b"TRAN"))] + BaseShadingValueTransparency(SubChunk), + #[br(magic(b"TRNL"))] + BaseShadingValueTranslucency(SubChunk), + #[br(magic(b"GLOS"))] + SpecularGlossiness(SubChunk), + #[br(magic(b"SHRP"))] + DiffuseSharpness(SubChunk), + #[br(magic(b"BUMP"))] + BumpIntensity(SubChunk), + #[br(magic(b"SIDE"))] + PolygonSidedness(SubChunk), + #[br(magic(b"SMAN"))] + MaxSmoothingAngle(SubChunk), + #[br(magic(b"BLOK"))] + Blocks(SubChunk), + #[br(magic(b"RFOP"))] + ReflectionOptions(SubChunk), + #[br(magic(b"RIMG"))] + ReflectionMapImage(SubChunk), + #[br(magic(b"TBLR"))] + RefractionBlurring(SubChunk), + #[br(magic(b"CLRH"))] + ColorHighlights(SubChunk), + #[br(magic(b"CLRF"))] + ColorFilter(SubChunk), + #[br(magic(b"ADTR"))] + AdditiveTransparency(SubChunk), +} + +#[binread] +#[br(repr = u16, import(_length: u32))] +#[derive(Debug)] +pub enum ReflectionOptions { + BackdropOnly = 0, + RaytracingAndBackdrop = 1, + SphericalMap = 2, + RaytracingAndSphericalMap = 3, +} + +#[binread] +#[br(import(_length: u32))] +#[derive(Debug)] +pub struct PolygonSidedness { + pub sidedness: u16, +} + +#[binread] +#[br(import(_length: u32))] +#[derive(Debug)] +pub struct MaxSmoothingAngle { + pub max_smoothing_angle: f32, +} diff --git a/rust/lightwave/src/lwo2/sub_tags/texture_mapping.rs b/rust/lightwave/src/lwo2/sub_tags/texture_mapping.rs new file mode 100644 index 0000000..7f0ddcf --- /dev/null +++ b/rust/lightwave/src/lwo2/sub_tags/texture_mapping.rs @@ -0,0 +1,67 @@ +use crate::binrw_helpers::until_size_limit; +use crate::iff::SubChunk; +use crate::lwo2::sub_tags::VectorEnvelope; +use crate::lwo2::vx; +use binrw::{binread, NullString}; + +#[binread] +#[br(import(length: u32))] +#[derive(Debug)] +pub struct TextureMapping { + #[br(parse_with = until_size_limit(length as u64))] + pub attributes: Vec, +} + +#[binread] +#[derive(Debug)] +pub enum TextureMappingSubChunk { + #[br(magic(b"CNTR"))] + Center(SubChunk), + #[br(magic(b"SIZE"))] + Size(SubChunk), + #[br(magic(b"ROTA"))] + Rotation(SubChunk), + #[br(magic(b"OREF"))] + ReferenceObject(SubChunk), + #[br(magic(b"FALL"))] + Falloff(SubChunk), + #[br(magic(b"CSYS"))] + CoordinateSystem(SubChunk), +} + +#[binread] +#[br(repr = u16, import(_length: u32))] +#[derive(Debug)] +pub enum CoordinateSystem { + ObjectCoordinates = 0, + WorldCoordinates = 1, +} + +#[binread] +#[br(import(_length: u32))] +#[derive(Debug)] +pub struct ReferenceObject { + #[br(align_after = 2)] + pub object_name: NullString, +} + +#[binread] +#[br(import(_length: u32))] +#[derive(Debug)] +pub struct Falloff { + pub kind: FalloffType, + pub vector: [f32; 3], + #[br(parse_with = vx)] + pub envelope: u32, +} + +#[binread] +#[br(repr = u16)] +#[derive(Debug)] +pub enum FalloffType { + Cubic = 0, + Spherical = 1, + LinearX = 2, + LinearY = 3, + LinearZ = 4, +} diff --git a/rust/lightwave/src/lwo2/tags/image_clip.rs b/rust/lightwave/src/lwo2/tags/image_clip.rs index 469c1f2..4559ecd 100644 --- a/rust/lightwave/src/lwo2/tags/image_clip.rs +++ b/rust/lightwave/src/lwo2/tags/image_clip.rs @@ -1,6 +1,6 @@ use crate::binrw_helpers::until_size_limit; use crate::iff::SubChunk; -use crate::lwo2::tags::surface_definition::ValueEnvelope; +use crate::lwo2::sub_tags::ValueEnvelope; use binrw::{binread, NullString}; /// Describes an image or a sequence of images. Surface definitions specify images by referring to diff --git a/rust/lightwave/src/lwo2/tags/mod.rs b/rust/lightwave/src/lwo2/tags/mod.rs index 26b322a..c7e102d 100644 --- a/rust/lightwave/src/lwo2/tags/mod.rs +++ b/rust/lightwave/src/lwo2/tags/mod.rs @@ -50,3 +50,4 @@ pub enum Tag { #[br(magic(b"CLIP"))] ImageClip(Chunk), } + diff --git a/rust/lightwave/src/lwo2/tags/surface_definition.rs b/rust/lightwave/src/lwo2/tags/surface_definition.rs index 112f6d0..888dd0b 100644 --- a/rust/lightwave/src/lwo2/tags/surface_definition.rs +++ b/rust/lightwave/src/lwo2/tags/surface_definition.rs @@ -1,6 +1,5 @@ use crate::binrw_helpers::until_size_limit; -use crate::iff::SubChunk; -use crate::lwo2::vx; +use crate::lwo2::sub_tags::surface_parameters::SurfaceParameterSubChunk; use binrw::{binread, NullString, PosValue}; #[binread] @@ -16,366 +15,5 @@ pub struct SurfaceDefinition { #[br(temp)] pub end_pos: PosValue<()>, #[br(parse_with = until_size_limit(length as u64 - (end_pos.pos - start_pos.pos)))] - pub attributes: Vec, -} - -#[binread] -#[derive(Debug)] -pub enum SurfaceSubTag { - #[br(magic(b"COLR"))] - BaseColor(SubChunk), - #[br(magic(b"DIFF"))] - BaseShadingValueDiffuse(SubChunk), - #[br(magic(b"LUMI"))] - BaseShadingValueLuminosity(SubChunk), - #[br(magic(b"SPEC"))] - BaseShadingValueSpecular(SubChunk), - #[br(magic(b"REFL"))] - BaseShadingValueReflectivity(SubChunk), - #[br(magic(b"TRAN"))] - BaseShadingValueTransparency(SubChunk), - #[br(magic(b"TRNL"))] - BaseShadingValueTranslucency(SubChunk), - #[br(magic(b"GLOS"))] - SpecularGlossiness(SubChunk), - #[br(magic(b"SHRP"))] - DiffuseSharpness(SubChunk), - #[br(magic(b"BUMP"))] - BumpIntensity(SubChunk), - #[br(magic(b"SIDE"))] - PolygonSidedness(SubChunk), - #[br(magic(b"SMAN"))] - MaxSmoothingAngle(SubChunk), - #[br(magic(b"BLOK"))] - Blocks(SubChunk), - #[br(magic(b"RFOP"))] - ReflectionOptions(SubChunk), - #[br(magic(b"RIMG"))] - ReflectionMapImage(SubChunk), - #[br(magic(b"TBLR"))] - RefractionBlurring(SubChunk), - #[br(magic(b"CLRH"))] - ColorHighlights(SubChunk), - #[br(magic(b"CLRF"))] - ColorFilter(SubChunk), - #[br(magic(b"ADTR"))] - AdditiveTransparency(SubChunk), -} - -#[binread] -#[br(repr = u16, import(_length: u32))] -#[derive(Debug)] -pub enum ReflectionOptions { - BackdropOnly = 0, - RaytracingAndBackdrop = 1, - SphericalMap = 2, - RaytracingAndSphericalMap = 3, -} - -#[binread] -#[br(import(_length: u32))] -#[derive(Debug)] -pub struct VectorEnvelope { - pub base_color: [f32; 3], - #[br(parse_with = vx)] - pub envelope: u32, -} - -#[binread] -#[br(import(_length: u32))] -#[derive(Debug)] -pub struct ValueEnvelope { - pub value: f32, - #[br(parse_with = vx)] - pub envelope: u32, -} - -#[binread] -#[br(import(_length: u32))] -#[derive(Debug)] -pub struct PolygonSidedness { - pub sidedness: u16, -} - -#[binread] -#[br(import(_length: u32))] -#[derive(Debug)] -pub struct MaxSmoothingAngle { - pub max_smoothing_angle: f32, -} - -#[binread] -#[br(import(length: u32))] -#[derive(Debug)] -pub struct SurfaceBlocks { - #[br(temp)] - start_pos: PosValue<()>, - pub header: SurfaceBlockHeader, - #[br(temp)] - end_pos: PosValue<()>, - #[br(parse_with = until_size_limit(length as u64 - (end_pos.pos - start_pos.pos)))] - pub attributes: Vec, -} - -#[binread] -#[derive(Debug)] -pub enum SurfaceBlockHeader { - #[br(magic(b"IMAP"))] - ImageMapTexture(SubChunk), - #[br(magic(b"PROC"))] - ProceduralTexture(SubChunk), - #[br(magic(b"GRAD"))] - GradientTexture(SubChunk), - #[br(magic(b"SHDR"))] - ShaderPlugin(SubChunk), -} - -#[binread] -#[br(import(length: u32))] -#[derive(Debug)] -pub struct SurfaceBlockHeaders { - #[br(pad_before = 2, parse_with = until_size_limit(length as u64))] - pub block_attributes: Vec, -} - -#[binread] -#[derive(Debug)] -pub enum SurfaceBlockSubChunk { - #[br(magic(b"CHAN"))] - Channel(SubChunk), - #[br(magic(b"ENAB"))] - EnabledState(SubChunk), - #[br(magic(b"OPAC"))] - Opacity(SubChunk), - #[br(magic(b"AXIS"))] - DisplacementAxis(SubChunk), - #[br(magic(b"TMAP"))] - TextureMapping(SubChunk), - #[br(magic(b"NEGA"))] - Negative(SubChunk), - #[br(magic(b"PROJ"))] - ProjectionMode(SubChunk), - #[br(magic(b"IMAG"))] - ImageMap(SubChunk), - #[br(magic(b"WRAP"))] - ImageWrapOptions(SubChunk), - #[br(magic(b"WRPW"))] - ImageWrapAmountWidth(SubChunk), - #[br(magic(b"WRPH"))] - ImageWrapAmountHeight(SubChunk), - #[br(magic(b"VMAP"))] - UvVertexMap(SubChunk), - #[br(magic(b"AAST"))] - AntialiasingStrength(SubChunk), - #[br(magic(b"PIXB"))] - PixelBlending(SubChunk), - #[br(magic(b"TAMP"))] - TextureAmplitude(SubChunk), -} - -/// Pixel blending enlarges the sample filter when it would otherwise be smaller than a single -/// image map pixel. If the low-order flag bit is set, then pixel blending is enabled. -#[binread] -#[br(import(_length: u32))] -#[derive(Debug)] -pub struct PixelBlending { - pub flags: u16, -} - -/// The low bit of the flags word is an enable flag for texture antialiasing. The antialiasing -/// strength is proportional to the width of the sample filter, so larger values sample a larger -/// area of the image. -#[binread] -#[br(import(_length: u32))] -#[derive(Debug)] -pub struct AntialiasingStrength { - pub flags: u16, - pub strength: f32, -} - -#[binread] -#[br(import(_length: u32))] -#[derive(Debug)] -pub struct UvMap { - #[br(align_after = 2)] - pub txuv_map_name: NullString, -} - -#[binread] -#[br(import(_length: u32))] -#[derive(Debug)] -pub struct ImageWrapAmount { - pub cycles: f32, - #[br(parse_with = vx)] - pub envelope: u32, -} - -#[binread] -#[br(import(_length: u32))] -#[derive(Debug)] -pub struct ImageWrapOptions { - pub width_wrap: ImageWrapType, - pub height_wrap: ImageWrapType, -} - -#[binread] -#[br(repr = u16)] -#[derive(Debug)] -pub enum ImageWrapType { - Reset = 0, - Repeat = 1, - Mirror = 2, - Edge = 3, -} - -#[binread] -#[br(repr = u16, import(_length: u32))] -#[derive(Debug)] -pub enum ProjectionMode { - Planar = 0, - Cylindrical = 1, - Spherical = 2, - Cubic = 3, - FrontProjection = 4, - UV = 5, -} - -#[binread] -#[br(import(_length: u32))] -#[derive(Debug)] -pub struct VxReference { - #[br(parse_with = vx)] - pub texture_image: u32, -} - -#[binread] -#[br(import(length: u32))] -#[derive(Debug)] -pub struct TextureMapping { - #[br(parse_with = until_size_limit(length as u64))] - pub attributes: Vec, -} - -#[binread] -#[derive(Debug)] -pub enum TextureMappingSubChunk { - #[br(magic(b"CNTR"))] - Center(SubChunk), - #[br(magic(b"SIZE"))] - Size(SubChunk), - #[br(magic(b"ROTA"))] - Rotation(SubChunk), - #[br(magic(b"OREF"))] - ReferenceObject(SubChunk), - #[br(magic(b"FALL"))] - Falloff(SubChunk), - #[br(magic(b"CSYS"))] - CoordinateSystem(SubChunk), -} - -#[binread] -#[br(repr = u16, import(_length: u32))] -#[derive(Debug)] -pub enum CoordinateSystem { - ObjectCoordinates = 0, - WorldCoordinates = 1, -} - -#[binread] -#[br(import(_length: u32))] -#[derive(Debug)] -pub struct ReferenceObject { - #[br(align_after = 2)] - pub object_name: NullString, -} - -#[binread] -#[br(import(_length: u32))] -#[derive(Debug)] -pub struct Falloff { - pub kind: FalloffType, - pub vector: [f32; 3], - #[br(parse_with = vx)] - pub envelope: u32, -} - -#[binread] -#[br(repr = u16)] -#[derive(Debug)] -pub enum FalloffType { - Cubic = 0, - Spherical = 1, - LinearX = 2, - LinearY = 3, - LinearZ = 4, -} - -#[binread] -#[br(import(_length: u32))] -#[derive(Debug)] -pub struct DisplacementAxis { - pub displacement_axis: u16, -} - -#[binread] -#[br(import(_length: u32))] -#[derive(Debug)] -pub struct Opacity { - pub kind: OpacityType, - pub opacity: f32, - #[br(parse_with = vx)] - pub envelope: u32, -} - -#[binread] -#[br(repr = u16)] -#[derive(Debug)] -pub enum OpacityType { - Normal = 0, - Subtractive = 1, - Difference = 2, - Multiply = 3, - Divide = 4, - Alpha = 5, - TextureDisplacement = 6, - Additive = 7, -} - -#[binread] -#[br(import(_length: u32))] -#[derive(Debug)] -pub struct EnableState { - pub enable: u16, -} - -#[binread] -#[br(import(_length: u32))] -#[derive(Debug)] -pub struct Channel { - pub texture_channel: TextureChannel, -} - -#[binread] -#[derive(Debug)] -pub enum TextureChannel { - #[br(magic(b"COLR"))] - Color, - #[br(magic(b"DIFF"))] - Diffuse, - #[br(magic(b"LUMI"))] - Luminosity, - #[br(magic(b"SPEC"))] - Specular, - #[br(magic(b"GLOS"))] - Glossy, - #[br(magic(b"REFL"))] - Reflectivity, - #[br(magic(b"TRAN"))] - Transparency, - #[br(magic(b"RIND"))] - RefractiveIndex, - #[br(magic(b"TRNL"))] - Translucency, - #[br(magic(b"BUMP"))] - Bump, + pub attributes: Vec, }