gausplat_loader/source/colmap/point/
mod.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
//! COLMAP point module.

pub mod points;

pub use crate::{
    error::Error,
    function::{Decoder, Encoder},
};
pub use points::*;

use crate::function::{advance, read_bytes_const};
use byteorder::{ReadBytesExt, WriteBytesExt, LE};
use std::io::{BufReader, BufWriter, Read, Write};

/// A COLMAP point.
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Point {
    /// Position in world space.
    pub position: [f64; 3],
    /// Color in 8-bit RGB.
    pub color_rgb: [u8; 3],
}

impl Point {
    /// Color in 32-bit normalized RGB.
    #[inline]
    pub fn color_rgb_normalized(&self) -> [f32; 3] {
        [
            self.color_rgb[0] as f32 / 255.0,
            self.color_rgb[1] as f32 / 255.0,
            self.color_rgb[2] as f32 / 255.0,
        ]
    }
}

impl Decoder for Point {
    type Err = Error;

    #[inline]
    fn decode(reader: &mut impl Read) -> Result<Self, Self::Err> {
        let position = [
            reader.read_f64::<LE>()?,
            reader.read_f64::<LE>()?,
            reader.read_f64::<LE>()?,
        ];
        let color_rgb = read_bytes_const(reader)?;

        // Skip re-projection error
        advance(reader, 8)?;

        // Skip tracks
        let track_count = reader.read_u64::<LE>()? as usize;
        advance(reader, 8 * track_count)?;

        Ok(Self {
            position,
            color_rgb,
        })
    }
}

impl Encoder for Point {
    type Err = Error;

    #[inline]
    fn encode(
        &self,
        writer: &mut impl Write,
    ) -> Result<(), Self::Err> {
        writer.write_f64::<LE>(self.position[0])?;
        writer.write_f64::<LE>(self.position[1])?;
        writer.write_f64::<LE>(self.position[2])?;
        writer.write_all(&self.color_rgb)?;

        // Write -1.0 to re-projection error
        writer.write_f64::<LE>(-1.0)?;

        // Write 0 to track count
        writer.write_u64::<LE>(0)?;

        Ok(())
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn color_rgb_normalized() {
        use super::*;

        let source = Point {
            position: Default::default(),
            color_rgb: [255, 128, 0],
        };

        let target = [1.0, 0.5019608, 0.0];
        let output = source.color_rgb_normalized();
        assert_eq!(output, target);
    }
}