Merge branch 'master' into feat-morph-targets
This commit is contained in:
commit
39cb6bd789
|
@ -22,7 +22,8 @@ const binaries = {
|
||||||
function convert(srcFile, destFile, opts = []) {
|
function convert(srcFile, destFile, opts = []) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
let tool = path.join(__dirname, 'bin', os.type(), 'FBX2glTF');
|
let binExt = os.type() === 'Windows_NT' ? '.exe' : '';
|
||||||
|
let tool = path.join(__dirname, 'bin', os.type(), 'FBX2glTF' + binExt);
|
||||||
if (!fs.existsSync(tool)) {
|
if (!fs.existsSync(tool)) {
|
||||||
throw new Error(`Unsupported OS: ${os.type()}`);
|
throw new Error(`Unsupported OS: ${os.type()}`);
|
||||||
}
|
}
|
||||||
|
@ -63,7 +64,7 @@ function convert(srcFile, destFile, opts = []) {
|
||||||
|
|
||||||
// non-zero exit code is failure
|
// non-zero exit code is failure
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
reject(new Error(`Script ${script} output:\n` +
|
reject(new Error(`Converter output:\n` +
|
||||||
(output.length ? output : "<none>")));
|
(output.length ? output : "<none>")));
|
||||||
} else {
|
} else {
|
||||||
resolve(destPath + destExt);
|
resolve(destPath + destExt);
|
||||||
|
|
|
@ -92,13 +92,13 @@ class FbxMaterialAccess
|
||||||
{
|
{
|
||||||
struct FbxMaterialProperties {
|
struct FbxMaterialProperties {
|
||||||
FbxFileTexture *texAmbient {};
|
FbxFileTexture *texAmbient {};
|
||||||
FbxDouble4 colAmbient {};
|
FbxVector4 colAmbient {};
|
||||||
FbxFileTexture *texSpecular {};
|
FbxFileTexture *texSpecular {};
|
||||||
FbxDouble4 colSpecular {};
|
FbxVector4 colSpecular {};
|
||||||
FbxFileTexture *texDiffuse {};
|
FbxFileTexture *texDiffuse {};
|
||||||
FbxDouble4 colDiffuse {};
|
FbxVector4 colDiffuse {};
|
||||||
FbxFileTexture *texEmissive {};
|
FbxFileTexture *texEmissive {};
|
||||||
FbxDouble4 colEmissive {};
|
FbxVector4 colEmissive {};
|
||||||
FbxFileTexture *texNormal {};
|
FbxFileTexture *texNormal {};
|
||||||
FbxFileTexture *texShininess {};
|
FbxFileTexture *texShininess {};
|
||||||
FbxDouble shininess {};
|
FbxDouble shininess {};
|
||||||
|
@ -129,7 +129,7 @@ public:
|
||||||
// four properties are on the same structure and follow the same rules
|
// four properties are on the same structure and follow the same rules
|
||||||
auto handleBasicProperty = [&](const char *colName, const char *facName) {
|
auto handleBasicProperty = [&](const char *colName, const char *facName) {
|
||||||
FbxFileTexture *colTex, *facTex;
|
FbxFileTexture *colTex, *facTex;
|
||||||
FbxDouble4 vec;
|
FbxVector4 vec;
|
||||||
|
|
||||||
std::tie(vec, colTex, facTex) = getSurfaceValues(colName, facName);
|
std::tie(vec, colTex, facTex) = getSurfaceValues(colName, facName);
|
||||||
if (colTex) {
|
if (colTex) {
|
||||||
|
@ -157,7 +157,7 @@ public:
|
||||||
std::tie(res.shininess, res.texShininess) = getSurfaceScalar(FbxSurfaceMaterial::sShininess);
|
std::tie(res.shininess, res.texShininess) = getSurfaceScalar(FbxSurfaceMaterial::sShininess);
|
||||||
|
|
||||||
// for transparency we just want a constant vector value;
|
// for transparency we just want a constant vector value;
|
||||||
FbxDouble4 transparency;
|
FbxVector4 transparency;
|
||||||
// extract any existing textures only so we can warn that we're throwing them away
|
// extract any existing textures only so we can warn that we're throwing them away
|
||||||
FbxFileTexture *colTex, *facTex;
|
FbxFileTexture *colTex, *facTex;
|
||||||
std::tie(transparency, colTex, facTex) =
|
std::tie(transparency, colTex, facTex) =
|
||||||
|
@ -204,7 +204,7 @@ public:
|
||||||
return std::make_tuple(val, tex);
|
return std::make_tuple(val, tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<FbxDouble4, FbxFileTexture *, FbxFileTexture *> getSurfaceValues(const char *colName, const char *facName) const
|
std::tuple<FbxVector4, FbxFileTexture *, FbxFileTexture *> getSurfaceValues(const char *colName, const char *facName) const
|
||||||
{
|
{
|
||||||
const FbxProperty colProp = fbxMaterial->FindProperty(colName);
|
const FbxProperty colProp = fbxMaterial->FindProperty(colName);
|
||||||
const FbxProperty facProp = fbxMaterial->FindProperty(facName);
|
const FbxProperty facProp = fbxMaterial->FindProperty(facName);
|
||||||
|
@ -227,7 +227,7 @@ public:
|
||||||
factorVal = facProp.Get<FbxDouble>();
|
factorVal = facProp.Get<FbxDouble>();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto val = FbxDouble4(
|
auto val = FbxVector4(
|
||||||
colorVal[0] * factorVal,
|
colorVal[0] * factorVal,
|
||||||
colorVal[1] * factorVal,
|
colorVal[1] * factorVal,
|
||||||
colorVal[2] * factorVal,
|
colorVal[2] * factorVal,
|
||||||
|
@ -627,10 +627,11 @@ static bool TriangleTexturePolarity(const Vec2f &uv0, const Vec2f &uv1, const Ve
|
||||||
}
|
}
|
||||||
|
|
||||||
static RawMaterialType
|
static RawMaterialType
|
||||||
GetMaterialType(const RawModel &raw, const int textures[RAW_TEXTURE_USAGE_MAX], const bool skinned)
|
GetMaterialType(const RawModel &raw, const int textures[RAW_TEXTURE_USAGE_MAX], const bool vertexTransparency, const bool skinned)
|
||||||
{
|
{
|
||||||
if ((raw.GetVertexAttributes() & RAW_VERTEX_ATTRIBUTE_COLOR) != 0) {
|
// if there is vertex transparency, definitely transparent
|
||||||
return skinned ? RAW_MATERIAL_TYPE_SKINNED_VERTEX_COLORED : RAW_MATERIAL_TYPE_VERTEX_COLORED;
|
if (vertexTransparency) {
|
||||||
|
return skinned ? RAW_MATERIAL_TYPE_SKINNED_TRANSPARENT : RAW_MATERIAL_TYPE_TRANSPARENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine material type based on texture occlusion.
|
// Determine material type based on texture occlusion.
|
||||||
|
@ -737,7 +738,7 @@ static void ReadMesh(RawModel &raw, FbxScene *pScene, FbxNode *pNode, const std:
|
||||||
std::fill_n(textures, RAW_TEXTURE_USAGE_MAX, -1);
|
std::fill_n(textures, RAW_TEXTURE_USAGE_MAX, -1);
|
||||||
|
|
||||||
FbxString shadingModel, materialName;
|
FbxString shadingModel, materialName;
|
||||||
FbxDouble4 ambient, specular, diffuse, emissive;
|
FbxVector4 ambient, specular, diffuse, emissive;
|
||||||
FbxDouble shininess;
|
FbxDouble shininess;
|
||||||
|
|
||||||
if (fbxMaterial == nullptr) {
|
if (fbxMaterial == nullptr) {
|
||||||
|
@ -773,15 +774,8 @@ static void ReadMesh(RawModel &raw, FbxScene *pScene, FbxNode *pNode, const std:
|
||||||
maybeAddTexture(matProps.texShininess, RAW_TEXTURE_USAGE_SHININESS);
|
maybeAddTexture(matProps.texShininess, RAW_TEXTURE_USAGE_SHININESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto toVec3 = [](FbxDouble4 vec4) { return Vec3f(vec4[0], vec4[1], vec4[2]); };
|
|
||||||
auto toVec4 = [](FbxDouble4 vec4) { return Vec4f(vec4[0], vec4[1], vec4[2], vec4[3]); };
|
|
||||||
|
|
||||||
const RawMaterialType materialType = GetMaterialType(raw, textures, skinning.IsSkinned());
|
|
||||||
const int rawMaterialIndex = raw.AddMaterial(
|
|
||||||
materialName, shadingModel, materialType, textures,
|
|
||||||
toVec3(ambient), toVec4(diffuse), toVec3(specular), toVec3(emissive), shininess);
|
|
||||||
|
|
||||||
RawVertex rawVertices[3];
|
RawVertex rawVertices[3];
|
||||||
|
bool vertexTransparency = false;
|
||||||
for (int vertexIndex = 0; vertexIndex < 3; vertexIndex++, polygonVertexIndex++) {
|
for (int vertexIndex = 0; vertexIndex < 3; vertexIndex++, polygonVertexIndex++) {
|
||||||
const int controlPointIndex = pMesh->GetPolygonVertex(polygonIndex, vertexIndex);
|
const int controlPointIndex = pMesh->GetPolygonVertex(polygonIndex, vertexIndex);
|
||||||
|
|
||||||
|
@ -824,6 +818,9 @@ static void ReadMesh(RawModel &raw, FbxScene *pScene, FbxNode *pNode, const std:
|
||||||
vertex.jointWeights = skinning.GetVertexWeights(controlPointIndex);
|
vertex.jointWeights = skinning.GetVertexWeights(controlPointIndex);
|
||||||
vertex.polarityUv0 = false;
|
vertex.polarityUv0 = false;
|
||||||
|
|
||||||
|
// flag this triangle as transparent if any of its corner vertices substantially deviates from fully opaque
|
||||||
|
vertexTransparency |= (fabs(fbxColor.mAlpha - 1.0) > 1e-3);
|
||||||
|
|
||||||
rawSurface.bounds.AddPoint(vertex.position);
|
rawSurface.bounds.AddPoint(vertex.position);
|
||||||
|
|
||||||
if (!targetShapes.empty()) {
|
if (!targetShapes.empty()) {
|
||||||
|
@ -896,6 +893,11 @@ static void ReadMesh(RawModel &raw, FbxScene *pScene, FbxNode *pNode, const std:
|
||||||
rawVertexIndices[vertexIndex] = raw.AddVertex(rawVertices[vertexIndex]);
|
rawVertexIndices[vertexIndex] = raw.AddVertex(rawVertices[vertexIndex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const RawMaterialType materialType = GetMaterialType(raw, textures, vertexTransparency, skinning.IsSkinned());
|
||||||
|
const int rawMaterialIndex = raw.AddMaterial(
|
||||||
|
materialName, shadingModel, materialType, textures,
|
||||||
|
toVec3f(ambient), toVec4f(diffuse), toVec3f(specular), toVec3f(emissive), shininess);
|
||||||
|
|
||||||
raw.AddTriangle(rawVertexIndices[0], rawVertexIndices[1], rawVertexIndices[2], rawMaterialIndex, rawSurfaceIndex);
|
raw.AddTriangle(rawVertexIndices[0], rawVertexIndices[1], rawVertexIndices[2], rawMaterialIndex, rawSurfaceIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1000,11 +1002,11 @@ static void ReadNodeHierarchy(
|
||||||
fmt::printf("node %d: %s\n", nodeIndex, newPath.c_str());
|
fmt::printf("node %d: %s\n", nodeIndex, newPath.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
static int warnRSrsCount = 0;
|
static int warnRrSsCount = 0;
|
||||||
static int warnRrsCount = 0;
|
static int warnRrsCount = 0;
|
||||||
if (lInheritType == FbxTransform::eInheritRSrs) {
|
if (lInheritType == FbxTransform::eInheritRrSs && !parentName.empty()) {
|
||||||
if (++warnRSrsCount == 1) {
|
if (++warnRrSsCount == 1) {
|
||||||
fmt::printf("Warning: node %s uses unsupported transform inheritance type 'eInheritRSrs'.\n", newPath);
|
fmt::printf("Warning: node %s uses unsupported transform inheritance type 'eInheritRrSs'.\n", newPath);
|
||||||
fmt::printf(" (Further warnings of this type squelched.)\n");
|
fmt::printf(" (Further warnings of this type squelched.)\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -320,7 +320,7 @@ ModelData *Raw2Gltf(
|
||||||
const RawAnimation &animation = raw.GetAnimation(i);
|
const RawAnimation &animation = raw.GetAnimation(i);
|
||||||
|
|
||||||
if (animation.channels.size() == 0) {
|
if (animation.channels.size() == 0) {
|
||||||
fmt::printf("Warning: animation '%s has zero channels. Skipping.\n", animation.name.c_str());
|
fmt::printf("Warning: animation '%s' has zero channels. Skipping.\n", animation.name.c_str());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,8 +413,6 @@ ModelData *Raw2Gltf(
|
||||||
for (int materialIndex = 0; materialIndex < raw.GetMaterialCount(); materialIndex++) {
|
for (int materialIndex = 0; materialIndex < raw.GetMaterialCount(); materialIndex++) {
|
||||||
const RawMaterial &material = raw.GetMaterial(materialIndex);
|
const RawMaterial &material = raw.GetMaterial(materialIndex);
|
||||||
const bool isTransparent =
|
const bool isTransparent =
|
||||||
material.type == RAW_MATERIAL_TYPE_VERTEX_COLORED ||
|
|
||||||
material.type == RAW_MATERIAL_TYPE_SKINNED_VERTEX_COLORED ||
|
|
||||||
material.type == RAW_MATERIAL_TYPE_TRANSPARENT ||
|
material.type == RAW_MATERIAL_TYPE_TRANSPARENT ||
|
||||||
material.type == RAW_MATERIAL_TYPE_SKINNED_TRANSPARENT;
|
material.type == RAW_MATERIAL_TYPE_SKINNED_TRANSPARENT;
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <cmath>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#if defined( __unix__ )
|
#if defined( __unix__ )
|
||||||
|
@ -21,11 +22,6 @@
|
||||||
#include "utils/Image_Utils.h"
|
#include "utils/Image_Utils.h"
|
||||||
#include "RawModel.h"
|
#include "RawModel.h"
|
||||||
|
|
||||||
static float Log2f(float f)
|
|
||||||
{
|
|
||||||
return logf(f) * 1.442695041f;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RawVertex::operator==(const RawVertex &other) const
|
bool RawVertex::operator==(const RawVertex &other) const
|
||||||
{
|
{
|
||||||
return (position == other.position) &&
|
return (position == other.position) &&
|
||||||
|
@ -103,7 +99,7 @@ int RawModel::AddTexture(const std::string &name, const std::string &fileName, c
|
||||||
texture.name = name;
|
texture.name = name;
|
||||||
texture.width = properties.width;
|
texture.width = properties.width;
|
||||||
texture.height = properties.height;
|
texture.height = properties.height;
|
||||||
texture.mipLevels = (int) ceilf(Log2f(std::max((float) properties.width, (float) properties.height)));
|
texture.mipLevels = (int) ceilf(log2f(std::max((float) properties.width, (float) properties.height)));
|
||||||
texture.usage = usage;
|
texture.usage = usage;
|
||||||
texture.occlusion = (properties.occlusion == IMAGE_TRANSPARENT) ?
|
texture.occlusion = (properties.occlusion == IMAGE_TRANSPARENT) ?
|
||||||
RAW_TEXTURE_OCCLUSION_TRANSPARENT : RAW_TEXTURE_OCCLUSION_OPAQUE;
|
RAW_TEXTURE_OCCLUSION_TRANSPARENT : RAW_TEXTURE_OCCLUSION_OPAQUE;
|
||||||
|
@ -198,7 +194,6 @@ int RawModel::AddSurface(const char *name, const char *nodeName)
|
||||||
surface.nodeName = nodeName;
|
surface.nodeName = nodeName;
|
||||||
surface.bounds.Clear();
|
surface.bounds.Clear();
|
||||||
surface.discrete = false;
|
surface.discrete = false;
|
||||||
surface.skinRigid = false;
|
|
||||||
|
|
||||||
surfaces.emplace_back(surface);
|
surfaces.emplace_back(surface);
|
||||||
return (int) (surfaces.size() - 1);
|
return (int) (surfaces.size() - 1);
|
||||||
|
|
|
@ -155,10 +155,8 @@ enum RawMaterialType
|
||||||
{
|
{
|
||||||
RAW_MATERIAL_TYPE_OPAQUE,
|
RAW_MATERIAL_TYPE_OPAQUE,
|
||||||
RAW_MATERIAL_TYPE_TRANSPARENT,
|
RAW_MATERIAL_TYPE_TRANSPARENT,
|
||||||
RAW_MATERIAL_TYPE_VERTEX_COLORED,
|
|
||||||
RAW_MATERIAL_TYPE_SKINNED_OPAQUE,
|
RAW_MATERIAL_TYPE_SKINNED_OPAQUE,
|
||||||
RAW_MATERIAL_TYPE_SKINNED_TRANSPARENT,
|
RAW_MATERIAL_TYPE_SKINNED_TRANSPARENT,
|
||||||
RAW_MATERIAL_TYPE_SKINNED_VERTEX_COLORED
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RawMaterial
|
struct RawMaterial
|
||||||
|
|
10
src/mathfu.h
10
src/mathfu.h
|
@ -33,7 +33,7 @@ struct Bounds
|
||||||
initialized = false;
|
initialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddPoint(mathfu::Vector<T, d> p) {
|
void AddPoint(const mathfu::Vector<T, d> &p) {
|
||||||
if (initialized) {
|
if (initialized) {
|
||||||
for (int ii = 0; ii < d; ii ++) {
|
for (int ii = 0; ii < d; ii ++) {
|
||||||
min(ii) = std::min(min(ii), p(ii));
|
min(ii) = std::min(min(ii), p(ii));
|
||||||
|
@ -58,7 +58,7 @@ typedef mathfu::Matrix<float, 4> Mat4f;
|
||||||
typedef mathfu::Quaternion<float> Quatf;
|
typedef mathfu::Quaternion<float> Quatf;
|
||||||
typedef Bounds<float, 3> Boundsf;
|
typedef Bounds<float, 3> Boundsf;
|
||||||
|
|
||||||
template<class T, int d> static inline std::vector<T> toStdVec(mathfu::Vector <T, d> vec)
|
template<class T, int d> static inline std::vector<T> toStdVec(const mathfu::Vector <T, d> &vec)
|
||||||
{
|
{
|
||||||
std::vector<T> result(d);
|
std::vector<T> result(d);
|
||||||
for (int ii = 0; ii < d; ii ++) {
|
for (int ii = 0; ii < d; ii ++) {
|
||||||
|
@ -67,7 +67,7 @@ template<class T, int d> static inline std::vector<T> toStdVec(mathfu::Vector <T
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> std::vector<T> toStdVec(mathfu::Quaternion<T> quat) {
|
template<class T> std::vector<T> toStdVec(const mathfu::Quaternion<T> &quat) {
|
||||||
return std::vector<T> { quat.vector()[0], quat.vector()[1], quat.vector()[2], quat.scalar() };
|
return std::vector<T> { quat.vector()[0], quat.vector()[1], quat.vector()[2], quat.scalar() };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +75,10 @@ static inline Vec3f toVec3f(const FbxVector4 &v) {
|
||||||
return Vec3f((float) v[0], (float) v[1], (float) v[2]);
|
return Vec3f((float) v[0], (float) v[1], (float) v[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline Vec4f toVec4f(const FbxVector4 &v) {
|
||||||
|
return Vec4f((float) v[0], (float) v[1], (float) v[2], (float) v[3]);
|
||||||
|
}
|
||||||
|
|
||||||
static inline Mat4f toMat4f(const FbxAMatrix &m) {
|
static inline Mat4f toMat4f(const FbxAMatrix &m) {
|
||||||
auto result = Mat4f();
|
auto result = Mat4f();
|
||||||
for (int row = 0; row < 4; row ++) {
|
for (int row = 0; row < 4; row ++) {
|
||||||
|
|
Loading…
Reference in New Issue