FBX2glTF/src/Raw2Gltf.h

218 lines
7.2 KiB
C++

/**
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#ifndef __RAW2GLTF_H__
#define __RAW2GLTF_H__
#include <memory>
#include <string>
// This can be a macro under Windows, confusing Draco
#undef ERROR
#include <draco/compression/encode.h>
#include <json.hpp>
#include <fifo_map.hpp>
template<class K, class V, class ignore, class A>
using workaround_fifo_map = nlohmann::fifo_map<K, V, nlohmann::fifo_map_compare<K>, A>;
using json = nlohmann::basic_json<workaround_fifo_map>;
#include "FBX2glTF.h"
#include "RawModel.h"
static const std::string KHR_DRACO_MESH_COMPRESSION = "KHR_draco_mesh_compression";
static const std::string KHR_MATERIALS_COMMON = "KHR_materials_common";
static const std::string KHR_MATERIALS_CMN_CONSTANT = "KHR_materials_cmnConstant";
static const std::string KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS = "KHR_materials_pbrSpecularGlossiness";
static const std::string extBufferFilename = "buffer.bin";
/**
* User-supplied options that dictate the nature of the glTF being generated.
*/
struct GltfOptions
{
/**
* If negative, disabled. Otherwise, a bitfield of RawVertexAttributes that
* specify the largest set of attributes that'll ever be kept for a vertex.
* The special bit RAW_VERTEX_ATTRIBUTE_AUTO triggers smart mode, where the
* attributes to keep are inferred from which textures are supplied.
*/
int keepAttribs;
/** Whether to output a .glb file, the binary format of glTF. */
bool outputBinary;
/** If non-binary, whether to inline all resources, for a single (large) .glTF file. */
bool embedResources;
/** Whether to use KHR_draco_mesh_compression to minimize static geometry size. */
bool useDraco;
/** Whether to use KHR_materials_common to extend materials definitions. */
bool useKHRMatCom;
/** Whether to use KHR_materials_cmnConstant to extend materials definitions. */
bool useKHRMatCmnConstant;
/** Whether to populate the pbrMetallicRoughness substruct in materials. */
bool usePBRMetRough;
/** Whether to use KHR_materials_pbrSpecularGlossiness to extend material definitions. */
bool usePBRSpecGloss;
/** Whether to include blend shape normals, if present according to the SDK. */
bool useBlendShapeNormals;
/** Whether to include blend shape tangents, if present according to the SDK. */
bool useBlendShapeTangents;
};
struct ComponentType {
// OpenGL Datatype enums
enum GL_DataType
{
GL_BYTE = 5120,
GL_UNSIGNED_BYTE,
GL_SHORT,
GL_UNSIGNED_SHORT,
GL_INT,
GL_UNSIGNED_INT,
GL_FLOAT
};
const GL_DataType glType;
const unsigned int size;
};
static const ComponentType CT_USHORT = {ComponentType::GL_UNSIGNED_SHORT, 2};
static const ComponentType CT_FLOAT = {ComponentType::GL_FLOAT, 4};
// Map our low-level data types for glTF output
struct GLType {
GLType(const ComponentType &componentType, unsigned int count, const std::string dataType)
: componentType(componentType),
count(count),
dataType(dataType)
{}
unsigned int byteStride() const { return componentType.size * count; }
void write(uint8_t *buf, const float scalar) const { *((float *) buf) = scalar; }
void write(uint8_t *buf, const uint16_t scalar) const { *((uint16_t *) buf) = scalar; }
template<class T, int d>
void write(uint8_t *buf, const mathfu::Vector<T, d> &vector) const {
for (int ii = 0; ii < d; ii ++) {
((T *)buf)[ii] = vector(ii);
}
}
template<class T, int d>
void write(uint8_t *buf, const mathfu::Matrix<T, d> &matrix) const {
// three matrix types require special alignment considerations that we don't handle
// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#data-alignment
assert(!(sizeof(T) == 1 && d == 2));
assert(!(sizeof(T) == 1 && d == 3));
assert(!(sizeof(T) == 2 && d == 2));
for (int col = 0; col < d; col ++) {
for (int row = 0; row < d; row ++) {
// glTF matrices are column-major
((T *)buf)[col * d + row] = matrix(row, col);
}
}
}
template<class T>
void write(uint8_t *buf, const mathfu::Quaternion<T> &quaternion) const {
for (int ii = 0; ii < 3; ii++) {
((T *)buf)[ii] = quaternion.vector()(ii);
}
((T *)buf)[3] = quaternion.scalar();
}
const ComponentType componentType;
const uint8_t count;
const std::string dataType;
};
static const GLType GLT_FLOAT = {CT_FLOAT, 1, "SCALAR"};
static const GLType GLT_USHORT = {CT_USHORT, 1, "SCALAR"};
static const GLType GLT_VEC2F = {CT_FLOAT, 2, "VEC2"};
static const GLType GLT_VEC3F = {CT_FLOAT, 3, "VEC3"};
static const GLType GLT_VEC4F = {CT_FLOAT, 4, "VEC4"};
static const GLType GLT_VEC4I = {CT_USHORT, 4, "VEC4"};
static const GLType GLT_MAT2F = {CT_USHORT, 4, "MAT2"};
static const GLType GLT_MAT3F = {CT_USHORT, 9, "MAT3"};
static const GLType GLT_MAT4F = {CT_FLOAT, 16, "MAT4"};
static const GLType GLT_QUATF = {CT_FLOAT, 4, "VEC4"};
/**
* The base of any indexed glTF entity.
*/
struct Holdable
{
uint32_t ix;
virtual json serialize() const = 0;
};
template<class T>
struct AttributeDefinition
{
const std::string gltfName;
const T RawVertex::* rawAttributeIx;
const GLType glType;
const draco::GeometryAttribute::Type dracoAttribute;
const draco::DataType dracoComponentType;
AttributeDefinition(
const std::string gltfName, const T RawVertex::*rawAttributeIx, const GLType &_glType,
const draco::GeometryAttribute::Type dracoAttribute, const draco::DataType dracoComponentType)
: gltfName(gltfName),
rawAttributeIx(rawAttributeIx),
glType(_glType),
dracoAttribute(dracoAttribute),
dracoComponentType(dracoComponentType) {}
AttributeDefinition(
const std::string gltfName, const T RawVertex::*rawAttributeIx, const GLType &_glType)
: gltfName(gltfName),
rawAttributeIx(rawAttributeIx),
glType(_glType),
dracoAttribute(draco::GeometryAttribute::INVALID),
dracoComponentType(draco::DataType::DT_INVALID) {}
};
struct AccessorData;
struct AnimationData;
struct BufferData;
struct BufferViewData;
struct CameraData;
struct GLTFData;
struct ImageData;
struct MaterialData;
struct MeshData;
struct NodeData;
struct PrimitiveData;
struct SamplerData;
struct SceneData;
struct SkinData;
struct TextureData;
struct ModelData
{
explicit ModelData(std::shared_ptr<const std::vector<uint8_t> > const &_binary)
: binary(_binary)
{
}
std::shared_ptr<const std::vector<uint8_t> > const binary;
};
ModelData *Raw2Gltf(
std::ofstream &gltfOutStream,
const std::string &outputFolder,
const RawModel &raw,
const GltfOptions &options
);
#endif // !__RAW2GLTF_H__