mirror of
https://github.com/Theaninova/mhlib.git
synced 2025-12-11 03:56:18 +00:00
add lightwave parser
This commit is contained in:
7
rust/Cargo.lock
generated
7
rust/Cargo.lock
generated
@@ -242,6 +242,12 @@ dependencies = [
|
||||
"weezl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "2.2.1"
|
||||
@@ -357,6 +363,7 @@ dependencies = [
|
||||
name = "mhex"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"lightwave",
|
||||
"starforcelib",
|
||||
]
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# LightWave 3D Rust Parser
|
||||
|
||||
* [LWO2 Spec](http://static.lightwave3d.com/sdk/2015/html/filefmts/lwo2.html)
|
||||
* [LWO2 Spec](http://static.lightwave3d.com/sdk/2015/html/filefmts/lwo2.html)
|
||||
* Progress: about 90% (?) complete, so most things should load.
|
||||
@@ -16,7 +16,7 @@ where
|
||||
R: Read + Seek,
|
||||
{
|
||||
let kind: u16 = reader.read_type(endian)?;
|
||||
Ok(if (kind & 0xff) != 0xff {
|
||||
Ok(if kind < 0xff00 {
|
||||
kind as u32
|
||||
} else {
|
||||
(((kind as u32) & 0xff) << 16) | (reader.read_type::<u16>(endian)? as u32)
|
||||
|
||||
146
rust/lightwave/src/lwo2/tags/image_clip.rs
Normal file
146
rust/lightwave/src/lwo2/tags/image_clip.rs
Normal file
@@ -0,0 +1,146 @@
|
||||
use crate::binrw_helpers::until_size_limit;
|
||||
use crate::iff::SubChunk;
|
||||
use crate::lwo2::tags::surface_definition::ValueEnvelope;
|
||||
use binrw::{binread, NullString};
|
||||
|
||||
/// 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
|
||||
/// or animations as well as stills. The index identifies this clip uniquely and may be any non-zero
|
||||
/// value less than 0x1000000. The filename and any image processing modifiers follow as a variable
|
||||
/// list of subchunks, which are documented below in the Clip Subchunks section.
|
||||
#[binread]
|
||||
#[br(import(length: u32))]
|
||||
#[derive(Debug)]
|
||||
pub struct ImageClip {
|
||||
pub index: u32,
|
||||
#[br(parse_with = until_size_limit(length as u64 - 4))]
|
||||
pub attributes: Vec<ImageClipSubChunk>,
|
||||
}
|
||||
|
||||
#[binread]
|
||||
#[derive(Debug)]
|
||||
pub enum ImageClipSubChunk {
|
||||
#[br(magic(b"STIL"))]
|
||||
StillImage(SubChunk<StillImage>),
|
||||
#[br(magic(b"ISEQ"))]
|
||||
ImageSequence(SubChunk<ImageSequence>),
|
||||
#[br(magic(b"XREF"))]
|
||||
Reference(SubChunk<Reference>),
|
||||
#[br(magic(b"FLAG"))]
|
||||
Flag(SubChunk<Flags>),
|
||||
#[br(magic(b"STCC"))]
|
||||
ColorCyclingStill(SubChunk<ColorCyclingStill>),
|
||||
#[br(magic(b"TIME"))]
|
||||
Time(SubChunk<Time>),
|
||||
#[br(magic(b"CLRS"))]
|
||||
ColorSpaceRgb(SubChunk<ColorSpace>),
|
||||
#[br(magic(b"CLRA"))]
|
||||
ColorSpaceAlpha(SubChunk<ColorSpace>),
|
||||
#[br(magic(b"FILT"))]
|
||||
ImageFiltering(SubChunk<Flags>),
|
||||
#[br(magic(b"DITH"))]
|
||||
ImageDithering(SubChunk<Flags>),
|
||||
#[br(magic(b"CONT"))]
|
||||
Contrast(SubChunk<ValueEnvelope>),
|
||||
#[br(magic(b"BRIT"))]
|
||||
Brightness(SubChunk<ValueEnvelope>),
|
||||
#[br(magic(b"SATR"))]
|
||||
Saturation(SubChunk<ValueEnvelope>),
|
||||
#[br(magic(b"HUE"))] // TODO: Typo? Docs say it's just "HUE"
|
||||
Hue(SubChunk<ValueEnvelope>),
|
||||
#[br(magic(b"GAMM"))]
|
||||
GammaCorrection(SubChunk<ValueEnvelope>),
|
||||
}
|
||||
|
||||
/// Contains the color space of the texture. If the flag is 0, then the color space is contained
|
||||
/// in the following 2 bytes. That color space is defined by the LWCOLORSPACE enum. If the flag
|
||||
/// is set to 1, then the file name of the color space is save as a local string.
|
||||
#[binread]
|
||||
#[br(import(_length: u32))]
|
||||
#[derive(Debug)]
|
||||
pub struct ColorSpace {
|
||||
pub flags: u16,
|
||||
pub color_space: u16,
|
||||
#[br(align_after = 2)]
|
||||
pub file_name: NullString,
|
||||
}
|
||||
|
||||
/// A still image with color-cycling is a source defined by a neutral-format name and cycling
|
||||
/// parameters. lo and hi are indexes into the image's color table. Within this range, the color
|
||||
/// table entries are shifted over time to cycle the colors in the image. If lo is less than hi,
|
||||
/// the colors cycle forward, and if hi is less than lo, they go backwards.
|
||||
///
|
||||
/// Except for the TIME subchunk, the subchunks after the source subchunk modify the source image
|
||||
/// and are applied as filters layered on top of the source image.
|
||||
#[binread]
|
||||
#[br(import(_length: u32))]
|
||||
#[derive(Debug)]
|
||||
pub struct ColorCyclingStill {
|
||||
pub lo: i16,
|
||||
pub hi: i16,
|
||||
#[br(align_after = 2)]
|
||||
pub name: NullString,
|
||||
}
|
||||
|
||||
/// Defines source times for an animated clip.
|
||||
#[binread]
|
||||
#[br(import(_length: u32))]
|
||||
#[derive(Debug)]
|
||||
pub struct Time {
|
||||
pub start_time: f32,
|
||||
pub duration: f32,
|
||||
pub frame_rate: f32,
|
||||
}
|
||||
|
||||
/// TODO: What's this?
|
||||
#[binread]
|
||||
#[br(import(_length: u32))]
|
||||
#[derive(Debug)]
|
||||
pub struct Flags {
|
||||
pub flag: u32,
|
||||
}
|
||||
|
||||
/// The source is a single still image referenced by a filename in neutral path format.
|
||||
#[binread]
|
||||
#[br(import(_length: u32))]
|
||||
#[derive(Debug)]
|
||||
pub struct StillImage {
|
||||
#[br(align_after = 2)]
|
||||
pub name: NullString,
|
||||
}
|
||||
|
||||
/// The source is a numbered sequence of still image files. Each filename contains a fixed number
|
||||
/// of decimal digits that specify a frame number, along with a prefix (the part before the frame
|
||||
/// number, which includes the path) and a suffix (the part after the number, typically a PC-style
|
||||
/// extension that identifies the file format). The prefix and suffix are the same for all files
|
||||
/// in the sequence.
|
||||
///
|
||||
/// The flags include bits for looping and interlace. The offset is added to the current frame
|
||||
/// number to obtain the digits of the filename for the current frame. The start and end values
|
||||
/// define the range of frames in the sequence.
|
||||
#[binread]
|
||||
#[br(import(_length: u32))]
|
||||
#[derive(Debug)]
|
||||
pub struct ImageSequence {
|
||||
pub num_digits: u8,
|
||||
pub flags: u8,
|
||||
pub offset: i16,
|
||||
pub reserved: u16,
|
||||
pub start: i16,
|
||||
pub end: i16,
|
||||
#[br(align_after = 2)]
|
||||
pub prefix: NullString,
|
||||
#[br(align_after = 2)]
|
||||
pub suffix: NullString,
|
||||
}
|
||||
|
||||
/// The source is a copy, or instance, of another clip, given by the index. The string is a unique
|
||||
/// name for this instance of the clip.
|
||||
#[binread]
|
||||
#[br(import(_length: u32))]
|
||||
#[derive(Debug)]
|
||||
pub struct Reference {
|
||||
pub index: u32,
|
||||
#[br(align_after = 2)]
|
||||
pub string: NullString,
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::iff::Chunk;
|
||||
use crate::lwo2::tags::bounding_box::BoundingBox;
|
||||
use crate::lwo2::tags::discontinuous_vertex_mapping::DiscontinuousVertexMappings;
|
||||
use crate::lwo2::tags::image_clip::ImageClip;
|
||||
use crate::lwo2::tags::layer::Layer;
|
||||
use crate::lwo2::tags::point_list::PointList;
|
||||
use crate::lwo2::tags::polygon_list::PolygonLists;
|
||||
@@ -13,6 +14,7 @@ use binrw::binread;
|
||||
|
||||
pub mod bounding_box;
|
||||
pub mod discontinuous_vertex_mapping;
|
||||
pub mod image_clip;
|
||||
pub mod layer;
|
||||
pub mod point_list;
|
||||
pub mod polygon_list;
|
||||
@@ -45,4 +47,6 @@ pub enum Tag {
|
||||
PolygonList(Chunk<PolygonLists>),
|
||||
#[br(magic(b"SURF"))]
|
||||
SurfaceDefinition(Chunk<SurfaceDefinition>),
|
||||
#[br(magic(b"CLIP"))]
|
||||
ImageClip(Chunk<ImageClip>),
|
||||
}
|
||||
|
||||
@@ -3,10 +3,10 @@ use binrw::binread;
|
||||
///Lists (x, y, z) coordinate triples for a set of points. The number of points in the chunk is
|
||||
/// just the chunk size divided by 12. The PNTS chunk must precede the POLS, VMAP and VMAD chunks
|
||||
/// that refer to it. These chunks list points using a 0-based index into PNTS.
|
||||
//
|
||||
// The LightWave® coordinate system is left-handed, with +X to the right or east, +Y upward,
|
||||
// and +Z forward or north. Object files don't contain explicit units, but by convention the
|
||||
// unit is meters. Coordinates in PNTS are relative to the pivot point of the layer.
|
||||
///
|
||||
/// The LightWave® coordinate system is left-handed, with +X to the right or east, +Y upward,
|
||||
/// and +Z forward or north. Object files don't contain explicit units, but by convention the
|
||||
/// unit is meters. Coordinates in PNTS are relative to the pivot point of the layer.
|
||||
#[binread]
|
||||
#[br(import(length: u32))]
|
||||
#[derive(Debug)]
|
||||
|
||||
@@ -23,35 +23,59 @@ pub struct SurfaceDefinition {
|
||||
#[derive(Debug)]
|
||||
pub enum SurfaceSubTag {
|
||||
#[br(magic(b"COLR"))]
|
||||
BaseColor(SubChunk<BaseColor>),
|
||||
BaseColor(SubChunk<VectorEnvelope>),
|
||||
#[br(magic(b"DIFF"))]
|
||||
BaseShadingValueDiffuse(SubChunk<BaseShadingValues>),
|
||||
BaseShadingValueDiffuse(SubChunk<ValueEnvelope>),
|
||||
#[br(magic(b"LUMI"))]
|
||||
BaseShadingValueLuminosity(SubChunk<BaseShadingValues>),
|
||||
BaseShadingValueLuminosity(SubChunk<ValueEnvelope>),
|
||||
#[br(magic(b"SPEC"))]
|
||||
BaseShadingValueSpecular(SubChunk<BaseShadingValues>),
|
||||
BaseShadingValueSpecular(SubChunk<ValueEnvelope>),
|
||||
#[br(magic(b"REFL"))]
|
||||
BaseShadingValueReflectivity(SubChunk<BaseShadingValues>),
|
||||
BaseShadingValueReflectivity(SubChunk<ValueEnvelope>),
|
||||
#[br(magic(b"TRAN"))]
|
||||
BaseShadingValueTransmission(SubChunk<BaseShadingValues>),
|
||||
#[br(magic(b"TRNL"))] // TODO
|
||||
BaseShadingValueTrnl(SubChunk<BaseShadingValues>),
|
||||
BaseShadingValueTransparency(SubChunk<ValueEnvelope>),
|
||||
#[br(magic(b"TRNL"))]
|
||||
BaseShadingValueTranslucency(SubChunk<ValueEnvelope>),
|
||||
#[br(magic(b"GLOS"))]
|
||||
SpecularGlossiness(SubChunk<BaseShadingValues>),
|
||||
SpecularGlossiness(SubChunk<ValueEnvelope>),
|
||||
#[br(magic(b"SHRP"))]
|
||||
DiffuseSharpness(SubChunk<BaseShadingValues>),
|
||||
DiffuseSharpness(SubChunk<ValueEnvelope>),
|
||||
#[br(magic(b"BUMP"))]
|
||||
BumpIntensity(SubChunk<BaseShadingValues>),
|
||||
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 BaseColor {
|
||||
pub struct VectorEnvelope {
|
||||
pub base_color: [f32; 3],
|
||||
#[br(parse_with = vx)]
|
||||
pub envelope: u32,
|
||||
@@ -60,7 +84,7 @@ pub struct BaseColor {
|
||||
#[binread]
|
||||
#[br(import(_length: u32))]
|
||||
#[derive(Debug)]
|
||||
pub struct BaseShadingValues {
|
||||
pub struct ValueEnvelope {
|
||||
pub value: f32,
|
||||
#[br(parse_with = vx)]
|
||||
pub envelope: u32,
|
||||
@@ -79,3 +103,279 @@ pub struct PolygonSidedness {
|
||||
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,
|
||||
}
|
||||
|
||||
@@ -8,3 +8,4 @@ edition = "2021"
|
||||
[dependencies]
|
||||
starforcelib = {path = "../starforcelib"}
|
||||
lightwave = {path = "../lightwave"}
|
||||
glob = "0.3.1"
|
||||
|
||||
@@ -1,6 +1,24 @@
|
||||
use glob::glob;
|
||||
use lightwave::LightWaveObject;
|
||||
|
||||
fn main() {
|
||||
let obj = LightWaveObject::read_file("E:\\Games\\Moorhuhn Kart 3\\extract\\D\\Moorhuhnkart\\3dobjects_tracks\\track04_robinhood\\colreset.lwo").unwrap();
|
||||
println!("{:#?}", obj);
|
||||
let mut successful = 0;
|
||||
let mut failed = 0;
|
||||
|
||||
for entry in glob("E:/Games/Moorhuhn Kart 3/extract/**/*.lwo").unwrap() {
|
||||
let path = entry.unwrap();
|
||||
println!("{:?}", path.display());
|
||||
match LightWaveObject::read_file(path) {
|
||||
Ok(_) => {
|
||||
successful += 1;
|
||||
println!("...Ok")
|
||||
}
|
||||
Err(err) => {
|
||||
failed += 1;
|
||||
eprintln!("{:?}", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println!("Successful: {}\nFailed: {}", successful, failed);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user