mirror of
https://github.com/lubosz/overte.git
synced 2025-04-23 13:33:38 +02:00
Merge pull request #3902 from samcake/tot
Adding detection of a "hifi" global light in a FBX file used to pass information
This commit is contained in:
commit
0ad361fd60
3 changed files with 195 additions and 23 deletions
|
@ -829,28 +829,44 @@ void GeometryReader::run() {
|
|||
return;
|
||||
}
|
||||
try {
|
||||
std::string urlname = _url.path().toLower().toStdString();
|
||||
FBXGeometry fbxgeo;
|
||||
if (_url.path().toLower().endsWith(".svo")) {
|
||||
fbxgeo = readSVO(_reply->readAll());
|
||||
} else {
|
||||
bool grabLightmaps = true;
|
||||
float lightmapLevel = 1.0f;
|
||||
// HACK: For monday 12/01/2014 we need to kill lighmaps loading in starchamber...
|
||||
if (_url.path().toLower().endsWith("loungev4_11-18.fbx")) {
|
||||
grabLightmaps = false;
|
||||
} else if (_url.path().toLower().endsWith("apt8_reboot.fbx")) {
|
||||
lightmapLevel = 4.0f;
|
||||
} else if (_url.path().toLower().endsWith("palaceoforinthilian4.fbx")) {
|
||||
lightmapLevel = 3.5f;
|
||||
}
|
||||
fbxgeo = readFBX(_reply->readAll(), _mapping, grabLightmaps, lightmapLevel);
|
||||
if (!_reply) {
|
||||
throw QString("Reply is NULL ?!");
|
||||
}
|
||||
QMetaObject::invokeMethod(geometry.data(), "setGeometry", Q_ARG(const FBXGeometry&, fbxgeo));
|
||||
std::string urlname = _url.path().toLower().toStdString();
|
||||
bool urlValid = true;
|
||||
urlValid &= !urlname.empty();
|
||||
urlValid &= !_url.path().isEmpty();
|
||||
urlValid &= _url.path().toLower().endsWith(".fbx")
|
||||
|| _url.path().toLower().endsWith(".svo");
|
||||
|
||||
if (urlValid) {
|
||||
// Let's read the binaries from the network
|
||||
QByteArray fileBinary = _reply->readAll();
|
||||
if (fileBinary.isEmpty() || fileBinary.isNull()) {
|
||||
throw QString("Read File binary is empty?!");
|
||||
}
|
||||
|
||||
FBXGeometry fbxgeo;
|
||||
if (_url.path().toLower().endsWith(".svo")) {
|
||||
fbxgeo = readSVO(fileBinary);
|
||||
} else if (_url.path().toLower().endsWith(".fbx")) {
|
||||
bool grabLightmaps = true;
|
||||
float lightmapLevel = 1.0f;
|
||||
// HACK: For monday 12/01/2014 we need to kill lighmaps loading in starchamber...
|
||||
if (_url.path().toLower().endsWith("loungev4_11-18.fbx")) {
|
||||
grabLightmaps = false;
|
||||
} else if (_url.path().toLower().endsWith("apt8_reboot.fbx")) {
|
||||
lightmapLevel = 4.0f;
|
||||
} else if (_url.path().toLower().endsWith("palaceoforinthilian4.fbx")) {
|
||||
lightmapLevel = 3.5f;
|
||||
}
|
||||
fbxgeo = readFBX(fileBinary, _mapping, grabLightmaps, lightmapLevel);
|
||||
}
|
||||
QMetaObject::invokeMethod(geometry.data(), "setGeometry", Q_ARG(const FBXGeometry&, fbxgeo));
|
||||
} else {
|
||||
throw QString("url is invalid");
|
||||
}
|
||||
|
||||
// _url.path().toLower().endsWith(".svo") ? readSVO(_reply->readAll()) : readFBX(_reply->readAll(), _mapping)));
|
||||
|
||||
} catch (const QString& error) {
|
||||
qDebug() << "Error reading " << _url << ": " << error;
|
||||
QMetaObject::invokeMethod(geometry.data(), "finishedLoading", Q_ARG(bool, false));
|
||||
|
|
|
@ -1046,6 +1046,7 @@ FBXBlendshape extractBlendshape(const FBXNode& object) {
|
|||
return blendshape;
|
||||
}
|
||||
|
||||
|
||||
void setTangents(FBXMesh& mesh, int firstIndex, int secondIndex) {
|
||||
const glm::vec3& normal = mesh.normals.at(firstIndex);
|
||||
glm::vec3 bitangent = glm::cross(normal, mesh.vertices.at(secondIndex) - mesh.vertices.at(firstIndex));
|
||||
|
@ -1194,6 +1195,44 @@ int matchTextureUVSetToAttributeChannel(const std::string& texUVSetName, const Q
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
FBXLight extractLight(const FBXNode& object) {
|
||||
FBXLight light;
|
||||
|
||||
foreach (const FBXNode& subobject, object.children) {
|
||||
std::string childname = QString(subobject.name).toStdString();
|
||||
if (subobject.name == "Properties70") {
|
||||
foreach (const FBXNode& property, subobject.children) {
|
||||
int valIndex = 4;
|
||||
std::string propName = QString(property.name).toStdString();
|
||||
if (property.name == "P") {
|
||||
std::string propname = property.properties.at(0).toString().toStdString();
|
||||
if (propname == "Intensity") {
|
||||
light.intensity = 0.01f * property.properties.at(valIndex).value<double>();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ( subobject.name == "GeometryVersion"
|
||||
|| subobject.name == "TypeFlags") {
|
||||
}
|
||||
}
|
||||
#if defined(DEBUG_FBXREADER)
|
||||
|
||||
std::string type = object.properties.at(0).toString().toStdString();
|
||||
type = object.properties.at(1).toString().toStdString();
|
||||
type = object.properties.at(2).toString().toStdString();
|
||||
|
||||
foreach (const QVariant& prop, object.properties) {
|
||||
std::string proptype = prop.typeName();
|
||||
std::string propval = prop.toString().toStdString();
|
||||
if (proptype == "Properties70") {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return light;
|
||||
}
|
||||
|
||||
FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping, bool loadLightmaps, float lightmapLevel) {
|
||||
QHash<QString, ExtractedMesh> meshes;
|
||||
QHash<QString, QString> modelIDsToNames;
|
||||
|
@ -1222,6 +1261,8 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
|
|||
QHash<QString, QString> yComponents;
|
||||
QHash<QString, QString> zComponents;
|
||||
|
||||
std::map<std::string, FBXLight> lights;
|
||||
|
||||
QVariantHash joints = mapping.value("joint").toHash();
|
||||
QString jointEyeLeftName = processID(getString(joints.value("jointEyeLeft", "jointEyeLeft")));
|
||||
QString jointEyeRightName = processID(getString(joints.value("jointEyeRight", "jointEyeRight")));
|
||||
|
@ -1276,6 +1317,8 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
|
|||
#endif
|
||||
FBXGeometry geometry;
|
||||
float unitScaleFactor = 1.0f;
|
||||
glm::vec3 ambientColor;
|
||||
QString hifiGlobalNodeID;
|
||||
foreach (const FBXNode& child, node.children) {
|
||||
|
||||
if (child.name == "FBXHeaderExtension") {
|
||||
|
@ -1302,10 +1345,16 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
|
|||
} else if (child.name == "GlobalSettings") {
|
||||
foreach (const FBXNode& object, child.children) {
|
||||
if (object.name == "Properties70") {
|
||||
QString propertyName = "P";
|
||||
int index = 4;
|
||||
foreach (const FBXNode& subobject, object.children) {
|
||||
if (subobject.name == "P" && subobject.properties.size() >= 5 &&
|
||||
subobject.properties.at(0) == "UnitScaleFactor") {
|
||||
unitScaleFactor = subobject.properties.at(4).toFloat();
|
||||
if (subobject.name == propertyName) {
|
||||
std::string subpropName = subobject.properties.at(0).toString().toStdString();
|
||||
if (subpropName == "UnitScaleFactor") {
|
||||
unitScaleFactor = subobject.properties.at(index).toFloat();
|
||||
} else if (subpropName == "AmbientColor") {
|
||||
ambientColor = getVec3(subobject.properties, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1324,6 +1373,11 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
|
|||
QString id = getID(object.properties);
|
||||
modelIDsToNames.insert(id, name);
|
||||
|
||||
std::string modelname = name.toLower().toStdString();
|
||||
if (modelname.find("hifi") == 0) {
|
||||
hifiGlobalNodeID = id;
|
||||
}
|
||||
|
||||
if (name == jointEyeLeftName || name == "EyeL" || name == "joint_Leye") {
|
||||
jointEyeLeftID = getID(object.properties);
|
||||
|
||||
|
@ -1354,6 +1408,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
|
|||
} else if (name == "RightToe" || name == "joint_R_toe" || name == "RightToe_End") {
|
||||
jointRightToeID = getID(object.properties);
|
||||
}
|
||||
|
||||
int humanIKJointIndex = humanIKJointNames.indexOf(name);
|
||||
if (humanIKJointIndex != -1) {
|
||||
humanIKJointIDs[humanIKJointIndex] = getID(object.properties);
|
||||
|
@ -1450,6 +1505,25 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
|
|||
extractBlendshape(subobject) };
|
||||
blendshapes.append(blendshape);
|
||||
}
|
||||
#if defined(DEBUG_FBXREADER)
|
||||
else if (subobject.name == "TypeFlags") {
|
||||
std::string attributetype = subobject.properties.at(0).toString().toStdString();
|
||||
if (!attributetype.empty()) {
|
||||
if (attributetype == "Light") {
|
||||
std::string lightprop;
|
||||
foreach (const QVariant& vprop, subobject.properties) {
|
||||
lightprop = vprop.toString().toStdString();
|
||||
}
|
||||
|
||||
FBXLight light = extractLight(object);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
std::string whatisthat = subobject.name;
|
||||
if (whatisthat == "WTF") {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// add the blendshapes included in the model, if any
|
||||
|
@ -1624,11 +1698,28 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
|
|||
materials.insert(material.id, material);
|
||||
|
||||
} else if (object.name == "NodeAttribute") {
|
||||
#if defined(DEBUG_FBXREADER)
|
||||
std::vector<std::string> properties;
|
||||
foreach(const QVariant& v, object.properties) {
|
||||
properties.push_back(v.toString().toStdString());
|
||||
}
|
||||
#endif
|
||||
std::string attribID = getID(object.properties).toStdString();
|
||||
std::string attributetype;
|
||||
foreach (const FBXNode& subobject, object.children) {
|
||||
if (subobject.name == "TypeFlags") {
|
||||
typeFlags.insert(getID(object.properties), subobject.properties.at(0).toString());
|
||||
attributetype = subobject.properties.at(0).toString().toStdString();
|
||||
}
|
||||
}
|
||||
|
||||
if (!attributetype.empty()) {
|
||||
if (attributetype == "Light") {
|
||||
FBXLight light = extractLight(object);
|
||||
lights[attribID] = light;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (object.name == "Deformer") {
|
||||
if (object.properties.last() == "Cluster") {
|
||||
Cluster cluster;
|
||||
|
@ -1666,7 +1757,20 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
|
|||
}
|
||||
}
|
||||
animationCurves.insert(getID(object.properties), curve);
|
||||
|
||||
}
|
||||
#if defined(DEBUG_FBXREADER)
|
||||
else {
|
||||
std::string objectname = object.name.data();
|
||||
if ( objectname == "Pose"
|
||||
|| objectname == "AnimationStack"
|
||||
|| objectname == "AnimationLayer"
|
||||
|| objectname == "AnimationCurveNode") {
|
||||
} else {
|
||||
unknown++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} else if (child.name == "Connections") {
|
||||
foreach (const FBXNode& connection, child.children) {
|
||||
|
@ -1675,6 +1779,15 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
|
|||
QString childID = getID(connection.properties, 1);
|
||||
QString parentID = getID(connection.properties, 2);
|
||||
ooChildToParent.insert(childID, parentID);
|
||||
if (!hifiGlobalNodeID.isEmpty() && (parentID == hifiGlobalNodeID)) {
|
||||
std::map< std::string, FBXLight >::iterator lit = lights.find(childID.toStdString());
|
||||
if (lit != lights.end()) {
|
||||
lightmapLevel = (*lit).second.intensity;
|
||||
if (lightmapLevel <= 0.0f) {
|
||||
loadLightmaps = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (connection.properties.at(0) == "OP") {
|
||||
int counter = 0;
|
||||
|
@ -1718,6 +1831,33 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
|
|||
}
|
||||
}
|
||||
}
|
||||
#if defined(DEBUG_FBXREADER)
|
||||
else {
|
||||
std::string objectname = child.name.data();
|
||||
if ( objectname == "Pose"
|
||||
|| objectname == "CreationTime"
|
||||
|| objectname == "FileId"
|
||||
|| objectname == "Creator"
|
||||
|| objectname == "Documents"
|
||||
|| objectname == "References"
|
||||
|| objectname == "Definitions"
|
||||
|| objectname == "Takes"
|
||||
|| objectname == "AnimationStack"
|
||||
|| objectname == "AnimationLayer"
|
||||
|| objectname == "AnimationCurveNode") {
|
||||
} else {
|
||||
unknown++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// TODO: check if is code is needed
|
||||
if (!lights.empty()) {
|
||||
if (hifiGlobalNodeID.isEmpty()) {
|
||||
std::map< std::string, FBXLight >::iterator l = lights.begin();
|
||||
lightmapLevel = (*l).second.intensity;
|
||||
}
|
||||
}
|
||||
|
||||
// assign the blendshapes to their corresponding meshes
|
||||
|
@ -1956,7 +2096,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping,
|
|||
emissiveParams.y = lightmapLevel;
|
||||
QString emissiveTextureID = emissiveTextures.value(childID);
|
||||
QString ambientTextureID = ambientTextures.value(childID);
|
||||
if (!emissiveTextureID.isNull() || !ambientTextureID.isNull()) {
|
||||
if (loadLightmaps && (!emissiveTextureID.isNull() || !ambientTextureID.isNull())) {
|
||||
|
||||
if (!emissiveTextureID.isNull()) {
|
||||
emissiveTexture = getTexture(emissiveTextureID, textureNames, textureFilenames, textureContent, textureParams);
|
||||
|
|
|
@ -165,6 +165,22 @@ public:
|
|||
QVector<glm::quat> rotations;
|
||||
};
|
||||
|
||||
/// A light in an FBX document.
|
||||
class FBXLight {
|
||||
public:
|
||||
QString name;
|
||||
Transform transform;
|
||||
float intensity;
|
||||
glm::vec3 color;
|
||||
|
||||
FBXLight() :
|
||||
name(),
|
||||
transform(),
|
||||
intensity(1.0f),
|
||||
color(1.0f)
|
||||
{}
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(FBXAnimationFrame)
|
||||
Q_DECLARE_METATYPE(QVector<FBXAnimationFrame>)
|
||||
|
||||
|
|
Loading…
Reference in a new issue