15#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
16#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_TEX_COORDS_DECODER_H_
17#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_TEX_COORDS_DECODER_H_
35template <
typename DataTypeT,
class TransformT,
class MeshDataT>
36class MeshPredictionSchemeTexCoordsDecoder
39 using CorrType =
typename MeshPredictionSchemeDecoder<DataTypeT, TransformT,
41 MeshPredictionSchemeTexCoordsDecoder(
const PointAttribute *attribute,
42 const TransformT &transform,
43 const MeshDataT &mesh_data,
int version)
44 : MeshPredictionSchemeDecoder<DataTypeT, TransformT, MeshDataT>(
45 attribute, transform, mesh_data),
46 pos_attribute_(nullptr),
47 entry_to_point_id_map_(nullptr),
51 bool ComputeOriginalValues(
const CorrType *in_corr, DataTypeT *out_data,
52 int size,
int num_components,
53 const PointIndex *entry_to_point_id_map)
override;
55 bool DecodePredictionData(DecoderBuffer *buffer)
override;
61 bool IsInitialized()
const override {
62 if (pos_attribute_ ==
nullptr) {
65 if (!this->mesh_data().IsInitialized()) {
71 int GetNumParentAttributes()
const override {
return 1; }
73 GeometryAttribute::Type GetParentAttributeType(
int i)
const override {
76 return GeometryAttribute::POSITION;
79 bool SetParentAttribute(
const PointAttribute *att)
override {
83 if (att->attribute_type() != GeometryAttribute::POSITION) {
86 if (att->num_components() != 3) {
94 Vector3f GetPositionForEntryId(
int entry_id)
const {
95 const PointIndex point_id = entry_to_point_id_map_[entry_id];
97 pos_attribute_->ConvertValue(pos_attribute_->mapped_index(point_id),
102 Vector2f GetTexCoordForEntryId(
int entry_id,
const DataTypeT *
data)
const {
103 const int data_offset = entry_id * num_components_;
105 static_cast<float>(
data[data_offset + 1]));
108 bool ComputePredictedValue(CornerIndex corner_id,
const DataTypeT *
data,
112 const PointAttribute *pos_attribute_;
113 const PointIndex *entry_to_point_id_map_;
114 std::unique_ptr<DataTypeT[]> predicted_value_;
117 std::vector<bool> orientations_;
121template <
typename DataTypeT,
class TransformT,
class MeshDataT>
122bool MeshPredictionSchemeTexCoordsDecoder<DataTypeT, TransformT, MeshDataT>::
123 ComputeOriginalValues(
const CorrType *in_corr, DataTypeT *out_data,
124 int ,
int num_components,
125 const PointIndex *entry_to_point_id_map) {
126 if (num_components != 2) {
130 num_components_ = num_components;
131 entry_to_point_id_map_ = entry_to_point_id_map;
133 std::unique_ptr<DataTypeT[]>(
new DataTypeT[num_components]);
134 this->transform().Init(num_components);
136 const int corner_map_size =
137 static_cast<int>(this->mesh_data().data_to_corner_map()->size());
138 for (
int p = 0; p < corner_map_size; ++p) {
139 const CornerIndex corner_id = this->mesh_data().data_to_corner_map()->at(p);
140 if (!ComputePredictedValue(corner_id, out_data, p)) {
144 const int dst_offset = p * num_components;
145 this->transform().ComputeOriginalValue(
146 predicted_value_.get(), in_corr + dst_offset, out_data + dst_offset);
151template <
typename DataTypeT,
class TransformT,
class MeshDataT>
152bool MeshPredictionSchemeTexCoordsDecoder<DataTypeT, TransformT, MeshDataT>::
155 uint32_t num_orientations = 0;
157 if (!buffer->Decode(&num_orientations)) {
165 if (num_orientations == 0) {
168 if (num_orientations > this->mesh_data().corner_table()->num_corners()) {
173 orientations_.resize(num_orientations);
174 bool last_orientation =
true;
176 if (!decoder.StartDecoding(buffer)) {
179 for (uint32_t i = 0; i < num_orientations; ++i) {
180 if (!decoder.DecodeNextBit()) {
181 last_orientation = !last_orientation;
183 orientations_[i] = last_orientation;
187 MeshDataT>::DecodePredictionData(buffer);
190template <
typename DataTypeT,
class TransformT,
class MeshDataT>
191bool MeshPredictionSchemeTexCoordsDecoder<DataTypeT, TransformT, MeshDataT>::
198 this->mesh_data().corner_table()->Next(corner_id);
200 this->mesh_data().corner_table()->Previous(corner_id);
203 int next_data_id, prev_data_id;
205 int next_vert_id, prev_vert_id;
207 this->mesh_data().corner_table()->Vertex(next_corner_id).value();
209 this->mesh_data().corner_table()->Vertex(prev_corner_id).value();
211 next_data_id = this->mesh_data().vertex_to_data_map()->at(next_vert_id);
212 prev_data_id = this->mesh_data().vertex_to_data_map()->at(prev_vert_id);
214 if (prev_data_id < data_id && next_data_id < data_id) {
216 const Vector2f n_uv = GetTexCoordForEntryId(next_data_id,
data);
217 const Vector2f p_uv = GetTexCoordForEntryId(prev_data_id,
data);
222 for (
const int i : {0, 1}) {
223 if (std::isnan(p_uv[i]) ||
static_cast<double>(p_uv[i]) > INT_MAX ||
224 static_cast<double>(p_uv[i]) < INT_MIN) {
225 predicted_value_[i] = INT_MIN;
227 predicted_value_[i] =
static_cast<int>(p_uv[i]);
234 const Vector3f tip_pos = GetPositionForEntryId(data_id);
235 const Vector3f next_pos = GetPositionForEntryId(next_data_id);
236 const Vector3f prev_pos = GetPositionForEntryId(prev_data_id);
260 const Vector3f pn = prev_pos - next_pos;
261 const Vector3f cn = tip_pos - next_pos;
262 const float pn_norm2_squared = pn.SquaredNorm();
274 s = pn.Dot(cn) / pn_norm2_squared;
278 t = sqrt((cn - pn * s).SquaredNorm() / pn_norm2_squared);
299 const float pnus = pn_uv[0] * s + n_uv[0];
300 const float pnut = pn_uv[0] * t;
301 const float pnvs = pn_uv[1] * s + n_uv[1];
302 const float pnvt = pn_uv[1] * t;
304 if (orientations_.empty()) {
309 const bool orientation = orientations_.back();
310 orientations_.pop_back();
312 predicted_uv =
Vector2f(pnus - pnvt, pnvs + pnut);
314 predicted_uv =
Vector2f(pnus + pnvt, pnvs - pnut);
316 if (std::is_integral<DataTypeT>::value) {
320 const double u =
floor(predicted_uv[0] + 0.5);
321 if (std::isnan(u) || u > INT_MAX || u < INT_MIN) {
322 predicted_value_[0] = INT_MIN;
324 predicted_value_[0] =
static_cast<int>(u);
326 const double v =
floor(predicted_uv[1] + 0.5);
327 if (std::isnan(v) || v > INT_MAX || v < INT_MIN) {
328 predicted_value_[1] = INT_MIN;
330 predicted_value_[1] =
static_cast<int>(v);
333 predicted_value_[0] =
static_cast<int>(predicted_uv[0]);
334 predicted_value_[1] =
static_cast<int>(predicted_uv[1]);
343 if (prev_data_id < data_id) {
345 data_offset = prev_data_id * num_components_;
347 if (next_data_id < data_id) {
349 data_offset = next_data_id * num_components_;
354 data_offset = (data_id - 1) * num_components_;
357 for (
int i = 0; i < num_components_; ++i) {
358 predicted_value_[i] = 0;
363 for (
int i = 0; i < num_components_; ++i) {
364 predicted_value_[i] =
data[data_offset + i];
void floor(const FCube &pos, FLine &l1, FLine &l2, FLine &l3, FLine &l4, FPlane &pl, FaceStore &s)
Definition Functions.cc:95
Definition decoder_buffer.h:30
Definition mesh_prediction_scheme_decoder.h:28
Definition rans_bit_decoder.h:28
void EndDecoding()
Definition rans_bit_decoder.h:44
#define DRACO_DCHECK_EQ(a, b)
Definition macros.h:81
#define DRACO_BITSTREAM_VERSION(MAJOR, MINOR)
Definition macros.h:114
lazy data
Definition meshpage.php:1583
n< br > font size
Definition meshpage.php:3536
Definition attribute_octahedron_transform.cc:21
bool DecodeVarint(IntTypeT *out_val, DecoderBuffer *buffer)
Definition varint_decoding.h:63
VectorD< float, 3 > Vector3f
Definition vector_d.h:340
VectorD< float, 2 > Vector2f
Definition vector_d.h:339
CornerIndex CornerIndex
Definition mesh_edgebreaker_encoder_impl.cc:35
PredictionSchemeMethod
Definition compression_shared.h:80
@ MESH_PREDICTION_TEX_COORDS_DEPRECATED
Definition compression_shared.h:88