Convert remaining HFMModels called model to hfmModel, and rename some missed local variables

This commit is contained in:
sabrina-shanman 2018-11-05 12:07:17 -08:00
parent cbca77b12f
commit 30eb360f62
20 changed files with 188 additions and 188 deletions

View file

@ -109,10 +109,10 @@ bool ModelPackager::loadModel() {
qCDebug(interfaceapp) << "Reading FBX file : " << _fbxInfo.filePath(); qCDebug(interfaceapp) << "Reading FBX file : " << _fbxInfo.filePath();
QByteArray fbxContents = fbx.readAll(); QByteArray fbxContents = fbx.readAll();
_model.reset(readFBX(fbxContents, QVariantHash(), _fbxInfo.filePath())); _hfmModel.reset(readFBX(fbxContents, QVariantHash(), _fbxInfo.filePath()));
// make sure we have some basic mappings // make sure we have some basic mappings
populateBasicMapping(_mapping, _fbxInfo.filePath(), *_model); populateBasicMapping(_mapping, _fbxInfo.filePath(), *_hfmModel);
} catch (const QString& error) { } catch (const QString& error) {
qCDebug(interfaceapp) << "Error reading " << _fbxInfo.filePath() << ": " << error; qCDebug(interfaceapp) << "Error reading " << _fbxInfo.filePath() << ": " << error;
return false; return false;
@ -122,7 +122,7 @@ bool ModelPackager::loadModel() {
bool ModelPackager::editProperties() { bool ModelPackager::editProperties() {
// open the dialog to configure the rest // open the dialog to configure the rest
ModelPropertiesDialog properties(_modelType, _mapping, _modelFile.path(), *_model); ModelPropertiesDialog properties(_modelType, _mapping, _modelFile.path(), *_hfmModel);
if (properties.exec() == QDialog::Rejected) { if (properties.exec() == QDialog::Rejected) {
return false; return false;
} }
@ -235,18 +235,18 @@ bool ModelPackager::zipModel() {
return true; return true;
} }
void ModelPackager::populateBasicMapping(QVariantHash& mapping, QString filename, const HFMModel& model) { void ModelPackager::populateBasicMapping(QVariantHash& mapping, QString filename, const HFMModel& hfmModel) {
bool isBodyType = _modelType == FSTReader::BODY_ONLY_MODEL || _modelType == FSTReader::HEAD_AND_BODY_MODEL; bool isBodyType = _modelType == FSTReader::BODY_ONLY_MODEL || _modelType == FSTReader::HEAD_AND_BODY_MODEL;
// mixamo files - in the event that a mixamo file was edited by some other tool, it's likely the applicationName will // mixamo files - in the event that a mixamo file was edited by some other tool, it's likely the applicationName will
// be rewritten, so we detect the existence of several different blendshapes which indicate we're likely a mixamo file // be rewritten, so we detect the existence of several different blendshapes which indicate we're likely a mixamo file
bool likelyMixamoFile = model.applicationName == "mixamo.com" || bool likelyMixamoFile = hfmModel.applicationName == "mixamo.com" ||
(model.blendshapeChannelNames.contains("BrowsDown_Right") && (hfmModel.blendshapeChannelNames.contains("BrowsDown_Right") &&
model.blendshapeChannelNames.contains("MouthOpen") && hfmModel.blendshapeChannelNames.contains("MouthOpen") &&
model.blendshapeChannelNames.contains("Blink_Left") && hfmModel.blendshapeChannelNames.contains("Blink_Left") &&
model.blendshapeChannelNames.contains("Blink_Right") && hfmModel.blendshapeChannelNames.contains("Blink_Right") &&
model.blendshapeChannelNames.contains("Squint_Right")); hfmModel.blendshapeChannelNames.contains("Squint_Right"));
if (!mapping.contains(NAME_FIELD)) { if (!mapping.contains(NAME_FIELD)) {
mapping.insert(NAME_FIELD, QFileInfo(filename).baseName()); mapping.insert(NAME_FIELD, QFileInfo(filename).baseName());
@ -268,15 +268,15 @@ void ModelPackager::populateBasicMapping(QVariantHash& mapping, QString filename
} }
QVariantHash joints = mapping.value(JOINT_FIELD).toHash(); QVariantHash joints = mapping.value(JOINT_FIELD).toHash();
if (!joints.contains("jointEyeLeft")) { if (!joints.contains("jointEyeLeft")) {
joints.insert("jointEyeLeft", model.jointIndices.contains("jointEyeLeft") ? "jointEyeLeft" : joints.insert("jointEyeLeft", hfmModel.jointIndices.contains("jointEyeLeft") ? "jointEyeLeft" :
(model.jointIndices.contains("EyeLeft") ? "EyeLeft" : "LeftEye")); (hfmModel.jointIndices.contains("EyeLeft") ? "EyeLeft" : "LeftEye"));
} }
if (!joints.contains("jointEyeRight")) { if (!joints.contains("jointEyeRight")) {
joints.insert("jointEyeRight", model.jointIndices.contains("jointEyeRight") ? "jointEyeRight" : joints.insert("jointEyeRight", hfmModel.jointIndices.contains("jointEyeRight") ? "jointEyeRight" :
model.jointIndices.contains("EyeRight") ? "EyeRight" : "RightEye"); hfmModel.jointIndices.contains("EyeRight") ? "EyeRight" : "RightEye");
} }
if (!joints.contains("jointNeck")) { if (!joints.contains("jointNeck")) {
joints.insert("jointNeck", model.jointIndices.contains("jointNeck") ? "jointNeck" : "Neck"); joints.insert("jointNeck", hfmModel.jointIndices.contains("jointNeck") ? "jointNeck" : "Neck");
} }
if (isBodyType) { if (isBodyType) {
@ -296,7 +296,7 @@ void ModelPackager::populateBasicMapping(QVariantHash& mapping, QString filename
if (!joints.contains("jointHead")) { if (!joints.contains("jointHead")) {
const char* topName = likelyMixamoFile ? "HeadTop_End" : "HeadEnd"; const char* topName = likelyMixamoFile ? "HeadTop_End" : "HeadEnd";
joints.insert("jointHead", model.jointIndices.contains(topName) ? topName : "Head"); joints.insert("jointHead", hfmModel.jointIndices.contains(topName) ? topName : "Head");
} }
mapping.insert(JOINT_FIELD, joints); mapping.insert(JOINT_FIELD, joints);
@ -370,7 +370,7 @@ void ModelPackager::populateBasicMapping(QVariantHash& mapping, QString filename
void ModelPackager::listTextures() { void ModelPackager::listTextures() {
_textures.clear(); _textures.clear();
foreach (const HFMMaterial mat, _model->materials) { foreach (const HFMMaterial mat, _hfmModel->materials) {
if (!mat.albedoTexture.filename.isEmpty() && mat.albedoTexture.content.isEmpty() && if (!mat.albedoTexture.filename.isEmpty() && mat.albedoTexture.content.isEmpty() &&
!_textures.contains(mat.albedoTexture.filename)) { !_textures.contains(mat.albedoTexture.filename)) {
_textures << mat.albedoTexture.filename; _textures << mat.albedoTexture.filename;

View file

@ -32,7 +32,7 @@ private:
bool editProperties(); bool editProperties();
bool zipModel(); bool zipModel();
void populateBasicMapping(QVariantHash& mapping, QString filename, const HFMModel& model); void populateBasicMapping(QVariantHash& mapping, QString filename, const HFMModel& hfmModel);
void listTextures(); void listTextures();
bool copyTextures(const QString& oldDir, const QDir& newDir); bool copyTextures(const QString& oldDir, const QDir& newDir);
@ -44,7 +44,7 @@ private:
QString _scriptDir; QString _scriptDir;
QVariantHash _mapping; QVariantHash _mapping;
std::unique_ptr<HFMModel> _model; std::unique_ptr<HFMModel> _hfmModel;
QStringList _textures; QStringList _textures;
QStringList _scripts; QStringList _scripts;
}; };

View file

@ -27,11 +27,11 @@
ModelPropertiesDialog::ModelPropertiesDialog(FSTReader::ModelType modelType, const QVariantHash& originalMapping, ModelPropertiesDialog::ModelPropertiesDialog(FSTReader::ModelType modelType, const QVariantHash& originalMapping,
const QString& basePath, const HFMModel& model) : const QString& basePath, const HFMModel& hfmModel) :
_modelType(modelType), _modelType(modelType),
_originalMapping(originalMapping), _originalMapping(originalMapping),
_basePath(basePath), _basePath(basePath),
_model(model) _hfmModel(hfmModel)
{ {
setWindowTitle("Set Model Properties"); setWindowTitle("Set Model Properties");
@ -108,8 +108,8 @@ QVariantHash ModelPropertiesDialog::getMapping() const {
// update the joint indices // update the joint indices
QVariantHash jointIndices; QVariantHash jointIndices;
for (int i = 0; i < _model.joints.size(); i++) { for (int i = 0; i < _hfmModel.joints.size(); i++) {
jointIndices.insert(_model.joints.at(i).name, QString::number(i)); jointIndices.insert(_hfmModel.joints.at(i).name, QString::number(i));
} }
mapping.insert(JOINT_INDEX_FIELD, jointIndices); mapping.insert(JOINT_INDEX_FIELD, jointIndices);
@ -118,10 +118,10 @@ QVariantHash ModelPropertiesDialog::getMapping() const {
if (_modelType == FSTReader::ATTACHMENT_MODEL) { if (_modelType == FSTReader::ATTACHMENT_MODEL) {
glm::vec3 pivot; glm::vec3 pivot;
if (_pivotAboutCenter->isChecked()) { if (_pivotAboutCenter->isChecked()) {
pivot = (_model.meshExtents.minimum + _model.meshExtents.maximum) * 0.5f; pivot = (_hfmModel.meshExtents.minimum + _hfmModel.meshExtents.maximum) * 0.5f;
} else if (_pivotJoint->currentIndex() != 0) { } else if (_pivotJoint->currentIndex() != 0) {
pivot = extractTranslation(_model.joints.at(_pivotJoint->currentIndex() - 1).transform); pivot = extractTranslation(_hfmModel.joints.at(_pivotJoint->currentIndex() - 1).transform);
} }
mapping.insert(TRANSLATION_X_FIELD, -pivot.x * (float)_scale->value() + (float)_translationX->value()); mapping.insert(TRANSLATION_X_FIELD, -pivot.x * (float)_scale->value() + (float)_translationX->value());
mapping.insert(TRANSLATION_Y_FIELD, -pivot.y * (float)_scale->value() + (float)_translationY->value()); mapping.insert(TRANSLATION_Y_FIELD, -pivot.y * (float)_scale->value() + (float)_translationY->value());
@ -191,7 +191,7 @@ void ModelPropertiesDialog::reset() {
} }
foreach (const QVariant& joint, _originalMapping.values(FREE_JOINT_FIELD)) { foreach (const QVariant& joint, _originalMapping.values(FREE_JOINT_FIELD)) {
QString jointName = joint.toString(); QString jointName = joint.toString();
if (_model.jointIndices.contains(jointName)) { if (_hfmModel.jointIndices.contains(jointName)) {
createNewFreeJoint(jointName); createNewFreeJoint(jointName);
} }
} }
@ -249,8 +249,8 @@ QComboBox* ModelPropertiesDialog::createJointBox(bool withNone) const {
if (withNone) { if (withNone) {
box->addItem("(none)"); box->addItem("(none)");
} }
foreach (const HFMJoint& joint, _model.joints) { foreach (const HFMJoint& joint, _hfmModel.joints) {
if (joint.isSkeletonJoint || !_model.hasSkeletonJoints) { if (joint.isSkeletonJoint || !_hfmModel.hasSkeletonJoints) {
box->addItem(joint.name); box->addItem(joint.name);
} }
} }
@ -266,7 +266,7 @@ QDoubleSpinBox* ModelPropertiesDialog::createTranslationBox() const {
} }
void ModelPropertiesDialog::insertJointMapping(QVariantHash& joints, const QString& joint, const QString& name) const { void ModelPropertiesDialog::insertJointMapping(QVariantHash& joints, const QString& joint, const QString& name) const {
if (_model.jointIndices.contains(name)) { if (_hfmModel.jointIndices.contains(name)) {
joints.insert(joint, name); joints.insert(joint, name);
} else { } else {
joints.remove(joint); joints.remove(joint);

View file

@ -30,7 +30,7 @@ class ModelPropertiesDialog : public QDialog {
public: public:
ModelPropertiesDialog(FSTReader::ModelType modelType, const QVariantHash& originalMapping, ModelPropertiesDialog(FSTReader::ModelType modelType, const QVariantHash& originalMapping,
const QString& basePath, const HFMModel& model); const QString& basePath, const HFMModel& hfmModel);
QVariantHash getMapping() const; QVariantHash getMapping() const;
@ -50,7 +50,7 @@ private:
FSTReader::ModelType _modelType; FSTReader::ModelType _modelType;
QVariantHash _originalMapping; QVariantHash _originalMapping;
QString _basePath; QString _basePath;
HFMModel _model; HFMModel _hfmModel;
QLineEdit* _name = nullptr; QLineEdit* _name = nullptr;
QPushButton* _textureDirectory = nullptr; QPushButton* _textureDirectory = nullptr;
QPushButton* _scriptDirectory = nullptr; QPushButton* _scriptDirectory = nullptr;

View file

@ -101,8 +101,8 @@ void AnimClip::copyFromNetworkAnim() {
// build a mapping from animation joint indices to skeleton joint indices. // build a mapping from animation joint indices to skeleton joint indices.
// by matching joints with the same name. // by matching joints with the same name.
const HFMModel& model = _networkAnim->getHFMModel(); const HFMModel& hfmModel = _networkAnim->getHFMModel();
AnimSkeleton animSkeleton(model); AnimSkeleton animSkeleton(hfmModel);
const auto animJointCount = animSkeleton.getNumJoints(); const auto animJointCount = animSkeleton.getNumJoints();
const auto skeletonJointCount = _skeleton->getNumJoints(); const auto skeletonJointCount = _skeleton->getNumJoints();
std::vector<int> jointMap; std::vector<int> jointMap;
@ -115,12 +115,12 @@ void AnimClip::copyFromNetworkAnim() {
jointMap.push_back(skeletonJoint); jointMap.push_back(skeletonJoint);
} }
const int frameCount = model.animationFrames.size(); const int frameCount = hfmModel.animationFrames.size();
_anim.resize(frameCount); _anim.resize(frameCount);
for (int frame = 0; frame < frameCount; frame++) { for (int frame = 0; frame < frameCount; frame++) {
const HFMAnimationFrame& hfmAnimFrame = model.animationFrames[frame]; const HFMAnimationFrame& hfmAnimFrame = hfmModel.animationFrames[frame];
// init all joints in animation to default pose // init all joints in animation to default pose
// this will give us a resonable result for bones in the model skeleton but not in the animation. // this will give us a resonable result for bones in the model skeleton but not in the animation.
@ -150,7 +150,7 @@ void AnimClip::copyFromNetworkAnim() {
// adjust translation offsets, so large translation animatons on the reference skeleton // adjust translation offsets, so large translation animatons on the reference skeleton
// will be adjusted when played on a skeleton with short limbs. // will be adjusted when played on a skeleton with short limbs.
const glm::vec3& hfmZeroTrans = model.animationFrames[0].translations[animJoint]; const glm::vec3& hfmZeroTrans = hfmModel.animationFrames[0].translations[animJoint];
const AnimPose& relDefaultPose = _skeleton->getRelativeDefaultPose(skeletonJoint); const AnimPose& relDefaultPose = _skeleton->getRelativeDefaultPose(skeletonJoint);
float boneLengthScale = 1.0f; float boneLengthScale = 1.0f;
const float EPSILON = 0.0001f; const float EPSILON = 0.0001f;

View file

@ -16,11 +16,11 @@
#include "AnimationLogging.h" #include "AnimationLogging.h"
AnimSkeleton::AnimSkeleton(const HFMModel& model) { AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel) {
// convert to std::vector of joints // convert to std::vector of joints
std::vector<HFMJoint> joints; std::vector<HFMJoint> joints;
joints.reserve(model.joints.size()); joints.reserve(hfmModel.joints.size());
for (auto& joint : model.joints) { for (auto& joint : hfmModel.joints) {
joints.push_back(joint); joints.push_back(joint);
} }
buildSkeletonFromJoints(joints); buildSkeletonFromJoints(joints);

View file

@ -23,7 +23,7 @@ public:
using Pointer = std::shared_ptr<AnimSkeleton>; using Pointer = std::shared_ptr<AnimSkeleton>;
using ConstPointer = std::shared_ptr<const AnimSkeleton>; using ConstPointer = std::shared_ptr<const AnimSkeleton>;
explicit AnimSkeleton(const HFMModel& model); explicit AnimSkeleton(const HFMModel& hfmModel);
explicit AnimSkeleton(const std::vector<HFMJoint>& joints); explicit AnimSkeleton(const std::vector<HFMJoint>& joints);
int nameToJointIndex(const QString& jointName) const; int nameToJointIndex(const QString& jointName) const;
const QString& getJointName(int jointIndex) const; const QString& getJointName(int jointIndex) const;

View file

@ -330,15 +330,15 @@ void SkeletonModel::computeBoundingShape() {
return; return;
} }
const HFMModel& model = getHFMModel(); const HFMModel& hfmModel = getHFMModel();
if (model.joints.isEmpty() || model.rootJointIndex == -1) { if (hfmModel.joints.isEmpty() || hfmModel.rootJointIndex == -1) {
// rootJointIndex == -1 if the avatar model has no skeleton // rootJointIndex == -1 if the avatar model has no skeleton
return; return;
} }
float radius, height; float radius, height;
glm::vec3 offset; glm::vec3 offset;
_rig.computeAvatarBoundingCapsule(model, radius, height, offset); _rig.computeAvatarBoundingCapsule(hfmModel, radius, height, offset);
float invScale = 1.0f / _owningAvatar->getModelScale(); float invScale = 1.0f / _owningAvatar->getModelScale();
_boundingCapsuleRadius = invScale * radius; _boundingCapsuleRadius = invScale * radius;
_boundingCapsuleHeight = invScale * height; _boundingCapsuleHeight = invScale * height;

View file

@ -206,7 +206,7 @@ void FBXBaker::importScene() {
} }
#endif #endif
_model = reader.extractHFMModel({}, _modelURL.toString()); _hfmModel = reader.extractHFMModel({}, _modelURL.toString());
_textureContentMap = reader._textureContent; _textureContentMap = reader._textureContent;
} }
@ -231,7 +231,7 @@ void FBXBaker::rewriteAndBakeSceneModels() {
for (FBXNode& objectChild : rootChild.children) { for (FBXNode& objectChild : rootChild.children) {
if (objectChild.name == "Geometry") { if (objectChild.name == "Geometry") {
// TODO Pull this out of _model instead so we don't have to reprocess it // TODO Pull this out of _hfmModel instead so we don't have to reprocess it
auto extractedMesh = FBXReader::extractMesh(objectChild, meshIndex, false); auto extractedMesh = FBXReader::extractMesh(objectChild, meshIndex, false);
// Callback to get MaterialID // Callback to get MaterialID
@ -293,7 +293,7 @@ void FBXBaker::rewriteAndBakeSceneTextures() {
QHash<QString, image::TextureUsage::Type> textureTypes; QHash<QString, image::TextureUsage::Type> textureTypes;
// enumerate the materials in the extracted geometry so we can determine the texture type for each texture ID // enumerate the materials in the extracted geometry so we can determine the texture type for each texture ID
for (const auto& material : _model->materials) { for (const auto& material : _hfmModel->materials) {
if (material.normalTexture.isBumpmap) { if (material.normalTexture.isBumpmap) {
textureTypes[material.normalTexture.id] = BUMP_TEXTURE; textureTypes[material.normalTexture.id] = BUMP_TEXTURE;
} else { } else {

View file

@ -53,7 +53,7 @@ private:
void rewriteAndBakeSceneModels(); void rewriteAndBakeSceneModels();
void rewriteAndBakeSceneTextures(); void rewriteAndBakeSceneTextures();
HFMModel* _model; HFMModel* _hfmModel;
QHash<QString, int> _textureNameMatchCount; QHash<QString, int> _textureNameMatchCount;
QHash<QUrl, QString> _remappedTexturePaths; QHash<QUrl, QString> _remappedTexturePaths;

View file

@ -153,7 +153,7 @@ void OBJBaker::bakeOBJ() {
checkIfTexturesFinished(); checkIfTexturesFinished();
} }
void OBJBaker::createFBXNodeTree(FBXNode& rootNode, HFMModel& model) { void OBJBaker::createFBXNodeTree(FBXNode& rootNode, HFMModel& hfmModel) {
// Generating FBX Header Node // Generating FBX Header Node
FBXNode headerNode; FBXNode headerNode;
headerNode.name = FBX_HEADER_EXTENSION; headerNode.name = FBX_HEADER_EXTENSION;
@ -199,7 +199,7 @@ void OBJBaker::createFBXNodeTree(FBXNode& rootNode, HFMModel& model) {
// Compress the mesh information and store in dracoNode // Compress the mesh information and store in dracoNode
bool hasDeformers = false; // No concept of deformers for an OBJ bool hasDeformers = false; // No concept of deformers for an OBJ
FBXNode dracoNode; FBXNode dracoNode;
compressMesh(model.meshes[0], hasDeformers, dracoNode); compressMesh(hfmModel.meshes[0], hasDeformers, dracoNode);
geometryNode.children.append(dracoNode); geometryNode.children.append(dracoNode);
// Generating Object node's child - Model node // Generating Object node's child - Model node
@ -214,17 +214,17 @@ void OBJBaker::createFBXNodeTree(FBXNode& rootNode, HFMModel& model) {
objectNode.children = { geometryNode, modelNode }; objectNode.children = { geometryNode, modelNode };
// Generating Objects node's child - Material node // Generating Objects node's child - Material node
auto& meshParts = model.meshes[0].parts; auto& meshParts = hfmModel.meshes[0].parts;
for (auto& meshPart : meshParts) { for (auto& meshPart : meshParts) {
FBXNode materialNode; FBXNode materialNode;
materialNode.name = MATERIAL_NODE_NAME; materialNode.name = MATERIAL_NODE_NAME;
if (model.materials.size() == 1) { if (hfmModel.materials.size() == 1) {
// case when no material information is provided, OBJReader considers it as a single default material // case when no material information is provided, OBJReader considers it as a single default material
for (auto& materialID : model.materials.keys()) { for (auto& materialID : hfmModel.materials.keys()) {
setMaterialNodeProperties(materialNode, materialID, model); setMaterialNodeProperties(materialNode, materialID, hfmModel);
} }
} else { } else {
setMaterialNodeProperties(materialNode, meshPart.materialID, model); setMaterialNodeProperties(materialNode, meshPart.materialID, hfmModel);
} }
objectNode.children.append(materialNode); objectNode.children.append(materialNode);
@ -235,7 +235,7 @@ void OBJBaker::createFBXNodeTree(FBXNode& rootNode, HFMModel& model) {
auto size = meshParts.size(); auto size = meshParts.size();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
QString material = meshParts[i].materialID; QString material = meshParts[i].materialID;
HFMMaterial currentMaterial = model.materials[material]; HFMMaterial currentMaterial = hfmModel.materials[material];
if (!currentMaterial.albedoTexture.filename.isEmpty() || !currentMaterial.specularTexture.filename.isEmpty()) { if (!currentMaterial.albedoTexture.filename.isEmpty() || !currentMaterial.specularTexture.filename.isEmpty()) {
auto textureID = nextNodeID(); auto textureID = nextNodeID();
_mapTextureMaterial.emplace_back(textureID, i); _mapTextureMaterial.emplace_back(textureID, i);
@ -325,12 +325,12 @@ void OBJBaker::createFBXNodeTree(FBXNode& rootNode, HFMModel& model) {
} }
// Set properties for material nodes // Set properties for material nodes
void OBJBaker::setMaterialNodeProperties(FBXNode& materialNode, QString material, HFMModel& model) { void OBJBaker::setMaterialNodeProperties(FBXNode& materialNode, QString material, HFMModel& hfmModel) {
auto materialID = nextNodeID(); auto materialID = nextNodeID();
_materialIDs.push_back(materialID); _materialIDs.push_back(materialID);
materialNode.properties = { materialID, material, MESH }; materialNode.properties = { materialID, material, MESH };
HFMMaterial currentMaterial = model.materials[material]; HFMMaterial currentMaterial = hfmModel.materials[material];
// Setting the hierarchy: Material -> Properties70 -> P -> Properties // Setting the hierarchy: Material -> Properties70 -> P -> Properties
FBXNode properties70Node; FBXNode properties70Node;

View file

@ -39,8 +39,8 @@ private slots:
private: private:
void loadOBJ(); void loadOBJ();
void createFBXNodeTree(FBXNode& rootNode, HFMModel& model); void createFBXNodeTree(FBXNode& rootNode, HFMModel& hfmModel);
void setMaterialNodeProperties(FBXNode& materialNode, QString material, HFMModel& model); void setMaterialNodeProperties(FBXNode& materialNode, QString material, HFMModel& hfmModel);
NodeID nextNodeID() { return _nodeID++; } NodeID nextNodeID() { return _nodeID++; }

View file

@ -264,17 +264,17 @@ public:
}; };
glm::mat4 getGlobalTransform(const QMultiMap<QString, QString>& _connectionParentMap, glm::mat4 getGlobalTransform(const QMultiMap<QString, QString>& _connectionParentMap,
const QHash<QString, FBXModel>& models, QString nodeID, bool mixamoHack, const QString& url) { const QHash<QString, FBXModel>& fbxModels, QString nodeID, bool mixamoHack, const QString& url) {
glm::mat4 globalTransform; glm::mat4 globalTransform;
QVector<QString> visitedNodes; // Used to prevent following a cycle QVector<QString> visitedNodes; // Used to prevent following a cycle
while (!nodeID.isNull()) { while (!nodeID.isNull()) {
visitedNodes.append(nodeID); // Append each node we visit visitedNodes.append(nodeID); // Append each node we visit
const FBXModel& model = models.value(nodeID); const FBXModel& fbxModel = fbxModels.value(nodeID);
globalTransform = glm::translate(model.translation) * model.preTransform * glm::mat4_cast(model.preRotation * globalTransform = glm::translate(fbxModel.translation) * fbxModel.preTransform * glm::mat4_cast(fbxModel.preRotation *
model.rotation * model.postRotation) * model.postTransform * globalTransform; fbxModel.rotation * fbxModel.postRotation) * fbxModel.postTransform * globalTransform;
if (model.hasGeometricOffset) { if (fbxModel.hasGeometricOffset) {
glm::mat4 geometricOffset = createMatFromScaleQuatAndPos(model.geometricScaling, model.geometricRotation, model.geometricTranslation); glm::mat4 geometricOffset = createMatFromScaleQuatAndPos(fbxModel.geometricScaling, fbxModel.geometricRotation, fbxModel.geometricTranslation);
globalTransform = globalTransform * geometricOffset; globalTransform = globalTransform * geometricOffset;
} }
@ -290,7 +290,7 @@ glm::mat4 getGlobalTransform(const QMultiMap<QString, QString>& _connectionParen
continue; continue;
} }
if (models.contains(parentID)) { if (fbxModels.contains(parentID)) {
nodeID = parentID; nodeID = parentID;
break; break;
} }
@ -329,7 +329,7 @@ public:
}; };
void appendModelIDs(const QString& parentID, const QMultiMap<QString, QString>& connectionChildMap, void appendModelIDs(const QString& parentID, const QMultiMap<QString, QString>& connectionChildMap,
QHash<QString, FBXModel>& models, QSet<QString>& remainingModels, QVector<QString>& modelIDs, bool isRootNode = false) { QHash<QString, FBXModel>& fbxModels, QSet<QString>& remainingModels, QVector<QString>& modelIDs, bool isRootNode = false) {
if (remainingModels.contains(parentID)) { if (remainingModels.contains(parentID)) {
modelIDs.append(parentID); modelIDs.append(parentID);
remainingModels.remove(parentID); remainingModels.remove(parentID);
@ -337,10 +337,10 @@ void appendModelIDs(const QString& parentID, const QMultiMap<QString, QString>&
int parentIndex = isRootNode ? -1 : modelIDs.size() - 1; int parentIndex = isRootNode ? -1 : modelIDs.size() - 1;
foreach (const QString& childID, connectionChildMap.values(parentID)) { foreach (const QString& childID, connectionChildMap.values(parentID)) {
if (remainingModels.contains(childID)) { if (remainingModels.contains(childID)) {
FBXModel& model = models[childID]; FBXModel& fbxModel = fbxModels[childID];
if (model.parentIndex == -1) { if (fbxModel.parentIndex == -1) {
model.parentIndex = parentIndex; fbxModel.parentIndex = parentIndex;
appendModelIDs(childID, connectionChildMap, models, remainingModels, modelIDs); appendModelIDs(childID, connectionChildMap, fbxModels, remainingModels, modelIDs);
} }
} }
} }
@ -503,7 +503,7 @@ void addBlendshapes(const ExtractedBlendshape& extracted, const QList<WeightedIn
} }
QString getTopModelID(const QMultiMap<QString, QString>& connectionParentMap, QString getTopModelID(const QMultiMap<QString, QString>& connectionParentMap,
const QHash<QString, FBXModel>& models, const QString& modelID, const QString& url) { const QHash<QString, FBXModel>& fbxModels, const QString& modelID, const QString& url) {
QString topID = modelID; QString topID = modelID;
QVector<QString> visitedNodes; // Used to prevent following a cycle QVector<QString> visitedNodes; // Used to prevent following a cycle
forever { forever {
@ -515,7 +515,7 @@ QString getTopModelID(const QMultiMap<QString, QString>& connectionParentMap,
continue; continue;
} }
if (models.contains(parentID)) { if (fbxModels.contains(parentID)) {
topID = parentID; topID = parentID;
goto outerContinue; goto outerContinue;
} }
@ -689,10 +689,10 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString&
#if defined(DEBUG_FBXREADER) #if defined(DEBUG_FBXREADER)
int unknown = 0; int unknown = 0;
#endif #endif
HFMModel* modelPtr = new HFMModel; HFMModel* hfmModelPtr = new HFMModel;
HFMModel& model = *modelPtr; HFMModel& hfmModel = *hfmModelPtr;
model.originalURL = url; hfmModel.originalURL = url;
float unitScaleFactor = 1.0f; float unitScaleFactor = 1.0f;
glm::vec3 ambientColor; glm::vec3 ambientColor;
@ -708,7 +708,7 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString&
if (subobject.name == "MetaData") { if (subobject.name == "MetaData") {
foreach (const FBXNode& subsubobject, subobject.children) { foreach (const FBXNode& subsubobject, subobject.children) {
if (subsubobject.name == "Author") { if (subsubobject.name == "Author") {
model.author = subsubobject.properties.at(0).toString(); hfmModel.author = subsubobject.properties.at(0).toString();
} }
} }
} else if (subobject.name == "Properties70") { } else if (subobject.name == "Properties70") {
@ -716,7 +716,7 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString&
static const QVariant APPLICATION_NAME = QVariant(QByteArray("Original|ApplicationName")); static const QVariant APPLICATION_NAME = QVariant(QByteArray("Original|ApplicationName"));
if (subsubobject.name == "P" && subsubobject.properties.size() >= 5 && if (subsubobject.name == "P" && subsubobject.properties.size() >= 5 &&
subsubobject.properties.at(0) == APPLICATION_NAME) { subsubobject.properties.at(0) == APPLICATION_NAME) {
model.applicationName = subsubobject.properties.at(4).toString(); hfmModel.applicationName = subsubobject.properties.at(4).toString();
} }
} }
} }
@ -1307,7 +1307,7 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString&
name = name.mid(name.lastIndexOf('.') + 1); name = name.mid(name.lastIndexOf('.') + 1);
} }
QString id = getID(object.properties); QString id = getID(object.properties);
model.blendshapeChannelNames << name; hfmModel.blendshapeChannelNames << name;
foreach (const WeightedIndex& index, blendshapeIndices.values(name)) { foreach (const WeightedIndex& index, blendshapeIndices.values(name)) {
blendshapeChannelIndices.insert(id, index); blendshapeChannelIndices.insert(id, index);
} }
@ -1454,7 +1454,7 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString&
float offsetScale = mapping.value("scale", 1.0f).toFloat() * unitScaleFactor * METERS_PER_CENTIMETER; float offsetScale = mapping.value("scale", 1.0f).toFloat() * unitScaleFactor * METERS_PER_CENTIMETER;
glm::quat offsetRotation = glm::quat(glm::radians(glm::vec3(mapping.value("rx").toFloat(), glm::quat offsetRotation = glm::quat(glm::radians(glm::vec3(mapping.value("rx").toFloat(),
mapping.value("ry").toFloat(), mapping.value("rz").toFloat()))); mapping.value("ry").toFloat(), mapping.value("rz").toFloat())));
model.offset = glm::translate(glm::vec3(mapping.value("tx").toFloat(), mapping.value("ty").toFloat(), hfmModel.offset = glm::translate(glm::vec3(mapping.value("tx").toFloat(), mapping.value("ty").toFloat(),
mapping.value("tz").toFloat())) * glm::mat4_cast(offsetRotation) * mapping.value("tz").toFloat())) * glm::mat4_cast(offsetRotation) *
glm::scale(glm::vec3(offsetScale, offsetScale, offsetScale)); glm::scale(glm::vec3(offsetScale, offsetScale, offsetScale));
@ -1507,12 +1507,12 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString&
HFMAnimationFrame frame; HFMAnimationFrame frame;
frame.rotations.resize(modelIDs.size()); frame.rotations.resize(modelIDs.size());
frame.translations.resize(modelIDs.size()); frame.translations.resize(modelIDs.size());
model.animationFrames.append(frame); hfmModel.animationFrames.append(frame);
} }
// convert the models to joints // convert the models to joints
QVariantList freeJoints = mapping.values("freeJoint"); QVariantList freeJoints = mapping.values("freeJoint");
model.hasSkeletonJoints = false; hfmModel.hasSkeletonJoints = false;
foreach (const QString& modelID, modelIDs) { foreach (const QString& modelID, modelIDs) {
const FBXModel& fbxModel = fbxModels[modelID]; const FBXModel& fbxModel = fbxModels[modelID];
HFMJoint joint; HFMJoint joint;
@ -1520,11 +1520,11 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString&
joint.parentIndex = fbxModel.parentIndex; joint.parentIndex = fbxModel.parentIndex;
// get the indices of all ancestors starting with the first free one (if any) // get the indices of all ancestors starting with the first free one (if any)
int jointIndex = model.joints.size(); int jointIndex = hfmModel.joints.size();
joint.freeLineage.append(jointIndex); joint.freeLineage.append(jointIndex);
int lastFreeIndex = joint.isFree ? 0 : -1; int lastFreeIndex = joint.isFree ? 0 : -1;
for (int index = joint.parentIndex; index != -1; index = model.joints.at(index).parentIndex) { for (int index = joint.parentIndex; index != -1; index = hfmModel.joints.at(index).parentIndex) {
if (model.joints.at(index).isFree) { if (hfmModel.joints.at(index).isFree) {
lastFreeIndex = joint.freeLineage.size(); lastFreeIndex = joint.freeLineage.size();
} }
joint.freeLineage.append(index); joint.freeLineage.append(index);
@ -1547,13 +1547,13 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString&
glm::quat combinedRotation = joint.preRotation * joint.rotation * joint.postRotation; glm::quat combinedRotation = joint.preRotation * joint.rotation * joint.postRotation;
if (joint.parentIndex == -1) { if (joint.parentIndex == -1) {
joint.transform = model.offset * glm::translate(joint.translation) * joint.preTransform * joint.transform = hfmModel.offset * glm::translate(joint.translation) * joint.preTransform *
glm::mat4_cast(combinedRotation) * joint.postTransform; glm::mat4_cast(combinedRotation) * joint.postTransform;
joint.inverseDefaultRotation = glm::inverse(combinedRotation); joint.inverseDefaultRotation = glm::inverse(combinedRotation);
joint.distanceToParent = 0.0f; joint.distanceToParent = 0.0f;
} else { } else {
const HFMJoint& parentJoint = model.joints.at(joint.parentIndex); const HFMJoint& parentJoint = hfmModel.joints.at(joint.parentIndex);
joint.transform = parentJoint.transform * glm::translate(joint.translation) * joint.transform = parentJoint.transform * glm::translate(joint.translation) *
joint.preTransform * glm::mat4_cast(combinedRotation) * joint.postTransform; joint.preTransform * glm::mat4_cast(combinedRotation) * joint.postTransform;
joint.inverseDefaultRotation = glm::inverse(combinedRotation) * parentJoint.inverseDefaultRotation; joint.inverseDefaultRotation = glm::inverse(combinedRotation) * parentJoint.inverseDefaultRotation;
@ -1566,15 +1566,15 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString&
foreach (const QString& childID, _connectionChildMap.values(modelID)) { foreach (const QString& childID, _connectionChildMap.values(modelID)) {
QString type = typeFlags.value(childID); QString type = typeFlags.value(childID);
if (!type.isEmpty()) { if (!type.isEmpty()) {
model.hasSkeletonJoints |= (joint.isSkeletonJoint = type.toLower().contains("Skeleton")); hfmModel.hasSkeletonJoints |= (joint.isSkeletonJoint = type.toLower().contains("Skeleton"));
break; break;
} }
} }
joint.bindTransformFoundInCluster = false; joint.bindTransformFoundInCluster = false;
model.joints.append(joint); hfmModel.joints.append(joint);
model.jointIndices.insert(fbxModel.name, model.joints.size()); hfmModel.jointIndices.insert(fbxModel.name, hfmModel.joints.size());
QString rotationID = localRotations.value(modelID); QString rotationID = localRotations.value(modelID);
AnimationCurve xRotCurve = animationCurves.value(xComponents.value(rotationID)); AnimationCurve xRotCurve = animationCurves.value(xComponents.value(rotationID));
@ -1590,11 +1590,11 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString&
glm::vec3 defaultPosValues = joint.translation; glm::vec3 defaultPosValues = joint.translation;
for (int i = 0; i < frameCount; i++) { for (int i = 0; i < frameCount; i++) {
model.animationFrames[i].rotations[jointIndex] = glm::quat(glm::radians(glm::vec3( hfmModel.animationFrames[i].rotations[jointIndex] = glm::quat(glm::radians(glm::vec3(
xRotCurve.values.isEmpty() ? defaultRotValues.x : xRotCurve.values.at(i % xRotCurve.values.size()), xRotCurve.values.isEmpty() ? defaultRotValues.x : xRotCurve.values.at(i % xRotCurve.values.size()),
yRotCurve.values.isEmpty() ? defaultRotValues.y : yRotCurve.values.at(i % yRotCurve.values.size()), yRotCurve.values.isEmpty() ? defaultRotValues.y : yRotCurve.values.at(i % yRotCurve.values.size()),
zRotCurve.values.isEmpty() ? defaultRotValues.z : zRotCurve.values.at(i % zRotCurve.values.size())))); zRotCurve.values.isEmpty() ? defaultRotValues.z : zRotCurve.values.at(i % zRotCurve.values.size()))));
model.animationFrames[i].translations[jointIndex] = glm::vec3( hfmModel.animationFrames[i].translations[jointIndex] = glm::vec3(
xPosCurve.values.isEmpty() ? defaultPosValues.x : xPosCurve.values.at(i % xPosCurve.values.size()), xPosCurve.values.isEmpty() ? defaultPosValues.x : xPosCurve.values.at(i % xPosCurve.values.size()),
yPosCurve.values.isEmpty() ? defaultPosValues.y : yPosCurve.values.at(i % yPosCurve.values.size()), yPosCurve.values.isEmpty() ? defaultPosValues.y : yPosCurve.values.at(i % yPosCurve.values.size()),
zPosCurve.values.isEmpty() ? defaultPosValues.z : zPosCurve.values.at(i % zPosCurve.values.size())); zPosCurve.values.isEmpty() ? defaultPosValues.z : zPosCurve.values.at(i % zPosCurve.values.size()));
@ -1603,32 +1603,32 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString&
// NOTE: shapeVertices are in joint-frame // NOTE: shapeVertices are in joint-frame
std::vector<ShapeVertices> shapeVertices; std::vector<ShapeVertices> shapeVertices;
shapeVertices.resize(std::max(1, model.joints.size()) ); shapeVertices.resize(std::max(1, hfmModel.joints.size()) );
// find our special joints // find our special joints
model.leftEyeJointIndex = modelIDs.indexOf(jointEyeLeftID); hfmModel.leftEyeJointIndex = modelIDs.indexOf(jointEyeLeftID);
model.rightEyeJointIndex = modelIDs.indexOf(jointEyeRightID); hfmModel.rightEyeJointIndex = modelIDs.indexOf(jointEyeRightID);
model.neckJointIndex = modelIDs.indexOf(jointNeckID); hfmModel.neckJointIndex = modelIDs.indexOf(jointNeckID);
model.rootJointIndex = modelIDs.indexOf(jointRootID); hfmModel.rootJointIndex = modelIDs.indexOf(jointRootID);
model.leanJointIndex = modelIDs.indexOf(jointLeanID); hfmModel.leanJointIndex = modelIDs.indexOf(jointLeanID);
model.headJointIndex = modelIDs.indexOf(jointHeadID); hfmModel.headJointIndex = modelIDs.indexOf(jointHeadID);
model.leftHandJointIndex = modelIDs.indexOf(jointLeftHandID); hfmModel.leftHandJointIndex = modelIDs.indexOf(jointLeftHandID);
model.rightHandJointIndex = modelIDs.indexOf(jointRightHandID); hfmModel.rightHandJointIndex = modelIDs.indexOf(jointRightHandID);
model.leftToeJointIndex = modelIDs.indexOf(jointLeftToeID); hfmModel.leftToeJointIndex = modelIDs.indexOf(jointLeftToeID);
model.rightToeJointIndex = modelIDs.indexOf(jointRightToeID); hfmModel.rightToeJointIndex = modelIDs.indexOf(jointRightToeID);
foreach (const QString& id, humanIKJointIDs) { foreach (const QString& id, humanIKJointIDs) {
model.humanIKJointIndices.append(modelIDs.indexOf(id)); hfmModel.humanIKJointIndices.append(modelIDs.indexOf(id));
} }
// extract the translation component of the neck transform // extract the translation component of the neck transform
if (model.neckJointIndex != -1) { if (hfmModel.neckJointIndex != -1) {
const glm::mat4& transform = model.joints.at(model.neckJointIndex).transform; const glm::mat4& transform = hfmModel.joints.at(hfmModel.neckJointIndex).transform;
model.neckPivot = glm::vec3(transform[3][0], transform[3][1], transform[3][2]); hfmModel.neckPivot = glm::vec3(transform[3][0], transform[3][1], transform[3][2]);
} }
model.bindExtents.reset(); hfmModel.bindExtents.reset();
model.meshExtents.reset(); hfmModel.meshExtents.reset();
// Create the Material Library // Create the Material Library
consolidateHFMMaterials(mapping); consolidateHFMMaterials(mapping);
@ -1664,7 +1664,7 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString&
} }
} }
#endif #endif
model.materials = _hfmMaterials; hfmModel.materials = _hfmMaterials;
// see if any materials have texture children // see if any materials have texture children
bool materialsHaveTextures = checkMaterialsHaveTextures(_hfmMaterials, _textureFilenames, _connectionChildMap); bool materialsHaveTextures = checkMaterialsHaveTextures(_hfmMaterials, _textureFilenames, _connectionChildMap);
@ -1676,13 +1676,13 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString&
// accumulate local transforms // accumulate local transforms
QString modelID = fbxModels.contains(it.key()) ? it.key() : _connectionParentMap.value(it.key()); QString modelID = fbxModels.contains(it.key()) ? it.key() : _connectionParentMap.value(it.key());
glm::mat4 modelTransform = getGlobalTransform(_connectionParentMap, fbxModels, modelID, model.applicationName == "mixamo.com", url); glm::mat4 modelTransform = getGlobalTransform(_connectionParentMap, fbxModels, modelID, hfmModel.applicationName == "mixamo.com", url);
// compute the mesh extents from the transformed vertices // compute the mesh extents from the transformed vertices
foreach (const glm::vec3& vertex, extracted.mesh.vertices) { foreach (const glm::vec3& vertex, extracted.mesh.vertices) {
glm::vec3 transformedVertex = glm::vec3(modelTransform * glm::vec4(vertex, 1.0f)); glm::vec3 transformedVertex = glm::vec3(modelTransform * glm::vec4(vertex, 1.0f));
model.meshExtents.minimum = glm::min(model.meshExtents.minimum, transformedVertex); hfmModel.meshExtents.minimum = glm::min(hfmModel.meshExtents.minimum, transformedVertex);
model.meshExtents.maximum = glm::max(model.meshExtents.maximum, transformedVertex); hfmModel.meshExtents.maximum = glm::max(hfmModel.meshExtents.maximum, transformedVertex);
extracted.mesh.meshExtents.minimum = glm::min(extracted.mesh.meshExtents.minimum, transformedVertex); extracted.mesh.meshExtents.minimum = glm::min(extracted.mesh.meshExtents.minimum, transformedVertex);
extracted.mesh.meshExtents.maximum = glm::max(extracted.mesh.meshExtents.maximum, transformedVertex); extracted.mesh.meshExtents.maximum = glm::max(extracted.mesh.meshExtents.maximum, transformedVertex);
@ -1763,14 +1763,14 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString&
extracted.mesh.clusters.append(hfmCluster); extracted.mesh.clusters.append(hfmCluster);
// override the bind rotation with the transform link // override the bind rotation with the transform link
HFMJoint& joint = model.joints[hfmCluster.jointIndex]; HFMJoint& joint = hfmModel.joints[hfmCluster.jointIndex];
joint.inverseBindRotation = glm::inverse(extractRotation(cluster.transformLink)); joint.inverseBindRotation = glm::inverse(extractRotation(cluster.transformLink));
joint.bindTransform = cluster.transformLink; joint.bindTransform = cluster.transformLink;
joint.bindTransformFoundInCluster = true; joint.bindTransformFoundInCluster = true;
// update the bind pose extents // update the bind pose extents
glm::vec3 bindTranslation = extractTranslation(model.offset * joint.bindTransform); glm::vec3 bindTranslation = extractTranslation(hfmModel.offset * joint.bindTransform);
model.bindExtents.addPoint(bindTranslation); hfmModel.bindExtents.addPoint(bindTranslation);
} }
} }
@ -1801,14 +1801,14 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString&
const Cluster& cluster = clusters[clusterID]; const Cluster& cluster = clusters[clusterID];
const HFMCluster& hfmCluster = extracted.mesh.clusters.at(i); const HFMCluster& hfmCluster = extracted.mesh.clusters.at(i);
int jointIndex = hfmCluster.jointIndex; int jointIndex = hfmCluster.jointIndex;
HFMJoint& joint = model.joints[jointIndex]; HFMJoint& joint = hfmModel.joints[jointIndex];
glm::mat4 transformJointToMesh = inverseModelTransform * joint.bindTransform; glm::mat4 transformJointToMesh = inverseModelTransform * joint.bindTransform;
glm::vec3 boneEnd = extractTranslation(transformJointToMesh); glm::vec3 boneEnd = extractTranslation(transformJointToMesh);
glm::vec3 boneBegin = boneEnd; glm::vec3 boneBegin = boneEnd;
glm::vec3 boneDirection; glm::vec3 boneDirection;
float boneLength = 0.0f; float boneLength = 0.0f;
if (joint.parentIndex != -1) { if (joint.parentIndex != -1) {
boneBegin = extractTranslation(inverseModelTransform * model.joints[joint.parentIndex].bindTransform); boneBegin = extractTranslation(inverseModelTransform * hfmModel.joints[joint.parentIndex].bindTransform);
boneDirection = boneEnd - boneBegin; boneDirection = boneEnd - boneBegin;
boneLength = glm::length(boneDirection); boneLength = glm::length(boneDirection);
if (boneLength > EPSILON) { if (boneLength > EPSILON) {
@ -1882,7 +1882,7 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString&
} else { } else {
// this is a single-mesh joint // this is a single-mesh joint
int jointIndex = firstHFMCluster.jointIndex; int jointIndex = firstHFMCluster.jointIndex;
HFMJoint& joint = model.joints[jointIndex]; HFMJoint& joint = hfmModel.joints[jointIndex];
// transform cluster vertices to joint-frame and save for later // transform cluster vertices to joint-frame and save for later
glm::mat4 meshToJoint = glm::inverse(joint.bindTransform) * modelTransform; glm::mat4 meshToJoint = glm::inverse(joint.bindTransform) * modelTransform;
@ -1902,8 +1902,8 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString&
} }
buildModelMesh(extracted.mesh, url); buildModelMesh(extracted.mesh, url);
model.meshes.append(extracted.mesh); hfmModel.meshes.append(extracted.mesh);
int meshIndex = model.meshes.size() - 1; int meshIndex = hfmModel.meshes.size() - 1;
if (extracted.mesh._mesh) { if (extracted.mesh._mesh) {
extracted.mesh._mesh->displayName = QString("%1#/mesh/%2").arg(url).arg(meshIndex).toStdString(); extracted.mesh._mesh->displayName = QString("%1#/mesh/%2").arg(url).arg(meshIndex).toStdString();
extracted.mesh._mesh->modelName = modelIDsToNames.value(modelID).toStdString(); extracted.mesh._mesh->modelName = modelIDsToNames.value(modelID).toStdString();
@ -1923,8 +1923,8 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString&
}; };
// now that all joints have been scanned compute a k-Dop bounding volume of mesh // now that all joints have been scanned compute a k-Dop bounding volume of mesh
for (int i = 0; i < model.joints.size(); ++i) { for (int i = 0; i < hfmModel.joints.size(); ++i) {
HFMJoint& joint = model.joints[i]; HFMJoint& joint = hfmModel.joints[i];
// NOTE: points are in joint-frame // NOTE: points are in joint-frame
ShapeVertices& points = shapeVertices.at(i); ShapeVertices& points = shapeVertices.at(i);
@ -1958,7 +1958,7 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString&
generateBoundryLinesForDop14(joint.shapeInfo.dots, joint.shapeInfo.avgPoint, joint.shapeInfo.debugLines); generateBoundryLinesForDop14(joint.shapeInfo.dots, joint.shapeInfo.avgPoint, joint.shapeInfo.debugLines);
} }
} }
model.palmDirection = parseVec3(mapping.value("palmDirection", "0, -1, 0").toString()); hfmModel.palmDirection = parseVec3(mapping.value("palmDirection", "0, -1, 0").toString());
// attempt to map any meshes to a named model // attempt to map any meshes to a named model
for (QHash<QString, int>::const_iterator m = meshIDsToMeshIndices.constBegin(); for (QHash<QString, int>::const_iterator m = meshIDsToMeshIndices.constBegin();
@ -1971,14 +1971,14 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString&
const QString& modelID = ooChildToParent.value(meshID); const QString& modelID = ooChildToParent.value(meshID);
if (modelIDsToNames.contains(modelID)) { if (modelIDsToNames.contains(modelID)) {
const QString& modelName = modelIDsToNames.value(modelID); const QString& modelName = modelIDsToNames.value(modelID);
model.meshIndicesToModelNames.insert(meshIndex, modelName); hfmModel.meshIndicesToModelNames.insert(meshIndex, modelName);
} }
} }
} }
{ {
int i = 0; int i = 0;
for (const auto& mesh : model.meshes) { for (const auto& mesh : hfmModel.meshes) {
auto name = model.getModelNameOfMesh(i++); auto name = hfmModel.getModelNameOfMesh(i++);
if (!name.isEmpty()) { if (!name.isEmpty()) {
if (mesh._mesh) { if (mesh._mesh) {
mesh._mesh->modelName = name.toStdString(); mesh._mesh->modelName = name.toStdString();
@ -1991,7 +1991,7 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString&
} }
} }
} }
return modelPtr; return hfmModelPtr;
} }
HFMModel* readFBX(const QByteArray& data, const QVariantHash& mapping, const QString& url, bool loadLightmaps, float lightmapLevel) { HFMModel* readFBX(const QByteArray& data, const QVariantHash& mapping, const QString& url, bool loadLightmaps, float lightmapLevel) {

View file

@ -697,7 +697,7 @@ glm::mat4 GLTFReader::getModelTransform(const GLTFNode& node) {
return tmat; return tmat;
} }
bool GLTFReader::buildGeometry(HFMModel& model, const QUrl& url) { bool GLTFReader::buildGeometry(HFMModel& hfmModel, const QUrl& url) {
//Build dependencies //Build dependencies
QVector<QVector<int>> nodeDependencies(_file.nodes.size()); QVector<QVector<int>> nodeDependencies(_file.nodes.size());
@ -727,17 +727,17 @@ bool GLTFReader::buildGeometry(HFMModel& model, const QUrl& url) {
} }
//Build default joints //Build default joints
model.joints.resize(1); hfmModel.joints.resize(1);
model.joints[0].isFree = false; hfmModel.joints[0].isFree = false;
model.joints[0].parentIndex = -1; hfmModel.joints[0].parentIndex = -1;
model.joints[0].distanceToParent = 0; hfmModel.joints[0].distanceToParent = 0;
model.joints[0].translation = glm::vec3(0, 0, 0); hfmModel.joints[0].translation = glm::vec3(0, 0, 0);
model.joints[0].rotationMin = glm::vec3(0, 0, 0); hfmModel.joints[0].rotationMin = glm::vec3(0, 0, 0);
model.joints[0].rotationMax = glm::vec3(0, 0, 0); hfmModel.joints[0].rotationMax = glm::vec3(0, 0, 0);
model.joints[0].name = "OBJ"; hfmModel.joints[0].name = "OBJ";
model.joints[0].isSkeletonJoint = true; hfmModel.joints[0].isSkeletonJoint = true;
model.jointIndices["x"] = 1; hfmModel.jointIndices["x"] = 1;
//Build materials //Build materials
QVector<QString> materialIDs; QVector<QString> materialIDs;
@ -750,8 +750,8 @@ bool GLTFReader::buildGeometry(HFMModel& model, const QUrl& url) {
for (int i = 0; i < materialIDs.size(); i++) { for (int i = 0; i < materialIDs.size(); i++) {
QString& matid = materialIDs[i]; QString& matid = materialIDs[i];
model.materials[matid] = HFMMaterial(); hfmModel.materials[matid] = HFMMaterial();
HFMMaterial& hfmMaterial = model.materials[matid]; HFMMaterial& hfmMaterial = hfmModel.materials[matid];
hfmMaterial._material = std::make_shared<graphics::Material>(); hfmMaterial._material = std::make_shared<graphics::Material>();
setHFMMaterial(hfmMaterial, _file.materials[i]); setHFMMaterial(hfmMaterial, _file.materials[i]);
} }
@ -765,8 +765,8 @@ bool GLTFReader::buildGeometry(HFMModel& model, const QUrl& url) {
if (node.defined["mesh"]) { if (node.defined["mesh"]) {
qCDebug(modelformat) << "node_transforms" << node.transforms; qCDebug(modelformat) << "node_transforms" << node.transforms;
foreach(auto &primitive, _file.meshes[node.mesh].primitives) { foreach(auto &primitive, _file.meshes[node.mesh].primitives) {
model.meshes.append(HFMMesh()); hfmModel.meshes.append(HFMMesh());
HFMMesh& mesh = model.meshes[model.meshes.size() - 1]; HFMMesh& mesh = hfmModel.meshes[hfmModel.meshes.size() - 1];
HFMCluster cluster; HFMCluster cluster;
cluster.jointIndex = 0; cluster.jointIndex = 0;
cluster.inverseBindMatrix = glm::mat4(1, 0, 0, 0, cluster.inverseBindMatrix = glm::mat4(1, 0, 0, 0,
@ -886,7 +886,7 @@ bool GLTFReader::buildGeometry(HFMModel& model, const QUrl& url) {
mesh.meshExtents.reset(); mesh.meshExtents.reset();
foreach(const glm::vec3& vertex, mesh.vertices) { foreach(const glm::vec3& vertex, mesh.vertices) {
mesh.meshExtents.addPoint(vertex); mesh.meshExtents.addPoint(vertex);
model.meshExtents.addPoint(vertex); hfmModel.meshExtents.addPoint(vertex);
} }
// since mesh.modelTransform seems to not have any effect I apply the transformation the model // since mesh.modelTransform seems to not have any effect I apply the transformation the model
@ -898,7 +898,7 @@ bool GLTFReader::buildGeometry(HFMModel& model, const QUrl& url) {
} }
} }
mesh.meshIndex = model.meshes.size(); mesh.meshIndex = hfmModel.meshes.size();
FBXReader::buildModelMesh(mesh, url.toString()); FBXReader::buildModelMesh(mesh, url.toString());
} }
@ -924,13 +924,13 @@ HFMModel* GLTFReader::readGLTF(QByteArray& data, const QVariantHash& mapping,
parseGLTF(data); parseGLTF(data);
//_file.dump(); //_file.dump();
HFMModel* modelPtr = new HFMModel(); HFMModel* hfmModelPtr = new HFMModel();
HFMModel& model = *modelPtr; HFMModel& hfmModel = *hfmModelPtr;
buildGeometry(model, url); buildGeometry(hfmModel, url);
//hfmDebugDump(data); //hfmDebugDump(data);
return modelPtr; return hfmModelPtr;
} }

View file

@ -706,7 +706,7 @@ class GLTFReader : public QObject {
Q_OBJECT Q_OBJECT
public: public:
GLTFReader(); GLTFReader();
HFMModel* readGLTF(QByteArray& model, const QVariantHash& mapping, HFMModel* readGLTF(QByteArray& data, const QVariantHash& mapping,
const QUrl& url, bool loadLightmaps = true, float lightmapLevel = 1.0f); const QUrl& url, bool loadLightmaps = true, float lightmapLevel = 1.0f);
private: private:
GLTFFile _file; GLTFFile _file;
@ -714,7 +714,7 @@ private:
glm::mat4 getModelTransform(const GLTFNode& node); glm::mat4 getModelTransform(const GLTFNode& node);
bool buildGeometry(HFMModel& model, const QUrl& url); bool buildGeometry(HFMModel& hfmModel, const QUrl& url);
bool parseGLTF(const QByteArray& data); bool parseGLTF(const QByteArray& data);
bool getStringVal(const QJsonObject& object, const QString& fieldname, bool getStringVal(const QJsonObject& object, const QString& fieldname,

View file

@ -488,10 +488,10 @@ QNetworkReply* request(QUrl& url, bool isTest) {
} }
bool OBJReader::parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& mapping, HFMModel& model, bool OBJReader::parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& mapping, HFMModel& hfmModel,
float& scaleGuess, bool combineParts) { float& scaleGuess, bool combineParts) {
FaceGroup faces; FaceGroup faces;
HFMMesh& mesh = model.meshes[0]; HFMMesh& mesh = hfmModel.meshes[0];
mesh.parts.append(HFMMeshPart()); mesh.parts.append(HFMMeshPart());
HFMMeshPart& meshPart = mesh.parts.last(); HFMMeshPart& meshPart = mesh.parts.last();
bool sawG = false; bool sawG = false;
@ -657,36 +657,36 @@ HFMModel::Pointer OBJReader::readOBJ(QByteArray& data, const QVariantHash& mappi
QBuffer buffer { &data }; QBuffer buffer { &data };
buffer.open(QIODevice::ReadOnly); buffer.open(QIODevice::ReadOnly);
auto modelPtr { std::make_shared<HFMModel>() }; auto hfmModelPtr { std::make_shared<HFMModel>() };
HFMModel& model { *modelPtr }; HFMModel& hfmModel { *hfmModelPtr };
OBJTokenizer tokenizer { &buffer }; OBJTokenizer tokenizer { &buffer };
float scaleGuess = 1.0f; float scaleGuess = 1.0f;
bool needsMaterialLibrary = false; bool needsMaterialLibrary = false;
_url = url; _url = url;
model.meshExtents.reset(); hfmModel.meshExtents.reset();
model.meshes.append(HFMMesh()); hfmModel.meshes.append(HFMMesh());
try { try {
// call parseOBJGroup as long as it's returning true. Each successful call will // call parseOBJGroup as long as it's returning true. Each successful call will
// add a new meshPart to the model's single mesh. // add a new meshPart to the model's single mesh.
while (parseOBJGroup(tokenizer, mapping, model, scaleGuess, combineParts)) {} while (parseOBJGroup(tokenizer, mapping, hfmModel, scaleGuess, combineParts)) {}
HFMMesh& mesh = model.meshes[0]; HFMMesh& mesh = hfmModel.meshes[0];
mesh.meshIndex = 0; mesh.meshIndex = 0;
model.joints.resize(1); hfmModel.joints.resize(1);
model.joints[0].isFree = false; hfmModel.joints[0].isFree = false;
model.joints[0].parentIndex = -1; hfmModel.joints[0].parentIndex = -1;
model.joints[0].distanceToParent = 0; hfmModel.joints[0].distanceToParent = 0;
model.joints[0].translation = glm::vec3(0, 0, 0); hfmModel.joints[0].translation = glm::vec3(0, 0, 0);
model.joints[0].rotationMin = glm::vec3(0, 0, 0); hfmModel.joints[0].rotationMin = glm::vec3(0, 0, 0);
model.joints[0].rotationMax = glm::vec3(0, 0, 0); hfmModel.joints[0].rotationMax = glm::vec3(0, 0, 0);
model.joints[0].name = "OBJ"; hfmModel.joints[0].name = "OBJ";
model.joints[0].isSkeletonJoint = true; hfmModel.joints[0].isSkeletonJoint = true;
model.jointIndices["x"] = 1; hfmModel.jointIndices["x"] = 1;
HFMCluster cluster; HFMCluster cluster;
cluster.jointIndex = 0; cluster.jointIndex = 0;
@ -818,13 +818,13 @@ HFMModel::Pointer OBJReader::readOBJ(QByteArray& data, const QVariantHash& mappi
mesh.meshExtents.reset(); mesh.meshExtents.reset();
foreach(const glm::vec3& vertex, mesh.vertices) { foreach(const glm::vec3& vertex, mesh.vertices) {
mesh.meshExtents.addPoint(vertex); mesh.meshExtents.addPoint(vertex);
model.meshExtents.addPoint(vertex); hfmModel.meshExtents.addPoint(vertex);
} }
// Build the single mesh. // Build the single mesh.
FBXReader::buildModelMesh(mesh, url.toString()); FBXReader::buildModelMesh(mesh, url.toString());
// hfmDebugDump(model); // hfmDebugDump(hfmModel);
} catch(const std::exception& e) { } catch(const std::exception& e) {
qCDebug(modelformat) << "OBJ reader fail: " << e.what(); qCDebug(modelformat) << "OBJ reader fail: " << e.what();
} }
@ -885,12 +885,12 @@ HFMModel::Pointer OBJReader::readOBJ(QByteArray& data, const QVariantHash& mappi
if (!objMaterial.used) { if (!objMaterial.used) {
continue; continue;
} }
model.materials[materialID] = HFMMaterial(objMaterial.diffuseColor, hfmModel.materials[materialID] = HFMMaterial(objMaterial.diffuseColor,
objMaterial.specularColor, objMaterial.specularColor,
objMaterial.emissiveColor, objMaterial.emissiveColor,
objMaterial.shininess, objMaterial.shininess,
objMaterial.opacity); objMaterial.opacity);
HFMMaterial& hfmMaterial = model.materials[materialID]; HFMMaterial& hfmMaterial = hfmModel.materials[materialID];
hfmMaterial.materialID = materialID; hfmMaterial.materialID = materialID;
hfmMaterial._material = std::make_shared<graphics::Material>(); hfmMaterial._material = std::make_shared<graphics::Material>();
graphics::MaterialPointer modelMaterial = hfmMaterial._material; graphics::MaterialPointer modelMaterial = hfmMaterial._material;
@ -988,7 +988,7 @@ HFMModel::Pointer OBJReader::readOBJ(QByteArray& data, const QVariantHash& mappi
modelMaterial->setOpacity(hfmMaterial.opacity); modelMaterial->setOpacity(hfmMaterial.opacity);
} }
return modelPtr; return hfmModelPtr;
} }
void hfmDebugDump(const HFMModel& hfmModel) { void hfmDebugDump(const HFMModel& hfmModel) {

View file

@ -93,7 +93,7 @@ private:
QUrl _url; QUrl _url;
QHash<QByteArray, bool> librariesSeen; QHash<QByteArray, bool> librariesSeen;
bool parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& mapping, HFMModel& model, bool parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& mapping, HFMModel& hfmModel,
float& scaleGuess, bool combineParts); float& scaleGuess, bool combineParts);
void parseMaterialLibrary(QIODevice* device); void parseMaterialLibrary(QIODevice* device);
void parseTextureLine(const QByteArray& textureLine, QByteArray& filename, OBJMaterialTextureOptions& textureOptions); void parseTextureLine(const QByteArray& textureLine, QByteArray& filename, OBJMaterialTextureOptions& textureOptions);

View file

@ -22,8 +22,8 @@
bool HFMModelLessThan(const HFMMesh& e1, const HFMMesh& e2) { bool HFMModelLessThan(const HFMMesh& e1, const HFMMesh& e2) {
return e1.meshIndex < e2.meshIndex; return e1.meshIndex < e2.meshIndex;
} }
void reSortHFMModelMeshes(HFMModel& model) { void reSortHFMModelMeshes(HFMModel& hfmModel) {
qSort(model.meshes.begin(), model.meshes.end(), HFMModelLessThan); qSort(hfmModel.meshes.begin(), hfmModel.meshes.end(), HFMModelLessThan);
} }
@ -41,17 +41,17 @@ bool vhacd::VHACDUtil::loadFBX(const QString filename, HFMModel& result) {
} }
try { try {
QByteArray fbxContents = fbx.readAll(); QByteArray fbxContents = fbx.readAll();
HFMModel::Pointer model; HFMModel::Pointer hfmModel;
if (filename.toLower().endsWith(".obj")) { if (filename.toLower().endsWith(".obj")) {
bool combineParts = false; bool combineParts = false;
model = OBJReader().readOBJ(fbxContents, QVariantHash(), combineParts); hfmModel = OBJReader().readOBJ(fbxContents, QVariantHash(), combineParts);
} else if (filename.toLower().endsWith(".fbx")) { } else if (filename.toLower().endsWith(".fbx")) {
model.reset(readFBX(fbxContents, QVariantHash(), filename)); hfmModel.reset(readFBX(fbxContents, QVariantHash(), filename));
} else { } else {
qWarning() << "file has unknown extension" << filename; qWarning() << "file has unknown extension" << filename;
return false; return false;
} }
result = *model; result = *hfmModel;
reSortHFMModelMeshes(result); reSortHFMModelMeshes(result);
} catch (const QString& error) { } catch (const QString& error) {
@ -288,17 +288,17 @@ float computeDt(uint64_t start) {
return (float)(usecTimestampNow() - start) / (float)USECS_PER_SECOND; return (float)(usecTimestampNow() - start) / (float)USECS_PER_SECOND;
} }
bool vhacd::VHACDUtil::computeVHACD(HFMModel& model, bool vhacd::VHACDUtil::computeVHACD(HFMModel& hfmModel,
VHACD::IVHACD::Parameters params, VHACD::IVHACD::Parameters params,
HFMModel& result, HFMModel& result,
float minimumMeshSize, float maximumMeshSize) { float minimumMeshSize, float maximumMeshSize) {
if (_verbose) { if (_verbose) {
qDebug() << "meshes =" << model.meshes.size(); qDebug() << "meshes =" << hfmModel.meshes.size();
} }
// count the mesh-parts // count the mesh-parts
int numParts = 0; int numParts = 0;
foreach (const HFMMesh& mesh, model.meshes) { foreach (const HFMMesh& mesh, hfmModel.meshes) {
numParts += mesh.parts.size(); numParts += mesh.parts.size();
} }
if (_verbose) { if (_verbose) {
@ -316,7 +316,7 @@ bool vhacd::VHACDUtil::computeVHACD(HFMModel& model,
int meshIndex = 0; int meshIndex = 0;
int validPartsFound = 0; int validPartsFound = 0;
foreach (const HFMMesh& mesh, model.meshes) { foreach (const HFMMesh& mesh, hfmModel.meshes) {
// find duplicate points // find duplicate points
int numDupes = 0; int numDupes = 0;
@ -337,7 +337,7 @@ bool vhacd::VHACDUtil::computeVHACD(HFMModel& model,
// each mesh has its own transform to move it to model-space // each mesh has its own transform to move it to model-space
std::vector<glm::vec3> vertices; std::vector<glm::vec3> vertices;
glm::mat4 totalTransform = model.offset * mesh.modelTransform; glm::mat4 totalTransform = hfmModel.offset * mesh.modelTransform;
foreach (glm::vec3 vertex, mesh.vertices) { foreach (glm::vec3 vertex, mesh.vertices) {
vertices.push_back(glm::vec3(totalTransform * glm::vec4(vertex, 1.0f))); vertices.push_back(glm::vec3(totalTransform * glm::vec4(vertex, 1.0f)));
} }

View file

@ -31,7 +31,7 @@ namespace vhacd {
void fattenMesh(const HFMMesh& mesh, const glm::mat4& modelOffset, HFMMesh& result) const; void fattenMesh(const HFMMesh& mesh, const glm::mat4& modelOffset, HFMMesh& result) const;
bool computeVHACD(HFMModel& model, bool computeVHACD(HFMModel& hfmModel,
VHACD::IVHACD::Parameters params, VHACD::IVHACD::Parameters params,
HFMModel& result, HFMModel& result,
float minimumMeshSize, float maximumMeshSize); float minimumMeshSize, float maximumMeshSize);

View file

@ -28,7 +28,7 @@ public:
VHACDUtilApp(int argc, char* argv[]); VHACDUtilApp(int argc, char* argv[]);
~VHACDUtilApp(); ~VHACDUtilApp();
bool writeOBJ(QString outFileName, HFMModel& model, bool outputCentimeters, int whichMeshPart = -1); bool writeOBJ(QString outFileName, HFMModel& hfmModel, bool outputCentimeters, int whichMeshPart = -1);
int getReturnCode() const { return _returnCode; } int getReturnCode() const { return _returnCode; }