GameApi 28
Library used by GameApi Builder tool
Loading...
Searching...
No Matches
mesh_prediction_scheme_constrained_multi_parallelogram_decoder.h
Go to the documentation of this file.
1// Copyright 2016 The Draco Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15#ifndef DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_CONSTRAINED_MULTI_PARALLELOGRAM_DECODER_H_
16#define DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_CONSTRAINED_MULTI_PARALLELOGRAM_DECODER_H_
17
18#include <algorithm>
19#include <cmath>
20
28
29namespace draco {
30
31// Decoder for predictions encoded with the constrained multi-parallelogram
32// encoder. See the corresponding encoder for more details about the prediction
33// method.
34template <typename DataTypeT, class TransformT, class MeshDataT>
36 : public MeshPredictionSchemeDecoder<DataTypeT, TransformT, MeshDataT> {
37 public:
38 using CorrType =
40 using CornerTable = typename MeshDataT::CornerTable;
41
44 : MeshPredictionSchemeDecoder<DataTypeT, TransformT, MeshDataT>(
45 attribute),
46 selected_mode_(Mode::OPTIMAL_MULTI_PARALLELOGRAM) {}
48 const PointAttribute *attribute, const TransformT &transform,
49 const MeshDataT &mesh_data)
50 : MeshPredictionSchemeDecoder<DataTypeT, TransformT, MeshDataT>(
52 selected_mode_(Mode::OPTIMAL_MULTI_PARALLELOGRAM) {}
53
54 bool ComputeOriginalValues(const CorrType *in_corr, DataTypeT *out_data,
55 int size, int num_components,
56 const PointIndex *entry_to_point_id_map) override;
57
58 bool DecodePredictionData(DecoderBuffer *buffer) override;
59
63
64 bool IsInitialized() const override {
65 return this->mesh_data().IsInitialized();
66 }
67
68 private:
70 static constexpr int kMaxNumParallelograms =
71 constrained_multi_parallelogram::kMaxNumParallelograms;
72 // Crease edges are used to store whether any given edge should be used for
73 // parallelogram prediction or not. New values are added in the order in which
74 // the edges are processed. For better compression, the flags are stored in
75 // in separate contexts based on the number of available parallelograms at a
76 // given vertex.
77 std::vector<bool> is_crease_edge_[kMaxNumParallelograms];
78 Mode selected_mode_;
79};
80
81template <typename DataTypeT, class TransformT, class MeshDataT>
82bool MeshPredictionSchemeConstrainedMultiParallelogramDecoder<
83 DataTypeT, TransformT, MeshDataT>::
84 ComputeOriginalValues(const CorrType *in_corr, DataTypeT *out_data,
85 int /* size */, int num_components,
86 const PointIndex * /* entry_to_point_id_map */) {
87 this->transform().Init(num_components);
88
89 // Predicted values for all simple parallelograms encountered at any given
90 // vertex.
91 std::vector<DataTypeT> pred_vals[kMaxNumParallelograms];
92 for (int i = 0; i < kMaxNumParallelograms; ++i) {
93 pred_vals[i].resize(num_components, 0);
94 }
95 this->transform().ComputeOriginalValue(pred_vals[0].data(), in_corr,
96 out_data);
97
98 const CornerTable *const table = this->mesh_data().corner_table();
99 const std::vector<int32_t> *const vertex_to_data_map =
100 this->mesh_data().vertex_to_data_map();
101
102 // Current position in the |is_crease_edge_| array for each context.
103 std::vector<int> is_crease_edge_pos(kMaxNumParallelograms, 0);
104
105 // Used to store predicted value for multi-parallelogram prediction.
106 std::vector<DataTypeT> multi_pred_vals(num_components);
107
108 const int corner_map_size =
109 static_cast<int>(this->mesh_data().data_to_corner_map()->size());
110 for (int p = 1; p < corner_map_size; ++p) {
111 const CornerIndex start_corner_id =
112 this->mesh_data().data_to_corner_map()->at(p);
113
114 CornerIndex corner_id(start_corner_id);
115 int num_parallelograms = 0;
116 bool first_pass = true;
117 while (corner_id != kInvalidCornerIndex) {
119 p, corner_id, table, *vertex_to_data_map, out_data,
120 num_components, &(pred_vals[num_parallelograms][0]))) {
121 // Parallelogram prediction applied and stored in
122 // |pred_vals[num_parallelograms]|
123 ++num_parallelograms;
124 // Stop processing when we reach the maximum number of allowed
125 // parallelograms.
126 if (num_parallelograms == kMaxNumParallelograms) {
127 break;
128 }
129 }
130
131 // Proceed to the next corner attached to the vertex. First swing left
132 // and if we reach a boundary, swing right from the start corner.
133 if (first_pass) {
134 corner_id = table->SwingLeft(corner_id);
135 } else {
136 corner_id = table->SwingRight(corner_id);
137 }
138 if (corner_id == start_corner_id) {
139 break;
140 }
141 if (corner_id == kInvalidCornerIndex && first_pass) {
142 first_pass = false;
143 corner_id = table->SwingRight(start_corner_id);
144 }
145 }
146
147 // Check which of the available parallelograms are actually used and compute
148 // the final predicted value.
149 int num_used_parallelograms = 0;
150 if (num_parallelograms > 0) {
151 for (int i = 0; i < num_components; ++i) {
152 multi_pred_vals[i] = 0;
153 }
154 // Check which parallelograms are actually used.
155 for (int i = 0; i < num_parallelograms; ++i) {
156 const int context = num_parallelograms - 1;
157 const int pos = is_crease_edge_pos[context]++;
158 if (is_crease_edge_[context].size() <= pos) {
159 return false;
160 }
161 const bool is_crease = is_crease_edge_[context][pos];
162 if (!is_crease) {
163 ++num_used_parallelograms;
164 for (int j = 0; j < num_components; ++j) {
165 multi_pred_vals[j] =
166 AddAsUnsigned(multi_pred_vals[j], pred_vals[i][j]);
167 }
168 }
169 }
170 }
171 const int dst_offset = p * num_components;
172 if (num_used_parallelograms == 0) {
173 // No parallelogram was valid.
174 // We use the last decoded point as a reference.
175 const int src_offset = (p - 1) * num_components;
176 this->transform().ComputeOriginalValue(
177 out_data + src_offset, in_corr + dst_offset, out_data + dst_offset);
178 } else {
179 // Compute the correction from the predicted value.
180 for (int c = 0; c < num_components; ++c) {
181 multi_pred_vals[c] /= num_used_parallelograms;
182 }
183 this->transform().ComputeOriginalValue(
184 multi_pred_vals.data(), in_corr + dst_offset, out_data + dst_offset);
185 }
186 }
187 return true;
188}
189
190template <typename DataTypeT, class TransformT, class MeshDataT>
192 DataTypeT, TransformT, MeshDataT>::DecodePredictionData(DecoderBuffer
193 *buffer) {
194#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
195 if (buffer->bitstream_version() < DRACO_BITSTREAM_VERSION(2, 2)) {
196 // Decode prediction mode.
197 uint8_t mode;
198 if (!buffer->Decode(&mode)) {
199 return false;
200 }
201
202 if (mode != Mode::OPTIMAL_MULTI_PARALLELOGRAM) {
203 // Unsupported mode.
204 return false;
205 }
206 }
207#endif
208
209 // Encode selected edges using separate rans bit coder for each context.
210 for (int i = 0; i < kMaxNumParallelograms; ++i) {
211 uint32_t num_flags;
212 if (!DecodeVarint<uint32_t>(&num_flags, buffer)) {
213 return false;
214 }
215 if (num_flags > this->mesh_data().corner_table()->num_corners()) {
216 return false;
217 }
218 if (num_flags > 0) {
219 is_crease_edge_[i].resize(num_flags);
220 RAnsBitDecoder decoder;
221 if (!decoder.StartDecoding(buffer)) {
222 return false;
223 }
224 for (uint32_t j = 0; j < num_flags; ++j) {
225 is_crease_edge_[i][j] = decoder.DecodeNextBit();
226 }
227 decoder.EndDecoding();
228 }
229 }
230 return MeshPredictionSchemeDecoder<DataTypeT, TransformT,
231 MeshDataT>::DecodePredictionData(buffer);
232}
233
234} // namespace draco
235
236#endif // DRACO_COMPRESSION_ATTRIBUTES_PREDICTION_SCHEMES_MESH_PREDICTION_SCHEME_CONSTRAINED_MULTI_PARALLELOGRAM_DECODER_H_
Definition decoder_buffer.h:30
uint16_t bitstream_version() const
Definition decoder_buffer.h:120
bool Decode(T *out_val)
Definition decoder_buffer.h:68
Definition mesh_prediction_scheme_constrained_multi_parallelogram_decoder.h:36
PredictionSchemeMethod GetPredictionMethod() const override
Definition mesh_prediction_scheme_constrained_multi_parallelogram_decoder.h:60
bool IsInitialized() const override
Definition mesh_prediction_scheme_constrained_multi_parallelogram_decoder.h:64
typename PredictionSchemeDecoder< DataTypeT, TransformT >::CorrType CorrType
Definition mesh_prediction_scheme_constrained_multi_parallelogram_decoder.h:38
bool DecodePredictionData(DecoderBuffer *buffer) override
Definition mesh_prediction_scheme_constrained_multi_parallelogram_decoder.h:192
bool ComputeOriginalValues(const CorrType *in_corr, DataTypeT *out_data, int size, int num_components, const PointIndex *entry_to_point_id_map) override
Definition mesh_prediction_scheme_constrained_multi_parallelogram_decoder.h:84
MeshPredictionSchemeConstrainedMultiParallelogramDecoder(const PointAttribute *attribute)
Definition mesh_prediction_scheme_constrained_multi_parallelogram_decoder.h:42
typename MeshDataT::CornerTable CornerTable
Definition mesh_prediction_scheme_constrained_multi_parallelogram_decoder.h:40
MeshPredictionSchemeConstrainedMultiParallelogramDecoder(const PointAttribute *attribute, const TransformT &transform, const MeshDataT &mesh_data)
Definition mesh_prediction_scheme_constrained_multi_parallelogram_decoder.h:47
const MeshData & mesh_data() const
Definition mesh_prediction_scheme_decoder.h:38
MeshPredictionSchemeDecoder(const PointAttribute *attribute, const TransformT &transform, const MeshDataT &mesh_data)
Definition mesh_prediction_scheme_decoder.h:31
Definition point_attribute.h:33
Transform::CorrType CorrType
Definition prediction_scheme_decoder.h:41
const Transform & transform() const
Definition prediction_scheme_decoder.h:80
const PointAttribute * attribute() const
Definition prediction_scheme_decoder.h:79
Definition rans_bit_decoder.h:28
bool StartDecoding(DecoderBuffer *source_buffer)
Definition rans_bit_decoder.cc:29
void EndDecoding()
Definition rans_bit_decoder.h:44
bool DecodeNextBit()
Definition rans_bit_decoder.cc:65
#define DRACO_BITSTREAM_VERSION(MAJOR, MINOR)
Definition macros.h:114
lazy data
Definition meshpage.php:1583
n< br > font size
Definition meshpage.php:3536
Mode
Definition mesh_prediction_scheme_constrained_multi_parallelogram_shared.h:23
Definition attribute_octahedron_transform.cc:21
bool ComputeParallelogramPrediction(int data_entry_id, const CornerIndex ci, const CornerTableT *table, const std::vector< int32_t > &vertex_to_data_map, const DataTypeT *in_data, int num_components, DataTypeT *out_prediction)
Definition mesh_prediction_scheme_parallelogram_shared.h:45
bool DecodeVarint(IntTypeT *out_val, DecoderBuffer *buffer)
Definition varint_decoding.h:63
CornerIndex CornerIndex
Definition mesh_edgebreaker_encoder_impl.cc:35
PredictionSchemeMethod
Definition compression_shared.h:80
@ MESH_PREDICTION_CONSTRAINED_MULTI_PARALLELOGRAM
Definition compression_shared.h:89
DataTypeT AddAsUnsigned(DataTypeT a, DataTypeT b)
Definition math_utils.h:63
Definition GameApi_pl.cc:29382