wow_m2/chunks/
color_animation.rs

1use crate::common::M2Parse;
2use crate::io_ext::{ReadExt, WriteExt};
3use std::io::{Read, Seek, Write};
4
5use crate::chunks::animation::M2AnimationBlock;
6use crate::error::Result;
7use crate::version::M2Version;
8
9/// RGBA color structure
10#[derive(Debug, Clone, Copy, PartialEq)]
11pub struct M2Color {
12    /// Red component (0-1)
13    pub r: f32,
14    /// Green component (0-1)
15    pub g: f32,
16    /// Blue component (0-1)
17    pub b: f32,
18}
19
20impl Default for M2Color {
21    fn default() -> Self {
22        Self::white()
23    }
24}
25
26impl M2Parse for M2Color {
27    fn parse<R: Read + Seek>(reader: &mut R) -> Result<Self> {
28        M2Color::parse(reader)
29    }
30
31    fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
32        self.write(writer)
33    }
34}
35
36impl M2Color {
37    /// Parse a color from a reader
38    pub fn parse<R: Read>(reader: &mut R) -> Result<Self> {
39        let r = reader.read_f32_le()?;
40        let g = reader.read_f32_le()?;
41        let b = reader.read_f32_le()?;
42
43        Ok(Self { r, g, b })
44    }
45
46    /// Write a color to a writer
47    pub fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
48        writer.write_f32_le(self.r)?;
49        writer.write_f32_le(self.g)?;
50        writer.write_f32_le(self.b)?;
51
52        Ok(())
53    }
54
55    /// Create a new color
56    pub fn new(r: f32, g: f32, b: f32) -> Self {
57        Self { r, g, b }
58    }
59
60    /// Create a new white color with full alpha
61    pub fn white() -> Self {
62        Self::new(1.0, 1.0, 1.0)
63    }
64
65    /// Create a new black color with full alpha
66    pub fn black() -> Self {
67        Self::new(0.0, 0.0, 0.0)
68    }
69
70    /// Create a new transparent color
71    pub fn transparent() -> Self {
72        Self::new(0.0, 0.0, 0.0)
73    }
74}
75
76/// Color animation structure
77#[derive(Debug, Clone)]
78pub struct M2ColorAnimation {
79    /// Animation for color RGB
80    pub color: M2AnimationBlock<M2Color>,
81    /// Animation for alpha
82    pub alpha: M2AnimationBlock<u16>,
83}
84
85impl M2ColorAnimation {
86    /// Parse a color animation from a reader
87    pub fn parse<R: Read + Seek>(reader: &mut R) -> Result<Self> {
88        let color = M2AnimationBlock::parse(reader)?;
89        let alpha = M2AnimationBlock::parse(reader)?;
90
91        Ok(Self { color, alpha })
92    }
93
94    /// Write a color animation to a writer
95    pub fn write<W: Write>(&self, writer: &mut W) -> Result<()> {
96        self.color.write(writer)?;
97        self.alpha.write(writer)?;
98
99        Ok(())
100    }
101
102    /// Convert this color animation to a different version (no version differences yet)
103    pub fn convert(&self, _target_version: M2Version) -> Self {
104        self.clone()
105    }
106}
107
108#[cfg(test)]
109mod tests {
110    use super::*;
111    use std::io::Cursor;
112
113    #[test]
114    fn test_color_parse_write() {
115        let color = M2Color::new(0.5, 0.6, 0.7);
116
117        let mut data = Vec::new();
118        color.write(&mut data).unwrap();
119
120        let mut cursor = Cursor::new(data);
121        let parsed_color = M2Color::parse(&mut cursor).unwrap();
122
123        assert_eq!(parsed_color.r, 0.5);
124        assert_eq!(parsed_color.g, 0.6);
125        assert_eq!(parsed_color.b, 0.7);
126    }
127}