mirror of
https://git.mirrors.martin98.com/https://github.com/google/draco
synced 2025-04-22 05:39:54 +08:00
4.2 KiB
4.2 KiB
Prediction Normal Transform
ModMax()
int32_t ModMax(x, center_value_, max_quantized_value_) {
if (x > center_value_)
return x - max_quantized_value_;
if (x < -center_value_)
return x + max_quantized_value_;
return x;
}
{:.draco-syntax}
InvertDiamond()
void InvertDiamond(s, t, center_value_) {
sign_s = 0;
sign_t = 0;
if (s >= 0 && t >= 0) {
sign_s = 1;
sign_t = 1;
} else if (s <= 0 && t <= 0) {
sign_s = -1;
sign_t = -1;
} else {
sign_s = (s > 0) ? 1 : -1;
sign_t = (t > 0) ? 1 : -1;
}
corner_point_s = sign_s * center_value_;
corner_point_t = sign_t * center_value_;
s = 2 * s - corner_point_s;
t = 2 * t - corner_point_t;
if (sign_s * sign_t >= 0) {
temp = s;
s = -t;
t = -temp;
} else {
temp = s;
s = t;
t = temp;
}
s = (s + corner_point_s) / 2;
t = (t + corner_point_t) / 2;
}
{:.draco-syntax}
GetRotationCount()
void GetRotationCount(pred, count) {
sign_x = pred[0];
sign_y = pred[1];
rotation_count = 0;
if (sign_x == 0) {
if (sign_y == 0) {
rotation_count = 0;
} else if (sign_y > 0) {
rotation_count = 3;
} else {
rotation_count = 1;
}
} else if (sign_x > 0) {
if (sign_y >= 0) {
rotation_count = 2;
} else {
rotation_count = 1;
}
} else {
if (sign_y <= 0) {
rotation_count = 0;
} else {
rotation_count = 3;
}
}
count = rotation_count;
}
{:.draco-syntax}
RotatePoint()
void RotatePoint(p, rotation_count, out_p) {
switch (rotation_count) {
case 1:
out_p.push_back(p[1]);
out_p.push_back(-p[0]);
return;
case 2:
out_p.push_back(-p[0]);
out_p.push_back(-p[1]);
return;
case 3:
out_p.push_back(-p[1]);
out_p.push_back(p[0]);
return;
default:
out_p.push_back(p[0]);
out_p.push_back(p[1]);
return;
}
}
{:.draco-syntax}
IsInBottomLeft()
bool IsInBottomLeft(p) {
if (p[0] == 0 && p[1] == 0)
return true;
return (p[0] < 0 && p[1] <= 0);
}
{:.draco-syntax}
PredictionSchemeNormalOctahedronCanonicalizedDecodingTransform_ComputeOriginalValue2()
void PredictionSchemeNormalOctahedronCanonicalizedDecodingTransform_ComputeOriginalValue2(
pred_in, corr, out, center_value_, max_quantized_value_) {
t.assign(2, center_value_);
SubtractVectors(pred_in, t, &pred);
pred_is_in_diamond = Abs(pred[0]) + Abs(pred[1]) <= center_value_;
if (!pred_is_in_diamond) {
InvertDiamond(&pred[0], &pred[1], center_value_);
}
pred_is_in_bottom_left = IsInBottomLeft(pred);
GetRotationCount(pred, &rotation_count);
if (!pred_is_in_bottom_left) {
RotatePoint(pred, rotation_count, &temp_rot);
for (i = 0; i < temp_rot.size(); ++i) {
pred[i] = temp_rot[i];
}
}
AddVectors(pred, corr, &orig);
orig[0] = ModMax(orig[0], center_value_, max_quantized_value_);
orig[1] = ModMax(orig[1], center_value_, max_quantized_value_);
if (!pred_is_in_bottom_left) {
reverse_rotation_count = (4 - rotation_count) % 4;
RotatePoint(orig, reverse_rotation_count, &temp_rot);
for (i = 0; i < temp_rot.size(); ++i) {
orig[i] = temp_rot[i];
}
}
if (!pred_is_in_diamond) {
InvertDiamond(&orig[0], &orig[1], center_value_);
}
AddVectors(orig, t, out);
}
{:.draco-syntax}
PredictionSchemeNormalOctahedronCanonicalizedDecodingTransform_ComputeOriginalValue()
void PredictionSchemeNormalOctahedronCanonicalizedDecodingTransform_ComputeOriginalValue(
pred_vals, corr_vals, out_orig_vals) {
encoded_max_quantized_value =
pred_trasnform_normal_max_q_val[curr_att_dec][curr_att];
quantization_bits_ = MostSignificantBit(encoded_max_quantized_value) + 1;
max_quantized_value_ = (1 << quantization_bits_) - 1;
max_value_ = max_quantized_value_ - 1;
center_value_ = max_value_ / 2;
pred.push_back(pred_vals[0]);
pred.push_back(pred_vals[1]);
corr.push_back(corr_vals[0]);
corr.push_back(corr_vals[1]);
PredictionSchemeNormalOctahedronCanonicalizedDecodingTransform_ComputeOriginalValue2(
pred, corr, &orig, center_value_, max_quantized_value_);
out_orig_vals[0] = orig[0];
out_orig_vals[1] = orig[1];
}
{:.draco-syntax}