52 lines
1.5 KiB
C++
52 lines
1.5 KiB
C++
#pragma once
|
|
#include <map>
|
|
#include <vector>
|
|
#include "NormalQuantizer.h"
|
|
#include "../../../core/BitHelper.h"
|
|
|
|
|
|
NormalQuantizer::NormalQuantizer(unsigned8 bits): mBits(bits)
|
|
{
|
|
// Bits must be an even number, as there are two channels for an ONV
|
|
assert(bits % 2 == 0);
|
|
|
|
// Precalculate the channel mask
|
|
unsigned32 channelStartHS = 32 - SmallNormal::BITS / 2;
|
|
mChannelMask = BitHelper::GetHSMask<unsigned32>(channelStartHS, channelStartHS + mBits / 2);
|
|
}
|
|
|
|
std::map<SmallNormal, SmallNormal, NormalCompare>* NormalQuantizer::QuantizeMaterials(std::vector<SmallNormal> normals) const
|
|
{
|
|
std::map<SmallNormal, SmallNormal, NormalCompare>* res = new std::map<SmallNormal, SmallNormal, NormalCompare>();
|
|
for (const SmallNormal& normal : normals)
|
|
{
|
|
res->insert(std::make_pair(normal, Quantize(normal)));
|
|
}
|
|
if (mBits <= QUANTIZE_ALL_UP_TO)
|
|
{
|
|
unsigned32 maxPerChannel = 1 << (mBits / 2);
|
|
unsigned8 shift = (SmallNormal::BITS - mBits) / 2;
|
|
for (unsigned32 x = 0; x < maxPerChannel; x++)
|
|
for (unsigned32 y = 0; y < maxPerChannel; y++)
|
|
{
|
|
SmallNormal v;
|
|
v.SetXComponent(x << shift);
|
|
v.SetYComponent(y << shift);
|
|
res->insert(std::make_pair(v, v));
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
SmallNormal NormalQuantizer::Quantize(const SmallNormal& normal) const
|
|
{
|
|
SmallNormal quantized;
|
|
quantized.SetXComponent(normal.GetXComponent() & mChannelMask);
|
|
quantized.SetYComponent(normal.GetYComponent() & mChannelMask);
|
|
return quantized;
|
|
}
|
|
|
|
std::string NormalQuantizer::GetQuantizerDescriptor() const
|
|
{
|
|
return std::to_string(mBits);
|
|
} |