This commit is contained in:
2023-05-09 23:01:43 +02:00
parent 8cf1ac2635
commit 92c3ab9b53
10 changed files with 577 additions and 370 deletions

View File

@@ -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.
## 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`<br>`LUMI`<br>`SPEC`<br>`REFL`<br>`TRAN`<br>`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`<br>`SIZE`<br>`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`<br>`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`<br>`GREN` | ❌ |
| Repeat Mode | `GRPT` | ❌ |
| Key Values | `FKEY` | ❌ |
| Key Parameters | `IKEY` | ❌ |
#### Shaders
| Chunk | Tag | Status |
|------------------|--------|--------|
| Shader Algorithm | `FUNC` | ❌ |

View File

@@ -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<R, Arg, T, Ret>(
limit: u64,
) -> impl Fn(&mut R, Endian, Arg) -> BinResult<Ret>

View File

@@ -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,
}

View File

@@ -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<TextureMapping>),
#[br(magic(b"PROJ"))]
ProjectionMode(SubChunk<ProjectionMode>),
#[br(magic(b"AXIS"))]
MajorAxis(SubChunk<MajorAxis>),
#[br(magic(b"IMAG"))]
ImageMap(SubChunk<VxReference>),
#[br(magic(b"WRAP"))]
ImageWrapOptions(SubChunk<ImageWrapOptions>),
#[br(magic(b"WRPW"))]
ImageWrapAmountWidth(SubChunk<ImageWrapAmount>),
#[br(magic(b"WRPH"))]
ImageWrapAmountHeight(SubChunk<ImageWrapAmount>),
#[br(magic(b"VMAP"))]
UvVertexMap(SubChunk<UvMap>),
#[br(magic(b"AAST"))]
AntialiasingStrength(SubChunk<AntialiasingStrength>),
#[br(magic(b"PIXB"))]
PixelBlending(SubChunk<PixelBlending>),
#[br(magic(b"TAMP"))]
TextureAmplitude(SubChunk<ValueEnvelope>),
}
/// 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,
}

View File

@@ -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<SurfaceBlockHeader>,
#[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<SurfaceBlockImageTextureSubChunk>,
}
#[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<SurfaceBlockHeaderSubChunk>,
}
#[binread]
#[derive(Debug)]
pub enum SurfaceBlockHeaderSubChunk {
#[br(magic(b"CHAN"))]
Channel(SubChunk<Channel>),
#[br(magic(b"ENAB"))]
EnabledState(SubChunk<EnableState>),
#[br(magic(b"OPAC"))]
Opacity(SubChunk<Opacity>),
#[br(magic(b"AXIS"))]
DisplacementAxis(SubChunk<DisplacementAxis>),
#[br(magic(b"NEGA"))]
Negative(SubChunk<EnableState>),
}
#[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,
}

View File

@@ -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<VectorEnvelope>),
#[br(magic(b"DIFF"))]
BaseShadingValueDiffuse(SubChunk<ValueEnvelope>),
#[br(magic(b"LUMI"))]
BaseShadingValueLuminosity(SubChunk<ValueEnvelope>),
#[br(magic(b"SPEC"))]
BaseShadingValueSpecular(SubChunk<ValueEnvelope>),
#[br(magic(b"REFL"))]
BaseShadingValueReflectivity(SubChunk<ValueEnvelope>),
#[br(magic(b"TRAN"))]
BaseShadingValueTransparency(SubChunk<ValueEnvelope>),
#[br(magic(b"TRNL"))]
BaseShadingValueTranslucency(SubChunk<ValueEnvelope>),
#[br(magic(b"GLOS"))]
SpecularGlossiness(SubChunk<ValueEnvelope>),
#[br(magic(b"SHRP"))]
DiffuseSharpness(SubChunk<ValueEnvelope>),
#[br(magic(b"BUMP"))]
BumpIntensity(SubChunk<ValueEnvelope>),
#[br(magic(b"SIDE"))]
PolygonSidedness(SubChunk<PolygonSidedness>),
#[br(magic(b"SMAN"))]
MaxSmoothingAngle(SubChunk<MaxSmoothingAngle>),
#[br(magic(b"BLOK"))]
Blocks(SubChunk<SurfaceBlocks>),
#[br(magic(b"RFOP"))]
ReflectionOptions(SubChunk<ReflectionOptions>),
#[br(magic(b"RIMG"))]
ReflectionMapImage(SubChunk<VxReference>),
#[br(magic(b"TBLR"))]
RefractionBlurring(SubChunk<ValueEnvelope>),
#[br(magic(b"CLRH"))]
ColorHighlights(SubChunk<ValueEnvelope>),
#[br(magic(b"CLRF"))]
ColorFilter(SubChunk<ValueEnvelope>),
#[br(magic(b"ADTR"))]
AdditiveTransparency(SubChunk<ValueEnvelope>),
}
#[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,
}

View File

@@ -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<TextureMappingSubChunk>,
}
#[binread]
#[derive(Debug)]
pub enum TextureMappingSubChunk {
#[br(magic(b"CNTR"))]
Center(SubChunk<VectorEnvelope>),
#[br(magic(b"SIZE"))]
Size(SubChunk<VectorEnvelope>),
#[br(magic(b"ROTA"))]
Rotation(SubChunk<VectorEnvelope>),
#[br(magic(b"OREF"))]
ReferenceObject(SubChunk<ReferenceObject>),
#[br(magic(b"FALL"))]
Falloff(SubChunk<Falloff>),
#[br(magic(b"CSYS"))]
CoordinateSystem(SubChunk<CoordinateSystem>),
}
#[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,
}

View File

@@ -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

View File

@@ -50,3 +50,4 @@ pub enum Tag {
#[br(magic(b"CLIP"))]
ImageClip(Chunk<ImageClip>),
}

View File

@@ -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<SurfaceSubTag>,
}
#[binread]
#[derive(Debug)]
pub enum SurfaceSubTag {
#[br(magic(b"COLR"))]
BaseColor(SubChunk<VectorEnvelope>),
#[br(magic(b"DIFF"))]
BaseShadingValueDiffuse(SubChunk<ValueEnvelope>),
#[br(magic(b"LUMI"))]
BaseShadingValueLuminosity(SubChunk<ValueEnvelope>),
#[br(magic(b"SPEC"))]
BaseShadingValueSpecular(SubChunk<ValueEnvelope>),
#[br(magic(b"REFL"))]
BaseShadingValueReflectivity(SubChunk<ValueEnvelope>),
#[br(magic(b"TRAN"))]
BaseShadingValueTransparency(SubChunk<ValueEnvelope>),
#[br(magic(b"TRNL"))]
BaseShadingValueTranslucency(SubChunk<ValueEnvelope>),
#[br(magic(b"GLOS"))]
SpecularGlossiness(SubChunk<ValueEnvelope>),
#[br(magic(b"SHRP"))]
DiffuseSharpness(SubChunk<ValueEnvelope>),
#[br(magic(b"BUMP"))]
BumpIntensity(SubChunk<ValueEnvelope>),
#[br(magic(b"SIDE"))]
PolygonSidedness(SubChunk<PolygonSidedness>),
#[br(magic(b"SMAN"))]
MaxSmoothingAngle(SubChunk<MaxSmoothingAngle>),
#[br(magic(b"BLOK"))]
Blocks(SubChunk<SurfaceBlocks>),
#[br(magic(b"RFOP"))]
ReflectionOptions(SubChunk<ReflectionOptions>),
#[br(magic(b"RIMG"))]
ReflectionMapImage(SubChunk<VxReference>),
#[br(magic(b"TBLR"))]
RefractionBlurring(SubChunk<ValueEnvelope>),
#[br(magic(b"CLRH"))]
ColorHighlights(SubChunk<ValueEnvelope>),
#[br(magic(b"CLRF"))]
ColorFilter(SubChunk<ValueEnvelope>),
#[br(magic(b"ADTR"))]
AdditiveTransparency(SubChunk<ValueEnvelope>),
}
#[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<SurfaceBlockSubChunk>,
}
#[binread]
#[derive(Debug)]
pub enum SurfaceBlockHeader {
#[br(magic(b"IMAP"))]
ImageMapTexture(SubChunk<SurfaceBlockHeaders>),
#[br(magic(b"PROC"))]
ProceduralTexture(SubChunk<SurfaceBlockHeaders>),
#[br(magic(b"GRAD"))]
GradientTexture(SubChunk<SurfaceBlockHeaders>),
#[br(magic(b"SHDR"))]
ShaderPlugin(SubChunk<SurfaceBlockHeaders>),
}
#[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<SurfaceBlockSubChunk>,
}
#[binread]
#[derive(Debug)]
pub enum SurfaceBlockSubChunk {
#[br(magic(b"CHAN"))]
Channel(SubChunk<Channel>),
#[br(magic(b"ENAB"))]
EnabledState(SubChunk<EnableState>),
#[br(magic(b"OPAC"))]
Opacity(SubChunk<Opacity>),
#[br(magic(b"AXIS"))]
DisplacementAxis(SubChunk<DisplacementAxis>),
#[br(magic(b"TMAP"))]
TextureMapping(SubChunk<TextureMapping>),
#[br(magic(b"NEGA"))]
Negative(SubChunk<EnableState>),
#[br(magic(b"PROJ"))]
ProjectionMode(SubChunk<ProjectionMode>),
#[br(magic(b"IMAG"))]
ImageMap(SubChunk<VxReference>),
#[br(magic(b"WRAP"))]
ImageWrapOptions(SubChunk<ImageWrapOptions>),
#[br(magic(b"WRPW"))]
ImageWrapAmountWidth(SubChunk<ImageWrapAmount>),
#[br(magic(b"WRPH"))]
ImageWrapAmountHeight(SubChunk<ImageWrapAmount>),
#[br(magic(b"VMAP"))]
UvVertexMap(SubChunk<UvMap>),
#[br(magic(b"AAST"))]
AntialiasingStrength(SubChunk<AntialiasingStrength>),
#[br(magic(b"PIXB"))]
PixelBlending(SubChunk<PixelBlending>),
#[br(magic(b"TAMP"))]
TextureAmplitude(SubChunk<ValueEnvelope>),
}
/// 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<TextureMappingSubChunk>,
}
#[binread]
#[derive(Debug)]
pub enum TextureMappingSubChunk {
#[br(magic(b"CNTR"))]
Center(SubChunk<VectorEnvelope>),
#[br(magic(b"SIZE"))]
Size(SubChunk<VectorEnvelope>),
#[br(magic(b"ROTA"))]
Rotation(SubChunk<VectorEnvelope>),
#[br(magic(b"OREF"))]
ReferenceObject(SubChunk<ReferenceObject>),
#[br(magic(b"FALL"))]
Falloff(SubChunk<Falloff>),
#[br(magic(b"CSYS"))]
CoordinateSystem(SubChunk<CoordinateSystem>),
}
#[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<SurfaceParameterSubChunk>,
}