#pragma once #include "DNACommon.hpp" #include namespace DataSpec::DNAANIM { struct Value { athena::simd simd; Value() = default; Value(const athena::simd& s) : simd(s) {} Value(const atVec3f& v) : simd(v.simd) {} Value(const atVec4f& v) : simd(v.simd) {} Value(float x, float y, float z) : simd(x, y, z, 0.f) {} Value(float w, float x, float y, float z) : simd(w, x, y, z) {} }; struct QuantizedValue { atInt32 v[4]; atInt32& operator[] (size_t idx) {return v[idx];} atInt32 operator[] (size_t idx) const {return v[idx];} int qFrom(const QuantizedValue& other, size_t idx) const { atInt32 delta = std::abs(v[idx] - other.v[idx]); if (delta == 0) return 1; return int(std::ceil(std::log2(delta))) + 1; } }; struct QuantizedRot { QuantizedValue v; bool w; }; struct Channel { enum class Type { Rotation, Translation, Scale, KfHead, RotationMP3 } type; atInt32 id = -1; QuantizedValue i = {}; atUint8 q[4] = {}; }; size_t ComputeBitstreamSize(size_t keyFrameCount, const std::vector& channels); class BitstreamReader { size_t m_bitCur; atInt32 dequantize(const atUint8* data, atUint8 q); bool dequantizeBit(const atUint8* data); public: std::vector> read(const atUint8* data, size_t keyFrameCount, const std::vector& channels, atUint32 rotDiv, float transMult, float scaleMult); }; class BitstreamWriter { size_t m_bitCur; void quantize(atUint8* data, atUint8 q, atInt32 val); void quantizeBit(atUint8* data, bool val); public: std::unique_ptr write(const std::vector>& chanKeys, size_t keyFrameCount, std::vector& channels, atUint32 quantRange, atUint32& rotDivOut, float& transMultOut, float& scaleMultOut, size_t& sizeOut); }; }