metaforce/DataSpec/DNACommon/ANIM.hpp

74 lines
2.1 KiB
C++
Raw Permalink Normal View History

2018-10-07 03:42:33 +00:00
#pragma once
2015-08-11 23:32:02 +00:00
#include <cassert>
2016-09-11 18:38:44 +00:00
#include <cmath>
#include <cstddef>
#include <memory>
#include <vector>
#include <athena/Types.hpp>
2015-08-11 23:32:02 +00:00
2018-12-08 05:30:43 +00:00
namespace DataSpec::DNAANIM {
struct Value {
athena::simd<float> simd;
Value() = default;
Value(const athena::simd<float>& 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) {}
2015-08-11 23:32:02 +00:00
};
2018-12-08 05:30:43 +00:00
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 = v[idx] - other.v[idx];
atInt32 absDelta = std::abs(delta);
if (absDelta == 0)
2018-12-08 05:30:43 +00:00
return 1;
int ret = int(std::ceil(std::log2(absDelta))) + 1;
if (delta > 0 && (delta >> (ret - 1)))
++ret;
2019-06-15 00:39:20 +00:00
assert(ret <= 24 && "Bad q value");
return ret;
2018-12-08 05:30:43 +00:00
}
2015-08-11 23:32:02 +00:00
};
2018-12-08 05:30:43 +00:00
struct QuantizedRot {
QuantizedValue v;
bool w;
2015-08-11 23:32:02 +00:00
};
2018-12-08 05:30:43 +00:00
struct Channel {
enum class Type { Rotation, Translation, Scale, KfHead, RotationMP3 } type;
atInt32 id = -1;
QuantizedValue i = {};
atUint8 q[4] = {};
2015-08-11 23:32:02 +00:00
};
size_t ComputeBitstreamSize(size_t keyFrameCount, const std::vector<Channel>& channels);
2018-12-08 05:30:43 +00:00
class BitstreamReader {
size_t m_bitCur;
atInt32 dequantize(const atUint8* data, atUint8 q);
bool dequantizeBit(const atUint8* data);
2015-08-11 23:32:02 +00:00
public:
2018-12-08 05:30:43 +00:00
std::vector<std::vector<Value>> read(const atUint8* data, size_t keyFrameCount, const std::vector<Channel>& channels,
atUint32 rotDiv, float transMult, float scaleMult);
2015-08-11 23:32:02 +00:00
};
2018-12-08 05:30:43 +00:00
class BitstreamWriter {
size_t m_bitCur;
void quantize(atUint8* data, atUint8 q, atInt32 val);
void quantizeBit(atUint8* data, bool val);
2015-08-11 23:32:02 +00:00
public:
2018-12-08 05:30:43 +00:00
std::unique_ptr<atUint8[]> write(const std::vector<std::vector<Value>>& chanKeys, size_t keyFrameCount,
std::vector<Channel>& channels, atUint32 quantRange, atUint32& rotDivOut,
float& transMultOut, float& scaleMultOut, size_t& sizeOut);
2015-08-11 23:32:02 +00:00
};
2018-12-08 05:30:43 +00:00
} // namespace DataSpec::DNAANIM