pub mod delta_prediction;
pub mod derivative_prediction;
pub mod mesh_multi_parallelogram_prediction;
pub mod mesh_normal_prediction;
pub mod mesh_parallelogram_prediction;
pub mod mesh_prediction_for_texture_coordinates;
use crate::core::shared::{ConfigType, CornerIdx, Vector, VertexIdx};
use crate::core::{attribute::Attribute, corner_table::GenericCornerTable};
use crate::prelude::{ByteReader, ByteWriter, NdVector};
pub(crate) trait PredictionSchemeImpl<'parents, C, const N: usize>
where
C: GenericCornerTable,
NdVector<N, i32>: Vector<N, Component = i32>,
{
#[allow(dead_code)]
const ID: u32 = 0;
type AdditionalDataForMetadata;
fn new(parents: &[&'parents Attribute], conn_att: &'parents C) -> Self;
#[allow(unused)]
fn get_values_impossible_to_predict(
&mut self,
value_indices: &mut Vec<std::ops::Range<usize>>,
) -> Vec<std::ops::Range<usize>>;
fn predict(
&mut self,
c: CornerIdx,
vertices_processed_up_till_now: &[VertexIdx],
attribute: &Attribute,
) -> NdVector<N, i32>;
fn encode_prediction_metadtata<W>(&self, _writer: &mut W) -> Result<(), Err>
where
W: ByteWriter,
{
Ok(())
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum PredictionSchemeType {
DerivativePrediction,
MeshMultiParallelogramPrediction,
MeshParallelogramPrediction,
MeshNormalPrediction,
MeshPredictionForTextureCoordinates,
DeltaPrediction,
NoPrediction,
Invalid,
}
impl PredictionSchemeType {
pub(crate) fn get_id(&self) -> u8 {
match self {
PredictionSchemeType::DeltaPrediction => 0,
PredictionSchemeType::MeshParallelogramPrediction => 1,
PredictionSchemeType::MeshMultiParallelogramPrediction => 2,
PredictionSchemeType::MeshPredictionForTextureCoordinates => 5,
PredictionSchemeType::MeshNormalPrediction => 6,
PredictionSchemeType::DerivativePrediction => 7,
PredictionSchemeType::NoPrediction => 0xFE, PredictionSchemeType::Invalid => 0xFF, }
}
pub(crate) fn write_to<W>(&self, writer: &mut W)
where
W: ByteWriter,
{
let id = self.get_id();
writer.write_u8(id);
}
#[allow(unused)]
pub(crate) fn read_from<R>(reader: &mut R) -> Result<Self, usize>
where
R: ByteReader,
{
let id = reader.read_u8().unwrap() as usize; let out = match id {
0 => PredictionSchemeType::DeltaPrediction,
1 => PredictionSchemeType::MeshParallelogramPrediction,
2 => PredictionSchemeType::MeshMultiParallelogramPrediction,
5 => PredictionSchemeType::DerivativePrediction,
6 => PredictionSchemeType::MeshNormalPrediction,
7 => PredictionSchemeType::MeshPredictionForTextureCoordinates,
0xFE => PredictionSchemeType::NoPrediction, 0xFF => PredictionSchemeType::Invalid, _ => return Err(id),
};
Ok(out)
}
#[allow(unused, clippy::inherent_to_string)]
pub fn to_string(&self) -> String {
match self {
PredictionSchemeType::DeltaPrediction => "DeltaPrediction".to_string(),
PredictionSchemeType::DerivativePrediction => "DerivativePrediction".to_string(),
PredictionSchemeType::MeshMultiParallelogramPrediction => {
"MeshMultiParallelogramPrediction".to_string()
}
PredictionSchemeType::MeshParallelogramPrediction => {
"MeshParallelogramPrediction".to_string()
}
PredictionSchemeType::NoPrediction => "NoPrediction".to_string(),
PredictionSchemeType::MeshNormalPrediction => "MeshNormalPrediction".to_string(),
PredictionSchemeType::MeshPredictionForTextureCoordinates => {
"MeshPredictionForTextureCoordinates".to_string()
}
PredictionSchemeType::Invalid => "Invalid".to_string(),
}
}
}
#[derive(thiserror::Error, Clone, Debug)]
pub enum Err {
#[error("ranscoder error: {0}")]
RanscoderError(#[from] crate::encode::entropy::rans::Err),
}
pub(crate) enum PredictionScheme<'parents, C, const N: usize> {
DeltaPrediction(delta_prediction::DeltaPrediction<'parents, C, N>),
DerivativePrediction(
derivative_prediction::DerivativePredictionForTextureCoordinates<'parents, C, N>,
),
MeshMultiParallelogramPrediction(
mesh_multi_parallelogram_prediction::MeshMultiParallelogramPrediction<'parents, C, N>,
),
MeshParallelogramPrediction(
mesh_parallelogram_prediction::MeshParallelogramPrediction<'parents, C, N>,
),
MeshNormalPrediction(mesh_normal_prediction::MeshNormalPrediction<'parents, C, N>),
MeshPredictionForTextureCoordinates(
mesh_prediction_for_texture_coordinates::MeshPredictionForTextureCoordinates<
'parents,
C,
N,
>,
),
NoPrediction(NoPrediction),
}
impl<'parents, C, const N: usize> PredictionScheme<'parents, C, N>
where
C: GenericCornerTable,
NdVector<N, i32>: Vector<N, Component = i32>,
{
pub(crate) fn new(
ty: PredictionSchemeType,
parents: &[&'parents Attribute],
corner_table: &'parents C,
) -> Self {
match ty {
PredictionSchemeType::DeltaPrediction => {
let prediction = delta_prediction::DeltaPrediction::new(parents, corner_table);
PredictionScheme::DeltaPrediction(prediction)
}
PredictionSchemeType::DerivativePrediction => {
let prediction =
derivative_prediction::DerivativePredictionForTextureCoordinates::new(
parents,
corner_table,
);
PredictionScheme::DerivativePrediction(prediction)
}
PredictionSchemeType::MeshMultiParallelogramPrediction => {
let prediction =
mesh_multi_parallelogram_prediction::MeshMultiParallelogramPrediction::new(
parents,
corner_table,
);
PredictionScheme::MeshMultiParallelogramPrediction(prediction)
}
PredictionSchemeType::MeshParallelogramPrediction => {
let prediction = mesh_parallelogram_prediction::MeshParallelogramPrediction::new(
parents,
corner_table,
);
PredictionScheme::MeshParallelogramPrediction(prediction)
}
PredictionSchemeType::MeshNormalPrediction => {
let prediction =
mesh_normal_prediction::MeshNormalPrediction::new(parents, corner_table);
PredictionScheme::MeshNormalPrediction(prediction)
}
PredictionSchemeType::MeshPredictionForTextureCoordinates => {
let prediction = mesh_prediction_for_texture_coordinates::MeshPredictionForTextureCoordinates::new(
parents, corner_table
);
PredictionScheme::MeshPredictionForTextureCoordinates(prediction)
}
PredictionSchemeType::NoPrediction => {
let prediction = NoPrediction::new();
PredictionScheme::NoPrediction(prediction)
}
PredictionSchemeType::Invalid => {
panic!("Invalid prediction scheme type");
}
}
}
#[allow(unused)] pub(crate) fn read_from<R>(
reader: &mut R,
parents: &[&'parents Attribute],
conn_att: &'parents C,
) -> Result<Self, usize>
where
R: ByteReader,
{
let ty = PredictionSchemeType::read_from(reader)?;
Ok(Self::new(ty, parents, conn_att))
}
#[allow(unused)] pub(crate) fn get_values_impossible_to_predict(
&mut self,
value_indices: &mut Vec<std::ops::Range<usize>>,
) -> Vec<std::ops::Range<usize>> {
match self {
PredictionScheme::DeltaPrediction(prediction) => {
prediction.get_values_impossible_to_predict(value_indices)
}
PredictionScheme::DerivativePrediction(prediction) => {
prediction.get_values_impossible_to_predict(value_indices)
}
PredictionScheme::MeshMultiParallelogramPrediction(prediction) => {
prediction.get_values_impossible_to_predict(value_indices)
}
PredictionScheme::MeshParallelogramPrediction(prediction) => {
prediction.get_values_impossible_to_predict(value_indices)
}
PredictionScheme::MeshNormalPrediction(prediction) => {
prediction.get_values_impossible_to_predict(value_indices)
}
PredictionScheme::MeshPredictionForTextureCoordinates(prediction) => {
prediction.get_values_impossible_to_predict(value_indices)
}
PredictionScheme::NoPrediction(_) => Vec::new(),
}
}
pub(crate) fn predict(
&mut self,
i: CornerIdx,
vertices_processed_up_till_now: &[VertexIdx],
attribute: &Attribute,
) -> NdVector<N, i32> {
match self {
PredictionScheme::DeltaPrediction(prediction) => {
prediction.predict(i, vertices_processed_up_till_now, attribute)
}
PredictionScheme::DerivativePrediction(prediction) => {
prediction.predict(i, vertices_processed_up_till_now, attribute)
}
PredictionScheme::MeshMultiParallelogramPrediction(prediction) => {
prediction.predict(i, vertices_processed_up_till_now, attribute)
}
PredictionScheme::MeshParallelogramPrediction(prediction) => {
prediction.predict(i, vertices_processed_up_till_now, attribute)
}
PredictionScheme::MeshNormalPrediction(prediction) => {
prediction.predict(i, vertices_processed_up_till_now, attribute)
}
PredictionScheme::MeshPredictionForTextureCoordinates(prediction) => {
prediction.predict(i, vertices_processed_up_till_now, attribute)
}
PredictionScheme::NoPrediction(_) => NdVector::zero(),
}
}
pub(crate) fn encode_prediction_metadtata<W>(&self, writer: &mut W) -> Result<(), Err>
where
W: ByteWriter,
{
match self {
PredictionScheme::DeltaPrediction(prediction) => {
prediction.encode_prediction_metadtata(writer)
}
PredictionScheme::DerivativePrediction(prediction) => {
prediction.encode_prediction_metadtata(writer)
}
PredictionScheme::MeshMultiParallelogramPrediction(prediction) => {
prediction.encode_prediction_metadtata(writer)
}
PredictionScheme::MeshParallelogramPrediction(prediction) => {
prediction.encode_prediction_metadtata(writer)
}
PredictionScheme::MeshNormalPrediction(prediction) => {
prediction.encode_prediction_metadtata(writer)
}
PredictionScheme::MeshPredictionForTextureCoordinates(prediction) => {
prediction.encode_prediction_metadtata(writer)
}
PredictionScheme::NoPrediction(_) => {
Ok(())
}
}
}
pub(crate) fn get_type(&self) -> PredictionSchemeType {
match self {
PredictionScheme::DeltaPrediction(_) => PredictionSchemeType::DeltaPrediction,
PredictionScheme::DerivativePrediction(_) => PredictionSchemeType::DerivativePrediction,
PredictionScheme::MeshMultiParallelogramPrediction(_) => {
PredictionSchemeType::MeshMultiParallelogramPrediction
}
PredictionScheme::MeshParallelogramPrediction(_) => {
PredictionSchemeType::MeshParallelogramPrediction
}
PredictionScheme::MeshNormalPrediction(_) => PredictionSchemeType::MeshNormalPrediction,
PredictionScheme::MeshPredictionForTextureCoordinates(_) => {
PredictionSchemeType::MeshPredictionForTextureCoordinates
}
PredictionScheme::NoPrediction(_) => PredictionSchemeType::NoPrediction,
}
}
}
#[derive(Clone, Debug)]
pub struct Config {
pub ty: PredictionSchemeType,
}
impl ConfigType for Config {
fn default() -> Self {
Config {
ty: PredictionSchemeType::DeltaPrediction,
}
}
}
pub struct NoPrediction {}
impl NoPrediction {
pub fn new() -> Self {
Self {}
}
}
impl<'a, C, const N: usize> PredictionSchemeImpl<'a, C, N> for NoPrediction
where
C: GenericCornerTable,
NdVector<N, i32>: Vector<N, Component = i32>,
{
const ID: u32 = 0;
type AdditionalDataForMetadata = ();
fn new(_parents: &[&'a Attribute], _conn_att: &'a C) -> Self {
unreachable!()
}
fn get_values_impossible_to_predict(
&mut self,
_value_indices: &mut Vec<std::ops::Range<usize>>,
) -> Vec<std::ops::Range<usize>> {
unreachable!()
}
fn predict(&mut self, _: CornerIdx, _: &[VertexIdx], _: &Attribute) -> NdVector<N, i32> {
unreachable!()
}
}