mirror of
https://git.mirrors.martin98.com/https://github.com/google/draco
synced 2025-04-22 05:39:54 +08:00
5.6 KiB
5.6 KiB
Normal Prediction Decoder
GetPositionForDataId()
void GetPositionForDataId(data_id, pos) {
corner = encoded_attribute_value_index_to_corner_map[curr_att_dec][data_id];
point_id = corner_to_point_map[corner];
mapped_index = indices_map_[0][point_id];
pos_orig = seq_int_att_dec_original_values[0][0];
for (i = 0; i < 3; ++i) {
pos.push_back(pos_orig[(mapped_index * 3) + i]);
}
}
{:.draco-syntax}
GetPositionForCorner()
void GetPositionForCorner(ci, pos) {
CornerToVerts(curr_att_dec, ci, &vert_id, &n, &p);
data_id = vertex_to_encoded_attribute_value_index_map[curr_att_dec][vert_id];
GetPositionForDataId(data_id, pos);
}
{:.draco-syntax}
MeshPredictionSchemeGeometricNormalPredictorArea_ComputePredictedValue()
void MeshPredictionSchemeGeometricNormalPredictorArea_ComputePredictedValue(
corner_id, predicted_value_) {
GetPositionForCorner(corner_id, &pos_cent);
normal.assign(3, 0);
corner = corner_id;
start_corner_ = corner;
left_traversal_ = true;
while (corner >= 0) {
c_next = Next(corner);
c_prev = Previous(corner);
GetPositionForCorner(c_next, &pos_next);
GetPositionForCorner(c_prev, &pos_prev);
SubtractVectors(pos_next, pos_cent, &delta_next);
SubtractVectors(pos_prev, pos_cent, &delta_prev);
CrossProduct(delta_next, delta_prev, &cross);
AddVectors(normal, cross, &temp_norm);
for (i = 0; i < temp_norm.size(); ++i) {
normal[i] = temp_norm[i];
}
if (left_traversal_) {
left_c = SwingLeft(curr_att_dec, corner);
corner = left_c;
if (corner < 0) {
right_c = SwingRight(curr_att_dec, start_corner_);
corner = right_c;
left_traversal_ = false;
} else if (corner == start_corner_) {
corner = kInvalidCornerIndex;
}
} else {
right_c = SwingRight(curr_att_dec, corner);
corner = right_c;
}
}
AbsSum(normal, &abs_sum);
upper_bound = 1 << 29;
if (abs_sum > upper_bound) {
quotient = abs_sum / upper_bound;
DivideScalar(normal, quotient, &vec_div);
for (i = 0; i < vec_div.size(); ++i) {
normal[i] = vec_div[i];
}
}
predicted_value_[0] = normal[0];
predicted_value_[1] = normal[1];
predicted_value_[2] = normal[2];
}
{:.draco-syntax}
CanonicalizeIntegerVector()
void CanonicalizeIntegerVector(vec, center_value_) {
abs_sum = Abs(vec[0]) + Abs(vec[1]) + Abs(vec[2]);
if (abs_sum == 0) {
vec[0] = center_value_;
} else {
vec[0] = (vec[0] * center_value_) / abs_sum;
vec[1] = (vec[1] * center_value_) / abs_sum;
if (vec[2] >= 0) {
vec[2] = center_value_ - Abs(vec[0]) - Abs(vec[1]);
} else {
vec[2] = -(center_value_ - Abs(vec[0]) - Abs(vec[1]));
}
}
}
{:.draco-syntax}
CanonicalizeOctahedralCoords()
void CanonicalizeOctahedralCoords(s, t, out_s,
out_t, center_value_, max_value_) {
if ((s == 0 && t == 0) || (s == 0 && t == max_value_) ||
(s == max_value_ && t == 0)) {
s = max_value_;
t = max_value_;
} else if (s == 0 && t > center_value_) {
t = center_value_ - (t - center_value_);
} else if (s == max_value_ && t < center_value_) {
t = center_value_ + (center_value_ - t);
} else if (t == max_value_ && s < center_value_) {
s = center_value_ + (center_value_ - s);
} else if (t == 0 && s > center_value_) {
s = center_value_ - (s - center_value_);
}
out_s = s;
out_t = t;
}
{:.draco-syntax}
IntegerVectorToQuantizedOctahedralCoords()
void IntegerVectorToQuantizedOctahedralCoords(
int_vec, out_s, out_t, center_value_, max_value_) {
if (int_vec[0] >= 0) {
s = (int_vec[1] + center_value_);
t = (int_vec[2] + center_value_);
} else {
if (int_vec[1] < 0) {
s = Abs(int_vec[2]);
} else {
s = (max_value_ - Abs(int_vec[2]));
}
if (int_vec[2] < 0) {
t = Abs(int_vec[1]);
} else {
t = (max_value_ - Abs(int_vec[1]));
}
}
CanonicalizeOctahedralCoords(s, t, out_s, out_t, center_value_, max_value_);
}
{:.draco-syntax}
MeshPredictionSchemeGeometricNormalDecoder_ComputeOriginalValues()
void MeshPredictionSchemeGeometricNormalDecoder_ComputeOriginalValues(num_values) {
signed_values = seq_int_att_dec_symbols_to_signed_ints[curr_att_dec][curr_att];
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;
corner_map_size = num_values;
flip_normal_bits = pred_transform_normal_flip_normal_bits[curr_att_dec][curr_att];
out_values = signed_values;
for (data_id = 0; data_id < corner_map_size; ++data_id) {
corner_id = encoded_attribute_value_index_to_corner_map[curr_att_dec][data_id];
MeshPredictionSchemeGeometricNormalPredictorArea_ComputePredictedValue(
corner_id, &pred_normal_3d);
CanonicalizeIntegerVector(pred_normal_3d, center_value_);
if (flip_normal_bits[data_id]) {
for (i = 0; i < pred_normal_3d.size(); ++i) {
pred_normal_3d[i] = -pred_normal_3d[i];
}
}
IntegerVectorToQuantizedOctahedralCoords(&pred_normal_3d[0],
&pred_normal_oct[0], &pred_normal_oct[1], center_value_, max_value_);
data_offset = data_id * 2;
PredictionSchemeNormalOctahedronCanonicalizedDecodingTransform_ComputeOriginalValue(
&pred_normal_oct[0], &out_values[data_offset], &out_values[data_offset]);
}
seq_int_att_dec_original_values[curr_att_dec][curr_att] = out_values;
}
{:.draco-syntax}