Merge pull request #14308 from sabrina-shanman/fbx2hfm

(case 19302) Re-name FBXGeometry to HFMGeometry and do the same for related classes
This commit is contained in:
Brad Hefta-Gaub 2018-11-02 16:44:31 -07:00 committed by GitHub
commit d0181283dd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
52 changed files with 613 additions and 613 deletions

View file

@ -69,10 +69,10 @@ void ScriptableAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) {
AvatarData::setSkeletonModelURL(skeletonModelURL); AvatarData::setSkeletonModelURL(skeletonModelURL);
} }
static AnimPose composeAnimPose(const FBXJoint& fbxJoint, const glm::quat rotation, const glm::vec3 translation) { static AnimPose composeAnimPose(const HFMJoint& joint, const glm::quat rotation, const glm::vec3 translation) {
glm::mat4 translationMat = glm::translate(translation); glm::mat4 translationMat = glm::translate(translation);
glm::mat4 rotationMat = glm::mat4_cast(fbxJoint.preRotation * rotation * fbxJoint.postRotation); glm::mat4 rotationMat = glm::mat4_cast(joint.preRotation * rotation * joint.postRotation);
glm::mat4 finalMat = translationMat * fbxJoint.preTransform * rotationMat * fbxJoint.postTransform; glm::mat4 finalMat = translationMat * joint.preTransform * rotationMat * joint.postTransform;
return AnimPose(finalMat); return AnimPose(finalMat);
} }
@ -93,7 +93,7 @@ void ScriptableAvatar::update(float deltatime) {
} }
_animationDetails.currentFrame = currentFrame; _animationDetails.currentFrame = currentFrame;
const QVector<FBXJoint>& modelJoints = _bind->getGeometry().joints; const QVector<HFMJoint>& modelJoints = _bind->getGeometry().joints;
QStringList animationJointNames = _animation->getJointNames(); QStringList animationJointNames = _animation->getJointNames();
const int nJoints = modelJoints.size(); const int nJoints = modelJoints.size();
@ -102,8 +102,8 @@ void ScriptableAvatar::update(float deltatime) {
} }
const int frameCount = _animation->getFrames().size(); const int frameCount = _animation->getFrames().size();
const FBXAnimationFrame& floorFrame = _animation->getFrames().at((int)glm::floor(currentFrame) % frameCount); const HFMAnimationFrame& floorFrame = _animation->getFrames().at((int)glm::floor(currentFrame) % frameCount);
const FBXAnimationFrame& ceilFrame = _animation->getFrames().at((int)glm::ceil(currentFrame) % frameCount); const HFMAnimationFrame& ceilFrame = _animation->getFrames().at((int)glm::ceil(currentFrame) % frameCount);
const float frameFraction = glm::fract(currentFrame); const float frameFraction = glm::fract(currentFrame);
std::vector<AnimPose> poses = _animSkeleton->getRelativeDefaultPoses(); std::vector<AnimPose> poses = _animSkeleton->getRelativeDefaultPoses();

View file

@ -235,7 +235,7 @@ bool ModelPackager::zipModel() {
return true; return true;
} }
void ModelPackager::populateBasicMapping(QVariantHash& mapping, QString filename, const FBXGeometry& geometry) { void ModelPackager::populateBasicMapping(QVariantHash& mapping, QString filename, const HFMGeometry& geometry) {
bool isBodyType = _modelType == FSTReader::BODY_ONLY_MODEL || _modelType == FSTReader::HEAD_AND_BODY_MODEL; bool isBodyType = _modelType == FSTReader::BODY_ONLY_MODEL || _modelType == FSTReader::HEAD_AND_BODY_MODEL;
@ -370,7 +370,7 @@ void ModelPackager::populateBasicMapping(QVariantHash& mapping, QString filename
void ModelPackager::listTextures() { void ModelPackager::listTextures() {
_textures.clear(); _textures.clear();
foreach (const FBXMaterial mat, _geometry->materials) { foreach (const HFMMaterial mat, _geometry->materials) {
if (!mat.albedoTexture.filename.isEmpty() && mat.albedoTexture.content.isEmpty() && if (!mat.albedoTexture.filename.isEmpty() && mat.albedoTexture.content.isEmpty() &&
!_textures.contains(mat.albedoTexture.filename)) { !_textures.contains(mat.albedoTexture.filename)) {
_textures << mat.albedoTexture.filename; _textures << mat.albedoTexture.filename;

View file

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

View file

@ -27,7 +27,7 @@
ModelPropertiesDialog::ModelPropertiesDialog(FSTReader::ModelType modelType, const QVariantHash& originalMapping, ModelPropertiesDialog::ModelPropertiesDialog(FSTReader::ModelType modelType, const QVariantHash& originalMapping,
const QString& basePath, const FBXGeometry& geometry) : const QString& basePath, const HFMGeometry& geometry) :
_modelType(modelType), _modelType(modelType),
_originalMapping(originalMapping), _originalMapping(originalMapping),
_basePath(basePath), _basePath(basePath),
@ -249,7 +249,7 @@ QComboBox* ModelPropertiesDialog::createJointBox(bool withNone) const {
if (withNone) { if (withNone) {
box->addItem("(none)"); box->addItem("(none)");
} }
foreach (const FBXJoint& joint, _geometry.joints) { foreach (const HFMJoint& joint, _geometry.joints) {
if (joint.isSkeletonJoint || !_geometry.hasSkeletonJoints) { if (joint.isSkeletonJoint || !_geometry.hasSkeletonJoints) {
box->addItem(joint.name); box->addItem(joint.name);
} }

View file

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

View file

@ -155,7 +155,7 @@ MyAvatar::MyAvatar(QThread* thread) :
}); });
connect(_skeletonModel.get(), &Model::rigReady, this, [this]() { connect(_skeletonModel.get(), &Model::rigReady, this, [this]() {
if (_shouldLoadScripts) { if (_shouldLoadScripts) {
auto geometry = getSkeletonModel()->getFBXGeometry(); auto geometry = getSkeletonModel()->getHFMGeometry();
qApp->loadAvatarScripts(geometry.scripts); qApp->loadAvatarScripts(geometry.scripts);
_shouldLoadScripts = false; _shouldLoadScripts = false;
} }
@ -2429,10 +2429,10 @@ void MyAvatar::attachmentDataToEntityProperties(const AttachmentData& data, Enti
void MyAvatar::initHeadBones() { void MyAvatar::initHeadBones() {
int neckJointIndex = -1; int neckJointIndex = -1;
if (_skeletonModel->isLoaded()) { if (_skeletonModel->isLoaded()) {
neckJointIndex = _skeletonModel->getFBXGeometry().neckJointIndex; neckJointIndex = _skeletonModel->getHFMGeometry().neckJointIndex;
} }
if (neckJointIndex == -1) { if (neckJointIndex == -1) {
neckJointIndex = (_skeletonModel->getFBXGeometry().headJointIndex - 1); neckJointIndex = (_skeletonModel->getHFMGeometry().headJointIndex - 1);
if (neckJointIndex < 0) { if (neckJointIndex < 0) {
// return if the head is not even there. can't cauterize!! // return if the head is not even there. can't cauterize!!
return; return;
@ -2443,7 +2443,7 @@ void MyAvatar::initHeadBones() {
q.push(neckJointIndex); q.push(neckJointIndex);
_headBoneSet.insert(neckJointIndex); _headBoneSet.insert(neckJointIndex);
// fbxJoints only hold links to parents not children, so we have to do a bit of extra work here. // hfmJoints only hold links to parents not children, so we have to do a bit of extra work here.
while (q.size() > 0) { while (q.size() > 0) {
int jointIndex = q.front(); int jointIndex = q.front();
for (int i = 0; i < _skeletonModel->getJointStateCount(); i++) { for (int i = 0; i < _skeletonModel->getJointStateCount(); i++) {
@ -2592,11 +2592,11 @@ void MyAvatar::postUpdate(float deltaTime, const render::ScenePointer& scene) {
if (_skeletonModel && _skeletonModel->isLoaded()) { if (_skeletonModel && _skeletonModel->isLoaded()) {
const Rig& rig = _skeletonModel->getRig(); const Rig& rig = _skeletonModel->getRig();
const FBXGeometry& geometry = _skeletonModel->getFBXGeometry(); const HFMGeometry& geometry = _skeletonModel->getHFMGeometry();
for (int i = 0; i < rig.getJointStateCount(); i++) { for (int i = 0; i < rig.getJointStateCount(); i++) {
AnimPose jointPose; AnimPose jointPose;
rig.getAbsoluteJointPoseInRigFrame(i, jointPose); rig.getAbsoluteJointPoseInRigFrame(i, jointPose);
const FBXJointShapeInfo& shapeInfo = geometry.joints[i].shapeInfo; const HFMJointShapeInfo& shapeInfo = geometry.joints[i].shapeInfo;
const AnimPose pose = rigToWorldPose * jointPose; const AnimPose pose = rigToWorldPose * jointPose;
for (size_t j = 0; j < shapeInfo.debugLines.size() / 2; j++) { for (size_t j = 0; j < shapeInfo.debugLines.size() / 2; j++) {
glm::vec3 pointA = pose.xformPoint(shapeInfo.debugLines[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> MyAvatar::getScriptUrls() {
QVector<QString> scripts = _skeletonModel->isLoaded() ? _skeletonModel->getFBXGeometry().scripts : QVector<QString>(); QVector<QString> scripts = _skeletonModel->isLoaded() ? _skeletonModel->getHFMGeometry().scripts : QVector<QString>();
return scripts; return scripts;
} }

View file

@ -90,7 +90,7 @@ static AnimPose computeHipsInSensorFrame(MyAvatar* myAvatar, bool isFlying) {
// Called within Model::simulate call, below. // Called within Model::simulate call, below.
void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
const FBXGeometry& geometry = getFBXGeometry(); const HFMGeometry& geometry = getHFMGeometry();
Head* head = _owningAvatar->getHead(); Head* head = _owningAvatar->getHead();

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 // should never fall in here when collision model not fully loaded
// TODO: assert that all geometries exist and are loaded // TODO: assert that all geometries exist and are loaded
//assert(_model && _model->isLoaded() && _compoundShapeResource && _compoundShapeResource->isLoaded()); //assert(_model && _model->isLoaded() && _compoundShapeResource && _compoundShapeResource->isLoaded());
const FBXGeometry& collisionGeometry = resource->getFBXGeometry(); const HFMGeometry& collisionGeometry = resource->getHFMGeometry();
ShapeInfo::PointCollection& pointCollection = shapeInfo.getPointCollection(); ShapeInfo::PointCollection& pointCollection = shapeInfo.getPointCollection();
pointCollection.clear(); pointCollection.clear();
@ -139,15 +139,15 @@ 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 // 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. // to find one actual "mesh" (with one or more meshParts in it), but we loop over the meshes, just in case.
foreach (const FBXMesh& mesh, collisionGeometry.meshes) { foreach (const HFMMesh& mesh, collisionGeometry.meshes) {
// each meshPart is a convex hull // each meshPart is a convex hull
foreach (const FBXMeshPart &meshPart, mesh.parts) { foreach (const HFMMeshPart &meshPart, mesh.parts) {
pointCollection.push_back(QVector<glm::vec3>()); pointCollection.push_back(QVector<glm::vec3>());
ShapeInfo::PointList& pointsInPart = pointCollection[i]; ShapeInfo::PointList& pointsInPart = pointCollection[i];
// run through all the triangles and (uniquely) add each point to the hull // run through all the triangles and (uniquely) add each point to the hull
uint32_t numIndices = (uint32_t)meshPart.triangleIndices.size(); uint32_t numIndices = (uint32_t)meshPart.triangleIndices.size();
// TODO: assert rather than workaround after we start sanitizing FBXMesh higher up // TODO: assert rather than workaround after we start sanitizing HFMMesh higher up
//assert(numIndices % TRIANGLE_STRIDE == 0); //assert(numIndices % TRIANGLE_STRIDE == 0);
numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXReader numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXReader
@ -168,7 +168,7 @@ void CollisionPick::computeShapeInfo(const CollisionRegion& pick, ShapeInfo& sha
// run through all the quads and (uniquely) add each point to the hull // run through all the quads and (uniquely) add each point to the hull
numIndices = (uint32_t)meshPart.quadIndices.size(); numIndices = (uint32_t)meshPart.quadIndices.size();
// TODO: assert rather than workaround after we start sanitizing FBXMesh higher up // TODO: assert rather than workaround after we start sanitizing HFMMesh higher up
//assert(numIndices % QUAD_STRIDE == 0); //assert(numIndices % QUAD_STRIDE == 0);
numIndices -= numIndices % QUAD_STRIDE; // WORKAROUND lack of sanity checking in FBXReader numIndices -= numIndices % QUAD_STRIDE; // WORKAROUND lack of sanity checking in FBXReader
@ -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 // to the visual model and apply them to the collision model (without regard for the
// collision model's extents). // collision model's extents).
glm::vec3 scaleToFit = dimensions / resource->getFBXGeometry().getUnscaledMeshExtents().size(); glm::vec3 scaleToFit = dimensions / resource->getHFMGeometry().getUnscaledMeshExtents().size();
// multiply each point by scale // multiply each point by scale
for (int32_t i = 0; i < pointCollection.size(); i++) { for (int32_t i = 0; i < pointCollection.size(); i++) {
for (int32_t j = 0; j < pointCollection[i].size(); j++) { 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()); shapeInfo.setParams(type, dimensions, resource->getURL().toString());
} else if (type >= SHAPE_TYPE_SIMPLE_HULL && type <= SHAPE_TYPE_STATIC_MESH) { } else if (type >= SHAPE_TYPE_SIMPLE_HULL && type <= SHAPE_TYPE_STATIC_MESH) {
const FBXGeometry& fbxGeometry = resource->getFBXGeometry(); const HFMGeometry& hfmGeometry = resource->getHFMGeometry();
int numFbxMeshes = fbxGeometry.meshes.size(); int numHFMMeshes = hfmGeometry.meshes.size();
int totalNumVertices = 0; int totalNumVertices = 0;
for (int i = 0; i < numFbxMeshes; i++) { for (int i = 0; i < numHFMMeshes; i++) {
const FBXMesh& mesh = fbxGeometry.meshes.at(i); const HFMMesh& mesh = hfmGeometry.meshes.at(i);
totalNumVertices += mesh.vertices.size(); totalNumVertices += mesh.vertices.size();
} }
const int32_t MAX_VERTICES_PER_STATIC_MESH = 1e6; const int32_t MAX_VERTICES_PER_STATIC_MESH = 1e6;
@ -230,7 +230,7 @@ void CollisionPick::computeShapeInfo(const CollisionRegion& pick, ShapeInfo& sha
return; return;
} }
auto& meshes = resource->getFBXGeometry().meshes; auto& meshes = resource->getHFMGeometry().meshes;
int32_t numMeshes = (int32_t)(meshes.size()); int32_t numMeshes = (int32_t)(meshes.size());
const int MAX_ALLOWED_MESH_COUNT = 1000; const int MAX_ALLOWED_MESH_COUNT = 1000;
@ -285,12 +285,12 @@ void CollisionPick::computeShapeInfo(const CollisionRegion& pick, ShapeInfo& sha
if (type == SHAPE_TYPE_STATIC_MESH) { if (type == SHAPE_TYPE_STATIC_MESH) {
// copy into triangleIndices // copy into triangleIndices
size_t triangleIndicesCount = 0; size_t triangleIndicesCount = 0;
for (const FBXMeshPart& meshPart : mesh.parts) { for (const HFMMeshPart& meshPart : mesh.parts) {
triangleIndicesCount += meshPart.triangleIndices.count(); triangleIndicesCount += meshPart.triangleIndices.count();
} }
triangleIndices.reserve((int)triangleIndicesCount); triangleIndices.reserve((int)triangleIndicesCount);
for (const FBXMeshPart& meshPart : mesh.parts) { for (const HFMMeshPart& meshPart : mesh.parts) {
const int* indexItr = meshPart.triangleIndices.cbegin(); const int* indexItr = meshPart.triangleIndices.cbegin();
while (indexItr != meshPart.triangleIndices.cend()) { while (indexItr != meshPart.triangleIndices.cend()) {
triangleIndices.push_back(*indexItr); triangleIndices.push_back(*indexItr);
@ -299,11 +299,11 @@ void CollisionPick::computeShapeInfo(const CollisionRegion& pick, ShapeInfo& sha
} }
} else if (type == SHAPE_TYPE_SIMPLE_COMPOUND) { } else if (type == SHAPE_TYPE_SIMPLE_COMPOUND) {
// for each mesh copy unique part indices, separated by special bogus (flag) index values // for each mesh copy unique part indices, separated by special bogus (flag) index values
for (const FBXMeshPart& meshPart : mesh.parts) { for (const HFMMeshPart& meshPart : mesh.parts) {
// collect unique list of indices for this part // collect unique list of indices for this part
std::set<int32_t> uniqueIndices; std::set<int32_t> uniqueIndices;
auto numIndices = meshPart.triangleIndices.count(); auto numIndices = meshPart.triangleIndices.count();
// TODO: assert rather than workaround after we start sanitizing FBXMesh higher up // TODO: assert rather than workaround after we start sanitizing HFMMesh higher up
//assert(numIndices% TRIANGLE_STRIDE == 0); //assert(numIndices% TRIANGLE_STRIDE == 0);
numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXReader numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXReader

View file

@ -446,7 +446,7 @@ QVariant ModelOverlay::getProperty(const QString& property) {
if (property == "jointNames") { if (property == "jointNames") {
if (_model && _model->isActive()) { if (_model && _model->isActive()) {
// note: going through Rig because Model::getJointNames() (which proxies to FBXGeometry) was always empty // note: going through Rig because Model::getJointNames() (which proxies to HFMGeometry) was always empty
const Rig* rig = &(_model->getRig()); const Rig* rig = &(_model->getRig());
return mapJoints<QStringList, QString>([rig](int jointIndex) -> QString { return mapJoints<QStringList, QString>([rig](int jointIndex) -> QString {
return rig->nameOfJoint(jointIndex); return rig->nameOfJoint(jointIndex);
@ -574,7 +574,7 @@ void ModelOverlay::animate() {
QVector<JointData> jointsData; QVector<JointData> jointsData;
const QVector<FBXAnimationFrame>& frames = _animation->getFramesReference(); // NOTE: getFrames() is too heavy const QVector<HFMAnimationFrame>& frames = _animation->getFramesReference(); // NOTE: getFrames() is too heavy
int frameCount = frames.size(); int frameCount = frames.size();
if (frameCount <= 0) { if (frameCount <= 0) {
return; return;
@ -606,10 +606,10 @@ void ModelOverlay::animate() {
} }
QStringList animationJointNames = _animation->getGeometry().getJointNames(); QStringList animationJointNames = _animation->getGeometry().getJointNames();
auto& fbxJoints = _animation->getGeometry().joints; auto& hfmJoints = _animation->getGeometry().joints;
auto& originalFbxJoints = _model->getFBXGeometry().joints; auto& originalHFMJoints = _model->getHFMGeometry().joints;
auto& originalFbxIndices = _model->getFBXGeometry().jointIndices; auto& originalFbxIndices = _model->getHFMGeometry().jointIndices;
const QVector<glm::quat>& rotations = frames[_lastKnownCurrentFrame].rotations; const QVector<glm::quat>& rotations = frames[_lastKnownCurrentFrame].rotations;
const QVector<glm::vec3>& translations = frames[_lastKnownCurrentFrame].translations; const QVector<glm::vec3>& translations = frames[_lastKnownCurrentFrame].translations;
@ -626,23 +626,23 @@ void ModelOverlay::animate() {
translationMat = glm::translate(translations[index]); translationMat = glm::translate(translations[index]);
} }
} else if (index < animationJointNames.size()) { } else if (index < animationJointNames.size()) {
QString jointName = fbxJoints[index].name; QString jointName = hfmJoints[index].name;
if (originalFbxIndices.contains(jointName)) { if (originalFbxIndices.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. // 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 = originalFbxIndices[jointName] - 1; // JointIndeces seem to always start from 1 and the found index is always 1 higher than actual.
translationMat = glm::translate(originalFbxJoints[remappedIndex].translation); translationMat = glm::translate(originalHFMJoints[remappedIndex].translation);
} }
} }
glm::mat4 rotationMat; glm::mat4 rotationMat;
if (index < rotations.size()) { if (index < rotations.size()) {
rotationMat = glm::mat4_cast(fbxJoints[index].preRotation * rotations[index] * fbxJoints[index].postRotation); rotationMat = glm::mat4_cast(hfmJoints[index].preRotation * rotations[index] * hfmJoints[index].postRotation);
} else { } else {
rotationMat = glm::mat4_cast(fbxJoints[index].preRotation * fbxJoints[index].postRotation); rotationMat = glm::mat4_cast(hfmJoints[index].preRotation * hfmJoints[index].postRotation);
} }
glm::mat4 finalMat = (translationMat * fbxJoints[index].preTransform * glm::mat4 finalMat = (translationMat * hfmJoints[index].preTransform *
rotationMat * fbxJoints[index].postTransform); rotationMat * hfmJoints[index].postTransform);
auto& jointData = jointsData[j]; auto& jointData = jointsData[j];
jointData.translation = extractTranslation(finalMat); jointData.translation = extractTranslation(finalMat);
jointData.translationIsDefaultPose = false; jointData.translationIsDefaultPose = false;

View file

@ -101,7 +101,7 @@ void AnimClip::copyFromNetworkAnim() {
// build a mapping from animation joint indices to skeleton joint indices. // build a mapping from animation joint indices to skeleton joint indices.
// by matching joints with the same name. // by matching joints with the same name.
const FBXGeometry& geom = _networkAnim->getGeometry(); const HFMGeometry& geom = _networkAnim->getGeometry();
AnimSkeleton animSkeleton(geom); AnimSkeleton animSkeleton(geom);
const auto animJointCount = animSkeleton.getNumJoints(); const auto animJointCount = animSkeleton.getNumJoints();
const auto skeletonJointCount = _skeleton->getNumJoints(); const auto skeletonJointCount = _skeleton->getNumJoints();
@ -120,7 +120,7 @@ void AnimClip::copyFromNetworkAnim() {
for (int frame = 0; frame < frameCount; frame++) { for (int frame = 0; frame < frameCount; frame++) {
const FBXAnimationFrame& fbxAnimFrame = geom.animationFrames[frame]; const HFMAnimationFrame& hfmAnimFrame = geom.animationFrames[frame];
// init all joints in animation to default pose // init all joints in animation to default pose
// this will give us a resonable result for bones in the model skeleton but not in the animation. // this will give us a resonable result for bones in the model skeleton but not in the animation.
@ -132,8 +132,8 @@ void AnimClip::copyFromNetworkAnim() {
for (int animJoint = 0; animJoint < animJointCount; animJoint++) { for (int animJoint = 0; animJoint < animJointCount; animJoint++) {
int skeletonJoint = jointMap[animJoint]; int skeletonJoint = jointMap[animJoint];
const glm::vec3& fbxAnimTrans = fbxAnimFrame.translations[animJoint]; const glm::vec3& hfmAnimTrans = hfmAnimFrame.translations[animJoint];
const glm::quat& fbxAnimRot = fbxAnimFrame.rotations[animJoint]; const glm::quat& hfmAnimRot = hfmAnimFrame.rotations[animJoint];
// skip joints that are in the animation but not in the skeleton. // skip joints that are in the animation but not in the skeleton.
if (skeletonJoint >= 0 && skeletonJoint < skeletonJointCount) { if (skeletonJoint >= 0 && skeletonJoint < skeletonJointCount) {
@ -146,19 +146,19 @@ void AnimClip::copyFromNetworkAnim() {
preRot.scale() = glm::vec3(1.0f); preRot.scale() = glm::vec3(1.0f);
postRot.scale() = glm::vec3(1.0f); postRot.scale() = glm::vec3(1.0f);
AnimPose rot(glm::vec3(1.0f), fbxAnimRot, glm::vec3()); AnimPose rot(glm::vec3(1.0f), hfmAnimRot, glm::vec3());
// adjust translation offsets, so large translation animatons on the reference skeleton // adjust translation offsets, so large translation animatons on the reference skeleton
// will be adjusted when played on a skeleton with short limbs. // will be adjusted when played on a skeleton with short limbs.
const glm::vec3& fbxZeroTrans = geom.animationFrames[0].translations[animJoint]; const glm::vec3& hfmZeroTrans = geom.animationFrames[0].translations[animJoint];
const AnimPose& relDefaultPose = _skeleton->getRelativeDefaultPose(skeletonJoint); const AnimPose& relDefaultPose = _skeleton->getRelativeDefaultPose(skeletonJoint);
float boneLengthScale = 1.0f; float boneLengthScale = 1.0f;
const float EPSILON = 0.0001f; const float EPSILON = 0.0001f;
if (fabsf(glm::length(fbxZeroTrans)) > EPSILON) { if (fabsf(glm::length(hfmZeroTrans)) > EPSILON) {
boneLengthScale = glm::length(relDefaultPose.trans()) / glm::length(fbxZeroTrans); boneLengthScale = glm::length(relDefaultPose.trans()) / glm::length(hfmZeroTrans);
} }
AnimPose trans = AnimPose(glm::vec3(1.0f), glm::quat(), relDefaultPose.trans() + boneLengthScale * (fbxAnimTrans - fbxZeroTrans)); AnimPose trans = AnimPose(glm::vec3(1.0f), glm::quat(), relDefaultPose.trans() + boneLengthScale * (hfmAnimTrans - hfmZeroTrans));
_anim[frame][skeletonJoint] = trans * preRot * rot * postRot; _anim[frame][skeletonJoint] = trans * preRot * rot * postRot;
} }

View file

@ -16,17 +16,17 @@
#include "AnimationLogging.h" #include "AnimationLogging.h"
AnimSkeleton::AnimSkeleton(const FBXGeometry& fbxGeometry) { AnimSkeleton::AnimSkeleton(const HFMGeometry& geometry) {
// convert to std::vector of joints // convert to std::vector of joints
std::vector<FBXJoint> joints; std::vector<HFMJoint> joints;
joints.reserve(fbxGeometry.joints.size()); joints.reserve(geometry.joints.size());
for (auto& joint : fbxGeometry.joints) { for (auto& joint : geometry.joints) {
joints.push_back(joint); joints.push_back(joint);
} }
buildSkeletonFromJoints(joints); buildSkeletonFromJoints(joints);
} }
AnimSkeleton::AnimSkeleton(const std::vector<FBXJoint>& joints) { AnimSkeleton::AnimSkeleton(const std::vector<HFMJoint>& joints) {
buildSkeletonFromJoints(joints); buildSkeletonFromJoints(joints);
} }
@ -166,7 +166,7 @@ void AnimSkeleton::mirrorAbsolutePoses(AnimPoseVec& poses) const {
} }
} }
void AnimSkeleton::buildSkeletonFromJoints(const std::vector<FBXJoint>& joints) { void AnimSkeleton::buildSkeletonFromJoints(const std::vector<HFMJoint>& joints) {
_joints = joints; _joints = joints;
_jointsSize = (int)joints.size(); _jointsSize = (int)joints.size();
// build a cache of bind poses // build a cache of bind poses
@ -177,7 +177,7 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector<FBXJoint>& joints)
_relativePreRotationPoses.reserve(_jointsSize); _relativePreRotationPoses.reserve(_jointsSize);
_relativePostRotationPoses.reserve(_jointsSize); _relativePostRotationPoses.reserve(_jointsSize);
// iterate over FBXJoints and extract the bind pose information. // iterate over HFMJoints and extract the bind pose information.
for (int i = 0; i < _jointsSize; i++) { for (int i = 0; i < _jointsSize; i++) {
// build pre and post transforms // build pre and post transforms
@ -240,7 +240,7 @@ void AnimSkeleton::dump(bool verbose) const {
qCDebug(animation) << " absDefaultPose =" << getAbsoluteDefaultPose(i); qCDebug(animation) << " absDefaultPose =" << getAbsoluteDefaultPose(i);
qCDebug(animation) << " relDefaultPose =" << getRelativeDefaultPose(i); qCDebug(animation) << " relDefaultPose =" << getRelativeDefaultPose(i);
if (verbose) { if (verbose) {
qCDebug(animation) << " fbxJoint ="; qCDebug(animation) << " hfmJoint =";
qCDebug(animation) << " isFree =" << _joints[i].isFree; qCDebug(animation) << " isFree =" << _joints[i].isFree;
qCDebug(animation) << " freeLineage =" << _joints[i].freeLineage; qCDebug(animation) << " freeLineage =" << _joints[i].freeLineage;
qCDebug(animation) << " parentIndex =" << _joints[i].parentIndex; qCDebug(animation) << " parentIndex =" << _joints[i].parentIndex;

View file

@ -23,8 +23,8 @@ public:
using Pointer = std::shared_ptr<AnimSkeleton>; using Pointer = std::shared_ptr<AnimSkeleton>;
using ConstPointer = std::shared_ptr<const AnimSkeleton>; using ConstPointer = std::shared_ptr<const AnimSkeleton>;
explicit AnimSkeleton(const FBXGeometry& fbxGeometry); explicit AnimSkeleton(const HFMGeometry& geometry);
explicit AnimSkeleton(const std::vector<FBXJoint>& joints); explicit AnimSkeleton(const std::vector<HFMJoint>& joints);
int nameToJointIndex(const QString& jointName) const; int nameToJointIndex(const QString& jointName) const;
const QString& getJointName(int jointIndex) const; const QString& getJointName(int jointIndex) const;
int getNumJoints() const; int getNumJoints() const;
@ -64,9 +64,9 @@ public:
std::vector<int> lookUpJointIndices(const std::vector<QString>& jointNames) const; std::vector<int> lookUpJointIndices(const std::vector<QString>& jointNames) const;
protected: protected:
void buildSkeletonFromJoints(const std::vector<FBXJoint>& joints); void buildSkeletonFromJoints(const std::vector<HFMJoint>& joints);
std::vector<FBXJoint> _joints; std::vector<HFMJoint> _joints;
int _jointsSize { 0 }; int _jointsSize { 0 };
AnimPoseVec _relativeDefaultPoses; AnimPoseVec _relativeDefaultPoses;
AnimPoseVec _absoluteDefaultPoses; AnimPoseVec _absoluteDefaultPoses;

View file

@ -69,7 +69,7 @@ void AnimationReader::run() {
if (urlValid) { if (urlValid) {
// Parse the FBX directly from the QNetworkReply // Parse the FBX directly from the QNetworkReply
FBXGeometry::Pointer fbxgeo; HFMGeometry::Pointer fbxgeo;
if (_url.path().toLower().endsWith(".fbx")) { if (_url.path().toLower().endsWith(".fbx")) {
fbxgeo.reset(readFBX(_data, QVariantHash(), _url.path())); fbxgeo.reset(readFBX(_data, QVariantHash(), _url.path()));
} else { } else {
@ -100,40 +100,40 @@ QStringList Animation::getJointNames() const {
} }
QStringList names; QStringList names;
if (_geometry) { if (_geometry) {
foreach (const FBXJoint& joint, _geometry->joints) { foreach (const HFMJoint& joint, _geometry->joints) {
names.append(joint.name); names.append(joint.name);
} }
} }
return names; return names;
} }
QVector<FBXAnimationFrame> Animation::getFrames() const { QVector<HFMAnimationFrame> Animation::getFrames() const {
if (QThread::currentThread() != thread()) { if (QThread::currentThread() != thread()) {
QVector<FBXAnimationFrame> result; QVector<HFMAnimationFrame> result;
BLOCKING_INVOKE_METHOD(const_cast<Animation*>(this), "getFrames", BLOCKING_INVOKE_METHOD(const_cast<Animation*>(this), "getFrames",
Q_RETURN_ARG(QVector<FBXAnimationFrame>, result)); Q_RETURN_ARG(QVector<HFMAnimationFrame>, result));
return result; return result;
} }
if (_geometry) { if (_geometry) {
return _geometry->animationFrames; return _geometry->animationFrames;
} else { } else {
return QVector<FBXAnimationFrame>(); return QVector<HFMAnimationFrame>();
} }
} }
const QVector<FBXAnimationFrame>& Animation::getFramesReference() const { const QVector<HFMAnimationFrame>& Animation::getFramesReference() const {
return _geometry->animationFrames; return _geometry->animationFrames;
} }
void Animation::downloadFinished(const QByteArray& data) { void Animation::downloadFinished(const QByteArray& data) {
// parse the animation/fbx file on a background thread. // parse the animation/fbx file on a background thread.
AnimationReader* animationReader = new AnimationReader(_url, data); AnimationReader* animationReader = new AnimationReader(_url, data);
connect(animationReader, SIGNAL(onSuccess(FBXGeometry::Pointer)), SLOT(animationParseSuccess(FBXGeometry::Pointer))); connect(animationReader, SIGNAL(onSuccess(HFMGeometry::Pointer)), SLOT(animationParseSuccess(HFMGeometry::Pointer)));
connect(animationReader, SIGNAL(onError(int, QString)), SLOT(animationParseError(int, QString))); connect(animationReader, SIGNAL(onError(int, QString)), SLOT(animationParseError(int, QString)));
QThreadPool::globalInstance()->start(animationReader); QThreadPool::globalInstance()->start(animationReader);
} }
void Animation::animationParseSuccess(FBXGeometry::Pointer geometry) { void Animation::animationParseSuccess(HFMGeometry::Pointer geometry) {
qCDebug(animation) << "Animation parse success" << _url.toDisplayString(); qCDebug(animation) << "Animation parse success" << _url.toDisplayString();

View file

@ -66,7 +66,7 @@ public:
QString getType() const override { return "Animation"; } QString getType() const override { return "Animation"; }
const FBXGeometry& getGeometry() const { return *_geometry; } const HFMGeometry& getGeometry() const { return *_geometry; }
virtual bool isLoaded() const override; virtual bool isLoaded() const override;
@ -80,20 +80,20 @@ public:
* @function AnimationObject.getFrames * @function AnimationObject.getFrames
* @returns {FBXAnimationFrame[]} * @returns {FBXAnimationFrame[]}
*/ */
Q_INVOKABLE QVector<FBXAnimationFrame> getFrames() const; Q_INVOKABLE QVector<HFMAnimationFrame> getFrames() const;
const QVector<FBXAnimationFrame>& getFramesReference() const; const QVector<HFMAnimationFrame>& getFramesReference() const;
protected: protected:
virtual void downloadFinished(const QByteArray& data) override; virtual void downloadFinished(const QByteArray& data) override;
protected slots: protected slots:
void animationParseSuccess(FBXGeometry::Pointer geometry); void animationParseSuccess(HFMGeometry::Pointer geometry);
void animationParseError(int error, QString str); void animationParseError(int error, QString str);
private: private:
FBXGeometry::Pointer _geometry; HFMGeometry::Pointer _geometry;
}; };
/// Reads geometry in a worker thread. /// Reads geometry in a worker thread.
@ -105,7 +105,7 @@ public:
virtual void run() override; virtual void run() override;
signals: signals:
void onSuccess(FBXGeometry::Pointer geometry); void onSuccess(HFMGeometry::Pointer geometry);
void onError(int error, QString str); void onError(int error, QString str);
private: private:

View file

@ -19,17 +19,17 @@ QStringList AnimationObject::getJointNames() const {
return qscriptvalue_cast<AnimationPointer>(thisObject())->getJointNames(); return qscriptvalue_cast<AnimationPointer>(thisObject())->getJointNames();
} }
QVector<FBXAnimationFrame> AnimationObject::getFrames() const { QVector<HFMAnimationFrame> AnimationObject::getFrames() const {
return qscriptvalue_cast<AnimationPointer>(thisObject())->getFrames(); return qscriptvalue_cast<AnimationPointer>(thisObject())->getFrames();
} }
QVector<glm::quat> AnimationFrameObject::getRotations() const { QVector<glm::quat> AnimationFrameObject::getRotations() const {
return qscriptvalue_cast<FBXAnimationFrame>(thisObject()).rotations; return qscriptvalue_cast<HFMAnimationFrame>(thisObject()).rotations;
} }
void registerAnimationTypes(QScriptEngine* engine) { void registerAnimationTypes(QScriptEngine* engine) {
qScriptRegisterSequenceMetaType<QVector<FBXAnimationFrame> >(engine); qScriptRegisterSequenceMetaType<QVector<HFMAnimationFrame> >(engine);
engine->setDefaultPrototype(qMetaTypeId<FBXAnimationFrame>(), engine->newQObject( engine->setDefaultPrototype(qMetaTypeId<HFMAnimationFrame>(), engine->newQObject(
new AnimationFrameObject(), QScriptEngine::ScriptOwnership)); new AnimationFrameObject(), QScriptEngine::ScriptOwnership));
engine->setDefaultPrototype(qMetaTypeId<AnimationPointer>(), engine->newQObject( engine->setDefaultPrototype(qMetaTypeId<AnimationPointer>(), engine->newQObject(
new AnimationObject(), QScriptEngine::ScriptOwnership)); new AnimationObject(), QScriptEngine::ScriptOwnership));

View file

@ -23,13 +23,13 @@ class QScriptEngine;
class AnimationObject : public QObject, protected QScriptable { class AnimationObject : public QObject, protected QScriptable {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QStringList jointNames READ getJointNames) Q_PROPERTY(QStringList jointNames READ getJointNames)
Q_PROPERTY(QVector<FBXAnimationFrame> frames READ getFrames) Q_PROPERTY(QVector<HFMAnimationFrame> frames READ getFrames)
public: public:
Q_INVOKABLE QStringList getJointNames() const; Q_INVOKABLE QStringList getJointNames() const;
Q_INVOKABLE QVector<FBXAnimationFrame> getFrames() const; Q_INVOKABLE QVector<HFMAnimationFrame> getFrames() const;
}; };
/// Scriptable wrapper for animation frames. /// Scriptable wrapper for animation frames.

View file

@ -260,7 +260,7 @@ void Rig::destroyAnimGraph() {
_rightEyeJointChildren.clear(); _rightEyeJointChildren.clear();
} }
void Rig::initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOffset) { void Rig::initJointStates(const HFMGeometry& geometry, const glm::mat4& modelOffset) {
_geometryOffset = AnimPose(geometry.offset); _geometryOffset = AnimPose(geometry.offset);
_invGeometryOffset = _geometryOffset.inverse(); _invGeometryOffset = _geometryOffset.inverse();
_geometryToRigTransform = modelOffset * geometry.offset; _geometryToRigTransform = modelOffset * geometry.offset;
@ -307,7 +307,7 @@ void Rig::initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOff
_rightEyeJointChildren = _animSkeleton->getChildrenOfJoint(geometry.rightEyeJointIndex); _rightEyeJointChildren = _animSkeleton->getChildrenOfJoint(geometry.rightEyeJointIndex);
} }
void Rig::reset(const FBXGeometry& geometry) { void Rig::reset(const HFMGeometry& geometry) {
_geometryOffset = AnimPose(geometry.offset); _geometryOffset = AnimPose(geometry.offset);
_invGeometryOffset = _geometryOffset.inverse(); _invGeometryOffset = _geometryOffset.inverse();
_animSkeleton = std::make_shared<AnimSkeleton>(geometry); _animSkeleton = std::make_shared<AnimSkeleton>(geometry);
@ -1253,7 +1253,7 @@ const glm::vec3 DOP14_NORMALS[DOP14_COUNT] = {
// returns true if the given point lies inside of the k-dop, specified by shapeInfo & shapePose. // returns true if the given point lies inside of the k-dop, specified by shapeInfo & shapePose.
// if the given point does lie within the k-dop, it also returns the amount of displacement necessary to push that point outward // if the given point does lie within the k-dop, it also returns the amount of displacement necessary to push that point outward
// such that it lies on the surface of the kdop. // such that it lies on the surface of the kdop.
static bool findPointKDopDisplacement(const glm::vec3& point, const AnimPose& shapePose, const FBXJointShapeInfo& shapeInfo, glm::vec3& displacementOut) { static bool findPointKDopDisplacement(const glm::vec3& point, const AnimPose& shapePose, const HFMJointShapeInfo& shapeInfo, glm::vec3& displacementOut) {
// transform point into local space of jointShape. // transform point into local space of jointShape.
glm::vec3 localPoint = shapePose.inverse().xformPoint(point); glm::vec3 localPoint = shapePose.inverse().xformPoint(point);
@ -1299,8 +1299,8 @@ static bool findPointKDopDisplacement(const glm::vec3& point, const AnimPose& sh
} }
} }
glm::vec3 Rig::deflectHandFromTorso(const glm::vec3& handPosition, const FBXJointShapeInfo& hipsShapeInfo, const FBXJointShapeInfo& spineShapeInfo, glm::vec3 Rig::deflectHandFromTorso(const glm::vec3& handPosition, const HFMJointShapeInfo& hipsShapeInfo, const HFMJointShapeInfo& spineShapeInfo,
const FBXJointShapeInfo& spine1ShapeInfo, const FBXJointShapeInfo& spine2ShapeInfo) const { const HFMJointShapeInfo& spine1ShapeInfo, const HFMJointShapeInfo& spine2ShapeInfo) const {
glm::vec3 position = handPosition; glm::vec3 position = handPosition;
glm::vec3 displacement; glm::vec3 displacement;
int hipsJoint = indexOfJoint("Hips"); int hipsJoint = indexOfJoint("Hips");
@ -1349,8 +1349,8 @@ glm::vec3 Rig::deflectHandFromTorso(const glm::vec3& handPosition, const FBXJoin
void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnabled, bool hipsEstimated, void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnabled, bool hipsEstimated,
bool leftArmEnabled, bool rightArmEnabled, bool headEnabled, float dt, bool leftArmEnabled, bool rightArmEnabled, bool headEnabled, float dt,
const AnimPose& leftHandPose, const AnimPose& rightHandPose, const AnimPose& leftHandPose, const AnimPose& rightHandPose,
const FBXJointShapeInfo& hipsShapeInfo, const FBXJointShapeInfo& spineShapeInfo, const HFMJointShapeInfo& hipsShapeInfo, const HFMJointShapeInfo& spineShapeInfo,
const FBXJointShapeInfo& spine1ShapeInfo, const FBXJointShapeInfo& spine2ShapeInfo, const HFMJointShapeInfo& spine1ShapeInfo, const HFMJointShapeInfo& spine2ShapeInfo,
const glm::mat4& rigToSensorMatrix, const glm::mat4& sensorToRigMatrix) { const glm::mat4& rigToSensorMatrix, const glm::mat4& sensorToRigMatrix) {
const bool ENABLE_POLE_VECTORS = true; const bool ENABLE_POLE_VECTORS = true;
@ -2008,7 +2008,7 @@ void Rig::computeExternalPoses(const glm::mat4& modelOffsetMat) {
} }
void Rig::computeAvatarBoundingCapsule( void Rig::computeAvatarBoundingCapsule(
const FBXGeometry& geometry, const HFMGeometry& geometry,
float& radiusOut, float& radiusOut,
float& heightOut, float& heightOut,
glm::vec3& localOffsetOut) const { 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. // from the head to the hips when computing the rest of the bounding capsule.
int index = indexOfJoint("Head"); int index = indexOfJoint("Head");
while (index != -1) { while (index != -1) {
const FBXJointShapeInfo& shapeInfo = geometry.joints.at(index).shapeInfo; const HFMJointShapeInfo& shapeInfo = geometry.joints.at(index).shapeInfo;
AnimPose pose = _animSkeleton->getAbsoluteDefaultPose(index); AnimPose pose = _animSkeleton->getAbsoluteDefaultPose(index);
if (shapeInfo.points.size() > 0) { if (shapeInfo.points.size() > 0) {
for (auto& point : shapeInfo.points) { for (auto& point : shapeInfo.points) {

View file

@ -86,10 +86,10 @@ public:
AnimPose secondaryControllerPoses[NumSecondaryControllerTypes]; // rig space AnimPose secondaryControllerPoses[NumSecondaryControllerTypes]; // rig space
uint8_t secondaryControllerFlags[NumSecondaryControllerTypes]; uint8_t secondaryControllerFlags[NumSecondaryControllerTypes];
bool isTalking; bool isTalking;
FBXJointShapeInfo hipsShapeInfo; HFMJointShapeInfo hipsShapeInfo;
FBXJointShapeInfo spineShapeInfo; HFMJointShapeInfo spineShapeInfo;
FBXJointShapeInfo spine1ShapeInfo; HFMJointShapeInfo spine1ShapeInfo;
FBXJointShapeInfo spine2ShapeInfo; HFMJointShapeInfo spine2ShapeInfo;
}; };
struct EyeParameters { struct EyeParameters {
@ -122,8 +122,8 @@ public:
void overrideRoleAnimation(const QString& role, const QString& url, float fps, bool loop, float firstFrame, float lastFrame); void overrideRoleAnimation(const QString& role, const QString& url, float fps, bool loop, float firstFrame, float lastFrame);
void restoreRoleAnimation(const QString& role); void restoreRoleAnimation(const QString& role);
void initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOffset); void initJointStates(const HFMGeometry& geometry, const glm::mat4& modelOffset);
void reset(const FBXGeometry& geometry); void reset(const HFMGeometry& geometry);
bool jointStatesEmpty(); bool jointStatesEmpty();
int getJointStateCount() const; int getJointStateCount() const;
int indexOfJoint(const QString& jointName) const; int indexOfJoint(const QString& jointName) const;
@ -210,7 +210,7 @@ public:
void copyJointsFromJointData(const QVector<JointData>& jointDataVec); void copyJointsFromJointData(const QVector<JointData>& jointDataVec);
void computeExternalPoses(const glm::mat4& modelOffsetMat); void computeExternalPoses(const glm::mat4& modelOffsetMat);
void computeAvatarBoundingCapsule(const FBXGeometry& geometry, float& radiusOut, float& heightOut, glm::vec3& offsetOut) const; void computeAvatarBoundingCapsule(const HFMGeometry& geometry, float& radiusOut, float& heightOut, glm::vec3& offsetOut) const;
void setEnableInverseKinematics(bool enable); void setEnableInverseKinematics(bool enable);
void setEnableAnimations(bool enable); void setEnableAnimations(bool enable);
@ -245,8 +245,8 @@ protected:
void updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnabled, bool hipsEstimated, void updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnabled, bool hipsEstimated,
bool leftArmEnabled, bool rightArmEnabled, bool headEnabled, float dt, bool leftArmEnabled, bool rightArmEnabled, bool headEnabled, float dt,
const AnimPose& leftHandPose, const AnimPose& rightHandPose, const AnimPose& leftHandPose, const AnimPose& rightHandPose,
const FBXJointShapeInfo& hipsShapeInfo, const FBXJointShapeInfo& spineShapeInfo, const HFMJointShapeInfo& hipsShapeInfo, const HFMJointShapeInfo& spineShapeInfo,
const FBXJointShapeInfo& spine1ShapeInfo, const FBXJointShapeInfo& spine2ShapeInfo, const HFMJointShapeInfo& spine1ShapeInfo, const HFMJointShapeInfo& spine2ShapeInfo,
const glm::mat4& rigToSensorMatrix, const glm::mat4& sensorToRigMatrix); const glm::mat4& rigToSensorMatrix, const glm::mat4& sensorToRigMatrix);
void updateFeet(bool leftFootEnabled, bool rightFootEnabled, bool headEnabled, void updateFeet(bool leftFootEnabled, bool rightFootEnabled, bool headEnabled,
const AnimPose& leftFootPose, const AnimPose& rightFootPose, const AnimPose& leftFootPose, const AnimPose& rightFootPose,
@ -257,8 +257,8 @@ protected:
bool calculateElbowPoleVector(int handIndex, int elbowIndex, int armIndex, int oppositeArmIndex, glm::vec3& poleVector) const; bool calculateElbowPoleVector(int handIndex, int elbowIndex, int armIndex, int oppositeArmIndex, glm::vec3& poleVector) const;
glm::vec3 calculateKneePoleVector(int footJointIndex, int kneeJoint, int upLegIndex, int hipsIndex, const AnimPose& targetFootPose) const; glm::vec3 calculateKneePoleVector(int footJointIndex, int kneeJoint, int upLegIndex, int hipsIndex, const AnimPose& targetFootPose) const;
glm::vec3 deflectHandFromTorso(const glm::vec3& handPosition, const FBXJointShapeInfo& hipsShapeInfo, const FBXJointShapeInfo& spineShapeInfo, glm::vec3 deflectHandFromTorso(const glm::vec3& handPosition, const HFMJointShapeInfo& hipsShapeInfo, const HFMJointShapeInfo& spineShapeInfo,
const FBXJointShapeInfo& spine1ShapeInfo, const FBXJointShapeInfo& spine2ShapeInfo) const; const HFMJointShapeInfo& spine1ShapeInfo, const HFMJointShapeInfo& spine2ShapeInfo) const;
AnimPose _modelOffset; // model to rig space AnimPose _modelOffset; // model to rig space

View file

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

View file

@ -54,7 +54,7 @@ void SkeletonModel::setTextures(const QVariantMap& textures) {
} }
void SkeletonModel::initJointStates() { void SkeletonModel::initJointStates() {
const FBXGeometry& geometry = getFBXGeometry(); const HFMGeometry& geometry = getHFMGeometry();
glm::mat4 modelOffset = glm::scale(_scale) * glm::translate(_offset); glm::mat4 modelOffset = glm::scale(_scale) * glm::translate(_offset);
_rig.initJointStates(geometry, modelOffset); _rig.initJointStates(geometry, modelOffset);
@ -96,7 +96,7 @@ void SkeletonModel::initJointStates() {
// Called within Model::simulate call, below. // Called within Model::simulate call, below.
void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
assert(!_owningAvatar->isMyAvatar()); assert(!_owningAvatar->isMyAvatar());
const FBXGeometry& geometry = getFBXGeometry(); const HFMGeometry& geometry = getHFMGeometry();
Head* head = _owningAvatar->getHead(); Head* head = _owningAvatar->getHead();
@ -259,22 +259,22 @@ bool SkeletonModel::getRightShoulderPosition(glm::vec3& position) const {
} }
bool SkeletonModel::getHeadPosition(glm::vec3& headPosition) const { bool SkeletonModel::getHeadPosition(glm::vec3& headPosition) const {
return isActive() && getJointPositionInWorldFrame(getFBXGeometry().headJointIndex, headPosition); return isActive() && getJointPositionInWorldFrame(getHFMGeometry().headJointIndex, headPosition);
} }
bool SkeletonModel::getNeckPosition(glm::vec3& neckPosition) const { bool SkeletonModel::getNeckPosition(glm::vec3& neckPosition) const {
return isActive() && getJointPositionInWorldFrame(getFBXGeometry().neckJointIndex, neckPosition); return isActive() && getJointPositionInWorldFrame(getHFMGeometry().neckJointIndex, neckPosition);
} }
bool SkeletonModel::getLocalNeckPosition(glm::vec3& neckPosition) const { bool SkeletonModel::getLocalNeckPosition(glm::vec3& neckPosition) const {
return isActive() && getJointPosition(getFBXGeometry().neckJointIndex, neckPosition); return isActive() && getJointPosition(getHFMGeometry().neckJointIndex, neckPosition);
} }
bool SkeletonModel::getEyeModelPositions(glm::vec3& firstEyePosition, glm::vec3& secondEyePosition) const { bool SkeletonModel::getEyeModelPositions(glm::vec3& firstEyePosition, glm::vec3& secondEyePosition) const {
if (!isActive()) { if (!isActive()) {
return false; return false;
} }
const FBXGeometry& geometry = getFBXGeometry(); const HFMGeometry& geometry = getHFMGeometry();
if (getJointPosition(geometry.leftEyeJointIndex, firstEyePosition) && if (getJointPosition(geometry.leftEyeJointIndex, firstEyePosition) &&
getJointPosition(geometry.rightEyeJointIndex, secondEyePosition)) { getJointPosition(geometry.rightEyeJointIndex, secondEyePosition)) {
@ -330,7 +330,7 @@ void SkeletonModel::computeBoundingShape() {
return; return;
} }
const FBXGeometry& geometry = getFBXGeometry(); const HFMGeometry& geometry = getHFMGeometry();
if (geometry.joints.isEmpty() || geometry.rootJointIndex == -1) { if (geometry.joints.isEmpty() || geometry.rootJointIndex == -1) {
// rootJointIndex == -1 if the avatar model has no skeleton // rootJointIndex == -1 if the avatar model has no skeleton
return; return;
@ -369,7 +369,7 @@ void SkeletonModel::renderBoundingCollisionShapes(RenderArgs* args, gpu::Batch&
} }
bool SkeletonModel::hasSkeleton() { bool SkeletonModel::hasSkeleton() {
return isActive() ? getFBXGeometry().rootJointIndex != -1 : false; return isActive() ? getHFMGeometry().rootJointIndex != -1 : false;
} }
void SkeletonModel::onInvalidate() { void SkeletonModel::onInvalidate() {

View file

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

View file

@ -206,7 +206,7 @@ void FBXBaker::importScene() {
} }
#endif #endif
_geometry = reader.extractFBXGeometry({}, _modelURL.toString()); _geometry = reader.extractHFMGeometry({}, _modelURL.toString());
_textureContentMap = reader._textureContent; _textureContentMap = reader._textureContent;
} }
@ -329,7 +329,7 @@ void FBXBaker::rewriteAndBakeSceneTextures() {
for (FBXNode& textureChild : object->children) { for (FBXNode& textureChild : object->children) {
if (textureChild.name == "RelativeFilename") { if (textureChild.name == "RelativeFilename") {
QString fbxTextureFileName { textureChild.properties.at(0).toString() }; QString hfmTextureFileName { textureChild.properties.at(0).toString() };
// grab the ID for this texture so we can figure out the // grab the ID for this texture so we can figure out the
// texture type from the loaded materials // texture type from the loaded materials
@ -337,7 +337,7 @@ void FBXBaker::rewriteAndBakeSceneTextures() {
auto textureType = textureTypes[textureID]; auto textureType = textureTypes[textureID];
// Compress the texture information and return the new filename to be added into the FBX scene // Compress the texture information and return the new filename to be added into the FBX scene
auto bakedTextureFile = compressTexture(fbxTextureFileName, textureType); auto bakedTextureFile = compressTexture(hfmTextureFileName, textureType);
// If no errors or warnings have occurred during texture compression add the filename to the FBX scene // If no errors or warnings have occurred during texture compression add the filename to the FBX scene
if (!bakedTextureFile.isNull()) { if (!bakedTextureFile.isNull()) {

View file

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

View file

@ -75,7 +75,7 @@ void ModelBaker::abort() {
} }
} }
bool ModelBaker::compressMesh(FBXMesh& mesh, bool hasDeformers, FBXNode& dracoMeshNode, GetMaterialIDCallback materialIDCallback) { bool ModelBaker::compressMesh(HFMMesh& mesh, bool hasDeformers, FBXNode& dracoMeshNode, GetMaterialIDCallback materialIDCallback) {
if (mesh.wasCompressed) { if (mesh.wasCompressed) {
handleError("Cannot re-bake a file that contains compressed mesh"); handleError("Cannot re-bake a file that contains compressed mesh");
return false; return false;

View file

@ -39,7 +39,7 @@ public:
const QString& bakedOutputDirectory, const QString& originalOutputDirectory = ""); const QString& bakedOutputDirectory, const QString& originalOutputDirectory = "");
virtual ~ModelBaker(); virtual ~ModelBaker();
bool compressMesh(FBXMesh& mesh, bool hasDeformers, FBXNode& dracoMeshNode, GetMaterialIDCallback materialIDCallback = nullptr); bool compressMesh(HFMMesh& mesh, bool hasDeformers, FBXNode& dracoMeshNode, GetMaterialIDCallback materialIDCallback = nullptr);
QString compressTexture(QString textureFileName, image::TextureUsage::Type = image::TextureUsage::Type::DEFAULT_TEXTURE); QString compressTexture(QString textureFileName, image::TextureUsage::Type = image::TextureUsage::Type::DEFAULT_TEXTURE);
virtual void setWasAborted(bool wasAborted) override; virtual void setWasAborted(bool wasAborted) override;

View file

@ -153,7 +153,7 @@ void OBJBaker::bakeOBJ() {
checkIfTexturesFinished(); checkIfTexturesFinished();
} }
void OBJBaker::createFBXNodeTree(FBXNode& rootNode, FBXGeometry& geometry) { void OBJBaker::createFBXNodeTree(FBXNode& rootNode, HFMGeometry& geometry) {
// Generating FBX Header Node // Generating FBX Header Node
FBXNode headerNode; FBXNode headerNode;
headerNode.name = FBX_HEADER_EXTENSION; headerNode.name = FBX_HEADER_EXTENSION;
@ -235,7 +235,7 @@ void OBJBaker::createFBXNodeTree(FBXNode& rootNode, FBXGeometry& geometry) {
auto size = meshParts.size(); auto size = meshParts.size();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
QString material = meshParts[i].materialID; QString material = meshParts[i].materialID;
FBXMaterial currentMaterial = geometry.materials[material]; HFMMaterial currentMaterial = geometry.materials[material];
if (!currentMaterial.albedoTexture.filename.isEmpty() || !currentMaterial.specularTexture.filename.isEmpty()) { if (!currentMaterial.albedoTexture.filename.isEmpty() || !currentMaterial.specularTexture.filename.isEmpty()) {
auto textureID = nextNodeID(); auto textureID = nextNodeID();
_mapTextureMaterial.emplace_back(textureID, i); _mapTextureMaterial.emplace_back(textureID, i);
@ -325,12 +325,12 @@ void OBJBaker::createFBXNodeTree(FBXNode& rootNode, FBXGeometry& geometry) {
} }
// Set properties for material nodes // Set properties for material nodes
void OBJBaker::setMaterialNodeProperties(FBXNode& materialNode, QString material, FBXGeometry& geometry) { void OBJBaker::setMaterialNodeProperties(FBXNode& materialNode, QString material, HFMGeometry& geometry) {
auto materialID = nextNodeID(); auto materialID = nextNodeID();
_materialIDs.push_back(materialID); _materialIDs.push_back(materialID);
materialNode.properties = { materialID, material, MESH }; materialNode.properties = { materialID, material, MESH };
FBXMaterial currentMaterial = geometry.materials[material]; HFMMaterial currentMaterial = geometry.materials[material];
// Setting the hierarchy: Material -> Properties70 -> P -> Properties // Setting the hierarchy: Material -> Properties70 -> P -> Properties
FBXNode properties70Node; FBXNode properties70Node;

View file

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

View file

@ -268,7 +268,7 @@ EntityItemProperties RenderableModelEntityItem::getProperties(const EntityProper
if (model->isLoaded()) { if (model->isLoaded()) {
// TODO: improve naturalDimensions in the future, // TODO: improve naturalDimensions in the future,
// for now we've added this hack for setting natural dimensions of models // for now we've added this hack for setting natural dimensions of models
Extents meshExtents = model->getFBXGeometry().getUnscaledMeshExtents(); Extents meshExtents = model->getHFMGeometry().getUnscaledMeshExtents();
properties.setNaturalDimensions(meshExtents.maximum - meshExtents.minimum); properties.setNaturalDimensions(meshExtents.maximum - meshExtents.minimum);
properties.calculateNaturalPosition(meshExtents.minimum, meshExtents.maximum); 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 // should never fall in here when collision model not fully loaded
// TODO: assert that all geometries exist and are loaded // TODO: assert that all geometries exist and are loaded
//assert(_model && _model->isLoaded() && _compoundShapeResource && _compoundShapeResource->isLoaded()); //assert(_model && _model->isLoaded() && _compoundShapeResource && _compoundShapeResource->isLoaded());
const FBXGeometry& collisionGeometry = _compoundShapeResource->getFBXGeometry(); const HFMGeometry& collisionGeometry = _compoundShapeResource->getHFMGeometry();
ShapeInfo::PointCollection& pointCollection = shapeInfo.getPointCollection(); ShapeInfo::PointCollection& pointCollection = shapeInfo.getPointCollection();
pointCollection.clear(); pointCollection.clear();
@ -411,15 +411,15 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
// the way OBJ files get read, each section under a "g" line is its own meshPart. We only expect // 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. // to find one actual "mesh" (with one or more meshParts in it), but we loop over the meshes, just in case.
foreach (const FBXMesh& mesh, collisionGeometry.meshes) { foreach (const HFMMesh& mesh, collisionGeometry.meshes) {
// each meshPart is a convex hull // each meshPart is a convex hull
foreach (const FBXMeshPart &meshPart, mesh.parts) { foreach (const HFMMeshPart &meshPart, mesh.parts) {
pointCollection.push_back(QVector<glm::vec3>()); pointCollection.push_back(QVector<glm::vec3>());
ShapeInfo::PointList& pointsInPart = pointCollection[i]; ShapeInfo::PointList& pointsInPart = pointCollection[i];
// run through all the triangles and (uniquely) add each point to the hull // run through all the triangles and (uniquely) add each point to the hull
uint32_t numIndices = (uint32_t)meshPart.triangleIndices.size(); uint32_t numIndices = (uint32_t)meshPart.triangleIndices.size();
// TODO: assert rather than workaround after we start sanitizing FBXMesh higher up // TODO: assert rather than workaround after we start sanitizing HFMMesh higher up
//assert(numIndices % TRIANGLE_STRIDE == 0); //assert(numIndices % TRIANGLE_STRIDE == 0);
numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXReader numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXReader
@ -440,7 +440,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
// run through all the quads and (uniquely) add each point to the hull // run through all the quads and (uniquely) add each point to the hull
numIndices = (uint32_t)meshPart.quadIndices.size(); numIndices = (uint32_t)meshPart.quadIndices.size();
// TODO: assert rather than workaround after we start sanitizing FBXMesh higher up // TODO: assert rather than workaround after we start sanitizing HFMMesh higher up
//assert(numIndices % QUAD_STRIDE == 0); //assert(numIndices % QUAD_STRIDE == 0);
numIndices -= numIndices % QUAD_STRIDE; // WORKAROUND lack of sanity checking in FBXReader numIndices -= numIndices % QUAD_STRIDE; // WORKAROUND lack of sanity checking in FBXReader
@ -478,7 +478,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
// to the visual model and apply them to the collision model (without regard for the // to the visual model and apply them to the collision model (without regard for the
// collision model's extents). // collision model's extents).
glm::vec3 scaleToFit = dimensions / model->getFBXGeometry().getUnscaledMeshExtents().size(); glm::vec3 scaleToFit = dimensions / model->getHFMGeometry().getUnscaledMeshExtents().size();
// multiply each point by scale before handing the point-set off to the physics engine. // multiply each point by scale before handing the point-set off to the physics engine.
// also determine the extents of the collision model. // also determine the extents of the collision model.
glm::vec3 registrationOffset = dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint()); glm::vec3 registrationOffset = dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint());
@ -498,14 +498,14 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
// compute meshPart local transforms // compute meshPart local transforms
QVector<glm::mat4> localTransforms; QVector<glm::mat4> localTransforms;
const FBXGeometry& fbxGeometry = model->getFBXGeometry(); const HFMGeometry& hfmGeometry = model->getHFMGeometry();
int numFbxMeshes = fbxGeometry.meshes.size(); int numHFMMeshes = hfmGeometry.meshes.size();
int totalNumVertices = 0; int totalNumVertices = 0;
glm::mat4 invRegistraionOffset = glm::translate(dimensions * (getRegistrationPoint() - ENTITY_ITEM_DEFAULT_REGISTRATION_POINT)); glm::mat4 invRegistraionOffset = glm::translate(dimensions * (getRegistrationPoint() - ENTITY_ITEM_DEFAULT_REGISTRATION_POINT));
for (int i = 0; i < numFbxMeshes; i++) { for (int i = 0; i < numHFMMeshes; i++) {
const FBXMesh& mesh = fbxGeometry.meshes.at(i); const HFMMesh& mesh = hfmGeometry.meshes.at(i);
if (mesh.clusters.size() > 0) { if (mesh.clusters.size() > 0) {
const FBXCluster& cluster = mesh.clusters.at(0); const HFMCluster& cluster = mesh.clusters.at(0);
auto jointMatrix = model->getRig().getJointTransform(cluster.jointIndex); auto jointMatrix = model->getRig().getJointTransform(cluster.jointIndex);
// we backtranslate by the registration offset so we can apply that offset to the shapeInfo later // we backtranslate by the registration offset so we can apply that offset to the shapeInfo later
localTransforms.push_back(invRegistraionOffset * jointMatrix * cluster.inverseBindMatrix); localTransforms.push_back(invRegistraionOffset * jointMatrix * cluster.inverseBindMatrix);
@ -524,10 +524,10 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
std::vector<std::shared_ptr<const graphics::Mesh>> meshes; std::vector<std::shared_ptr<const graphics::Mesh>> meshes;
if (type == SHAPE_TYPE_SIMPLE_COMPOUND) { if (type == SHAPE_TYPE_SIMPLE_COMPOUND) {
auto& fbxMeshes = _compoundShapeResource->getFBXGeometry().meshes; auto& hfmMeshes = _compoundShapeResource->getHFMGeometry().meshes;
meshes.reserve(fbxMeshes.size()); meshes.reserve(hfmMeshes.size());
for (auto& fbxMesh : fbxMeshes) { for (auto& hfmMesh : hfmMeshes) {
meshes.push_back(fbxMesh._mesh); meshes.push_back(hfmMesh._mesh);
} }
} else { } else {
meshes = model->getGeometry()->getMeshes(); meshes = model->getGeometry()->getMeshes();
@ -594,7 +594,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
while (partItr != parts.cend<const graphics::Mesh::Part>()) { while (partItr != parts.cend<const graphics::Mesh::Part>()) {
auto numIndices = partItr->_numIndices; auto numIndices = partItr->_numIndices;
if (partItr->_topology == graphics::Mesh::TRIANGLES) { if (partItr->_topology == graphics::Mesh::TRIANGLES) {
// TODO: assert rather than workaround after we start sanitizing FBXMesh higher up // TODO: assert rather than workaround after we start sanitizing HFMMesh higher up
//assert(numIndices % TRIANGLE_STRIDE == 0); //assert(numIndices % TRIANGLE_STRIDE == 0);
numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXReader numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXReader
@ -605,7 +605,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
++indexItr; ++indexItr;
} }
} else if (partItr->_topology == graphics::Mesh::TRIANGLE_STRIP) { } else if (partItr->_topology == graphics::Mesh::TRIANGLE_STRIP) {
// TODO: resurrect assert after we start sanitizing FBXMesh higher up // TODO: resurrect assert after we start sanitizing HFMMesh higher up
//assert(numIndices > 2); //assert(numIndices > 2);
uint32_t approxNumIndices = TRIANGLE_STRIDE * numIndices; uint32_t approxNumIndices = TRIANGLE_STRIDE * numIndices;
@ -651,7 +651,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
std::set<int32_t> uniqueIndices; std::set<int32_t> uniqueIndices;
auto numIndices = partItr->_numIndices; auto numIndices = partItr->_numIndices;
if (partItr->_topology == graphics::Mesh::TRIANGLES) { if (partItr->_topology == graphics::Mesh::TRIANGLES) {
// TODO: assert rather than workaround after we start sanitizing FBXMesh higher up // TODO: assert rather than workaround after we start sanitizing HFMMesh higher up
//assert(numIndices% TRIANGLE_STRIDE == 0); //assert(numIndices% TRIANGLE_STRIDE == 0);
numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXReader numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXReader
@ -662,7 +662,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
++indexItr; ++indexItr;
} }
} else if (partItr->_topology == graphics::Mesh::TRIANGLE_STRIP) { } else if (partItr->_topology == graphics::Mesh::TRIANGLE_STRIP) {
// TODO: resurrect assert after we start sanitizing FBXMesh higher up // TODO: resurrect assert after we start sanitizing HFMMesh higher up
//assert(numIndices > TRIANGLE_STRIDE - 1); //assert(numIndices > TRIANGLE_STRIDE - 1);
auto indexItr = indices.cbegin<const gpu::BufferView::Index>() + partItr->_startIndex; auto indexItr = indices.cbegin<const gpu::BufferView::Index>() + partItr->_startIndex;
@ -755,7 +755,7 @@ int RenderableModelEntityItem::avatarJointIndex(int modelJointIndex) {
bool RenderableModelEntityItem::contains(const glm::vec3& point) const { bool RenderableModelEntityItem::contains(const glm::vec3& point) const {
auto model = getModel(); auto model = getModel();
if (EntityItem::contains(point) && model && _compoundShapeResource && _compoundShapeResource->isLoaded()) { if (EntityItem::contains(point) && model && _compoundShapeResource && _compoundShapeResource->isLoaded()) {
return _compoundShapeResource->getFBXGeometry().convexHullContains(worldToEntity(point)); return _compoundShapeResource->getHFMGeometry().convexHullContains(worldToEntity(point));
} }
return false; return false;
@ -1135,7 +1135,7 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) {
QVector<EntityJointData> jointsData; QVector<EntityJointData> jointsData;
const QVector<FBXAnimationFrame>& frames = _animation->getFramesReference(); // NOTE: getFrames() is too heavy const QVector<HFMAnimationFrame>& frames = _animation->getFramesReference(); // NOTE: getFrames() is too heavy
int frameCount = frames.size(); int frameCount = frames.size();
if (frameCount <= 0) { if (frameCount <= 0) {
return; return;
@ -1160,10 +1160,10 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) {
} }
QStringList animationJointNames = _animation->getGeometry().getJointNames(); QStringList animationJointNames = _animation->getGeometry().getJointNames();
auto& fbxJoints = _animation->getGeometry().joints; auto& hfmJoints = _animation->getGeometry().joints;
auto& originalFbxJoints = _model->getFBXGeometry().joints; auto& originalHFMJoints = _model->getHFMGeometry().joints;
auto& originalFbxIndices = _model->getFBXGeometry().jointIndices; auto& originalHFMIndices = _model->getHFMGeometry().jointIndices;
bool allowTranslation = entity->getAnimationAllowTranslation(); bool allowTranslation = entity->getAnimationAllowTranslation();
@ -1182,22 +1182,22 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) {
translationMat = glm::translate(translations[index]); translationMat = glm::translate(translations[index]);
} }
} else if (index < animationJointNames.size()) { } else if (index < animationJointNames.size()) {
QString jointName = fbxJoints[index].name; // Pushing this here so its not done on every entity, with the exceptions of those allowing for translation QString jointName = hfmJoints[index].name; // Pushing this here so its not done on every entity, with the exceptions of those allowing for translation
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 it's translation. // Making sure the joint names exist in the original model the animation is trying to apply onto. If they do, then remap and get it's 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(originalFbxJoints[remappedIndex].translation); translationMat = glm::translate(originalHFMJoints[remappedIndex].translation);
} }
} }
glm::mat4 rotationMat; glm::mat4 rotationMat;
if (index < rotations.size()) { if (index < rotations.size()) {
rotationMat = glm::mat4_cast(fbxJoints[index].preRotation * rotations[index] * fbxJoints[index].postRotation); rotationMat = glm::mat4_cast(hfmJoints[index].preRotation * rotations[index] * hfmJoints[index].postRotation);
} else { } else {
rotationMat = glm::mat4_cast(fbxJoints[index].preRotation * fbxJoints[index].postRotation); rotationMat = glm::mat4_cast(hfmJoints[index].preRotation * hfmJoints[index].postRotation);
} }
glm::mat4 finalMat = (translationMat * fbxJoints[index].preTransform * glm::mat4 finalMat = (translationMat * hfmJoints[index].preTransform *
rotationMat * fbxJoints[index].postTransform); rotationMat * hfmJoints[index].postTransform);
auto& jointData = jointsData[j]; auto& jointData = jointsData[j];
jointData.translation = extractTranslation(finalMat); jointData.translation = extractTranslation(finalMat);
jointData.translationSet = true; jointData.translationSet = true;

View file

@ -70,8 +70,8 @@ public:
}; };
/// A single blendshape extracted from an FBX document. /// A single blendshape.
class FBXBlendshape { class HFMBlendshape {
public: public:
QVector<int> indices; QVector<int> indices;
QVector<glm::vec3> vertices; QVector<glm::vec3> vertices;
@ -79,19 +79,19 @@ public:
QVector<glm::vec3> tangents; QVector<glm::vec3> tangents;
}; };
struct FBXJointShapeInfo { struct HFMJointShapeInfo {
// same units and frame as FBXJoint.translation // same units and frame as HFMJoint.translation
glm::vec3 avgPoint; glm::vec3 avgPoint;
std::vector<float> dots; std::vector<float> dots;
std::vector<glm::vec3> points; std::vector<glm::vec3> points;
std::vector<glm::vec3> debugLines; std::vector<glm::vec3> debugLines;
}; };
/// A single joint (transformation node) extracted from an FBX document. /// A single joint (transformation node).
class FBXJoint { class HFMJoint {
public: public:
FBXJointShapeInfo shapeInfo; HFMJointShapeInfo shapeInfo;
QVector<int> freeLineage; QVector<int> freeLineage;
bool isFree; bool isFree;
int parentIndex; int parentIndex;
@ -126,8 +126,8 @@ public:
}; };
/// A single binding to a joint in an FBX document. /// A single binding to a joint.
class FBXCluster { class HFMCluster {
public: public:
int jointIndex; int jointIndex;
@ -137,8 +137,8 @@ public:
const int MAX_NUM_PIXELS_FOR_FBX_TEXTURE = 2048 * 2048; const int MAX_NUM_PIXELS_FOR_FBX_TEXTURE = 2048 * 2048;
/// A texture map in an FBX document. /// A texture map.
class FBXTexture { class HFMTexture {
public: public:
QString id; QString id;
QString name; QString name;
@ -156,7 +156,7 @@ public:
}; };
/// A single part of a mesh (with the same material). /// A single part of a mesh (with the same material).
class FBXMeshPart { class HFMMeshPart {
public: public:
QVector<int> quadIndices; // original indices from the FBX mesh QVector<int> quadIndices; // original indices from the FBX mesh
@ -166,10 +166,10 @@ public:
QString materialID; QString materialID;
}; };
class FBXMaterial { class HFMMaterial {
public: public:
FBXMaterial() {}; HFMMaterial() {};
FBXMaterial(const glm::vec3& diffuseColor, const glm::vec3& specularColor, const glm::vec3& emissiveColor, HFMMaterial(const glm::vec3& diffuseColor, const glm::vec3& specularColor, const glm::vec3& emissiveColor,
float shininess, float opacity) : float shininess, float opacity) :
diffuseColor(diffuseColor), diffuseColor(diffuseColor),
specularColor(specularColor), specularColor(specularColor),
@ -203,17 +203,17 @@ public:
QString shadingModel; QString shadingModel;
graphics::MaterialPointer _material; graphics::MaterialPointer _material;
FBXTexture normalTexture; HFMTexture normalTexture;
FBXTexture albedoTexture; HFMTexture albedoTexture;
FBXTexture opacityTexture; HFMTexture opacityTexture;
FBXTexture glossTexture; HFMTexture glossTexture;
FBXTexture roughnessTexture; HFMTexture roughnessTexture;
FBXTexture specularTexture; HFMTexture specularTexture;
FBXTexture metallicTexture; HFMTexture metallicTexture;
FBXTexture emissiveTexture; HFMTexture emissiveTexture;
FBXTexture occlusionTexture; HFMTexture occlusionTexture;
FBXTexture scatteringTexture; HFMTexture scatteringTexture;
FBXTexture lightmapTexture; HFMTexture lightmapTexture;
glm::vec2 lightmapParams{ 0.0f, 1.0f }; glm::vec2 lightmapParams{ 0.0f, 1.0f };
@ -232,10 +232,10 @@ public:
}; };
/// A single mesh (with optional blendshapes) extracted from an FBX document. /// A single mesh (with optional blendshapes) extracted from an FBX document.
class FBXMesh { class HFMMesh {
public: public:
QVector<FBXMeshPart> parts; QVector<HFMMeshPart> parts;
QVector<glm::vec3> vertices; QVector<glm::vec3> vertices;
QVector<glm::vec3> normals; QVector<glm::vec3> normals;
@ -247,12 +247,12 @@ public:
QVector<uint16_t> clusterWeights; QVector<uint16_t> clusterWeights;
QVector<int32_t> originalIndices; QVector<int32_t> originalIndices;
QVector<FBXCluster> clusters; QVector<HFMCluster> clusters;
Extents meshExtents; Extents meshExtents;
glm::mat4 modelTransform; glm::mat4 modelTransform;
QVector<FBXBlendshape> blendshapes; QVector<HFMBlendshape> blendshapes;
unsigned int meshIndex; // the order the meshes appeared in the object file unsigned int meshIndex; // the order the meshes appeared in the object file
@ -265,7 +265,7 @@ public:
class ExtractedMesh { class ExtractedMesh {
public: public:
FBXMesh mesh; HFMMesh mesh;
QMultiHash<int, int> newIndices; QMultiHash<int, int> newIndices;
QVector<QHash<int, int> > blendshapeIndexMaps; QVector<QHash<int, int> > blendshapeIndexMaps;
QVector<QPair<int, int> > partMaterialTextures; QVector<QPair<int, int> > partMaterialTextures;
@ -278,14 +278,14 @@ public:
* @property {Vec3[]} translations * @property {Vec3[]} translations
*/ */
/// A single animation frame extracted from an FBX document. /// A single animation frame extracted from an FBX document.
class FBXAnimationFrame { class HFMAnimationFrame {
public: public:
QVector<glm::quat> rotations; QVector<glm::quat> rotations;
QVector<glm::vec3> translations; QVector<glm::vec3> translations;
}; };
/// A light in an FBX document. /// A light.
class FBXLight { class HFMLight {
public: public:
QString name; QString name;
Transform transform; Transform transform;
@ -293,7 +293,7 @@ public:
float fogValue; float fogValue;
glm::vec3 color; glm::vec3 color;
FBXLight() : HFMLight() :
name(), name(),
transform(), transform(),
intensity(1.0f), intensity(1.0f),
@ -302,26 +302,26 @@ public:
{} {}
}; };
Q_DECLARE_METATYPE(FBXAnimationFrame) Q_DECLARE_METATYPE(HFMAnimationFrame)
Q_DECLARE_METATYPE(QVector<FBXAnimationFrame>) Q_DECLARE_METATYPE(QVector<HFMAnimationFrame>)
/// A set of meshes extracted from an FBX document. /// A set of meshes extracted from an FBX document.
class FBXGeometry { class HFMGeometry {
public: public:
using Pointer = std::shared_ptr<FBXGeometry>; using Pointer = std::shared_ptr<HFMGeometry>;
QString originalURL; QString originalURL;
QString author; QString author;
QString applicationName; ///< the name of the application that generated the model QString applicationName; ///< the name of the application that generated the model
QVector<FBXJoint> joints; QVector<HFMJoint> joints;
QHash<QString, int> jointIndices; ///< 1-based, so as to more easily detect missing indices QHash<QString, int> jointIndices; ///< 1-based, so as to more easily detect missing indices
bool hasSkeletonJoints; bool hasSkeletonJoints;
QVector<FBXMesh> meshes; QVector<HFMMesh> meshes;
QVector<QString> scripts; QVector<QString> scripts;
QHash<QString, FBXMaterial> materials; QHash<QString, HFMMaterial> materials;
glm::mat4 offset; // This includes offset, rotation, and scale as specified by the FST file glm::mat4 offset; // This includes offset, rotation, and scale as specified by the FST file
@ -348,7 +348,7 @@ public:
Extents bindExtents; Extents bindExtents;
Extents meshExtents; Extents meshExtents;
QVector<FBXAnimationFrame> animationFrames; QVector<HFMAnimationFrame> animationFrames;
int getJointIndex(const QString& name) const { return jointIndices.value(name) - 1; } int getJointIndex(const QString& name) const { return jointIndices.value(name) - 1; }
QStringList getJointNames() const; QStringList getJointNames() const;
@ -368,7 +368,7 @@ public:
QList<QString> blendshapeChannelNames; QList<QString> blendshapeChannelNames;
}; };
Q_DECLARE_METATYPE(FBXGeometry) Q_DECLARE_METATYPE(HFMGeometry)
Q_DECLARE_METATYPE(FBXGeometry::Pointer) Q_DECLARE_METATYPE(HFMGeometry::Pointer)
#endif // hifi_FBX_h_ #endif // hifi_FBX_h_

View file

@ -40,19 +40,19 @@
using namespace std; using namespace std;
int FBXGeometryPointerMetaTypeId = qRegisterMetaType<FBXGeometry::Pointer>(); int HFMGeometryPointerMetaTypeId = qRegisterMetaType<HFMGeometry::Pointer>();
QStringList FBXGeometry::getJointNames() const { QStringList HFMGeometry::getJointNames() const {
QStringList names; QStringList names;
foreach (const FBXJoint& joint, joints) { foreach (const HFMJoint& joint, joints) {
names.append(joint.name); names.append(joint.name);
} }
return names; return names;
} }
bool FBXGeometry::hasBlendedMeshes() const { bool HFMGeometry::hasBlendedMeshes() const {
if (!meshes.isEmpty()) { if (!meshes.isEmpty()) {
foreach (const FBXMesh& mesh, meshes) { foreach (const HFMMesh& mesh, meshes) {
if (!mesh.blendshapes.isEmpty()) { if (!mesh.blendshapes.isEmpty()) {
return true; return true;
} }
@ -61,7 +61,7 @@ bool FBXGeometry::hasBlendedMeshes() const {
return false; return false;
} }
Extents FBXGeometry::getUnscaledMeshExtents() const { Extents HFMGeometry::getUnscaledMeshExtents() const {
const Extents& extents = meshExtents; const Extents& extents = meshExtents;
// even though our caller asked for "unscaled" we need to include any fst scaling, translation, and rotation, which // even though our caller asked for "unscaled" we need to include any fst scaling, translation, and rotation, which
@ -74,12 +74,12 @@ Extents FBXGeometry::getUnscaledMeshExtents() const {
} }
// TODO: Move to graphics::Mesh when Sam's ready // TODO: Move to graphics::Mesh when Sam's ready
bool FBXGeometry::convexHullContains(const glm::vec3& point) const { bool HFMGeometry::convexHullContains(const glm::vec3& point) const {
if (!getUnscaledMeshExtents().containsPoint(point)) { if (!getUnscaledMeshExtents().containsPoint(point)) {
return false; return false;
} }
auto checkEachPrimitive = [=](FBXMesh& mesh, QVector<int> indices, int primitiveSize) -> bool { auto checkEachPrimitive = [=](HFMMesh& mesh, QVector<int> indices, int primitiveSize) -> bool {
// Check whether the point is "behind" all the primitives. // Check whether the point is "behind" all the primitives.
int verticesSize = mesh.vertices.size(); int verticesSize = mesh.vertices.size();
for (int j = 0; for (int j = 0;
@ -124,16 +124,16 @@ bool FBXGeometry::convexHullContains(const glm::vec3& point) const {
return false; return false;
} }
QString FBXGeometry::getModelNameOfMesh(int meshIndex) const { QString HFMGeometry::getModelNameOfMesh(int meshIndex) const {
if (meshIndicesToModelNames.contains(meshIndex)) { if (meshIndicesToModelNames.contains(meshIndex)) {
return meshIndicesToModelNames.value(meshIndex); return meshIndicesToModelNames.value(meshIndex);
} }
return QString(); return QString();
} }
int fbxGeometryMetaTypeId = qRegisterMetaType<FBXGeometry>(); int hfmGeometryMetaTypeId = qRegisterMetaType<HFMGeometry>();
int fbxAnimationFrameMetaTypeId = qRegisterMetaType<FBXAnimationFrame>(); int hfmAnimationFrameMetaTypeId = qRegisterMetaType<HFMAnimationFrame>();
int fbxAnimationFrameVectorMetaTypeId = qRegisterMetaType<QVector<FBXAnimationFrame> >(); int hfmAnimationFrameVectorMetaTypeId = qRegisterMetaType<QVector<HFMAnimationFrame> >();
glm::vec3 parseVec3(const QString& string) { glm::vec3 parseVec3(const QString& string) {
@ -303,7 +303,7 @@ glm::mat4 getGlobalTransform(const QMultiMap<QString, QString>& _connectionParen
class ExtractedBlendshape { class ExtractedBlendshape {
public: public:
QString id; QString id;
FBXBlendshape blendshape; HFMBlendshape blendshape;
}; };
void printNode(const FBXNode& node, int indentLevel) { void printNode(const FBXNode& node, int indentLevel) {
@ -346,8 +346,8 @@ void appendModelIDs(const QString& parentID, const QMultiMap<QString, QString>&
} }
} }
FBXBlendshape extractBlendshape(const FBXNode& object) { HFMBlendshape extractBlendshape(const FBXNode& object) {
FBXBlendshape blendshape; HFMBlendshape blendshape;
foreach (const FBXNode& data, object.children) { foreach (const FBXNode& data, object.children) {
if (data.name == "Indexes") { if (data.name == "Indexes") {
blendshape.indices = FBXReader::getIntVector(data); blendshape.indices = FBXReader::getIntVector(data);
@ -362,9 +362,9 @@ FBXBlendshape extractBlendshape(const FBXNode& object) {
return blendshape; return blendshape;
} }
using IndexAccessor = std::function<glm::vec3*(const FBXMesh&, int, int, glm::vec3*, glm::vec3&)>; using IndexAccessor = std::function<glm::vec3*(const HFMMesh&, int, int, glm::vec3*, glm::vec3&)>;
static void setTangents(const FBXMesh& mesh, const IndexAccessor& vertexAccessor, int firstIndex, int secondIndex, static void setTangents(const HFMMesh& mesh, const IndexAccessor& vertexAccessor, int firstIndex, int secondIndex,
const QVector<glm::vec3>& vertices, const QVector<glm::vec3>& normals, QVector<glm::vec3>& tangents) { const QVector<glm::vec3>& vertices, const QVector<glm::vec3>& normals, QVector<glm::vec3>& tangents) {
glm::vec3 vertex[2]; glm::vec3 vertex[2];
glm::vec3 normal; glm::vec3 normal;
@ -381,14 +381,14 @@ static void setTangents(const FBXMesh& mesh, const IndexAccessor& vertexAccessor
} }
} }
static void createTangents(const FBXMesh& mesh, bool generateFromTexCoords, static void createTangents(const HFMMesh& mesh, bool generateFromTexCoords,
const QVector<glm::vec3>& vertices, const QVector<glm::vec3>& normals, QVector<glm::vec3>& tangents, const QVector<glm::vec3>& vertices, const QVector<glm::vec3>& normals, QVector<glm::vec3>& tangents,
IndexAccessor accessor) { IndexAccessor accessor) {
// if we have a normal map (and texture coordinates), we must compute tangents // if we have a normal map (and texture coordinates), we must compute tangents
if (generateFromTexCoords && !mesh.texCoords.isEmpty()) { if (generateFromTexCoords && !mesh.texCoords.isEmpty()) {
tangents.resize(vertices.size()); tangents.resize(vertices.size());
foreach(const FBXMeshPart& part, mesh.parts) { foreach(const HFMMeshPart& part, mesh.parts) {
for (int i = 0; i < part.quadIndices.size(); i += 4) { for (int i = 0; i < part.quadIndices.size(); i += 4) {
setTangents(mesh, accessor, part.quadIndices.at(i), part.quadIndices.at(i + 1), vertices, normals, tangents); setTangents(mesh, accessor, part.quadIndices.at(i), part.quadIndices.at(i + 1), vertices, normals, tangents);
setTangents(mesh, accessor, part.quadIndices.at(i + 1), part.quadIndices.at(i + 2), vertices, normals, tangents); setTangents(mesh, accessor, part.quadIndices.at(i + 1), part.quadIndices.at(i + 2), vertices, normals, tangents);
@ -403,27 +403,27 @@ static void createTangents(const FBXMesh& mesh, bool generateFromTexCoords,
setTangents(mesh, accessor, part.triangleIndices.at(i + 2), part.triangleIndices.at(i), vertices, normals, tangents); setTangents(mesh, accessor, part.triangleIndices.at(i + 2), part.triangleIndices.at(i), vertices, normals, tangents);
} }
if ((part.triangleIndices.size() % 3) != 0) { if ((part.triangleIndices.size() % 3) != 0) {
qCDebug(modelformat) << "Error in extractFBXGeometry part.triangleIndices.size() is not divisible by three "; qCDebug(modelformat) << "Error in extractHFMGeometry part.triangleIndices.size() is not divisible by three ";
} }
} }
} }
} }
static void _createBlendShapeTangents(FBXMesh& mesh, bool generateFromTexCoords, FBXBlendshape& blendShape); static void _createBlendShapeTangents(HFMMesh& mesh, bool generateFromTexCoords, HFMBlendshape& blendShape);
void FBXMesh::createBlendShapeTangents(bool generateTangents) { void HFMMesh::createBlendShapeTangents(bool generateTangents) {
for (auto& blendShape : blendshapes) { for (auto& blendShape : blendshapes) {
_createBlendShapeTangents(*this, generateTangents, blendShape); _createBlendShapeTangents(*this, generateTangents, blendShape);
} }
} }
void FBXMesh::createMeshTangents(bool generateFromTexCoords) { void HFMMesh::createMeshTangents(bool generateFromTexCoords) {
FBXMesh& mesh = *this; HFMMesh& mesh = *this;
// This is the only workaround I've found to trick the compiler into understanding that mesh.tangents isn't // This is the only workaround I've found to trick the compiler into understanding that mesh.tangents isn't
// const in the lambda function. // const in the lambda function.
auto& tangents = mesh.tangents; auto& tangents = mesh.tangents;
createTangents(mesh, generateFromTexCoords, mesh.vertices, mesh.normals, mesh.tangents, createTangents(mesh, generateFromTexCoords, mesh.vertices, mesh.normals, mesh.tangents,
[&](const FBXMesh& mesh, int firstIndex, int secondIndex, glm::vec3* outVertices, glm::vec3& outNormal) { [&](const HFMMesh& mesh, int firstIndex, int secondIndex, glm::vec3* outVertices, glm::vec3& outNormal) {
outVertices[0] = mesh.vertices[firstIndex]; outVertices[0] = mesh.vertices[firstIndex];
outVertices[1] = mesh.vertices[secondIndex]; outVertices[1] = mesh.vertices[secondIndex];
outNormal = mesh.normals[firstIndex]; outNormal = mesh.normals[firstIndex];
@ -431,7 +431,7 @@ void FBXMesh::createMeshTangents(bool generateFromTexCoords) {
}); });
} }
static void _createBlendShapeTangents(FBXMesh& mesh, bool generateFromTexCoords, FBXBlendshape& blendShape) { static void _createBlendShapeTangents(HFMMesh& mesh, bool generateFromTexCoords, HFMBlendshape& blendShape) {
// Create lookup to get index in blend shape from vertex index in mesh // Create lookup to get index in blend shape from vertex index in mesh
std::vector<int> reverseIndices; std::vector<int> reverseIndices;
reverseIndices.resize(mesh.vertices.size()); reverseIndices.resize(mesh.vertices.size());
@ -443,7 +443,7 @@ static void _createBlendShapeTangents(FBXMesh& mesh, bool generateFromTexCoords,
} }
createTangents(mesh, generateFromTexCoords, blendShape.vertices, blendShape.normals, blendShape.tangents, createTangents(mesh, generateFromTexCoords, blendShape.vertices, blendShape.normals, blendShape.tangents,
[&](const FBXMesh& mesh, int firstIndex, int secondIndex, glm::vec3* outVertices, glm::vec3& outNormal) { [&](const HFMMesh& mesh, int firstIndex, int secondIndex, glm::vec3* outVertices, glm::vec3& outNormal) {
const auto index1 = reverseIndices[firstIndex]; const auto index1 = reverseIndices[firstIndex];
const auto index2 = reverseIndices[secondIndex]; const auto index2 = reverseIndices[secondIndex];
@ -481,7 +481,7 @@ void addBlendshapes(const ExtractedBlendshape& extracted, const QList<WeightedIn
foreach (const WeightedIndex& index, indices) { foreach (const WeightedIndex& index, indices) {
extractedMesh.mesh.blendshapes.resize(max(extractedMesh.mesh.blendshapes.size(), index.first + 1)); extractedMesh.mesh.blendshapes.resize(max(extractedMesh.mesh.blendshapes.size(), index.first + 1));
extractedMesh.blendshapeIndexMaps.resize(extractedMesh.mesh.blendshapes.size()); extractedMesh.blendshapeIndexMaps.resize(extractedMesh.mesh.blendshapes.size());
FBXBlendshape& blendshape = extractedMesh.mesh.blendshapes[index.first]; HFMBlendshape& blendshape = extractedMesh.mesh.blendshapes[index.first];
QHash<int, int>& blendshapeIndexMap = extractedMesh.blendshapeIndexMaps[index.first]; QHash<int, int>& blendshapeIndexMap = extractedMesh.blendshapeIndexMaps[index.first];
for (int i = 0; i < extracted.blendshape.indices.size(); i++) { for (int i = 0; i < extracted.blendshape.indices.size(); i++) {
int oldIndex = extracted.blendshape.indices.at(i); int oldIndex = extracted.blendshape.indices.at(i);
@ -539,7 +539,7 @@ public:
QVector<float> values; QVector<float> values;
}; };
bool checkMaterialsHaveTextures(const QHash<QString, FBXMaterial>& materials, bool checkMaterialsHaveTextures(const QHash<QString, HFMMaterial>& materials,
const QHash<QString, QByteArray>& textureFilenames, const QMultiMap<QString, QString>& _connectionChildMap) { const QHash<QString, QByteArray>& textureFilenames, const QMultiMap<QString, QString>& _connectionChildMap) {
foreach (const QString& materialID, materials.keys()) { foreach (const QString& materialID, materials.keys()) {
foreach (const QString& childID, _connectionChildMap.values(materialID)) { foreach (const QString& childID, _connectionChildMap.values(materialID)) {
@ -569,8 +569,8 @@ int matchTextureUVSetToAttributeChannel(const QString& texUVSetName, const QHash
} }
FBXLight extractLight(const FBXNode& object) { HFMLight extractLight(const FBXNode& object) {
FBXLight light; HFMLight light;
foreach (const FBXNode& subobject, object.children) { foreach (const FBXNode& subobject, object.children) {
QString childname = QString(subobject.name); QString childname = QString(subobject.name);
if (subobject.name == "Properties70") { if (subobject.name == "Properties70") {
@ -615,7 +615,7 @@ QByteArray fileOnUrl(const QByteArray& filepath, const QString& url) {
return filepath.mid(filepath.lastIndexOf('/') + 1); return filepath.mid(filepath.lastIndexOf('/') + 1);
} }
FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QString& url) { HFMGeometry* FBXReader::extractHFMGeometry(const QVariantHash& mapping, const QString& url) {
const FBXNode& node = _rootNode; const FBXNode& node = _rootNode;
QMap<QString, ExtractedMesh> meshes; QMap<QString, ExtractedMesh> meshes;
QHash<QString, QString> modelIDsToNames; QHash<QString, QString> modelIDsToNames;
@ -636,7 +636,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
QHash<QString, QString> yComponents; QHash<QString, QString> yComponents;
QHash<QString, QString> zComponents; QHash<QString, QString> zComponents;
std::map<QString, FBXLight> lights; std::map<QString, HFMLight> lights;
QVariantHash joints = mapping.value("joint").toHash(); QVariantHash joints = mapping.value("joint").toHash();
QString jointEyeLeftName = processID(getString(joints.value("jointEyeLeft", "jointEyeLeft"))); QString jointEyeLeftName = processID(getString(joints.value("jointEyeLeft", "jointEyeLeft")));
@ -689,8 +689,8 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
#if defined(DEBUG_FBXREADER) #if defined(DEBUG_FBXREADER)
int unknown = 0; int unknown = 0;
#endif #endif
FBXGeometry* geometryPtr = new FBXGeometry; HFMGeometry* geometryPtr = new HFMGeometry;
FBXGeometry& geometry = *geometryPtr; HFMGeometry& geometry = *geometryPtr;
geometry.originalURL = url; geometry.originalURL = url;
@ -944,7 +944,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
lightprop = vprop.toString(); lightprop = vprop.toString();
} }
FBXLight light = extractLight(object); HFMLight light = extractLight(object);
} }
} }
} else { } else {
@ -1102,7 +1102,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
_textureContent.insert(filepath, content); _textureContent.insert(filepath, content);
} }
} else if (object.name == "Material") { } else if (object.name == "Material") {
FBXMaterial material; HFMMaterial material;
material.name = (object.properties.at(1).toString()); material.name = (object.properties.at(1).toString());
foreach (const FBXNode& subobject, object.children) { foreach (const FBXNode& subobject, object.children) {
bool properties = false; bool properties = false;
@ -1255,7 +1255,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
#endif #endif
} }
material.materialID = getID(object.properties); material.materialID = getID(object.properties);
_fbxMaterials.insert(material.materialID, material); _hfmMaterials.insert(material.materialID, material);
} else if (object.name == "NodeAttribute") { } else if (object.name == "NodeAttribute") {
@ -1276,7 +1276,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
if (!attributetype.isEmpty()) { if (!attributetype.isEmpty()) {
if (attributetype == "Light") { if (attributetype == "Light") {
FBXLight light = extractLight(object); HFMLight light = extractLight(object);
lights[attribID] = light; lights[attribID] = light;
} }
} }
@ -1345,7 +1345,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
QString parentID = getID(connection.properties, 2); QString parentID = getID(connection.properties, 2);
ooChildToParent.insert(childID, parentID); ooChildToParent.insert(childID, parentID);
if (!hifiGlobalNodeID.isEmpty() && (parentID == hifiGlobalNodeID)) { if (!hifiGlobalNodeID.isEmpty() && (parentID == hifiGlobalNodeID)) {
std::map< QString, FBXLight >::iterator lightIt = lights.find(childID); std::map< QString, HFMLight >::iterator lightIt = lights.find(childID);
if (lightIt != lights.end()) { if (lightIt != lights.end()) {
_lightmapLevel = (*lightIt).second.intensity; _lightmapLevel = (*lightIt).second.intensity;
if (_lightmapLevel <= 0.0f) { if (_lightmapLevel <= 0.0f) {
@ -1504,7 +1504,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
frameCount = qMax(frameCount, curve.values.size()); frameCount = qMax(frameCount, curve.values.size());
} }
for (int i = 0; i < frameCount; i++) { for (int i = 0; i < frameCount; i++) {
FBXAnimationFrame frame; HFMAnimationFrame frame;
frame.rotations.resize(modelIDs.size()); frame.rotations.resize(modelIDs.size());
frame.translations.resize(modelIDs.size()); frame.translations.resize(modelIDs.size());
geometry.animationFrames.append(frame); geometry.animationFrames.append(frame);
@ -1515,7 +1515,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
geometry.hasSkeletonJoints = false; geometry.hasSkeletonJoints = false;
foreach (const QString& modelID, modelIDs) { foreach (const QString& modelID, modelIDs) {
const FBXModel& model = models[modelID]; const FBXModel& model = models[modelID];
FBXJoint joint; HFMJoint joint;
joint.isFree = freeJoints.contains(model.name); joint.isFree = freeJoints.contains(model.name);
joint.parentIndex = model.parentIndex; joint.parentIndex = model.parentIndex;
@ -1553,7 +1553,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
joint.distanceToParent = 0.0f; joint.distanceToParent = 0.0f;
} else { } else {
const FBXJoint& parentJoint = geometry.joints.at(joint.parentIndex); const HFMJoint& parentJoint = geometry.joints.at(joint.parentIndex);
joint.transform = parentJoint.transform * glm::translate(joint.translation) * joint.transform = parentJoint.transform * glm::translate(joint.translation) *
joint.preTransform * glm::mat4_cast(combinedRotation) * joint.postTransform; joint.preTransform * glm::mat4_cast(combinedRotation) * joint.postTransform;
joint.inverseDefaultRotation = glm::inverse(combinedRotation) * parentJoint.inverseDefaultRotation; joint.inverseDefaultRotation = glm::inverse(combinedRotation) * parentJoint.inverseDefaultRotation;
@ -1631,7 +1631,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
geometry.meshExtents.reset(); geometry.meshExtents.reset();
// Create the Material Library // Create the Material Library
consolidateFBXMaterials(mapping); consolidateHFMMaterials(mapping);
// We can't allow the scaling of a given image to different sizes, because the hash used for the KTX cache is based on the original image // We can't allow the scaling of a given image to different sizes, because the hash used for the KTX cache is based on the original image
// Allowing scaling of the same image to different sizes would cause different KTX files to target the same cache key // Allowing scaling of the same image to different sizes would cause different KTX files to target the same cache key
@ -1643,7 +1643,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
// 33 - 128 textures --> 512 // 33 - 128 textures --> 512
// etc... // etc...
QSet<QString> uniqueTextures; QSet<QString> uniqueTextures;
for (auto& material : _fbxMaterials) { for (auto& material : _hfmMaterials) {
material.getTextureNames(uniqueTextures); material.getTextureNames(uniqueTextures);
} }
int numTextures = uniqueTextures.size(); int numTextures = uniqueTextures.size();
@ -1659,15 +1659,15 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
} while (numTextureThreshold < numTextures && maxWidth > MIN_MIP_TEXTURE_WIDTH); } while (numTextureThreshold < numTextures && maxWidth > MIN_MIP_TEXTURE_WIDTH);
qCDebug(modelformat) << "Capped square texture width =" << maxWidth << "for model" << url << "with" << numTextures << "textures"; qCDebug(modelformat) << "Capped square texture width =" << maxWidth << "for model" << url << "with" << numTextures << "textures";
for (auto& material : _fbxMaterials) { for (auto& material : _hfmMaterials) {
material.setMaxNumPixelsPerTexture(maxWidth * maxWidth); material.setMaxNumPixelsPerTexture(maxWidth * maxWidth);
} }
} }
#endif #endif
geometry.materials = _fbxMaterials; geometry.materials = _hfmMaterials;
// see if any materials have texture children // see if any materials have texture children
bool materialsHaveTextures = checkMaterialsHaveTextures(_fbxMaterials, _textureFilenames, _connectionChildMap); bool materialsHaveTextures = checkMaterialsHaveTextures(_hfmMaterials, _textureFilenames, _connectionChildMap);
for (QMap<QString, ExtractedMesh>::iterator it = meshes.begin(); it != meshes.end(); it++) { for (QMap<QString, ExtractedMesh>::iterator it = meshes.begin(); it != meshes.end(); it++) {
ExtractedMesh& extracted = it.value(); ExtractedMesh& extracted = it.value();
@ -1698,13 +1698,13 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
for (int i = children.size() - 1; i >= 0; i--) { for (int i = children.size() - 1; i >= 0; i--) {
const QString& childID = children.at(i); const QString& childID = children.at(i);
if (_fbxMaterials.contains(childID)) { if (_hfmMaterials.contains(childID)) {
// the pure material associated with this part // the pure material associated with this part
FBXMaterial material = _fbxMaterials.value(childID); HFMMaterial material = _hfmMaterials.value(childID);
for (int j = 0; j < extracted.partMaterialTextures.size(); j++) { for (int j = 0; j < extracted.partMaterialTextures.size(); j++) {
if (extracted.partMaterialTextures.at(j).first == materialIndex) { if (extracted.partMaterialTextures.at(j).first == materialIndex) {
FBXMeshPart& part = extracted.mesh.parts[j]; HFMMeshPart& part = extracted.mesh.parts[j];
part.materialID = material.materialID; part.materialID = material.materialID;
generateTangents |= material.needTangentSpace(); generateTangents |= material.needTangentSpace();
} }
@ -1713,7 +1713,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
materialIndex++; materialIndex++;
} else if (_textureFilenames.contains(childID)) { } else if (_textureFilenames.contains(childID)) {
FBXTexture texture = getTexture(childID); HFMTexture texture = getTexture(childID);
for (int j = 0; j < extracted.partMaterialTextures.size(); j++) { for (int j = 0; j < extracted.partMaterialTextures.size(); j++) {
int partTexture = extracted.partMaterialTextures.at(j).second; int partTexture = extracted.partMaterialTextures.at(j).second;
if (partTexture == textureIndex && !(partTexture == 0 && materialsHaveTextures)) { if (partTexture == textureIndex && !(partTexture == 0 && materialsHaveTextures)) {
@ -1736,34 +1736,34 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
if (!clusters.contains(clusterID)) { if (!clusters.contains(clusterID)) {
continue; continue;
} }
FBXCluster fbxCluster; HFMCluster hfmCluster;
const Cluster& cluster = clusters[clusterID]; const Cluster& cluster = clusters[clusterID];
clusterIDs.append(clusterID); clusterIDs.append(clusterID);
// see http://stackoverflow.com/questions/13566608/loading-skinning-information-from-fbx for a discussion // see http://stackoverflow.com/questions/13566608/loading-skinning-information-from-fbx for a discussion
// of skinning information in FBX // of skinning information in FBX
QString jointID = _connectionChildMap.value(clusterID); QString jointID = _connectionChildMap.value(clusterID);
fbxCluster.jointIndex = modelIDs.indexOf(jointID); hfmCluster.jointIndex = modelIDs.indexOf(jointID);
if (fbxCluster.jointIndex == -1) { if (hfmCluster.jointIndex == -1) {
qCDebug(modelformat) << "Joint not in model list: " << jointID; qCDebug(modelformat) << "Joint not in model list: " << jointID;
fbxCluster.jointIndex = 0; hfmCluster.jointIndex = 0;
} }
fbxCluster.inverseBindMatrix = glm::inverse(cluster.transformLink) * modelTransform; hfmCluster.inverseBindMatrix = glm::inverse(cluster.transformLink) * modelTransform;
// slam bottom row to (0, 0, 0, 1), we KNOW this is not a perspective matrix and // slam bottom row to (0, 0, 0, 1), we KNOW this is not a perspective matrix and
// sometimes floating point fuzz can be introduced after the inverse. // sometimes floating point fuzz can be introduced after the inverse.
fbxCluster.inverseBindMatrix[0][3] = 0.0f; hfmCluster.inverseBindMatrix[0][3] = 0.0f;
fbxCluster.inverseBindMatrix[1][3] = 0.0f; hfmCluster.inverseBindMatrix[1][3] = 0.0f;
fbxCluster.inverseBindMatrix[2][3] = 0.0f; hfmCluster.inverseBindMatrix[2][3] = 0.0f;
fbxCluster.inverseBindMatrix[3][3] = 1.0f; hfmCluster.inverseBindMatrix[3][3] = 1.0f;
fbxCluster.inverseBindTransform = Transform(fbxCluster.inverseBindMatrix); hfmCluster.inverseBindTransform = Transform(hfmCluster.inverseBindMatrix);
extracted.mesh.clusters.append(fbxCluster); extracted.mesh.clusters.append(hfmCluster);
// override the bind rotation with the transform link // override the bind rotation with the transform link
FBXJoint& joint = geometry.joints[fbxCluster.jointIndex]; HFMJoint& joint = geometry.joints[hfmCluster.jointIndex];
joint.inverseBindRotation = glm::inverse(extractRotation(cluster.transformLink)); joint.inverseBindRotation = glm::inverse(extractRotation(cluster.transformLink));
joint.bindTransform = cluster.transformLink; joint.bindTransform = cluster.transformLink;
joint.bindTransformFoundInCluster = true; joint.bindTransformFoundInCluster = true;
@ -1776,7 +1776,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
// if we don't have a skinned joint, parent to the model itself // if we don't have a skinned joint, parent to the model itself
if (extracted.mesh.clusters.isEmpty()) { if (extracted.mesh.clusters.isEmpty()) {
FBXCluster cluster; HFMCluster cluster;
cluster.jointIndex = modelIDs.indexOf(modelID); cluster.jointIndex = modelIDs.indexOf(modelID);
if (cluster.jointIndex == -1) { if (cluster.jointIndex == -1) {
qCDebug(modelformat) << "Model not in model list: " << modelID; qCDebug(modelformat) << "Model not in model list: " << modelID;
@ -1786,7 +1786,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
} }
// whether we're skinned depends on how many clusters are attached // whether we're skinned depends on how many clusters are attached
const FBXCluster& firstFBXCluster = extracted.mesh.clusters.at(0); const HFMCluster& firstHFMCluster = extracted.mesh.clusters.at(0);
glm::mat4 inverseModelTransform = glm::inverse(modelTransform); glm::mat4 inverseModelTransform = glm::inverse(modelTransform);
if (clusterIDs.size() > 1) { if (clusterIDs.size() > 1) {
// this is a multi-mesh joint // this is a multi-mesh joint
@ -1799,9 +1799,9 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
for (int i = 0; i < clusterIDs.size(); i++) { for (int i = 0; i < clusterIDs.size(); i++) {
QString clusterID = clusterIDs.at(i); QString clusterID = clusterIDs.at(i);
const Cluster& cluster = clusters[clusterID]; const Cluster& cluster = clusters[clusterID];
const FBXCluster& fbxCluster = extracted.mesh.clusters.at(i); const HFMCluster& hfmCluster = extracted.mesh.clusters.at(i);
int jointIndex = fbxCluster.jointIndex; int jointIndex = hfmCluster.jointIndex;
FBXJoint& joint = geometry.joints[jointIndex]; HFMJoint& joint = geometry.joints[jointIndex];
glm::mat4 transformJointToMesh = inverseModelTransform * joint.bindTransform; glm::mat4 transformJointToMesh = inverseModelTransform * joint.bindTransform;
glm::vec3 boneEnd = extractTranslation(transformJointToMesh); glm::vec3 boneEnd = extractTranslation(transformJointToMesh);
glm::vec3 boneBegin = boneEnd; glm::vec3 boneBegin = boneEnd;
@ -1881,8 +1881,8 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
} }
} else { } else {
// this is a single-mesh joint // this is a single-mesh joint
int jointIndex = firstFBXCluster.jointIndex; int jointIndex = firstHFMCluster.jointIndex;
FBXJoint& joint = geometry.joints[jointIndex]; HFMJoint& joint = geometry.joints[jointIndex];
// transform cluster vertices to joint-frame and save for later // transform cluster vertices to joint-frame and save for later
glm::mat4 meshToJoint = glm::inverse(joint.bindTransform) * modelTransform; glm::mat4 meshToJoint = glm::inverse(joint.bindTransform) * modelTransform;
@ -1924,7 +1924,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
// now that all joints have been scanned compute a k-Dop bounding volume of mesh // now that all joints have been scanned compute a k-Dop bounding volume of mesh
for (int i = 0; i < geometry.joints.size(); ++i) { for (int i = 0; i < geometry.joints.size(); ++i) {
FBXJoint& joint = geometry.joints[i]; HFMJoint& joint = geometry.joints[i];
// NOTE: points are in joint-frame // NOTE: points are in joint-frame
ShapeVertices& points = shapeVertices.at(i); ShapeVertices& points = shapeVertices.at(i);
@ -1994,13 +1994,13 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
return geometryPtr; return geometryPtr;
} }
FBXGeometry* readFBX(const QByteArray& model, const QVariantHash& mapping, const QString& url, bool loadLightmaps, float lightmapLevel) { HFMGeometry* readFBX(const QByteArray& model, const QVariantHash& mapping, const QString& url, bool loadLightmaps, float lightmapLevel) {
QBuffer buffer(const_cast<QByteArray*>(&model)); QBuffer buffer(const_cast<QByteArray*>(&model));
buffer.open(QIODevice::ReadOnly); buffer.open(QIODevice::ReadOnly);
return readFBX(&buffer, mapping, url, loadLightmaps, lightmapLevel); return readFBX(&buffer, mapping, url, loadLightmaps, lightmapLevel);
} }
FBXGeometry* readFBX(QIODevice* device, const QVariantHash& mapping, const QString& url, bool loadLightmaps, float lightmapLevel) { HFMGeometry* readFBX(QIODevice* device, const QVariantHash& mapping, const QString& url, bool loadLightmaps, float lightmapLevel) {
FBXReader reader; FBXReader reader;
reader._rootNode = FBXReader::parseFBX(device); reader._rootNode = FBXReader::parseFBX(device);
reader._loadLightmaps = loadLightmaps; reader._loadLightmaps = loadLightmaps;
@ -2008,5 +2008,5 @@ FBXGeometry* readFBX(QIODevice* device, const QVariantHash& mapping, const QStri
qCDebug(modelformat) << "Reading FBX: " << url; qCDebug(modelformat) << "Reading FBX: " << url;
return reader.extractFBXGeometry(mapping, url); return reader.extractHFMGeometry(mapping, url);
} }

View file

@ -36,11 +36,11 @@ class FBXNode;
/// Reads FBX geometry from the supplied model and mapping data. /// Reads FBX geometry from the supplied model and mapping data.
/// \exception QString if an error occurs in parsing /// \exception QString if an error occurs in parsing
FBXGeometry* readFBX(const QByteArray& model, const QVariantHash& mapping, const QString& url = "", bool loadLightmaps = true, float lightmapLevel = 1.0f); HFMGeometry* readFBX(const QByteArray& model, const QVariantHash& mapping, const QString& url = "", bool loadLightmaps = true, float lightmapLevel = 1.0f);
/// Reads FBX geometry from the supplied model and mapping data. /// Reads FBX geometry from the supplied model and mapping data.
/// \exception QString if an error occurs in parsing /// \exception QString if an error occurs in parsing
FBXGeometry* readFBX(QIODevice* device, const QVariantHash& mapping, const QString& url = "", bool loadLightmaps = true, float lightmapLevel = 1.0f); HFMGeometry* readFBX(QIODevice* device, const QVariantHash& mapping, const QString& url = "", bool loadLightmaps = true, float lightmapLevel = 1.0f);
class TextureParam { class TextureParam {
public: public:
@ -103,20 +103,20 @@ class ExtractedMesh;
class FBXReader { class FBXReader {
public: public:
FBXGeometry* _fbxGeometry; HFMGeometry* _hfmGeometry;
FBXNode _rootNode; FBXNode _rootNode;
static FBXNode parseFBX(QIODevice* device); static FBXNode parseFBX(QIODevice* device);
FBXGeometry* extractFBXGeometry(const QVariantHash& mapping, const QString& url); HFMGeometry* extractHFMGeometry(const QVariantHash& mapping, const QString& url);
static ExtractedMesh extractMesh(const FBXNode& object, unsigned int& meshIndex, bool deduplicate = true); static ExtractedMesh extractMesh(const FBXNode& object, unsigned int& meshIndex, bool deduplicate = true);
QHash<QString, ExtractedMesh> meshes; QHash<QString, ExtractedMesh> meshes;
static void buildModelMesh(FBXMesh& extractedMesh, const QString& url); static void buildModelMesh(HFMMesh& extractedMesh, const QString& url);
static glm::vec3 normalizeDirForPacking(const glm::vec3& dir); static glm::vec3 normalizeDirForPacking(const glm::vec3& dir);
FBXTexture getTexture(const QString& textureID); HFMTexture getTexture(const QString& textureID);
QHash<QString, QString> _textureNames; QHash<QString, QString> _textureNames;
// Hashes the original RelativeFilename of textures // Hashes the original RelativeFilename of textures
@ -142,9 +142,9 @@ public:
QHash<QString, QString> ambientFactorTextures; QHash<QString, QString> ambientFactorTextures;
QHash<QString, QString> occlusionTextures; QHash<QString, QString> occlusionTextures;
QHash<QString, FBXMaterial> _fbxMaterials; QHash<QString, HFMMaterial> _hfmMaterials;
void consolidateFBXMaterials(const QVariantHash& mapping); void consolidateHFMMaterials(const QVariantHash& mapping);
bool _loadLightmaps = true; bool _loadLightmaps = true;
float _lightmapOffset = 0.0f; float _lightmapOffset = 0.0f;

View file

@ -27,7 +27,7 @@
#include "ModelFormatLogging.h" #include "ModelFormatLogging.h"
void FBXMaterial::getTextureNames(QSet<QString>& textureList) const { void HFMMaterial::getTextureNames(QSet<QString>& textureList) const {
if (!normalTexture.isNull()) { if (!normalTexture.isNull()) {
textureList.insert(normalTexture.name); textureList.insert(normalTexture.name);
} }
@ -63,7 +63,7 @@ void FBXMaterial::getTextureNames(QSet<QString>& textureList) const {
} }
} }
void FBXMaterial::setMaxNumPixelsPerTexture(int maxNumPixels) { void HFMMaterial::setMaxNumPixelsPerTexture(int maxNumPixels) {
normalTexture.maxNumPixels = maxNumPixels; normalTexture.maxNumPixels = maxNumPixels;
albedoTexture.maxNumPixels = maxNumPixels; albedoTexture.maxNumPixels = maxNumPixels;
opacityTexture.maxNumPixels = maxNumPixels; opacityTexture.maxNumPixels = maxNumPixels;
@ -77,12 +77,12 @@ void FBXMaterial::setMaxNumPixelsPerTexture(int maxNumPixels) {
lightmapTexture.maxNumPixels = maxNumPixels; lightmapTexture.maxNumPixels = maxNumPixels;
} }
bool FBXMaterial::needTangentSpace() const { bool HFMMaterial::needTangentSpace() const {
return !normalTexture.isNull(); return !normalTexture.isNull();
} }
FBXTexture FBXReader::getTexture(const QString& textureID) { HFMTexture FBXReader::getTexture(const QString& textureID) {
FBXTexture texture; HFMTexture texture;
const QByteArray& filepath = _textureFilepaths.value(textureID); const QByteArray& filepath = _textureFilepaths.value(textureID);
texture.content = _textureContent.value(filepath); texture.content = _textureContent.value(filepath);
@ -123,7 +123,7 @@ FBXTexture FBXReader::getTexture(const QString& textureID) {
return texture; return texture;
} }
void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) { void FBXReader::consolidateHFMMaterials(const QVariantHash& mapping) {
QString materialMapString = mapping.value("materialMap").toString(); QString materialMapString = mapping.value("materialMap").toString();
QJsonDocument materialMapDocument = QJsonDocument::fromJson(materialMapString.toUtf8()); QJsonDocument materialMapDocument = QJsonDocument::fromJson(materialMapString.toUtf8());
@ -133,16 +133,16 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) {
qCDebug(modelformat) << "fbx Material Map found but did not produce valid JSON:" << materialMapString; qCDebug(modelformat) << "fbx Material Map found but did not produce valid JSON:" << materialMapString;
} }
} }
for (QHash<QString, FBXMaterial>::iterator it = _fbxMaterials.begin(); it != _fbxMaterials.end(); it++) { for (QHash<QString, HFMMaterial>::iterator it = _hfmMaterials.begin(); it != _hfmMaterials.end(); it++) {
FBXMaterial& material = (*it); HFMMaterial& material = (*it);
// Maya is the exporting the shading model and we are trying to use it // Maya is the exporting the shading model and we are trying to use it
bool isMaterialLambert = (material.shadingModel.toLower() == "lambert"); bool isMaterialLambert = (material.shadingModel.toLower() == "lambert");
// the pure material associated with this part // the pure material associated with this part
bool detectDifferentUVs = false; bool detectDifferentUVs = false;
FBXTexture diffuseTexture; HFMTexture diffuseTexture;
FBXTexture diffuseFactorTexture; HFMTexture diffuseFactorTexture;
QString diffuseTextureID = diffuseTextures.value(material.materialID); QString diffuseTextureID = diffuseTextures.value(material.materialID);
QString diffuseFactorTextureID = diffuseFactorTextures.value(material.materialID); QString diffuseFactorTextureID = diffuseFactorTextures.value(material.materialID);
@ -169,7 +169,7 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) {
detectDifferentUVs = (diffuseTexture.texcoordSet != 0) || (!diffuseTexture.transform.isIdentity()); detectDifferentUVs = (diffuseTexture.texcoordSet != 0) || (!diffuseTexture.transform.isIdentity());
} }
FBXTexture transparentTexture; HFMTexture transparentTexture;
QString transparentTextureID = transparentTextures.value(material.materialID); QString transparentTextureID = transparentTextures.value(material.materialID);
// If PBS Material, systematically bind the albedo texture as transparency texture and check for the alpha channel // If PBS Material, systematically bind the albedo texture as transparency texture and check for the alpha channel
if (material.isPBSMaterial) { if (material.isPBSMaterial) {
@ -181,7 +181,7 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) {
detectDifferentUVs |= (transparentTexture.texcoordSet != 0) || (!transparentTexture.transform.isIdentity()); detectDifferentUVs |= (transparentTexture.texcoordSet != 0) || (!transparentTexture.transform.isIdentity());
} }
FBXTexture normalTexture; HFMTexture normalTexture;
QString bumpTextureID = bumpTextures.value(material.materialID); QString bumpTextureID = bumpTextures.value(material.materialID);
QString normalTextureID = normalTextures.value(material.materialID); QString normalTextureID = normalTextures.value(material.materialID);
if (!normalTextureID.isNull()) { if (!normalTextureID.isNull()) {
@ -198,7 +198,7 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) {
detectDifferentUVs |= (normalTexture.texcoordSet != 0) || (!normalTexture.transform.isIdentity()); detectDifferentUVs |= (normalTexture.texcoordSet != 0) || (!normalTexture.transform.isIdentity());
} }
FBXTexture specularTexture; HFMTexture specularTexture;
QString specularTextureID = specularTextures.value(material.materialID); QString specularTextureID = specularTextures.value(material.materialID);
if (!specularTextureID.isNull()) { if (!specularTextureID.isNull()) {
specularTexture = getTexture(specularTextureID); specularTexture = getTexture(specularTextureID);
@ -206,7 +206,7 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) {
material.specularTexture = specularTexture; material.specularTexture = specularTexture;
} }
FBXTexture metallicTexture; HFMTexture metallicTexture;
QString metallicTextureID = metallicTextures.value(material.materialID); QString metallicTextureID = metallicTextures.value(material.materialID);
if (!metallicTextureID.isNull()) { if (!metallicTextureID.isNull()) {
metallicTexture = getTexture(metallicTextureID); metallicTexture = getTexture(metallicTextureID);
@ -214,7 +214,7 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) {
material.metallicTexture = metallicTexture; material.metallicTexture = metallicTexture;
} }
FBXTexture roughnessTexture; HFMTexture roughnessTexture;
QString roughnessTextureID = roughnessTextures.value(material.materialID); QString roughnessTextureID = roughnessTextures.value(material.materialID);
if (!roughnessTextureID.isNull()) { if (!roughnessTextureID.isNull()) {
roughnessTexture = getTexture(roughnessTextureID); roughnessTexture = getTexture(roughnessTextureID);
@ -222,7 +222,7 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) {
detectDifferentUVs |= (roughnessTexture.texcoordSet != 0) || (!roughnessTexture.transform.isIdentity()); detectDifferentUVs |= (roughnessTexture.texcoordSet != 0) || (!roughnessTexture.transform.isIdentity());
} }
FBXTexture shininessTexture; HFMTexture shininessTexture;
QString shininessTextureID = shininessTextures.value(material.materialID); QString shininessTextureID = shininessTextures.value(material.materialID);
if (!shininessTextureID.isNull()) { if (!shininessTextureID.isNull()) {
shininessTexture = getTexture(shininessTextureID); shininessTexture = getTexture(shininessTextureID);
@ -230,7 +230,7 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) {
detectDifferentUVs |= (shininessTexture.texcoordSet != 0) || (!shininessTexture.transform.isIdentity()); detectDifferentUVs |= (shininessTexture.texcoordSet != 0) || (!shininessTexture.transform.isIdentity());
} }
FBXTexture emissiveTexture; HFMTexture emissiveTexture;
QString emissiveTextureID = emissiveTextures.value(material.materialID); QString emissiveTextureID = emissiveTextures.value(material.materialID);
if (!emissiveTextureID.isNull()) { if (!emissiveTextureID.isNull()) {
emissiveTexture = getTexture(emissiveTextureID); emissiveTexture = getTexture(emissiveTextureID);
@ -245,7 +245,7 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) {
} }
} }
FBXTexture occlusionTexture; HFMTexture occlusionTexture;
QString occlusionTextureID = occlusionTextures.value(material.materialID); QString occlusionTextureID = occlusionTextures.value(material.materialID);
if (occlusionTextureID.isNull()) { if (occlusionTextureID.isNull()) {
// 2nd chance // 2nd chance
@ -265,7 +265,7 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) {
lightmapParams.x = _lightmapOffset; lightmapParams.x = _lightmapOffset;
lightmapParams.y = _lightmapLevel; lightmapParams.y = _lightmapLevel;
FBXTexture ambientTexture; HFMTexture ambientTexture;
QString ambientTextureID = ambientTextures.value(material.materialID); QString ambientTextureID = ambientTextures.value(material.materialID);
if (ambientTextureID.isNull()) { if (ambientTextureID.isNull()) {
// 2nd chance // 2nd chance
@ -326,7 +326,7 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) {
if (materialOptions.contains("scatteringMap")) { if (materialOptions.contains("scatteringMap")) {
QByteArray scatteringMap = materialOptions.value("scatteringMap").toVariant().toByteArray(); QByteArray scatteringMap = materialOptions.value("scatteringMap").toVariant().toByteArray();
material.scatteringTexture = FBXTexture(); material.scatteringTexture = HFMTexture();
material.scatteringTexture.name = material.name + ".scatteringMap"; material.scatteringTexture.name = material.name + ".scatteringMap";
material.scatteringTexture.filename = scatteringMap; material.scatteringTexture.filename = scatteringMap;
} }

View file

@ -42,9 +42,9 @@
using vec2h = glm::tvec2<glm::detail::hdata>; using vec2h = glm::tvec2<glm::detail::hdata>;
#define FBX_PACK_COLORS 1 #define HFM_PACK_COLORS 1
#if FBX_PACK_COLORS #if HFM_PACK_COLORS
using ColorType = glm::uint32; using ColorType = glm::uint32;
#define FBX_COLOR_ELEMENT gpu::Element::COLOR_RGBA_32 #define FBX_COLOR_ELEMENT gpu::Element::COLOR_RGBA_32
#else #else
@ -469,7 +469,7 @@ ExtractedMesh FBXReader::extractMesh(const FBXNode& object, unsigned int& meshIn
QPair<int, int> materialTexture(materialID, 0); QPair<int, int> materialTexture(materialID, 0);
// grab or setup the FBXMeshPart for the part this face belongs to // grab or setup the HFMMeshPart for the part this face belongs to
int& partIndexPlusOne = materialTextureParts[materialTexture]; int& partIndexPlusOne = materialTextureParts[materialTexture];
if (partIndexPlusOne == 0) { if (partIndexPlusOne == 0) {
data.extracted.partMaterialTextures.append(materialTexture); data.extracted.partMaterialTextures.append(materialTexture);
@ -478,7 +478,7 @@ ExtractedMesh FBXReader::extractMesh(const FBXNode& object, unsigned int& meshIn
} }
// give the mesh part this index // give the mesh part this index
FBXMeshPart& part = data.extracted.mesh.parts[partIndexPlusOne - 1]; HFMMeshPart& part = data.extracted.mesh.parts[partIndexPlusOne - 1];
part.triangleIndices.append(firstCorner.value()); part.triangleIndices.append(firstCorner.value());
part.triangleIndices.append(dracoFace[1].value()); part.triangleIndices.append(dracoFace[1].value());
part.triangleIndices.append(dracoFace[2].value()); part.triangleIndices.append(dracoFace[2].value());
@ -511,7 +511,7 @@ ExtractedMesh FBXReader::extractMesh(const FBXNode& object, unsigned int& meshIn
data.extracted.mesh.parts.resize(data.extracted.mesh.parts.size() + 1); data.extracted.mesh.parts.resize(data.extracted.mesh.parts.size() + 1);
partIndex = data.extracted.mesh.parts.size(); partIndex = data.extracted.mesh.parts.size();
} }
FBXMeshPart& part = data.extracted.mesh.parts[partIndex - 1]; HFMMeshPart& part = data.extracted.mesh.parts[partIndex - 1];
if (endIndex - beginIndex == 4) { if (endIndex - beginIndex == 4) {
appendIndex(data, part.quadIndices, beginIndex++, deduplicate); appendIndex(data, part.quadIndices, beginIndex++, deduplicate);
@ -565,9 +565,9 @@ glm::vec3 FBXReader::normalizeDirForPacking(const glm::vec3& dir) {
return dir; return dir;
} }
void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { void FBXReader::buildModelMesh(HFMMesh& extractedMesh, const QString& url) {
unsigned int totalSourceIndices = 0; unsigned int totalSourceIndices = 0;
foreach(const FBXMeshPart& part, extractedMesh.parts) { foreach(const HFMMeshPart& part, extractedMesh.parts) {
totalSourceIndices += (part.quadTrianglesIndices.size() + part.triangleIndices.size()); totalSourceIndices += (part.quadTrianglesIndices.size() + part.triangleIndices.size());
} }
@ -583,17 +583,17 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
return; return;
} }
FBXMesh& fbxMesh = extractedMesh; HFMMesh& hfmMesh = extractedMesh;
graphics::MeshPointer mesh(new graphics::Mesh()); graphics::MeshPointer mesh(new graphics::Mesh());
int numVerts = extractedMesh.vertices.size(); int numVerts = extractedMesh.vertices.size();
if (!fbxMesh.normals.empty() && fbxMesh.tangents.empty()) { if (!hfmMesh.normals.empty() && hfmMesh.tangents.empty()) {
// Fill with a dummy value to force tangents to be present if there are normals // Fill with a dummy value to force tangents to be present if there are normals
fbxMesh.tangents.reserve(fbxMesh.normals.size()); hfmMesh.tangents.reserve(hfmMesh.normals.size());
std::fill_n(std::back_inserter(fbxMesh.tangents), fbxMesh.normals.size(), Vectors::UNIT_X); std::fill_n(std::back_inserter(hfmMesh.tangents), hfmMesh.normals.size(), Vectors::UNIT_X);
} }
// Same thing with blend shapes // Same thing with blend shapes
for (auto& blendShape : fbxMesh.blendshapes) { for (auto& blendShape : hfmMesh.blendshapes) {
if (!blendShape.normals.empty() && blendShape.tangents.empty()) { if (!blendShape.normals.empty() && blendShape.tangents.empty()) {
// Fill with a dummy value to force tangents to be present if there are normals // Fill with a dummy value to force tangents to be present if there are normals
blendShape.tangents.reserve(blendShape.normals.size()); blendShape.tangents.reserve(blendShape.normals.size());
@ -609,8 +609,8 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
// Normal and tangent are always there together packed in normalized xyz32bits word (times 2) // Normal and tangent are always there together packed in normalized xyz32bits word (times 2)
const auto normalElement = FBX_NORMAL_ELEMENT; const auto normalElement = FBX_NORMAL_ELEMENT;
const int normalsSize = fbxMesh.normals.size() * normalElement.getSize(); const int normalsSize = hfmMesh.normals.size() * normalElement.getSize();
const int tangentsSize = fbxMesh.tangents.size() * normalElement.getSize(); const int tangentsSize = hfmMesh.tangents.size() * normalElement.getSize();
// If there are normals then there should be tangents // If there are normals then there should be tangents
assert(normalsSize <= tangentsSize); assert(normalsSize <= tangentsSize);
if (tangentsSize > normalsSize) { if (tangentsSize > normalsSize) {
@ -620,22 +620,22 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
// Color attrib // Color attrib
const auto colorElement = FBX_COLOR_ELEMENT; const auto colorElement = FBX_COLOR_ELEMENT;
const int colorsSize = fbxMesh.colors.size() * colorElement.getSize(); const int colorsSize = hfmMesh.colors.size() * colorElement.getSize();
// Texture coordinates are stored in 2 half floats // Texture coordinates are stored in 2 half floats
const auto texCoordsElement = gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV); const auto texCoordsElement = gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV);
const int texCoordsSize = fbxMesh.texCoords.size() * texCoordsElement.getSize(); const int texCoordsSize = hfmMesh.texCoords.size() * texCoordsElement.getSize();
const int texCoords1Size = fbxMesh.texCoords1.size() * texCoordsElement.getSize(); const int texCoords1Size = hfmMesh.texCoords1.size() * texCoordsElement.getSize();
// Support for 4 skinning clusters: // Support for 4 skinning clusters:
// 4 Indices are uint8 ideally, uint16 if more than 256. // 4 Indices are uint8 ideally, uint16 if more than 256.
const auto clusterIndiceElement = (fbxMesh.clusters.size() < UINT8_MAX ? gpu::Element(gpu::VEC4, gpu::UINT8, gpu::XYZW) : gpu::Element(gpu::VEC4, gpu::UINT16, gpu::XYZW)); const auto clusterIndiceElement = (hfmMesh.clusters.size() < UINT8_MAX ? gpu::Element(gpu::VEC4, gpu::UINT8, gpu::XYZW) : gpu::Element(gpu::VEC4, gpu::UINT16, gpu::XYZW));
// 4 Weights are normalized 16bits // 4 Weights are normalized 16bits
const auto clusterWeightElement = gpu::Element(gpu::VEC4, gpu::NUINT16, gpu::XYZW); const auto clusterWeightElement = gpu::Element(gpu::VEC4, gpu::NUINT16, gpu::XYZW);
// Cluster indices and weights must be the same sizes // Cluster indices and weights must be the same sizes
const int NUM_CLUSTERS_PER_VERT = 4; const int NUM_CLUSTERS_PER_VERT = 4;
const int numVertClusters = (fbxMesh.clusterIndices.size() == fbxMesh.clusterWeights.size() ? fbxMesh.clusterIndices.size() / NUM_CLUSTERS_PER_VERT : 0); const int numVertClusters = (hfmMesh.clusterIndices.size() == hfmMesh.clusterWeights.size() ? hfmMesh.clusterIndices.size() / NUM_CLUSTERS_PER_VERT : 0);
const int clusterIndicesSize = numVertClusters * clusterIndiceElement.getSize(); const int clusterIndicesSize = numVertClusters * clusterIndiceElement.getSize();
const int clusterWeightsSize = numVertClusters * clusterWeightElement.getSize(); const int clusterWeightsSize = numVertClusters * clusterWeightElement.getSize();
@ -660,9 +660,9 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
if (normalsSize > 0) { if (normalsSize > 0) {
std::vector<NormalType> normalsAndTangents; std::vector<NormalType> normalsAndTangents;
normalsAndTangents.reserve(fbxMesh.normals.size() + fbxMesh.tangents.size()); normalsAndTangents.reserve(hfmMesh.normals.size() + hfmMesh.tangents.size());
for (auto normalIt = fbxMesh.normals.constBegin(), tangentIt = fbxMesh.tangents.constBegin(); for (auto normalIt = hfmMesh.normals.constBegin(), tangentIt = hfmMesh.tangents.constBegin();
normalIt != fbxMesh.normals.constEnd(); normalIt != hfmMesh.normals.constEnd();
++normalIt, ++tangentIt) { ++normalIt, ++tangentIt) {
#if FBX_PACK_NORMALS #if FBX_PACK_NORMALS
const auto normal = normalizeDirForPacking(*normalIt); const auto normal = normalizeDirForPacking(*normalIt);
@ -681,24 +681,24 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
// Pack colors // Pack colors
if (colorsSize > 0) { if (colorsSize > 0) {
#if FBX_PACK_COLORS #if HFM_PACK_COLORS
std::vector<ColorType> colors; std::vector<ColorType> colors;
colors.reserve(fbxMesh.colors.size()); colors.reserve(hfmMesh.colors.size());
for (const auto& color : fbxMesh.colors) { for (const auto& color : hfmMesh.colors) {
colors.push_back(glm::packUnorm4x8(glm::vec4(color, 1.0f))); colors.push_back(glm::packUnorm4x8(glm::vec4(color, 1.0f)));
} }
vertBuffer->setSubData(colorsOffset, colorsSize, (const gpu::Byte*) colors.data()); vertBuffer->setSubData(colorsOffset, colorsSize, (const gpu::Byte*) colors.data());
#else #else
vertBuffer->setSubData(colorsOffset, colorsSize, (const gpu::Byte*) fbxMesh.colors.constData()); vertBuffer->setSubData(colorsOffset, colorsSize, (const gpu::Byte*) hfmMesh.colors.constData());
#endif #endif
} }
// Pack Texcoords 0 and 1 (if exists) // Pack Texcoords 0 and 1 (if exists)
if (texCoordsSize > 0) { if (texCoordsSize > 0) {
QVector<vec2h> texCoordData; QVector<vec2h> texCoordData;
texCoordData.reserve(fbxMesh.texCoords.size()); texCoordData.reserve(hfmMesh.texCoords.size());
for (auto& texCoordVec2f : fbxMesh.texCoords) { for (auto& texCoordVec2f : hfmMesh.texCoords) {
vec2h texCoordVec2h; vec2h texCoordVec2h;
texCoordVec2h.x = glm::detail::toFloat16(texCoordVec2f.x); texCoordVec2h.x = glm::detail::toFloat16(texCoordVec2f.x);
@ -709,8 +709,8 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
} }
if (texCoords1Size > 0) { if (texCoords1Size > 0) {
QVector<vec2h> texCoordData; QVector<vec2h> texCoordData;
texCoordData.reserve(fbxMesh.texCoords1.size()); texCoordData.reserve(hfmMesh.texCoords1.size());
for (auto& texCoordVec2f : fbxMesh.texCoords1) { for (auto& texCoordVec2f : hfmMesh.texCoords1) {
vec2h texCoordVec2h; vec2h texCoordVec2h;
texCoordVec2h.x = glm::detail::toFloat16(texCoordVec2f.x); texCoordVec2h.x = glm::detail::toFloat16(texCoordVec2f.x);
@ -722,22 +722,22 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
// Clusters data // Clusters data
if (clusterIndicesSize > 0) { if (clusterIndicesSize > 0) {
if (fbxMesh.clusters.size() < UINT8_MAX) { if (hfmMesh.clusters.size() < UINT8_MAX) {
// yay! we can fit the clusterIndices within 8-bits // yay! we can fit the clusterIndices within 8-bits
int32_t numIndices = fbxMesh.clusterIndices.size(); int32_t numIndices = hfmMesh.clusterIndices.size();
QVector<uint8_t> clusterIndices; QVector<uint8_t> clusterIndices;
clusterIndices.resize(numIndices); clusterIndices.resize(numIndices);
for (int32_t i = 0; i < numIndices; ++i) { for (int32_t i = 0; i < numIndices; ++i) {
assert(fbxMesh.clusterIndices[i] <= UINT8_MAX); assert(hfmMesh.clusterIndices[i] <= UINT8_MAX);
clusterIndices[i] = (uint8_t)(fbxMesh.clusterIndices[i]); clusterIndices[i] = (uint8_t)(hfmMesh.clusterIndices[i]);
} }
vertBuffer->setSubData(clusterIndicesOffset, clusterIndicesSize, (const gpu::Byte*) clusterIndices.constData()); vertBuffer->setSubData(clusterIndicesOffset, clusterIndicesSize, (const gpu::Byte*) clusterIndices.constData());
} else { } else {
vertBuffer->setSubData(clusterIndicesOffset, clusterIndicesSize, (const gpu::Byte*) fbxMesh.clusterIndices.constData()); vertBuffer->setSubData(clusterIndicesOffset, clusterIndicesSize, (const gpu::Byte*) hfmMesh.clusterIndices.constData());
} }
} }
if (clusterWeightsSize > 0) { if (clusterWeightsSize > 0) {
vertBuffer->setSubData(clusterWeightsOffset, clusterWeightsSize, (const gpu::Byte*) fbxMesh.clusterWeights.constData()); vertBuffer->setSubData(clusterWeightsOffset, clusterWeightsSize, (const gpu::Byte*) hfmMesh.clusterWeights.constData());
} }
@ -856,7 +856,7 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
// Index and Part Buffers // Index and Part Buffers
unsigned int totalIndices = 0; unsigned int totalIndices = 0;
foreach(const FBXMeshPart& part, extractedMesh.parts) { foreach(const HFMMeshPart& part, extractedMesh.parts) {
totalIndices += (part.quadTrianglesIndices.size() + part.triangleIndices.size()); totalIndices += (part.quadTrianglesIndices.size() + part.triangleIndices.size());
} }
@ -875,7 +875,7 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
if (extractedMesh.parts.size() > 1) { if (extractedMesh.parts.size() > 1) {
indexNum = 0; indexNum = 0;
} }
foreach(const FBXMeshPart& part, extractedMesh.parts) { foreach(const HFMMeshPart& part, extractedMesh.parts) {
graphics::Mesh::Part modelPart(indexNum, 0, 0, graphics::Mesh::TRIANGLES); graphics::Mesh::Part modelPart(indexNum, 0, 0, graphics::Mesh::TRIANGLES);
if (part.quadTrianglesIndices.size()) { if (part.quadTrianglesIndices.size()) {

View file

@ -697,7 +697,7 @@ glm::mat4 GLTFReader::getModelTransform(const GLTFNode& node) {
return tmat; return tmat;
} }
bool GLTFReader::buildGeometry(FBXGeometry& geometry, const QUrl& url) { bool GLTFReader::buildGeometry(HFMGeometry& geometry, const QUrl& url) {
//Build dependencies //Build dependencies
QVector<QVector<int>> nodeDependencies(_file.nodes.size()); QVector<QVector<int>> nodeDependencies(_file.nodes.size());
@ -750,10 +750,10 @@ bool GLTFReader::buildGeometry(FBXGeometry& geometry, const QUrl& url) {
for (int i = 0; i < materialIDs.size(); i++) { for (int i = 0; i < materialIDs.size(); i++) {
QString& matid = materialIDs[i]; QString& matid = materialIDs[i];
geometry.materials[matid] = FBXMaterial(); geometry.materials[matid] = HFMMaterial();
FBXMaterial& fbxMaterial = geometry.materials[matid]; HFMMaterial& hfmMaterial = geometry.materials[matid];
fbxMaterial._material = std::make_shared<graphics::Material>(); hfmMaterial._material = std::make_shared<graphics::Material>();
setFBXMaterial(fbxMaterial, _file.materials[i]); setHFMMaterial(hfmMaterial, _file.materials[i]);
} }
@ -765,9 +765,9 @@ bool GLTFReader::buildGeometry(FBXGeometry& geometry, const QUrl& url) {
if (node.defined["mesh"]) { if (node.defined["mesh"]) {
qCDebug(modelformat) << "node_transforms" << node.transforms; qCDebug(modelformat) << "node_transforms" << node.transforms;
foreach(auto &primitive, _file.meshes[node.mesh].primitives) { foreach(auto &primitive, _file.meshes[node.mesh].primitives) {
geometry.meshes.append(FBXMesh()); geometry.meshes.append(HFMMesh());
FBXMesh& mesh = geometry.meshes[geometry.meshes.size() - 1]; HFMMesh& mesh = geometry.meshes[geometry.meshes.size() - 1];
FBXCluster cluster; HFMCluster cluster;
cluster.jointIndex = 0; cluster.jointIndex = 0;
cluster.inverseBindMatrix = glm::mat4(1, 0, 0, 0, cluster.inverseBindMatrix = glm::mat4(1, 0, 0, 0,
0, 1, 0, 0, 0, 1, 0, 0,
@ -775,7 +775,7 @@ bool GLTFReader::buildGeometry(FBXGeometry& geometry, const QUrl& url) {
0, 0, 0, 1); 0, 0, 0, 1);
mesh.clusters.append(cluster); mesh.clusters.append(cluster);
FBXMeshPart part = FBXMeshPart(); HFMMeshPart part = HFMMeshPart();
int indicesAccessorIdx = primitive.indices; int indicesAccessorIdx = primitive.indices;
@ -910,7 +910,7 @@ bool GLTFReader::buildGeometry(FBXGeometry& geometry, const QUrl& url) {
return true; return true;
} }
FBXGeometry* GLTFReader::readGLTF(QByteArray& model, const QVariantHash& mapping, HFMGeometry* GLTFReader::readGLTF(QByteArray& model, const QVariantHash& mapping,
const QUrl& url, bool loadLightmaps, float lightmapLevel) { const QUrl& url, bool loadLightmaps, float lightmapLevel) {
_url = url; _url = url;
@ -924,12 +924,12 @@ FBXGeometry* GLTFReader::readGLTF(QByteArray& model, const QVariantHash& mapping
parseGLTF(model); parseGLTF(model);
//_file.dump(); //_file.dump();
FBXGeometry* geometryPtr = new FBXGeometry(); HFMGeometry* geometryPtr = new HFMGeometry();
FBXGeometry& geometry = *geometryPtr; HFMGeometry& geometry = *geometryPtr;
buildGeometry(geometry, url); buildGeometry(geometry, url);
//fbxDebugDump(geometry); //hfmDebugDump(geometry);
return geometryPtr; return geometryPtr;
} }
@ -997,8 +997,8 @@ QNetworkReply* GLTFReader::request(QUrl& url, bool isTest) {
return netReply; // trying to sync later on. return netReply; // trying to sync later on.
} }
FBXTexture GLTFReader::getFBXTexture(const GLTFTexture& texture) { HFMTexture GLTFReader::getHFMTexture(const GLTFTexture& texture) {
FBXTexture fbxtex = FBXTexture(); HFMTexture fbxtex = HFMTexture();
fbxtex.texcoordSet = 0; fbxtex.texcoordSet = 0;
if (texture.defined["source"]) { if (texture.defined["source"]) {
@ -1014,7 +1014,7 @@ FBXTexture GLTFReader::getFBXTexture(const GLTFTexture& texture) {
return fbxtex; return fbxtex;
} }
void GLTFReader::setFBXMaterial(FBXMaterial& fbxmat, const GLTFMaterial& material) { void GLTFReader::setHFMMaterial(HFMMaterial& fbxmat, const GLTFMaterial& material) {
if (material.defined["name"]) { if (material.defined["name"]) {
@ -1029,17 +1029,17 @@ void GLTFReader::setFBXMaterial(FBXMaterial& fbxmat, const GLTFMaterial& materia
} }
if (material.defined["emissiveTexture"]) { if (material.defined["emissiveTexture"]) {
fbxmat.emissiveTexture = getFBXTexture(_file.textures[material.emissiveTexture]); fbxmat.emissiveTexture = getHFMTexture(_file.textures[material.emissiveTexture]);
fbxmat.useEmissiveMap = true; fbxmat.useEmissiveMap = true;
} }
if (material.defined["normalTexture"]) { if (material.defined["normalTexture"]) {
fbxmat.normalTexture = getFBXTexture(_file.textures[material.normalTexture]); fbxmat.normalTexture = getHFMTexture(_file.textures[material.normalTexture]);
fbxmat.useNormalMap = true; fbxmat.useNormalMap = true;
} }
if (material.defined["occlusionTexture"]) { if (material.defined["occlusionTexture"]) {
fbxmat.occlusionTexture = getFBXTexture(_file.textures[material.occlusionTexture]); fbxmat.occlusionTexture = getHFMTexture(_file.textures[material.occlusionTexture]);
fbxmat.useOcclusionMap = true; fbxmat.useOcclusionMap = true;
} }
@ -1050,14 +1050,14 @@ void GLTFReader::setFBXMaterial(FBXMaterial& fbxmat, const GLTFMaterial& materia
fbxmat.metallic = material.pbrMetallicRoughness.metallicFactor; fbxmat.metallic = material.pbrMetallicRoughness.metallicFactor;
} }
if (material.pbrMetallicRoughness.defined["baseColorTexture"]) { if (material.pbrMetallicRoughness.defined["baseColorTexture"]) {
fbxmat.opacityTexture = getFBXTexture(_file.textures[material.pbrMetallicRoughness.baseColorTexture]); fbxmat.opacityTexture = getHFMTexture(_file.textures[material.pbrMetallicRoughness.baseColorTexture]);
fbxmat.albedoTexture = getFBXTexture(_file.textures[material.pbrMetallicRoughness.baseColorTexture]); fbxmat.albedoTexture = getHFMTexture(_file.textures[material.pbrMetallicRoughness.baseColorTexture]);
fbxmat.useAlbedoMap = true; fbxmat.useAlbedoMap = true;
} }
if (material.pbrMetallicRoughness.defined["metallicRoughnessTexture"]) { if (material.pbrMetallicRoughness.defined["metallicRoughnessTexture"]) {
fbxmat.roughnessTexture = getFBXTexture(_file.textures[material.pbrMetallicRoughness.metallicRoughnessTexture]); fbxmat.roughnessTexture = getHFMTexture(_file.textures[material.pbrMetallicRoughness.metallicRoughnessTexture]);
fbxmat.useRoughnessMap = true; fbxmat.useRoughnessMap = true;
fbxmat.metallicTexture = getFBXTexture(_file.textures[material.pbrMetallicRoughness.metallicRoughnessTexture]); fbxmat.metallicTexture = getHFMTexture(_file.textures[material.pbrMetallicRoughness.metallicRoughnessTexture]);
fbxmat.useMetallicMap = true; fbxmat.useMetallicMap = true;
} }
if (material.pbrMetallicRoughness.defined["roughnessFactor"]) { if (material.pbrMetallicRoughness.defined["roughnessFactor"]) {
@ -1181,37 +1181,37 @@ void GLTFReader::retriangulate(const QVector<int>& inIndices, const QVector<glm:
} }
} }
void GLTFReader::fbxDebugDump(const FBXGeometry& fbxgeo) { void GLTFReader::hfmDebugDump(const HFMGeometry& hfmgeo) {
qCDebug(modelformat) << "---------------- fbxGeometry ----------------"; qCDebug(modelformat) << "---------------- hfmGeometry ----------------";
qCDebug(modelformat) << " hasSkeletonJoints =" << fbxgeo.hasSkeletonJoints; qCDebug(modelformat) << " hasSkeletonJoints =" << hfmgeo.hasSkeletonJoints;
qCDebug(modelformat) << " offset =" << fbxgeo.offset; qCDebug(modelformat) << " offset =" << hfmgeo.offset;
qCDebug(modelformat) << " leftEyeJointIndex =" << fbxgeo.leftEyeJointIndex; qCDebug(modelformat) << " leftEyeJointIndex =" << hfmgeo.leftEyeJointIndex;
qCDebug(modelformat) << " rightEyeJointIndex =" << fbxgeo.rightEyeJointIndex; qCDebug(modelformat) << " rightEyeJointIndex =" << hfmgeo.rightEyeJointIndex;
qCDebug(modelformat) << " neckJointIndex =" << fbxgeo.neckJointIndex; qCDebug(modelformat) << " neckJointIndex =" << hfmgeo.neckJointIndex;
qCDebug(modelformat) << " rootJointIndex =" << fbxgeo.rootJointIndex; qCDebug(modelformat) << " rootJointIndex =" << hfmgeo.rootJointIndex;
qCDebug(modelformat) << " leanJointIndex =" << fbxgeo.leanJointIndex; qCDebug(modelformat) << " leanJointIndex =" << hfmgeo.leanJointIndex;
qCDebug(modelformat) << " headJointIndex =" << fbxgeo.headJointIndex; qCDebug(modelformat) << " headJointIndex =" << hfmgeo.headJointIndex;
qCDebug(modelformat) << " leftHandJointIndex" << fbxgeo.leftHandJointIndex; qCDebug(modelformat) << " leftHandJointIndex" << hfmgeo.leftHandJointIndex;
qCDebug(modelformat) << " rightHandJointIndex" << fbxgeo.rightHandJointIndex; qCDebug(modelformat) << " rightHandJointIndex" << hfmgeo.rightHandJointIndex;
qCDebug(modelformat) << " leftToeJointIndex" << fbxgeo.leftToeJointIndex; qCDebug(modelformat) << " leftToeJointIndex" << hfmgeo.leftToeJointIndex;
qCDebug(modelformat) << " rightToeJointIndex" << fbxgeo.rightToeJointIndex; qCDebug(modelformat) << " rightToeJointIndex" << hfmgeo.rightToeJointIndex;
qCDebug(modelformat) << " leftEyeSize = " << fbxgeo.leftEyeSize; qCDebug(modelformat) << " leftEyeSize = " << hfmgeo.leftEyeSize;
qCDebug(modelformat) << " rightEyeSize = " << fbxgeo.rightEyeSize; qCDebug(modelformat) << " rightEyeSize = " << hfmgeo.rightEyeSize;
qCDebug(modelformat) << " palmDirection = " << fbxgeo.palmDirection; qCDebug(modelformat) << " palmDirection = " << hfmgeo.palmDirection;
qCDebug(modelformat) << " neckPivot = " << fbxgeo.neckPivot; qCDebug(modelformat) << " neckPivot = " << hfmgeo.neckPivot;
qCDebug(modelformat) << " bindExtents.size() = " << fbxgeo.bindExtents.size(); qCDebug(modelformat) << " bindExtents.size() = " << hfmgeo.bindExtents.size();
qCDebug(modelformat) << " meshExtents.size() = " << fbxgeo.meshExtents.size(); qCDebug(modelformat) << " meshExtents.size() = " << hfmgeo.meshExtents.size();
qCDebug(modelformat) << " jointIndices.size() =" << fbxgeo.jointIndices.size(); qCDebug(modelformat) << " jointIndices.size() =" << hfmgeo.jointIndices.size();
qCDebug(modelformat) << " joints.count() =" << fbxgeo.joints.count(); qCDebug(modelformat) << " joints.count() =" << hfmgeo.joints.count();
qCDebug(modelformat) << "---------------- Meshes ----------------"; qCDebug(modelformat) << "---------------- Meshes ----------------";
qCDebug(modelformat) << " meshes.count() =" << fbxgeo.meshes.count(); qCDebug(modelformat) << " meshes.count() =" << hfmgeo.meshes.count();
qCDebug(modelformat) << " blendshapeChannelNames = " << fbxgeo.blendshapeChannelNames; qCDebug(modelformat) << " blendshapeChannelNames = " << hfmgeo.blendshapeChannelNames;
foreach(FBXMesh mesh, fbxgeo.meshes) { foreach(HFMMesh mesh, hfmgeo.meshes) {
qCDebug(modelformat) << "\n"; qCDebug(modelformat) << "\n";
qCDebug(modelformat) << " meshpointer =" << mesh._mesh.get(); qCDebug(modelformat) << " meshpointer =" << mesh._mesh.get();
qCDebug(modelformat) << " meshindex =" << mesh.meshIndex; qCDebug(modelformat) << " meshindex =" << mesh.meshIndex;
@ -1227,7 +1227,7 @@ void GLTFReader::fbxDebugDump(const FBXGeometry& fbxgeo) {
qCDebug(modelformat) << " modelTransform =" << mesh.modelTransform; qCDebug(modelformat) << " modelTransform =" << mesh.modelTransform;
qCDebug(modelformat) << " parts.count() =" << mesh.parts.count(); qCDebug(modelformat) << " parts.count() =" << mesh.parts.count();
qCDebug(modelformat) << "---------------- Meshes (blendshapes)--------"; qCDebug(modelformat) << "---------------- Meshes (blendshapes)--------";
foreach(FBXBlendshape bshape, mesh.blendshapes) { foreach(HFMBlendshape bshape, mesh.blendshapes) {
qCDebug(modelformat) << "\n"; qCDebug(modelformat) << "\n";
qCDebug(modelformat) << " bshape.indices.count() =" << bshape.indices.count(); qCDebug(modelformat) << " bshape.indices.count() =" << bshape.indices.count();
qCDebug(modelformat) << " bshape.vertices.count() =" << bshape.vertices.count(); qCDebug(modelformat) << " bshape.vertices.count() =" << bshape.vertices.count();
@ -1235,7 +1235,7 @@ void GLTFReader::fbxDebugDump(const FBXGeometry& fbxgeo) {
qCDebug(modelformat) << "\n"; qCDebug(modelformat) << "\n";
} }
qCDebug(modelformat) << "---------------- Meshes (meshparts)--------"; qCDebug(modelformat) << "---------------- Meshes (meshparts)--------";
foreach(FBXMeshPart meshPart, mesh.parts) { foreach(HFMMeshPart meshPart, mesh.parts) {
qCDebug(modelformat) << "\n"; qCDebug(modelformat) << "\n";
qCDebug(modelformat) << " quadIndices.count() =" << meshPart.quadIndices.count(); qCDebug(modelformat) << " quadIndices.count() =" << meshPart.quadIndices.count();
qCDebug(modelformat) << " triangleIndices.count() =" << meshPart.triangleIndices.count(); qCDebug(modelformat) << " triangleIndices.count() =" << meshPart.triangleIndices.count();
@ -1245,7 +1245,7 @@ void GLTFReader::fbxDebugDump(const FBXGeometry& fbxgeo) {
} }
qCDebug(modelformat) << "---------------- Meshes (clusters)--------"; qCDebug(modelformat) << "---------------- Meshes (clusters)--------";
qCDebug(modelformat) << " clusters.count() =" << mesh.clusters.count(); qCDebug(modelformat) << " clusters.count() =" << mesh.clusters.count();
foreach(FBXCluster cluster, mesh.clusters) { foreach(HFMCluster cluster, mesh.clusters) {
qCDebug(modelformat) << "\n"; qCDebug(modelformat) << "\n";
qCDebug(modelformat) << " jointIndex =" << cluster.jointIndex; qCDebug(modelformat) << " jointIndex =" << cluster.jointIndex;
qCDebug(modelformat) << " inverseBindMatrix =" << cluster.inverseBindMatrix; qCDebug(modelformat) << " inverseBindMatrix =" << cluster.inverseBindMatrix;
@ -1254,18 +1254,18 @@ void GLTFReader::fbxDebugDump(const FBXGeometry& fbxgeo) {
qCDebug(modelformat) << "\n"; qCDebug(modelformat) << "\n";
} }
qCDebug(modelformat) << "---------------- AnimationFrames ----------------"; qCDebug(modelformat) << "---------------- AnimationFrames ----------------";
foreach(FBXAnimationFrame anim, fbxgeo.animationFrames) { foreach(HFMAnimationFrame anim, hfmgeo.animationFrames) {
qCDebug(modelformat) << " anim.translations = " << anim.translations; qCDebug(modelformat) << " anim.translations = " << anim.translations;
qCDebug(modelformat) << " anim.rotations = " << anim.rotations; qCDebug(modelformat) << " anim.rotations = " << anim.rotations;
} }
QList<int> mitomona_keys = fbxgeo.meshIndicesToModelNames.keys(); QList<int> mitomona_keys = hfmgeo.meshIndicesToModelNames.keys();
foreach(int key, mitomona_keys) { foreach(int key, mitomona_keys) {
qCDebug(modelformat) << " meshIndicesToModelNames key =" << key << " val =" << fbxgeo.meshIndicesToModelNames[key]; qCDebug(modelformat) << " meshIndicesToModelNames key =" << key << " val =" << hfmgeo.meshIndicesToModelNames[key];
} }
qCDebug(modelformat) << "---------------- Materials ----------------"; qCDebug(modelformat) << "---------------- Materials ----------------";
foreach(FBXMaterial mat, fbxgeo.materials) { foreach(HFMMaterial mat, hfmgeo.materials) {
qCDebug(modelformat) << "\n"; qCDebug(modelformat) << "\n";
qCDebug(modelformat) << " mat.materialID =" << mat.materialID; qCDebug(modelformat) << " mat.materialID =" << mat.materialID;
qCDebug(modelformat) << " diffuseColor =" << mat.diffuseColor; qCDebug(modelformat) << " diffuseColor =" << mat.diffuseColor;
@ -1314,7 +1314,7 @@ void GLTFReader::fbxDebugDump(const FBXGeometry& fbxgeo) {
qCDebug(modelformat) << "---------------- Joints ----------------"; qCDebug(modelformat) << "---------------- Joints ----------------";
foreach(FBXJoint joint, fbxgeo.joints) { foreach(HFMJoint joint, hfmgeo.joints) {
qCDebug(modelformat) << "\n"; qCDebug(modelformat) << "\n";
qCDebug(modelformat) << " shapeInfo.avgPoint =" << joint.shapeInfo.avgPoint; qCDebug(modelformat) << " shapeInfo.avgPoint =" << joint.shapeInfo.avgPoint;
qCDebug(modelformat) << " shapeInfo.debugLines =" << joint.shapeInfo.debugLines; qCDebug(modelformat) << " shapeInfo.debugLines =" << joint.shapeInfo.debugLines;

View file

@ -706,7 +706,7 @@ class GLTFReader : public QObject {
Q_OBJECT Q_OBJECT
public: public:
GLTFReader(); GLTFReader();
FBXGeometry* readGLTF(QByteArray& model, const QVariantHash& mapping, HFMGeometry* readGLTF(QByteArray& model, const QVariantHash& mapping,
const QUrl& url, bool loadLightmaps = true, float lightmapLevel = 1.0f); const QUrl& url, bool loadLightmaps = true, float lightmapLevel = 1.0f);
private: private:
GLTFFile _file; GLTFFile _file;
@ -714,7 +714,7 @@ private:
glm::mat4 getModelTransform(const GLTFNode& node); glm::mat4 getModelTransform(const GLTFNode& node);
bool buildGeometry(FBXGeometry& geometry, const QUrl& url); bool buildGeometry(HFMGeometry& geometry, const QUrl& url);
bool parseGLTF(const QByteArray& model); bool parseGLTF(const QByteArray& model);
bool getStringVal(const QJsonObject& object, const QString& fieldname, bool getStringVal(const QJsonObject& object, const QString& fieldname,
@ -778,9 +778,9 @@ private:
bool doesResourceExist(const QString& url); bool doesResourceExist(const QString& url);
void setFBXMaterial(FBXMaterial& fbxmat, const GLTFMaterial& material); void setHFMMaterial(HFMMaterial& fbxmat, const GLTFMaterial& material);
FBXTexture getFBXTexture(const GLTFTexture& texture); HFMTexture getHFMTexture(const GLTFTexture& texture);
void fbxDebugDump(const FBXGeometry& fbxgeo); void hfmDebugDump(const HFMGeometry& hfmgeo);
}; };
#endif // hifi_GLTFReader_h #endif // hifi_GLTFReader_h

View file

@ -175,7 +175,7 @@ glm::vec2 OBJTokenizer::getVec2() {
} }
void setMeshPartDefaults(FBXMeshPart& meshPart, QString materialID) { void setMeshPartDefaults(HFMMeshPart& meshPart, QString materialID) {
meshPart.materialID = materialID; meshPart.materialID = materialID;
} }
@ -488,12 +488,12 @@ QNetworkReply* request(QUrl& url, bool isTest) {
} }
bool OBJReader::parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& mapping, FBXGeometry& geometry, bool OBJReader::parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& mapping, HFMGeometry& geometry,
float& scaleGuess, bool combineParts) { float& scaleGuess, bool combineParts) {
FaceGroup faces; FaceGroup faces;
FBXMesh& mesh = geometry.meshes[0]; HFMMesh& mesh = geometry.meshes[0];
mesh.parts.append(FBXMeshPart()); mesh.parts.append(HFMMeshPart());
FBXMeshPart& meshPart = mesh.parts.last(); HFMMeshPart& meshPart = mesh.parts.last();
bool sawG = false; bool sawG = false;
bool result = true; bool result = true;
int originalFaceCountForDebugging = 0; int originalFaceCountForDebugging = 0;
@ -652,13 +652,13 @@ done:
} }
FBXGeometry::Pointer OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping, bool combineParts, const QUrl& url) { HFMGeometry::Pointer OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping, bool combineParts, const QUrl& url) {
PROFILE_RANGE_EX(resource_parse, __FUNCTION__, 0xffff0000, nullptr); PROFILE_RANGE_EX(resource_parse, __FUNCTION__, 0xffff0000, nullptr);
QBuffer buffer { &model }; QBuffer buffer { &model };
buffer.open(QIODevice::ReadOnly); buffer.open(QIODevice::ReadOnly);
auto geometryPtr { std::make_shared<FBXGeometry>() }; auto geometryPtr { std::make_shared<HFMGeometry>() };
FBXGeometry& geometry { *geometryPtr }; HFMGeometry& geometry { *geometryPtr };
OBJTokenizer tokenizer { &buffer }; OBJTokenizer tokenizer { &buffer };
float scaleGuess = 1.0f; float scaleGuess = 1.0f;
@ -666,14 +666,14 @@ FBXGeometry::Pointer OBJReader::readOBJ(QByteArray& model, const QVariantHash& m
_url = url; _url = url;
geometry.meshExtents.reset(); geometry.meshExtents.reset();
geometry.meshes.append(FBXMesh()); geometry.meshes.append(HFMMesh());
try { try {
// call parseOBJGroup as long as it's returning true. Each successful call will // call parseOBJGroup as long as it's returning true. Each successful call will
// add a new meshPart to the geometry's single mesh. // add a new meshPart to the geometry's single mesh.
while (parseOBJGroup(tokenizer, mapping, geometry, scaleGuess, combineParts)) {} while (parseOBJGroup(tokenizer, mapping, geometry, scaleGuess, combineParts)) {}
FBXMesh& mesh = geometry.meshes[0]; HFMMesh& mesh = geometry.meshes[0];
mesh.meshIndex = 0; mesh.meshIndex = 0;
geometry.joints.resize(1); geometry.joints.resize(1);
@ -688,7 +688,7 @@ FBXGeometry::Pointer OBJReader::readOBJ(QByteArray& model, const QVariantHash& m
geometry.jointIndices["x"] = 1; geometry.jointIndices["x"] = 1;
FBXCluster cluster; HFMCluster cluster;
cluster.jointIndex = 0; cluster.jointIndex = 0;
cluster.inverseBindMatrix = glm::mat4(1, 0, 0, 0, cluster.inverseBindMatrix = glm::mat4(1, 0, 0, 0,
0, 1, 0, 0, 0, 1, 0, 0,
@ -697,20 +697,20 @@ FBXGeometry::Pointer OBJReader::readOBJ(QByteArray& model, const QVariantHash& m
mesh.clusters.append(cluster); mesh.clusters.append(cluster);
QMap<QString, int> materialMeshIdMap; QMap<QString, int> materialMeshIdMap;
QVector<FBXMeshPart> fbxMeshParts; QVector<HFMMeshPart> hfmMeshParts;
for (int i = 0, meshPartCount = 0; i < mesh.parts.count(); i++, meshPartCount++) { for (int i = 0, meshPartCount = 0; i < mesh.parts.count(); i++, meshPartCount++) {
FBXMeshPart& meshPart = mesh.parts[i]; HFMMeshPart& meshPart = mesh.parts[i];
FaceGroup faceGroup = faceGroups[meshPartCount]; FaceGroup faceGroup = faceGroups[meshPartCount];
bool specifiesUV = false; bool specifiesUV = false;
foreach(OBJFace face, faceGroup) { foreach(OBJFace face, faceGroup) {
// Go through all of the OBJ faces and determine the number of different materials necessary (each different material will be a unique mesh). // Go through all of the OBJ faces and determine the number of different materials necessary (each different material will be a unique mesh).
// NOTE (trent/mittens 3/30/17): this seems hardcore wasteful and is slowed down a bit by iterating through the face group twice, but it's the best way I've thought of to hack multi-material support in an OBJ into this pipeline. // NOTE (trent/mittens 3/30/17): this seems hardcore wasteful and is slowed down a bit by iterating through the face group twice, but it's the best way I've thought of to hack multi-material support in an OBJ into this pipeline.
if (!materialMeshIdMap.contains(face.materialName)) { if (!materialMeshIdMap.contains(face.materialName)) {
// Create a new FBXMesh for this material mapping. // Create a new HFMMesh for this material mapping.
materialMeshIdMap.insert(face.materialName, materialMeshIdMap.count()); materialMeshIdMap.insert(face.materialName, materialMeshIdMap.count());
fbxMeshParts.append(FBXMeshPart()); hfmMeshParts.append(HFMMeshPart());
FBXMeshPart& meshPartNew = fbxMeshParts.last(); HFMMeshPart& meshPartNew = hfmMeshParts.last();
meshPartNew.quadIndices = QVector<int>(meshPart.quadIndices); // Copy over quad indices [NOTE (trent/mittens, 4/3/17): Likely unnecessary since they go unused anyway]. meshPartNew.quadIndices = QVector<int>(meshPart.quadIndices); // Copy over quad indices [NOTE (trent/mittens, 4/3/17): Likely unnecessary since they go unused anyway].
meshPartNew.quadTrianglesIndices = QVector<int>(meshPart.quadTrianglesIndices); // Copy over quad triangulated indices [NOTE (trent/mittens, 4/3/17): Likely unnecessary since they go unused anyway]. meshPartNew.quadTrianglesIndices = QVector<int>(meshPart.quadTrianglesIndices); // Copy over quad triangulated indices [NOTE (trent/mittens, 4/3/17): Likely unnecessary since they go unused anyway].
meshPartNew.triangleIndices = QVector<int>(meshPart.triangleIndices); // Copy over triangle indices. meshPartNew.triangleIndices = QVector<int>(meshPart.triangleIndices); // Copy over triangle indices.
@ -745,14 +745,14 @@ FBXGeometry::Pointer OBJReader::readOBJ(QByteArray& model, const QVariantHash& m
// clean up old mesh parts. // clean up old mesh parts.
int unmodifiedMeshPartCount = mesh.parts.count(); int unmodifiedMeshPartCount = mesh.parts.count();
mesh.parts.clear(); mesh.parts.clear();
mesh.parts = QVector<FBXMeshPart>(fbxMeshParts); mesh.parts = QVector<HFMMeshPart>(hfmMeshParts);
for (int i = 0, meshPartCount = 0; i < unmodifiedMeshPartCount; i++, meshPartCount++) { for (int i = 0, meshPartCount = 0; i < unmodifiedMeshPartCount; i++, meshPartCount++) {
FaceGroup faceGroup = faceGroups[meshPartCount]; FaceGroup faceGroup = faceGroups[meshPartCount];
// Now that each mesh has been created with its own unique material mappings, fill them with data (vertex data is duplicated, face data is not). // Now that each mesh has been created with its own unique material mappings, fill them with data (vertex data is duplicated, face data is not).
foreach(OBJFace face, faceGroup) { foreach(OBJFace face, faceGroup) {
FBXMeshPart& meshPart = mesh.parts[materialMeshIdMap[face.materialName]]; HFMMeshPart& meshPart = mesh.parts[materialMeshIdMap[face.materialName]];
glm::vec3 v0 = checked_at(vertices, face.vertexIndices[0]); glm::vec3 v0 = checked_at(vertices, face.vertexIndices[0]);
glm::vec3 v1 = checked_at(vertices, face.vertexIndices[1]); glm::vec3 v1 = checked_at(vertices, face.vertexIndices[1]);
@ -824,7 +824,7 @@ FBXGeometry::Pointer OBJReader::readOBJ(QByteArray& model, const QVariantHash& m
// Build the single mesh. // Build the single mesh.
FBXReader::buildModelMesh(mesh, url.toString()); FBXReader::buildModelMesh(mesh, url.toString());
// fbxDebugDump(geometry); // hfmDebugDump(geometry);
} catch(const std::exception& e) { } catch(const std::exception& e) {
qCDebug(modelformat) << "OBJ reader fail: " << e.what(); qCDebug(modelformat) << "OBJ reader fail: " << e.what();
} }
@ -885,38 +885,38 @@ FBXGeometry::Pointer OBJReader::readOBJ(QByteArray& model, const QVariantHash& m
if (!objMaterial.used) { if (!objMaterial.used) {
continue; continue;
} }
geometry.materials[materialID] = FBXMaterial(objMaterial.diffuseColor, geometry.materials[materialID] = HFMMaterial(objMaterial.diffuseColor,
objMaterial.specularColor, objMaterial.specularColor,
objMaterial.emissiveColor, objMaterial.emissiveColor,
objMaterial.shininess, objMaterial.shininess,
objMaterial.opacity); objMaterial.opacity);
FBXMaterial& fbxMaterial = geometry.materials[materialID]; HFMMaterial& hfmMaterial = geometry.materials[materialID];
fbxMaterial.materialID = materialID; hfmMaterial.materialID = materialID;
fbxMaterial._material = std::make_shared<graphics::Material>(); hfmMaterial._material = std::make_shared<graphics::Material>();
graphics::MaterialPointer modelMaterial = fbxMaterial._material; graphics::MaterialPointer modelMaterial = hfmMaterial._material;
if (!objMaterial.diffuseTextureFilename.isEmpty()) { if (!objMaterial.diffuseTextureFilename.isEmpty()) {
fbxMaterial.albedoTexture.filename = objMaterial.diffuseTextureFilename; hfmMaterial.albedoTexture.filename = objMaterial.diffuseTextureFilename;
} }
if (!objMaterial.specularTextureFilename.isEmpty()) { if (!objMaterial.specularTextureFilename.isEmpty()) {
fbxMaterial.specularTexture.filename = objMaterial.specularTextureFilename; hfmMaterial.specularTexture.filename = objMaterial.specularTextureFilename;
} }
if (!objMaterial.emissiveTextureFilename.isEmpty()) { if (!objMaterial.emissiveTextureFilename.isEmpty()) {
fbxMaterial.emissiveTexture.filename = objMaterial.emissiveTextureFilename; hfmMaterial.emissiveTexture.filename = objMaterial.emissiveTextureFilename;
} }
if (!objMaterial.bumpTextureFilename.isEmpty()) { if (!objMaterial.bumpTextureFilename.isEmpty()) {
fbxMaterial.normalTexture.filename = objMaterial.bumpTextureFilename; hfmMaterial.normalTexture.filename = objMaterial.bumpTextureFilename;
fbxMaterial.normalTexture.isBumpmap = true; hfmMaterial.normalTexture.isBumpmap = true;
fbxMaterial.bumpMultiplier = objMaterial.bumpTextureOptions.bumpMultiplier; hfmMaterial.bumpMultiplier = objMaterial.bumpTextureOptions.bumpMultiplier;
} }
if (!objMaterial.opacityTextureFilename.isEmpty()) { if (!objMaterial.opacityTextureFilename.isEmpty()) {
fbxMaterial.opacityTexture.filename = objMaterial.opacityTextureFilename; hfmMaterial.opacityTexture.filename = objMaterial.opacityTextureFilename;
} }
modelMaterial->setEmissive(fbxMaterial.emissiveColor); modelMaterial->setEmissive(hfmMaterial.emissiveColor);
modelMaterial->setAlbedo(fbxMaterial.diffuseColor); modelMaterial->setAlbedo(hfmMaterial.diffuseColor);
modelMaterial->setMetallic(glm::length(fbxMaterial.specularColor)); modelMaterial->setMetallic(glm::length(hfmMaterial.specularColor));
modelMaterial->setRoughness(graphics::Material::shininessToRoughness(fbxMaterial.shininess)); modelMaterial->setRoughness(graphics::Material::shininessToRoughness(hfmMaterial.shininess));
bool applyTransparency = false; bool applyTransparency = false;
bool applyShininess = false; bool applyShininess = false;
@ -971,7 +971,7 @@ FBXGeometry::Pointer OBJReader::readOBJ(QByteArray& model, const QVariantHash& m
} }
if (applyTransparency) { if (applyTransparency) {
fbxMaterial.opacity = std::max(fbxMaterial.opacity, ILLUMINATION_MODEL_MIN_OPACITY); hfmMaterial.opacity = std::max(hfmMaterial.opacity, ILLUMINATION_MODEL_MIN_OPACITY);
} }
if (applyShininess) { if (applyShininess) {
modelMaterial->setRoughness(ILLUMINATION_MODEL_APPLY_SHININESS); modelMaterial->setRoughness(ILLUMINATION_MODEL_APPLY_SHININESS);
@ -985,18 +985,18 @@ FBXGeometry::Pointer OBJReader::readOBJ(QByteArray& model, const QVariantHash& m
modelMaterial->setFresnel(glm::vec3(1.0f)); modelMaterial->setFresnel(glm::vec3(1.0f));
} }
modelMaterial->setOpacity(fbxMaterial.opacity); modelMaterial->setOpacity(hfmMaterial.opacity);
} }
return geometryPtr; return geometryPtr;
} }
void fbxDebugDump(const FBXGeometry& fbxgeo) { void hfmDebugDump(const HFMGeometry& hfmgeo) {
qCDebug(modelformat) << "---------------- fbxGeometry ----------------"; qCDebug(modelformat) << "---------------- hfmGeometry ----------------";
qCDebug(modelformat) << " hasSkeletonJoints =" << fbxgeo.hasSkeletonJoints; qCDebug(modelformat) << " hasSkeletonJoints =" << hfmgeo.hasSkeletonJoints;
qCDebug(modelformat) << " offset =" << fbxgeo.offset; qCDebug(modelformat) << " offset =" << hfmgeo.offset;
qCDebug(modelformat) << " meshes.count() =" << fbxgeo.meshes.count(); qCDebug(modelformat) << " meshes.count() =" << hfmgeo.meshes.count();
foreach (FBXMesh mesh, fbxgeo.meshes) { foreach (HFMMesh mesh, hfmgeo.meshes) {
qCDebug(modelformat) << " vertices.count() =" << mesh.vertices.count(); qCDebug(modelformat) << " vertices.count() =" << mesh.vertices.count();
qCDebug(modelformat) << " colors.count() =" << mesh.colors.count(); qCDebug(modelformat) << " colors.count() =" << mesh.colors.count();
qCDebug(modelformat) << " normals.count() =" << mesh.normals.count(); qCDebug(modelformat) << " normals.count() =" << mesh.normals.count();
@ -1014,7 +1014,7 @@ void fbxDebugDump(const FBXGeometry& fbxgeo) {
qCDebug(modelformat) << " meshExtents =" << mesh.meshExtents; qCDebug(modelformat) << " meshExtents =" << mesh.meshExtents;
qCDebug(modelformat) << " modelTransform =" << mesh.modelTransform; qCDebug(modelformat) << " modelTransform =" << mesh.modelTransform;
qCDebug(modelformat) << " parts.count() =" << mesh.parts.count(); qCDebug(modelformat) << " parts.count() =" << mesh.parts.count();
foreach (FBXMeshPart meshPart, mesh.parts) { foreach (HFMMeshPart meshPart, mesh.parts) {
qCDebug(modelformat) << " quadIndices.count() =" << meshPart.quadIndices.count(); qCDebug(modelformat) << " quadIndices.count() =" << meshPart.quadIndices.count();
qCDebug(modelformat) << " triangleIndices.count() =" << meshPart.triangleIndices.count(); qCDebug(modelformat) << " triangleIndices.count() =" << meshPart.triangleIndices.count();
/* /*
@ -1031,16 +1031,16 @@ void fbxDebugDump(const FBXGeometry& fbxgeo) {
*/ */
} }
qCDebug(modelformat) << " clusters.count() =" << mesh.clusters.count(); qCDebug(modelformat) << " clusters.count() =" << mesh.clusters.count();
foreach (FBXCluster cluster, mesh.clusters) { foreach (HFMCluster cluster, mesh.clusters) {
qCDebug(modelformat) << " jointIndex =" << cluster.jointIndex; qCDebug(modelformat) << " jointIndex =" << cluster.jointIndex;
qCDebug(modelformat) << " inverseBindMatrix =" << cluster.inverseBindMatrix; qCDebug(modelformat) << " inverseBindMatrix =" << cluster.inverseBindMatrix;
} }
} }
qCDebug(modelformat) << " jointIndices =" << fbxgeo.jointIndices; qCDebug(modelformat) << " jointIndices =" << hfmgeo.jointIndices;
qCDebug(modelformat) << " joints.count() =" << fbxgeo.joints.count(); qCDebug(modelformat) << " joints.count() =" << hfmgeo.joints.count();
foreach (FBXJoint joint, fbxgeo.joints) { foreach (HFMJoint joint, hfmgeo.joints) {
qCDebug(modelformat) << " isFree =" << joint.isFree; qCDebug(modelformat) << " isFree =" << joint.isFree;
qCDebug(modelformat) << " freeLineage" << joint.freeLineage; qCDebug(modelformat) << " freeLineage" << joint.freeLineage;
qCDebug(modelformat) << " parentIndex" << joint.parentIndex; qCDebug(modelformat) << " parentIndex" << joint.parentIndex;

View file

@ -42,7 +42,7 @@ public:
bool add(const QByteArray& vertexIndex, const QByteArray& textureIndex, const QByteArray& normalIndex, bool add(const QByteArray& vertexIndex, const QByteArray& textureIndex, const QByteArray& normalIndex,
const QVector<glm::vec3>& vertices, const QVector<glm::vec3>& vertexColors); const QVector<glm::vec3>& vertices, const QVector<glm::vec3>& vertexColors);
// Return a set of one or more OBJFaces from this one, in which each is just a triangle. // Return a set of one or more OBJFaces from this one, in which each is just a triangle.
// Even though FBXMeshPart can handle quads, it would be messy to try to keep track of mixed-size faces, so we treat everything as triangles. // Even though HFMMeshPart can handle quads, it would be messy to try to keep track of mixed-size faces, so we treat everything as triangles.
QVector<OBJFace> triangulate(); QVector<OBJFace> triangulate();
private: private:
void addFrom(const OBJFace* face, int index); void addFrom(const OBJFace* face, int index);
@ -54,7 +54,7 @@ public:
} }
; ;
// Materials and references to material names can come in any order, and different mesh parts can refer to the same material. // Materials and references to material names can come in any order, and different mesh parts can refer to the same material.
// Therefore it would get pretty hacky to try to use FBXMeshPart to store these as we traverse the files. // Therefore it would get pretty hacky to try to use HFMMeshPart to store these as we traverse the files.
class OBJMaterial { class OBJMaterial {
public: public:
float shininess; float shininess;
@ -87,13 +87,13 @@ public:
QString currentMaterialName; QString currentMaterialName;
QHash<QString, OBJMaterial> materials; QHash<QString, OBJMaterial> materials;
FBXGeometry::Pointer readOBJ(QByteArray& model, const QVariantHash& mapping, bool combineParts, const QUrl& url = QUrl()); HFMGeometry::Pointer readOBJ(QByteArray& model, const QVariantHash& mapping, bool combineParts, const QUrl& url = QUrl());
private: private:
QUrl _url; QUrl _url;
QHash<QByteArray, bool> librariesSeen; QHash<QByteArray, bool> librariesSeen;
bool parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& mapping, FBXGeometry& geometry, bool parseOBJGroup(OBJTokenizer& tokenizer, const QVariantHash& mapping, HFMGeometry& geometry,
float& scaleGuess, bool combineParts); float& scaleGuess, bool combineParts);
void parseMaterialLibrary(QIODevice* device); void parseMaterialLibrary(QIODevice* device);
void parseTextureLine(const QByteArray& textureLine, QByteArray& filename, OBJMaterialTextureOptions& textureOptions); void parseTextureLine(const QByteArray& textureLine, QByteArray& filename, OBJMaterialTextureOptions& textureOptions);
@ -103,5 +103,5 @@ private:
}; };
// What are these utilities doing here? One is used by fbx loading code in VHACD Utils, and the other a general debugging utility. // 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(FBXMeshPart& meshPart, QString materialID); void setMeshPartDefaults(HFMMeshPart& meshPart, QString materialID);
void fbxDebugDump(const FBXGeometry& fbxgeo); void hfmDebugDump(const HFMGeometry& hfmgeo);

View file

@ -128,7 +128,7 @@ void GeometryMappingResource::downloadFinished(const QByteArray& data) {
void GeometryMappingResource::onGeometryMappingLoaded(bool success) { void GeometryMappingResource::onGeometryMappingLoaded(bool success) {
if (success && _geometryResource) { if (success && _geometryResource) {
_fbxGeometry = _geometryResource->_fbxGeometry; _hfmGeometry = _geometryResource->_hfmGeometry;
_meshParts = _geometryResource->_meshParts; _meshParts = _geometryResource->_meshParts;
_meshes = _geometryResource->_meshes; _meshes = _geometryResource->_meshes;
_materials = _geometryResource->_materials; _materials = _geometryResource->_materials;
@ -193,38 +193,38 @@ void GeometryReader::run() {
_url.path().toLower().endsWith(".obj.gz") || _url.path().toLower().endsWith(".obj.gz") ||
_url.path().toLower().endsWith(".gltf"))) { _url.path().toLower().endsWith(".gltf"))) {
FBXGeometry::Pointer fbxGeometry; HFMGeometry::Pointer hfmGeometry;
if (_url.path().toLower().endsWith(".fbx")) { if (_url.path().toLower().endsWith(".fbx")) {
fbxGeometry.reset(readFBX(_data, _mapping, _url.path())); hfmGeometry.reset(readFBX(_data, _mapping, _url.path()));
if (fbxGeometry->meshes.size() == 0 && fbxGeometry->joints.size() == 0) { if (hfmGeometry->meshes.size() == 0 && hfmGeometry->joints.size() == 0) {
throw QString("empty geometry, possibly due to an unsupported FBX version"); throw QString("empty geometry, possibly due to an unsupported FBX version");
} }
} else if (_url.path().toLower().endsWith(".obj")) { } else if (_url.path().toLower().endsWith(".obj")) {
fbxGeometry = OBJReader().readOBJ(_data, _mapping, _combineParts, _url); hfmGeometry = OBJReader().readOBJ(_data, _mapping, _combineParts, _url);
} else if (_url.path().toLower().endsWith(".obj.gz")) { } else if (_url.path().toLower().endsWith(".obj.gz")) {
QByteArray uncompressedData; QByteArray uncompressedData;
if (gunzip(_data, uncompressedData)){ if (gunzip(_data, uncompressedData)){
fbxGeometry = OBJReader().readOBJ(uncompressedData, _mapping, _combineParts, _url); hfmGeometry = OBJReader().readOBJ(uncompressedData, _mapping, _combineParts, _url);
} else { } else {
throw QString("failed to decompress .obj.gz"); throw QString("failed to decompress .obj.gz");
} }
} else if (_url.path().toLower().endsWith(".gltf")) { } else if (_url.path().toLower().endsWith(".gltf")) {
std::shared_ptr<GLTFReader> glreader = std::make_shared<GLTFReader>(); std::shared_ptr<GLTFReader> glreader = std::make_shared<GLTFReader>();
fbxGeometry.reset(glreader->readGLTF(_data, _mapping, _url)); hfmGeometry.reset(glreader->readGLTF(_data, _mapping, _url));
if (fbxGeometry->meshes.size() == 0 && fbxGeometry->joints.size() == 0) { if (hfmGeometry->meshes.size() == 0 && hfmGeometry->joints.size() == 0) {
throw QString("empty geometry, possibly due to an unsupported GLTF version"); throw QString("empty geometry, possibly due to an unsupported GLTF version");
} }
} else { } else {
throw QString("unsupported format"); throw QString("unsupported format");
} }
// Add scripts to fbxgeometry // Add scripts to hfmGeometry
if (!_mapping.value(SCRIPT_FIELD).isNull()) { if (!_mapping.value(SCRIPT_FIELD).isNull()) {
QVariantList scripts = _mapping.values(SCRIPT_FIELD); QVariantList scripts = _mapping.values(SCRIPT_FIELD);
for (auto &script : scripts) { for (auto &script : scripts) {
fbxGeometry->scripts.push_back(script.toString()); hfmGeometry->scripts.push_back(script.toString());
} }
} }
@ -234,7 +234,7 @@ void GeometryReader::run() {
qCWarning(modelnetworking) << "Abandoning load of" << _url << "; could not get strong ref"; qCWarning(modelnetworking) << "Abandoning load of" << _url << "; could not get strong ref";
} else { } else {
QMetaObject::invokeMethod(resource.data(), "setGeometryDefinition", QMetaObject::invokeMethod(resource.data(), "setGeometryDefinition",
Q_ARG(FBXGeometry::Pointer, fbxGeometry)); Q_ARG(HFMGeometry::Pointer, hfmGeometry));
} }
} else { } else {
throw QString("url is invalid"); throw QString("url is invalid");
@ -262,7 +262,7 @@ public:
virtual void downloadFinished(const QByteArray& data) override; virtual void downloadFinished(const QByteArray& data) override;
protected: protected:
Q_INVOKABLE void setGeometryDefinition(FBXGeometry::Pointer fbxGeometry); Q_INVOKABLE void setGeometryDefinition(HFMGeometry::Pointer hfmGeometry);
private: private:
QVariantHash _mapping; QVariantHash _mapping;
@ -277,13 +277,13 @@ void GeometryDefinitionResource::downloadFinished(const QByteArray& data) {
QThreadPool::globalInstance()->start(new GeometryReader(_self, _effectiveBaseURL, _mapping, data, _combineParts)); QThreadPool::globalInstance()->start(new GeometryReader(_self, _effectiveBaseURL, _mapping, data, _combineParts));
} }
void GeometryDefinitionResource::setGeometryDefinition(FBXGeometry::Pointer fbxGeometry) { void GeometryDefinitionResource::setGeometryDefinition(HFMGeometry::Pointer hfmGeometry) {
// Assume ownership of the geometry pointer // Assume ownership of the geometry pointer
_fbxGeometry = fbxGeometry; _hfmGeometry = hfmGeometry;
// Copy materials // Copy materials
QHash<QString, size_t> materialIDAtlas; QHash<QString, size_t> materialIDAtlas;
for (const FBXMaterial& material : _fbxGeometry->materials) { for (const HFMMaterial& material : _hfmGeometry->materials) {
materialIDAtlas[material.materialID] = _materials.size(); materialIDAtlas[material.materialID] = _materials.size();
_materials.push_back(std::make_shared<NetworkMaterial>(material, _textureBaseUrl)); _materials.push_back(std::make_shared<NetworkMaterial>(material, _textureBaseUrl));
} }
@ -291,11 +291,11 @@ void GeometryDefinitionResource::setGeometryDefinition(FBXGeometry::Pointer fbxG
std::shared_ptr<GeometryMeshes> meshes = std::make_shared<GeometryMeshes>(); std::shared_ptr<GeometryMeshes> meshes = std::make_shared<GeometryMeshes>();
std::shared_ptr<GeometryMeshParts> parts = std::make_shared<GeometryMeshParts>(); std::shared_ptr<GeometryMeshParts> parts = std::make_shared<GeometryMeshParts>();
int meshID = 0; int meshID = 0;
for (const FBXMesh& mesh : _fbxGeometry->meshes) { for (const HFMMesh& mesh : _hfmGeometry->meshes) {
// Copy mesh pointers // Copy mesh pointers
meshes->emplace_back(mesh._mesh); meshes->emplace_back(mesh._mesh);
int partID = 0; int partID = 0;
for (const FBXMeshPart& part : mesh.parts) { for (const HFMMeshPart& part : mesh.parts) {
// Construct local parts // Construct local parts
parts->push_back(std::make_shared<MeshPart>(meshID, partID, (int)materialIDAtlas[part.materialID])); parts->push_back(std::make_shared<MeshPart>(meshID, partID, (int)materialIDAtlas[part.materialID]));
partID++; partID++;
@ -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 // FIXME: The materials should only be copied when modified, but the Model currently caches the original
Geometry::Geometry(const Geometry& geometry) { Geometry::Geometry(const Geometry& geometry) {
_fbxGeometry = geometry._fbxGeometry; _hfmGeometry = geometry._hfmGeometry;
_meshes = geometry._meshes; _meshes = geometry._meshes;
_meshParts = geometry._meshParts; _meshParts = geometry._meshParts;
@ -444,8 +444,8 @@ void GeometryResource::deleter() {
} }
void GeometryResource::setTextures() { void GeometryResource::setTextures() {
if (_fbxGeometry) { if (_hfmGeometry) {
for (const FBXMaterial& material : _fbxGeometry->materials) { for (const HFMMaterial& material : _hfmGeometry->materials) {
_materials.push_back(std::make_shared<NetworkMaterial>(material, _textureBaseUrl)); _materials.push_back(std::make_shared<NetworkMaterial>(material, _textureBaseUrl));
} }
} }
@ -512,7 +512,7 @@ const QString& NetworkMaterial::getTextureName(MapChannel channel) {
return NO_TEXTURE; return NO_TEXTURE;
} }
QUrl NetworkMaterial::getTextureUrl(const QUrl& baseUrl, const FBXTexture& texture) { QUrl NetworkMaterial::getTextureUrl(const QUrl& baseUrl, const HFMTexture& texture) {
if (texture.content.isEmpty()) { if (texture.content.isEmpty()) {
// External file: search relative to the baseUrl, in case filename is relative // External file: search relative to the baseUrl, in case filename is relative
return baseUrl.resolved(QUrl(texture.filename)); return baseUrl.resolved(QUrl(texture.filename));
@ -529,22 +529,22 @@ QUrl NetworkMaterial::getTextureUrl(const QUrl& baseUrl, const FBXTexture& textu
} }
} }
graphics::TextureMapPointer NetworkMaterial::fetchTextureMap(const QUrl& baseUrl, const FBXTexture& fbxTexture, graphics::TextureMapPointer NetworkMaterial::fetchTextureMap(const QUrl& baseUrl, const HFMTexture& hfmTexture,
image::TextureUsage::Type type, MapChannel channel) { image::TextureUsage::Type type, MapChannel channel) {
if (baseUrl.isEmpty()) { if (baseUrl.isEmpty()) {
return nullptr; return nullptr;
} }
const auto url = getTextureUrl(baseUrl, fbxTexture); const auto url = getTextureUrl(baseUrl, hfmTexture);
const auto texture = DependencyManager::get<TextureCache>()->getTexture(url, type, fbxTexture.content, fbxTexture.maxNumPixels); const auto texture = DependencyManager::get<TextureCache>()->getTexture(url, type, hfmTexture.content, hfmTexture.maxNumPixels);
_textures[channel] = Texture { fbxTexture.name, texture }; _textures[channel] = Texture { hfmTexture.name, texture };
auto map = std::make_shared<graphics::TextureMap>(); auto map = std::make_shared<graphics::TextureMap>();
if (texture) { if (texture) {
map->setTextureSource(texture->_textureSource); map->setTextureSource(texture->_textureSource);
} }
map->setTextureTransform(fbxTexture.transform); map->setTextureTransform(hfmTexture.transform);
return map; return map;
} }
@ -624,7 +624,7 @@ void NetworkMaterial::setLightmapMap(const QUrl& url) {
} }
} }
NetworkMaterial::NetworkMaterial(const FBXMaterial& material, const QUrl& textureBaseUrl) : NetworkMaterial::NetworkMaterial(const HFMMaterial& material, const QUrl& textureBaseUrl) :
graphics::Material(*material._material), graphics::Material(*material._material),
_textures(MapChannel::NUM_MAP_CHANNELS) _textures(MapChannel::NUM_MAP_CHANNELS)
{ {

View file

@ -45,9 +45,9 @@ public:
// Mutable, but must retain structure of vector // Mutable, but must retain structure of vector
using NetworkMaterials = std::vector<std::shared_ptr<NetworkMaterial>>; using NetworkMaterials = std::vector<std::shared_ptr<NetworkMaterial>>;
bool isGeometryLoaded() const { return (bool)_fbxGeometry; } bool isGeometryLoaded() const { return (bool)_hfmGeometry; }
const FBXGeometry& getFBXGeometry() const { return *_fbxGeometry; } const HFMGeometry& getHFMGeometry() const { return *_hfmGeometry; }
const GeometryMeshes& getMeshes() const { return *_meshes; } const GeometryMeshes& getMeshes() const { return *_meshes; }
const std::shared_ptr<NetworkMaterial> getShapeMaterial(int shapeID) const; const std::shared_ptr<NetworkMaterial> getShapeMaterial(int shapeID) const;
@ -62,7 +62,7 @@ protected:
friend class GeometryMappingResource; friend class GeometryMappingResource;
// Shared across all geometries, constant throughout lifetime // Shared across all geometries, constant throughout lifetime
std::shared_ptr<const FBXGeometry> _fbxGeometry; std::shared_ptr<const HFMGeometry> _hfmGeometry;
std::shared_ptr<const GeometryMeshes> _meshes; std::shared_ptr<const GeometryMeshes> _meshes;
std::shared_ptr<const GeometryMeshParts> _meshParts; 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 // 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 // Instead, these methods clear and reset textures from the geometry when caching/loading
bool shouldSetTextures() const { return _fbxGeometry && _materials.empty(); } bool shouldSetTextures() const { return _hfmGeometry && _materials.empty(); }
void setTextures(); void setTextures();
void resetTextures(); void resetTextures();
@ -165,7 +165,7 @@ public:
using MapChannel = graphics::Material::MapChannel; using MapChannel = graphics::Material::MapChannel;
NetworkMaterial() : _textures(MapChannel::NUM_MAP_CHANNELS) {} NetworkMaterial() : _textures(MapChannel::NUM_MAP_CHANNELS) {}
NetworkMaterial(const FBXMaterial& material, const QUrl& textureBaseUrl); NetworkMaterial(const HFMMaterial& material, const QUrl& textureBaseUrl);
NetworkMaterial(const NetworkMaterial& material); NetworkMaterial(const NetworkMaterial& material);
void setAlbedoMap(const QUrl& url, bool useAlphaChannel); void setAlbedoMap(const QUrl& url, bool useAlphaChannel);
@ -201,8 +201,8 @@ protected:
private: private:
// Helpers for the ctors // Helpers for the ctors
QUrl getTextureUrl(const QUrl& baseUrl, const FBXTexture& fbxTexture); QUrl getTextureUrl(const QUrl& baseUrl, const HFMTexture& hfmTexture);
graphics::TextureMapPointer fetchTextureMap(const QUrl& baseUrl, const FBXTexture& fbxTexture, graphics::TextureMapPointer fetchTextureMap(const QUrl& baseUrl, const HFMTexture& hfmTexture,
image::TextureUsage::Type type, MapChannel channel); image::TextureUsage::Type type, MapChannel channel);
graphics::TextureMapPointer fetchTextureMap(const QUrl& url, image::TextureUsage::Type type, MapChannel channel); graphics::TextureMapPointer fetchTextureMap(const QUrl& url, image::TextureUsage::Type type, MapChannel channel);

View file

@ -32,8 +32,8 @@ bool CauterizedModel::updateGeometry() {
bool needsFullUpdate = Model::updateGeometry(); bool needsFullUpdate = Model::updateGeometry();
if (_isCauterized && needsFullUpdate) { if (_isCauterized && needsFullUpdate) {
assert(_cauterizeMeshStates.empty()); assert(_cauterizeMeshStates.empty());
const FBXGeometry& fbxGeometry = getFBXGeometry(); const HFMGeometry& hfmGeometry = getHFMGeometry();
foreach (const FBXMesh& mesh, fbxGeometry.meshes) { foreach (const HFMMesh& mesh, hfmGeometry.meshes) {
Model::MeshState state; Model::MeshState state;
if (_useDualQuaternionSkinning) { if (_useDualQuaternionSkinning) {
state.clusterDualQuaternions.resize(mesh.clusters.size()); 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 // Run through all of the meshes, and place them into their segregated, but unsorted buckets
int shapeID = 0; int shapeID = 0;
uint32_t numMeshes = (uint32_t)meshes.size(); uint32_t numMeshes = (uint32_t)meshes.size();
const FBXGeometry& fbxGeometry = getFBXGeometry(); const HFMGeometry& hfmGeometry = getHFMGeometry();
for (uint32_t i = 0; i < numMeshes; i++) { for (uint32_t i = 0; i < numMeshes; i++) {
const auto& mesh = meshes.at(i); const auto& mesh = meshes.at(i);
if (!mesh) { if (!mesh) {
@ -86,7 +86,7 @@ void CauterizedModel::createRenderItemSet() {
// Create the render payloads // Create the render payloads
int numParts = (int)mesh->getNumParts(); int numParts = (int)mesh->getNumParts();
for (int partIndex = 0; partIndex < numParts; partIndex++) { for (int partIndex = 0; partIndex < numParts; partIndex++) {
initializeBlendshapes(fbxGeometry.meshes[i], i); initializeBlendshapes(hfmGeometry.meshes[i], i);
auto ptr = std::make_shared<CauterizedMeshPartPayload>(shared_from_this(), i, partIndex, shapeID, transform, offset); auto ptr = std::make_shared<CauterizedMeshPartPayload>(shared_from_this(), i, partIndex, shapeID, transform, offset);
_modelMeshRenderItems << std::static_pointer_cast<ModelMeshPartPayload>(ptr); _modelMeshRenderItems << std::static_pointer_cast<ModelMeshPartPayload>(ptr);
@ -109,13 +109,13 @@ void CauterizedModel::updateClusterMatrices() {
return; return;
} }
_needsUpdateClusterMatrices = false; _needsUpdateClusterMatrices = false;
const FBXGeometry& geometry = getFBXGeometry(); const HFMGeometry& geometry = getHFMGeometry();
for (int i = 0; i < (int)_meshStates.size(); i++) { for (int i = 0; i < (int)_meshStates.size(); i++) {
Model::MeshState& state = _meshStates[i]; Model::MeshState& state = _meshStates[i];
const FBXMesh& mesh = geometry.meshes.at(i); const HFMMesh& mesh = geometry.meshes.at(i);
for (int j = 0; j < mesh.clusters.size(); j++) { for (int j = 0; j < mesh.clusters.size(); j++) {
const FBXCluster& cluster = mesh.clusters.at(j); const HFMCluster& cluster = mesh.clusters.at(j);
if (_useDualQuaternionSkinning) { if (_useDualQuaternionSkinning) {
auto jointPose = _rig.getJointPose(cluster.jointIndex); auto jointPose = _rig.getJointPose(cluster.jointIndex);
Transform jointTransform(jointPose.rot(), jointPose.scale(), jointPose.trans()); Transform jointTransform(jointPose.rot(), jointPose.scale(), jointPose.trans());
@ -145,10 +145,10 @@ void CauterizedModel::updateClusterMatrices() {
for (int i = 0; i < _cauterizeMeshStates.size(); i++) { for (int i = 0; i < _cauterizeMeshStates.size(); i++) {
Model::MeshState& state = _cauterizeMeshStates[i]; Model::MeshState& state = _cauterizeMeshStates[i];
const FBXMesh& mesh = geometry.meshes.at(i); const HFMMesh& mesh = geometry.meshes.at(i);
for (int j = 0; j < mesh.clusters.size(); j++) { for (int j = 0; j < mesh.clusters.size(); j++) {
const FBXCluster& cluster = mesh.clusters.at(j); const HFMCluster& cluster = mesh.clusters.at(j);
if (_useDualQuaternionSkinning) { if (_useDualQuaternionSkinning) {
if (_cauterizeBoneSet.find(cluster.jointIndex) == _cauterizeBoneSet.end()) { if (_cauterizeBoneSet.find(cluster.jointIndex) == _cauterizeBoneSet.end()) {

View file

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

View file

@ -183,7 +183,7 @@ bool Model::shouldInvalidatePayloadShapeKey(int meshIndex) {
return true; return true;
} }
const FBXGeometry& geometry = getFBXGeometry(); const HFMGeometry& geometry = getHFMGeometry();
const auto& networkMeshes = getGeometry()->getMeshes(); 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 // 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. // to false to rebuild out mesh groups.
@ -278,7 +278,7 @@ void Model::setRenderItemsNeedUpdate() {
void Model::reset() { void Model::reset() {
if (isLoaded()) { if (isLoaded()) {
const FBXGeometry& geometry = getFBXGeometry(); const HFMGeometry& geometry = getHFMGeometry();
_rig.reset(geometry); _rig.reset(geometry);
emit rigReset(); emit rigReset();
emit rigReady(); emit rigReady();
@ -295,13 +295,13 @@ bool Model::updateGeometry() {
_needsReload = false; _needsReload = false;
// TODO: should all Models have a valid _rig? // TODO: should all Models have a valid _rig?
if (_rig.jointStatesEmpty() && getFBXGeometry().joints.size() > 0) { if (_rig.jointStatesEmpty() && getHFMGeometry().joints.size() > 0) {
initJointStates(); initJointStates();
assert(_meshStates.empty()); assert(_meshStates.empty());
const FBXGeometry& fbxGeometry = getFBXGeometry(); const HFMGeometry& hfmGeometry = getHFMGeometry();
int i = 0; int i = 0;
foreach (const FBXMesh& mesh, fbxGeometry.meshes) { foreach (const HFMMesh& mesh, hfmGeometry.meshes) {
MeshState state; MeshState state;
state.clusterDualQuaternions.resize(mesh.clusters.size()); state.clusterDualQuaternions.resize(mesh.clusters.size());
state.clusterMatrices.resize(mesh.clusters.size()); state.clusterMatrices.resize(mesh.clusters.size());
@ -319,7 +319,7 @@ bool Model::updateGeometry() {
// virtual // virtual
void Model::initJointStates() { void Model::initJointStates() {
const FBXGeometry& geometry = getFBXGeometry(); const HFMGeometry& geometry = getHFMGeometry();
glm::mat4 modelOffset = glm::scale(_scale) * glm::translate(_offset); glm::mat4 modelOffset = glm::scale(_scale) * glm::translate(_offset);
_rig.initJointStates(geometry, modelOffset); _rig.initJointStates(geometry, modelOffset);
@ -363,7 +363,7 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g
int bestShapeID = 0; int bestShapeID = 0;
int bestSubMeshIndex = 0; int bestSubMeshIndex = 0;
const FBXGeometry& geometry = getFBXGeometry(); const HFMGeometry& geometry = getHFMGeometry();
if (!_triangleSetsValid) { if (!_triangleSetsValid) {
calculateTriangleSets(geometry); calculateTriangleSets(geometry);
} }
@ -506,7 +506,7 @@ bool Model::findParabolaIntersectionAgainstSubMeshes(const glm::vec3& origin, co
int bestShapeID = 0; int bestShapeID = 0;
int bestSubMeshIndex = 0; int bestSubMeshIndex = 0;
const FBXGeometry& geometry = getFBXGeometry(); const HFMGeometry& geometry = getHFMGeometry();
if (!_triangleSetsValid) { if (!_triangleSetsValid) {
calculateTriangleSets(geometry); calculateTriangleSets(geometry);
} }
@ -641,7 +641,7 @@ bool Model::convexHullContains(glm::vec3 point) {
QMutexLocker locker(&_mutex); QMutexLocker locker(&_mutex);
if (!_triangleSetsValid) { if (!_triangleSetsValid) {
calculateTriangleSets(getFBXGeometry()); calculateTriangleSets(getHFMGeometry());
} }
// If we are inside the models box, then consider the submeshes... // If we are inside the models box, then consider the submeshes...
@ -753,14 +753,14 @@ bool Model::replaceScriptableModelMeshPart(scriptable::ScriptableModelBasePointe
} }
// update triangles for picking // update triangles for picking
{ {
FBXGeometry geometry; HFMGeometry geometry;
for (const auto& newMesh : meshes) { for (const auto& newMesh : meshes) {
FBXMesh mesh; HFMMesh mesh;
mesh._mesh = newMesh.getMeshPointer(); mesh._mesh = newMesh.getMeshPointer();
mesh.vertices = buffer_helpers::mesh::attributeToVector<glm::vec3>(mesh._mesh, gpu::Stream::POSITION); mesh.vertices = buffer_helpers::mesh::attributeToVector<glm::vec3>(mesh._mesh, gpu::Stream::POSITION);
int numParts = (int)newMesh.getMeshPointer()->getNumParts(); int numParts = (int)newMesh.getMeshPointer()->getNumParts();
for (int partID = 0; partID < numParts; partID++) { for (int partID = 0; partID < numParts; partID++) {
FBXMeshPart part; HFMMeshPart part;
part.triangleIndices = buffer_helpers::bufferToVector<int>(mesh._mesh->getIndexBuffer(), "part.triangleIndices"); part.triangleIndices = buffer_helpers::bufferToVector<int>(mesh._mesh->getIndexBuffer(), "part.triangleIndices");
mesh.parts << part; mesh.parts << part;
} }
@ -789,12 +789,12 @@ scriptable::ScriptableModelBase Model::getScriptableModel() {
return result; return result;
} }
const FBXGeometry& geometry = getFBXGeometry(); const HFMGeometry& geometry = getHFMGeometry();
int numberOfMeshes = geometry.meshes.size(); int numberOfMeshes = geometry.meshes.size();
int shapeID = 0; int shapeID = 0;
for (int i = 0; i < numberOfMeshes; i++) { for (int i = 0; i < numberOfMeshes; i++) {
const FBXMesh& fbxMesh = geometry.meshes.at(i); const HFMMesh& hfmMesh = geometry.meshes.at(i);
if (auto mesh = fbxMesh._mesh) { if (auto mesh = hfmMesh._mesh) {
result.append(mesh); result.append(mesh);
int numParts = (int)mesh->getNumParts(); int numParts = (int)mesh->getNumParts();
@ -808,7 +808,7 @@ scriptable::ScriptableModelBase Model::getScriptableModel() {
return result; return result;
} }
void Model::calculateTriangleSets(const FBXGeometry& geometry) { void Model::calculateTriangleSets(const HFMGeometry& geometry) {
PROFILE_RANGE(render, __FUNCTION__); PROFILE_RANGE(render, __FUNCTION__);
int numberOfMeshes = geometry.meshes.size(); int numberOfMeshes = geometry.meshes.size();
@ -818,14 +818,14 @@ void Model::calculateTriangleSets(const FBXGeometry& geometry) {
_modelSpaceMeshTriangleSets.resize(numberOfMeshes); _modelSpaceMeshTriangleSets.resize(numberOfMeshes);
for (int i = 0; i < numberOfMeshes; i++) { for (int i = 0; i < numberOfMeshes; i++) {
const FBXMesh& mesh = geometry.meshes.at(i); const HFMMesh& mesh = geometry.meshes.at(i);
const int numberOfParts = mesh.parts.size(); const int numberOfParts = mesh.parts.size();
auto& meshTriangleSets = _modelSpaceMeshTriangleSets[i]; auto& meshTriangleSets = _modelSpaceMeshTriangleSets[i];
meshTriangleSets.resize(numberOfParts); meshTriangleSets.resize(numberOfParts);
for (int j = 0; j < numberOfParts; j++) { for (int j = 0; j < numberOfParts; j++) {
const FBXMeshPart& part = mesh.parts.at(j); const HFMMeshPart& part = mesh.parts.at(j);
auto& partTriangleSet = meshTriangleSets[j]; auto& partTriangleSet = meshTriangleSets[j];
@ -1114,7 +1114,7 @@ Extents Model::getBindExtents() const {
if (!isActive()) { if (!isActive()) {
return Extents(); return Extents();
} }
const Extents& bindExtents = getFBXGeometry().bindExtents; const Extents& bindExtents = getHFMGeometry().bindExtents;
Extents scaledExtents = { bindExtents.minimum * _scale, bindExtents.maximum * _scale }; Extents scaledExtents = { bindExtents.minimum * _scale, bindExtents.maximum * _scale };
return scaledExtents; return scaledExtents;
} }
@ -1128,12 +1128,12 @@ Extents Model::getMeshExtents() const {
if (!isActive()) { if (!isActive()) {
return Extents(); return Extents();
} }
const Extents& extents = getFBXGeometry().meshExtents; const Extents& extents = getHFMGeometry().meshExtents;
// even though our caller asked for "unscaled" we need to include any fst scaling, translation, and rotation, which // even though our caller asked for "unscaled" we need to include any fst scaling, translation, and rotation, which
// is captured in the offset matrix // is captured in the offset matrix
glm::vec3 minimum = glm::vec3(getFBXGeometry().offset * glm::vec4(extents.minimum, 1.0f)); glm::vec3 minimum = glm::vec3(getHFMGeometry().offset * glm::vec4(extents.minimum, 1.0f));
glm::vec3 maximum = glm::vec3(getFBXGeometry().offset * glm::vec4(extents.maximum, 1.0f)); glm::vec3 maximum = glm::vec3(getHFMGeometry().offset * glm::vec4(extents.maximum, 1.0f));
Extents scaledExtents = { minimum * _scale, maximum * _scale }; Extents scaledExtents = { minimum * _scale, maximum * _scale };
return scaledExtents; return scaledExtents;
} }
@ -1143,12 +1143,12 @@ Extents Model::getUnscaledMeshExtents() const {
return Extents(); return Extents();
} }
const Extents& extents = getFBXGeometry().meshExtents; const Extents& extents = getHFMGeometry().meshExtents;
// even though our caller asked for "unscaled" we need to include any fst scaling, translation, and rotation, which // even though our caller asked for "unscaled" we need to include any fst scaling, translation, and rotation, which
// is captured in the offset matrix // is captured in the offset matrix
glm::vec3 minimum = glm::vec3(getFBXGeometry().offset * glm::vec4(extents.minimum, 1.0f)); glm::vec3 minimum = glm::vec3(getHFMGeometry().offset * glm::vec4(extents.minimum, 1.0f));
glm::vec3 maximum = glm::vec3(getFBXGeometry().offset * glm::vec4(extents.maximum, 1.0f)); glm::vec3 maximum = glm::vec3(getHFMGeometry().offset * glm::vec4(extents.maximum, 1.0f));
Extents scaledExtents = { minimum, maximum }; Extents scaledExtents = { minimum, maximum };
return scaledExtents; return scaledExtents;
@ -1171,11 +1171,11 @@ void Model::setJointTranslation(int index, bool valid, const glm::vec3& translat
} }
int Model::getParentJointIndex(int jointIndex) const { int Model::getParentJointIndex(int jointIndex) const {
return (isActive() && jointIndex != -1) ? getFBXGeometry().joints.at(jointIndex).parentIndex : -1; return (isActive() && jointIndex != -1) ? getHFMGeometry().joints.at(jointIndex).parentIndex : -1;
} }
int Model::getLastFreeJointIndex(int jointIndex) const { int Model::getLastFreeJointIndex(int jointIndex) const {
return (isActive() && jointIndex != -1) ? getFBXGeometry().joints.at(jointIndex).freeLineage.last() : -1; return (isActive() && jointIndex != -1) ? getHFMGeometry().joints.at(jointIndex).freeLineage.last() : -1;
} }
void Model::setTextures(const QVariantMap& textures) { void Model::setTextures(const QVariantMap& textures) {
@ -1275,7 +1275,7 @@ QStringList Model::getJointNames() const {
Q_RETURN_ARG(QStringList, result)); Q_RETURN_ARG(QStringList, result));
return result; return result;
} }
return isActive() ? getFBXGeometry().getJointNames() : QStringList(); return isActive() ? getHFMGeometry().getJointNames() : QStringList();
} }
void Model::setScaleToFit(bool scaleToFit, const glm::vec3& dimensions, bool forceRescale) { void Model::setScaleToFit(bool scaleToFit, const glm::vec3& dimensions, bool forceRescale) {
@ -1415,12 +1415,12 @@ void Model::updateClusterMatrices() {
} }
_needsUpdateClusterMatrices = false; _needsUpdateClusterMatrices = false;
const FBXGeometry& geometry = getFBXGeometry(); const HFMGeometry& geometry = getHFMGeometry();
for (int i = 0; i < (int) _meshStates.size(); i++) { for (int i = 0; i < (int) _meshStates.size(); i++) {
MeshState& state = _meshStates[i]; MeshState& state = _meshStates[i];
const FBXMesh& mesh = geometry.meshes.at(i); const HFMMesh& mesh = geometry.meshes.at(i);
for (int j = 0; j < mesh.clusters.size(); j++) { for (int j = 0; j < mesh.clusters.size(); j++) {
const FBXCluster& cluster = mesh.clusters.at(j); const HFMCluster& cluster = mesh.clusters.at(j);
if (_useDualQuaternionSkinning) { if (_useDualQuaternionSkinning) {
auto jointPose = _rig.getJointPose(cluster.jointIndex); auto jointPose = _rig.getJointPose(cluster.jointIndex);
Transform jointTransform(jointPose.rot(), jointPose.scale(), jointPose.trans()); Transform jointTransform(jointPose.rot(), jointPose.scale(), jointPose.trans());
@ -1505,7 +1505,7 @@ void Model::createRenderItemSet() {
// Run through all of the meshes, and place them into their segregated, but unsorted buckets // Run through all of the meshes, and place them into their segregated, but unsorted buckets
int shapeID = 0; int shapeID = 0;
uint32_t numMeshes = (uint32_t)meshes.size(); uint32_t numMeshes = (uint32_t)meshes.size();
auto& fbxGeometry = getFBXGeometry(); auto& hfmGeometry = getHFMGeometry();
for (uint32_t i = 0; i < numMeshes; i++) { for (uint32_t i = 0; i < numMeshes; i++) {
const auto& mesh = meshes.at(i); const auto& mesh = meshes.at(i);
if (!mesh) { if (!mesh) {
@ -1515,7 +1515,7 @@ void Model::createRenderItemSet() {
// Create the render payloads // Create the render payloads
int numParts = (int)mesh->getNumParts(); int numParts = (int)mesh->getNumParts();
for (int partIndex = 0; partIndex < numParts; partIndex++) { for (int partIndex = 0; partIndex < numParts; partIndex++) {
initializeBlendshapes(fbxGeometry.meshes[i], i); initializeBlendshapes(hfmGeometry.meshes[i], i);
_modelMeshRenderItems << std::make_shared<ModelMeshPartPayload>(shared_from_this(), i, partIndex, shapeID, transform, offset); _modelMeshRenderItems << std::make_shared<ModelMeshPartPayload>(shared_from_this(), i, partIndex, shapeID, transform, offset);
auto material = getGeometry()->getShapeMaterial(shapeID); auto material = getGeometry()->getShapeMaterial(shapeID);
_modelMeshMaterialNames.push_back(material ? material->getName() : ""); _modelMeshMaterialNames.push_back(material ? material->getName() : "");
@ -1600,7 +1600,7 @@ void Model::removeMaterial(graphics::MaterialPointer material, const std::string
class CollisionRenderGeometry : public Geometry { class CollisionRenderGeometry : public Geometry {
public: public:
CollisionRenderGeometry(graphics::MeshPointer mesh) { CollisionRenderGeometry(graphics::MeshPointer mesh) {
_fbxGeometry = std::make_shared<FBXGeometry>(); _hfmGeometry = std::make_shared<HFMGeometry>();
std::shared_ptr<GeometryMeshes> meshes = std::make_shared<GeometryMeshes>(); std::shared_ptr<GeometryMeshes> meshes = std::make_shared<GeometryMeshes>();
meshes->push_back(mesh); meshes->push_back(mesh);
_meshes = meshes; _meshes = meshes;
@ -1656,9 +1656,9 @@ void Blender::run() {
if (_model && _model->isLoaded()) { if (_model && _model->isLoaded()) {
DETAILED_PROFILE_RANGE_EX(simulation_animation, __FUNCTION__, 0xFFFF0000, 0, { { "url", _model->getURL().toString() } }); DETAILED_PROFILE_RANGE_EX(simulation_animation, __FUNCTION__, 0xFFFF0000, 0, { { "url", _model->getURL().toString() } });
int offset = 0; int offset = 0;
auto meshes = _model->getFBXGeometry().meshes; auto meshes = _model->getHFMGeometry().meshes;
int meshIndex = 0; int meshIndex = 0;
foreach(const FBXMesh& mesh, meshes) { foreach(const HFMMesh& mesh, meshes) {
auto modelMeshBlendshapeOffsets = _model->_blendshapeOffsets.find(meshIndex++); auto modelMeshBlendshapeOffsets = _model->_blendshapeOffsets.find(meshIndex++);
if (mesh.blendshapes.isEmpty() || modelMeshBlendshapeOffsets == _model->_blendshapeOffsets.end()) { if (mesh.blendshapes.isEmpty() || modelMeshBlendshapeOffsets == _model->_blendshapeOffsets.end()) {
// Not blendshaped or not initialized // Not blendshaped or not initialized
@ -1688,7 +1688,7 @@ void Blender::run() {
} }
float normalCoefficient = vertexCoefficient * NORMAL_COEFFICIENT_SCALE; float normalCoefficient = vertexCoefficient * NORMAL_COEFFICIENT_SCALE;
const FBXBlendshape& blendshape = mesh.blendshapes.at(i); const HFMBlendshape& blendshape = mesh.blendshapes.at(i);
tbb::parallel_for(tbb::blocked_range<int>(0, blendshape.indices.size()), [&](const tbb::blocked_range<int>& range) { tbb::parallel_for(tbb::blocked_range<int>(0, blendshape.indices.size()), [&](const tbb::blocked_range<int>& range) {
for (auto j = range.begin(); j < range.end(); j++) { for (auto j = range.begin(); j < range.end(); j++) {
@ -1731,7 +1731,7 @@ bool Model::maybeStartBlender() {
return false; return false;
} }
void Model::initializeBlendshapes(const FBXMesh& mesh, int index) { void Model::initializeBlendshapes(const HFMMesh& mesh, int index) {
if (mesh.blendshapes.empty()) { if (mesh.blendshapes.empty()) {
// mesh doesn't have blendshape, did we allocate one though ? // mesh doesn't have blendshape, did we allocate one though ?
if (_blendshapeOffsets.find(index) != _blendshapeOffsets.end()) { if (_blendshapeOffsets.find(index) != _blendshapeOffsets.end()) {

View file

@ -185,7 +185,7 @@ public:
/// Provided as a convenience, will crash if !isLoaded() /// Provided as a convenience, will crash if !isLoaded()
// And so that getGeometry() isn't chained everywhere // And so that getGeometry() isn't chained everywhere
const FBXGeometry& getFBXGeometry() const { assert(isLoaded()); return _renderGeometry->getFBXGeometry(); } const HFMGeometry& getHFMGeometry() const { assert(isLoaded()); return _renderGeometry->getHFMGeometry(); }
bool isActive() const { return isLoaded(); } bool isActive() const { return isLoaded(); }
@ -450,7 +450,7 @@ protected:
bool _overrideModelTransform { false }; bool _overrideModelTransform { false };
bool _triangleSetsValid { false }; bool _triangleSetsValid { false };
void calculateTriangleSets(const FBXGeometry& geometry); void calculateTriangleSets(const HFMGeometry& geometry);
std::vector<std::vector<TriangleSet>> _modelSpaceMeshTriangleSets; // model space triangles for all sub meshes std::vector<std::vector<TriangleSet>> _modelSpaceMeshTriangleSets; // model space triangles for all sub meshes
virtual void createRenderItemSet(); virtual void createRenderItemSet();
@ -506,7 +506,7 @@ protected:
bool shouldInvalidatePayloadShapeKey(int meshIndex); bool shouldInvalidatePayloadShapeKey(int meshIndex);
void initializeBlendshapes(const FBXMesh& mesh, int index); void initializeBlendshapes(const HFMMesh& mesh, int index);
private: private:
float _loadingPriority { 0.0f }; float _loadingPriority { 0.0f };

View file

@ -41,14 +41,14 @@ void SoftAttachmentModel::updateClusterMatrices() {
_needsUpdateClusterMatrices = false; _needsUpdateClusterMatrices = false;
const FBXGeometry& geometry = getFBXGeometry(); const HFMGeometry& geometry = getHFMGeometry();
for (int i = 0; i < (int) _meshStates.size(); i++) { for (int i = 0; i < (int) _meshStates.size(); i++) {
MeshState& state = _meshStates[i]; MeshState& state = _meshStates[i];
const FBXMesh& mesh = geometry.meshes.at(i); const HFMMesh& mesh = geometry.meshes.at(i);
for (int j = 0; j < mesh.clusters.size(); j++) { for (int j = 0; j < mesh.clusters.size(); j++) {
const FBXCluster& cluster = mesh.clusters.at(j); const HFMCluster& cluster = mesh.clusters.at(j);
// TODO: cache these look-ups as an optimization // TODO: cache these look-ups as an optimization
int jointIndexOverride = getJointIndexOverride(cluster.jointIndex); int jointIndexOverride = getJointIndexOverride(cluster.jointIndex);

View file

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

View file

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

View file

@ -28,8 +28,8 @@ const glm::quat identity = glm::quat();
const glm::quat quaterTurnAroundZ = glm::angleAxis(0.5f * PI, zAxis); const glm::quat quaterTurnAroundZ = glm::angleAxis(0.5f * PI, zAxis);
void makeTestFBXJoints(FBXGeometry& geometry) { void makeTestFBXJoints(HFMGeometry& geometry) {
FBXJoint joint; HFMJoint joint;
joint.isFree = false; joint.isFree = false;
joint.freeLineage.clear(); joint.freeLineage.clear();
joint.parentIndex = -1; joint.parentIndex = -1;
@ -79,7 +79,7 @@ void makeTestFBXJoints(FBXGeometry& geometry) {
// compute each joint's transform // compute each joint's transform
for (int i = 1; i < (int)geometry.joints.size(); ++i) { for (int i = 1; i < (int)geometry.joints.size(); ++i) {
FBXJoint& j = geometry.joints[i]; HFMJoint& j = geometry.joints[i];
int parentIndex = j.parentIndex; int parentIndex = j.parentIndex;
// World = ParentWorld * T * (Roff * Rp) * Rpre * R * Rpost * (Rp-1 * Soff * Sp * S * Sp-1) // World = ParentWorld * T * (Roff * Rp) * Rpre * R * Rpost * (Rp-1 * Soff * Sp * S * Sp-1)
j.transform = geometry.joints[parentIndex].transform * j.transform = geometry.joints[parentIndex].transform *
@ -96,7 +96,7 @@ void AnimInverseKinematicsTests::testSingleChain() {
AnimContext context(false, false, false, glm::mat4(), glm::mat4()); AnimContext context(false, false, false, glm::mat4(), glm::mat4());
FBXGeometry geometry; HFMGeometry geometry;
makeTestFBXJoints(geometry); makeTestFBXJoints(geometry);
// create a skeleton and doll // create a skeleton and doll

View file

@ -54,8 +54,8 @@ SkeletonDumpApp::SkeletonDumpApp(int argc, char* argv[]) : QCoreApplication(argc
return; return;
} }
QByteArray blob = file.readAll(); QByteArray blob = file.readAll();
std::unique_ptr<FBXGeometry> fbxGeometry(readFBX(blob, QVariantHash())); std::unique_ptr<HFMGeometry> geometry(readFBX(blob, QVariantHash()));
std::unique_ptr<AnimSkeleton> skeleton(new AnimSkeleton(*fbxGeometry)); std::unique_ptr<AnimSkeleton> skeleton(new AnimSkeleton(*geometry));
skeleton->dump(verbose); 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 // 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. // them back in the order in which they appeared in the file.
bool FBXGeometryLessThan(const FBXMesh& e1, const FBXMesh& e2) { bool HFMGeometryLessThan(const HFMMesh& e1, const HFMMesh& e2) {
return e1.meshIndex < e2.meshIndex; return e1.meshIndex < e2.meshIndex;
} }
void reSortFBXGeometryMeshes(FBXGeometry& geometry) { void reSortHFMGeometryMeshes(HFMGeometry& geometry) {
qSort(geometry.meshes.begin(), geometry.meshes.end(), FBXGeometryLessThan); qSort(geometry.meshes.begin(), geometry.meshes.end(), HFMGeometryLessThan);
} }
// Read all the meshes from provided FBX file // Read all the meshes from provided FBX file
bool vhacd::VHACDUtil::loadFBX(const QString filename, FBXGeometry& result) { bool vhacd::VHACDUtil::loadFBX(const QString filename, HFMGeometry& result) {
if (_verbose) { if (_verbose) {
qDebug() << "reading FBX file =" << filename << "..."; qDebug() << "reading FBX file =" << filename << "...";
} }
@ -41,7 +41,7 @@ bool vhacd::VHACDUtil::loadFBX(const QString filename, FBXGeometry& result) {
} }
try { try {
QByteArray fbxContents = fbx.readAll(); QByteArray fbxContents = fbx.readAll();
FBXGeometry::Pointer geom; HFMGeometry::Pointer geom;
if (filename.toLower().endsWith(".obj")) { if (filename.toLower().endsWith(".obj")) {
bool combineParts = false; bool combineParts = false;
geom = OBJReader().readOBJ(fbxContents, QVariantHash(), combineParts); geom = OBJReader().readOBJ(fbxContents, QVariantHash(), combineParts);
@ -53,7 +53,7 @@ bool vhacd::VHACDUtil::loadFBX(const QString filename, FBXGeometry& result) {
} }
result = *geom; result = *geom;
reSortFBXGeometryMeshes(result); reSortHFMGeometryMeshes(result);
} catch (const QString& error) { } catch (const QString& error) {
qWarning() << "error reading" << filename << ":" << error; qWarning() << "error reading" << filename << ":" << error;
return false; return false;
@ -63,7 +63,7 @@ bool vhacd::VHACDUtil::loadFBX(const QString filename, FBXGeometry& result) {
} }
void getTrianglesInMeshPart(const FBXMeshPart &meshPart, std::vector<int>& triangleIndices) { void getTrianglesInMeshPart(const HFMMeshPart &meshPart, std::vector<int>& triangleIndices) {
// append triangle indices // append triangle indices
triangleIndices.reserve(triangleIndices.size() + (size_t)meshPart.triangleIndices.size()); triangleIndices.reserve(triangleIndices.size() + (size_t)meshPart.triangleIndices.size());
for (auto index : meshPart.triangleIndices) { for (auto index : meshPart.triangleIndices) {
@ -88,12 +88,12 @@ void getTrianglesInMeshPart(const FBXMeshPart &meshPart, std::vector<int>& trian
} }
} }
void vhacd::VHACDUtil::fattenMesh(const FBXMesh& mesh, const glm::mat4& geometryOffset, FBXMesh& result) const { void vhacd::VHACDUtil::fattenMesh(const HFMMesh& mesh, const glm::mat4& geometryOffset, HFMMesh& result) const {
// this is used to make meshes generated from a highfield collidable. each triangle // 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. // is converted into a tetrahedron and made into its own mesh-part.
std::vector<int> triangleIndices; std::vector<int> triangleIndices;
foreach (const FBXMeshPart &meshPart, mesh.parts) { foreach (const HFMMeshPart &meshPart, mesh.parts) {
getTrianglesInMeshPart(meshPart, triangleIndices); getTrianglesInMeshPart(meshPart, triangleIndices);
} }
@ -145,7 +145,7 @@ void vhacd::VHACDUtil::fattenMesh(const FBXMesh& mesh, const glm::mat4& geometry
int index3 = result.vertices.size(); int index3 = result.vertices.size();
result.vertices << p3; // add the new point to the result mesh result.vertices << p3; // add the new point to the result mesh
FBXMeshPart newMeshPart; HFMMeshPart newMeshPart;
setMeshPartDefaults(newMeshPart, "unknown"); setMeshPartDefaults(newMeshPart, "unknown");
newMeshPart.triangleIndices << index0 << index1 << index2; newMeshPart.triangleIndices << index0 << index1 << index2;
newMeshPart.triangleIndices << index0 << index3 << index1; newMeshPart.triangleIndices << index0 << index3 << index1;
@ -155,7 +155,7 @@ void vhacd::VHACDUtil::fattenMesh(const FBXMesh& mesh, const glm::mat4& geometry
} }
} }
AABox getAABoxForMeshPart(const FBXMesh& mesh, const FBXMeshPart &meshPart) { AABox getAABoxForMeshPart(const HFMMesh& mesh, const HFMMeshPart &meshPart) {
AABox aaBox; AABox aaBox;
const int TRIANGLE_STRIDE = 3; const int TRIANGLE_STRIDE = 3;
for (int i = 0; i < meshPart.triangleIndices.size(); i += TRIANGLE_STRIDE) { for (int i = 0; i < meshPart.triangleIndices.size(); i += TRIANGLE_STRIDE) {
@ -242,7 +242,7 @@ bool isClosedManifold(const std::vector<int>& triangleIndices) {
return true; return true;
} }
void vhacd::VHACDUtil::getConvexResults(VHACD::IVHACD* convexifier, FBXMesh& resultMesh) const { void vhacd::VHACDUtil::getConvexResults(VHACD::IVHACD* convexifier, HFMMesh& resultMesh) const {
// Number of hulls for this input meshPart // Number of hulls for this input meshPart
uint32_t numHulls = convexifier->GetNConvexHulls(); uint32_t numHulls = convexifier->GetNConvexHulls();
if (_verbose) { if (_verbose) {
@ -256,8 +256,8 @@ void vhacd::VHACDUtil::getConvexResults(VHACD::IVHACD* convexifier, FBXMesh& res
VHACD::IVHACD::ConvexHull hull; VHACD::IVHACD::ConvexHull hull;
convexifier->GetConvexHull(j, hull); convexifier->GetConvexHull(j, hull);
resultMesh.parts.append(FBXMeshPart()); resultMesh.parts.append(HFMMeshPart());
FBXMeshPart& resultMeshPart = resultMesh.parts.last(); HFMMeshPart& resultMeshPart = resultMesh.parts.last();
int hullIndexStart = resultMesh.vertices.size(); int hullIndexStart = resultMesh.vertices.size();
resultMesh.vertices.reserve(hullIndexStart + hull.m_nPoints); resultMesh.vertices.reserve(hullIndexStart + hull.m_nPoints);
@ -288,9 +288,9 @@ float computeDt(uint64_t start) {
return (float)(usecTimestampNow() - start) / (float)USECS_PER_SECOND; return (float)(usecTimestampNow() - start) / (float)USECS_PER_SECOND;
} }
bool vhacd::VHACDUtil::computeVHACD(FBXGeometry& geometry, bool vhacd::VHACDUtil::computeVHACD(HFMGeometry& geometry,
VHACD::IVHACD::Parameters params, VHACD::IVHACD::Parameters params,
FBXGeometry& result, HFMGeometry& result,
float minimumMeshSize, float maximumMeshSize) { float minimumMeshSize, float maximumMeshSize) {
if (_verbose) { if (_verbose) {
qDebug() << "meshes =" << geometry.meshes.size(); qDebug() << "meshes =" << geometry.meshes.size();
@ -298,7 +298,7 @@ bool vhacd::VHACDUtil::computeVHACD(FBXGeometry& geometry,
// count the mesh-parts // count the mesh-parts
int numParts = 0; int numParts = 0;
foreach (const FBXMesh& mesh, geometry.meshes) { foreach (const HFMMesh& mesh, geometry.meshes) {
numParts += mesh.parts.size(); numParts += mesh.parts.size();
} }
if (_verbose) { if (_verbose) {
@ -308,15 +308,15 @@ bool vhacd::VHACDUtil::computeVHACD(FBXGeometry& geometry,
VHACD::IVHACD * convexifier = VHACD::CreateVHACD(); VHACD::IVHACD * convexifier = VHACD::CreateVHACD();
result.meshExtents.reset(); result.meshExtents.reset();
result.meshes.append(FBXMesh()); result.meshes.append(HFMMesh());
FBXMesh &resultMesh = result.meshes.last(); HFMMesh &resultMesh = result.meshes.last();
const uint32_t POINT_STRIDE = 3; const uint32_t POINT_STRIDE = 3;
const uint32_t TRIANGLE_STRIDE = 3; const uint32_t TRIANGLE_STRIDE = 3;
int meshIndex = 0; int meshIndex = 0;
int validPartsFound = 0; int validPartsFound = 0;
foreach (const FBXMesh& mesh, geometry.meshes) { foreach (const HFMMesh& mesh, geometry.meshes) {
// find duplicate points // find duplicate points
int numDupes = 0; int numDupes = 0;
@ -354,7 +354,7 @@ bool vhacd::VHACDUtil::computeVHACD(FBXGeometry& geometry,
int partIndex = 0; int partIndex = 0;
std::vector<int> triangleIndices; std::vector<int> triangleIndices;
foreach (const FBXMeshPart &meshPart, mesh.parts) { foreach (const HFMMeshPart &meshPart, mesh.parts) {
triangleIndices.clear(); triangleIndices.clear();
getTrianglesInMeshPart(meshPart, triangleIndices); getTrianglesInMeshPart(meshPart, triangleIndices);
@ -421,7 +421,7 @@ bool vhacd::VHACDUtil::computeVHACD(FBXGeometry& geometry,
triangleIndices.clear(); triangleIndices.clear();
for (auto index : openParts) { for (auto index : openParts) {
const FBXMeshPart &meshPart = mesh.parts[index]; const HFMMeshPart &meshPart = mesh.parts[index];
getTrianglesInMeshPart(meshPart, triangleIndices); getTrianglesInMeshPart(meshPart, triangleIndices);
} }

View file

@ -27,16 +27,16 @@ namespace vhacd {
public: public:
void setVerbose(bool verbose) { _verbose = verbose; } void setVerbose(bool verbose) { _verbose = verbose; }
bool loadFBX(const QString filename, FBXGeometry& result); bool loadFBX(const QString filename, HFMGeometry& result);
void fattenMesh(const FBXMesh& mesh, const glm::mat4& gometryOffset, FBXMesh& result) const; void fattenMesh(const HFMMesh& mesh, const glm::mat4& gometryOffset, HFMMesh& result) const;
bool computeVHACD(FBXGeometry& geometry, bool computeVHACD(HFMGeometry& geometry,
VHACD::IVHACD::Parameters params, VHACD::IVHACD::Parameters params,
FBXGeometry& result, HFMGeometry& result,
float minimumMeshSize, float maximumMeshSize); float minimumMeshSize, float maximumMeshSize);
void getConvexResults(VHACD::IVHACD* convexifier, FBXMesh& resultMesh) const; void getConvexResults(VHACD::IVHACD* convexifier, HFMMesh& resultMesh) const;
~VHACDUtil(); ~VHACDUtil();
@ -55,6 +55,6 @@ namespace vhacd {
}; };
} }
AABox getAABoxForMeshPart(const FBXMeshPart &meshPart); AABox getAABoxForMeshPart(const HFMMeshPart &meshPart);
#endif //hifi_VHACDUtil_h #endif //hifi_VHACDUtil_h

View file

@ -36,7 +36,7 @@ QString formatFloat(double n) {
} }
bool VHACDUtilApp::writeOBJ(QString outFileName, FBXGeometry& geometry, bool outputCentimeters, int whichMeshPart) { bool VHACDUtilApp::writeOBJ(QString outFileName, HFMGeometry& geometry, bool outputCentimeters, int whichMeshPart) {
QFile file(outFileName); QFile file(outFileName);
if (!file.open(QIODevice::WriteOnly)) { if (!file.open(QIODevice::WriteOnly)) {
qWarning() << "unable to write to" << outFileName; qWarning() << "unable to write to" << outFileName;
@ -56,9 +56,9 @@ bool VHACDUtilApp::writeOBJ(QString outFileName, FBXGeometry& geometry, bool out
int vertexIndexOffset = 0; int vertexIndexOffset = 0;
foreach (const FBXMesh& mesh, geometry.meshes) { foreach (const HFMMesh& mesh, geometry.meshes) {
bool verticesHaveBeenOutput = false; bool verticesHaveBeenOutput = false;
foreach (const FBXMeshPart &meshPart, mesh.parts) { foreach (const HFMMeshPart &meshPart, mesh.parts) {
if (whichMeshPart >= 0 && nth != (unsigned int) whichMeshPart) { if (whichMeshPart >= 0 && nth != (unsigned int) whichMeshPart) {
nth++; nth++;
continue; continue;
@ -297,7 +297,7 @@ VHACDUtilApp::VHACDUtilApp(int argc, char* argv[]) :
} }
// load the mesh // load the mesh
FBXGeometry fbx; HFMGeometry fbx;
auto begin = std::chrono::high_resolution_clock::now(); auto begin = std::chrono::high_resolution_clock::now();
if (!vUtil.loadFBX(inputFilename, fbx)){ if (!vUtil.loadFBX(inputFilename, fbx)){
_returnCode = VHACD_RETURN_CODE_FAILURE_TO_READ; _returnCode = VHACD_RETURN_CODE_FAILURE_TO_READ;
@ -315,8 +315,8 @@ VHACDUtilApp::VHACDUtilApp(int argc, char* argv[]) :
QVector<QString> infileExtensions = {"fbx", "obj"}; QVector<QString> infileExtensions = {"fbx", "obj"};
QString baseFileName = fileNameWithoutExtension(outputFilename, infileExtensions); QString baseFileName = fileNameWithoutExtension(outputFilename, infileExtensions);
int count = 0; int count = 0;
foreach (const FBXMesh& mesh, fbx.meshes) { foreach (const HFMMesh& mesh, fbx.meshes) {
foreach (const FBXMeshPart &meshPart, mesh.parts) { foreach (const HFMMeshPart &meshPart, mesh.parts) {
QString outputFileName = baseFileName + "-" + QString::number(count) + ".obj"; QString outputFileName = baseFileName + "-" + QString::number(count) + ".obj";
writeOBJ(outputFileName, fbx, outputCentimeters, count); writeOBJ(outputFileName, fbx, outputCentimeters, count);
count++; count++;
@ -358,7 +358,7 @@ VHACDUtilApp::VHACDUtilApp(int argc, char* argv[]) :
} }
begin = std::chrono::high_resolution_clock::now(); begin = std::chrono::high_resolution_clock::now();
FBXGeometry result; HFMGeometry result;
bool success = vUtil.computeVHACD(fbx, params, result, minimumMeshSize, maximumMeshSize); bool success = vUtil.computeVHACD(fbx, params, result, minimumMeshSize, maximumMeshSize);
end = std::chrono::high_resolution_clock::now(); end = std::chrono::high_resolution_clock::now();
@ -377,9 +377,9 @@ VHACDUtilApp::VHACDUtilApp(int argc, char* argv[]) :
int totalVertices = 0; int totalVertices = 0;
int totalTriangles = 0; int totalTriangles = 0;
foreach (const FBXMesh& mesh, result.meshes) { foreach (const HFMMesh& mesh, result.meshes) {
totalVertices += mesh.vertices.size(); totalVertices += mesh.vertices.size();
foreach (const FBXMeshPart &meshPart, mesh.parts) { foreach (const HFMMeshPart &meshPart, mesh.parts) {
totalTriangles += meshPart.triangleIndices.size() / 3; totalTriangles += meshPart.triangleIndices.size() / 3;
// each quad was made into two triangles // each quad was made into two triangles
totalTriangles += 2 * meshPart.quadIndices.size() / 4; totalTriangles += 2 * meshPart.quadIndices.size() / 4;
@ -398,17 +398,17 @@ VHACDUtilApp::VHACDUtilApp(int argc, char* argv[]) :
} }
if (fattenFaces) { if (fattenFaces) {
FBXGeometry newFbx; HFMGeometry newFbx;
FBXMesh result; HFMMesh result;
// count the mesh-parts // count the mesh-parts
unsigned int meshCount = 0; unsigned int meshCount = 0;
foreach (const FBXMesh& mesh, fbx.meshes) { foreach (const HFMMesh& mesh, fbx.meshes) {
meshCount += mesh.parts.size(); meshCount += mesh.parts.size();
} }
result.modelTransform = glm::mat4(); // Identity matrix result.modelTransform = glm::mat4(); // Identity matrix
foreach (const FBXMesh& mesh, fbx.meshes) { foreach (const HFMMesh& mesh, fbx.meshes) {
vUtil.fattenMesh(mesh, fbx.offset, result); vUtil.fattenMesh(mesh, fbx.offset, result);
} }

View file

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