pub const DRACO_POINT_CLOUD_BITSTREAM_VERSION_MAJOR: u8 = 2;
pub const DRACO_POINT_CLOUD_BITSTREAM_VERSION_MINOR: u8 = 3;
pub const DRACO_MESH_BITSTREAM_VERSION_MAJOR: u8 = 2;
pub const DRACO_MESH_BITSTREAM_VERSION_MINOR: u8 = 2;
pub const DEFAULT_MESH_VERSION: (u8, u8) = (
DRACO_MESH_BITSTREAM_VERSION_MAJOR,
DRACO_MESH_BITSTREAM_VERSION_MINOR,
);
pub const DEFAULT_POINT_CLOUD_VERSION: (u8, u8) = (
DRACO_POINT_CLOUD_BITSTREAM_VERSION_MAJOR,
DRACO_POINT_CLOUD_BITSTREAM_VERSION_MINOR,
);
pub const VERSION_FLAGS_INTRODUCED: (u8, u8) = (1, 3);
pub const VERSION_VARINT_ENCODING: (u8, u8) = (2, 0);
pub const VERSION_VARINT_UNIQUE_ID: (u8, u8) = (1, 3);
#[inline]
pub fn version_at_least(major: u8, minor: u8, target: (u8, u8)) -> bool {
major > target.0 || (major == target.0 && minor >= target.1)
}
#[inline]
pub fn version_less_than(major: u8, minor: u8, target: (u8, u8)) -> bool {
major < target.0 || (major == target.0 && minor < target.1)
}
#[inline]
pub fn uses_varint_encoding(major: u8, _minor: u8) -> bool {
major >= VERSION_VARINT_ENCODING.0
}
#[inline]
pub fn has_header_flags(major: u8, minor: u8) -> bool {
version_at_least(major, minor, VERSION_FLAGS_INTRODUCED)
}
#[inline]
pub fn uses_varint_unique_id(major: u8, minor: u8) -> bool {
version_at_least(major, minor, VERSION_VARINT_UNIQUE_ID)
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EncodeTarget {
MeshEdgebreaker,
MeshSequential,
PointCloudSequential,
PointCloudKdTree,
}
impl EncodeTarget {
pub fn claimed_versions(self) -> &'static [(u8, u8)] {
match self {
EncodeTarget::MeshEdgebreaker => &[(2, 2), (2, 1), (2, 0), (1, 2), (1, 1)],
EncodeTarget::MeshSequential => &[(2, 2), (1, 3)],
EncodeTarget::PointCloudSequential => &[(2, 3), (1, 3)],
EncodeTarget::PointCloudKdTree => &[(2, 3)],
}
}
pub fn default_version(self) -> (u8, u8) {
match self {
EncodeTarget::MeshEdgebreaker | EncodeTarget::MeshSequential => DEFAULT_MESH_VERSION,
EncodeTarget::PointCloudSequential | EncodeTarget::PointCloudKdTree => {
DEFAULT_POINT_CLOUD_VERSION
}
}
}
}
pub fn validate_encodable_version(
major: u8,
minor: u8,
target: EncodeTarget,
) -> Result<(), crate::status::DracoError> {
if major == 0 && minor == 0 {
return Ok(());
}
if target.claimed_versions().contains(&(major, minor)) {
return Ok(());
}
let claimed = target
.claimed_versions()
.iter()
.map(|(major, minor)| format!("{major}.{minor}"))
.collect::<Vec<_>>()
.join(", ");
Err(crate::status::DracoError::unsupported_version(format!(
"Cannot encode bitstream version {major}.{minor} for {target:?}: supported are {claimed}"
)))
}
#[inline]
pub fn bitstream_version(major: u8, minor: u8) -> u16 {
((major as u16) << 8) | (minor as u16)
}
#[cfg(feature = "encoder")]
#[inline]
pub(crate) fn binds_portable_parent_only(major: u8, minor: u8) -> bool {
major == 0 || bitstream_version(major, minor) >= 0x0200
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_version_at_least() {
assert!(version_at_least(1, 3, (1, 3)));
assert!(version_at_least(2, 0, (1, 3)));
assert!(!version_at_least(1, 2, (1, 3)));
assert!(!version_at_least(0, 9, (1, 3)));
}
#[test]
fn test_version_less_than() {
assert!(version_less_than(1, 2, (2, 0)));
assert!(!version_less_than(2, 0, (2, 0)));
assert!(!version_less_than(2, 1, (2, 0)));
}
#[test]
fn test_uses_varint_encoding() {
assert!(!uses_varint_encoding(1, 3));
assert!(uses_varint_encoding(2, 0));
assert!(uses_varint_encoding(2, 2));
}
#[test]
fn test_has_header_flags() {
assert!(!has_header_flags(1, 2));
assert!(has_header_flags(1, 3));
assert!(has_header_flags(2, 0));
}
#[test]
fn test_bitstream_version() {
assert_eq!(bitstream_version(2, 2), 0x0202);
assert_eq!(bitstream_version(1, 1), 0x0101);
assert_eq!(bitstream_version(2, 0), 0x0200);
assert!(bitstream_version(1, 2) < bitstream_version(2, 0));
assert!(bitstream_version(2, 1) < bitstream_version(2, 2));
}
}