GameApi 28
Library used by GameApi Builder tool
Loading...
Searching...
No Matches
mesh_edgebreaker_traversal_predictive_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#ifdef DRACO_BACKWARDS_COMPATIBILITY_SUPPORTED
16#ifndef DRACO_COMPRESSION_MESH_MESH_EDGEBREAKER_TRAVERSAL_PREDICTIVE_DECODER_H_
17#define DRACO_COMPRESSION_MESH_MESH_EDGEBREAKER_TRAVERSAL_PREDICTIVE_DECODER_H_
18
21
22namespace draco {
23
24// Decoder for traversal encoded with the
25// MeshEdgebreakerTraversalPredictiveEncoder. The decoder maintains valences
26// of the decoded portion of the traversed mesh and it uses them to predict
27// symbols that are about to be decoded.
28class MeshEdgebreakerTraversalPredictiveDecoder
30 public:
31 MeshEdgebreakerTraversalPredictiveDecoder()
32 : corner_table_(nullptr),
33 num_vertices_(0),
34 last_symbol_(-1),
35 predicted_symbol_(-1) {}
36 void Init(MeshEdgebreakerDecoderImplInterface *decoder) {
37 MeshEdgebreakerTraversalDecoder::Init(decoder);
38 corner_table_ = decoder->GetCornerTable();
39 }
40 void SetNumEncodedVertices(int num_vertices) { num_vertices_ = num_vertices; }
41
42 bool Start(DecoderBuffer *out_buffer) {
43 if (!MeshEdgebreakerTraversalDecoder::Start(out_buffer)) {
44 return false;
45 }
46 int32_t num_split_symbols;
47 if (!out_buffer->Decode(&num_split_symbols) || num_split_symbols < 0)
48 return false;
49 if (num_split_symbols >= num_vertices_) {
50 return false;
51 }
52 // Set the valences of all initial vertices to 0.
53 vertex_valences_.resize(num_vertices_, 0);
54 if (!prediction_decoder_.StartDecoding(out_buffer)) {
55 return false;
56 }
57 return true;
58 }
59
60 inline uint32_t DecodeSymbol() {
61 // First check if we have a predicted symbol.
62 if (predicted_symbol_ != -1) {
63 // Double check that the predicted symbol was predicted correctly.
64 if (prediction_decoder_.DecodeNextBit()) {
65 last_symbol_ = predicted_symbol_;
66 return predicted_symbol_;
67 }
68 }
69 // We don't have a predicted symbol or the symbol was mis-predicted.
70 // Decode it directly.
71 last_symbol_ = MeshEdgebreakerTraversalDecoder::DecodeSymbol();
72 return last_symbol_;
73 }
74
75 inline void NewActiveCornerReached(CornerIndex corner) {
76 const CornerIndex next = corner_table_->Next(corner);
77 const CornerIndex prev = corner_table_->Previous(corner);
78 // Update valences.
79 switch (last_symbol_) {
80 case TOPOLOGY_C:
81 case TOPOLOGY_S:
82 vertex_valences_[corner_table_->Vertex(next).value()] += 1;
83 vertex_valences_[corner_table_->Vertex(prev).value()] += 1;
84 break;
85 case TOPOLOGY_R:
86 vertex_valences_[corner_table_->Vertex(corner).value()] += 1;
87 vertex_valences_[corner_table_->Vertex(next).value()] += 1;
88 vertex_valences_[corner_table_->Vertex(prev).value()] += 2;
89 break;
90 case TOPOLOGY_L:
91 vertex_valences_[corner_table_->Vertex(corner).value()] += 1;
92 vertex_valences_[corner_table_->Vertex(next).value()] += 2;
93 vertex_valences_[corner_table_->Vertex(prev).value()] += 1;
94 break;
95 case TOPOLOGY_E:
96 vertex_valences_[corner_table_->Vertex(corner).value()] += 2;
97 vertex_valences_[corner_table_->Vertex(next).value()] += 2;
98 vertex_valences_[corner_table_->Vertex(prev).value()] += 2;
99 break;
100 default:
101 break;
102 }
103 // Compute the new predicted symbol.
104 if (last_symbol_ == TOPOLOGY_C || last_symbol_ == TOPOLOGY_R) {
105 const VertexIndex pivot =
106 corner_table_->Vertex(corner_table_->Next(corner));
107 if (vertex_valences_[pivot.value()] < 6) {
108 predicted_symbol_ = TOPOLOGY_R;
109 } else {
110 predicted_symbol_ = TOPOLOGY_C;
111 }
112 } else {
113 predicted_symbol_ = -1;
114 }
115 }
116
117 inline void MergeVertices(VertexIndex dest, VertexIndex source) {
118 // Update valences on the merged vertices.
119 vertex_valences_[dest.value()] += vertex_valences_[source.value()];
120 }
121
122 private:
123 const CornerTable *corner_table_;
124 int num_vertices_;
125 std::vector<int> vertex_valences_;
126 BinaryDecoder prediction_decoder_;
127 int last_symbol_;
128 int predicted_symbol_;
129};
130
131} // namespace draco
132
133#endif // DRACO_COMPRESSION_MESH_MESH_EDGEBREAKER_TRAVERSAL_PREDICTIVE_DECODER_H_
134#endif
Definition mesh_edgebreaker_traversal_decoder.h:30
Definition attribute_octahedron_transform.cc:21
VertexIndex VertexIndex
Definition mesh_edgebreaker_encoder_impl.cc:37
RAnsBitDecoder BinaryDecoder
Definition mesh_edgebreaker_traversal_decoder.h:26
CornerIndex CornerIndex
Definition mesh_edgebreaker_encoder_impl.cc:35
@ TOPOLOGY_R
Definition mesh_edgebreaker_shared.h:57
@ TOPOLOGY_S
Definition mesh_edgebreaker_shared.h:55
@ TOPOLOGY_L
Definition mesh_edgebreaker_shared.h:56
@ TOPOLOGY_E
Definition mesh_edgebreaker_shared.h:58
@ TOPOLOGY_C
Definition mesh_edgebreaker_shared.h:54