Merge pull request #14338 from sabrina-shanman/hfm_geo2model

(case 19302) Rename HFMGeometry to HFMModel and adjust related variables
This commit is contained in:
John Conklin II 2018-11-05 15:00:06 -08:00 committed by GitHub
commit 4d74f7a0da
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
46 changed files with 557 additions and 557 deletions

View file

@ -84,7 +84,7 @@ void ScriptableAvatar::update(float deltatime) {
// Run animation
if (_animation && _animation->isLoaded() && _animation->getFrames().size() > 0 && !_bind.isNull() && _bind->isLoaded()) {
if (!_animSkeleton) {
_animSkeleton = std::make_shared<AnimSkeleton>(_bind->getGeometry());
_animSkeleton = std::make_shared<AnimSkeleton>(_bind->getHFMModel());
}
float currentFrame = _animationDetails.currentFrame + deltatime * _animationDetails.fps;
if (_animationDetails.loop || currentFrame < _animationDetails.lastFrame) {
@ -93,7 +93,7 @@ void ScriptableAvatar::update(float deltatime) {
}
_animationDetails.currentFrame = currentFrame;
const QVector<HFMJoint>& modelJoints = _bind->getGeometry().joints;
const QVector<HFMJoint>& modelJoints = _bind->getHFMModel().joints;
QStringList animationJointNames = _animation->getJointNames();
const int nJoints = modelJoints.size();
@ -113,7 +113,7 @@ void ScriptableAvatar::update(float deltatime) {
const QString& name = animationJointNames[i];
// As long as we need the model preRotations anyway, let's get the jointIndex from the bind skeleton rather than
// trusting the .fst (which is sometimes not updated to match changes to .fbx).
int mapping = _bind->getGeometry().getJointIndex(name);
int mapping = _bind->getHFMModel().getJointIndex(name);
if (mapping != -1 && !_maskedJoints.contains(name)) {
AnimPose floorPose = composeAnimPose(modelJoints[mapping], floorFrame.rotations[i], floorFrame.translations[i] * UNIT_SCALE);

View file

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

View file

@ -19,7 +19,7 @@
#include "ui/ModelsBrowser.h"
class HFMGeometry;
class HFMModel;
class ModelPackager : public QObject {
public:
@ -32,7 +32,7 @@ private:
bool editProperties();
bool zipModel();
void populateBasicMapping(QVariantHash& mapping, QString filename, const HFMGeometry& geometry);
void populateBasicMapping(QVariantHash& mapping, QString filename, const HFMModel& hfmModel);
void listTextures();
bool copyTextures(const QString& oldDir, const QDir& newDir);
@ -44,7 +44,7 @@ private:
QString _scriptDir;
QVariantHash _mapping;
std::unique_ptr<HFMGeometry> _geometry;
std::unique_ptr<HFMModel> _hfmModel;
QStringList _textures;
QStringList _scripts;
};

View file

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

View file

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

View file

@ -155,8 +155,8 @@ MyAvatar::MyAvatar(QThread* thread) :
});
connect(_skeletonModel.get(), &Model::rigReady, this, [this]() {
if (_shouldLoadScripts) {
auto geometry = getSkeletonModel()->getHFMGeometry();
qApp->loadAvatarScripts(geometry.scripts);
auto hfmModel = getSkeletonModel()->getHFMModel();
qApp->loadAvatarScripts(hfmModel.scripts);
_shouldLoadScripts = false;
}
// Load and convert old attachments to avatar entities
@ -2429,10 +2429,10 @@ void MyAvatar::attachmentDataToEntityProperties(const AttachmentData& data, Enti
void MyAvatar::initHeadBones() {
int neckJointIndex = -1;
if (_skeletonModel->isLoaded()) {
neckJointIndex = _skeletonModel->getHFMGeometry().neckJointIndex;
neckJointIndex = _skeletonModel->getHFMModel().neckJointIndex;
}
if (neckJointIndex == -1) {
neckJointIndex = (_skeletonModel->getHFMGeometry().headJointIndex - 1);
neckJointIndex = (_skeletonModel->getHFMModel().headJointIndex - 1);
if (neckJointIndex < 0) {
// return if the head is not even there. can't cauterize!!
return;
@ -2592,11 +2592,11 @@ void MyAvatar::postUpdate(float deltaTime, const render::ScenePointer& scene) {
if (_skeletonModel && _skeletonModel->isLoaded()) {
const Rig& rig = _skeletonModel->getRig();
const HFMGeometry& geometry = _skeletonModel->getHFMGeometry();
const HFMModel& hfmModel = _skeletonModel->getHFMModel();
for (int i = 0; i < rig.getJointStateCount(); i++) {
AnimPose jointPose;
rig.getAbsoluteJointPoseInRigFrame(i, jointPose);
const HFMJointShapeInfo& shapeInfo = geometry.joints[i].shapeInfo;
const HFMJointShapeInfo& shapeInfo = hfmModel.joints[i].shapeInfo;
const AnimPose pose = rigToWorldPose * jointPose;
for (size_t j = 0; j < shapeInfo.debugLines.size() / 2; j++) {
glm::vec3 pointA = pose.xformPoint(shapeInfo.debugLines[2 * j]);
@ -4012,7 +4012,7 @@ float MyAvatar::getSitStandStateChange() const {
}
QVector<QString> MyAvatar::getScriptUrls() {
QVector<QString> scripts = _skeletonModel->isLoaded() ? _skeletonModel->getHFMGeometry().scripts : QVector<QString>();
QVector<QString> scripts = _skeletonModel->isLoaded() ? _skeletonModel->getHFMModel().scripts : QVector<QString>();
return scripts;
}

View file

@ -90,7 +90,7 @@ static AnimPose computeHipsInSensorFrame(MyAvatar* myAvatar, bool isFlying) {
// Called within Model::simulate call, below.
void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
const HFMGeometry& geometry = getHFMGeometry();
const HFMModel& hfmModel = getHFMModel();
Head* head = _owningAvatar->getHead();
@ -268,19 +268,19 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
// pass detailed torso k-dops to rig.
int hipsJoint = _rig.indexOfJoint("Hips");
if (hipsJoint >= 0) {
params.hipsShapeInfo = geometry.joints[hipsJoint].shapeInfo;
params.hipsShapeInfo = hfmModel.joints[hipsJoint].shapeInfo;
}
int spineJoint = _rig.indexOfJoint("Spine");
if (spineJoint >= 0) {
params.spineShapeInfo = geometry.joints[spineJoint].shapeInfo;
params.spineShapeInfo = hfmModel.joints[spineJoint].shapeInfo;
}
int spine1Joint = _rig.indexOfJoint("Spine1");
if (spine1Joint >= 0) {
params.spine1ShapeInfo = geometry.joints[spine1Joint].shapeInfo;
params.spine1ShapeInfo = hfmModel.joints[spine1Joint].shapeInfo;
}
int spine2Joint = _rig.indexOfJoint("Spine2");
if (spine2Joint >= 0) {
params.spine2ShapeInfo = geometry.joints[spine2Joint].shapeInfo;
params.spine2ShapeInfo = hfmModel.joints[spine2Joint].shapeInfo;
}
_rig.updateFromControllerParameters(params, deltaTime);
@ -300,8 +300,8 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
eyeParams.eyeSaccade = head->getSaccade();
eyeParams.modelRotation = getRotation();
eyeParams.modelTranslation = getTranslation();
eyeParams.leftEyeJointIndex = geometry.leftEyeJointIndex;
eyeParams.rightEyeJointIndex = geometry.rightEyeJointIndex;
eyeParams.leftEyeJointIndex = hfmModel.leftEyeJointIndex;
eyeParams.rightEyeJointIndex = hfmModel.rightEyeJointIndex;
_rig.updateFromEyeParameters(eyeParams);

View file

@ -131,7 +131,7 @@ void CollisionPick::computeShapeInfo(const CollisionRegion& pick, ShapeInfo& sha
// should never fall in here when collision model not fully loaded
// TODO: assert that all geometries exist and are loaded
//assert(_model && _model->isLoaded() && _compoundShapeResource && _compoundShapeResource->isLoaded());
const HFMGeometry& collisionGeometry = resource->getHFMGeometry();
const HFMModel& collisionModel = resource->getHFMModel();
ShapeInfo::PointCollection& pointCollection = shapeInfo.getPointCollection();
pointCollection.clear();
@ -139,7 +139,7 @@ void CollisionPick::computeShapeInfo(const CollisionRegion& pick, ShapeInfo& sha
// the way OBJ files get read, each section under a "g" line is its own meshPart. We only expect
// to find one actual "mesh" (with one or more meshParts in it), but we loop over the meshes, just in case.
foreach (const HFMMesh& mesh, collisionGeometry.meshes) {
foreach (const HFMMesh& mesh, collisionModel.meshes) {
// each meshPart is a convex hull
foreach (const HFMMeshPart &meshPart, mesh.parts) {
pointCollection.push_back(QVector<glm::vec3>());
@ -206,7 +206,7 @@ void CollisionPick::computeShapeInfo(const CollisionRegion& pick, ShapeInfo& sha
// to the visual model and apply them to the collision model (without regard for the
// collision model's extents).
glm::vec3 scaleToFit = dimensions / resource->getHFMGeometry().getUnscaledMeshExtents().size();
glm::vec3 scaleToFit = dimensions / resource->getHFMModel().getUnscaledMeshExtents().size();
// multiply each point by scale
for (int32_t i = 0; i < pointCollection.size(); i++) {
for (int32_t j = 0; j < pointCollection[i].size(); j++) {
@ -216,11 +216,11 @@ void CollisionPick::computeShapeInfo(const CollisionRegion& pick, ShapeInfo& sha
}
shapeInfo.setParams(type, dimensions, resource->getURL().toString());
} else if (type >= SHAPE_TYPE_SIMPLE_HULL && type <= SHAPE_TYPE_STATIC_MESH) {
const HFMGeometry& hfmGeometry = resource->getHFMGeometry();
int numHFMMeshes = hfmGeometry.meshes.size();
const HFMModel& hfmModel = resource->getHFMModel();
int numHFMMeshes = hfmModel.meshes.size();
int totalNumVertices = 0;
for (int i = 0; i < numHFMMeshes; i++) {
const HFMMesh& mesh = hfmGeometry.meshes.at(i);
const HFMMesh& mesh = hfmModel.meshes.at(i);
totalNumVertices += mesh.vertices.size();
}
const int32_t MAX_VERTICES_PER_STATIC_MESH = 1e6;
@ -230,7 +230,7 @@ void CollisionPick::computeShapeInfo(const CollisionRegion& pick, ShapeInfo& sha
return;
}
auto& meshes = resource->getHFMGeometry().meshes;
auto& meshes = resource->getHFMModel().meshes;
int32_t numMeshes = (int32_t)(meshes.size());
const int MAX_ALLOWED_MESH_COUNT = 1000;

View file

@ -446,7 +446,7 @@ QVariant ModelOverlay::getProperty(const QString& property) {
if (property == "jointNames") {
if (_model && _model->isActive()) {
// note: going through Rig because Model::getJointNames() (which proxies to HFMGeometry) was always empty
// note: going through Rig because Model::getJointNames() (which proxies to HFMModel) was always empty
const Rig* rig = &(_model->getRig());
return mapJoints<QStringList, QString>([rig](int jointIndex) -> QString {
return rig->nameOfJoint(jointIndex);
@ -605,11 +605,11 @@ void ModelOverlay::animate() {
return;
}
QStringList animationJointNames = _animation->getGeometry().getJointNames();
auto& hfmJoints = _animation->getGeometry().joints;
QStringList animationJointNames = _animation->getHFMModel().getJointNames();
auto& hfmJoints = _animation->getHFMModel().joints;
auto& originalHFMJoints = _model->getHFMGeometry().joints;
auto& originalFbxIndices = _model->getHFMGeometry().jointIndices;
auto& originalHFMJoints = _model->getHFMModel().joints;
auto& originalHFMIndices = _model->getHFMModel().jointIndices;
const QVector<glm::quat>& rotations = frames[_lastKnownCurrentFrame].rotations;
const QVector<glm::vec3>& translations = frames[_lastKnownCurrentFrame].translations;
@ -628,9 +628,9 @@ void ModelOverlay::animate() {
} else if (index < animationJointNames.size()) {
QString jointName = hfmJoints[index].name;
if (originalFbxIndices.contains(jointName)) {
if (originalHFMIndices.contains(jointName)) {
// Making sure the joint names exist in the original model the animation is trying to apply onto. If they do, then remap and get its translation.
int remappedIndex = originalFbxIndices[jointName] - 1; // JointIndeces seem to always start from 1 and the found index is always 1 higher than actual.
int remappedIndex = originalHFMIndices[jointName] - 1; // JointIndeces seem to always start from 1 and the found index is always 1 higher than actual.
translationMat = glm::translate(originalHFMJoints[remappedIndex].translation);
}
}

View file

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

View file

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

View file

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

View file

@ -69,14 +69,14 @@ void AnimationReader::run() {
if (urlValid) {
// Parse the FBX directly from the QNetworkReply
HFMGeometry::Pointer fbxgeo;
HFMModel::Pointer hfmModel;
if (_url.path().toLower().endsWith(".fbx")) {
fbxgeo.reset(readFBX(_data, QVariantHash(), _url.path()));
hfmModel.reset(readFBX(_data, QVariantHash(), _url.path()));
} else {
QString errorStr("usupported format");
emit onError(299, errorStr);
}
emit onSuccess(fbxgeo);
emit onSuccess(hfmModel);
} else {
throw QString("url is invalid");
}
@ -88,7 +88,7 @@ void AnimationReader::run() {
}
bool Animation::isLoaded() const {
return _loaded && _geometry;
return _loaded && _hfmModel;
}
QStringList Animation::getJointNames() const {
@ -99,8 +99,8 @@ QStringList Animation::getJointNames() const {
return result;
}
QStringList names;
if (_geometry) {
foreach (const HFMJoint& joint, _geometry->joints) {
if (_hfmModel) {
foreach (const HFMJoint& joint, _hfmModel->joints) {
names.append(joint.name);
}
}
@ -114,30 +114,30 @@ QVector<HFMAnimationFrame> Animation::getFrames() const {
Q_RETURN_ARG(QVector<HFMAnimationFrame>, result));
return result;
}
if (_geometry) {
return _geometry->animationFrames;
if (_hfmModel) {
return _hfmModel->animationFrames;
} else {
return QVector<HFMAnimationFrame>();
}
}
const QVector<HFMAnimationFrame>& Animation::getFramesReference() const {
return _geometry->animationFrames;
return _hfmModel->animationFrames;
}
void Animation::downloadFinished(const QByteArray& data) {
// parse the animation/fbx file on a background thread.
AnimationReader* animationReader = new AnimationReader(_url, data);
connect(animationReader, SIGNAL(onSuccess(HFMGeometry::Pointer)), SLOT(animationParseSuccess(HFMGeometry::Pointer)));
connect(animationReader, SIGNAL(onSuccess(HFMModel::Pointer)), SLOT(animationParseSuccess(HFMModel::Pointer)));
connect(animationReader, SIGNAL(onError(int, QString)), SLOT(animationParseError(int, QString)));
QThreadPool::globalInstance()->start(animationReader);
}
void Animation::animationParseSuccess(HFMGeometry::Pointer geometry) {
void Animation::animationParseSuccess(HFMModel::Pointer hfmModel) {
qCDebug(animation) << "Animation parse success" << _url.toDisplayString();
_geometry = geometry;
_hfmModel = hfmModel;
finishedLoading(true);
}

View file

@ -66,7 +66,7 @@ public:
QString getType() const override { return "Animation"; }
const HFMGeometry& getGeometry() const { return *_geometry; }
const HFMModel& getHFMModel() const { return *_hfmModel; }
virtual bool isLoaded() const override;
@ -88,12 +88,12 @@ protected:
virtual void downloadFinished(const QByteArray& data) override;
protected slots:
void animationParseSuccess(HFMGeometry::Pointer geometry);
void animationParseSuccess(HFMModel::Pointer hfmModel);
void animationParseError(int error, QString str);
private:
HFMGeometry::Pointer _geometry;
HFMModel::Pointer _hfmModel;
};
/// Reads geometry in a worker thread.
@ -105,7 +105,7 @@ public:
virtual void run() override;
signals:
void onSuccess(HFMGeometry::Pointer geometry);
void onSuccess(HFMModel::Pointer hfmModel);
void onError(int error, QString str);
private:

View file

@ -260,14 +260,14 @@ void Rig::destroyAnimGraph() {
_rightEyeJointChildren.clear();
}
void Rig::initJointStates(const HFMGeometry& geometry, const glm::mat4& modelOffset) {
_geometryOffset = AnimPose(geometry.offset);
void Rig::initJointStates(const HFMModel& hfmModel, const glm::mat4& modelOffset) {
_geometryOffset = AnimPose(hfmModel.offset);
_invGeometryOffset = _geometryOffset.inverse();
_geometryToRigTransform = modelOffset * geometry.offset;
_geometryToRigTransform = modelOffset * hfmModel.offset;
_rigToGeometryTransform = glm::inverse(_geometryToRigTransform);
setModelOffset(modelOffset);
_animSkeleton = std::make_shared<AnimSkeleton>(geometry);
_animSkeleton = std::make_shared<AnimSkeleton>(hfmModel);
_internalPoseSet._relativePoses.clear();
_internalPoseSet._relativePoses = _animSkeleton->getRelativeDefaultPoses();
@ -293,24 +293,24 @@ void Rig::initJointStates(const HFMGeometry& geometry, const glm::mat4& modelOff
buildAbsoluteRigPoses(_animSkeleton->getRelativeDefaultPoses(), _absoluteDefaultPoses);
_rootJointIndex = geometry.rootJointIndex;
_leftEyeJointIndex = geometry.leftEyeJointIndex;
_rightEyeJointIndex = geometry.rightEyeJointIndex;
_leftHandJointIndex = geometry.leftHandJointIndex;
_leftElbowJointIndex = _leftHandJointIndex >= 0 ? geometry.joints.at(_leftHandJointIndex).parentIndex : -1;
_leftShoulderJointIndex = _leftElbowJointIndex >= 0 ? geometry.joints.at(_leftElbowJointIndex).parentIndex : -1;
_rightHandJointIndex = geometry.rightHandJointIndex;
_rightElbowJointIndex = _rightHandJointIndex >= 0 ? geometry.joints.at(_rightHandJointIndex).parentIndex : -1;
_rightShoulderJointIndex = _rightElbowJointIndex >= 0 ? geometry.joints.at(_rightElbowJointIndex).parentIndex : -1;
_rootJointIndex = hfmModel.rootJointIndex;
_leftEyeJointIndex = hfmModel.leftEyeJointIndex;
_rightEyeJointIndex = hfmModel.rightEyeJointIndex;
_leftHandJointIndex = hfmModel.leftHandJointIndex;
_leftElbowJointIndex = _leftHandJointIndex >= 0 ? hfmModel.joints.at(_leftHandJointIndex).parentIndex : -1;
_leftShoulderJointIndex = _leftElbowJointIndex >= 0 ? hfmModel.joints.at(_leftElbowJointIndex).parentIndex : -1;
_rightHandJointIndex = hfmModel.rightHandJointIndex;
_rightElbowJointIndex = _rightHandJointIndex >= 0 ? hfmModel.joints.at(_rightHandJointIndex).parentIndex : -1;
_rightShoulderJointIndex = _rightElbowJointIndex >= 0 ? hfmModel.joints.at(_rightElbowJointIndex).parentIndex : -1;
_leftEyeJointChildren = _animSkeleton->getChildrenOfJoint(geometry.leftEyeJointIndex);
_rightEyeJointChildren = _animSkeleton->getChildrenOfJoint(geometry.rightEyeJointIndex);
_leftEyeJointChildren = _animSkeleton->getChildrenOfJoint(hfmModel.leftEyeJointIndex);
_rightEyeJointChildren = _animSkeleton->getChildrenOfJoint(hfmModel.rightEyeJointIndex);
}
void Rig::reset(const HFMGeometry& geometry) {
_geometryOffset = AnimPose(geometry.offset);
void Rig::reset(const HFMModel& hfmModel) {
_geometryOffset = AnimPose(hfmModel.offset);
_invGeometryOffset = _geometryOffset.inverse();
_animSkeleton = std::make_shared<AnimSkeleton>(geometry);
_animSkeleton = std::make_shared<AnimSkeleton>(hfmModel);
_internalPoseSet._relativePoses.clear();
_internalPoseSet._relativePoses = _animSkeleton->getRelativeDefaultPoses();
@ -338,18 +338,18 @@ void Rig::reset(const HFMGeometry& geometry) {
buildAbsoluteRigPoses(_animSkeleton->getRelativeDefaultPoses(), _absoluteDefaultPoses);
_rootJointIndex = geometry.rootJointIndex;
_leftEyeJointIndex = geometry.leftEyeJointIndex;
_rightEyeJointIndex = geometry.rightEyeJointIndex;
_leftHandJointIndex = geometry.leftHandJointIndex;
_leftElbowJointIndex = _leftHandJointIndex >= 0 ? geometry.joints.at(_leftHandJointIndex).parentIndex : -1;
_leftShoulderJointIndex = _leftElbowJointIndex >= 0 ? geometry.joints.at(_leftElbowJointIndex).parentIndex : -1;
_rightHandJointIndex = geometry.rightHandJointIndex;
_rightElbowJointIndex = _rightHandJointIndex >= 0 ? geometry.joints.at(_rightHandJointIndex).parentIndex : -1;
_rightShoulderJointIndex = _rightElbowJointIndex >= 0 ? geometry.joints.at(_rightElbowJointIndex).parentIndex : -1;
_rootJointIndex = hfmModel.rootJointIndex;
_leftEyeJointIndex = hfmModel.leftEyeJointIndex;
_rightEyeJointIndex = hfmModel.rightEyeJointIndex;
_leftHandJointIndex = hfmModel.leftHandJointIndex;
_leftElbowJointIndex = _leftHandJointIndex >= 0 ? hfmModel.joints.at(_leftHandJointIndex).parentIndex : -1;
_leftShoulderJointIndex = _leftElbowJointIndex >= 0 ? hfmModel.joints.at(_leftElbowJointIndex).parentIndex : -1;
_rightHandJointIndex = hfmModel.rightHandJointIndex;
_rightElbowJointIndex = _rightHandJointIndex >= 0 ? hfmModel.joints.at(_rightHandJointIndex).parentIndex : -1;
_rightShoulderJointIndex = _rightElbowJointIndex >= 0 ? hfmModel.joints.at(_rightElbowJointIndex).parentIndex : -1;
_leftEyeJointChildren = _animSkeleton->getChildrenOfJoint(geometry.leftEyeJointIndex);
_rightEyeJointChildren = _animSkeleton->getChildrenOfJoint(geometry.rightEyeJointIndex);
_leftEyeJointChildren = _animSkeleton->getChildrenOfJoint(hfmModel.leftEyeJointIndex);
_rightEyeJointChildren = _animSkeleton->getChildrenOfJoint(hfmModel.rightEyeJointIndex);
if (!_animGraphURL.isEmpty()) {
_animNode.reset();
@ -1938,7 +1938,7 @@ void Rig::copyJointsIntoJointData(QVector<JointData>& jointDataVec) const {
data.rotationIsDefaultPose = isEqual(data.rotation, defaultAbsRot);
// translations are in relative frame but scaled so that they are in meters,
// instead of geometry units.
// instead of model units.
glm::vec3 defaultRelTrans = _geometryOffset.scale() * _animSkeleton->getRelativeDefaultPose(i).trans();
data.translation = _geometryOffset.scale() * (!_sendNetworkNode ? _internalPoseSet._relativePoses[i].trans() : _networkPoseSet._relativePoses[i].trans());
data.translationIsDefaultPose = isEqual(data.translation, defaultRelTrans);
@ -1963,7 +1963,7 @@ void Rig::copyJointsFromJointData(const QVector<JointData>& jointDataVec) {
return;
}
// make a vector of rotations in absolute-geometry-frame
// make a vector of rotations in absolute-model-frame
std::vector<glm::quat> rotations;
rotations.reserve(numJoints);
const glm::quat rigToGeometryRot(glmExtractRotation(_rigToGeometryTransform));
@ -1972,7 +1972,7 @@ void Rig::copyJointsFromJointData(const QVector<JointData>& jointDataVec) {
if (data.rotationIsDefaultPose) {
rotations.push_back(absoluteDefaultPoses[i].rot());
} else {
// JointData rotations are in absolute rig-frame so we rotate them to absolute geometry-frame
// JointData rotations are in absolute rig-frame so we rotate them to absolute model-frame
rotations.push_back(rigToGeometryRot * data.rotation);
}
}
@ -2008,7 +2008,7 @@ void Rig::computeExternalPoses(const glm::mat4& modelOffsetMat) {
}
void Rig::computeAvatarBoundingCapsule(
const HFMGeometry& geometry,
const HFMModel& hfmModel,
float& radiusOut,
float& heightOut,
glm::vec3& localOffsetOut) const {
@ -2041,7 +2041,7 @@ void Rig::computeAvatarBoundingCapsule(
// from the head to the hips when computing the rest of the bounding capsule.
int index = indexOfJoint("Head");
while (index != -1) {
const HFMJointShapeInfo& shapeInfo = geometry.joints.at(index).shapeInfo;
const HFMJointShapeInfo& shapeInfo = hfmModel.joints.at(index).shapeInfo;
AnimPose pose = _animSkeleton->getAbsoluteDefaultPose(index);
if (shapeInfo.points.size() > 0) {
for (auto& point : shapeInfo.points) {

View file

@ -122,8 +122,8 @@ public:
void overrideRoleAnimation(const QString& role, const QString& url, float fps, bool loop, float firstFrame, float lastFrame);
void restoreRoleAnimation(const QString& role);
void initJointStates(const HFMGeometry& geometry, const glm::mat4& modelOffset);
void reset(const HFMGeometry& geometry);
void initJointStates(const HFMModel& hfmModel, const glm::mat4& modelOffset);
void reset(const HFMModel& hfmModel);
bool jointStatesEmpty();
int getJointStateCount() const;
int indexOfJoint(const QString& jointName) const;
@ -210,7 +210,7 @@ public:
void copyJointsFromJointData(const QVector<JointData>& jointDataVec);
void computeExternalPoses(const glm::mat4& modelOffsetMat);
void computeAvatarBoundingCapsule(const HFMGeometry& geometry, float& radiusOut, float& heightOut, glm::vec3& offsetOut) const;
void computeAvatarBoundingCapsule(const HFMModel& hfmModel, float& radiusOut, float& heightOut, glm::vec3& offsetOut) const;
void setEnableInverseKinematics(bool enable);
void setEnableAnimations(bool enable);

View file

@ -1311,7 +1311,7 @@ glm::quat Avatar::getAbsoluteJointRotationInObjectFrame(int index) const {
case CAMERA_MATRIX_INDEX: {
glm::quat rotation;
if (_skeletonModel && _skeletonModel->isActive()) {
int headJointIndex = _skeletonModel->getHFMGeometry().headJointIndex;
int headJointIndex = _skeletonModel->getHFMModel().headJointIndex;
if (headJointIndex >= 0) {
_skeletonModel->getAbsoluteJointRotationInRigFrame(headJointIndex, rotation);
}
@ -1360,7 +1360,7 @@ glm::vec3 Avatar::getAbsoluteJointTranslationInObjectFrame(int index) const {
case CAMERA_MATRIX_INDEX: {
glm::vec3 translation;
if (_skeletonModel && _skeletonModel->isActive()) {
int headJointIndex = _skeletonModel->getHFMGeometry().headJointIndex;
int headJointIndex = _skeletonModel->getHFMModel().headJointIndex;
if (headJointIndex >= 0) {
_skeletonModel->getAbsoluteJointTranslationInRigFrame(headJointIndex, translation);
}
@ -1416,7 +1416,7 @@ void Avatar::withValidJointIndicesCache(std::function<void()> const& worker) con
if (!_modelJointsCached) {
_modelJointIndicesCache.clear();
if (_skeletonModel && _skeletonModel->isActive()) {
_modelJointIndicesCache = _skeletonModel->getHFMGeometry().jointIndices;
_modelJointIndicesCache = _skeletonModel->getHFMModel().jointIndices;
_modelJointsCached = true;
}
}

View file

@ -54,9 +54,9 @@ void SkeletonModel::setTextures(const QVariantMap& textures) {
}
void SkeletonModel::initJointStates() {
const HFMGeometry& geometry = getHFMGeometry();
const HFMModel& hfmModel = getHFMModel();
glm::mat4 modelOffset = glm::scale(_scale) * glm::translate(_offset);
_rig.initJointStates(geometry, modelOffset);
_rig.initJointStates(hfmModel, modelOffset);
{
// initialize _jointData with proper values for default joints
@ -66,7 +66,7 @@ void SkeletonModel::initJointStates() {
}
// Determine the default eye position for avatar scale = 1.0
int headJointIndex = geometry.headJointIndex;
int headJointIndex = hfmModel.headJointIndex;
if (0 > headJointIndex || headJointIndex >= _rig.getJointStateCount()) {
qCWarning(avatars_renderer) << "Bad head joint! Got:" << headJointIndex << "jointCount:" << _rig.getJointStateCount();
}
@ -74,7 +74,7 @@ void SkeletonModel::initJointStates() {
getEyeModelPositions(leftEyePosition, rightEyePosition);
glm::vec3 midEyePosition = (leftEyePosition + rightEyePosition) / 2.0f;
int rootJointIndex = geometry.rootJointIndex;
int rootJointIndex = hfmModel.rootJointIndex;
glm::vec3 rootModelPosition;
getJointPosition(rootJointIndex, rootModelPosition);
@ -96,7 +96,7 @@ void SkeletonModel::initJointStates() {
// Called within Model::simulate call, below.
void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
assert(!_owningAvatar->isMyAvatar());
const HFMGeometry& geometry = getHFMGeometry();
const HFMModel& hfmModel = getHFMModel();
Head* head = _owningAvatar->getHead();
@ -124,7 +124,7 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
// If the head is not positioned, updateEyeJoints won't get the math right
glm::quat headOrientation;
_rig.getJointRotation(geometry.headJointIndex, headOrientation);
_rig.getJointRotation(hfmModel.headJointIndex, headOrientation);
glm::vec3 eulers = safeEulerAngles(headOrientation);
head->setBasePitch(glm::degrees(-eulers.x));
head->setBaseYaw(glm::degrees(eulers.y));
@ -135,8 +135,8 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
eyeParams.eyeSaccade = glm::vec3(0.0f);
eyeParams.modelRotation = getRotation();
eyeParams.modelTranslation = getTranslation();
eyeParams.leftEyeJointIndex = geometry.leftEyeJointIndex;
eyeParams.rightEyeJointIndex = geometry.rightEyeJointIndex;
eyeParams.leftEyeJointIndex = hfmModel.leftEyeJointIndex;
eyeParams.rightEyeJointIndex = hfmModel.rightEyeJointIndex;
_rig.updateFromEyeParameters(eyeParams);
}
@ -259,45 +259,45 @@ bool SkeletonModel::getRightShoulderPosition(glm::vec3& position) const {
}
bool SkeletonModel::getHeadPosition(glm::vec3& headPosition) const {
return isActive() && getJointPositionInWorldFrame(getHFMGeometry().headJointIndex, headPosition);
return isActive() && getJointPositionInWorldFrame(getHFMModel().headJointIndex, headPosition);
}
bool SkeletonModel::getNeckPosition(glm::vec3& neckPosition) const {
return isActive() && getJointPositionInWorldFrame(getHFMGeometry().neckJointIndex, neckPosition);
return isActive() && getJointPositionInWorldFrame(getHFMModel().neckJointIndex, neckPosition);
}
bool SkeletonModel::getLocalNeckPosition(glm::vec3& neckPosition) const {
return isActive() && getJointPosition(getHFMGeometry().neckJointIndex, neckPosition);
return isActive() && getJointPosition(getHFMModel().neckJointIndex, neckPosition);
}
bool SkeletonModel::getEyeModelPositions(glm::vec3& firstEyePosition, glm::vec3& secondEyePosition) const {
if (!isActive()) {
return false;
}
const HFMGeometry& geometry = getHFMGeometry();
const HFMModel& hfmModel = getHFMModel();
if (getJointPosition(geometry.leftEyeJointIndex, firstEyePosition) &&
getJointPosition(geometry.rightEyeJointIndex, secondEyePosition)) {
if (getJointPosition(hfmModel.leftEyeJointIndex, firstEyePosition) &&
getJointPosition(hfmModel.rightEyeJointIndex, secondEyePosition)) {
return true;
}
// no eye joints; try to estimate based on head/neck joints
glm::vec3 neckPosition, headPosition;
if (getJointPosition(geometry.neckJointIndex, neckPosition) &&
getJointPosition(geometry.headJointIndex, headPosition)) {
if (getJointPosition(hfmModel.neckJointIndex, neckPosition) &&
getJointPosition(hfmModel.headJointIndex, headPosition)) {
const float EYE_PROPORTION = 0.6f;
glm::vec3 baseEyePosition = glm::mix(neckPosition, headPosition, EYE_PROPORTION);
glm::quat headRotation;
getJointRotation(geometry.headJointIndex, headRotation);
getJointRotation(hfmModel.headJointIndex, headRotation);
const float EYES_FORWARD = 0.25f;
const float EYE_SEPARATION = 0.1f;
float headHeight = glm::distance(neckPosition, headPosition);
firstEyePosition = baseEyePosition + headRotation * glm::vec3(EYE_SEPARATION, 0.0f, EYES_FORWARD) * headHeight;
secondEyePosition = baseEyePosition + headRotation * glm::vec3(-EYE_SEPARATION, 0.0f, EYES_FORWARD) * headHeight;
return true;
} else if (getJointPosition(geometry.headJointIndex, headPosition)) {
} else if (getJointPosition(hfmModel.headJointIndex, headPosition)) {
glm::vec3 baseEyePosition = headPosition;
glm::quat headRotation;
getJointRotation(geometry.headJointIndex, headRotation);
getJointRotation(hfmModel.headJointIndex, headRotation);
const float EYES_FORWARD_HEAD_ONLY = 0.30f;
const float EYE_SEPARATION = 0.1f;
firstEyePosition = baseEyePosition + headRotation * glm::vec3(EYE_SEPARATION, 0.0f, EYES_FORWARD_HEAD_ONLY);
@ -330,15 +330,15 @@ void SkeletonModel::computeBoundingShape() {
return;
}
const HFMGeometry& geometry = getHFMGeometry();
if (geometry.joints.isEmpty() || geometry.rootJointIndex == -1) {
const HFMModel& hfmModel = getHFMModel();
if (hfmModel.joints.isEmpty() || hfmModel.rootJointIndex == -1) {
// rootJointIndex == -1 if the avatar model has no skeleton
return;
}
float radius, height;
glm::vec3 offset;
_rig.computeAvatarBoundingCapsule(geometry, radius, height, offset);
_rig.computeAvatarBoundingCapsule(hfmModel, radius, height, offset);
float invScale = 1.0f / _owningAvatar->getModelScale();
_boundingCapsuleRadius = invScale * radius;
_boundingCapsuleHeight = invScale * height;
@ -369,7 +369,7 @@ void SkeletonModel::renderBoundingCollisionShapes(RenderArgs* args, gpu::Batch&
}
bool SkeletonModel::hasSkeleton() {
return isActive() ? getHFMGeometry().rootJointIndex != -1 : false;
return isActive() ? getHFMModel().rootJointIndex != -1 : false;
}
void SkeletonModel::onInvalidate() {

View file

@ -41,10 +41,10 @@ public:
void updateAttitude(const glm::quat& orientation);
/// Returns the index of the left hand joint, or -1 if not found.
int getLeftHandJointIndex() const { return isActive() ? getHFMGeometry().leftHandJointIndex : -1; }
int getLeftHandJointIndex() const { return isActive() ? getHFMModel().leftHandJointIndex : -1; }
/// Returns the index of the right hand joint, or -1 if not found.
int getRightHandJointIndex() const { return isActive() ? getHFMGeometry().rightHandJointIndex : -1; }
int getRightHandJointIndex() const { return isActive() ? getHFMModel().rightHandJointIndex : -1; }
bool getLeftGrabPosition(glm::vec3& position) const;
bool getRightGrabPosition(glm::vec3& position) const;

View file

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

View file

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

View file

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

View file

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

View file

@ -268,7 +268,7 @@ EntityItemProperties RenderableModelEntityItem::getProperties(const EntityProper
if (model->isLoaded()) {
// TODO: improve naturalDimensions in the future,
// for now we've added this hack for setting natural dimensions of models
Extents meshExtents = model->getHFMGeometry().getUnscaledMeshExtents();
Extents meshExtents = model->getHFMModel().getUnscaledMeshExtents();
properties.setNaturalDimensions(meshExtents.maximum - meshExtents.minimum);
properties.calculateNaturalPosition(meshExtents.minimum, meshExtents.maximum);
}
@ -403,7 +403,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
// should never fall in here when collision model not fully loaded
// TODO: assert that all geometries exist and are loaded
//assert(_model && _model->isLoaded() && _compoundShapeResource && _compoundShapeResource->isLoaded());
const HFMGeometry& collisionGeometry = _compoundShapeResource->getHFMGeometry();
const HFMModel& collisionGeometry = _compoundShapeResource->getHFMModel();
ShapeInfo::PointCollection& pointCollection = shapeInfo.getPointCollection();
pointCollection.clear();
@ -478,7 +478,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
// to the visual model and apply them to the collision model (without regard for the
// collision model's extents).
glm::vec3 scaleToFit = dimensions / model->getHFMGeometry().getUnscaledMeshExtents().size();
glm::vec3 scaleToFit = dimensions / model->getHFMModel().getUnscaledMeshExtents().size();
// multiply each point by scale before handing the point-set off to the physics engine.
// also determine the extents of the collision model.
glm::vec3 registrationOffset = dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint());
@ -498,12 +498,12 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
// compute meshPart local transforms
QVector<glm::mat4> localTransforms;
const HFMGeometry& hfmGeometry = model->getHFMGeometry();
int numHFMMeshes = hfmGeometry.meshes.size();
const HFMModel& hfmModel = model->getHFMModel();
int numHFMMeshes = hfmModel.meshes.size();
int totalNumVertices = 0;
glm::mat4 invRegistraionOffset = glm::translate(dimensions * (getRegistrationPoint() - ENTITY_ITEM_DEFAULT_REGISTRATION_POINT));
for (int i = 0; i < numHFMMeshes; i++) {
const HFMMesh& mesh = hfmGeometry.meshes.at(i);
const HFMMesh& mesh = hfmModel.meshes.at(i);
if (mesh.clusters.size() > 0) {
const HFMCluster& cluster = mesh.clusters.at(0);
auto jointMatrix = model->getRig().getJointTransform(cluster.jointIndex);
@ -524,7 +524,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
std::vector<std::shared_ptr<const graphics::Mesh>> meshes;
if (type == SHAPE_TYPE_SIMPLE_COMPOUND) {
auto& hfmMeshes = _compoundShapeResource->getHFMGeometry().meshes;
auto& hfmMeshes = _compoundShapeResource->getHFMModel().meshes;
meshes.reserve(hfmMeshes.size());
for (auto& hfmMesh : hfmMeshes) {
meshes.push_back(hfmMesh._mesh);
@ -755,7 +755,7 @@ int RenderableModelEntityItem::avatarJointIndex(int modelJointIndex) {
bool RenderableModelEntityItem::contains(const glm::vec3& point) const {
auto model = getModel();
if (EntityItem::contains(point) && model && _compoundShapeResource && _compoundShapeResource->isLoaded()) {
return _compoundShapeResource->getHFMGeometry().convexHullContains(worldToEntity(point));
return _compoundShapeResource->getHFMModel().convexHullContains(worldToEntity(point));
}
return false;
@ -1159,11 +1159,11 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) {
return;
}
QStringList animationJointNames = _animation->getGeometry().getJointNames();
auto& hfmJoints = _animation->getGeometry().joints;
QStringList animationJointNames = _animation->getHFMModel().getJointNames();
auto& hfmJoints = _animation->getHFMModel().joints;
auto& originalHFMJoints = _model->getHFMGeometry().joints;
auto& originalHFMIndices = _model->getHFMGeometry().jointIndices;
auto& originalHFMJoints = _model->getHFMModel().joints;
auto& originalHFMIndices = _model->getHFMModel().jointIndices;
bool allowTranslation = entity->getAnimationAllowTranslation();

View file

@ -231,7 +231,7 @@ public:
bool needTangentSpace() const;
};
/// A single mesh (with optional blendshapes) extracted from an FBX document.
/// A single mesh (with optional blendshapes).
class HFMMesh {
public:
@ -277,7 +277,7 @@ public:
* @property {Quat[]} rotations
* @property {Vec3[]} translations
*/
/// A single animation frame extracted from an FBX document.
/// A single animation frame.
class HFMAnimationFrame {
public:
QVector<glm::quat> rotations;
@ -305,10 +305,10 @@ public:
Q_DECLARE_METATYPE(HFMAnimationFrame)
Q_DECLARE_METATYPE(QVector<HFMAnimationFrame>)
/// A set of meshes extracted from an FBX document.
class HFMGeometry {
/// The runtime model format.
class HFMModel {
public:
using Pointer = std::shared_ptr<HFMGeometry>;
using Pointer = std::shared_ptr<HFMModel>;
QString originalURL;
QString author;
@ -368,7 +368,7 @@ public:
QList<QString> blendshapeChannelNames;
};
Q_DECLARE_METATYPE(HFMGeometry)
Q_DECLARE_METATYPE(HFMGeometry::Pointer)
Q_DECLARE_METATYPE(HFMModel)
Q_DECLARE_METATYPE(HFMModel::Pointer)
#endif // hifi_FBX_h_

View file

@ -40,9 +40,9 @@
using namespace std;
int HFMGeometryPointerMetaTypeId = qRegisterMetaType<HFMGeometry::Pointer>();
int HFMModelPointerMetaTypeId = qRegisterMetaType<HFMModel::Pointer>();
QStringList HFMGeometry::getJointNames() const {
QStringList HFMModel::getJointNames() const {
QStringList names;
foreach (const HFMJoint& joint, joints) {
names.append(joint.name);
@ -50,7 +50,7 @@ QStringList HFMGeometry::getJointNames() const {
return names;
}
bool HFMGeometry::hasBlendedMeshes() const {
bool HFMModel::hasBlendedMeshes() const {
if (!meshes.isEmpty()) {
foreach (const HFMMesh& mesh, meshes) {
if (!mesh.blendshapes.isEmpty()) {
@ -61,7 +61,7 @@ bool HFMGeometry::hasBlendedMeshes() const {
return false;
}
Extents HFMGeometry::getUnscaledMeshExtents() const {
Extents HFMModel::getUnscaledMeshExtents() const {
const Extents& extents = meshExtents;
// even though our caller asked for "unscaled" we need to include any fst scaling, translation, and rotation, which
@ -74,7 +74,7 @@ Extents HFMGeometry::getUnscaledMeshExtents() const {
}
// TODO: Move to graphics::Mesh when Sam's ready
bool HFMGeometry::convexHullContains(const glm::vec3& point) const {
bool HFMModel::convexHullContains(const glm::vec3& point) const {
if (!getUnscaledMeshExtents().containsPoint(point)) {
return false;
}
@ -124,16 +124,16 @@ bool HFMGeometry::convexHullContains(const glm::vec3& point) const {
return false;
}
QString HFMGeometry::getModelNameOfMesh(int meshIndex) const {
QString HFMModel::getModelNameOfMesh(int meshIndex) const {
if (meshIndicesToModelNames.contains(meshIndex)) {
return meshIndicesToModelNames.value(meshIndex);
}
return QString();
}
int hfmGeometryMetaTypeId = qRegisterMetaType<HFMGeometry>();
int hfmModelMetaTypeId = qRegisterMetaType<HFMModel>();
int hfmAnimationFrameMetaTypeId = qRegisterMetaType<HFMAnimationFrame>();
int hfmAnimationFrameVectorMetaTypeId = qRegisterMetaType<QVector<HFMAnimationFrame> >();
int hfmAnimationFrameVectorMetaTypeId = qRegisterMetaType<QVector<HFMAnimationFrame>>();
glm::vec3 parseVec3(const QString& string) {
@ -264,17 +264,17 @@ public:
};
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;
QVector<QString> visitedNodes; // Used to prevent following a cycle
while (!nodeID.isNull()) {
visitedNodes.append(nodeID); // Append each node we visit
const FBXModel& model = models.value(nodeID);
globalTransform = glm::translate(model.translation) * model.preTransform * glm::mat4_cast(model.preRotation *
model.rotation * model.postRotation) * model.postTransform * globalTransform;
if (model.hasGeometricOffset) {
glm::mat4 geometricOffset = createMatFromScaleQuatAndPos(model.geometricScaling, model.geometricRotation, model.geometricTranslation);
const FBXModel& fbxModel = fbxModels.value(nodeID);
globalTransform = glm::translate(fbxModel.translation) * fbxModel.preTransform * glm::mat4_cast(fbxModel.preRotation *
fbxModel.rotation * fbxModel.postRotation) * fbxModel.postTransform * globalTransform;
if (fbxModel.hasGeometricOffset) {
glm::mat4 geometricOffset = createMatFromScaleQuatAndPos(fbxModel.geometricScaling, fbxModel.geometricRotation, fbxModel.geometricTranslation);
globalTransform = globalTransform * geometricOffset;
}
@ -290,7 +290,7 @@ glm::mat4 getGlobalTransform(const QMultiMap<QString, QString>& _connectionParen
continue;
}
if (models.contains(parentID)) {
if (fbxModels.contains(parentID)) {
nodeID = parentID;
break;
}
@ -329,7 +329,7 @@ public:
};
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)) {
modelIDs.append(parentID);
remainingModels.remove(parentID);
@ -337,10 +337,10 @@ void appendModelIDs(const QString& parentID, const QMultiMap<QString, QString>&
int parentIndex = isRootNode ? -1 : modelIDs.size() - 1;
foreach (const QString& childID, connectionChildMap.values(parentID)) {
if (remainingModels.contains(childID)) {
FBXModel& model = models[childID];
if (model.parentIndex == -1) {
model.parentIndex = parentIndex;
appendModelIDs(childID, connectionChildMap, models, remainingModels, modelIDs);
FBXModel& fbxModel = fbxModels[childID];
if (fbxModel.parentIndex == -1) {
fbxModel.parentIndex = parentIndex;
appendModelIDs(childID, connectionChildMap, fbxModels, remainingModels, modelIDs);
}
}
}
@ -403,7 +403,7 @@ static void createTangents(const HFMMesh& mesh, bool generateFromTexCoords,
setTangents(mesh, accessor, part.triangleIndices.at(i + 2), part.triangleIndices.at(i), vertices, normals, tangents);
}
if ((part.triangleIndices.size() % 3) != 0) {
qCDebug(modelformat) << "Error in extractHFMGeometry part.triangleIndices.size() is not divisible by three ";
qCDebug(modelformat) << "Error in extractHFMModel part.triangleIndices.size() is not divisible by three ";
}
}
}
@ -503,7 +503,7 @@ void addBlendshapes(const ExtractedBlendshape& extracted, const QList<WeightedIn
}
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;
QVector<QString> visitedNodes; // Used to prevent following a cycle
forever {
@ -515,7 +515,7 @@ QString getTopModelID(const QMultiMap<QString, QString>& connectionParentMap,
continue;
}
if (models.contains(parentID)) {
if (fbxModels.contains(parentID)) {
topID = parentID;
goto outerContinue;
}
@ -615,7 +615,7 @@ QByteArray fileOnUrl(const QByteArray& filepath, const QString& url) {
return filepath.mid(filepath.lastIndexOf('/') + 1);
}
HFMGeometry* FBXReader::extractHFMGeometry(const QVariantHash& mapping, const QString& url) {
HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString& url) {
const FBXNode& node = _rootNode;
QMap<QString, ExtractedMesh> meshes;
QHash<QString, QString> modelIDsToNames;
@ -624,7 +624,7 @@ HFMGeometry* FBXReader::extractHFMGeometry(const QVariantHash& mapping, const QS
QVector<ExtractedBlendshape> blendshapes;
QHash<QString, FBXModel> models;
QHash<QString, FBXModel> fbxModels;
QHash<QString, Cluster> clusters;
QHash<QString, AnimationCurve> animationCurves;
@ -689,10 +689,10 @@ HFMGeometry* FBXReader::extractHFMGeometry(const QVariantHash& mapping, const QS
#if defined(DEBUG_FBXREADER)
int unknown = 0;
#endif
HFMGeometry* geometryPtr = new HFMGeometry;
HFMGeometry& geometry = *geometryPtr;
HFMModel* hfmModelPtr = new HFMModel;
HFMModel& hfmModel = *hfmModelPtr;
geometry.originalURL = url;
hfmModel.originalURL = url;
float unitScaleFactor = 1.0f;
glm::vec3 ambientColor;
@ -708,7 +708,7 @@ HFMGeometry* FBXReader::extractHFMGeometry(const QVariantHash& mapping, const QS
if (subobject.name == "MetaData") {
foreach (const FBXNode& subsubobject, subobject.children) {
if (subsubobject.name == "Author") {
geometry.author = subsubobject.properties.at(0).toString();
hfmModel.author = subsubobject.properties.at(0).toString();
}
}
} else if (subobject.name == "Properties70") {
@ -716,7 +716,7 @@ HFMGeometry* FBXReader::extractHFMGeometry(const QVariantHash& mapping, const QS
static const QVariant APPLICATION_NAME = QVariant(QByteArray("Original|ApplicationName"));
if (subsubobject.name == "P" && subsubobject.properties.size() >= 5 &&
subsubobject.properties.at(0) == APPLICATION_NAME) {
geometry.applicationName = subsubobject.properties.at(4).toString();
hfmModel.applicationName = subsubobject.properties.at(4).toString();
}
}
}
@ -814,7 +814,7 @@ HFMGeometry* FBXReader::extractHFMGeometry(const QVariantHash& mapping, const QS
glm::vec3 geometricRotation;
glm::vec3 rotationMin, rotationMax;
FBXModel model = { name, -1, glm::vec3(), glm::mat4(), glm::quat(), glm::quat(), glm::quat(),
FBXModel fbxModel = { name, -1, glm::vec3(), glm::mat4(), glm::quat(), glm::quat(), glm::quat(),
glm::mat4(), glm::vec3(), glm::vec3(),
false, glm::vec3(), glm::quat(), glm::vec3(1.0f) };
ExtractedMesh* mesh = NULL;
@ -963,27 +963,27 @@ HFMGeometry* FBXReader::extractHFMGeometry(const QVariantHash& mapping, const QS
}
// see FBX documentation, http://download.autodesk.com/us/fbx/20112/FBX_SDK_HELP/index.html
model.translation = translation;
fbxModel.translation = translation;
model.preTransform = glm::translate(rotationOffset) * glm::translate(rotationPivot);
model.preRotation = glm::quat(glm::radians(preRotation));
model.rotation = glm::quat(glm::radians(rotation));
model.postRotation = glm::inverse(glm::quat(glm::radians(postRotation)));
model.postTransform = glm::translate(-rotationPivot) * glm::translate(scaleOffset) *
fbxModel.preTransform = glm::translate(rotationOffset) * glm::translate(rotationPivot);
fbxModel.preRotation = glm::quat(glm::radians(preRotation));
fbxModel.rotation = glm::quat(glm::radians(rotation));
fbxModel.postRotation = glm::inverse(glm::quat(glm::radians(postRotation)));
fbxModel.postTransform = glm::translate(-rotationPivot) * glm::translate(scaleOffset) *
glm::translate(scalePivot) * glm::scale(scale) * glm::translate(-scalePivot);
// NOTE: angles from the FBX file are in degrees
// so we convert them to radians for the FBXModel class
model.rotationMin = glm::radians(glm::vec3(rotationMinX ? rotationMin.x : -180.0f,
fbxModel.rotationMin = glm::radians(glm::vec3(rotationMinX ? rotationMin.x : -180.0f,
rotationMinY ? rotationMin.y : -180.0f, rotationMinZ ? rotationMin.z : -180.0f));
model.rotationMax = glm::radians(glm::vec3(rotationMaxX ? rotationMax.x : 180.0f,
fbxModel.rotationMax = glm::radians(glm::vec3(rotationMaxX ? rotationMax.x : 180.0f,
rotationMaxY ? rotationMax.y : 180.0f, rotationMaxZ ? rotationMax.z : 180.0f));
model.hasGeometricOffset = hasGeometricOffset;
model.geometricTranslation = geometricTranslation;
model.geometricRotation = glm::quat(glm::radians(geometricRotation));
model.geometricScaling = geometricScaling;
fbxModel.hasGeometricOffset = hasGeometricOffset;
fbxModel.geometricTranslation = geometricTranslation;
fbxModel.geometricRotation = glm::quat(glm::radians(geometricRotation));
fbxModel.geometricScaling = geometricScaling;
models.insert(getID(object.properties), model);
fbxModels.insert(getID(object.properties), fbxModel);
} else if (object.name == "Texture") {
TextureParam tex;
foreach (const FBXNode& subobject, object.children) {
@ -1307,7 +1307,7 @@ HFMGeometry* FBXReader::extractHFMGeometry(const QVariantHash& mapping, const QS
name = name.mid(name.lastIndexOf('.') + 1);
}
QString id = getID(object.properties);
geometry.blendshapeChannelNames << name;
hfmModel.blendshapeChannelNames << name;
foreach (const WeightedIndex& index, blendshapeIndices.values(name)) {
blendshapeChannelIndices.insert(id, index);
}
@ -1454,26 +1454,26 @@ HFMGeometry* FBXReader::extractHFMGeometry(const QVariantHash& mapping, const QS
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(),
mapping.value("ry").toFloat(), mapping.value("rz").toFloat())));
geometry.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) *
glm::scale(glm::vec3(offsetScale, offsetScale, offsetScale));
// get the list of models in depth-first traversal order
QVector<QString> modelIDs;
QSet<QString> remainingModels;
for (QHash<QString, FBXModel>::const_iterator model = models.constBegin(); model != models.constEnd(); model++) {
QSet<QString> remainingFBXModels;
for (QHash<QString, FBXModel>::const_iterator fbxModel = fbxModels.constBegin(); fbxModel != fbxModels.constEnd(); fbxModel++) {
// models with clusters must be parented to the cluster top
// Unless the model is a root node.
bool isARootNode = !modelIDs.contains(_connectionParentMap.value(model.key()));
bool isARootNode = !modelIDs.contains(_connectionParentMap.value(fbxModel.key()));
if (!isARootNode) {
foreach(const QString& deformerID, _connectionChildMap.values(model.key())) {
foreach(const QString& deformerID, _connectionChildMap.values(fbxModel.key())) {
foreach(const QString& clusterID, _connectionChildMap.values(deformerID)) {
if (!clusters.contains(clusterID)) {
continue;
}
QString topID = getTopModelID(_connectionParentMap, models, _connectionChildMap.value(clusterID), url);
_connectionChildMap.remove(_connectionParentMap.take(model.key()), model.key());
_connectionParentMap.insert(model.key(), topID);
QString topID = getTopModelID(_connectionParentMap, fbxModels, _connectionChildMap.value(clusterID), url);
_connectionChildMap.remove(_connectionParentMap.take(fbxModel.key()), fbxModel.key());
_connectionParentMap.insert(fbxModel.key(), topID);
goto outerBreak;
}
}
@ -1481,21 +1481,21 @@ HFMGeometry* FBXReader::extractHFMGeometry(const QVariantHash& mapping, const QS
}
// make sure the parent is in the child map
QString parent = _connectionParentMap.value(model.key());
if (!_connectionChildMap.contains(parent, model.key())) {
_connectionChildMap.insert(parent, model.key());
QString parent = _connectionParentMap.value(fbxModel.key());
if (!_connectionChildMap.contains(parent, fbxModel.key())) {
_connectionChildMap.insert(parent, fbxModel.key());
}
remainingModels.insert(model.key());
remainingFBXModels.insert(fbxModel.key());
}
while (!remainingModels.isEmpty()) {
QString first = *remainingModels.constBegin();
foreach (const QString& id, remainingModels) {
while (!remainingFBXModels.isEmpty()) {
QString first = *remainingFBXModels.constBegin();
foreach (const QString& id, remainingFBXModels) {
if (id < first) {
first = id;
}
}
QString topID = getTopModelID(_connectionParentMap, models, first, url);
appendModelIDs(_connectionParentMap.value(topID), _connectionChildMap, models, remainingModels, modelIDs, true);
QString topID = getTopModelID(_connectionParentMap, fbxModels, first, url);
appendModelIDs(_connectionParentMap.value(topID), _connectionChildMap, fbxModels, remainingFBXModels, modelIDs, true);
}
// figure the number of animation frames from the curves
@ -1507,53 +1507,53 @@ HFMGeometry* FBXReader::extractHFMGeometry(const QVariantHash& mapping, const QS
HFMAnimationFrame frame;
frame.rotations.resize(modelIDs.size());
frame.translations.resize(modelIDs.size());
geometry.animationFrames.append(frame);
hfmModel.animationFrames.append(frame);
}
// convert the models to joints
QVariantList freeJoints = mapping.values("freeJoint");
geometry.hasSkeletonJoints = false;
hfmModel.hasSkeletonJoints = false;
foreach (const QString& modelID, modelIDs) {
const FBXModel& model = models[modelID];
const FBXModel& fbxModel = fbxModels[modelID];
HFMJoint joint;
joint.isFree = freeJoints.contains(model.name);
joint.parentIndex = model.parentIndex;
joint.isFree = freeJoints.contains(fbxModel.name);
joint.parentIndex = fbxModel.parentIndex;
// get the indices of all ancestors starting with the first free one (if any)
int jointIndex = geometry.joints.size();
int jointIndex = hfmModel.joints.size();
joint.freeLineage.append(jointIndex);
int lastFreeIndex = joint.isFree ? 0 : -1;
for (int index = joint.parentIndex; index != -1; index = geometry.joints.at(index).parentIndex) {
if (geometry.joints.at(index).isFree) {
for (int index = joint.parentIndex; index != -1; index = hfmModel.joints.at(index).parentIndex) {
if (hfmModel.joints.at(index).isFree) {
lastFreeIndex = joint.freeLineage.size();
}
joint.freeLineage.append(index);
}
joint.freeLineage.remove(lastFreeIndex + 1, joint.freeLineage.size() - lastFreeIndex - 1);
joint.translation = model.translation; // these are usually in centimeters
joint.preTransform = model.preTransform;
joint.preRotation = model.preRotation;
joint.rotation = model.rotation;
joint.postRotation = model.postRotation;
joint.postTransform = model.postTransform;
joint.rotationMin = model.rotationMin;
joint.rotationMax = model.rotationMax;
joint.translation = fbxModel.translation; // these are usually in centimeters
joint.preTransform = fbxModel.preTransform;
joint.preRotation = fbxModel.preRotation;
joint.rotation = fbxModel.rotation;
joint.postRotation = fbxModel.postRotation;
joint.postTransform = fbxModel.postTransform;
joint.rotationMin = fbxModel.rotationMin;
joint.rotationMax = fbxModel.rotationMax;
joint.hasGeometricOffset = model.hasGeometricOffset;
joint.geometricTranslation = model.geometricTranslation;
joint.geometricRotation = model.geometricRotation;
joint.geometricScaling = model.geometricScaling;
joint.hasGeometricOffset = fbxModel.hasGeometricOffset;
joint.geometricTranslation = fbxModel.geometricTranslation;
joint.geometricRotation = fbxModel.geometricRotation;
joint.geometricScaling = fbxModel.geometricScaling;
glm::quat combinedRotation = joint.preRotation * joint.rotation * joint.postRotation;
if (joint.parentIndex == -1) {
joint.transform = geometry.offset * glm::translate(joint.translation) * joint.preTransform *
joint.transform = hfmModel.offset * glm::translate(joint.translation) * joint.preTransform *
glm::mat4_cast(combinedRotation) * joint.postTransform;
joint.inverseDefaultRotation = glm::inverse(combinedRotation);
joint.distanceToParent = 0.0f;
} else {
const HFMJoint& parentJoint = geometry.joints.at(joint.parentIndex);
const HFMJoint& parentJoint = hfmModel.joints.at(joint.parentIndex);
joint.transform = parentJoint.transform * glm::translate(joint.translation) *
joint.preTransform * glm::mat4_cast(combinedRotation) * joint.postTransform;
joint.inverseDefaultRotation = glm::inverse(combinedRotation) * parentJoint.inverseDefaultRotation;
@ -1561,20 +1561,20 @@ HFMGeometry* FBXReader::extractHFMGeometry(const QVariantHash& mapping, const QS
extractTranslation(joint.transform));
}
joint.inverseBindRotation = joint.inverseDefaultRotation;
joint.name = model.name;
joint.name = fbxModel.name;
foreach (const QString& childID, _connectionChildMap.values(modelID)) {
QString type = typeFlags.value(childID);
if (!type.isEmpty()) {
geometry.hasSkeletonJoints |= (joint.isSkeletonJoint = type.toLower().contains("Skeleton"));
hfmModel.hasSkeletonJoints |= (joint.isSkeletonJoint = type.toLower().contains("Skeleton"));
break;
}
}
joint.bindTransformFoundInCluster = false;
geometry.joints.append(joint);
geometry.jointIndices.insert(model.name, geometry.joints.size());
hfmModel.joints.append(joint);
hfmModel.jointIndices.insert(fbxModel.name, hfmModel.joints.size());
QString rotationID = localRotations.value(modelID);
AnimationCurve xRotCurve = animationCurves.value(xComponents.value(rotationID));
@ -1590,11 +1590,11 @@ HFMGeometry* FBXReader::extractHFMGeometry(const QVariantHash& mapping, const QS
glm::vec3 defaultPosValues = joint.translation;
for (int i = 0; i < frameCount; i++) {
geometry.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()),
yRotCurve.values.isEmpty() ? defaultRotValues.y : yRotCurve.values.at(i % yRotCurve.values.size()),
zRotCurve.values.isEmpty() ? defaultRotValues.z : zRotCurve.values.at(i % zRotCurve.values.size()))));
geometry.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()),
yPosCurve.values.isEmpty() ? defaultPosValues.y : yPosCurve.values.at(i % yPosCurve.values.size()),
zPosCurve.values.isEmpty() ? defaultPosValues.z : zPosCurve.values.at(i % zPosCurve.values.size()));
@ -1603,32 +1603,32 @@ HFMGeometry* FBXReader::extractHFMGeometry(const QVariantHash& mapping, const QS
// NOTE: shapeVertices are in joint-frame
std::vector<ShapeVertices> shapeVertices;
shapeVertices.resize(std::max(1, geometry.joints.size()) );
shapeVertices.resize(std::max(1, hfmModel.joints.size()) );
// find our special joints
geometry.leftEyeJointIndex = modelIDs.indexOf(jointEyeLeftID);
geometry.rightEyeJointIndex = modelIDs.indexOf(jointEyeRightID);
geometry.neckJointIndex = modelIDs.indexOf(jointNeckID);
geometry.rootJointIndex = modelIDs.indexOf(jointRootID);
geometry.leanJointIndex = modelIDs.indexOf(jointLeanID);
geometry.headJointIndex = modelIDs.indexOf(jointHeadID);
geometry.leftHandJointIndex = modelIDs.indexOf(jointLeftHandID);
geometry.rightHandJointIndex = modelIDs.indexOf(jointRightHandID);
geometry.leftToeJointIndex = modelIDs.indexOf(jointLeftToeID);
geometry.rightToeJointIndex = modelIDs.indexOf(jointRightToeID);
hfmModel.leftEyeJointIndex = modelIDs.indexOf(jointEyeLeftID);
hfmModel.rightEyeJointIndex = modelIDs.indexOf(jointEyeRightID);
hfmModel.neckJointIndex = modelIDs.indexOf(jointNeckID);
hfmModel.rootJointIndex = modelIDs.indexOf(jointRootID);
hfmModel.leanJointIndex = modelIDs.indexOf(jointLeanID);
hfmModel.headJointIndex = modelIDs.indexOf(jointHeadID);
hfmModel.leftHandJointIndex = modelIDs.indexOf(jointLeftHandID);
hfmModel.rightHandJointIndex = modelIDs.indexOf(jointRightHandID);
hfmModel.leftToeJointIndex = modelIDs.indexOf(jointLeftToeID);
hfmModel.rightToeJointIndex = modelIDs.indexOf(jointRightToeID);
foreach (const QString& id, humanIKJointIDs) {
geometry.humanIKJointIndices.append(modelIDs.indexOf(id));
hfmModel.humanIKJointIndices.append(modelIDs.indexOf(id));
}
// extract the translation component of the neck transform
if (geometry.neckJointIndex != -1) {
const glm::mat4& transform = geometry.joints.at(geometry.neckJointIndex).transform;
geometry.neckPivot = glm::vec3(transform[3][0], transform[3][1], transform[3][2]);
if (hfmModel.neckJointIndex != -1) {
const glm::mat4& transform = hfmModel.joints.at(hfmModel.neckJointIndex).transform;
hfmModel.neckPivot = glm::vec3(transform[3][0], transform[3][1], transform[3][2]);
}
geometry.bindExtents.reset();
geometry.meshExtents.reset();
hfmModel.bindExtents.reset();
hfmModel.meshExtents.reset();
// Create the Material Library
consolidateHFMMaterials(mapping);
@ -1664,7 +1664,7 @@ HFMGeometry* FBXReader::extractHFMGeometry(const QVariantHash& mapping, const QS
}
}
#endif
geometry.materials = _hfmMaterials;
hfmModel.materials = _hfmMaterials;
// see if any materials have texture children
bool materialsHaveTextures = checkMaterialsHaveTextures(_hfmMaterials, _textureFilenames, _connectionChildMap);
@ -1675,14 +1675,14 @@ HFMGeometry* FBXReader::extractHFMGeometry(const QVariantHash& mapping, const QS
extracted.mesh.meshExtents.reset();
// accumulate local transforms
QString modelID = models.contains(it.key()) ? it.key() : _connectionParentMap.value(it.key());
glm::mat4 modelTransform = getGlobalTransform(_connectionParentMap, models, modelID, geometry.applicationName == "mixamo.com", url);
QString modelID = fbxModels.contains(it.key()) ? it.key() : _connectionParentMap.value(it.key());
glm::mat4 modelTransform = getGlobalTransform(_connectionParentMap, fbxModels, modelID, hfmModel.applicationName == "mixamo.com", url);
// compute the mesh extents from the transformed vertices
foreach (const glm::vec3& vertex, extracted.mesh.vertices) {
glm::vec3 transformedVertex = glm::vec3(modelTransform * glm::vec4(vertex, 1.0f));
geometry.meshExtents.minimum = glm::min(geometry.meshExtents.minimum, transformedVertex);
geometry.meshExtents.maximum = glm::max(geometry.meshExtents.maximum, transformedVertex);
hfmModel.meshExtents.minimum = glm::min(hfmModel.meshExtents.minimum, transformedVertex);
hfmModel.meshExtents.maximum = glm::max(hfmModel.meshExtents.maximum, transformedVertex);
extracted.mesh.meshExtents.minimum = glm::min(extracted.mesh.meshExtents.minimum, transformedVertex);
extracted.mesh.meshExtents.maximum = glm::max(extracted.mesh.meshExtents.maximum, transformedVertex);
@ -1763,14 +1763,14 @@ HFMGeometry* FBXReader::extractHFMGeometry(const QVariantHash& mapping, const QS
extracted.mesh.clusters.append(hfmCluster);
// override the bind rotation with the transform link
HFMJoint& joint = geometry.joints[hfmCluster.jointIndex];
HFMJoint& joint = hfmModel.joints[hfmCluster.jointIndex];
joint.inverseBindRotation = glm::inverse(extractRotation(cluster.transformLink));
joint.bindTransform = cluster.transformLink;
joint.bindTransformFoundInCluster = true;
// update the bind pose extents
glm::vec3 bindTranslation = extractTranslation(geometry.offset * joint.bindTransform);
geometry.bindExtents.addPoint(bindTranslation);
glm::vec3 bindTranslation = extractTranslation(hfmModel.offset * joint.bindTransform);
hfmModel.bindExtents.addPoint(bindTranslation);
}
}
@ -1801,14 +1801,14 @@ HFMGeometry* FBXReader::extractHFMGeometry(const QVariantHash& mapping, const QS
const Cluster& cluster = clusters[clusterID];
const HFMCluster& hfmCluster = extracted.mesh.clusters.at(i);
int jointIndex = hfmCluster.jointIndex;
HFMJoint& joint = geometry.joints[jointIndex];
HFMJoint& joint = hfmModel.joints[jointIndex];
glm::mat4 transformJointToMesh = inverseModelTransform * joint.bindTransform;
glm::vec3 boneEnd = extractTranslation(transformJointToMesh);
glm::vec3 boneBegin = boneEnd;
glm::vec3 boneDirection;
float boneLength = 0.0f;
if (joint.parentIndex != -1) {
boneBegin = extractTranslation(inverseModelTransform * geometry.joints[joint.parentIndex].bindTransform);
boneBegin = extractTranslation(inverseModelTransform * hfmModel.joints[joint.parentIndex].bindTransform);
boneDirection = boneEnd - boneBegin;
boneLength = glm::length(boneDirection);
if (boneLength > EPSILON) {
@ -1882,7 +1882,7 @@ HFMGeometry* FBXReader::extractHFMGeometry(const QVariantHash& mapping, const QS
} else {
// this is a single-mesh joint
int jointIndex = firstHFMCluster.jointIndex;
HFMJoint& joint = geometry.joints[jointIndex];
HFMJoint& joint = hfmModel.joints[jointIndex];
// transform cluster vertices to joint-frame and save for later
glm::mat4 meshToJoint = glm::inverse(joint.bindTransform) * modelTransform;
@ -1902,8 +1902,8 @@ HFMGeometry* FBXReader::extractHFMGeometry(const QVariantHash& mapping, const QS
}
buildModelMesh(extracted.mesh, url);
geometry.meshes.append(extracted.mesh);
int meshIndex = geometry.meshes.size() - 1;
hfmModel.meshes.append(extracted.mesh);
int meshIndex = hfmModel.meshes.size() - 1;
if (extracted.mesh._mesh) {
extracted.mesh._mesh->displayName = QString("%1#/mesh/%2").arg(url).arg(meshIndex).toStdString();
extracted.mesh._mesh->modelName = modelIDsToNames.value(modelID).toStdString();
@ -1923,8 +1923,8 @@ HFMGeometry* FBXReader::extractHFMGeometry(const QVariantHash& mapping, const QS
};
// now that all joints have been scanned compute a k-Dop bounding volume of mesh
for (int i = 0; i < geometry.joints.size(); ++i) {
HFMJoint& joint = geometry.joints[i];
for (int i = 0; i < hfmModel.joints.size(); ++i) {
HFMJoint& joint = hfmModel.joints[i];
// NOTE: points are in joint-frame
ShapeVertices& points = shapeVertices.at(i);
@ -1958,7 +1958,7 @@ HFMGeometry* FBXReader::extractHFMGeometry(const QVariantHash& mapping, const QS
generateBoundryLinesForDop14(joint.shapeInfo.dots, joint.shapeInfo.avgPoint, joint.shapeInfo.debugLines);
}
}
geometry.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
for (QHash<QString, int>::const_iterator m = meshIDsToMeshIndices.constBegin();
@ -1971,14 +1971,14 @@ HFMGeometry* FBXReader::extractHFMGeometry(const QVariantHash& mapping, const QS
const QString& modelID = ooChildToParent.value(meshID);
if (modelIDsToNames.contains(modelID)) {
const QString& modelName = modelIDsToNames.value(modelID);
geometry.meshIndicesToModelNames.insert(meshIndex, modelName);
hfmModel.meshIndicesToModelNames.insert(meshIndex, modelName);
}
}
}
{
int i = 0;
for (const auto& mesh : geometry.meshes) {
auto name = geometry.getModelNameOfMesh(i++);
for (const auto& mesh : hfmModel.meshes) {
auto name = hfmModel.getModelNameOfMesh(i++);
if (!name.isEmpty()) {
if (mesh._mesh) {
mesh._mesh->modelName = name.toStdString();
@ -1991,16 +1991,16 @@ HFMGeometry* FBXReader::extractHFMGeometry(const QVariantHash& mapping, const QS
}
}
}
return geometryPtr;
return hfmModelPtr;
}
HFMGeometry* readFBX(const QByteArray& model, const QVariantHash& mapping, const QString& url, bool loadLightmaps, float lightmapLevel) {
QBuffer buffer(const_cast<QByteArray*>(&model));
HFMModel* readFBX(const QByteArray& data, const QVariantHash& mapping, const QString& url, bool loadLightmaps, float lightmapLevel) {
QBuffer buffer(const_cast<QByteArray*>(&data));
buffer.open(QIODevice::ReadOnly);
return readFBX(&buffer, mapping, url, loadLightmaps, lightmapLevel);
}
HFMGeometry* readFBX(QIODevice* device, const QVariantHash& mapping, const QString& url, bool loadLightmaps, float lightmapLevel) {
HFMModel* readFBX(QIODevice* device, const QVariantHash& mapping, const QString& url, bool loadLightmaps, float lightmapLevel) {
FBXReader reader;
reader._rootNode = FBXReader::parseFBX(device);
reader._loadLightmaps = loadLightmaps;
@ -2008,5 +2008,5 @@ HFMGeometry* readFBX(QIODevice* device, const QVariantHash& mapping, const QStri
qCDebug(modelformat) << "Reading FBX: " << url;
return reader.extractHFMGeometry(mapping, url);
return reader.extractHFMModel(mapping, url);
}

View file

@ -34,13 +34,13 @@
class QIODevice;
class FBXNode;
/// Reads FBX geometry from the supplied model and mapping data.
/// Reads HFMModel from the supplied model and mapping data.
/// \exception QString if an error occurs in parsing
HFMGeometry* readFBX(const QByteArray& model, const QVariantHash& mapping, const QString& url = "", bool loadLightmaps = true, float lightmapLevel = 1.0f);
HFMModel* readFBX(const QByteArray& data, const QVariantHash& mapping, const QString& url = "", bool loadLightmaps = true, float lightmapLevel = 1.0f);
/// Reads FBX geometry from the supplied model and mapping data.
/// Reads HFMModel from the supplied model and mapping data.
/// \exception QString if an error occurs in parsing
HFMGeometry* readFBX(QIODevice* device, const QVariantHash& mapping, const QString& url = "", bool loadLightmaps = true, float lightmapLevel = 1.0f);
HFMModel* readFBX(QIODevice* device, const QVariantHash& mapping, const QString& url = "", bool loadLightmaps = true, float lightmapLevel = 1.0f);
class TextureParam {
public:
@ -103,12 +103,12 @@ class ExtractedMesh;
class FBXReader {
public:
HFMGeometry* _hfmGeometry;
HFMModel* _hfmModel;
FBXNode _rootNode;
static FBXNode parseFBX(QIODevice* device);
HFMGeometry* extractHFMGeometry(const QVariantHash& mapping, const QString& url);
HFMModel* extractHFMModel(const QVariantHash& mapping, const QString& url);
static ExtractedMesh extractMesh(const FBXNode& object, unsigned int& meshIndex, bool deduplicate = true);
QHash<QString, ExtractedMesh> meshes;

View file

@ -533,10 +533,10 @@ bool GLTFReader::addTexture(const QJsonObject& object) {
return true;
}
bool GLTFReader::parseGLTF(const QByteArray& model) {
bool GLTFReader::parseGLTF(const QByteArray& data) {
PROFILE_RANGE_EX(resource_parse, __FUNCTION__, 0xffff0000, nullptr);
QJsonDocument d = QJsonDocument::fromJson(model);
QJsonDocument d = QJsonDocument::fromJson(data);
QJsonObject jsFile = d.object();
bool isvalid = setAsset(jsFile);
@ -697,7 +697,7 @@ glm::mat4 GLTFReader::getModelTransform(const GLTFNode& node) {
return tmat;
}
bool GLTFReader::buildGeometry(HFMGeometry& geometry, const QUrl& url) {
bool GLTFReader::buildGeometry(HFMModel& hfmModel, const QUrl& url) {
//Build dependencies
QVector<QVector<int>> nodeDependencies(_file.nodes.size());
@ -727,17 +727,17 @@ bool GLTFReader::buildGeometry(HFMGeometry& geometry, const QUrl& url) {
}
//Build default joints
geometry.joints.resize(1);
geometry.joints[0].isFree = false;
geometry.joints[0].parentIndex = -1;
geometry.joints[0].distanceToParent = 0;
geometry.joints[0].translation = glm::vec3(0, 0, 0);
geometry.joints[0].rotationMin = glm::vec3(0, 0, 0);
geometry.joints[0].rotationMax = glm::vec3(0, 0, 0);
geometry.joints[0].name = "OBJ";
geometry.joints[0].isSkeletonJoint = true;
hfmModel.joints.resize(1);
hfmModel.joints[0].isFree = false;
hfmModel.joints[0].parentIndex = -1;
hfmModel.joints[0].distanceToParent = 0;
hfmModel.joints[0].translation = glm::vec3(0, 0, 0);
hfmModel.joints[0].rotationMin = glm::vec3(0, 0, 0);
hfmModel.joints[0].rotationMax = glm::vec3(0, 0, 0);
hfmModel.joints[0].name = "OBJ";
hfmModel.joints[0].isSkeletonJoint = true;
geometry.jointIndices["x"] = 1;
hfmModel.jointIndices["x"] = 1;
//Build materials
QVector<QString> materialIDs;
@ -750,8 +750,8 @@ bool GLTFReader::buildGeometry(HFMGeometry& geometry, const QUrl& url) {
for (int i = 0; i < materialIDs.size(); i++) {
QString& matid = materialIDs[i];
geometry.materials[matid] = HFMMaterial();
HFMMaterial& hfmMaterial = geometry.materials[matid];
hfmModel.materials[matid] = HFMMaterial();
HFMMaterial& hfmMaterial = hfmModel.materials[matid];
hfmMaterial._material = std::make_shared<graphics::Material>();
setHFMMaterial(hfmMaterial, _file.materials[i]);
}
@ -765,8 +765,8 @@ bool GLTFReader::buildGeometry(HFMGeometry& geometry, const QUrl& url) {
if (node.defined["mesh"]) {
qCDebug(modelformat) << "node_transforms" << node.transforms;
foreach(auto &primitive, _file.meshes[node.mesh].primitives) {
geometry.meshes.append(HFMMesh());
HFMMesh& mesh = geometry.meshes[geometry.meshes.size() - 1];
hfmModel.meshes.append(HFMMesh());
HFMMesh& mesh = hfmModel.meshes[hfmModel.meshes.size() - 1];
HFMCluster cluster;
cluster.jointIndex = 0;
cluster.inverseBindMatrix = glm::mat4(1, 0, 0, 0,
@ -886,7 +886,7 @@ bool GLTFReader::buildGeometry(HFMGeometry& geometry, const QUrl& url) {
mesh.meshExtents.reset();
foreach(const glm::vec3& vertex, mesh.vertices) {
mesh.meshExtents.addPoint(vertex);
geometry.meshExtents.addPoint(vertex);
hfmModel.meshExtents.addPoint(vertex);
}
// since mesh.modelTransform seems to not have any effect I apply the transformation the model
@ -898,7 +898,7 @@ bool GLTFReader::buildGeometry(HFMGeometry& geometry, const QUrl& url) {
}
}
mesh.meshIndex = geometry.meshes.size();
mesh.meshIndex = hfmModel.meshes.size();
FBXReader::buildModelMesh(mesh, url.toString());
}
@ -910,7 +910,7 @@ bool GLTFReader::buildGeometry(HFMGeometry& geometry, const QUrl& url) {
return true;
}
HFMGeometry* GLTFReader::readGLTF(QByteArray& model, const QVariantHash& mapping,
HFMModel* GLTFReader::readGLTF(QByteArray& data, const QVariantHash& mapping,
const QUrl& url, bool loadLightmaps, float lightmapLevel) {
_url = url;
@ -922,15 +922,15 @@ HFMGeometry* GLTFReader::readGLTF(QByteArray& model, const QVariantHash& mapping
_url = QUrl(QFileInfo(localFileName).absoluteFilePath());
}
parseGLTF(model);
parseGLTF(data);
//_file.dump();
HFMGeometry* geometryPtr = new HFMGeometry();
HFMGeometry& geometry = *geometryPtr;
HFMModel* hfmModelPtr = new HFMModel();
HFMModel& hfmModel = *hfmModelPtr;
buildGeometry(geometry, url);
buildGeometry(hfmModel, url);
//hfmDebugDump(geometry);
return geometryPtr;
//hfmDebugDump(data);
return hfmModelPtr;
}
@ -1181,37 +1181,37 @@ void GLTFReader::retriangulate(const QVector<int>& inIndices, const QVector<glm:
}
}
void GLTFReader::hfmDebugDump(const HFMGeometry& hfmgeo) {
qCDebug(modelformat) << "---------------- hfmGeometry ----------------";
qCDebug(modelformat) << " hasSkeletonJoints =" << hfmgeo.hasSkeletonJoints;
qCDebug(modelformat) << " offset =" << hfmgeo.offset;
void GLTFReader::hfmDebugDump(const HFMModel& hfmModel) {
qCDebug(modelformat) << "---------------- hfmModel ----------------";
qCDebug(modelformat) << " hasSkeletonJoints =" << hfmModel.hasSkeletonJoints;
qCDebug(modelformat) << " offset =" << hfmModel.offset;
qCDebug(modelformat) << " leftEyeJointIndex =" << hfmgeo.leftEyeJointIndex;
qCDebug(modelformat) << " rightEyeJointIndex =" << hfmgeo.rightEyeJointIndex;
qCDebug(modelformat) << " neckJointIndex =" << hfmgeo.neckJointIndex;
qCDebug(modelformat) << " rootJointIndex =" << hfmgeo.rootJointIndex;
qCDebug(modelformat) << " leanJointIndex =" << hfmgeo.leanJointIndex;
qCDebug(modelformat) << " headJointIndex =" << hfmgeo.headJointIndex;
qCDebug(modelformat) << " leftHandJointIndex" << hfmgeo.leftHandJointIndex;
qCDebug(modelformat) << " rightHandJointIndex" << hfmgeo.rightHandJointIndex;
qCDebug(modelformat) << " leftToeJointIndex" << hfmgeo.leftToeJointIndex;
qCDebug(modelformat) << " rightToeJointIndex" << hfmgeo.rightToeJointIndex;
qCDebug(modelformat) << " leftEyeSize = " << hfmgeo.leftEyeSize;
qCDebug(modelformat) << " rightEyeSize = " << hfmgeo.rightEyeSize;
qCDebug(modelformat) << " leftEyeJointIndex =" << hfmModel.leftEyeJointIndex;
qCDebug(modelformat) << " rightEyeJointIndex =" << hfmModel.rightEyeJointIndex;
qCDebug(modelformat) << " neckJointIndex =" << hfmModel.neckJointIndex;
qCDebug(modelformat) << " rootJointIndex =" << hfmModel.rootJointIndex;
qCDebug(modelformat) << " leanJointIndex =" << hfmModel.leanJointIndex;
qCDebug(modelformat) << " headJointIndex =" << hfmModel.headJointIndex;
qCDebug(modelformat) << " leftHandJointIndex" << hfmModel.leftHandJointIndex;
qCDebug(modelformat) << " rightHandJointIndex" << hfmModel.rightHandJointIndex;
qCDebug(modelformat) << " leftToeJointIndex" << hfmModel.leftToeJointIndex;
qCDebug(modelformat) << " rightToeJointIndex" << hfmModel.rightToeJointIndex;
qCDebug(modelformat) << " leftEyeSize = " << hfmModel.leftEyeSize;
qCDebug(modelformat) << " rightEyeSize = " << hfmModel.rightEyeSize;
qCDebug(modelformat) << " palmDirection = " << hfmgeo.palmDirection;
qCDebug(modelformat) << " palmDirection = " << hfmModel.palmDirection;
qCDebug(modelformat) << " neckPivot = " << hfmgeo.neckPivot;
qCDebug(modelformat) << " neckPivot = " << hfmModel.neckPivot;
qCDebug(modelformat) << " bindExtents.size() = " << hfmgeo.bindExtents.size();
qCDebug(modelformat) << " meshExtents.size() = " << hfmgeo.meshExtents.size();
qCDebug(modelformat) << " bindExtents.size() = " << hfmModel.bindExtents.size();
qCDebug(modelformat) << " meshExtents.size() = " << hfmModel.meshExtents.size();
qCDebug(modelformat) << " jointIndices.size() =" << hfmgeo.jointIndices.size();
qCDebug(modelformat) << " joints.count() =" << hfmgeo.joints.count();
qCDebug(modelformat) << " jointIndices.size() =" << hfmModel.jointIndices.size();
qCDebug(modelformat) << " joints.count() =" << hfmModel.joints.count();
qCDebug(modelformat) << "---------------- Meshes ----------------";
qCDebug(modelformat) << " meshes.count() =" << hfmgeo.meshes.count();
qCDebug(modelformat) << " blendshapeChannelNames = " << hfmgeo.blendshapeChannelNames;
foreach(HFMMesh mesh, hfmgeo.meshes) {
qCDebug(modelformat) << " meshes.count() =" << hfmModel.meshes.count();
qCDebug(modelformat) << " blendshapeChannelNames = " << hfmModel.blendshapeChannelNames;
foreach(HFMMesh mesh, hfmModel.meshes) {
qCDebug(modelformat) << "\n";
qCDebug(modelformat) << " meshpointer =" << mesh._mesh.get();
qCDebug(modelformat) << " meshindex =" << mesh.meshIndex;
@ -1254,18 +1254,18 @@ void GLTFReader::hfmDebugDump(const HFMGeometry& hfmgeo) {
qCDebug(modelformat) << "\n";
}
qCDebug(modelformat) << "---------------- AnimationFrames ----------------";
foreach(HFMAnimationFrame anim, hfmgeo.animationFrames) {
foreach(HFMAnimationFrame anim, hfmModel.animationFrames) {
qCDebug(modelformat) << " anim.translations = " << anim.translations;
qCDebug(modelformat) << " anim.rotations = " << anim.rotations;
}
QList<int> mitomona_keys = hfmgeo.meshIndicesToModelNames.keys();
QList<int> mitomona_keys = hfmModel.meshIndicesToModelNames.keys();
foreach(int key, mitomona_keys) {
qCDebug(modelformat) << " meshIndicesToModelNames key =" << key << " val =" << hfmgeo.meshIndicesToModelNames[key];
qCDebug(modelformat) << " meshIndicesToModelNames key =" << key << " val =" << hfmModel.meshIndicesToModelNames[key];
}
qCDebug(modelformat) << "---------------- Materials ----------------";
foreach(HFMMaterial mat, hfmgeo.materials) {
foreach(HFMMaterial mat, hfmModel.materials) {
qCDebug(modelformat) << "\n";
qCDebug(modelformat) << " mat.materialID =" << mat.materialID;
qCDebug(modelformat) << " diffuseColor =" << mat.diffuseColor;
@ -1314,7 +1314,7 @@ void GLTFReader::hfmDebugDump(const HFMGeometry& hfmgeo) {
qCDebug(modelformat) << "---------------- Joints ----------------";
foreach(HFMJoint joint, hfmgeo.joints) {
foreach(HFMJoint joint, hfmModel.joints) {
qCDebug(modelformat) << "\n";
qCDebug(modelformat) << " shapeInfo.avgPoint =" << joint.shapeInfo.avgPoint;
qCDebug(modelformat) << " shapeInfo.debugLines =" << joint.shapeInfo.debugLines;

View file

@ -706,7 +706,7 @@ class GLTFReader : public QObject {
Q_OBJECT
public:
GLTFReader();
HFMGeometry* readGLTF(QByteArray& model, const QVariantHash& mapping,
HFMModel* readGLTF(QByteArray& data, const QVariantHash& mapping,
const QUrl& url, bool loadLightmaps = true, float lightmapLevel = 1.0f);
private:
GLTFFile _file;
@ -714,8 +714,8 @@ private:
glm::mat4 getModelTransform(const GLTFNode& node);
bool buildGeometry(HFMGeometry& geometry, const QUrl& url);
bool parseGLTF(const QByteArray& model);
bool buildGeometry(HFMModel& hfmModel, const QUrl& url);
bool parseGLTF(const QByteArray& data);
bool getStringVal(const QJsonObject& object, const QString& fieldname,
QString& value, QMap<QString, bool>& defined);
@ -780,7 +780,7 @@ private:
void setHFMMaterial(HFMMaterial& fbxmat, const GLTFMaterial& material);
HFMTexture getHFMTexture(const GLTFTexture& texture);
void hfmDebugDump(const HFMGeometry& hfmgeo);
void hfmDebugDump(const HFMModel& hfmModel);
};
#endif // hifi_GLTFReader_h

View file

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

View file

@ -87,13 +87,13 @@ public:
QString currentMaterialName;
QHash<QString, OBJMaterial> materials;
HFMGeometry::Pointer readOBJ(QByteArray& model, const QVariantHash& mapping, bool combineParts, const QUrl& url = QUrl());
HFMModel::Pointer readOBJ(QByteArray& data, const QVariantHash& mapping, bool combineParts, const QUrl& url = QUrl());
private:
QUrl _url;
QHash<QByteArray, bool> librariesSeen;
bool parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& mapping, HFMGeometry& geometry,
bool parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& mapping, HFMModel& hfmModel,
float& scaleGuess, bool combineParts);
void parseMaterialLibrary(QIODevice* device);
void parseTextureLine(const QByteArray& textureLine, QByteArray& filename, OBJMaterialTextureOptions& textureOptions);
@ -104,4 +104,4 @@ private:
// What are these utilities doing here? One is used by fbx loading code in VHACD Utils, and the other a general debugging utility.
void setMeshPartDefaults(HFMMeshPart& meshPart, QString materialID);
void hfmDebugDump(const HFMGeometry& hfmgeo);
void hfmDebugDump(const HFMModel& hfmModel);

View file

@ -128,7 +128,7 @@ void GeometryMappingResource::downloadFinished(const QByteArray& data) {
void GeometryMappingResource::onGeometryMappingLoaded(bool success) {
if (success && _geometryResource) {
_hfmGeometry = _geometryResource->_hfmGeometry;
_hfmModel = _geometryResource->_hfmModel;
_meshParts = _geometryResource->_meshParts;
_meshes = _geometryResource->_meshes;
_materials = _geometryResource->_materials;
@ -193,38 +193,38 @@ void GeometryReader::run() {
_url.path().toLower().endsWith(".obj.gz") ||
_url.path().toLower().endsWith(".gltf"))) {
HFMGeometry::Pointer hfmGeometry;
HFMModel::Pointer hfmModel;
if (_url.path().toLower().endsWith(".fbx")) {
hfmGeometry.reset(readFBX(_data, _mapping, _url.path()));
if (hfmGeometry->meshes.size() == 0 && hfmGeometry->joints.size() == 0) {
hfmModel.reset(readFBX(_data, _mapping, _url.path()));
if (hfmModel->meshes.size() == 0 && hfmModel->joints.size() == 0) {
throw QString("empty geometry, possibly due to an unsupported FBX version");
}
} else if (_url.path().toLower().endsWith(".obj")) {
hfmGeometry = OBJReader().readOBJ(_data, _mapping, _combineParts, _url);
hfmModel = OBJReader().readOBJ(_data, _mapping, _combineParts, _url);
} else if (_url.path().toLower().endsWith(".obj.gz")) {
QByteArray uncompressedData;
if (gunzip(_data, uncompressedData)){
hfmGeometry = OBJReader().readOBJ(uncompressedData, _mapping, _combineParts, _url);
hfmModel = OBJReader().readOBJ(uncompressedData, _mapping, _combineParts, _url);
} else {
throw QString("failed to decompress .obj.gz");
}
} else if (_url.path().toLower().endsWith(".gltf")) {
std::shared_ptr<GLTFReader> glreader = std::make_shared<GLTFReader>();
hfmGeometry.reset(glreader->readGLTF(_data, _mapping, _url));
if (hfmGeometry->meshes.size() == 0 && hfmGeometry->joints.size() == 0) {
hfmModel.reset(glreader->readGLTF(_data, _mapping, _url));
if (hfmModel->meshes.size() == 0 && hfmModel->joints.size() == 0) {
throw QString("empty geometry, possibly due to an unsupported GLTF version");
}
} else {
throw QString("unsupported format");
}
// Add scripts to hfmGeometry
// Add scripts to hfmModel
if (!_mapping.value(SCRIPT_FIELD).isNull()) {
QVariantList scripts = _mapping.values(SCRIPT_FIELD);
for (auto &script : scripts) {
hfmGeometry->scripts.push_back(script.toString());
hfmModel->scripts.push_back(script.toString());
}
}
@ -234,7 +234,7 @@ void GeometryReader::run() {
qCWarning(modelnetworking) << "Abandoning load of" << _url << "; could not get strong ref";
} else {
QMetaObject::invokeMethod(resource.data(), "setGeometryDefinition",
Q_ARG(HFMGeometry::Pointer, hfmGeometry));
Q_ARG(HFMModel::Pointer, hfmModel));
}
} else {
throw QString("url is invalid");
@ -262,7 +262,7 @@ public:
virtual void downloadFinished(const QByteArray& data) override;
protected:
Q_INVOKABLE void setGeometryDefinition(HFMGeometry::Pointer hfmGeometry);
Q_INVOKABLE void setGeometryDefinition(HFMModel::Pointer hfmModel);
private:
QVariantHash _mapping;
@ -277,13 +277,13 @@ void GeometryDefinitionResource::downloadFinished(const QByteArray& data) {
QThreadPool::globalInstance()->start(new GeometryReader(_self, _effectiveBaseURL, _mapping, data, _combineParts));
}
void GeometryDefinitionResource::setGeometryDefinition(HFMGeometry::Pointer hfmGeometry) {
// Assume ownership of the geometry pointer
_hfmGeometry = hfmGeometry;
void GeometryDefinitionResource::setGeometryDefinition(HFMModel::Pointer hfmModel) {
// Assume ownership of the HFMModel pointer
_hfmModel = hfmModel;
// Copy materials
QHash<QString, size_t> materialIDAtlas;
for (const HFMMaterial& material : _hfmGeometry->materials) {
for (const HFMMaterial& material : _hfmModel->materials) {
materialIDAtlas[material.materialID] = _materials.size();
_materials.push_back(std::make_shared<NetworkMaterial>(material, _textureBaseUrl));
}
@ -291,7 +291,7 @@ void GeometryDefinitionResource::setGeometryDefinition(HFMGeometry::Pointer hfmG
std::shared_ptr<GeometryMeshes> meshes = std::make_shared<GeometryMeshes>();
std::shared_ptr<GeometryMeshParts> parts = std::make_shared<GeometryMeshParts>();
int meshID = 0;
for (const HFMMesh& mesh : _hfmGeometry->meshes) {
for (const HFMMesh& mesh : _hfmModel->meshes) {
// Copy mesh pointers
meshes->emplace_back(mesh._mesh);
int partID = 0;
@ -371,7 +371,7 @@ const QVariantMap Geometry::getTextures() const {
// FIXME: The materials should only be copied when modified, but the Model currently caches the original
Geometry::Geometry(const Geometry& geometry) {
_hfmGeometry = geometry._hfmGeometry;
_hfmModel = geometry._hfmModel;
_meshes = geometry._meshes;
_meshParts = geometry._meshParts;
@ -444,8 +444,8 @@ void GeometryResource::deleter() {
}
void GeometryResource::setTextures() {
if (_hfmGeometry) {
for (const HFMMaterial& material : _hfmGeometry->materials) {
if (_hfmModel) {
for (const HFMMaterial& material : _hfmModel->materials) {
_materials.push_back(std::make_shared<NetworkMaterial>(material, _textureBaseUrl));
}
}

View file

@ -45,9 +45,9 @@ public:
// Mutable, but must retain structure of vector
using NetworkMaterials = std::vector<std::shared_ptr<NetworkMaterial>>;
bool isGeometryLoaded() const { return (bool)_hfmGeometry; }
bool isHFMModelLoaded() const { return (bool)_hfmModel; }
const HFMGeometry& getHFMGeometry() const { return *_hfmGeometry; }
const HFMModel& getHFMModel() const { return *_hfmModel; }
const GeometryMeshes& getMeshes() const { return *_meshes; }
const std::shared_ptr<NetworkMaterial> getShapeMaterial(int shapeID) const;
@ -62,7 +62,7 @@ protected:
friend class GeometryMappingResource;
// Shared across all geometries, constant throughout lifetime
std::shared_ptr<const HFMGeometry> _hfmGeometry;
std::shared_ptr<const HFMModel> _hfmModel;
std::shared_ptr<const GeometryMeshes> _meshes;
std::shared_ptr<const GeometryMeshParts> _meshParts;
@ -94,7 +94,7 @@ protected:
// Geometries may not hold onto textures while cached - that is for the texture cache
// Instead, these methods clear and reset textures from the geometry when caching/loading
bool shouldSetTextures() const { return _hfmGeometry && _materials.empty(); }
bool shouldSetTextures() const { return _hfmModel && _materials.empty(); }
void setTextures();
void resetTextures();

View file

@ -32,8 +32,8 @@ bool CauterizedModel::updateGeometry() {
bool needsFullUpdate = Model::updateGeometry();
if (_isCauterized && needsFullUpdate) {
assert(_cauterizeMeshStates.empty());
const HFMGeometry& hfmGeometry = getHFMGeometry();
foreach (const HFMMesh& mesh, hfmGeometry.meshes) {
const HFMModel& hfmModel = getHFMModel();
foreach (const HFMMesh& mesh, hfmModel.meshes) {
Model::MeshState state;
if (_useDualQuaternionSkinning) {
state.clusterDualQuaternions.resize(mesh.clusters.size());
@ -76,7 +76,7 @@ void CauterizedModel::createRenderItemSet() {
// Run through all of the meshes, and place them into their segregated, but unsorted buckets
int shapeID = 0;
uint32_t numMeshes = (uint32_t)meshes.size();
const HFMGeometry& hfmGeometry = getHFMGeometry();
const HFMModel& hfmModel = getHFMModel();
for (uint32_t i = 0; i < numMeshes; i++) {
const auto& mesh = meshes.at(i);
if (!mesh) {
@ -86,7 +86,7 @@ void CauterizedModel::createRenderItemSet() {
// Create the render payloads
int numParts = (int)mesh->getNumParts();
for (int partIndex = 0; partIndex < numParts; partIndex++) {
initializeBlendshapes(hfmGeometry.meshes[i], i);
initializeBlendshapes(hfmModel.meshes[i], i);
auto ptr = std::make_shared<CauterizedMeshPartPayload>(shared_from_this(), i, partIndex, shapeID, transform, offset);
_modelMeshRenderItems << std::static_pointer_cast<ModelMeshPartPayload>(ptr);
@ -109,11 +109,11 @@ void CauterizedModel::updateClusterMatrices() {
return;
}
_needsUpdateClusterMatrices = false;
const HFMGeometry& geometry = getHFMGeometry();
const HFMModel& hfmModel = getHFMModel();
for (int i = 0; i < (int)_meshStates.size(); i++) {
Model::MeshState& state = _meshStates[i];
const HFMMesh& mesh = geometry.meshes.at(i);
const HFMMesh& mesh = hfmModel.meshes.at(i);
for (int j = 0; j < mesh.clusters.size(); j++) {
const HFMCluster& cluster = mesh.clusters.at(j);
if (_useDualQuaternionSkinning) {
@ -133,7 +133,7 @@ void CauterizedModel::updateClusterMatrices() {
// as an optimization, don't build cautrizedClusterMatrices if the boneSet is empty.
if (!_cauterizeBoneSet.empty()) {
AnimPose cauterizePose = _rig.getJointPose(geometry.neckJointIndex);
AnimPose cauterizePose = _rig.getJointPose(hfmModel.neckJointIndex);
cauterizePose.scale() = glm::vec3(0.0001f, 0.0001f, 0.0001f);
static const glm::mat4 zeroScale(
@ -141,11 +141,11 @@ void CauterizedModel::updateClusterMatrices() {
glm::vec4(0.0f, 0.0001f, 0.0f, 0.0f),
glm::vec4(0.0f, 0.0f, 0.0001f, 0.0f),
glm::vec4(0.0f, 0.0f, 0.0f, 1.0f));
auto cauterizeMatrix = _rig.getJointTransform(geometry.neckJointIndex) * zeroScale;
auto cauterizeMatrix = _rig.getJointTransform(hfmModel.neckJointIndex) * zeroScale;
for (int i = 0; i < _cauterizeMeshStates.size(); i++) {
Model::MeshState& state = _cauterizeMeshStates[i];
const HFMMesh& mesh = geometry.meshes.at(i);
const HFMMesh& mesh = hfmModel.meshes.at(i);
for (int j = 0; j < mesh.clusters.size(); j++) {
const HFMCluster& cluster = mesh.clusters.at(j);
@ -175,7 +175,7 @@ void CauterizedModel::updateClusterMatrices() {
// post the blender if we're not currently waiting for one to finish
auto modelBlender = DependencyManager::get<ModelBlender>();
if (_blendshapeOffsetsInitialized && modelBlender->shouldComputeBlendshapes() && geometry.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) {
if (_blendshapeOffsetsInitialized && modelBlender->shouldComputeBlendshapes() && hfmModel.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) {
_blendedBlendshapeCoefficients = _blendshapeCoefficients;
modelBlender->noteRequiresBlend(getThisPointer());
}

View file

@ -260,8 +260,8 @@ void ModelMeshPartPayload::initCache(const ModelPointer& model) {
_hasColorAttrib = vertexFormat->hasAttribute(gpu::Stream::COLOR);
_isSkinned = vertexFormat->hasAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT) && vertexFormat->hasAttribute(gpu::Stream::SKIN_CLUSTER_INDEX);
const HFMGeometry& geometry = model->getHFMGeometry();
const HFMMesh& mesh = geometry.meshes.at(_meshIndex);
const HFMModel& hfmModel = model->getHFMModel();
const HFMMesh& mesh = hfmModel.meshes.at(_meshIndex);
_isBlendShaped = !mesh.blendshapes.isEmpty();
_hasTangents = !mesh.tangents.isEmpty();

View file

@ -183,11 +183,11 @@ bool Model::shouldInvalidatePayloadShapeKey(int meshIndex) {
return true;
}
const HFMGeometry& geometry = getHFMGeometry();
const HFMModel& hfmModel = getHFMModel();
const auto& networkMeshes = getGeometry()->getMeshes();
// if our index is ever out of range for either meshes or networkMeshes, then skip it, and set our _meshGroupsKnown
// to false to rebuild out mesh groups.
if (meshIndex < 0 || meshIndex >= (int)networkMeshes.size() || meshIndex >= (int)geometry.meshes.size() || meshIndex >= (int)_meshStates.size()) {
if (meshIndex < 0 || meshIndex >= (int)networkMeshes.size() || meshIndex >= (int)hfmModel.meshes.size() || meshIndex >= (int)_meshStates.size()) {
_needsFixupInScene = true; // trigger remove/add cycle
invalidCalculatedMeshBoxes(); // if we have to reload, we need to assume our mesh boxes are all invalid
return true;
@ -278,8 +278,8 @@ void Model::setRenderItemsNeedUpdate() {
void Model::reset() {
if (isLoaded()) {
const HFMGeometry& geometry = getHFMGeometry();
_rig.reset(geometry);
const HFMModel& hfmModel = getHFMModel();
_rig.reset(hfmModel);
emit rigReset();
emit rigReady();
}
@ -295,13 +295,13 @@ bool Model::updateGeometry() {
_needsReload = false;
// TODO: should all Models have a valid _rig?
if (_rig.jointStatesEmpty() && getHFMGeometry().joints.size() > 0) {
if (_rig.jointStatesEmpty() && getHFMModel().joints.size() > 0) {
initJointStates();
assert(_meshStates.empty());
const HFMGeometry& hfmGeometry = getHFMGeometry();
const HFMModel& hfmModel = getHFMModel();
int i = 0;
foreach (const HFMMesh& mesh, hfmGeometry.meshes) {
foreach (const HFMMesh& mesh, hfmModel.meshes) {
MeshState state;
state.clusterDualQuaternions.resize(mesh.clusters.size());
state.clusterMatrices.resize(mesh.clusters.size());
@ -319,10 +319,10 @@ bool Model::updateGeometry() {
// virtual
void Model::initJointStates() {
const HFMGeometry& geometry = getHFMGeometry();
const HFMModel& hfmModel = getHFMModel();
glm::mat4 modelOffset = glm::scale(_scale) * glm::translate(_offset);
_rig.initJointStates(geometry, modelOffset);
_rig.initJointStates(hfmModel, modelOffset);
}
bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const glm::vec3& direction, float& distance,
@ -363,9 +363,9 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g
int bestShapeID = 0;
int bestSubMeshIndex = 0;
const HFMGeometry& geometry = getHFMGeometry();
const HFMModel& hfmModel = getHFMModel();
if (!_triangleSetsValid) {
calculateTriangleSets(geometry);
calculateTriangleSets(hfmModel);
}
glm::mat4 meshToModelMatrix = glm::scale(_scale) * glm::translate(_offset);
@ -448,7 +448,7 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g
extraInfo["shapeID"] = bestShapeID;
if (pickAgainstTriangles) {
extraInfo["subMeshIndex"] = bestSubMeshIndex;
extraInfo["subMeshName"] = geometry.getModelNameOfMesh(bestSubMeshIndex);
extraInfo["subMeshName"] = hfmModel.getModelNameOfMesh(bestSubMeshIndex);
extraInfo["subMeshTriangleWorld"] = QVariantMap{
{ "v0", vec3toVariant(bestWorldTriangle.v0) },
{ "v1", vec3toVariant(bestWorldTriangle.v1) },
@ -506,9 +506,9 @@ bool Model::findParabolaIntersectionAgainstSubMeshes(const glm::vec3& origin, co
int bestShapeID = 0;
int bestSubMeshIndex = 0;
const HFMGeometry& geometry = getHFMGeometry();
const HFMModel& hfmModel = getHFMModel();
if (!_triangleSetsValid) {
calculateTriangleSets(geometry);
calculateTriangleSets(hfmModel);
}
glm::mat4 meshToModelMatrix = glm::scale(_scale) * glm::translate(_offset);
@ -595,7 +595,7 @@ bool Model::findParabolaIntersectionAgainstSubMeshes(const glm::vec3& origin, co
extraInfo["shapeID"] = bestShapeID;
if (pickAgainstTriangles) {
extraInfo["subMeshIndex"] = bestSubMeshIndex;
extraInfo["subMeshName"] = geometry.getModelNameOfMesh(bestSubMeshIndex);
extraInfo["subMeshName"] = hfmModel.getModelNameOfMesh(bestSubMeshIndex);
extraInfo["subMeshTriangleWorld"] = QVariantMap{
{ "v0", vec3toVariant(bestWorldTriangle.v0) },
{ "v1", vec3toVariant(bestWorldTriangle.v1) },
@ -641,7 +641,7 @@ bool Model::convexHullContains(glm::vec3 point) {
QMutexLocker locker(&_mutex);
if (!_triangleSetsValid) {
calculateTriangleSets(getHFMGeometry());
calculateTriangleSets(getHFMModel());
}
// If we are inside the models box, then consider the submeshes...
@ -753,7 +753,7 @@ bool Model::replaceScriptableModelMeshPart(scriptable::ScriptableModelBasePointe
}
// update triangles for picking
{
HFMGeometry geometry;
HFMModel hfmModel;
for (const auto& newMesh : meshes) {
HFMMesh mesh;
mesh._mesh = newMesh.getMeshPointer();
@ -767,15 +767,15 @@ bool Model::replaceScriptableModelMeshPart(scriptable::ScriptableModelBasePointe
{
foreach (const glm::vec3& vertex, mesh.vertices) {
glm::vec3 transformedVertex = glm::vec3(mesh.modelTransform * glm::vec4(vertex, 1.0f));
geometry.meshExtents.minimum = glm::min(geometry.meshExtents.minimum, transformedVertex);
geometry.meshExtents.maximum = glm::max(geometry.meshExtents.maximum, transformedVertex);
hfmModel.meshExtents.minimum = glm::min(hfmModel.meshExtents.minimum, transformedVertex);
hfmModel.meshExtents.maximum = glm::max(hfmModel.meshExtents.maximum, transformedVertex);
mesh.meshExtents.minimum = glm::min(mesh.meshExtents.minimum, transformedVertex);
mesh.meshExtents.maximum = glm::max(mesh.meshExtents.maximum, transformedVertex);
}
}
geometry.meshes << mesh;
hfmModel.meshes << mesh;
}
calculateTriangleSets(geometry);
calculateTriangleSets(hfmModel);
}
return true;
}
@ -789,11 +789,11 @@ scriptable::ScriptableModelBase Model::getScriptableModel() {
return result;
}
const HFMGeometry& geometry = getHFMGeometry();
int numberOfMeshes = geometry.meshes.size();
const HFMModel& hfmModel = getHFMModel();
int numberOfMeshes = hfmModel.meshes.size();
int shapeID = 0;
for (int i = 0; i < numberOfMeshes; i++) {
const HFMMesh& hfmMesh = geometry.meshes.at(i);
const HFMMesh& hfmMesh = hfmModel.meshes.at(i);
if (auto mesh = hfmMesh._mesh) {
result.append(mesh);
@ -808,17 +808,17 @@ scriptable::ScriptableModelBase Model::getScriptableModel() {
return result;
}
void Model::calculateTriangleSets(const HFMGeometry& geometry) {
void Model::calculateTriangleSets(const HFMModel& hfmModel) {
PROFILE_RANGE(render, __FUNCTION__);
int numberOfMeshes = geometry.meshes.size();
int numberOfMeshes = hfmModel.meshes.size();
_triangleSetsValid = true;
_modelSpaceMeshTriangleSets.clear();
_modelSpaceMeshTriangleSets.resize(numberOfMeshes);
for (int i = 0; i < numberOfMeshes; i++) {
const HFMMesh& mesh = geometry.meshes.at(i);
const HFMMesh& mesh = hfmModel.meshes.at(i);
const int numberOfParts = mesh.parts.size();
auto& meshTriangleSets = _modelSpaceMeshTriangleSets[i];
@ -839,7 +839,7 @@ void Model::calculateTriangleSets(const HFMGeometry& geometry) {
int totalTriangles = (numberOfQuads * TRIANGLES_PER_QUAD) + numberOfTris;
partTriangleSet.reserve(totalTriangles);
auto meshTransform = geometry.offset * mesh.modelTransform;
auto meshTransform = hfmModel.offset * mesh.modelTransform;
if (part.quadIndices.size() > 0) {
int vIndex = 0;
@ -1114,7 +1114,7 @@ Extents Model::getBindExtents() const {
if (!isActive()) {
return Extents();
}
const Extents& bindExtents = getHFMGeometry().bindExtents;
const Extents& bindExtents = getHFMModel().bindExtents;
Extents scaledExtents = { bindExtents.minimum * _scale, bindExtents.maximum * _scale };
return scaledExtents;
}
@ -1128,12 +1128,12 @@ Extents Model::getMeshExtents() const {
if (!isActive()) {
return Extents();
}
const Extents& extents = getHFMGeometry().meshExtents;
const Extents& extents = getHFMModel().meshExtents;
// even though our caller asked for "unscaled" we need to include any fst scaling, translation, and rotation, which
// is captured in the offset matrix
glm::vec3 minimum = glm::vec3(getHFMGeometry().offset * glm::vec4(extents.minimum, 1.0f));
glm::vec3 maximum = glm::vec3(getHFMGeometry().offset * glm::vec4(extents.maximum, 1.0f));
glm::vec3 minimum = glm::vec3(getHFMModel().offset * glm::vec4(extents.minimum, 1.0f));
glm::vec3 maximum = glm::vec3(getHFMModel().offset * glm::vec4(extents.maximum, 1.0f));
Extents scaledExtents = { minimum * _scale, maximum * _scale };
return scaledExtents;
}
@ -1143,12 +1143,12 @@ Extents Model::getUnscaledMeshExtents() const {
return Extents();
}
const Extents& extents = getHFMGeometry().meshExtents;
const Extents& extents = getHFMModel().meshExtents;
// even though our caller asked for "unscaled" we need to include any fst scaling, translation, and rotation, which
// is captured in the offset matrix
glm::vec3 minimum = glm::vec3(getHFMGeometry().offset * glm::vec4(extents.minimum, 1.0f));
glm::vec3 maximum = glm::vec3(getHFMGeometry().offset * glm::vec4(extents.maximum, 1.0f));
glm::vec3 minimum = glm::vec3(getHFMModel().offset * glm::vec4(extents.minimum, 1.0f));
glm::vec3 maximum = glm::vec3(getHFMModel().offset * glm::vec4(extents.maximum, 1.0f));
Extents scaledExtents = { minimum, maximum };
return scaledExtents;
@ -1171,11 +1171,11 @@ void Model::setJointTranslation(int index, bool valid, const glm::vec3& translat
}
int Model::getParentJointIndex(int jointIndex) const {
return (isActive() && jointIndex != -1) ? getHFMGeometry().joints.at(jointIndex).parentIndex : -1;
return (isActive() && jointIndex != -1) ? getHFMModel().joints.at(jointIndex).parentIndex : -1;
}
int Model::getLastFreeJointIndex(int jointIndex) const {
return (isActive() && jointIndex != -1) ? getHFMGeometry().joints.at(jointIndex).freeLineage.last() : -1;
return (isActive() && jointIndex != -1) ? getHFMModel().joints.at(jointIndex).freeLineage.last() : -1;
}
void Model::setTextures(const QVariantMap& textures) {
@ -1275,7 +1275,7 @@ QStringList Model::getJointNames() const {
Q_RETURN_ARG(QStringList, result));
return result;
}
return isActive() ? getHFMGeometry().getJointNames() : QStringList();
return isActive() ? getHFMModel().getJointNames() : QStringList();
}
void Model::setScaleToFit(bool scaleToFit, const glm::vec3& dimensions, bool forceRescale) {
@ -1415,10 +1415,10 @@ void Model::updateClusterMatrices() {
}
_needsUpdateClusterMatrices = false;
const HFMGeometry& geometry = getHFMGeometry();
const HFMModel& hfmModel = getHFMModel();
for (int i = 0; i < (int) _meshStates.size(); i++) {
MeshState& state = _meshStates[i];
const HFMMesh& mesh = geometry.meshes.at(i);
const HFMMesh& mesh = hfmModel.meshes.at(i);
for (int j = 0; j < mesh.clusters.size(); j++) {
const HFMCluster& cluster = mesh.clusters.at(j);
if (_useDualQuaternionSkinning) {
@ -1436,7 +1436,7 @@ void Model::updateClusterMatrices() {
// post the blender if we're not currently waiting for one to finish
auto modelBlender = DependencyManager::get<ModelBlender>();
if (_blendshapeOffsetsInitialized && modelBlender->shouldComputeBlendshapes() && geometry.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) {
if (_blendshapeOffsetsInitialized && modelBlender->shouldComputeBlendshapes() && hfmModel.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) {
_blendedBlendshapeCoefficients = _blendshapeCoefficients;
modelBlender->noteRequiresBlend(getThisPointer());
}
@ -1505,7 +1505,7 @@ void Model::createRenderItemSet() {
// Run through all of the meshes, and place them into their segregated, but unsorted buckets
int shapeID = 0;
uint32_t numMeshes = (uint32_t)meshes.size();
auto& hfmGeometry = getHFMGeometry();
auto& hfmModel = getHFMModel();
for (uint32_t i = 0; i < numMeshes; i++) {
const auto& mesh = meshes.at(i);
if (!mesh) {
@ -1515,7 +1515,7 @@ void Model::createRenderItemSet() {
// Create the render payloads
int numParts = (int)mesh->getNumParts();
for (int partIndex = 0; partIndex < numParts; partIndex++) {
initializeBlendshapes(hfmGeometry.meshes[i], i);
initializeBlendshapes(hfmModel.meshes[i], i);
_modelMeshRenderItems << std::make_shared<ModelMeshPartPayload>(shared_from_this(), i, partIndex, shapeID, transform, offset);
auto material = getGeometry()->getShapeMaterial(shapeID);
_modelMeshMaterialNames.push_back(material ? material->getName() : "");
@ -1600,7 +1600,7 @@ void Model::removeMaterial(graphics::MaterialPointer material, const std::string
class CollisionRenderGeometry : public Geometry {
public:
CollisionRenderGeometry(graphics::MeshPointer mesh) {
_hfmGeometry = std::make_shared<HFMGeometry>();
_hfmModel = std::make_shared<HFMModel>();
std::shared_ptr<GeometryMeshes> meshes = std::make_shared<GeometryMeshes>();
meshes->push_back(mesh);
_meshes = meshes;
@ -1656,7 +1656,7 @@ void Blender::run() {
if (_model && _model->isLoaded()) {
DETAILED_PROFILE_RANGE_EX(simulation_animation, __FUNCTION__, 0xFFFF0000, 0, { { "url", _model->getURL().toString() } });
int offset = 0;
auto meshes = _model->getHFMGeometry().meshes;
auto meshes = _model->getHFMModel().meshes;
int meshIndex = 0;
foreach(const HFMMesh& mesh, meshes) {
auto modelMeshBlendshapeOffsets = _model->_blendshapeOffsets.find(meshIndex++);

View file

@ -163,7 +163,7 @@ public:
bool maybeStartBlender();
bool isLoaded() const { return (bool)_renderGeometry && _renderGeometry->isGeometryLoaded(); }
bool isLoaded() const { return (bool)_renderGeometry && _renderGeometry->isHFMModelLoaded(); }
bool isAddedToScene() const { return _addedToScene; }
void setIsWireframe(bool isWireframe) { _isWireframe = isWireframe; }
@ -184,8 +184,8 @@ public:
Q_INVOKABLE virtual void setTextures(const QVariantMap& textures);
/// Provided as a convenience, will crash if !isLoaded()
// And so that getGeometry() isn't chained everywhere
const HFMGeometry& getHFMGeometry() const { assert(isLoaded()); return _renderGeometry->getHFMGeometry(); }
// And so that getHFMModel() isn't chained everywhere
const HFMModel& getHFMModel() const { assert(isLoaded()); return _renderGeometry->getHFMModel(); }
bool isActive() const { return isLoaded(); }
@ -450,7 +450,7 @@ protected:
bool _overrideModelTransform { false };
bool _triangleSetsValid { false };
void calculateTriangleSets(const HFMGeometry& geometry);
void calculateTriangleSets(const HFMModel& hfmModel);
std::vector<std::vector<TriangleSet>> _modelSpaceMeshTriangleSets; // model space triangles for all sub meshes
virtual void createRenderItemSet();

View file

@ -41,11 +41,11 @@ void SoftAttachmentModel::updateClusterMatrices() {
_needsUpdateClusterMatrices = false;
const HFMGeometry& geometry = getHFMGeometry();
const HFMModel& hfmModel = getHFMModel();
for (int i = 0; i < (int) _meshStates.size(); i++) {
MeshState& state = _meshStates[i];
const HFMMesh& mesh = geometry.meshes.at(i);
const HFMMesh& mesh = hfmModel.meshes.at(i);
for (int j = 0; j < mesh.clusters.size(); j++) {
const HFMCluster& cluster = mesh.clusters.at(j);
@ -78,7 +78,7 @@ void SoftAttachmentModel::updateClusterMatrices() {
// post the blender if we're not currently waiting for one to finish
auto modelBlender = DependencyManager::get<ModelBlender>();
if (_blendshapeOffsetsInitialized && modelBlender->shouldComputeBlendshapes() && geometry.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) {
if (_blendshapeOffsetsInitialized && modelBlender->shouldComputeBlendshapes() && hfmModel.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) {
_blendedBlendshapeCoefficients = _blendshapeCoefficients;
modelBlender->noteRequiresBlend(getThisPointer());
}

View file

@ -100,12 +100,12 @@ bool TestFbx::isReady() const {
void TestFbx::parseFbx(const QByteArray& fbxData) {
QVariantHash mapping;
HFMGeometry* geometry = readFBX(fbxData, mapping);
HFMModel* hfmModel = readFBX(fbxData, mapping);
size_t totalVertexCount = 0;
size_t totalIndexCount = 0;
size_t totalPartCount = 0;
size_t highestIndex = 0;
for (const auto& mesh : geometry->meshes) {
for (const auto& mesh : hfmModel->meshes) {
size_t vertexCount = mesh.vertices.size();
totalVertexCount += mesh.vertices.size();
highestIndex = std::max(highestIndex, vertexCount);
@ -123,7 +123,7 @@ void TestFbx::parseFbx(const QByteArray& fbxData) {
std::vector<DrawElementsIndirectCommand> parts;
parts.reserve(totalPartCount);
_partCount = totalPartCount;
for (const auto& mesh : geometry->meshes) {
for (const auto& mesh : hfmModel->meshes) {
baseVertex = vertices.size();
vec3 color;
@ -133,7 +133,7 @@ void TestFbx::parseFbx(const QByteArray& fbxData) {
partIndirect.firstIndex = (uint)indices.size();
partIndirect.baseInstance = (uint)parts.size();
_partTransforms.push_back(mesh.modelTransform);
auto material = geometry->materials[part.materialID];
auto material = hfmModel->materials[part.materialID];
color = material.diffuseColor;
for (auto index : part.quadTrianglesIndices) {
indices.push_back(index);
@ -163,7 +163,7 @@ void TestFbx::parseFbx(const QByteArray& fbxData) {
_vertexBuffer->append(vertices);
_indexBuffer->append(indices);
_indirectBuffer->append(parts);
delete geometry;
delete hfmModel;
}
void TestFbx::renderTest(size_t testId, RenderArgs* args) {

View file

@ -11,7 +11,7 @@
#include <render/ShapePipeline.h>
class HFMGeometry;
class HFMModel;
class TestFbx : public GpuTestBase {
size_t _partCount { 0 };

View file

@ -28,7 +28,7 @@ const glm::quat identity = glm::quat();
const glm::quat quaterTurnAroundZ = glm::angleAxis(0.5f * PI, zAxis);
void makeTestFBXJoints(HFMGeometry& geometry) {
void makeTestFBXJoints(HFMModel& hfmModel) {
HFMJoint joint;
joint.isFree = false;
joint.freeLineage.clear();
@ -60,29 +60,29 @@ void makeTestFBXJoints(HFMGeometry& geometry) {
joint.name = "A";
joint.parentIndex = -1;
joint.translation = origin;
geometry.joints.push_back(joint);
hfmModel.joints.push_back(joint);
joint.name = "B";
joint.parentIndex = 0;
joint.translation = xAxis;
geometry.joints.push_back(joint);
hfmModel.joints.push_back(joint);
joint.name = "C";
joint.parentIndex = 1;
joint.translation = xAxis;
geometry.joints.push_back(joint);
hfmModel.joints.push_back(joint);
joint.name = "D";
joint.parentIndex = 2;
joint.translation = xAxis;
geometry.joints.push_back(joint);
hfmModel.joints.push_back(joint);
// compute each joint's transform
for (int i = 1; i < (int)geometry.joints.size(); ++i) {
HFMJoint& j = geometry.joints[i];
for (int i = 1; i < (int)hfmModel.joints.size(); ++i) {
HFMJoint& j = hfmModel.joints[i];
int parentIndex = j.parentIndex;
// World = ParentWorld * T * (Roff * Rp) * Rpre * R * Rpost * (Rp-1 * Soff * Sp * S * Sp-1)
j.transform = geometry.joints[parentIndex].transform *
j.transform = hfmModel.joints[parentIndex].transform *
glm::translate(j.translation) *
j.preTransform *
glm::mat4_cast(j.preRotation * j.rotation * j.postRotation) *
@ -96,12 +96,12 @@ void AnimInverseKinematicsTests::testSingleChain() {
AnimContext context(false, false, false, glm::mat4(), glm::mat4());
HFMGeometry geometry;
makeTestFBXJoints(geometry);
HFMModel hfmModel;
makeTestFBXJoints(hfmModel);
// create a skeleton and doll
AnimPose offset;
AnimSkeleton::Pointer skeletonPtr = std::make_shared<AnimSkeleton>(geometry);
AnimSkeleton::Pointer skeletonPtr = std::make_shared<AnimSkeleton>(hfmModel);
AnimInverseKinematics ikDoll("doll");
ikDoll.setSkeleton(skeletonPtr);
@ -119,7 +119,7 @@ void AnimInverseKinematicsTests::testSingleChain() {
poses.push_back(pose);
pose.trans() = xAxis;
for (int i = 1; i < (int)geometry.joints.size(); ++i) {
for (int i = 1; i < (int)hfmModel.joints.size(); ++i) {
poses.push_back(pose);
}
ikDoll.loadPoses(poses);

View file

@ -54,7 +54,7 @@ SkeletonDumpApp::SkeletonDumpApp(int argc, char* argv[]) : QCoreApplication(argc
return;
}
QByteArray blob = file.readAll();
std::unique_ptr<HFMGeometry> geometry(readFBX(blob, QVariantHash()));
std::unique_ptr<HFMModel> geometry(readFBX(blob, QVariantHash()));
std::unique_ptr<AnimSkeleton> skeleton(new AnimSkeleton(*geometry));
skeleton->dump(verbose);
}

View file

@ -19,16 +19,16 @@
// FBXReader jumbles the order of the meshes by reading them back out of a hashtable. This will put
// them back in the order in which they appeared in the file.
bool HFMGeometryLessThan(const HFMMesh& e1, const HFMMesh& e2) {
bool HFMModelLessThan(const HFMMesh& e1, const HFMMesh& e2) {
return e1.meshIndex < e2.meshIndex;
}
void reSortHFMGeometryMeshes(HFMGeometry& geometry) {
qSort(geometry.meshes.begin(), geometry.meshes.end(), HFMGeometryLessThan);
void reSortHFMModelMeshes(HFMModel& hfmModel) {
qSort(hfmModel.meshes.begin(), hfmModel.meshes.end(), HFMModelLessThan);
}
// Read all the meshes from provided FBX file
bool vhacd::VHACDUtil::loadFBX(const QString filename, HFMGeometry& result) {
bool vhacd::VHACDUtil::loadFBX(const QString filename, HFMModel& result) {
if (_verbose) {
qDebug() << "reading FBX file =" << filename << "...";
}
@ -41,19 +41,19 @@ bool vhacd::VHACDUtil::loadFBX(const QString filename, HFMGeometry& result) {
}
try {
QByteArray fbxContents = fbx.readAll();
HFMGeometry::Pointer geom;
HFMModel::Pointer hfmModel;
if (filename.toLower().endsWith(".obj")) {
bool combineParts = false;
geom = OBJReader().readOBJ(fbxContents, QVariantHash(), combineParts);
hfmModel = OBJReader().readOBJ(fbxContents, QVariantHash(), combineParts);
} else if (filename.toLower().endsWith(".fbx")) {
geom.reset(readFBX(fbxContents, QVariantHash(), filename));
hfmModel.reset(readFBX(fbxContents, QVariantHash(), filename));
} else {
qWarning() << "file has unknown extension" << filename;
return false;
}
result = *geom;
result = *hfmModel;
reSortHFMGeometryMeshes(result);
reSortHFMModelMeshes(result);
} catch (const QString& error) {
qWarning() << "error reading" << filename << ":" << error;
return false;
@ -88,7 +88,7 @@ void getTrianglesInMeshPart(const HFMMeshPart &meshPart, std::vector<int>& trian
}
}
void vhacd::VHACDUtil::fattenMesh(const HFMMesh& mesh, const glm::mat4& geometryOffset, HFMMesh& result) const {
void vhacd::VHACDUtil::fattenMesh(const HFMMesh& mesh, const glm::mat4& modelOffset, HFMMesh& result) const {
// this is used to make meshes generated from a highfield collidable. each triangle
// is converted into a tetrahedron and made into its own mesh-part.
@ -104,7 +104,7 @@ void vhacd::VHACDUtil::fattenMesh(const HFMMesh& mesh, const glm::mat4& geometry
int indexStartOffset = result.vertices.size();
// new mesh gets the transformed points from the original
glm::mat4 totalTransform = geometryOffset * mesh.modelTransform;
glm::mat4 totalTransform = modelOffset * mesh.modelTransform;
for (int i = 0; i < mesh.vertices.size(); i++) {
// apply the source mesh's transform to the points
glm::vec4 v = totalTransform * glm::vec4(mesh.vertices[i], 1.0f);
@ -288,17 +288,17 @@ float computeDt(uint64_t start) {
return (float)(usecTimestampNow() - start) / (float)USECS_PER_SECOND;
}
bool vhacd::VHACDUtil::computeVHACD(HFMGeometry& geometry,
bool vhacd::VHACDUtil::computeVHACD(HFMModel& hfmModel,
VHACD::IVHACD::Parameters params,
HFMGeometry& result,
HFMModel& result,
float minimumMeshSize, float maximumMeshSize) {
if (_verbose) {
qDebug() << "meshes =" << geometry.meshes.size();
qDebug() << "meshes =" << hfmModel.meshes.size();
}
// count the mesh-parts
int numParts = 0;
foreach (const HFMMesh& mesh, geometry.meshes) {
foreach (const HFMMesh& mesh, hfmModel.meshes) {
numParts += mesh.parts.size();
}
if (_verbose) {
@ -316,7 +316,7 @@ bool vhacd::VHACDUtil::computeVHACD(HFMGeometry& geometry,
int meshIndex = 0;
int validPartsFound = 0;
foreach (const HFMMesh& mesh, geometry.meshes) {
foreach (const HFMMesh& mesh, hfmModel.meshes) {
// find duplicate points
int numDupes = 0;
@ -337,7 +337,7 @@ bool vhacd::VHACDUtil::computeVHACD(HFMGeometry& geometry,
// each mesh has its own transform to move it to model-space
std::vector<glm::vec3> vertices;
glm::mat4 totalTransform = geometry.offset * mesh.modelTransform;
glm::mat4 totalTransform = hfmModel.offset * mesh.modelTransform;
foreach (glm::vec3 vertex, mesh.vertices) {
vertices.push_back(glm::vec3(totalTransform * glm::vec4(vertex, 1.0f)));
}

View file

@ -27,13 +27,13 @@ namespace vhacd {
public:
void setVerbose(bool verbose) { _verbose = verbose; }
bool loadFBX(const QString filename, HFMGeometry& result);
bool loadFBX(const QString filename, HFMModel& result);
void fattenMesh(const HFMMesh& mesh, const glm::mat4& gometryOffset, HFMMesh& result) const;
void fattenMesh(const HFMMesh& mesh, const glm::mat4& modelOffset, HFMMesh& result) const;
bool computeVHACD(HFMGeometry& geometry,
bool computeVHACD(HFMModel& hfmModel,
VHACD::IVHACD::Parameters params,
HFMGeometry& result,
HFMModel& result,
float minimumMeshSize, float maximumMeshSize);
void getConvexResults(VHACD::IVHACD* convexifier, HFMMesh& resultMesh) const;

View file

@ -36,7 +36,7 @@ QString formatFloat(double n) {
}
bool VHACDUtilApp::writeOBJ(QString outFileName, HFMGeometry& geometry, bool outputCentimeters, int whichMeshPart) {
bool VHACDUtilApp::writeOBJ(QString outFileName, HFMModel& hfmModel, bool outputCentimeters, int whichMeshPart) {
QFile file(outFileName);
if (!file.open(QIODevice::WriteOnly)) {
qWarning() << "unable to write to" << outFileName;
@ -56,7 +56,7 @@ bool VHACDUtilApp::writeOBJ(QString outFileName, HFMGeometry& geometry, bool out
int vertexIndexOffset = 0;
foreach (const HFMMesh& mesh, geometry.meshes) {
foreach (const HFMMesh& mesh, hfmModel.meshes) {
bool verticesHaveBeenOutput = false;
foreach (const HFMMeshPart &meshPart, mesh.parts) {
if (whichMeshPart >= 0 && nth != (unsigned int) whichMeshPart) {
@ -297,7 +297,7 @@ VHACDUtilApp::VHACDUtilApp(int argc, char* argv[]) :
}
// load the mesh
HFMGeometry fbx;
HFMModel fbx;
auto begin = std::chrono::high_resolution_clock::now();
if (!vUtil.loadFBX(inputFilename, fbx)){
_returnCode = VHACD_RETURN_CODE_FAILURE_TO_READ;
@ -358,7 +358,7 @@ VHACDUtilApp::VHACDUtilApp(int argc, char* argv[]) :
}
begin = std::chrono::high_resolution_clock::now();
HFMGeometry result;
HFMModel result;
bool success = vUtil.computeVHACD(fbx, params, result, minimumMeshSize, maximumMeshSize);
end = std::chrono::high_resolution_clock::now();
@ -398,7 +398,7 @@ VHACDUtilApp::VHACDUtilApp(int argc, char* argv[]) :
}
if (fattenFaces) {
HFMGeometry newFbx;
HFMModel newFbx;
HFMMesh result;
// count the mesh-parts

View file

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