2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-05-13 11:51:21 +00:00
Lioncash 7f7a18a708 DataSpec/DNACommon: Resolve indirect includes where applicable
Avoids indirect inclusions where applicable and includes the necessary
headers as used by the interface. This way, it prevents code from
failing to compile due to changes in other header inclusions.
2019-08-23 22:03:03 -04:00

74 lines
2.1 KiB
C++

#pragma once
#include <cassert>
#include <cmath>
#include <cstddef>
#include <memory>
#include <vector>
#include <athena/Types.hpp>
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) {}
};
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)
return 1;
int ret = int(std::ceil(std::log2(absDelta))) + 1;
if (delta > 0 && (delta >> (ret - 1)))
++ret;
assert(ret <= 24 && "Bad q value");
return ret;
}
};
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<Channel>& channels);
class BitstreamReader {
size_t m_bitCur;
atInt32 dequantize(const atUint8* data, atUint8 q);
bool dequantizeBit(const atUint8* data);
public:
std::vector<std::vector<Value>> read(const atUint8* data, size_t keyFrameCount, const std::vector<Channel>& 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<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);
};
} // namespace DataSpec::DNAANIM