142 lines
5.8 KiB
C++
142 lines
5.8 KiB
C++
// Copyright 2019 The Draco Authors.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
//
|
|
#ifndef DRACO_COMPRESSION_DRACO_COMPRESSION_OPTIONS_H_
|
|
#define DRACO_COMPRESSION_DRACO_COMPRESSION_OPTIONS_H_
|
|
|
|
#include "draco/draco_features.h"
|
|
|
|
#ifdef DRACO_TRANSCODER_SUPPORTED
|
|
#include "draco/core/status.h"
|
|
|
|
namespace draco {
|
|
|
|
// Quantization options for positions. Currently there are two modes for
|
|
// quantizing positions:
|
|
//
|
|
// 1. Quantization bits:
|
|
// - User defined number of quantization bits that is evenly distributed
|
|
// to cover the compressed geometry.
|
|
// 2. Grid:
|
|
// - Positions are snapped to a global grid defined by grid spacing.
|
|
// - This method is primarily intended to be used when the location of
|
|
// quantized vertices needs to be consistent between multiple
|
|
// geometries.
|
|
class SpatialQuantizationOptions {
|
|
public:
|
|
explicit SpatialQuantizationOptions(int quantization_bits);
|
|
|
|
// Sets quantization bits that are going to be used for the compressed
|
|
// geometry. If the geometry is a scene, the same number of quantization bits
|
|
// is going to be applied to each mesh of the scene. Quantized values are
|
|
// going to be distributed within the bounds of individual meshes.
|
|
void SetQuantizationBits(int quantization_bits);
|
|
|
|
// If this returns true, quantization_bits() should be used to get the
|
|
// desired number of quantization bits for compression. Otherwise the grid
|
|
// mode is selected and spacing() should be used to get the desired grid
|
|
// spacing.
|
|
bool AreQuantizationBitsDefined() const;
|
|
const int quantization_bits() const { return quantization_bits_; }
|
|
|
|
// Defines quantization grid used for the compressed geometry. All vertices
|
|
// are going to be snapped to the nearest grid vertex that corresponds to an
|
|
// integer quantized position. |spacing| defines the distance between two grid
|
|
// vertices. E.g. a grid with |spacing| = 10 would have grid vertices at
|
|
// locations {10 * i, 10 * j, 10 * k} where i, j, k are integer numbers.
|
|
SpatialQuantizationOptions &SetGrid(float spacing);
|
|
|
|
const float spacing() const { return spacing_; }
|
|
|
|
bool operator==(const SpatialQuantizationOptions &other) const;
|
|
|
|
private:
|
|
enum Mode { LOCAL_QUANTIZATION_BITS, GLOBAL_GRID };
|
|
Mode mode_ = LOCAL_QUANTIZATION_BITS;
|
|
int quantization_bits_; // Default quantization bits for positions.
|
|
float spacing_ = 0.f;
|
|
};
|
|
|
|
// TODO(fgalligan): Add support for unified_position_quantization.
|
|
// Struct to hold Draco compression options.
|
|
struct DracoCompressionOptions {
|
|
int compression_level = 7; // compression level [0-10], most=10, least=0.
|
|
SpatialQuantizationOptions quantization_position{11};
|
|
int quantization_bits_normal = 8;
|
|
int quantization_bits_tex_coord = 10;
|
|
int quantization_bits_color = 8;
|
|
int quantization_bits_generic = 8;
|
|
int quantization_bits_tangent = 8;
|
|
int quantization_bits_weight = 8;
|
|
bool find_non_degenerate_texture_quantization = false;
|
|
|
|
bool operator==(const DracoCompressionOptions &other) const {
|
|
return compression_level == other.compression_level &&
|
|
quantization_position == other.quantization_position &&
|
|
quantization_bits_normal == other.quantization_bits_normal &&
|
|
quantization_bits_tex_coord == other.quantization_bits_tex_coord &&
|
|
quantization_bits_color == other.quantization_bits_color &&
|
|
quantization_bits_generic == other.quantization_bits_generic &&
|
|
quantization_bits_tangent == other.quantization_bits_tangent &&
|
|
quantization_bits_weight == other.quantization_bits_weight &&
|
|
find_non_degenerate_texture_quantization ==
|
|
other.find_non_degenerate_texture_quantization;
|
|
}
|
|
|
|
bool operator!=(const DracoCompressionOptions &other) const {
|
|
return !(*this == other);
|
|
}
|
|
|
|
Status Check() const {
|
|
DRACO_RETURN_IF_ERROR(
|
|
Validate("Compression level", compression_level, 0, 10));
|
|
if (quantization_position.AreQuantizationBitsDefined()) {
|
|
DRACO_RETURN_IF_ERROR(Validate("Position quantization",
|
|
quantization_position.quantization_bits(),
|
|
0, 30));
|
|
} else {
|
|
if (quantization_position.spacing() <= 0.f) {
|
|
return ErrorStatus("Position quantization spacing is invalid.");
|
|
}
|
|
}
|
|
DRACO_RETURN_IF_ERROR(
|
|
Validate("Normals quantization", quantization_bits_normal, 0, 30));
|
|
DRACO_RETURN_IF_ERROR(
|
|
Validate("Tex coord quantization", quantization_bits_tex_coord, 0, 30));
|
|
DRACO_RETURN_IF_ERROR(
|
|
Validate("Color quantization", quantization_bits_color, 0, 30));
|
|
DRACO_RETURN_IF_ERROR(
|
|
Validate("Generic quantization", quantization_bits_generic, 0, 30));
|
|
DRACO_RETURN_IF_ERROR(
|
|
Validate("Tangent quantization", quantization_bits_tangent, 0, 30));
|
|
DRACO_RETURN_IF_ERROR(
|
|
Validate("Weights quantization", quantization_bits_weight, 0, 30));
|
|
return OkStatus();
|
|
}
|
|
|
|
static Status Validate(const std::string &name, int value, int min, int max) {
|
|
if (value < min || value > max) {
|
|
const std::string range =
|
|
"[" + std::to_string(min) + "-" + std::to_string(max) + "].";
|
|
return Status(Status::DRACO_ERROR, name + " is out of range " + range);
|
|
}
|
|
return OkStatus();
|
|
}
|
|
};
|
|
|
|
} // namespace draco
|
|
|
|
#endif // DRACO_TRANSCODER_SUPPORTED
|
|
#endif // DRACO_COMPRESSION_DRACO_COMPRESSION_OPTIONS_H_
|