mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 04:24:07 +02:00
glTF importer Demo
Imports a glTF model as the default avatar. Geometry data and materials are imported. No bone information is imported.
This commit is contained in:
parent
304c6451eb
commit
d7c525cf3a
11 changed files with 2082 additions and 14 deletions
BIN
interface/resources/meshes/DamagedHelmet/DamagedHelmet.bin
Normal file
BIN
interface/resources/meshes/DamagedHelmet/DamagedHelmet.bin
Normal file
Binary file not shown.
After Width: | Height: | Size: 539 KiB |
209
interface/resources/meshes/DamagedHelmet/DamagedHelmet.gltf
Normal file
209
interface/resources/meshes/DamagedHelmet/DamagedHelmet.gltf
Normal file
|
@ -0,0 +1,209 @@
|
|||
{
|
||||
"accessors" : [
|
||||
{
|
||||
"bufferView" : 0,
|
||||
"componentType" : 5123,
|
||||
"count" : 46356,
|
||||
"max" : [
|
||||
14358
|
||||
],
|
||||
"min" : [
|
||||
0
|
||||
],
|
||||
"type" : "SCALAR"
|
||||
},
|
||||
{
|
||||
"bufferView" : 1,
|
||||
"componentType" : 5126,
|
||||
"count" : 14359,
|
||||
"max" : [
|
||||
0.9449769854545593,
|
||||
1.0,
|
||||
0.9009739756584167
|
||||
],
|
||||
"min" : [
|
||||
-0.9449769854545593,
|
||||
-1.0,
|
||||
-0.9009950160980225
|
||||
],
|
||||
"type" : "VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView" : 2,
|
||||
"componentType" : 5126,
|
||||
"count" : 14359,
|
||||
"max" : [
|
||||
1.0,
|
||||
1.0,
|
||||
1.0
|
||||
],
|
||||
"min" : [
|
||||
-1.0,
|
||||
-1.0,
|
||||
-1.0
|
||||
],
|
||||
"type" : "VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView" : 3,
|
||||
"componentType" : 5126,
|
||||
"count" : 14359,
|
||||
"max" : [
|
||||
0.9999759793281555,
|
||||
1.998665988445282
|
||||
],
|
||||
"min" : [
|
||||
0.002448640065267682,
|
||||
1.0005531199858524
|
||||
],
|
||||
"type" : "VEC2"
|
||||
}
|
||||
],
|
||||
"asset" : {
|
||||
"generator" : "Khronos Blender glTF 2.0 exporter",
|
||||
"version" : "2.0"
|
||||
},
|
||||
"bufferViews" : [
|
||||
{
|
||||
"buffer" : 0,
|
||||
"byteLength" : 92712,
|
||||
"byteOffset" : 0,
|
||||
"target" : 34963
|
||||
},
|
||||
{
|
||||
"buffer" : 0,
|
||||
"byteLength" : 172308,
|
||||
"byteOffset" : 92712,
|
||||
"target" : 34962
|
||||
},
|
||||
{
|
||||
"buffer" : 0,
|
||||
"byteLength" : 172308,
|
||||
"byteOffset" : 265020,
|
||||
"target" : 34962
|
||||
},
|
||||
{
|
||||
"buffer" : 0,
|
||||
"byteLength" : 114872,
|
||||
"byteOffset" : 437328,
|
||||
"target" : 34962
|
||||
}
|
||||
],
|
||||
"buffers" : [
|
||||
{
|
||||
"byteLength" : 552200,
|
||||
"uri" : "DamagedHelmet.bin"
|
||||
}
|
||||
],
|
||||
"images" : [
|
||||
{
|
||||
"uri" : "Default_albedo.jpg"
|
||||
},
|
||||
{
|
||||
"uri" : "Default_normal.jpg"
|
||||
},
|
||||
{
|
||||
"uri" : "Default_metalRoughness.jpg"
|
||||
},
|
||||
{
|
||||
"uri" : "Default_emissive.jpg"
|
||||
},
|
||||
{
|
||||
"uri" : "Default_AO.jpg"
|
||||
}
|
||||
],
|
||||
"materials" : [
|
||||
{
|
||||
"emissiveFactor" : [
|
||||
1.0,
|
||||
1.0,
|
||||
1.0
|
||||
],
|
||||
"emissiveTexture" : {
|
||||
"index" : 3
|
||||
},
|
||||
"name" : "glTF Material",
|
||||
"normalTexture" : {
|
||||
"index" : 1
|
||||
},
|
||||
"occlusionTexture" : {
|
||||
"index" : 4
|
||||
},
|
||||
"pbrMetallicRoughness" : {
|
||||
"baseColorTexture" : {
|
||||
"index" : 0
|
||||
},
|
||||
"metallicRoughnessTexture" : {
|
||||
"index" : 2
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"meshes" : [
|
||||
{
|
||||
"name" : "mesh_helmet_LP_13930damagedHelmet",
|
||||
"primitives" : [
|
||||
{
|
||||
"attributes" : {
|
||||
"NORMAL" : 2,
|
||||
"POSITION" : 1,
|
||||
"TEXCOORD_0" : 3
|
||||
},
|
||||
"indices" : 0,
|
||||
"material" : 0
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"nodes" : [
|
||||
{
|
||||
"mesh" : 0,
|
||||
"name" : "node_damagedHelmet_-6514",
|
||||
"rotation" : [
|
||||
0.7071068286895752,
|
||||
0.15,
|
||||
-0.25,
|
||||
0.7071068286895752
|
||||
],
|
||||
"scale" : [
|
||||
0.5,
|
||||
0.5,
|
||||
0.5
|
||||
]
|
||||
}
|
||||
],
|
||||
"samplers" : [
|
||||
{}
|
||||
],
|
||||
"scene" : 0,
|
||||
"scenes" : [
|
||||
{
|
||||
"name" : "Scene",
|
||||
"nodes" : [
|
||||
0
|
||||
]
|
||||
}
|
||||
],
|
||||
"textures" : [
|
||||
{
|
||||
"sampler" : 0,
|
||||
"source" : 0
|
||||
},
|
||||
{
|
||||
"sampler" : 0,
|
||||
"source" : 1
|
||||
},
|
||||
{
|
||||
"sampler" : 0,
|
||||
"source" : 2
|
||||
},
|
||||
{
|
||||
"sampler" : 0,
|
||||
"source" : 3
|
||||
},
|
||||
{
|
||||
"sampler" : 0,
|
||||
"source" : 4
|
||||
}
|
||||
]
|
||||
}
|
BIN
interface/resources/meshes/DamagedHelmet/Default_AO.jpg
Normal file
BIN
interface/resources/meshes/DamagedHelmet/Default_AO.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 353 KiB |
BIN
interface/resources/meshes/DamagedHelmet/Default_albedo.jpg
Normal file
BIN
interface/resources/meshes/DamagedHelmet/Default_albedo.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 914 KiB |
BIN
interface/resources/meshes/DamagedHelmet/Default_emissive.jpg
Normal file
BIN
interface/resources/meshes/DamagedHelmet/Default_emissive.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 95 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.2 MiB |
BIN
interface/resources/meshes/DamagedHelmet/Default_normal.jpg
Normal file
BIN
interface/resources/meshes/DamagedHelmet/Default_normal.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 506 KiB |
|
@ -1,7 +1,7 @@
|
|||
name = mannequin
|
||||
name = Avocado
|
||||
type = body+head
|
||||
scale = 1
|
||||
filename = mannequin/mannequin.baked.fbx
|
||||
filename = DamagedHelmet/DamagedHelmet.gltf
|
||||
joint = jointEyeLeft = LeftEye
|
||||
joint = jointRightHand = RightHand
|
||||
joint = jointHead = Head
|
||||
|
|
1264
libraries/fbx/src/GLTFReader.cpp
Normal file
1264
libraries/fbx/src/GLTFReader.cpp
Normal file
File diff suppressed because it is too large
Load diff
582
libraries/fbx/src/GLTFReader.h
Normal file
582
libraries/fbx/src/GLTFReader.h
Normal file
|
@ -0,0 +1,582 @@
|
|||
//
|
||||
// GLTFReader.h
|
||||
// interface/src/renderer
|
||||
//
|
||||
// Created by Luis Cuenca on 8/30/17.
|
||||
// Copyright 2017 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_GLTFReader_h
|
||||
#define hifi_GLTFReader_h
|
||||
|
||||
#include "FBXReader.h"
|
||||
#include <QtNetwork/QNetworkReply>
|
||||
#include "ModelFormatLogging.h"
|
||||
#include <memory.h>
|
||||
|
||||
struct GLTFAsset {
|
||||
QString generator;
|
||||
QString version; //required
|
||||
QString copyright;
|
||||
QMap<QString, bool> defined;
|
||||
void dump() {
|
||||
if (defined["generator"]) qCDebug(modelformat) << "generator: " << generator;
|
||||
if (defined["version"]) qCDebug(modelformat) << "version: " << version;
|
||||
if (defined["copyright"]) qCDebug(modelformat) << "copyright: " << copyright;
|
||||
}
|
||||
};
|
||||
|
||||
struct GLTFNode {
|
||||
QString name;
|
||||
int camera;
|
||||
int mesh;
|
||||
QVector<int> children;
|
||||
QVector<double> translation;
|
||||
QVector<double> rotation;
|
||||
QVector<double> scale;
|
||||
QVector<double> matrix;
|
||||
QVector<glm::mat4> transforms;
|
||||
int skin;
|
||||
QVector<int> skeletons;
|
||||
QString jointName;
|
||||
QMap<QString, bool> defined;
|
||||
void dump() {
|
||||
if (defined["name"]) qCDebug(modelformat) << "name: " << name;
|
||||
if (defined["camera"]) qCDebug(modelformat) << "camera: " << camera;
|
||||
if (defined["mesh"]) qCDebug(modelformat) << "mesh: " << mesh;
|
||||
if (defined["skin"]) qCDebug(modelformat) << "skin: " << skin;
|
||||
if (defined["jointName"]) qCDebug(modelformat) << "jointName: " << jointName;
|
||||
if (defined["children"]) qCDebug(modelformat) << "children: " << children;
|
||||
if (defined["translation"]) qCDebug(modelformat) << "translation: " << translation;
|
||||
if (defined["rotation"]) qCDebug(modelformat) << "rotation: " << rotation;
|
||||
if (defined["scale"]) qCDebug(modelformat) << "scale: " << scale;
|
||||
if (defined["matrix"]) qCDebug(modelformat) << "matrix: " << matrix;
|
||||
if (defined["skeletons"]) qCDebug(modelformat) << "skeletons: " << skeletons;
|
||||
}
|
||||
};
|
||||
|
||||
// Meshes
|
||||
|
||||
struct GLTFMeshPrimitivesTarget {
|
||||
int normal;
|
||||
int position;
|
||||
int tangent;
|
||||
QMap<QString, bool> defined;
|
||||
void dump() {
|
||||
if (defined["normal"]) qCDebug(modelformat) << "normal: " << normal;
|
||||
if (defined["position"]) qCDebug(modelformat) << "position: " << position;
|
||||
if (defined["tangent"]) qCDebug(modelformat) << "tangent: " << tangent;
|
||||
}
|
||||
};
|
||||
|
||||
namespace GLTFMeshPrimitivesRenderingMode {
|
||||
enum Values {
|
||||
POINTS = 0,
|
||||
LINES,
|
||||
LINE_LOOP,
|
||||
LINE_STRIP,
|
||||
TRIANGLES,
|
||||
TRIANGLE_STRIP,
|
||||
TRIANGLE_FAN
|
||||
};
|
||||
}
|
||||
|
||||
struct GLTFMeshPrimitiveAttr {
|
||||
QMap<QString, int> values;
|
||||
QMap<QString, bool> defined;
|
||||
void dump() {
|
||||
QList<QString> keys = values.keys();
|
||||
qCDebug(modelformat) << "values: ";
|
||||
foreach(auto k, keys) qCDebug(modelformat) << k << ": " << values[k];
|
||||
}
|
||||
};
|
||||
|
||||
struct GLTFMeshPrimitive {
|
||||
GLTFMeshPrimitiveAttr attributes;
|
||||
int indices;
|
||||
int material;
|
||||
int mode{ GLTFMeshPrimitivesRenderingMode::TRIANGLES };
|
||||
QVector<GLTFMeshPrimitiveAttr> targets;
|
||||
QMap<QString, bool> defined;
|
||||
void dump() {
|
||||
if (defined["attributes"]) {
|
||||
qCDebug(modelformat) << "attributes: ";
|
||||
attributes.dump();
|
||||
}
|
||||
if (defined["indices"]) qCDebug(modelformat) << "indices: " << indices;
|
||||
if (defined["material"]) qCDebug(modelformat) << "material: " << material;
|
||||
if (defined["mode"]) qCDebug(modelformat) << "mode: " << mode;
|
||||
if (defined["targets"]) {
|
||||
qCDebug(modelformat) << "targets: ";
|
||||
foreach(auto t, targets) t.dump();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct GLTFMesh {
|
||||
QString name;
|
||||
QVector<GLTFMeshPrimitive> primitives;
|
||||
QVector<double> weights;
|
||||
QMap<QString, bool> defined;
|
||||
void dump() {
|
||||
if (defined["name"]) qCDebug(modelformat) << "name: " << name;
|
||||
if (defined["primitives"]) {
|
||||
qCDebug(modelformat) << "primitives: ";
|
||||
foreach(auto prim, primitives) prim.dump();
|
||||
}
|
||||
if (defined["weights"]) qCDebug(modelformat) << "weights: " << weights;
|
||||
}
|
||||
};
|
||||
|
||||
// BufferViews
|
||||
|
||||
namespace GLTFBufferViewTarget {
|
||||
enum Values {
|
||||
ARRAY_BUFFER = 34962,
|
||||
ELEMENT_ARRAY_BUFFER = 34963
|
||||
};
|
||||
}
|
||||
|
||||
struct GLTFBufferView {
|
||||
int buffer; //required
|
||||
int byteLength; //required
|
||||
int byteOffset;
|
||||
int target;
|
||||
QMap<QString, bool> defined;
|
||||
void dump() {
|
||||
if (defined["buffer"]) qCDebug(modelformat) << "buffer: " << buffer;
|
||||
if (defined["byteLength"]) qCDebug(modelformat) << "byteLength: " << byteLength;
|
||||
if (defined["byteOffset"]) qCDebug(modelformat) << "byteOffset: " << byteOffset;
|
||||
if (defined["target"]) qCDebug(modelformat) << "target: " << target;
|
||||
}
|
||||
};
|
||||
|
||||
// Buffers
|
||||
|
||||
struct GLTFBuffer {
|
||||
int byteLength; //required
|
||||
QString uri;
|
||||
QByteArray blob;
|
||||
QMap<QString, bool> defined;
|
||||
void dump() {
|
||||
if (defined["byteLength"]) qCDebug(modelformat) << "byteLength: " << byteLength;
|
||||
if (defined["uri"]) qCDebug(modelformat) << "uri: " << uri;
|
||||
if (defined["blob"]) qCDebug(modelformat) << "blob: " << "DEFINED";
|
||||
}
|
||||
};
|
||||
|
||||
// Samplers
|
||||
namespace GLTFSamplerFilterType {
|
||||
enum Values {
|
||||
NEAREST = 9728,
|
||||
LINEAR = 9729,
|
||||
NEAREST_MIPMAP_NEAREST = 9984,
|
||||
LINEAR_MIPMAP_NEAREST = 9985,
|
||||
NEAREST_MIPMAP_LINEAR = 9986,
|
||||
LINEAR_MIPMAP_LINEAR = 9987
|
||||
};
|
||||
}
|
||||
|
||||
namespace GLTFSamplerWrapType {
|
||||
enum Values {
|
||||
CLAMP_TO_EDGE = 33071,
|
||||
MIRRORED_REPEAT = 33648,
|
||||
REPEAT = 10497
|
||||
};
|
||||
}
|
||||
|
||||
struct GLTFSampler {
|
||||
int magFilter;
|
||||
int minFilter;
|
||||
int wrapS;
|
||||
int wrapT;
|
||||
QMap<QString, bool> defined;
|
||||
void dump() {
|
||||
if (defined["magFilter"]) qCDebug(modelformat) << "magFilter: " << magFilter;
|
||||
if (defined["minFilter"]) qCDebug(modelformat) << "minFilter: " << minFilter;
|
||||
if (defined["wrapS"]) qCDebug(modelformat) << "wrapS: " << wrapS;
|
||||
if (defined["wrapT"]) qCDebug(modelformat) << "wrapT: " << wrapT;
|
||||
}
|
||||
};
|
||||
|
||||
// Cameras
|
||||
|
||||
struct GLTFCameraPerspective {
|
||||
double aspectRatio;
|
||||
double yfov; //required
|
||||
double zfar;
|
||||
double znear; //required
|
||||
QMap<QString, bool> defined;
|
||||
void dump() {
|
||||
if (defined["zfar"]) qCDebug(modelformat) << "zfar: " << zfar;
|
||||
if (defined["znear"]) qCDebug(modelformat) << "znear: " << znear;
|
||||
if (defined["aspectRatio"]) qCDebug(modelformat) << "aspectRatio: " << aspectRatio;
|
||||
if (defined["yfov"]) qCDebug(modelformat) << "yfov: " << yfov;
|
||||
}
|
||||
};
|
||||
|
||||
struct GLTFCameraOrthographic {
|
||||
double zfar; //required
|
||||
double znear; //required
|
||||
double xmag; //required
|
||||
double ymag; //required
|
||||
QMap<QString, bool> defined;
|
||||
void dump() {
|
||||
if (defined["zfar"]) qCDebug(modelformat) << "zfar: " << zfar;
|
||||
if (defined["znear"]) qCDebug(modelformat) << "znear: " << znear;
|
||||
if (defined["xmag"]) qCDebug(modelformat) << "xmag: " << xmag;
|
||||
if (defined["ymag"]) qCDebug(modelformat) << "ymag: " << ymag;
|
||||
}
|
||||
};
|
||||
|
||||
namespace GLTFCameraTypes {
|
||||
enum Values {
|
||||
ORTHOGRAPHIC = 0,
|
||||
PERSPECTIVE
|
||||
};
|
||||
}
|
||||
|
||||
struct GLTFCamera {
|
||||
QString name;
|
||||
GLTFCameraPerspective perspective; //required (or)
|
||||
GLTFCameraOrthographic orthographic; //required (or)
|
||||
int type;
|
||||
QMap<QString, bool> defined;
|
||||
void dump() {
|
||||
if (defined["name"]) qCDebug(modelformat) << "name: " << name;
|
||||
if (defined["type"]) qCDebug(modelformat) << "type: " << type;
|
||||
if (defined["perspective"]) perspective.dump();
|
||||
if (defined["orthographic"]) orthographic.dump();
|
||||
}
|
||||
};
|
||||
|
||||
// Images
|
||||
|
||||
namespace GLTFImageMimetype {
|
||||
enum Values {
|
||||
JPEG = 0,
|
||||
PNG
|
||||
};
|
||||
};
|
||||
|
||||
struct GLTFImage {
|
||||
QString uri; //required (or)
|
||||
int mimeType;
|
||||
int bufferView; //required (or)
|
||||
QMap<QString, bool> defined;
|
||||
void dump() {
|
||||
if (defined["uri"]) qCDebug(modelformat) << "uri: " << uri;
|
||||
if (defined["mimeType"]) qCDebug(modelformat) << "mimeType: " << mimeType;
|
||||
if (defined["bufferView"]) qCDebug(modelformat) << "bufferView: " << bufferView;
|
||||
}
|
||||
};
|
||||
|
||||
// Materials
|
||||
|
||||
struct GLTFpbrMetallicRoughness {
|
||||
QVector<double> baseColorFactor;
|
||||
int baseColorTexture;
|
||||
int metallicRoughnessTexture;
|
||||
double metallicFactor;
|
||||
double roughnessFactor;
|
||||
QMap<QString, bool> defined;
|
||||
void dump() {
|
||||
if (defined["baseColorFactor"]) qCDebug(modelformat) << "baseColorFactor: " << baseColorFactor;
|
||||
if (defined["baseColorTexture"]) qCDebug(modelformat) << "baseColorTexture: " << baseColorTexture;
|
||||
if (defined["metallicRoughnessTexture"]) qCDebug(modelformat) << "metallicRoughnessTexture: " << metallicRoughnessTexture;
|
||||
if (defined["metallicFactor"]) qCDebug(modelformat) << "metallicFactor: " << metallicFactor;
|
||||
if (defined["roughnessFactor"]) qCDebug(modelformat) << "roughnessFactor: " << roughnessFactor;
|
||||
if (defined["baseColorFactor"]) qCDebug(modelformat) << "baseColorFactor: " << baseColorFactor;
|
||||
}
|
||||
};
|
||||
|
||||
namespace GLTFMaterialAlphaMode {
|
||||
enum Values {
|
||||
OPAQUE = 0,
|
||||
MASK,
|
||||
BLEND
|
||||
};
|
||||
};
|
||||
|
||||
struct GLTFMaterial {
|
||||
QString name;
|
||||
QVector<double> emissiveFactor;
|
||||
int emissiveTexture;
|
||||
int normalTexture;
|
||||
int occlusionTexture;
|
||||
int alphaMode;
|
||||
double alphaCutoff;
|
||||
bool doubleSided;
|
||||
GLTFpbrMetallicRoughness pbrMetallicRoughness;
|
||||
QMap<QString, bool> defined;
|
||||
void dump() {
|
||||
if (defined["name"]) qCDebug(modelformat) << "name: " << name;
|
||||
if (defined["emissiveTexture"]) qCDebug(modelformat) << "emissiveTexture: " << emissiveTexture;
|
||||
if (defined["normalTexture"]) qCDebug(modelformat) << "normalTexture: " << normalTexture;
|
||||
if (defined["occlusionTexture"]) qCDebug(modelformat) << "occlusionTexture: " << occlusionTexture;
|
||||
if (defined["emissiveFactor"]) qCDebug(modelformat) << "emissiveFactor: " << emissiveFactor;
|
||||
if (defined["pbrMetallicRoughness"]) pbrMetallicRoughness.dump();
|
||||
}
|
||||
};
|
||||
|
||||
// Accesors
|
||||
|
||||
namespace GLTFAccessorType {
|
||||
enum Values {
|
||||
SCALAR = 0,
|
||||
VEC2,
|
||||
VEC3,
|
||||
VEC4,
|
||||
MAT2,
|
||||
MAT3,
|
||||
MAT4
|
||||
};
|
||||
}
|
||||
namespace GLTFAccessorComponentType {
|
||||
enum Values {
|
||||
BYTE = 5120,
|
||||
UNSIGNED_BYTE = 5121,
|
||||
SHORT = 5122,
|
||||
UNSIGNED_SHORT = 5123,
|
||||
UNSIGNED_INT = 5125,
|
||||
FLOAT = 5126
|
||||
};
|
||||
}
|
||||
struct GLTFAccessor {
|
||||
int bufferView;
|
||||
int byteOffset;
|
||||
int componentType; //required
|
||||
int count; //required
|
||||
int type; //required
|
||||
bool normalized{ false };
|
||||
QVector<double> max;
|
||||
QVector<double> min;
|
||||
QMap<QString, bool> defined;
|
||||
void dump() {
|
||||
if (defined["bufferView"]) qCDebug(modelformat) << "bufferView: " << bufferView;
|
||||
if (defined["byteOffset"]) qCDebug(modelformat) << "byteOffset: " << byteOffset;
|
||||
if (defined["componentType"]) qCDebug(modelformat) << "componentType: " << componentType;
|
||||
if (defined["count"]) qCDebug(modelformat) << "count: " << count;
|
||||
if (defined["type"]) qCDebug(modelformat) << "type: " << type;
|
||||
if (defined["normalized"]) qCDebug(modelformat) << "normalized: " << (normalized ? "TRUE" : "FALSE");
|
||||
if (defined["max"]) {
|
||||
qCDebug(modelformat) << "max: ";
|
||||
foreach(float m, max) qCDebug(modelformat) << m;
|
||||
}
|
||||
if (defined["min"]) {
|
||||
qCDebug(modelformat) << "min: ";
|
||||
foreach(float m, min) qCDebug(modelformat) << m;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Animation
|
||||
|
||||
namespace GLTFChannelTargetPath {
|
||||
enum Values {
|
||||
TRANSLATION = 0,
|
||||
ROTATION,
|
||||
SCALE
|
||||
};
|
||||
}
|
||||
|
||||
struct GLTFChannelTarget {
|
||||
int node;
|
||||
int path;
|
||||
QMap<QString, bool> defined;
|
||||
void dump() {
|
||||
if (defined["node"]) qCDebug(modelformat) << "node: " << node;
|
||||
if (defined["path"]) qCDebug(modelformat) << "path: " << path;
|
||||
}
|
||||
};
|
||||
|
||||
struct GLTFChannel {
|
||||
int sampler;
|
||||
GLTFChannelTarget target;
|
||||
QMap<QString, bool> defined;
|
||||
void dump() {
|
||||
if (defined["sampler"]) qCDebug(modelformat) << "sampler: " << sampler;
|
||||
if (defined["target"]) target.dump();
|
||||
}
|
||||
};
|
||||
|
||||
namespace GLTFAnimationSamplerInterpolation {
|
||||
enum Values{
|
||||
LINEAR = 0
|
||||
};
|
||||
}
|
||||
|
||||
struct GLTFAnimationSampler {
|
||||
int input;
|
||||
int output;
|
||||
int interpolation;
|
||||
QMap<QString, bool> defined;
|
||||
void dump() {
|
||||
if (defined["input"]) qCDebug(modelformat) << "input: " << input;
|
||||
if (defined["output"]) qCDebug(modelformat) << "output: " << output;
|
||||
if (defined["interpolation"]) qCDebug(modelformat) << "interpolation: " << interpolation;
|
||||
}
|
||||
};
|
||||
|
||||
struct GLTFAnimation {
|
||||
QVector<GLTFChannel> channels;
|
||||
QVector<GLTFAnimationSampler> samplers;
|
||||
QMap<QString, bool> defined;
|
||||
void dump() {
|
||||
if (defined["channels"]) foreach(auto channel, channels) channel.dump();
|
||||
if (defined["samplers"]) foreach(auto sampler, samplers) sampler.dump();
|
||||
}
|
||||
};
|
||||
|
||||
struct GLTFScene {
|
||||
QString name;
|
||||
QVector<int> nodes;
|
||||
QMap<QString, bool> defined;
|
||||
void dump() {
|
||||
if (defined["name"]) qCDebug(modelformat) << "name: " << name;
|
||||
if (defined["nodes"]) {
|
||||
qCDebug(modelformat) << "nodes: ";
|
||||
foreach(int node, nodes) qCDebug(modelformat) << node;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct GLTFSkin {
|
||||
int inverseBindMatrices;
|
||||
QVector<int> joints;
|
||||
int skeleton;
|
||||
QMap<QString, bool> defined;
|
||||
void dump() {
|
||||
if (defined["inverseBindMatrices"]) qCDebug(modelformat) << "inverseBindMatrices: " << inverseBindMatrices;
|
||||
if (defined["skeleton"]) qCDebug(modelformat) << "skeleton: " << skeleton;
|
||||
if (defined["joints"]) {
|
||||
qCDebug(modelformat) << "joints: ";
|
||||
foreach(int joint, joints) qCDebug(modelformat) << joint;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct GLTFTexture {
|
||||
int sampler;
|
||||
int source;
|
||||
QMap<QString, bool> defined;
|
||||
void dump() {
|
||||
if (defined["sampler"]) qCDebug(modelformat) << "sampler: " << sampler;
|
||||
if (defined["source"]) qCDebug(modelformat) << "source: " << sampler;
|
||||
}
|
||||
};
|
||||
|
||||
struct GLTFFile {
|
||||
GLTFAsset asset;
|
||||
int scene = 0;
|
||||
QVector<GLTFAccessor> accessors;
|
||||
QVector<GLTFAnimation> animations;
|
||||
QVector<GLTFBufferView> bufferviews;
|
||||
QVector<GLTFBuffer> buffers;
|
||||
QVector<GLTFCamera> cameras;
|
||||
QVector<GLTFImage> images;
|
||||
QVector<GLTFMaterial> materials;
|
||||
QVector<GLTFMesh> meshes;
|
||||
QVector<GLTFNode> nodes;
|
||||
QVector<GLTFSampler> samplers;
|
||||
QVector<GLTFScene> scenes;
|
||||
QVector<GLTFSkin> skins;
|
||||
QVector<GLTFTexture> textures;
|
||||
QMap<QString, bool> defined;
|
||||
void dump() {
|
||||
if (defined["asset"]) asset.dump();
|
||||
if (defined["scene"]) qCDebug(modelformat) << "scene: " << scene;
|
||||
if (defined["accessors"]) foreach(auto acc, accessors) acc.dump();
|
||||
if (defined["animations"]) foreach(auto ani, animations) ani.dump();
|
||||
if (defined["bufferviews"]) foreach(auto bv, bufferviews) bv.dump();
|
||||
if (defined["buffers"]) foreach(auto b, buffers) b.dump();
|
||||
if (defined["cameras"]) foreach(auto c, cameras) c.dump();
|
||||
if (defined["images"]) foreach(auto i, images) i.dump();
|
||||
if (defined["materials"]) foreach(auto mat, materials) mat.dump();
|
||||
if (defined["meshes"]) foreach(auto mes, meshes) mes.dump();
|
||||
if (defined["nodes"]) foreach(auto nod, nodes) nod.dump();
|
||||
if (defined["samplers"]) foreach(auto sa, samplers) sa.dump();
|
||||
if (defined["scenes"]) foreach(auto sc, scenes) sc.dump();
|
||||
if (defined["skins"]) foreach(auto sk, nodes) sk.dump();
|
||||
if (defined["textures"]) foreach(auto tex, textures) tex.dump();
|
||||
}
|
||||
};
|
||||
|
||||
class GLTFReader : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
GLTFReader();
|
||||
FBXGeometry* readGLTF(QByteArray& model, const QVariantHash& mapping, const QUrl& url, bool loadLightmaps = true, float lightmapLevel = 1.0f);
|
||||
private:
|
||||
GLTFFile _file;
|
||||
QUrl _url;
|
||||
|
||||
glm::mat4 getModelTransform(const GLTFNode& node);
|
||||
|
||||
bool buildGeometry(FBXGeometry& geometry, const QUrl& url);
|
||||
bool parseGLTF(const QByteArray& model);
|
||||
|
||||
bool getStringVal(const QJsonObject& object, const QString& fieldname, QString& value, QMap<QString, bool>& defined);
|
||||
bool getBoolVal(const QJsonObject& object, const QString& fieldname, bool& value, QMap<QString, bool>& defined);
|
||||
bool getIntVal(const QJsonObject& object, const QString& fieldname, int& value, QMap<QString, bool>& defined);
|
||||
bool getDoubleVal(const QJsonObject& object, const QString& fieldname, double& value, QMap<QString, bool>& defined);
|
||||
bool getObjectVal(const QJsonObject& object, const QString& fieldname, QJsonObject& value, QMap<QString, bool>& defined);
|
||||
bool getIntArrayVal(const QJsonObject& object, const QString& fieldname, QVector<int>& values, QMap<QString, bool>& defined);
|
||||
bool getDoubleArrayVal(const QJsonObject& object, const QString& fieldname, QVector<double>& values, QMap<QString, bool>& defined);
|
||||
bool getObjectArrayVal(const QJsonObject& object, const QString& fieldname, QJsonArray& objects, QMap<QString, bool>& defined);
|
||||
|
||||
int getMaterialAlphaMode(const QString& type);
|
||||
int getAccessorType(const QString& type);
|
||||
int getAnimationSamplerInterpolation(const QString& interpolation);
|
||||
int getCameraType(const QString& type);
|
||||
int getImageMimeType(const QString& mime);
|
||||
int getMeshPrimitiveRenderingMode(const QString& type);
|
||||
|
||||
bool getIndexFromObject(const QJsonObject& object, const QString& field, int& outidx, QMap<QString, bool>& defined);
|
||||
|
||||
bool setAsset(const QJsonObject& object);
|
||||
bool addAccessor(const QJsonObject& object);
|
||||
bool addAnimation(const QJsonObject& object);
|
||||
bool addBufferView(const QJsonObject& object);
|
||||
bool addBuffer(const QJsonObject& object);
|
||||
bool addCamera(const QJsonObject& object);
|
||||
bool addImage(const QJsonObject& object);
|
||||
bool addMaterial(const QJsonObject& object);
|
||||
bool addMesh(const QJsonObject& object);
|
||||
bool addNode(const QJsonObject& object);
|
||||
bool addSampler(const QJsonObject& object);
|
||||
bool addScene(const QJsonObject& object);
|
||||
bool addSkin(const QJsonObject& object);
|
||||
bool addTexture(const QJsonObject& object);
|
||||
|
||||
bool readBinary(const QString& url, QByteArray& outdata);
|
||||
|
||||
template<typename T, typename L>
|
||||
bool readArray(const QByteArray& bin, int byteOffset, int byteLength, QVector<L>& outarray, int accessorType);
|
||||
|
||||
template<typename T>
|
||||
bool addArrayOfType(const QByteArray& bin, int byteOffset, int byteLength, QVector<T>& outarray, int accessorType, int componentType);
|
||||
|
||||
void retriangulate(const QVector<int>& in_indices, const QVector<glm::vec3>& in_vertices, const QVector<glm::vec3>& in_normals,
|
||||
QVector<int>& out_indices, QVector<glm::vec3>& out_vertices, QVector<glm::vec3>& out_normals);
|
||||
|
||||
std::tuple<bool, QByteArray> GLTFReader::requestData(QUrl& url);
|
||||
QNetworkReply* GLTFReader::request(QUrl& url, bool isTest);
|
||||
bool doesResourceExist(const QString& url);
|
||||
|
||||
|
||||
void setFBXMaterial(FBXMaterial& fbxmat, const GLTFMaterial& material);
|
||||
FBXTexture getFBXTexture(const GLTFTexture& texture);
|
||||
void fbxDebugDump(const FBXGeometry& fbxgeo);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif hifi_GLTFReader_h
|
|
@ -14,6 +14,7 @@
|
|||
#include <FSTReader.h>
|
||||
#include "FBXReader.h"
|
||||
#include "OBJReader.h"
|
||||
#include "GLTFReader.h"
|
||||
|
||||
#include <gpu/Batch.h>
|
||||
#include <gpu/Stream.h>
|
||||
|
@ -173,9 +174,10 @@ void GeometryReader::run() {
|
|||
|
||||
QString urlname = _url.path().toLower();
|
||||
if (!urlname.isEmpty() && !_url.path().isEmpty() &&
|
||||
(_url.path().toLower().endsWith(".fbx") ||
|
||||
_url.path().toLower().endsWith(".obj") ||
|
||||
_url.path().toLower().endsWith(".obj.gz"))) {
|
||||
(_url.path().toLower().endsWith(".fbx") ||
|
||||
_url.path().toLower().endsWith(".obj") ||
|
||||
_url.path().toLower().endsWith(".obj.gz") ||
|
||||
_url.path().toLower().endsWith(".gltf"))) {
|
||||
FBXGeometry::Pointer fbxGeometry;
|
||||
|
||||
if (_url.path().toLower().endsWith(".fbx")) {
|
||||
|
@ -183,17 +185,28 @@ void GeometryReader::run() {
|
|||
if (fbxGeometry->meshes.size() == 0 && fbxGeometry->joints.size() == 0) {
|
||||
throw QString("empty geometry, possibly due to an unsupported FBX version");
|
||||
}
|
||||
} else if (_url.path().toLower().endsWith(".obj")) {
|
||||
}
|
||||
else if (_url.path().toLower().endsWith(".obj")) {
|
||||
fbxGeometry.reset(OBJReader().readOBJ(_data, _mapping, _combineParts, _url));
|
||||
} else if (_url.path().toLower().endsWith(".obj.gz")) {
|
||||
QByteArray uncompressedData;
|
||||
if (gunzip(_data, uncompressedData)){
|
||||
fbxGeometry.reset(OBJReader().readOBJ(uncompressedData, _mapping, _combineParts, _url));
|
||||
} else {
|
||||
throw QString("failed to decompress .obj.gz" );
|
||||
}
|
||||
}
|
||||
else if (_url.path().toLower().endsWith(".obj.gz")) {
|
||||
QByteArray uncompressedData;
|
||||
if (gunzip(_data, uncompressedData)) {
|
||||
fbxGeometry.reset(OBJReader().readOBJ(uncompressedData, _mapping, _combineParts, _url));
|
||||
}
|
||||
else {
|
||||
throw QString("failed to decompress .obj.gz");
|
||||
}
|
||||
|
||||
} else {
|
||||
}
|
||||
else if (_url.path().toLower().endsWith(".gltf")) {
|
||||
std::unique_ptr<GLTFReader> glreader = std::make_unique<GLTFReader>();
|
||||
fbxGeometry.reset(glreader->readGLTF(_data, _mapping, _url));
|
||||
if (fbxGeometry->meshes.size() == 0 && fbxGeometry->joints.size() == 0) {
|
||||
throw QString("empty geometry, possibly due to an unsupported GLTF version");
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw QString("unsupported format");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue