mirror of
https://git.mirrors.martin98.com/https://github.com/google/draco
synced 2025-06-04 11:25:44 +08:00
150 lines
4.5 KiB
Markdown
150 lines
4.5 KiB
Markdown
## TexCoords Prediction Decoder
|
|
|
|
### IntSqrt()
|
|
|
|
~~~~~
|
|
uint64_t IntSqrt(number) {
|
|
if (number == 0)
|
|
return 0;
|
|
act_number = number;
|
|
square_root = 1;
|
|
while (act_number >= 2) {
|
|
square_root *= 2;
|
|
act_number /= 4;
|
|
}
|
|
do {
|
|
square_root = (square_root + number / square_root) / 2;
|
|
} while (square_root * square_root > number);
|
|
return square_root;
|
|
}
|
|
~~~~~
|
|
{:.draco-syntax}
|
|
|
|
|
|
### GetPositionForEntryId()
|
|
|
|
~~~~~
|
|
void GetPositionForEntryId(entry_id, pos) {
|
|
corner = encoded_attribute_value_index_to_corner_map[curr_att_dec][entry_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}
|
|
|
|
|
|
### GetTexCoordForEntryId()
|
|
|
|
~~~~~
|
|
void GetTexCoordForEntryId(entry_id, data, tex_coords) {
|
|
data_offset = entry_id * kTexCoordsNumComponents;
|
|
tex_coords.push_back(data[data_offset]);
|
|
tex_coords.push_back(data[data_offset + 1]);
|
|
}
|
|
~~~~~
|
|
{:.draco-syntax}
|
|
|
|
|
|
### MeshPredictionSchemeTexCoordsPortablePredictor_ComputePredictedValue()
|
|
|
|
~~~~~
|
|
void MeshPredictionSchemeTexCoordsPortablePredictor_ComputePredictedValue(
|
|
corner_id, data, data_id, predicted_value_) {
|
|
CornerToVerts(curr_att_dec, corner_id, &vert_id, &next_vert_id, &prev_vert_id);
|
|
next_data_id =
|
|
vertex_to_encoded_attribute_value_index_map[curr_att_dec][next_vert_id];
|
|
prev_data_id =
|
|
vertex_to_encoded_attribute_value_index_map[curr_att_dec][prev_vert_id];
|
|
|
|
if (prev_data_id < data_id && next_data_id < data_id) {
|
|
GetTexCoordForEntryId(next_data_id, data, &n_uv);
|
|
GetTexCoordForEntryId(prev_data_id, data, &p_uv);
|
|
if (p_uv == n_uv) {
|
|
predicted_value_[0] = p_uv[0];
|
|
predicted_value_[1] = p_uv[1];
|
|
return;
|
|
}
|
|
GetPositionForEntryId(data_id, &tip_pos);
|
|
GetPositionForEntryId(next_data_id, &next_pos);
|
|
GetPositionForEntryId(prev_data_id, &prev_pos);
|
|
SubtractVectors(prev_pos, next_pos, &pn);
|
|
Dot(pn, pn, &pn_norm2_squared);
|
|
|
|
if (pn_norm2_squared != 0) {
|
|
SubtractVectors(tip_pos, next_pos, &cn);
|
|
Dot(cn, pn, &cn_dot_pn);
|
|
SubtractVectors(p_uv, n_uv, &pn_uv);
|
|
MultiplyScalar(pn_uv, cn_dot_pn, &vec_mult_1);
|
|
MultiplyScalar(n_uv, pn_norm2_squared, &vec_mult_2);
|
|
AddVectors(vec_mult_1, vec_mult_2, &x_uv);
|
|
MultiplyScalar(pn, cn_dot_pn, &vec_mult);
|
|
DivideScalar(vec_mult, pn_norm2_squared, &vec_div);
|
|
AddVectors(next_pos, vec_div, &x_pos);
|
|
SubtractVectors(tip_pos, x_pos, &vec_sub);
|
|
Dot(vec_sub, vec_sub, &cx_norm2_squared);
|
|
|
|
temp_vec.push_back(pn_uv[1]);
|
|
temp_vec.push_back(-pn_uv[0]);
|
|
norm_squared = IntSqrt(cx_norm2_squared * pn_norm2_squared);
|
|
MultiplyScalar(temp_vec, norm_squared, &cx_uv);
|
|
orientation = pred_tex_coords_orientations[curr_att_dec][curr_att].pop_back();
|
|
if (orientation)
|
|
AddVectors(x_uv, cx_uv, &temp_vec);
|
|
else
|
|
SubtractVectors(x_uv, cx_uv, &temp_vec);
|
|
DivideScalar(temp_vec, pn_norm2_squared, &predicted_uv);
|
|
predicted_value_[0] = predicted_uv[0];
|
|
predicted_value_[1] = predicted_uv[1];
|
|
return;
|
|
}
|
|
}
|
|
data_offset = 0;
|
|
if (prev_data_id < data_id) {
|
|
data_offset = prev_data_id * kTexCoordsNumComponents;
|
|
}
|
|
if (next_data_id < data_id) {
|
|
data_offset = next_data_id * kTexCoordsNumComponents;
|
|
} else {
|
|
if (data_id > 0) {
|
|
data_offset = (data_id - 1) * kTexCoordsNumComponents;
|
|
} else {
|
|
for (i = 0; i < kTexCoordsNumComponents; ++i) {
|
|
predicted_value_[i] = 0;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
for (i = 0; i < kTexCoordsNumComponents; ++i) {
|
|
predicted_value_[i] = data[data_offset + i];
|
|
}
|
|
}
|
|
~~~~~
|
|
{:.draco-syntax}
|
|
|
|
|
|
### MeshPredictionSchemeTexCoordsPortableDecoder_ComputeOriginalValues()
|
|
|
|
~~~~~
|
|
void MeshPredictionSchemeTexCoordsPortableDecoder_ComputeOriginalValues(num_values)
|
|
{
|
|
signed_values = seq_int_att_dec_symbols_to_signed_ints[curr_att_dec][curr_att];
|
|
num_components = GetNumComponents();
|
|
corner_map_size = num_values;
|
|
out_values = signed_values;
|
|
for (p = 0; p < corner_map_size; ++p) {
|
|
corner_id = encoded_attribute_value_index_to_corner_map[curr_att_dec][p];
|
|
MeshPredictionSchemeTexCoordsPortablePredictor_ComputePredictedValue(
|
|
corner_id, &out_values[0], p, &predicted_value_);
|
|
dst_offset = p * num_components;
|
|
PredictionSchemeWrapDecodingTransform_ComputeOriginalValue(
|
|
&predicted_value_[0], &out_values[dst_offset], &out_values[dst_offset]);
|
|
}
|
|
seq_int_att_dec_original_values[curr_att_dec][curr_att] = out_values;
|
|
}
|
|
~~~~~
|
|
{:.draco-syntax}
|