mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
Re-name FBXGeometry to HFMGeometry and do the same for related classes
This commit is contained in:
parent
e01401294f
commit
becee7f010
52 changed files with 578 additions and 578 deletions
|
@ -69,10 +69,10 @@ void ScriptableAvatar::setSkeletonModelURL(const QUrl& 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 rotationMat = glm::mat4_cast(fbxJoint.preRotation * rotation * fbxJoint.postRotation);
|
||||
glm::mat4 finalMat = translationMat * fbxJoint.preTransform * rotationMat * fbxJoint.postTransform;
|
||||
glm::mat4 rotationMat = glm::mat4_cast(joint.preRotation * rotation * joint.postRotation);
|
||||
glm::mat4 finalMat = translationMat * joint.preTransform * rotationMat * joint.postTransform;
|
||||
return AnimPose(finalMat);
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,7 @@ void ScriptableAvatar::update(float deltatime) {
|
|||
}
|
||||
_animationDetails.currentFrame = currentFrame;
|
||||
|
||||
const QVector<FBXJoint>& modelJoints = _bind->getGeometry().joints;
|
||||
const QVector<HFMJoint>& modelJoints = _bind->getGeometry().joints;
|
||||
QStringList animationJointNames = _animation->getJointNames();
|
||||
|
||||
const int nJoints = modelJoints.size();
|
||||
|
@ -102,8 +102,8 @@ void ScriptableAvatar::update(float deltatime) {
|
|||
}
|
||||
|
||||
const int frameCount = _animation->getFrames().size();
|
||||
const FBXAnimationFrame& floorFrame = _animation->getFrames().at((int)glm::floor(currentFrame) % frameCount);
|
||||
const FBXAnimationFrame& ceilFrame = _animation->getFrames().at((int)glm::ceil(currentFrame) % frameCount);
|
||||
const HFMAnimationFrame& floorFrame = _animation->getFrames().at((int)glm::floor(currentFrame) % frameCount);
|
||||
const HFMAnimationFrame& ceilFrame = _animation->getFrames().at((int)glm::ceil(currentFrame) % frameCount);
|
||||
const float frameFraction = glm::fract(currentFrame);
|
||||
std::vector<AnimPose> poses = _animSkeleton->getRelativeDefaultPoses();
|
||||
|
||||
|
|
|
@ -235,7 +235,7 @@ bool ModelPackager::zipModel() {
|
|||
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;
|
||||
|
||||
|
@ -370,7 +370,7 @@ void ModelPackager::populateBasicMapping(QVariantHash& mapping, QString filename
|
|||
|
||||
void ModelPackager::listTextures() {
|
||||
_textures.clear();
|
||||
foreach (const FBXMaterial mat, _geometry->materials) {
|
||||
foreach (const HFMMaterial mat, _geometry->materials) {
|
||||
if (!mat.albedoTexture.filename.isEmpty() && mat.albedoTexture.content.isEmpty() &&
|
||||
!_textures.contains(mat.albedoTexture.filename)) {
|
||||
_textures << mat.albedoTexture.filename;
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include "ui/ModelsBrowser.h"
|
||||
|
||||
class FBXGeometry;
|
||||
class HFMGeometry;
|
||||
|
||||
class ModelPackager : public QObject {
|
||||
public:
|
||||
|
@ -32,7 +32,7 @@ private:
|
|||
bool editProperties();
|
||||
bool zipModel();
|
||||
|
||||
void populateBasicMapping(QVariantHash& mapping, QString filename, const FBXGeometry& geometry);
|
||||
void populateBasicMapping(QVariantHash& mapping, QString filename, const HFMGeometry& geometry);
|
||||
|
||||
void listTextures();
|
||||
bool copyTextures(const QString& oldDir, const QDir& newDir);
|
||||
|
@ -44,7 +44,7 @@ private:
|
|||
QString _scriptDir;
|
||||
|
||||
QVariantHash _mapping;
|
||||
std::unique_ptr<FBXGeometry> _geometry;
|
||||
std::unique_ptr<HFMGeometry> _geometry;
|
||||
QStringList _textures;
|
||||
QStringList _scripts;
|
||||
};
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
|
||||
ModelPropertiesDialog::ModelPropertiesDialog(FSTReader::ModelType modelType, const QVariantHash& originalMapping,
|
||||
const QString& basePath, const FBXGeometry& geometry) :
|
||||
const QString& basePath, const HFMGeometry& geometry) :
|
||||
_modelType(modelType),
|
||||
_originalMapping(originalMapping),
|
||||
_basePath(basePath),
|
||||
|
@ -249,7 +249,7 @@ QComboBox* ModelPropertiesDialog::createJointBox(bool withNone) const {
|
|||
if (withNone) {
|
||||
box->addItem("(none)");
|
||||
}
|
||||
foreach (const FBXJoint& joint, _geometry.joints) {
|
||||
foreach (const HFMJoint& joint, _geometry.joints) {
|
||||
if (joint.isSkeletonJoint || !_geometry.hasSkeletonJoints) {
|
||||
box->addItem(joint.name);
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ class ModelPropertiesDialog : public QDialog {
|
|||
|
||||
public:
|
||||
ModelPropertiesDialog(FSTReader::ModelType modelType, const QVariantHash& originalMapping,
|
||||
const QString& basePath, const FBXGeometry& geometry);
|
||||
const QString& basePath, const HFMGeometry& geometry);
|
||||
|
||||
QVariantHash getMapping() const;
|
||||
|
||||
|
@ -50,7 +50,7 @@ private:
|
|||
FSTReader::ModelType _modelType;
|
||||
QVariantHash _originalMapping;
|
||||
QString _basePath;
|
||||
FBXGeometry _geometry;
|
||||
HFMGeometry _geometry;
|
||||
QLineEdit* _name = nullptr;
|
||||
QPushButton* _textureDirectory = nullptr;
|
||||
QPushButton* _scriptDirectory = nullptr;
|
||||
|
|
|
@ -155,7 +155,7 @@ MyAvatar::MyAvatar(QThread* thread) :
|
|||
});
|
||||
connect(_skeletonModel.get(), &Model::rigReady, this, [this]() {
|
||||
if (_shouldLoadScripts) {
|
||||
auto geometry = getSkeletonModel()->getFBXGeometry();
|
||||
auto geometry = getSkeletonModel()->getHFMGeometry();
|
||||
qApp->loadAvatarScripts(geometry.scripts);
|
||||
_shouldLoadScripts = false;
|
||||
}
|
||||
|
@ -2429,10 +2429,10 @@ void MyAvatar::attachmentDataToEntityProperties(const AttachmentData& data, Enti
|
|||
void MyAvatar::initHeadBones() {
|
||||
int neckJointIndex = -1;
|
||||
if (_skeletonModel->isLoaded()) {
|
||||
neckJointIndex = _skeletonModel->getFBXGeometry().neckJointIndex;
|
||||
neckJointIndex = _skeletonModel->getHFMGeometry().neckJointIndex;
|
||||
}
|
||||
if (neckJointIndex == -1) {
|
||||
neckJointIndex = (_skeletonModel->getFBXGeometry().headJointIndex - 1);
|
||||
neckJointIndex = (_skeletonModel->getHFMGeometry().headJointIndex - 1);
|
||||
if (neckJointIndex < 0) {
|
||||
// return if the head is not even there. can't cauterize!!
|
||||
return;
|
||||
|
@ -2443,7 +2443,7 @@ void MyAvatar::initHeadBones() {
|
|||
q.push(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) {
|
||||
int jointIndex = q.front();
|
||||
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()) {
|
||||
const Rig& rig = _skeletonModel->getRig();
|
||||
const FBXGeometry& geometry = _skeletonModel->getFBXGeometry();
|
||||
const HFMGeometry& geometry = _skeletonModel->getHFMGeometry();
|
||||
for (int i = 0; i < rig.getJointStateCount(); i++) {
|
||||
AnimPose jointPose;
|
||||
rig.getAbsoluteJointPoseInRigFrame(i, jointPose);
|
||||
const FBXJointShapeInfo& shapeInfo = geometry.joints[i].shapeInfo;
|
||||
const HFMJointShapeInfo& shapeInfo = geometry.joints[i].shapeInfo;
|
||||
const AnimPose pose = rigToWorldPose * jointPose;
|
||||
for (size_t j = 0; j < shapeInfo.debugLines.size() / 2; j++) {
|
||||
glm::vec3 pointA = pose.xformPoint(shapeInfo.debugLines[2 * j]);
|
||||
|
@ -4012,7 +4012,7 @@ float MyAvatar::getSitStandStateChange() const {
|
|||
}
|
||||
|
||||
QVector<QString> MyAvatar::getScriptUrls() {
|
||||
QVector<QString> scripts = _skeletonModel->isLoaded() ? _skeletonModel->getFBXGeometry().scripts : QVector<QString>();
|
||||
QVector<QString> scripts = _skeletonModel->isLoaded() ? _skeletonModel->getHFMGeometry().scripts : QVector<QString>();
|
||||
return scripts;
|
||||
}
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ static AnimPose computeHipsInSensorFrame(MyAvatar* myAvatar, bool isFlying) {
|
|||
|
||||
// Called within Model::simulate call, below.
|
||||
void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
|
||||
const FBXGeometry& geometry = getFBXGeometry();
|
||||
const HFMGeometry& geometry = getHFMGeometry();
|
||||
|
||||
Head* head = _owningAvatar->getHead();
|
||||
|
||||
|
|
|
@ -131,7 +131,7 @@ void CollisionPick::computeShapeInfo(const CollisionRegion& pick, ShapeInfo& sha
|
|||
// should never fall in here when collision model not fully loaded
|
||||
// TODO: assert that all geometries exist and are loaded
|
||||
//assert(_model && _model->isLoaded() && _compoundShapeResource && _compoundShapeResource->isLoaded());
|
||||
const FBXGeometry& collisionGeometry = resource->getFBXGeometry();
|
||||
const HFMGeometry& collisionGeometry = resource->getHFMGeometry();
|
||||
|
||||
ShapeInfo::PointCollection& pointCollection = shapeInfo.getPointCollection();
|
||||
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
|
||||
// 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
|
||||
foreach (const FBXMeshPart &meshPart, mesh.parts) {
|
||||
foreach (const HFMMeshPart &meshPart, mesh.parts) {
|
||||
pointCollection.push_back(QVector<glm::vec3>());
|
||||
ShapeInfo::PointList& pointsInPart = pointCollection[i];
|
||||
|
||||
// run through all the triangles and (uniquely) add each point to the hull
|
||||
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);
|
||||
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
|
||||
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);
|
||||
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
|
||||
// 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
|
||||
for (int32_t i = 0; i < pointCollection.size(); i++) {
|
||||
for (int32_t j = 0; j < pointCollection[i].size(); j++) {
|
||||
|
@ -216,11 +216,11 @@ void CollisionPick::computeShapeInfo(const CollisionRegion& pick, ShapeInfo& sha
|
|||
}
|
||||
shapeInfo.setParams(type, dimensions, resource->getURL().toString());
|
||||
} else if (type >= SHAPE_TYPE_SIMPLE_HULL && type <= SHAPE_TYPE_STATIC_MESH) {
|
||||
const FBXGeometry& fbxGeometry = resource->getFBXGeometry();
|
||||
int numFbxMeshes = fbxGeometry.meshes.size();
|
||||
const HFMGeometry& hfmGeometry = resource->getHFMGeometry();
|
||||
int numHFMMeshes = hfmGeometry.meshes.size();
|
||||
int totalNumVertices = 0;
|
||||
for (int i = 0; i < numFbxMeshes; i++) {
|
||||
const FBXMesh& mesh = fbxGeometry.meshes.at(i);
|
||||
for (int i = 0; i < numHFMMeshes; i++) {
|
||||
const HFMMesh& mesh = hfmGeometry.meshes.at(i);
|
||||
totalNumVertices += mesh.vertices.size();
|
||||
}
|
||||
const int32_t MAX_VERTICES_PER_STATIC_MESH = 1e6;
|
||||
|
@ -230,7 +230,7 @@ void CollisionPick::computeShapeInfo(const CollisionRegion& pick, ShapeInfo& sha
|
|||
return;
|
||||
}
|
||||
|
||||
auto& meshes = resource->getFBXGeometry().meshes;
|
||||
auto& meshes = resource->getHFMGeometry().meshes;
|
||||
int32_t numMeshes = (int32_t)(meshes.size());
|
||||
|
||||
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) {
|
||||
// copy into triangleIndices
|
||||
size_t triangleIndicesCount = 0;
|
||||
for (const FBXMeshPart& meshPart : mesh.parts) {
|
||||
for (const HFMMeshPart& meshPart : mesh.parts) {
|
||||
triangleIndicesCount += meshPart.triangleIndices.count();
|
||||
}
|
||||
triangleIndices.reserve((int)triangleIndicesCount);
|
||||
|
||||
for (const FBXMeshPart& meshPart : mesh.parts) {
|
||||
for (const HFMMeshPart& meshPart : mesh.parts) {
|
||||
const int* indexItr = meshPart.triangleIndices.cbegin();
|
||||
while (indexItr != meshPart.triangleIndices.cend()) {
|
||||
triangleIndices.push_back(*indexItr);
|
||||
|
@ -299,11 +299,11 @@ void CollisionPick::computeShapeInfo(const CollisionRegion& pick, ShapeInfo& sha
|
|||
}
|
||||
} else if (type == SHAPE_TYPE_SIMPLE_COMPOUND) {
|
||||
// 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
|
||||
std::set<int32_t> uniqueIndices;
|
||||
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);
|
||||
numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXReader
|
||||
|
||||
|
|
|
@ -446,7 +446,7 @@ QVariant ModelOverlay::getProperty(const QString& property) {
|
|||
|
||||
if (property == "jointNames") {
|
||||
if (_model && _model->isActive()) {
|
||||
// note: going through Rig because Model::getJointNames() (which proxies to FBXGeometry) was always empty
|
||||
// note: going through Rig because Model::getJointNames() (which proxies to HFMGeometry) was always empty
|
||||
const Rig* rig = &(_model->getRig());
|
||||
return mapJoints<QStringList, QString>([rig](int jointIndex) -> QString {
|
||||
return rig->nameOfJoint(jointIndex);
|
||||
|
@ -574,7 +574,7 @@ void ModelOverlay::animate() {
|
|||
|
||||
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();
|
||||
if (frameCount <= 0) {
|
||||
return;
|
||||
|
@ -606,10 +606,10 @@ void ModelOverlay::animate() {
|
|||
}
|
||||
|
||||
QStringList animationJointNames = _animation->getGeometry().getJointNames();
|
||||
auto& fbxJoints = _animation->getGeometry().joints;
|
||||
auto& hfmJoints = _animation->getGeometry().joints;
|
||||
|
||||
auto& originalFbxJoints = _model->getFBXGeometry().joints;
|
||||
auto& originalFbxIndices = _model->getFBXGeometry().jointIndices;
|
||||
auto& originalHFMJoints = _model->getHFMGeometry().joints;
|
||||
auto& originalFbxIndices = _model->getHFMGeometry().jointIndices;
|
||||
|
||||
const QVector<glm::quat>& rotations = frames[_lastKnownCurrentFrame].rotations;
|
||||
const QVector<glm::vec3>& translations = frames[_lastKnownCurrentFrame].translations;
|
||||
|
@ -626,23 +626,23 @@ void ModelOverlay::animate() {
|
|||
translationMat = glm::translate(translations[index]);
|
||||
}
|
||||
} else if (index < animationJointNames.size()) {
|
||||
QString jointName = fbxJoints[index].name;
|
||||
QString jointName = hfmJoints[index].name;
|
||||
|
||||
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.
|
||||
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;
|
||||
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 {
|
||||
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 *
|
||||
rotationMat * fbxJoints[index].postTransform);
|
||||
glm::mat4 finalMat = (translationMat * hfmJoints[index].preTransform *
|
||||
rotationMat * hfmJoints[index].postTransform);
|
||||
auto& jointData = jointsData[j];
|
||||
jointData.translation = extractTranslation(finalMat);
|
||||
jointData.translationIsDefaultPose = false;
|
||||
|
|
|
@ -101,7 +101,7 @@ void AnimClip::copyFromNetworkAnim() {
|
|||
|
||||
// build a mapping from animation joint indices to skeleton joint indices.
|
||||
// by matching joints with the same name.
|
||||
const FBXGeometry& geom = _networkAnim->getGeometry();
|
||||
const HFMGeometry& geom = _networkAnim->getGeometry();
|
||||
AnimSkeleton animSkeleton(geom);
|
||||
const auto animJointCount = animSkeleton.getNumJoints();
|
||||
const auto skeletonJointCount = _skeleton->getNumJoints();
|
||||
|
@ -120,7 +120,7 @@ void AnimClip::copyFromNetworkAnim() {
|
|||
|
||||
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
|
||||
// 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++) {
|
||||
int skeletonJoint = jointMap[animJoint];
|
||||
|
||||
const glm::vec3& fbxAnimTrans = fbxAnimFrame.translations[animJoint];
|
||||
const glm::quat& fbxAnimRot = fbxAnimFrame.rotations[animJoint];
|
||||
const glm::vec3& hfmAnimTrans = hfmAnimFrame.translations[animJoint];
|
||||
const glm::quat& hfmAnimRot = hfmAnimFrame.rotations[animJoint];
|
||||
|
||||
// skip joints that are in the animation but not in the skeleton.
|
||||
if (skeletonJoint >= 0 && skeletonJoint < skeletonJointCount) {
|
||||
|
@ -146,19 +146,19 @@ void AnimClip::copyFromNetworkAnim() {
|
|||
preRot.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
|
||||
// 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);
|
||||
float boneLengthScale = 1.0f;
|
||||
const float EPSILON = 0.0001f;
|
||||
if (fabsf(glm::length(fbxZeroTrans)) > EPSILON) {
|
||||
boneLengthScale = glm::length(relDefaultPose.trans()) / glm::length(fbxZeroTrans);
|
||||
if (fabsf(glm::length(hfmZeroTrans)) > EPSILON) {
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -16,17 +16,17 @@
|
|||
|
||||
#include "AnimationLogging.h"
|
||||
|
||||
AnimSkeleton::AnimSkeleton(const FBXGeometry& fbxGeometry) {
|
||||
AnimSkeleton::AnimSkeleton(const HFMGeometry& geometry) {
|
||||
// convert to std::vector of joints
|
||||
std::vector<FBXJoint> joints;
|
||||
joints.reserve(fbxGeometry.joints.size());
|
||||
for (auto& joint : fbxGeometry.joints) {
|
||||
std::vector<HFMJoint> joints;
|
||||
joints.reserve(geometry.joints.size());
|
||||
for (auto& joint : geometry.joints) {
|
||||
joints.push_back(joint);
|
||||
}
|
||||
buildSkeletonFromJoints(joints);
|
||||
}
|
||||
|
||||
AnimSkeleton::AnimSkeleton(const std::vector<FBXJoint>& joints) {
|
||||
AnimSkeleton::AnimSkeleton(const std::vector<HFMJoint>& 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;
|
||||
_jointsSize = (int)joints.size();
|
||||
// build a cache of bind poses
|
||||
|
@ -177,7 +177,7 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector<FBXJoint>& joints)
|
|||
_relativePreRotationPoses.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++) {
|
||||
|
||||
// build pre and post transforms
|
||||
|
@ -240,7 +240,7 @@ void AnimSkeleton::dump(bool verbose) const {
|
|||
qCDebug(animation) << " absDefaultPose =" << getAbsoluteDefaultPose(i);
|
||||
qCDebug(animation) << " relDefaultPose =" << getRelativeDefaultPose(i);
|
||||
if (verbose) {
|
||||
qCDebug(animation) << " fbxJoint =";
|
||||
qCDebug(animation) << " hfmJoint =";
|
||||
qCDebug(animation) << " isFree =" << _joints[i].isFree;
|
||||
qCDebug(animation) << " freeLineage =" << _joints[i].freeLineage;
|
||||
qCDebug(animation) << " parentIndex =" << _joints[i].parentIndex;
|
||||
|
|
|
@ -23,8 +23,8 @@ public:
|
|||
using Pointer = std::shared_ptr<AnimSkeleton>;
|
||||
using ConstPointer = std::shared_ptr<const AnimSkeleton>;
|
||||
|
||||
explicit AnimSkeleton(const FBXGeometry& fbxGeometry);
|
||||
explicit AnimSkeleton(const std::vector<FBXJoint>& joints);
|
||||
explicit AnimSkeleton(const HFMGeometry& geometry);
|
||||
explicit AnimSkeleton(const std::vector<HFMJoint>& joints);
|
||||
int nameToJointIndex(const QString& jointName) const;
|
||||
const QString& getJointName(int jointIndex) const;
|
||||
int getNumJoints() const;
|
||||
|
@ -64,9 +64,9 @@ public:
|
|||
std::vector<int> lookUpJointIndices(const std::vector<QString>& jointNames) const;
|
||||
|
||||
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 };
|
||||
AnimPoseVec _relativeDefaultPoses;
|
||||
AnimPoseVec _absoluteDefaultPoses;
|
||||
|
|
|
@ -69,7 +69,7 @@ void AnimationReader::run() {
|
|||
|
||||
if (urlValid) {
|
||||
// Parse the FBX directly from the QNetworkReply
|
||||
FBXGeometry::Pointer fbxgeo;
|
||||
HFMGeometry::Pointer fbxgeo;
|
||||
if (_url.path().toLower().endsWith(".fbx")) {
|
||||
fbxgeo.reset(readFBX(_data, QVariantHash(), _url.path()));
|
||||
} else {
|
||||
|
@ -100,40 +100,40 @@ QStringList Animation::getJointNames() const {
|
|||
}
|
||||
QStringList names;
|
||||
if (_geometry) {
|
||||
foreach (const FBXJoint& joint, _geometry->joints) {
|
||||
foreach (const HFMJoint& joint, _geometry->joints) {
|
||||
names.append(joint.name);
|
||||
}
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
QVector<FBXAnimationFrame> Animation::getFrames() const {
|
||||
QVector<HFMAnimationFrame> Animation::getFrames() const {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QVector<FBXAnimationFrame> result;
|
||||
QVector<HFMAnimationFrame> result;
|
||||
BLOCKING_INVOKE_METHOD(const_cast<Animation*>(this), "getFrames",
|
||||
Q_RETURN_ARG(QVector<FBXAnimationFrame>, result));
|
||||
Q_RETURN_ARG(QVector<HFMAnimationFrame>, result));
|
||||
return result;
|
||||
}
|
||||
if (_geometry) {
|
||||
return _geometry->animationFrames;
|
||||
} else {
|
||||
return QVector<FBXAnimationFrame>();
|
||||
return QVector<HFMAnimationFrame>();
|
||||
}
|
||||
}
|
||||
|
||||
const QVector<FBXAnimationFrame>& Animation::getFramesReference() const {
|
||||
const QVector<HFMAnimationFrame>& Animation::getFramesReference() const {
|
||||
return _geometry->animationFrames;
|
||||
}
|
||||
|
||||
void Animation::downloadFinished(const QByteArray& data) {
|
||||
// parse the animation/fbx file on a background thread.
|
||||
AnimationReader* animationReader = new AnimationReader(_url, data);
|
||||
connect(animationReader, SIGNAL(onSuccess(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)));
|
||||
QThreadPool::globalInstance()->start(animationReader);
|
||||
}
|
||||
|
||||
void Animation::animationParseSuccess(FBXGeometry::Pointer geometry) {
|
||||
void Animation::animationParseSuccess(HFMGeometry::Pointer geometry) {
|
||||
|
||||
qCDebug(animation) << "Animation parse success" << _url.toDisplayString();
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ public:
|
|||
|
||||
QString getType() const override { return "Animation"; }
|
||||
|
||||
const FBXGeometry& getGeometry() const { return *_geometry; }
|
||||
const HFMGeometry& getGeometry() const { return *_geometry; }
|
||||
|
||||
virtual bool isLoaded() const override;
|
||||
|
||||
|
@ -80,20 +80,20 @@ public:
|
|||
* @function AnimationObject.getFrames
|
||||
* @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:
|
||||
virtual void downloadFinished(const QByteArray& data) override;
|
||||
|
||||
protected slots:
|
||||
void animationParseSuccess(FBXGeometry::Pointer geometry);
|
||||
void animationParseSuccess(HFMGeometry::Pointer geometry);
|
||||
void animationParseError(int error, QString str);
|
||||
|
||||
private:
|
||||
|
||||
FBXGeometry::Pointer _geometry;
|
||||
HFMGeometry::Pointer _geometry;
|
||||
};
|
||||
|
||||
/// Reads geometry in a worker thread.
|
||||
|
@ -105,7 +105,7 @@ public:
|
|||
virtual void run() override;
|
||||
|
||||
signals:
|
||||
void onSuccess(FBXGeometry::Pointer geometry);
|
||||
void onSuccess(HFMGeometry::Pointer geometry);
|
||||
void onError(int error, QString str);
|
||||
|
||||
private:
|
||||
|
|
|
@ -19,17 +19,17 @@ QStringList AnimationObject::getJointNames() const {
|
|||
return qscriptvalue_cast<AnimationPointer>(thisObject())->getJointNames();
|
||||
}
|
||||
|
||||
QVector<FBXAnimationFrame> AnimationObject::getFrames() const {
|
||||
QVector<HFMAnimationFrame> AnimationObject::getFrames() const {
|
||||
return qscriptvalue_cast<AnimationPointer>(thisObject())->getFrames();
|
||||
}
|
||||
|
||||
QVector<glm::quat> AnimationFrameObject::getRotations() const {
|
||||
return qscriptvalue_cast<FBXAnimationFrame>(thisObject()).rotations;
|
||||
return qscriptvalue_cast<HFMAnimationFrame>(thisObject()).rotations;
|
||||
}
|
||||
|
||||
void registerAnimationTypes(QScriptEngine* engine) {
|
||||
qScriptRegisterSequenceMetaType<QVector<FBXAnimationFrame> >(engine);
|
||||
engine->setDefaultPrototype(qMetaTypeId<FBXAnimationFrame>(), engine->newQObject(
|
||||
qScriptRegisterSequenceMetaType<QVector<HFMAnimationFrame> >(engine);
|
||||
engine->setDefaultPrototype(qMetaTypeId<HFMAnimationFrame>(), engine->newQObject(
|
||||
new AnimationFrameObject(), QScriptEngine::ScriptOwnership));
|
||||
engine->setDefaultPrototype(qMetaTypeId<AnimationPointer>(), engine->newQObject(
|
||||
new AnimationObject(), QScriptEngine::ScriptOwnership));
|
||||
|
|
|
@ -23,13 +23,13 @@ class QScriptEngine;
|
|||
class AnimationObject : public QObject, protected QScriptable {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QStringList jointNames READ getJointNames)
|
||||
Q_PROPERTY(QVector<FBXAnimationFrame> frames READ getFrames)
|
||||
Q_PROPERTY(QVector<HFMAnimationFrame> frames READ getFrames)
|
||||
|
||||
public:
|
||||
|
||||
Q_INVOKABLE QStringList getJointNames() const;
|
||||
|
||||
Q_INVOKABLE QVector<FBXAnimationFrame> getFrames() const;
|
||||
Q_INVOKABLE QVector<HFMAnimationFrame> getFrames() const;
|
||||
};
|
||||
|
||||
/// Scriptable wrapper for animation frames.
|
||||
|
|
|
@ -260,7 +260,7 @@ void Rig::destroyAnimGraph() {
|
|||
_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);
|
||||
_invGeometryOffset = _geometryOffset.inverse();
|
||||
_geometryToRigTransform = modelOffset * geometry.offset;
|
||||
|
@ -307,7 +307,7 @@ void Rig::initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOff
|
|||
_rightEyeJointChildren = _animSkeleton->getChildrenOfJoint(geometry.rightEyeJointIndex);
|
||||
}
|
||||
|
||||
void Rig::reset(const FBXGeometry& geometry) {
|
||||
void Rig::reset(const HFMGeometry& geometry) {
|
||||
_geometryOffset = AnimPose(geometry.offset);
|
||||
_invGeometryOffset = _geometryOffset.inverse();
|
||||
_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.
|
||||
// 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.
|
||||
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.
|
||||
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,
|
||||
const FBXJointShapeInfo& spine1ShapeInfo, const FBXJointShapeInfo& spine2ShapeInfo) const {
|
||||
glm::vec3 Rig::deflectHandFromTorso(const glm::vec3& handPosition, const HFMJointShapeInfo& hipsShapeInfo, const HFMJointShapeInfo& spineShapeInfo,
|
||||
const HFMJointShapeInfo& spine1ShapeInfo, const HFMJointShapeInfo& spine2ShapeInfo) const {
|
||||
glm::vec3 position = handPosition;
|
||||
glm::vec3 displacement;
|
||||
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,
|
||||
bool leftArmEnabled, bool rightArmEnabled, bool headEnabled, float dt,
|
||||
const AnimPose& leftHandPose, const AnimPose& rightHandPose,
|
||||
const FBXJointShapeInfo& hipsShapeInfo, const FBXJointShapeInfo& spineShapeInfo,
|
||||
const FBXJointShapeInfo& spine1ShapeInfo, const FBXJointShapeInfo& spine2ShapeInfo,
|
||||
const HFMJointShapeInfo& hipsShapeInfo, const HFMJointShapeInfo& spineShapeInfo,
|
||||
const HFMJointShapeInfo& spine1ShapeInfo, const HFMJointShapeInfo& spine2ShapeInfo,
|
||||
const glm::mat4& rigToSensorMatrix, const glm::mat4& sensorToRigMatrix) {
|
||||
|
||||
const bool ENABLE_POLE_VECTORS = true;
|
||||
|
@ -2008,7 +2008,7 @@ void Rig::computeExternalPoses(const glm::mat4& modelOffsetMat) {
|
|||
}
|
||||
|
||||
void Rig::computeAvatarBoundingCapsule(
|
||||
const FBXGeometry& geometry,
|
||||
const HFMGeometry& geometry,
|
||||
float& radiusOut,
|
||||
float& heightOut,
|
||||
glm::vec3& localOffsetOut) const {
|
||||
|
@ -2041,7 +2041,7 @@ void Rig::computeAvatarBoundingCapsule(
|
|||
// from the head to the hips when computing the rest of the bounding capsule.
|
||||
int index = indexOfJoint("Head");
|
||||
while (index != -1) {
|
||||
const FBXJointShapeInfo& shapeInfo = geometry.joints.at(index).shapeInfo;
|
||||
const HFMJointShapeInfo& shapeInfo = geometry.joints.at(index).shapeInfo;
|
||||
AnimPose pose = _animSkeleton->getAbsoluteDefaultPose(index);
|
||||
if (shapeInfo.points.size() > 0) {
|
||||
for (auto& point : shapeInfo.points) {
|
||||
|
|
|
@ -86,10 +86,10 @@ public:
|
|||
AnimPose secondaryControllerPoses[NumSecondaryControllerTypes]; // rig space
|
||||
uint8_t secondaryControllerFlags[NumSecondaryControllerTypes];
|
||||
bool isTalking;
|
||||
FBXJointShapeInfo hipsShapeInfo;
|
||||
FBXJointShapeInfo spineShapeInfo;
|
||||
FBXJointShapeInfo spine1ShapeInfo;
|
||||
FBXJointShapeInfo spine2ShapeInfo;
|
||||
HFMJointShapeInfo hipsShapeInfo;
|
||||
HFMJointShapeInfo spineShapeInfo;
|
||||
HFMJointShapeInfo spine1ShapeInfo;
|
||||
HFMJointShapeInfo spine2ShapeInfo;
|
||||
};
|
||||
|
||||
struct EyeParameters {
|
||||
|
@ -122,8 +122,8 @@ public:
|
|||
void overrideRoleAnimation(const QString& role, const QString& url, float fps, bool loop, float firstFrame, float lastFrame);
|
||||
void restoreRoleAnimation(const QString& role);
|
||||
|
||||
void initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOffset);
|
||||
void reset(const FBXGeometry& geometry);
|
||||
void initJointStates(const HFMGeometry& geometry, const glm::mat4& modelOffset);
|
||||
void reset(const HFMGeometry& geometry);
|
||||
bool jointStatesEmpty();
|
||||
int getJointStateCount() const;
|
||||
int indexOfJoint(const QString& jointName) const;
|
||||
|
@ -210,7 +210,7 @@ public:
|
|||
void copyJointsFromJointData(const QVector<JointData>& jointDataVec);
|
||||
void computeExternalPoses(const glm::mat4& modelOffsetMat);
|
||||
|
||||
void computeAvatarBoundingCapsule(const 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 setEnableAnimations(bool enable);
|
||||
|
@ -245,8 +245,8 @@ protected:
|
|||
void updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnabled, bool hipsEstimated,
|
||||
bool leftArmEnabled, bool rightArmEnabled, bool headEnabled, float dt,
|
||||
const AnimPose& leftHandPose, const AnimPose& rightHandPose,
|
||||
const FBXJointShapeInfo& hipsShapeInfo, const FBXJointShapeInfo& spineShapeInfo,
|
||||
const FBXJointShapeInfo& spine1ShapeInfo, const FBXJointShapeInfo& spine2ShapeInfo,
|
||||
const HFMJointShapeInfo& hipsShapeInfo, const HFMJointShapeInfo& spineShapeInfo,
|
||||
const HFMJointShapeInfo& spine1ShapeInfo, const HFMJointShapeInfo& spine2ShapeInfo,
|
||||
const glm::mat4& rigToSensorMatrix, const glm::mat4& sensorToRigMatrix);
|
||||
void updateFeet(bool leftFootEnabled, bool rightFootEnabled, bool headEnabled,
|
||||
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;
|
||||
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,
|
||||
const FBXJointShapeInfo& spine1ShapeInfo, const FBXJointShapeInfo& spine2ShapeInfo) const;
|
||||
glm::vec3 deflectHandFromTorso(const glm::vec3& handPosition, const HFMJointShapeInfo& hipsShapeInfo, const HFMJointShapeInfo& spineShapeInfo,
|
||||
const HFMJointShapeInfo& spine1ShapeInfo, const HFMJointShapeInfo& spine2ShapeInfo) const;
|
||||
|
||||
|
||||
AnimPose _modelOffset; // model to rig space
|
||||
|
|
|
@ -1311,7 +1311,7 @@ glm::quat Avatar::getAbsoluteJointRotationInObjectFrame(int index) const {
|
|||
case CAMERA_MATRIX_INDEX: {
|
||||
glm::quat rotation;
|
||||
if (_skeletonModel && _skeletonModel->isActive()) {
|
||||
int headJointIndex = _skeletonModel->getFBXGeometry().headJointIndex;
|
||||
int headJointIndex = _skeletonModel->getHFMGeometry().headJointIndex;
|
||||
if (headJointIndex >= 0) {
|
||||
_skeletonModel->getAbsoluteJointRotationInRigFrame(headJointIndex, rotation);
|
||||
}
|
||||
|
@ -1360,7 +1360,7 @@ glm::vec3 Avatar::getAbsoluteJointTranslationInObjectFrame(int index) const {
|
|||
case CAMERA_MATRIX_INDEX: {
|
||||
glm::vec3 translation;
|
||||
if (_skeletonModel && _skeletonModel->isActive()) {
|
||||
int headJointIndex = _skeletonModel->getFBXGeometry().headJointIndex;
|
||||
int headJointIndex = _skeletonModel->getHFMGeometry().headJointIndex;
|
||||
if (headJointIndex >= 0) {
|
||||
_skeletonModel->getAbsoluteJointTranslationInRigFrame(headJointIndex, translation);
|
||||
}
|
||||
|
@ -1416,7 +1416,7 @@ void Avatar::withValidJointIndicesCache(std::function<void()> const& worker) con
|
|||
if (!_modelJointsCached) {
|
||||
_modelJointIndicesCache.clear();
|
||||
if (_skeletonModel && _skeletonModel->isActive()) {
|
||||
_modelJointIndicesCache = _skeletonModel->getFBXGeometry().jointIndices;
|
||||
_modelJointIndicesCache = _skeletonModel->getHFMGeometry().jointIndices;
|
||||
_modelJointsCached = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ void SkeletonModel::setTextures(const QVariantMap& textures) {
|
|||
}
|
||||
|
||||
void SkeletonModel::initJointStates() {
|
||||
const FBXGeometry& geometry = getFBXGeometry();
|
||||
const HFMGeometry& geometry = getHFMGeometry();
|
||||
glm::mat4 modelOffset = glm::scale(_scale) * glm::translate(_offset);
|
||||
_rig.initJointStates(geometry, modelOffset);
|
||||
|
||||
|
@ -96,7 +96,7 @@ void SkeletonModel::initJointStates() {
|
|||
// Called within Model::simulate call, below.
|
||||
void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
|
||||
assert(!_owningAvatar->isMyAvatar());
|
||||
const FBXGeometry& geometry = getFBXGeometry();
|
||||
const HFMGeometry& geometry = getHFMGeometry();
|
||||
|
||||
Head* head = _owningAvatar->getHead();
|
||||
|
||||
|
@ -259,22 +259,22 @@ bool SkeletonModel::getRightShoulderPosition(glm::vec3& position) 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 {
|
||||
return isActive() && getJointPositionInWorldFrame(getFBXGeometry().neckJointIndex, neckPosition);
|
||||
return isActive() && getJointPositionInWorldFrame(getHFMGeometry().neckJointIndex, neckPosition);
|
||||
}
|
||||
|
||||
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 {
|
||||
if (!isActive()) {
|
||||
return false;
|
||||
}
|
||||
const FBXGeometry& geometry = getFBXGeometry();
|
||||
const HFMGeometry& geometry = getHFMGeometry();
|
||||
|
||||
if (getJointPosition(geometry.leftEyeJointIndex, firstEyePosition) &&
|
||||
getJointPosition(geometry.rightEyeJointIndex, secondEyePosition)) {
|
||||
|
@ -330,7 +330,7 @@ void SkeletonModel::computeBoundingShape() {
|
|||
return;
|
||||
}
|
||||
|
||||
const FBXGeometry& geometry = getFBXGeometry();
|
||||
const HFMGeometry& geometry = getHFMGeometry();
|
||||
if (geometry.joints.isEmpty() || geometry.rootJointIndex == -1) {
|
||||
// rootJointIndex == -1 if the avatar model has no skeleton
|
||||
return;
|
||||
|
@ -369,7 +369,7 @@ void SkeletonModel::renderBoundingCollisionShapes(RenderArgs* args, gpu::Batch&
|
|||
}
|
||||
|
||||
bool SkeletonModel::hasSkeleton() {
|
||||
return isActive() ? getFBXGeometry().rootJointIndex != -1 : false;
|
||||
return isActive() ? getHFMGeometry().rootJointIndex != -1 : false;
|
||||
}
|
||||
|
||||
void SkeletonModel::onInvalidate() {
|
||||
|
|
|
@ -41,10 +41,10 @@ public:
|
|||
void updateAttitude(const glm::quat& orientation);
|
||||
|
||||
/// Returns the index of the left hand joint, or -1 if not found.
|
||||
int getLeftHandJointIndex() const { return isActive() ? getFBXGeometry().leftHandJointIndex : -1; }
|
||||
int getLeftHandJointIndex() const { return isActive() ? getHFMGeometry().leftHandJointIndex : -1; }
|
||||
|
||||
/// 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 getRightGrabPosition(glm::vec3& position) const;
|
||||
|
|
|
@ -206,7 +206,7 @@ void FBXBaker::importScene() {
|
|||
}
|
||||
#endif
|
||||
|
||||
_geometry = reader.extractFBXGeometry({}, _modelURL.toString());
|
||||
_geometry = reader.extractHFMGeometry({}, _modelURL.toString());
|
||||
_textureContentMap = reader._textureContent;
|
||||
}
|
||||
|
||||
|
@ -329,7 +329,7 @@ void FBXBaker::rewriteAndBakeSceneTextures() {
|
|||
for (FBXNode& textureChild : object->children) {
|
||||
|
||||
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
|
||||
// texture type from the loaded materials
|
||||
|
@ -337,7 +337,7 @@ void FBXBaker::rewriteAndBakeSceneTextures() {
|
|||
auto textureType = textureTypes[textureID];
|
||||
|
||||
// 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 (!bakedTextureFile.isNull()) {
|
||||
|
|
|
@ -53,7 +53,7 @@ private:
|
|||
void rewriteAndBakeSceneModels();
|
||||
void rewriteAndBakeSceneTextures();
|
||||
|
||||
FBXGeometry* _geometry;
|
||||
HFMGeometry* _geometry;
|
||||
QHash<QString, int> _textureNameMatchCount;
|
||||
QHash<QUrl, QString> _remappedTexturePaths;
|
||||
|
||||
|
|
|
@ -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) {
|
||||
handleError("Cannot re-bake a file that contains compressed mesh");
|
||||
return false;
|
||||
|
|
|
@ -39,7 +39,7 @@ public:
|
|||
const QString& bakedOutputDirectory, const QString& originalOutputDirectory = "");
|
||||
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);
|
||||
virtual void setWasAborted(bool wasAborted) override;
|
||||
|
||||
|
|
|
@ -153,7 +153,7 @@ void OBJBaker::bakeOBJ() {
|
|||
checkIfTexturesFinished();
|
||||
}
|
||||
|
||||
void OBJBaker::createFBXNodeTree(FBXNode& rootNode, FBXGeometry& geometry) {
|
||||
void OBJBaker::createFBXNodeTree(FBXNode& rootNode, HFMGeometry& geometry) {
|
||||
// Generating FBX Header Node
|
||||
FBXNode headerNode;
|
||||
headerNode.name = FBX_HEADER_EXTENSION;
|
||||
|
@ -235,7 +235,7 @@ void OBJBaker::createFBXNodeTree(FBXNode& rootNode, FBXGeometry& geometry) {
|
|||
auto size = meshParts.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
QString material = meshParts[i].materialID;
|
||||
FBXMaterial currentMaterial = geometry.materials[material];
|
||||
HFMMaterial currentMaterial = geometry.materials[material];
|
||||
if (!currentMaterial.albedoTexture.filename.isEmpty() || !currentMaterial.specularTexture.filename.isEmpty()) {
|
||||
auto textureID = nextNodeID();
|
||||
_mapTextureMaterial.emplace_back(textureID, i);
|
||||
|
@ -325,12 +325,12 @@ void OBJBaker::createFBXNodeTree(FBXNode& rootNode, FBXGeometry& geometry) {
|
|||
}
|
||||
|
||||
// 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();
|
||||
_materialIDs.push_back(materialID);
|
||||
materialNode.properties = { materialID, material, MESH };
|
||||
|
||||
FBXMaterial currentMaterial = geometry.materials[material];
|
||||
HFMMaterial currentMaterial = geometry.materials[material];
|
||||
|
||||
// Setting the hierarchy: Material -> Properties70 -> P -> Properties
|
||||
FBXNode properties70Node;
|
||||
|
|
|
@ -39,8 +39,8 @@ private slots:
|
|||
|
||||
private:
|
||||
void loadOBJ();
|
||||
void createFBXNodeTree(FBXNode& rootNode, FBXGeometry& geometry);
|
||||
void setMaterialNodeProperties(FBXNode& materialNode, QString material, FBXGeometry& geometry);
|
||||
void createFBXNodeTree(FBXNode& rootNode, HFMGeometry& geometry);
|
||||
void setMaterialNodeProperties(FBXNode& materialNode, QString material, HFMGeometry& geometry);
|
||||
NodeID nextNodeID() { return _nodeID++; }
|
||||
|
||||
|
||||
|
|
|
@ -268,7 +268,7 @@ EntityItemProperties RenderableModelEntityItem::getProperties(const EntityProper
|
|||
if (model->isLoaded()) {
|
||||
// TODO: improve naturalDimensions in the future,
|
||||
// for now we've added this hack for setting natural dimensions of models
|
||||
Extents meshExtents = model->getFBXGeometry().getUnscaledMeshExtents();
|
||||
Extents meshExtents = model->getHFMGeometry().getUnscaledMeshExtents();
|
||||
properties.setNaturalDimensions(meshExtents.maximum - meshExtents.minimum);
|
||||
properties.calculateNaturalPosition(meshExtents.minimum, meshExtents.maximum);
|
||||
}
|
||||
|
@ -403,7 +403,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
|
|||
// should never fall in here when collision model not fully loaded
|
||||
// TODO: assert that all geometries exist and are loaded
|
||||
//assert(_model && _model->isLoaded() && _compoundShapeResource && _compoundShapeResource->isLoaded());
|
||||
const FBXGeometry& collisionGeometry = _compoundShapeResource->getFBXGeometry();
|
||||
const HFMGeometry& collisionGeometry = _compoundShapeResource->getHFMGeometry();
|
||||
|
||||
ShapeInfo::PointCollection& pointCollection = shapeInfo.getPointCollection();
|
||||
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
|
||||
// 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
|
||||
foreach (const FBXMeshPart &meshPart, mesh.parts) {
|
||||
foreach (const HFMMeshPart &meshPart, mesh.parts) {
|
||||
pointCollection.push_back(QVector<glm::vec3>());
|
||||
ShapeInfo::PointList& pointsInPart = pointCollection[i];
|
||||
|
||||
// run through all the triangles and (uniquely) add each point to the hull
|
||||
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);
|
||||
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
|
||||
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);
|
||||
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
|
||||
// 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.
|
||||
// also determine the extents of the collision model.
|
||||
glm::vec3 registrationOffset = dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint());
|
||||
|
@ -498,14 +498,14 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
|
|||
|
||||
// compute meshPart local transforms
|
||||
QVector<glm::mat4> localTransforms;
|
||||
const FBXGeometry& fbxGeometry = model->getFBXGeometry();
|
||||
int numFbxMeshes = fbxGeometry.meshes.size();
|
||||
const HFMGeometry& hfmGeometry = model->getHFMGeometry();
|
||||
int numHFMMeshes = hfmGeometry.meshes.size();
|
||||
int totalNumVertices = 0;
|
||||
glm::mat4 invRegistraionOffset = glm::translate(dimensions * (getRegistrationPoint() - ENTITY_ITEM_DEFAULT_REGISTRATION_POINT));
|
||||
for (int i = 0; i < numFbxMeshes; i++) {
|
||||
const FBXMesh& mesh = fbxGeometry.meshes.at(i);
|
||||
for (int i = 0; i < numHFMMeshes; i++) {
|
||||
const HFMMesh& mesh = hfmGeometry.meshes.at(i);
|
||||
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);
|
||||
// we backtranslate by the registration offset so we can apply that offset to the shapeInfo later
|
||||
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;
|
||||
if (type == SHAPE_TYPE_SIMPLE_COMPOUND) {
|
||||
auto& fbxMeshes = _compoundShapeResource->getFBXGeometry().meshes;
|
||||
meshes.reserve(fbxMeshes.size());
|
||||
for (auto& fbxMesh : fbxMeshes) {
|
||||
meshes.push_back(fbxMesh._mesh);
|
||||
auto& hfmMeshes = _compoundShapeResource->getHFMGeometry().meshes;
|
||||
meshes.reserve(hfmMeshes.size());
|
||||
for (auto& hfmMesh : hfmMeshes) {
|
||||
meshes.push_back(hfmMesh._mesh);
|
||||
}
|
||||
} else {
|
||||
meshes = model->getGeometry()->getMeshes();
|
||||
|
@ -594,7 +594,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
|
|||
while (partItr != parts.cend<const graphics::Mesh::Part>()) {
|
||||
auto numIndices = partItr->_numIndices;
|
||||
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);
|
||||
numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXReader
|
||||
|
||||
|
@ -605,7 +605,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
|
|||
++indexItr;
|
||||
}
|
||||
} 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);
|
||||
|
||||
uint32_t approxNumIndices = TRIANGLE_STRIDE * numIndices;
|
||||
|
@ -651,7 +651,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
|
|||
std::set<int32_t> uniqueIndices;
|
||||
auto numIndices = partItr->_numIndices;
|
||||
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);
|
||||
numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXReader
|
||||
|
||||
|
@ -662,7 +662,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
|
|||
++indexItr;
|
||||
}
|
||||
} 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);
|
||||
|
||||
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 {
|
||||
auto model = getModel();
|
||||
if (EntityItem::contains(point) && model && _compoundShapeResource && _compoundShapeResource->isLoaded()) {
|
||||
return _compoundShapeResource->getFBXGeometry().convexHullContains(worldToEntity(point));
|
||||
return _compoundShapeResource->getHFMGeometry().convexHullContains(worldToEntity(point));
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -1135,7 +1135,7 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) {
|
|||
|
||||
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();
|
||||
if (frameCount <= 0) {
|
||||
return;
|
||||
|
@ -1160,10 +1160,10 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) {
|
|||
}
|
||||
|
||||
QStringList animationJointNames = _animation->getGeometry().getJointNames();
|
||||
auto& fbxJoints = _animation->getGeometry().joints;
|
||||
auto& hfmJoints = _animation->getGeometry().joints;
|
||||
|
||||
auto& originalFbxJoints = _model->getFBXGeometry().joints;
|
||||
auto& originalFbxIndices = _model->getFBXGeometry().jointIndices;
|
||||
auto& originalHFMJoints = _model->getHFMGeometry().joints;
|
||||
auto& originalHFMIndices = _model->getHFMGeometry().jointIndices;
|
||||
|
||||
bool allowTranslation = entity->getAnimationAllowTranslation();
|
||||
|
||||
|
@ -1182,22 +1182,22 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) {
|
|||
translationMat = glm::translate(translations[index]);
|
||||
}
|
||||
} 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
|
||||
if (originalFbxIndices.contains(jointName)) {
|
||||
QString jointName = hfmJoints[index].name; // Pushing this here so its not done on every entity, with the exceptions of those allowing for translation
|
||||
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.
|
||||
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);
|
||||
int remappedIndex = originalHFMIndices[jointName] - 1; // JointIndeces seem to always start from 1 and the found index is always 1 higher than actual.
|
||||
translationMat = glm::translate(originalHFMJoints[remappedIndex].translation);
|
||||
}
|
||||
}
|
||||
glm::mat4 rotationMat;
|
||||
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 {
|
||||
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 *
|
||||
rotationMat * fbxJoints[index].postTransform);
|
||||
glm::mat4 finalMat = (translationMat * hfmJoints[index].preTransform *
|
||||
rotationMat * hfmJoints[index].postTransform);
|
||||
auto& jointData = jointsData[j];
|
||||
jointData.translation = extractTranslation(finalMat);
|
||||
jointData.translationSet = true;
|
||||
|
|
|
@ -70,8 +70,8 @@ public:
|
|||
};
|
||||
|
||||
|
||||
/// A single blendshape extracted from an FBX document.
|
||||
class FBXBlendshape {
|
||||
/// A single blendshape.
|
||||
class HFMBlendshape {
|
||||
public:
|
||||
QVector<int> indices;
|
||||
QVector<glm::vec3> vertices;
|
||||
|
@ -79,19 +79,19 @@ public:
|
|||
QVector<glm::vec3> tangents;
|
||||
};
|
||||
|
||||
struct FBXJointShapeInfo {
|
||||
// same units and frame as FBXJoint.translation
|
||||
struct HFMJointShapeInfo {
|
||||
// same units and frame as HFMJoint.translation
|
||||
glm::vec3 avgPoint;
|
||||
std::vector<float> dots;
|
||||
std::vector<glm::vec3> points;
|
||||
std::vector<glm::vec3> debugLines;
|
||||
};
|
||||
|
||||
/// A single joint (transformation node) extracted from an FBX document.
|
||||
class FBXJoint {
|
||||
/// A single joint (transformation node).
|
||||
class HFMJoint {
|
||||
public:
|
||||
|
||||
FBXJointShapeInfo shapeInfo;
|
||||
HFMJointShapeInfo shapeInfo;
|
||||
QVector<int> freeLineage;
|
||||
bool isFree;
|
||||
int parentIndex;
|
||||
|
@ -126,8 +126,8 @@ public:
|
|||
};
|
||||
|
||||
|
||||
/// A single binding to a joint in an FBX document.
|
||||
class FBXCluster {
|
||||
/// A single binding to a joint.
|
||||
class HFMCluster {
|
||||
public:
|
||||
|
||||
int jointIndex;
|
||||
|
@ -137,8 +137,8 @@ public:
|
|||
|
||||
const int MAX_NUM_PIXELS_FOR_FBX_TEXTURE = 2048 * 2048;
|
||||
|
||||
/// A texture map in an FBX document.
|
||||
class FBXTexture {
|
||||
/// A texture map.
|
||||
class HFMTexture {
|
||||
public:
|
||||
QString id;
|
||||
QString name;
|
||||
|
@ -156,7 +156,7 @@ public:
|
|||
};
|
||||
|
||||
/// A single part of a mesh (with the same material).
|
||||
class FBXMeshPart {
|
||||
class HFMMeshPart {
|
||||
public:
|
||||
|
||||
QVector<int> quadIndices; // original indices from the FBX mesh
|
||||
|
@ -166,10 +166,10 @@ public:
|
|||
QString materialID;
|
||||
};
|
||||
|
||||
class FBXMaterial {
|
||||
class HFMMaterial {
|
||||
public:
|
||||
FBXMaterial() {};
|
||||
FBXMaterial(const glm::vec3& diffuseColor, const glm::vec3& specularColor, const glm::vec3& emissiveColor,
|
||||
HFMMaterial() {};
|
||||
HFMMaterial(const glm::vec3& diffuseColor, const glm::vec3& specularColor, const glm::vec3& emissiveColor,
|
||||
float shininess, float opacity) :
|
||||
diffuseColor(diffuseColor),
|
||||
specularColor(specularColor),
|
||||
|
@ -203,17 +203,17 @@ public:
|
|||
QString shadingModel;
|
||||
graphics::MaterialPointer _material;
|
||||
|
||||
FBXTexture normalTexture;
|
||||
FBXTexture albedoTexture;
|
||||
FBXTexture opacityTexture;
|
||||
FBXTexture glossTexture;
|
||||
FBXTexture roughnessTexture;
|
||||
FBXTexture specularTexture;
|
||||
FBXTexture metallicTexture;
|
||||
FBXTexture emissiveTexture;
|
||||
FBXTexture occlusionTexture;
|
||||
FBXTexture scatteringTexture;
|
||||
FBXTexture lightmapTexture;
|
||||
HFMTexture normalTexture;
|
||||
HFMTexture albedoTexture;
|
||||
HFMTexture opacityTexture;
|
||||
HFMTexture glossTexture;
|
||||
HFMTexture roughnessTexture;
|
||||
HFMTexture specularTexture;
|
||||
HFMTexture metallicTexture;
|
||||
HFMTexture emissiveTexture;
|
||||
HFMTexture occlusionTexture;
|
||||
HFMTexture scatteringTexture;
|
||||
HFMTexture lightmapTexture;
|
||||
glm::vec2 lightmapParams{ 0.0f, 1.0f };
|
||||
|
||||
|
||||
|
@ -232,10 +232,10 @@ public:
|
|||
};
|
||||
|
||||
/// A single mesh (with optional blendshapes) extracted from an FBX document.
|
||||
class FBXMesh {
|
||||
class HFMMesh {
|
||||
public:
|
||||
|
||||
QVector<FBXMeshPart> parts;
|
||||
QVector<HFMMeshPart> parts;
|
||||
|
||||
QVector<glm::vec3> vertices;
|
||||
QVector<glm::vec3> normals;
|
||||
|
@ -247,12 +247,12 @@ public:
|
|||
QVector<uint16_t> clusterWeights;
|
||||
QVector<int32_t> originalIndices;
|
||||
|
||||
QVector<FBXCluster> clusters;
|
||||
QVector<HFMCluster> clusters;
|
||||
|
||||
Extents meshExtents;
|
||||
glm::mat4 modelTransform;
|
||||
|
||||
QVector<FBXBlendshape> blendshapes;
|
||||
QVector<HFMBlendshape> blendshapes;
|
||||
|
||||
unsigned int meshIndex; // the order the meshes appeared in the object file
|
||||
|
||||
|
@ -265,7 +265,7 @@ public:
|
|||
|
||||
class ExtractedMesh {
|
||||
public:
|
||||
FBXMesh mesh;
|
||||
HFMMesh mesh;
|
||||
QMultiHash<int, int> newIndices;
|
||||
QVector<QHash<int, int> > blendshapeIndexMaps;
|
||||
QVector<QPair<int, int> > partMaterialTextures;
|
||||
|
@ -278,14 +278,14 @@ public:
|
|||
* @property {Vec3[]} translations
|
||||
*/
|
||||
/// A single animation frame extracted from an FBX document.
|
||||
class FBXAnimationFrame {
|
||||
class HFMAnimationFrame {
|
||||
public:
|
||||
QVector<glm::quat> rotations;
|
||||
QVector<glm::vec3> translations;
|
||||
};
|
||||
|
||||
/// A light in an FBX document.
|
||||
class FBXLight {
|
||||
/// A light.
|
||||
class HFMLight {
|
||||
public:
|
||||
QString name;
|
||||
Transform transform;
|
||||
|
@ -293,7 +293,7 @@ public:
|
|||
float fogValue;
|
||||
glm::vec3 color;
|
||||
|
||||
FBXLight() :
|
||||
HFMLight() :
|
||||
name(),
|
||||
transform(),
|
||||
intensity(1.0f),
|
||||
|
@ -302,26 +302,26 @@ public:
|
|||
{}
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(FBXAnimationFrame)
|
||||
Q_DECLARE_METATYPE(QVector<FBXAnimationFrame>)
|
||||
Q_DECLARE_METATYPE(HFMAnimationFrame)
|
||||
Q_DECLARE_METATYPE(QVector<HFMAnimationFrame>)
|
||||
|
||||
/// A set of meshes extracted from an FBX document.
|
||||
class FBXGeometry {
|
||||
class HFMGeometry {
|
||||
public:
|
||||
using Pointer = std::shared_ptr<FBXGeometry>;
|
||||
using Pointer = std::shared_ptr<HFMGeometry>;
|
||||
|
||||
QString originalURL;
|
||||
QString author;
|
||||
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
|
||||
bool hasSkeletonJoints;
|
||||
|
||||
QVector<FBXMesh> meshes;
|
||||
QVector<HFMMesh> meshes;
|
||||
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
|
||||
|
||||
|
@ -348,7 +348,7 @@ public:
|
|||
Extents bindExtents;
|
||||
Extents meshExtents;
|
||||
|
||||
QVector<FBXAnimationFrame> animationFrames;
|
||||
QVector<HFMAnimationFrame> animationFrames;
|
||||
|
||||
int getJointIndex(const QString& name) const { return jointIndices.value(name) - 1; }
|
||||
QStringList getJointNames() const;
|
||||
|
@ -368,7 +368,7 @@ public:
|
|||
QList<QString> blendshapeChannelNames;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(FBXGeometry)
|
||||
Q_DECLARE_METATYPE(FBXGeometry::Pointer)
|
||||
Q_DECLARE_METATYPE(HFMGeometry)
|
||||
Q_DECLARE_METATYPE(HFMGeometry::Pointer)
|
||||
|
||||
#endif // hifi_FBX_h_
|
||||
|
|
|
@ -40,19 +40,19 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
int FBXGeometryPointerMetaTypeId = qRegisterMetaType<FBXGeometry::Pointer>();
|
||||
int HFMGeometryPointerMetaTypeId = qRegisterMetaType<HFMGeometry::Pointer>();
|
||||
|
||||
QStringList FBXGeometry::getJointNames() const {
|
||||
QStringList HFMGeometry::getJointNames() const {
|
||||
QStringList names;
|
||||
foreach (const FBXJoint& joint, joints) {
|
||||
foreach (const HFMJoint& joint, joints) {
|
||||
names.append(joint.name);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
bool FBXGeometry::hasBlendedMeshes() const {
|
||||
bool HFMGeometry::hasBlendedMeshes() const {
|
||||
if (!meshes.isEmpty()) {
|
||||
foreach (const FBXMesh& mesh, meshes) {
|
||||
foreach (const HFMMesh& mesh, meshes) {
|
||||
if (!mesh.blendshapes.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ bool FBXGeometry::hasBlendedMeshes() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
Extents FBXGeometry::getUnscaledMeshExtents() const {
|
||||
Extents HFMGeometry::getUnscaledMeshExtents() const {
|
||||
const Extents& extents = meshExtents;
|
||||
|
||||
// even though our caller asked for "unscaled" we need to include any fst scaling, translation, and rotation, which
|
||||
|
@ -74,12 +74,12 @@ Extents FBXGeometry::getUnscaledMeshExtents() const {
|
|||
}
|
||||
|
||||
// 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)) {
|
||||
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.
|
||||
int verticesSize = mesh.vertices.size();
|
||||
for (int j = 0;
|
||||
|
@ -124,16 +124,16 @@ bool FBXGeometry::convexHullContains(const glm::vec3& point) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
QString FBXGeometry::getModelNameOfMesh(int meshIndex) const {
|
||||
QString HFMGeometry::getModelNameOfMesh(int meshIndex) const {
|
||||
if (meshIndicesToModelNames.contains(meshIndex)) {
|
||||
return meshIndicesToModelNames.value(meshIndex);
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
int fbxGeometryMetaTypeId = qRegisterMetaType<FBXGeometry>();
|
||||
int fbxAnimationFrameMetaTypeId = qRegisterMetaType<FBXAnimationFrame>();
|
||||
int fbxAnimationFrameVectorMetaTypeId = qRegisterMetaType<QVector<FBXAnimationFrame> >();
|
||||
int hfmGeometryMetaTypeId = qRegisterMetaType<HFMGeometry>();
|
||||
int hfmAnimationFrameMetaTypeId = qRegisterMetaType<HFMAnimationFrame>();
|
||||
int hfmAnimationFrameVectorMetaTypeId = qRegisterMetaType<QVector<HFMAnimationFrame> >();
|
||||
|
||||
|
||||
glm::vec3 parseVec3(const QString& string) {
|
||||
|
@ -303,7 +303,7 @@ glm::mat4 getGlobalTransform(const QMultiMap<QString, QString>& _connectionParen
|
|||
class ExtractedBlendshape {
|
||||
public:
|
||||
QString id;
|
||||
FBXBlendshape blendshape;
|
||||
HFMBlendshape blendshape;
|
||||
};
|
||||
|
||||
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) {
|
||||
FBXBlendshape blendshape;
|
||||
HFMBlendshape extractBlendshape(const FBXNode& object) {
|
||||
HFMBlendshape blendshape;
|
||||
foreach (const FBXNode& data, object.children) {
|
||||
if (data.name == "Indexes") {
|
||||
blendshape.indices = FBXReader::getIntVector(data);
|
||||
|
@ -362,9 +362,9 @@ FBXBlendshape extractBlendshape(const FBXNode& object) {
|
|||
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) {
|
||||
glm::vec3 vertex[2];
|
||||
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,
|
||||
IndexAccessor accessor) {
|
||||
// if we have a normal map (and texture coordinates), we must compute tangents
|
||||
if (generateFromTexCoords && !mesh.texCoords.isEmpty()) {
|
||||
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) {
|
||||
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);
|
||||
|
@ -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);
|
||||
}
|
||||
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) {
|
||||
_createBlendShapeTangents(*this, generateTangents, blendShape);
|
||||
}
|
||||
}
|
||||
|
||||
void FBXMesh::createMeshTangents(bool generateFromTexCoords) {
|
||||
FBXMesh& mesh = *this;
|
||||
void HFMMesh::createMeshTangents(bool generateFromTexCoords) {
|
||||
HFMMesh& mesh = *this;
|
||||
// This is the only workaround I've found to trick the compiler into understanding that mesh.tangents isn't
|
||||
// const in the lambda function.
|
||||
auto& tangents = 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[1] = mesh.vertices[secondIndex];
|
||||
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
|
||||
std::vector<int> reverseIndices;
|
||||
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,
|
||||
[&](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 index2 = reverseIndices[secondIndex];
|
||||
|
||||
|
@ -481,7 +481,7 @@ void addBlendshapes(const ExtractedBlendshape& extracted, const QList<WeightedIn
|
|||
foreach (const WeightedIndex& index, indices) {
|
||||
extractedMesh.mesh.blendshapes.resize(max(extractedMesh.mesh.blendshapes.size(), index.first + 1));
|
||||
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];
|
||||
for (int i = 0; i < extracted.blendshape.indices.size(); i++) {
|
||||
int oldIndex = extracted.blendshape.indices.at(i);
|
||||
|
@ -539,7 +539,7 @@ public:
|
|||
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) {
|
||||
foreach (const QString& materialID, materials.keys()) {
|
||||
foreach (const QString& childID, _connectionChildMap.values(materialID)) {
|
||||
|
@ -569,8 +569,8 @@ int matchTextureUVSetToAttributeChannel(const QString& texUVSetName, const QHash
|
|||
}
|
||||
|
||||
|
||||
FBXLight extractLight(const FBXNode& object) {
|
||||
FBXLight light;
|
||||
HFMLight extractLight(const FBXNode& object) {
|
||||
HFMLight light;
|
||||
foreach (const FBXNode& subobject, object.children) {
|
||||
QString childname = QString(subobject.name);
|
||||
if (subobject.name == "Properties70") {
|
||||
|
@ -615,7 +615,7 @@ QByteArray fileOnUrl(const QByteArray& filepath, const QString& url) {
|
|||
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;
|
||||
QMap<QString, ExtractedMesh> meshes;
|
||||
QHash<QString, QString> modelIDsToNames;
|
||||
|
@ -636,7 +636,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
QHash<QString, QString> yComponents;
|
||||
QHash<QString, QString> zComponents;
|
||||
|
||||
std::map<QString, FBXLight> lights;
|
||||
std::map<QString, HFMLight> lights;
|
||||
|
||||
QVariantHash joints = mapping.value("joint").toHash();
|
||||
QString jointEyeLeftName = processID(getString(joints.value("jointEyeLeft", "jointEyeLeft")));
|
||||
|
@ -689,8 +689,8 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
#if defined(DEBUG_FBXREADER)
|
||||
int unknown = 0;
|
||||
#endif
|
||||
FBXGeometry* geometryPtr = new FBXGeometry;
|
||||
FBXGeometry& geometry = *geometryPtr;
|
||||
HFMGeometry* geometryPtr = new HFMGeometry;
|
||||
HFMGeometry& geometry = *geometryPtr;
|
||||
|
||||
geometry.originalURL = url;
|
||||
|
||||
|
@ -944,7 +944,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
lightprop = vprop.toString();
|
||||
}
|
||||
|
||||
FBXLight light = extractLight(object);
|
||||
HFMLight light = extractLight(object);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -1102,7 +1102,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
_textureContent.insert(filepath, content);
|
||||
}
|
||||
} else if (object.name == "Material") {
|
||||
FBXMaterial material;
|
||||
HFMMaterial material;
|
||||
material.name = (object.properties.at(1).toString());
|
||||
foreach (const FBXNode& subobject, object.children) {
|
||||
bool properties = false;
|
||||
|
@ -1255,7 +1255,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
#endif
|
||||
}
|
||||
material.materialID = getID(object.properties);
|
||||
_fbxMaterials.insert(material.materialID, material);
|
||||
_hfmMaterials.insert(material.materialID, material);
|
||||
|
||||
|
||||
} else if (object.name == "NodeAttribute") {
|
||||
|
@ -1276,7 +1276,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
|
||||
if (!attributetype.isEmpty()) {
|
||||
if (attributetype == "Light") {
|
||||
FBXLight light = extractLight(object);
|
||||
HFMLight light = extractLight(object);
|
||||
lights[attribID] = light;
|
||||
}
|
||||
}
|
||||
|
@ -1345,7 +1345,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
QString parentID = getID(connection.properties, 2);
|
||||
ooChildToParent.insert(childID, parentID);
|
||||
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()) {
|
||||
_lightmapLevel = (*lightIt).second.intensity;
|
||||
if (_lightmapLevel <= 0.0f) {
|
||||
|
@ -1504,7 +1504,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
frameCount = qMax(frameCount, curve.values.size());
|
||||
}
|
||||
for (int i = 0; i < frameCount; i++) {
|
||||
FBXAnimationFrame frame;
|
||||
HFMAnimationFrame frame;
|
||||
frame.rotations.resize(modelIDs.size());
|
||||
frame.translations.resize(modelIDs.size());
|
||||
geometry.animationFrames.append(frame);
|
||||
|
@ -1515,7 +1515,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
geometry.hasSkeletonJoints = false;
|
||||
foreach (const QString& modelID, modelIDs) {
|
||||
const FBXModel& model = models[modelID];
|
||||
FBXJoint joint;
|
||||
HFMJoint joint;
|
||||
joint.isFree = freeJoints.contains(model.name);
|
||||
joint.parentIndex = model.parentIndex;
|
||||
|
||||
|
@ -1553,7 +1553,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
joint.distanceToParent = 0.0f;
|
||||
|
||||
} 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.preTransform * glm::mat4_cast(combinedRotation) * joint.postTransform;
|
||||
joint.inverseDefaultRotation = glm::inverse(combinedRotation) * parentJoint.inverseDefaultRotation;
|
||||
|
@ -1631,7 +1631,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
geometry.meshExtents.reset();
|
||||
|
||||
// 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
|
||||
// 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
|
||||
// etc...
|
||||
QSet<QString> uniqueTextures;
|
||||
for (auto& material : _fbxMaterials) {
|
||||
for (auto& material : _hfmMaterials) {
|
||||
material.getTextureNames(uniqueTextures);
|
||||
}
|
||||
int numTextures = uniqueTextures.size();
|
||||
|
@ -1659,15 +1659,15 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
} while (numTextureThreshold < numTextures && maxWidth > MIN_MIP_TEXTURE_WIDTH);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
geometry.materials = _fbxMaterials;
|
||||
geometry.materials = _hfmMaterials;
|
||||
|
||||
// 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++) {
|
||||
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--) {
|
||||
|
||||
const QString& childID = children.at(i);
|
||||
if (_fbxMaterials.contains(childID)) {
|
||||
if (_hfmMaterials.contains(childID)) {
|
||||
// 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++) {
|
||||
if (extracted.partMaterialTextures.at(j).first == materialIndex) {
|
||||
FBXMeshPart& part = extracted.mesh.parts[j];
|
||||
HFMMeshPart& part = extracted.mesh.parts[j];
|
||||
part.materialID = material.materialID;
|
||||
generateTangents |= material.needTangentSpace();
|
||||
}
|
||||
|
@ -1713,7 +1713,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
materialIndex++;
|
||||
|
||||
} else if (_textureFilenames.contains(childID)) {
|
||||
FBXTexture texture = getTexture(childID);
|
||||
HFMTexture texture = getTexture(childID);
|
||||
for (int j = 0; j < extracted.partMaterialTextures.size(); j++) {
|
||||
int partTexture = extracted.partMaterialTextures.at(j).second;
|
||||
if (partTexture == textureIndex && !(partTexture == 0 && materialsHaveTextures)) {
|
||||
|
@ -1736,34 +1736,34 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
if (!clusters.contains(clusterID)) {
|
||||
continue;
|
||||
}
|
||||
FBXCluster fbxCluster;
|
||||
HFMCluster hfmCluster;
|
||||
const Cluster& cluster = clusters[clusterID];
|
||||
clusterIDs.append(clusterID);
|
||||
|
||||
// see http://stackoverflow.com/questions/13566608/loading-skinning-information-from-fbx for a discussion
|
||||
// of skinning information in FBX
|
||||
QString jointID = _connectionChildMap.value(clusterID);
|
||||
fbxCluster.jointIndex = modelIDs.indexOf(jointID);
|
||||
if (fbxCluster.jointIndex == -1) {
|
||||
hfmCluster.jointIndex = modelIDs.indexOf(jointID);
|
||||
if (hfmCluster.jointIndex == -1) {
|
||||
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
|
||||
// sometimes floating point fuzz can be introduced after the inverse.
|
||||
fbxCluster.inverseBindMatrix[0][3] = 0.0f;
|
||||
fbxCluster.inverseBindMatrix[1][3] = 0.0f;
|
||||
fbxCluster.inverseBindMatrix[2][3] = 0.0f;
|
||||
fbxCluster.inverseBindMatrix[3][3] = 1.0f;
|
||||
hfmCluster.inverseBindMatrix[0][3] = 0.0f;
|
||||
hfmCluster.inverseBindMatrix[1][3] = 0.0f;
|
||||
hfmCluster.inverseBindMatrix[2][3] = 0.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
|
||||
FBXJoint& joint = geometry.joints[fbxCluster.jointIndex];
|
||||
HFMJoint& joint = geometry.joints[hfmCluster.jointIndex];
|
||||
joint.inverseBindRotation = glm::inverse(extractRotation(cluster.transformLink));
|
||||
joint.bindTransform = cluster.transformLink;
|
||||
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 (extracted.mesh.clusters.isEmpty()) {
|
||||
FBXCluster cluster;
|
||||
HFMCluster cluster;
|
||||
cluster.jointIndex = modelIDs.indexOf(modelID);
|
||||
if (cluster.jointIndex == -1) {
|
||||
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
|
||||
const FBXCluster& firstFBXCluster = extracted.mesh.clusters.at(0);
|
||||
const HFMCluster& firstHFMCluster = extracted.mesh.clusters.at(0);
|
||||
glm::mat4 inverseModelTransform = glm::inverse(modelTransform);
|
||||
if (clusterIDs.size() > 1) {
|
||||
// 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++) {
|
||||
QString clusterID = clusterIDs.at(i);
|
||||
const Cluster& cluster = clusters[clusterID];
|
||||
const FBXCluster& fbxCluster = extracted.mesh.clusters.at(i);
|
||||
int jointIndex = fbxCluster.jointIndex;
|
||||
FBXJoint& joint = geometry.joints[jointIndex];
|
||||
const HFMCluster& hfmCluster = extracted.mesh.clusters.at(i);
|
||||
int jointIndex = hfmCluster.jointIndex;
|
||||
HFMJoint& joint = geometry.joints[jointIndex];
|
||||
glm::mat4 transformJointToMesh = inverseModelTransform * joint.bindTransform;
|
||||
glm::vec3 boneEnd = extractTranslation(transformJointToMesh);
|
||||
glm::vec3 boneBegin = boneEnd;
|
||||
|
@ -1881,8 +1881,8 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
}
|
||||
} else {
|
||||
// this is a single-mesh joint
|
||||
int jointIndex = firstFBXCluster.jointIndex;
|
||||
FBXJoint& joint = geometry.joints[jointIndex];
|
||||
int jointIndex = firstHFMCluster.jointIndex;
|
||||
HFMJoint& joint = geometry.joints[jointIndex];
|
||||
|
||||
// transform cluster vertices to joint-frame and save for later
|
||||
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
|
||||
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
|
||||
ShapeVertices& points = shapeVertices.at(i);
|
||||
|
@ -1994,13 +1994,13 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
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));
|
||||
buffer.open(QIODevice::ReadOnly);
|
||||
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;
|
||||
reader._rootNode = FBXReader::parseFBX(device);
|
||||
reader._loadLightmaps = loadLightmaps;
|
||||
|
@ -2008,5 +2008,5 @@ FBXGeometry* readFBX(QIODevice* device, const QVariantHash& mapping, const QStri
|
|||
|
||||
qCDebug(modelformat) << "Reading FBX: " << url;
|
||||
|
||||
return reader.extractFBXGeometry(mapping, url);
|
||||
return reader.extractHFMGeometry(mapping, url);
|
||||
}
|
||||
|
|
|
@ -36,11 +36,11 @@ class FBXNode;
|
|||
|
||||
/// Reads FBX geometry from the supplied model and mapping data.
|
||||
/// \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.
|
||||
/// \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 {
|
||||
public:
|
||||
|
@ -103,20 +103,20 @@ class ExtractedMesh;
|
|||
|
||||
class FBXReader {
|
||||
public:
|
||||
FBXGeometry* _fbxGeometry;
|
||||
HFMGeometry* _hfmGeometry;
|
||||
|
||||
FBXNode _rootNode;
|
||||
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);
|
||||
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);
|
||||
|
||||
FBXTexture getTexture(const QString& textureID);
|
||||
HFMTexture getTexture(const QString& textureID);
|
||||
|
||||
QHash<QString, QString> _textureNames;
|
||||
// Hashes the original RelativeFilename of textures
|
||||
|
@ -142,9 +142,9 @@ public:
|
|||
QHash<QString, QString> ambientFactorTextures;
|
||||
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;
|
||||
float _lightmapOffset = 0.0f;
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
#include "ModelFormatLogging.h"
|
||||
|
||||
void FBXMaterial::getTextureNames(QSet<QString>& textureList) const {
|
||||
void HFMMaterial::getTextureNames(QSet<QString>& textureList) const {
|
||||
if (!normalTexture.isNull()) {
|
||||
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;
|
||||
albedoTexture.maxNumPixels = maxNumPixels;
|
||||
opacityTexture.maxNumPixels = maxNumPixels;
|
||||
|
@ -77,12 +77,12 @@ void FBXMaterial::setMaxNumPixelsPerTexture(int maxNumPixels) {
|
|||
lightmapTexture.maxNumPixels = maxNumPixels;
|
||||
}
|
||||
|
||||
bool FBXMaterial::needTangentSpace() const {
|
||||
bool HFMMaterial::needTangentSpace() const {
|
||||
return !normalTexture.isNull();
|
||||
}
|
||||
|
||||
FBXTexture FBXReader::getTexture(const QString& textureID) {
|
||||
FBXTexture texture;
|
||||
HFMTexture FBXReader::getTexture(const QString& textureID) {
|
||||
HFMTexture texture;
|
||||
const QByteArray& filepath = _textureFilepaths.value(textureID);
|
||||
texture.content = _textureContent.value(filepath);
|
||||
|
||||
|
@ -123,7 +123,7 @@ FBXTexture FBXReader::getTexture(const QString& textureID) {
|
|||
return texture;
|
||||
}
|
||||
|
||||
void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) {
|
||||
void FBXReader::consolidateHFMMaterials(const QVariantHash& mapping) {
|
||||
|
||||
QString materialMapString = mapping.value("materialMap").toString();
|
||||
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;
|
||||
}
|
||||
}
|
||||
for (QHash<QString, FBXMaterial>::iterator it = _fbxMaterials.begin(); it != _fbxMaterials.end(); it++) {
|
||||
FBXMaterial& material = (*it);
|
||||
for (QHash<QString, HFMMaterial>::iterator it = _hfmMaterials.begin(); it != _hfmMaterials.end(); it++) {
|
||||
HFMMaterial& material = (*it);
|
||||
|
||||
// Maya is the exporting the shading model and we are trying to use it
|
||||
bool isMaterialLambert = (material.shadingModel.toLower() == "lambert");
|
||||
|
||||
// the pure material associated with this part
|
||||
bool detectDifferentUVs = false;
|
||||
FBXTexture diffuseTexture;
|
||||
FBXTexture diffuseFactorTexture;
|
||||
HFMTexture diffuseTexture;
|
||||
HFMTexture diffuseFactorTexture;
|
||||
QString diffuseTextureID = diffuseTextures.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());
|
||||
}
|
||||
|
||||
FBXTexture transparentTexture;
|
||||
HFMTexture transparentTexture;
|
||||
QString transparentTextureID = transparentTextures.value(material.materialID);
|
||||
// If PBS Material, systematically bind the albedo texture as transparency texture and check for the alpha channel
|
||||
if (material.isPBSMaterial) {
|
||||
|
@ -181,7 +181,7 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) {
|
|||
detectDifferentUVs |= (transparentTexture.texcoordSet != 0) || (!transparentTexture.transform.isIdentity());
|
||||
}
|
||||
|
||||
FBXTexture normalTexture;
|
||||
HFMTexture normalTexture;
|
||||
QString bumpTextureID = bumpTextures.value(material.materialID);
|
||||
QString normalTextureID = normalTextures.value(material.materialID);
|
||||
if (!normalTextureID.isNull()) {
|
||||
|
@ -198,7 +198,7 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) {
|
|||
detectDifferentUVs |= (normalTexture.texcoordSet != 0) || (!normalTexture.transform.isIdentity());
|
||||
}
|
||||
|
||||
FBXTexture specularTexture;
|
||||
HFMTexture specularTexture;
|
||||
QString specularTextureID = specularTextures.value(material.materialID);
|
||||
if (!specularTextureID.isNull()) {
|
||||
specularTexture = getTexture(specularTextureID);
|
||||
|
@ -206,7 +206,7 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) {
|
|||
material.specularTexture = specularTexture;
|
||||
}
|
||||
|
||||
FBXTexture metallicTexture;
|
||||
HFMTexture metallicTexture;
|
||||
QString metallicTextureID = metallicTextures.value(material.materialID);
|
||||
if (!metallicTextureID.isNull()) {
|
||||
metallicTexture = getTexture(metallicTextureID);
|
||||
|
@ -214,7 +214,7 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) {
|
|||
material.metallicTexture = metallicTexture;
|
||||
}
|
||||
|
||||
FBXTexture roughnessTexture;
|
||||
HFMTexture roughnessTexture;
|
||||
QString roughnessTextureID = roughnessTextures.value(material.materialID);
|
||||
if (!roughnessTextureID.isNull()) {
|
||||
roughnessTexture = getTexture(roughnessTextureID);
|
||||
|
@ -222,7 +222,7 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) {
|
|||
detectDifferentUVs |= (roughnessTexture.texcoordSet != 0) || (!roughnessTexture.transform.isIdentity());
|
||||
}
|
||||
|
||||
FBXTexture shininessTexture;
|
||||
HFMTexture shininessTexture;
|
||||
QString shininessTextureID = shininessTextures.value(material.materialID);
|
||||
if (!shininessTextureID.isNull()) {
|
||||
shininessTexture = getTexture(shininessTextureID);
|
||||
|
@ -230,7 +230,7 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) {
|
|||
detectDifferentUVs |= (shininessTexture.texcoordSet != 0) || (!shininessTexture.transform.isIdentity());
|
||||
}
|
||||
|
||||
FBXTexture emissiveTexture;
|
||||
HFMTexture emissiveTexture;
|
||||
QString emissiveTextureID = emissiveTextures.value(material.materialID);
|
||||
if (!emissiveTextureID.isNull()) {
|
||||
emissiveTexture = getTexture(emissiveTextureID);
|
||||
|
@ -245,7 +245,7 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) {
|
|||
}
|
||||
}
|
||||
|
||||
FBXTexture occlusionTexture;
|
||||
HFMTexture occlusionTexture;
|
||||
QString occlusionTextureID = occlusionTextures.value(material.materialID);
|
||||
if (occlusionTextureID.isNull()) {
|
||||
// 2nd chance
|
||||
|
@ -265,7 +265,7 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) {
|
|||
lightmapParams.x = _lightmapOffset;
|
||||
lightmapParams.y = _lightmapLevel;
|
||||
|
||||
FBXTexture ambientTexture;
|
||||
HFMTexture ambientTexture;
|
||||
QString ambientTextureID = ambientTextures.value(material.materialID);
|
||||
if (ambientTextureID.isNull()) {
|
||||
// 2nd chance
|
||||
|
@ -326,7 +326,7 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) {
|
|||
|
||||
if (materialOptions.contains("scatteringMap")) {
|
||||
QByteArray scatteringMap = materialOptions.value("scatteringMap").toVariant().toByteArray();
|
||||
material.scatteringTexture = FBXTexture();
|
||||
material.scatteringTexture = HFMTexture();
|
||||
material.scatteringTexture.name = material.name + ".scatteringMap";
|
||||
material.scatteringTexture.filename = scatteringMap;
|
||||
}
|
||||
|
|
|
@ -42,9 +42,9 @@
|
|||
|
||||
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;
|
||||
#define FBX_COLOR_ELEMENT gpu::Element::COLOR_RGBA_32
|
||||
#else
|
||||
|
@ -469,7 +469,7 @@ ExtractedMesh FBXReader::extractMesh(const FBXNode& object, unsigned int& meshIn
|
|||
|
||||
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];
|
||||
if (partIndexPlusOne == 0) {
|
||||
data.extracted.partMaterialTextures.append(materialTexture);
|
||||
|
@ -478,7 +478,7 @@ ExtractedMesh FBXReader::extractMesh(const FBXNode& object, unsigned int& meshIn
|
|||
}
|
||||
|
||||
// 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(dracoFace[1].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);
|
||||
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) {
|
||||
appendIndex(data, part.quadIndices, beginIndex++, deduplicate);
|
||||
|
@ -565,9 +565,9 @@ glm::vec3 FBXReader::normalizeDirForPacking(const glm::vec3& dir) {
|
|||
return dir;
|
||||
}
|
||||
|
||||
void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
|
||||
void FBXReader::buildModelMesh(HFMMesh& extractedMesh, const QString& url) {
|
||||
unsigned int totalSourceIndices = 0;
|
||||
foreach(const FBXMeshPart& part, extractedMesh.parts) {
|
||||
foreach(const HFMMeshPart& part, extractedMesh.parts) {
|
||||
totalSourceIndices += (part.quadTrianglesIndices.size() + part.triangleIndices.size());
|
||||
}
|
||||
|
||||
|
@ -583,17 +583,17 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
|
|||
return;
|
||||
}
|
||||
|
||||
FBXMesh& fbxMesh = extractedMesh;
|
||||
HFMMesh& hfmMesh = extractedMesh;
|
||||
graphics::MeshPointer mesh(new graphics::Mesh());
|
||||
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
|
||||
fbxMesh.tangents.reserve(fbxMesh.normals.size());
|
||||
std::fill_n(std::back_inserter(fbxMesh.tangents), fbxMesh.normals.size(), Vectors::UNIT_X);
|
||||
hfmMesh.tangents.reserve(hfmMesh.normals.size());
|
||||
std::fill_n(std::back_inserter(hfmMesh.tangents), hfmMesh.normals.size(), Vectors::UNIT_X);
|
||||
}
|
||||
// Same thing with blend shapes
|
||||
for (auto& blendShape : fbxMesh.blendshapes) {
|
||||
for (auto& blendShape : hfmMesh.blendshapes) {
|
||||
if (!blendShape.normals.empty() && blendShape.tangents.empty()) {
|
||||
// Fill with a dummy value to force tangents to be present if there are normals
|
||||
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)
|
||||
const auto normalElement = FBX_NORMAL_ELEMENT;
|
||||
const int normalsSize = fbxMesh.normals.size() * normalElement.getSize();
|
||||
const int tangentsSize = fbxMesh.tangents.size() * normalElement.getSize();
|
||||
const int normalsSize = hfmMesh.normals.size() * normalElement.getSize();
|
||||
const int tangentsSize = hfmMesh.tangents.size() * normalElement.getSize();
|
||||
// If there are normals then there should be tangents
|
||||
assert(normalsSize <= tangentsSize);
|
||||
if (tangentsSize > normalsSize) {
|
||||
|
@ -620,22 +620,22 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
|
|||
|
||||
// Color attrib
|
||||
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
|
||||
const auto texCoordsElement = gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV);
|
||||
const int texCoordsSize = fbxMesh.texCoords.size() * texCoordsElement.getSize();
|
||||
const int texCoords1Size = fbxMesh.texCoords1.size() * texCoordsElement.getSize();
|
||||
const int texCoordsSize = hfmMesh.texCoords.size() * texCoordsElement.getSize();
|
||||
const int texCoords1Size = hfmMesh.texCoords1.size() * texCoordsElement.getSize();
|
||||
|
||||
// Support for 4 skinning clusters:
|
||||
// 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
|
||||
const auto clusterWeightElement = gpu::Element(gpu::VEC4, gpu::NUINT16, gpu::XYZW);
|
||||
|
||||
// Cluster indices and weights must be the same sizes
|
||||
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 clusterWeightsSize = numVertClusters * clusterWeightElement.getSize();
|
||||
|
||||
|
@ -660,9 +660,9 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
|
|||
if (normalsSize > 0) {
|
||||
std::vector<NormalType> normalsAndTangents;
|
||||
|
||||
normalsAndTangents.reserve(fbxMesh.normals.size() + fbxMesh.tangents.size());
|
||||
for (auto normalIt = fbxMesh.normals.constBegin(), tangentIt = fbxMesh.tangents.constBegin();
|
||||
normalIt != fbxMesh.normals.constEnd();
|
||||
normalsAndTangents.reserve(hfmMesh.normals.size() + hfmMesh.tangents.size());
|
||||
for (auto normalIt = hfmMesh.normals.constBegin(), tangentIt = hfmMesh.tangents.constBegin();
|
||||
normalIt != hfmMesh.normals.constEnd();
|
||||
++normalIt, ++tangentIt) {
|
||||
#if FBX_PACK_NORMALS
|
||||
const auto normal = normalizeDirForPacking(*normalIt);
|
||||
|
@ -681,24 +681,24 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
|
|||
|
||||
// Pack colors
|
||||
if (colorsSize > 0) {
|
||||
#if FBX_PACK_COLORS
|
||||
#if HFM_PACK_COLORS
|
||||
std::vector<ColorType> colors;
|
||||
|
||||
colors.reserve(fbxMesh.colors.size());
|
||||
for (const auto& color : fbxMesh.colors) {
|
||||
colors.reserve(hfmMesh.colors.size());
|
||||
for (const auto& color : hfmMesh.colors) {
|
||||
colors.push_back(glm::packUnorm4x8(glm::vec4(color, 1.0f)));
|
||||
}
|
||||
vertBuffer->setSubData(colorsOffset, colorsSize, (const gpu::Byte*) colors.data());
|
||||
#else
|
||||
vertBuffer->setSubData(colorsOffset, colorsSize, (const gpu::Byte*) fbxMesh.colors.constData());
|
||||
vertBuffer->setSubData(colorsOffset, colorsSize, (const gpu::Byte*) hfmMesh.colors.constData());
|
||||
#endif
|
||||
}
|
||||
|
||||
// Pack Texcoords 0 and 1 (if exists)
|
||||
if (texCoordsSize > 0) {
|
||||
QVector<vec2h> texCoordData;
|
||||
texCoordData.reserve(fbxMesh.texCoords.size());
|
||||
for (auto& texCoordVec2f : fbxMesh.texCoords) {
|
||||
texCoordData.reserve(hfmMesh.texCoords.size());
|
||||
for (auto& texCoordVec2f : hfmMesh.texCoords) {
|
||||
vec2h texCoordVec2h;
|
||||
|
||||
texCoordVec2h.x = glm::detail::toFloat16(texCoordVec2f.x);
|
||||
|
@ -709,8 +709,8 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
|
|||
}
|
||||
if (texCoords1Size > 0) {
|
||||
QVector<vec2h> texCoordData;
|
||||
texCoordData.reserve(fbxMesh.texCoords1.size());
|
||||
for (auto& texCoordVec2f : fbxMesh.texCoords1) {
|
||||
texCoordData.reserve(hfmMesh.texCoords1.size());
|
||||
for (auto& texCoordVec2f : hfmMesh.texCoords1) {
|
||||
vec2h texCoordVec2h;
|
||||
|
||||
texCoordVec2h.x = glm::detail::toFloat16(texCoordVec2f.x);
|
||||
|
@ -722,22 +722,22 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
|
|||
|
||||
// Clusters data
|
||||
if (clusterIndicesSize > 0) {
|
||||
if (fbxMesh.clusters.size() < UINT8_MAX) {
|
||||
if (hfmMesh.clusters.size() < UINT8_MAX) {
|
||||
// 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;
|
||||
clusterIndices.resize(numIndices);
|
||||
for (int32_t i = 0; i < numIndices; ++i) {
|
||||
assert(fbxMesh.clusterIndices[i] <= UINT8_MAX);
|
||||
clusterIndices[i] = (uint8_t)(fbxMesh.clusterIndices[i]);
|
||||
assert(hfmMesh.clusterIndices[i] <= UINT8_MAX);
|
||||
clusterIndices[i] = (uint8_t)(hfmMesh.clusterIndices[i]);
|
||||
}
|
||||
vertBuffer->setSubData(clusterIndicesOffset, clusterIndicesSize, (const gpu::Byte*) clusterIndices.constData());
|
||||
} else {
|
||||
vertBuffer->setSubData(clusterIndicesOffset, clusterIndicesSize, (const gpu::Byte*) fbxMesh.clusterIndices.constData());
|
||||
vertBuffer->setSubData(clusterIndicesOffset, clusterIndicesSize, (const gpu::Byte*) hfmMesh.clusterIndices.constData());
|
||||
}
|
||||
}
|
||||
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
|
||||
unsigned int totalIndices = 0;
|
||||
foreach(const FBXMeshPart& part, extractedMesh.parts) {
|
||||
foreach(const HFMMeshPart& part, extractedMesh.parts) {
|
||||
totalIndices += (part.quadTrianglesIndices.size() + part.triangleIndices.size());
|
||||
}
|
||||
|
||||
|
@ -875,7 +875,7 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
|
|||
if (extractedMesh.parts.size() > 1) {
|
||||
indexNum = 0;
|
||||
}
|
||||
foreach(const FBXMeshPart& part, extractedMesh.parts) {
|
||||
foreach(const HFMMeshPart& part, extractedMesh.parts) {
|
||||
graphics::Mesh::Part modelPart(indexNum, 0, 0, graphics::Mesh::TRIANGLES);
|
||||
|
||||
if (part.quadTrianglesIndices.size()) {
|
||||
|
|
|
@ -697,7 +697,7 @@ glm::mat4 GLTFReader::getModelTransform(const GLTFNode& node) {
|
|||
return tmat;
|
||||
}
|
||||
|
||||
bool GLTFReader::buildGeometry(FBXGeometry& geometry, const QUrl& url) {
|
||||
bool GLTFReader::buildGeometry(HFMGeometry& geometry, const QUrl& url) {
|
||||
|
||||
//Build dependencies
|
||||
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++) {
|
||||
QString& matid = materialIDs[i];
|
||||
geometry.materials[matid] = FBXMaterial();
|
||||
FBXMaterial& fbxMaterial = geometry.materials[matid];
|
||||
fbxMaterial._material = std::make_shared<graphics::Material>();
|
||||
setFBXMaterial(fbxMaterial, _file.materials[i]);
|
||||
geometry.materials[matid] = HFMMaterial();
|
||||
HFMMaterial& hfmMaterial = geometry.materials[matid];
|
||||
hfmMaterial._material = std::make_shared<graphics::Material>();
|
||||
setHFMMaterial(hfmMaterial, _file.materials[i]);
|
||||
}
|
||||
|
||||
|
||||
|
@ -765,9 +765,9 @@ bool GLTFReader::buildGeometry(FBXGeometry& geometry, const QUrl& url) {
|
|||
if (node.defined["mesh"]) {
|
||||
qCDebug(modelformat) << "node_transforms" << node.transforms;
|
||||
foreach(auto &primitive, _file.meshes[node.mesh].primitives) {
|
||||
geometry.meshes.append(FBXMesh());
|
||||
FBXMesh& mesh = geometry.meshes[geometry.meshes.size() - 1];
|
||||
FBXCluster cluster;
|
||||
geometry.meshes.append(HFMMesh());
|
||||
HFMMesh& mesh = geometry.meshes[geometry.meshes.size() - 1];
|
||||
HFMCluster cluster;
|
||||
cluster.jointIndex = 0;
|
||||
cluster.inverseBindMatrix = glm::mat4(1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
|
@ -775,7 +775,7 @@ bool GLTFReader::buildGeometry(FBXGeometry& geometry, const QUrl& url) {
|
|||
0, 0, 0, 1);
|
||||
mesh.clusters.append(cluster);
|
||||
|
||||
FBXMeshPart part = FBXMeshPart();
|
||||
HFMMeshPart part = HFMMeshPart();
|
||||
|
||||
int indicesAccessorIdx = primitive.indices;
|
||||
|
||||
|
@ -910,7 +910,7 @@ bool GLTFReader::buildGeometry(FBXGeometry& geometry, const QUrl& url) {
|
|||
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) {
|
||||
|
||||
_url = url;
|
||||
|
@ -924,8 +924,8 @@ FBXGeometry* GLTFReader::readGLTF(QByteArray& model, const QVariantHash& mapping
|
|||
|
||||
parseGLTF(model);
|
||||
//_file.dump();
|
||||
FBXGeometry* geometryPtr = new FBXGeometry();
|
||||
FBXGeometry& geometry = *geometryPtr;
|
||||
HFMGeometry* geometryPtr = new HFMGeometry();
|
||||
HFMGeometry& geometry = *geometryPtr;
|
||||
|
||||
buildGeometry(geometry, url);
|
||||
|
||||
|
@ -997,8 +997,8 @@ QNetworkReply* GLTFReader::request(QUrl& url, bool isTest) {
|
|||
return netReply; // trying to sync later on.
|
||||
}
|
||||
|
||||
FBXTexture GLTFReader::getFBXTexture(const GLTFTexture& texture) {
|
||||
FBXTexture fbxtex = FBXTexture();
|
||||
HFMTexture GLTFReader::getHFMTexture(const GLTFTexture& texture) {
|
||||
HFMTexture fbxtex = HFMTexture();
|
||||
fbxtex.texcoordSet = 0;
|
||||
|
||||
if (texture.defined["source"]) {
|
||||
|
@ -1014,7 +1014,7 @@ FBXTexture GLTFReader::getFBXTexture(const GLTFTexture& texture) {
|
|||
return fbxtex;
|
||||
}
|
||||
|
||||
void GLTFReader::setFBXMaterial(FBXMaterial& fbxmat, const GLTFMaterial& material) {
|
||||
void GLTFReader::setHFMMaterial(HFMMaterial& fbxmat, const GLTFMaterial& material) {
|
||||
|
||||
|
||||
if (material.defined["name"]) {
|
||||
|
@ -1029,17 +1029,17 @@ void GLTFReader::setFBXMaterial(FBXMaterial& fbxmat, const GLTFMaterial& materia
|
|||
}
|
||||
|
||||
if (material.defined["emissiveTexture"]) {
|
||||
fbxmat.emissiveTexture = getFBXTexture(_file.textures[material.emissiveTexture]);
|
||||
fbxmat.emissiveTexture = getHFMTexture(_file.textures[material.emissiveTexture]);
|
||||
fbxmat.useEmissiveMap = true;
|
||||
}
|
||||
|
||||
if (material.defined["normalTexture"]) {
|
||||
fbxmat.normalTexture = getFBXTexture(_file.textures[material.normalTexture]);
|
||||
fbxmat.normalTexture = getHFMTexture(_file.textures[material.normalTexture]);
|
||||
fbxmat.useNormalMap = true;
|
||||
}
|
||||
|
||||
if (material.defined["occlusionTexture"]) {
|
||||
fbxmat.occlusionTexture = getFBXTexture(_file.textures[material.occlusionTexture]);
|
||||
fbxmat.occlusionTexture = getHFMTexture(_file.textures[material.occlusionTexture]);
|
||||
fbxmat.useOcclusionMap = true;
|
||||
}
|
||||
|
||||
|
@ -1050,14 +1050,14 @@ void GLTFReader::setFBXMaterial(FBXMaterial& fbxmat, const GLTFMaterial& materia
|
|||
fbxmat.metallic = material.pbrMetallicRoughness.metallicFactor;
|
||||
}
|
||||
if (material.pbrMetallicRoughness.defined["baseColorTexture"]) {
|
||||
fbxmat.opacityTexture = getFBXTexture(_file.textures[material.pbrMetallicRoughness.baseColorTexture]);
|
||||
fbxmat.albedoTexture = getFBXTexture(_file.textures[material.pbrMetallicRoughness.baseColorTexture]);
|
||||
fbxmat.opacityTexture = getHFMTexture(_file.textures[material.pbrMetallicRoughness.baseColorTexture]);
|
||||
fbxmat.albedoTexture = getHFMTexture(_file.textures[material.pbrMetallicRoughness.baseColorTexture]);
|
||||
fbxmat.useAlbedoMap = true;
|
||||
}
|
||||
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.metallicTexture = getFBXTexture(_file.textures[material.pbrMetallicRoughness.metallicRoughnessTexture]);
|
||||
fbxmat.metallicTexture = getHFMTexture(_file.textures[material.pbrMetallicRoughness.metallicRoughnessTexture]);
|
||||
fbxmat.useMetallicMap = true;
|
||||
}
|
||||
if (material.pbrMetallicRoughness.defined["roughnessFactor"]) {
|
||||
|
@ -1181,8 +1181,8 @@ void GLTFReader::retriangulate(const QVector<int>& inIndices, const QVector<glm:
|
|||
}
|
||||
}
|
||||
|
||||
void GLTFReader::fbxDebugDump(const FBXGeometry& fbxgeo) {
|
||||
qCDebug(modelformat) << "---------------- fbxGeometry ----------------";
|
||||
void GLTFReader::fbxDebugDump(const HFMGeometry& fbxgeo) {
|
||||
qCDebug(modelformat) << "---------------- hfmGeometry ----------------";
|
||||
qCDebug(modelformat) << " hasSkeletonJoints =" << fbxgeo.hasSkeletonJoints;
|
||||
qCDebug(modelformat) << " offset =" << fbxgeo.offset;
|
||||
|
||||
|
@ -1211,7 +1211,7 @@ void GLTFReader::fbxDebugDump(const FBXGeometry& fbxgeo) {
|
|||
qCDebug(modelformat) << "---------------- Meshes ----------------";
|
||||
qCDebug(modelformat) << " meshes.count() =" << fbxgeo.meshes.count();
|
||||
qCDebug(modelformat) << " blendshapeChannelNames = " << fbxgeo.blendshapeChannelNames;
|
||||
foreach(FBXMesh mesh, fbxgeo.meshes) {
|
||||
foreach(HFMMesh mesh, fbxgeo.meshes) {
|
||||
qCDebug(modelformat) << "\n";
|
||||
qCDebug(modelformat) << " meshpointer =" << mesh._mesh.get();
|
||||
qCDebug(modelformat) << " meshindex =" << mesh.meshIndex;
|
||||
|
@ -1227,7 +1227,7 @@ void GLTFReader::fbxDebugDump(const FBXGeometry& fbxgeo) {
|
|||
qCDebug(modelformat) << " modelTransform =" << mesh.modelTransform;
|
||||
qCDebug(modelformat) << " parts.count() =" << mesh.parts.count();
|
||||
qCDebug(modelformat) << "---------------- Meshes (blendshapes)--------";
|
||||
foreach(FBXBlendshape bshape, mesh.blendshapes) {
|
||||
foreach(HFMBlendshape bshape, mesh.blendshapes) {
|
||||
qCDebug(modelformat) << "\n";
|
||||
qCDebug(modelformat) << " bshape.indices.count() =" << bshape.indices.count();
|
||||
qCDebug(modelformat) << " bshape.vertices.count() =" << bshape.vertices.count();
|
||||
|
@ -1235,7 +1235,7 @@ void GLTFReader::fbxDebugDump(const FBXGeometry& fbxgeo) {
|
|||
qCDebug(modelformat) << "\n";
|
||||
}
|
||||
qCDebug(modelformat) << "---------------- Meshes (meshparts)--------";
|
||||
foreach(FBXMeshPart meshPart, mesh.parts) {
|
||||
foreach(HFMMeshPart meshPart, mesh.parts) {
|
||||
qCDebug(modelformat) << "\n";
|
||||
qCDebug(modelformat) << " quadIndices.count() =" << meshPart.quadIndices.count();
|
||||
qCDebug(modelformat) << " triangleIndices.count() =" << meshPart.triangleIndices.count();
|
||||
|
@ -1245,7 +1245,7 @@ void GLTFReader::fbxDebugDump(const FBXGeometry& fbxgeo) {
|
|||
}
|
||||
qCDebug(modelformat) << "---------------- Meshes (clusters)--------";
|
||||
qCDebug(modelformat) << " clusters.count() =" << mesh.clusters.count();
|
||||
foreach(FBXCluster cluster, mesh.clusters) {
|
||||
foreach(HFMCluster cluster, mesh.clusters) {
|
||||
qCDebug(modelformat) << "\n";
|
||||
qCDebug(modelformat) << " jointIndex =" << cluster.jointIndex;
|
||||
qCDebug(modelformat) << " inverseBindMatrix =" << cluster.inverseBindMatrix;
|
||||
|
@ -1254,7 +1254,7 @@ void GLTFReader::fbxDebugDump(const FBXGeometry& fbxgeo) {
|
|||
qCDebug(modelformat) << "\n";
|
||||
}
|
||||
qCDebug(modelformat) << "---------------- AnimationFrames ----------------";
|
||||
foreach(FBXAnimationFrame anim, fbxgeo.animationFrames) {
|
||||
foreach(HFMAnimationFrame anim, fbxgeo.animationFrames) {
|
||||
qCDebug(modelformat) << " anim.translations = " << anim.translations;
|
||||
qCDebug(modelformat) << " anim.rotations = " << anim.rotations;
|
||||
}
|
||||
|
@ -1265,7 +1265,7 @@ void GLTFReader::fbxDebugDump(const FBXGeometry& fbxgeo) {
|
|||
|
||||
qCDebug(modelformat) << "---------------- Materials ----------------";
|
||||
|
||||
foreach(FBXMaterial mat, fbxgeo.materials) {
|
||||
foreach(HFMMaterial mat, fbxgeo.materials) {
|
||||
qCDebug(modelformat) << "\n";
|
||||
qCDebug(modelformat) << " mat.materialID =" << mat.materialID;
|
||||
qCDebug(modelformat) << " diffuseColor =" << mat.diffuseColor;
|
||||
|
@ -1314,7 +1314,7 @@ void GLTFReader::fbxDebugDump(const FBXGeometry& fbxgeo) {
|
|||
|
||||
qCDebug(modelformat) << "---------------- Joints ----------------";
|
||||
|
||||
foreach(FBXJoint joint, fbxgeo.joints) {
|
||||
foreach(HFMJoint joint, fbxgeo.joints) {
|
||||
qCDebug(modelformat) << "\n";
|
||||
qCDebug(modelformat) << " shapeInfo.avgPoint =" << joint.shapeInfo.avgPoint;
|
||||
qCDebug(modelformat) << " shapeInfo.debugLines =" << joint.shapeInfo.debugLines;
|
||||
|
|
|
@ -706,7 +706,7 @@ class GLTFReader : public QObject {
|
|||
Q_OBJECT
|
||||
public:
|
||||
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);
|
||||
private:
|
||||
GLTFFile _file;
|
||||
|
@ -714,7 +714,7 @@ private:
|
|||
|
||||
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 getStringVal(const QJsonObject& object, const QString& fieldname,
|
||||
|
@ -778,9 +778,9 @@ private:
|
|||
bool doesResourceExist(const QString& url);
|
||||
|
||||
|
||||
void setFBXMaterial(FBXMaterial& fbxmat, const GLTFMaterial& material);
|
||||
FBXTexture getFBXTexture(const GLTFTexture& texture);
|
||||
void fbxDebugDump(const FBXGeometry& fbxgeo);
|
||||
void setHFMMaterial(HFMMaterial& fbxmat, const GLTFMaterial& material);
|
||||
HFMTexture getHFMTexture(const GLTFTexture& texture);
|
||||
void fbxDebugDump(const HFMGeometry& fbxgeo);
|
||||
};
|
||||
|
||||
#endif // hifi_GLTFReader_h
|
|
@ -175,7 +175,7 @@ glm::vec2 OBJTokenizer::getVec2() {
|
|||
}
|
||||
|
||||
|
||||
void setMeshPartDefaults(FBXMeshPart& meshPart, QString materialID) {
|
||||
void setMeshPartDefaults(HFMMeshPart& meshPart, QString 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) {
|
||||
FaceGroup faces;
|
||||
FBXMesh& mesh = geometry.meshes[0];
|
||||
mesh.parts.append(FBXMeshPart());
|
||||
FBXMeshPart& meshPart = mesh.parts.last();
|
||||
HFMMesh& mesh = geometry.meshes[0];
|
||||
mesh.parts.append(HFMMeshPart());
|
||||
HFMMeshPart& meshPart = mesh.parts.last();
|
||||
bool sawG = false;
|
||||
bool result = true;
|
||||
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);
|
||||
QBuffer buffer { &model };
|
||||
buffer.open(QIODevice::ReadOnly);
|
||||
|
||||
auto geometryPtr { std::make_shared<FBXGeometry>() };
|
||||
FBXGeometry& geometry { *geometryPtr };
|
||||
auto geometryPtr { std::make_shared<HFMGeometry>() };
|
||||
HFMGeometry& geometry { *geometryPtr };
|
||||
OBJTokenizer tokenizer { &buffer };
|
||||
float scaleGuess = 1.0f;
|
||||
|
||||
|
@ -666,14 +666,14 @@ FBXGeometry::Pointer OBJReader::readOBJ(QByteArray& model, const QVariantHash& m
|
|||
|
||||
_url = url;
|
||||
geometry.meshExtents.reset();
|
||||
geometry.meshes.append(FBXMesh());
|
||||
geometry.meshes.append(HFMMesh());
|
||||
|
||||
try {
|
||||
// call parseOBJGroup as long as it's returning true. Each successful call will
|
||||
// add a new meshPart to the geometry's single mesh.
|
||||
while (parseOBJGroup(tokenizer, mapping, geometry, scaleGuess, combineParts)) {}
|
||||
|
||||
FBXMesh& mesh = geometry.meshes[0];
|
||||
HFMMesh& mesh = geometry.meshes[0];
|
||||
mesh.meshIndex = 0;
|
||||
|
||||
geometry.joints.resize(1);
|
||||
|
@ -688,7 +688,7 @@ FBXGeometry::Pointer OBJReader::readOBJ(QByteArray& model, const QVariantHash& m
|
|||
|
||||
geometry.jointIndices["x"] = 1;
|
||||
|
||||
FBXCluster cluster;
|
||||
HFMCluster cluster;
|
||||
cluster.jointIndex = 0;
|
||||
cluster.inverseBindMatrix = glm::mat4(1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
|
@ -697,20 +697,20 @@ FBXGeometry::Pointer OBJReader::readOBJ(QByteArray& model, const QVariantHash& m
|
|||
mesh.clusters.append(cluster);
|
||||
|
||||
QMap<QString, int> materialMeshIdMap;
|
||||
QVector<FBXMeshPart> fbxMeshParts;
|
||||
QVector<HFMMeshPart> hfmMeshParts;
|
||||
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];
|
||||
bool specifiesUV = false;
|
||||
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).
|
||||
// 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)) {
|
||||
// Create a new FBXMesh for this material mapping.
|
||||
// Create a new HFMMesh for this material mapping.
|
||||
materialMeshIdMap.insert(face.materialName, materialMeshIdMap.count());
|
||||
|
||||
fbxMeshParts.append(FBXMeshPart());
|
||||
FBXMeshPart& meshPartNew = fbxMeshParts.last();
|
||||
hfmMeshParts.append(HFMMeshPart());
|
||||
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.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.
|
||||
|
@ -745,14 +745,14 @@ FBXGeometry::Pointer OBJReader::readOBJ(QByteArray& model, const QVariantHash& m
|
|||
// clean up old mesh parts.
|
||||
int unmodifiedMeshPartCount = mesh.parts.count();
|
||||
mesh.parts.clear();
|
||||
mesh.parts = QVector<FBXMeshPart>(fbxMeshParts);
|
||||
mesh.parts = QVector<HFMMeshPart>(hfmMeshParts);
|
||||
|
||||
for (int i = 0, meshPartCount = 0; i < unmodifiedMeshPartCount; i++, 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).
|
||||
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 v1 = checked_at(vertices, face.vertexIndices[1]);
|
||||
|
@ -885,38 +885,38 @@ FBXGeometry::Pointer OBJReader::readOBJ(QByteArray& model, const QVariantHash& m
|
|||
if (!objMaterial.used) {
|
||||
continue;
|
||||
}
|
||||
geometry.materials[materialID] = FBXMaterial(objMaterial.diffuseColor,
|
||||
geometry.materials[materialID] = HFMMaterial(objMaterial.diffuseColor,
|
||||
objMaterial.specularColor,
|
||||
objMaterial.emissiveColor,
|
||||
objMaterial.shininess,
|
||||
objMaterial.opacity);
|
||||
FBXMaterial& fbxMaterial = geometry.materials[materialID];
|
||||
fbxMaterial.materialID = materialID;
|
||||
fbxMaterial._material = std::make_shared<graphics::Material>();
|
||||
graphics::MaterialPointer modelMaterial = fbxMaterial._material;
|
||||
HFMMaterial& hfmMaterial = geometry.materials[materialID];
|
||||
hfmMaterial.materialID = materialID;
|
||||
hfmMaterial._material = std::make_shared<graphics::Material>();
|
||||
graphics::MaterialPointer modelMaterial = hfmMaterial._material;
|
||||
|
||||
if (!objMaterial.diffuseTextureFilename.isEmpty()) {
|
||||
fbxMaterial.albedoTexture.filename = objMaterial.diffuseTextureFilename;
|
||||
hfmMaterial.albedoTexture.filename = objMaterial.diffuseTextureFilename;
|
||||
}
|
||||
if (!objMaterial.specularTextureFilename.isEmpty()) {
|
||||
fbxMaterial.specularTexture.filename = objMaterial.specularTextureFilename;
|
||||
hfmMaterial.specularTexture.filename = objMaterial.specularTextureFilename;
|
||||
}
|
||||
if (!objMaterial.emissiveTextureFilename.isEmpty()) {
|
||||
fbxMaterial.emissiveTexture.filename = objMaterial.emissiveTextureFilename;
|
||||
hfmMaterial.emissiveTexture.filename = objMaterial.emissiveTextureFilename;
|
||||
}
|
||||
if (!objMaterial.bumpTextureFilename.isEmpty()) {
|
||||
fbxMaterial.normalTexture.filename = objMaterial.bumpTextureFilename;
|
||||
fbxMaterial.normalTexture.isBumpmap = true;
|
||||
fbxMaterial.bumpMultiplier = objMaterial.bumpTextureOptions.bumpMultiplier;
|
||||
hfmMaterial.normalTexture.filename = objMaterial.bumpTextureFilename;
|
||||
hfmMaterial.normalTexture.isBumpmap = true;
|
||||
hfmMaterial.bumpMultiplier = objMaterial.bumpTextureOptions.bumpMultiplier;
|
||||
}
|
||||
if (!objMaterial.opacityTextureFilename.isEmpty()) {
|
||||
fbxMaterial.opacityTexture.filename = objMaterial.opacityTextureFilename;
|
||||
hfmMaterial.opacityTexture.filename = objMaterial.opacityTextureFilename;
|
||||
}
|
||||
|
||||
modelMaterial->setEmissive(fbxMaterial.emissiveColor);
|
||||
modelMaterial->setAlbedo(fbxMaterial.diffuseColor);
|
||||
modelMaterial->setMetallic(glm::length(fbxMaterial.specularColor));
|
||||
modelMaterial->setRoughness(graphics::Material::shininessToRoughness(fbxMaterial.shininess));
|
||||
modelMaterial->setEmissive(hfmMaterial.emissiveColor);
|
||||
modelMaterial->setAlbedo(hfmMaterial.diffuseColor);
|
||||
modelMaterial->setMetallic(glm::length(hfmMaterial.specularColor));
|
||||
modelMaterial->setRoughness(graphics::Material::shininessToRoughness(hfmMaterial.shininess));
|
||||
|
||||
bool applyTransparency = false;
|
||||
bool applyShininess = false;
|
||||
|
@ -971,7 +971,7 @@ FBXGeometry::Pointer OBJReader::readOBJ(QByteArray& model, const QVariantHash& m
|
|||
}
|
||||
|
||||
if (applyTransparency) {
|
||||
fbxMaterial.opacity = std::max(fbxMaterial.opacity, ILLUMINATION_MODEL_MIN_OPACITY);
|
||||
hfmMaterial.opacity = std::max(hfmMaterial.opacity, ILLUMINATION_MODEL_MIN_OPACITY);
|
||||
}
|
||||
if (applyShininess) {
|
||||
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->setOpacity(fbxMaterial.opacity);
|
||||
modelMaterial->setOpacity(hfmMaterial.opacity);
|
||||
}
|
||||
|
||||
return geometryPtr;
|
||||
}
|
||||
|
||||
void fbxDebugDump(const FBXGeometry& fbxgeo) {
|
||||
qCDebug(modelformat) << "---------------- fbxGeometry ----------------";
|
||||
void fbxDebugDump(const HFMGeometry& fbxgeo) {
|
||||
qCDebug(modelformat) << "---------------- hfmGeometry ----------------";
|
||||
qCDebug(modelformat) << " hasSkeletonJoints =" << fbxgeo.hasSkeletonJoints;
|
||||
qCDebug(modelformat) << " offset =" << fbxgeo.offset;
|
||||
qCDebug(modelformat) << " meshes.count() =" << fbxgeo.meshes.count();
|
||||
foreach (FBXMesh mesh, fbxgeo.meshes) {
|
||||
foreach (HFMMesh mesh, fbxgeo.meshes) {
|
||||
qCDebug(modelformat) << " vertices.count() =" << mesh.vertices.count();
|
||||
qCDebug(modelformat) << " colors.count() =" << mesh.colors.count();
|
||||
qCDebug(modelformat) << " normals.count() =" << mesh.normals.count();
|
||||
|
@ -1014,7 +1014,7 @@ void fbxDebugDump(const FBXGeometry& fbxgeo) {
|
|||
qCDebug(modelformat) << " meshExtents =" << mesh.meshExtents;
|
||||
qCDebug(modelformat) << " modelTransform =" << mesh.modelTransform;
|
||||
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) << " triangleIndices.count() =" << meshPart.triangleIndices.count();
|
||||
/*
|
||||
|
@ -1031,7 +1031,7 @@ void fbxDebugDump(const FBXGeometry& fbxgeo) {
|
|||
*/
|
||||
}
|
||||
qCDebug(modelformat) << " clusters.count() =" << mesh.clusters.count();
|
||||
foreach (FBXCluster cluster, mesh.clusters) {
|
||||
foreach (HFMCluster cluster, mesh.clusters) {
|
||||
qCDebug(modelformat) << " jointIndex =" << cluster.jointIndex;
|
||||
qCDebug(modelformat) << " inverseBindMatrix =" << cluster.inverseBindMatrix;
|
||||
}
|
||||
|
@ -1040,7 +1040,7 @@ void fbxDebugDump(const FBXGeometry& fbxgeo) {
|
|||
qCDebug(modelformat) << " jointIndices =" << fbxgeo.jointIndices;
|
||||
qCDebug(modelformat) << " joints.count() =" << fbxgeo.joints.count();
|
||||
|
||||
foreach (FBXJoint joint, fbxgeo.joints) {
|
||||
foreach (HFMJoint joint, fbxgeo.joints) {
|
||||
qCDebug(modelformat) << " isFree =" << joint.isFree;
|
||||
qCDebug(modelformat) << " freeLineage" << joint.freeLineage;
|
||||
qCDebug(modelformat) << " parentIndex" << joint.parentIndex;
|
||||
|
|
|
@ -42,7 +42,7 @@ public:
|
|||
bool add(const QByteArray& vertexIndex, const QByteArray& textureIndex, const QByteArray& normalIndex,
|
||||
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.
|
||||
// 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();
|
||||
private:
|
||||
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.
|
||||
// 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 {
|
||||
public:
|
||||
float shininess;
|
||||
|
@ -87,13 +87,13 @@ public:
|
|||
QString currentMaterialName;
|
||||
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:
|
||||
QUrl _url;
|
||||
|
||||
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);
|
||||
void parseMaterialLibrary(QIODevice* device);
|
||||
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.
|
||||
void setMeshPartDefaults(FBXMeshPart& meshPart, QString materialID);
|
||||
void fbxDebugDump(const FBXGeometry& fbxgeo);
|
||||
void setMeshPartDefaults(HFMMeshPart& meshPart, QString materialID);
|
||||
void fbxDebugDump(const HFMGeometry& fbxgeo);
|
||||
|
|
|
@ -128,7 +128,7 @@ void GeometryMappingResource::downloadFinished(const QByteArray& data) {
|
|||
|
||||
void GeometryMappingResource::onGeometryMappingLoaded(bool success) {
|
||||
if (success && _geometryResource) {
|
||||
_fbxGeometry = _geometryResource->_fbxGeometry;
|
||||
_hfmGeometry = _geometryResource->_hfmGeometry;
|
||||
_meshParts = _geometryResource->_meshParts;
|
||||
_meshes = _geometryResource->_meshes;
|
||||
_materials = _geometryResource->_materials;
|
||||
|
@ -193,38 +193,38 @@ void GeometryReader::run() {
|
|||
_url.path().toLower().endsWith(".obj.gz") ||
|
||||
_url.path().toLower().endsWith(".gltf"))) {
|
||||
|
||||
FBXGeometry::Pointer fbxGeometry;
|
||||
HFMGeometry::Pointer hfmGeometry;
|
||||
|
||||
if (_url.path().toLower().endsWith(".fbx")) {
|
||||
fbxGeometry.reset(readFBX(_data, _mapping, _url.path()));
|
||||
if (fbxGeometry->meshes.size() == 0 && fbxGeometry->joints.size() == 0) {
|
||||
hfmGeometry.reset(readFBX(_data, _mapping, _url.path()));
|
||||
if (hfmGeometry->meshes.size() == 0 && hfmGeometry->joints.size() == 0) {
|
||||
throw QString("empty geometry, possibly due to an unsupported FBX version");
|
||||
}
|
||||
} 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")) {
|
||||
QByteArray uncompressedData;
|
||||
if (gunzip(_data, uncompressedData)){
|
||||
fbxGeometry = OBJReader().readOBJ(uncompressedData, _mapping, _combineParts, _url);
|
||||
hfmGeometry = OBJReader().readOBJ(uncompressedData, _mapping, _combineParts, _url);
|
||||
} else {
|
||||
throw QString("failed to decompress .obj.gz");
|
||||
}
|
||||
|
||||
} else if (_url.path().toLower().endsWith(".gltf")) {
|
||||
std::shared_ptr<GLTFReader> glreader = std::make_shared<GLTFReader>();
|
||||
fbxGeometry.reset(glreader->readGLTF(_data, _mapping, _url));
|
||||
if (fbxGeometry->meshes.size() == 0 && fbxGeometry->joints.size() == 0) {
|
||||
hfmGeometry.reset(glreader->readGLTF(_data, _mapping, _url));
|
||||
if (hfmGeometry->meshes.size() == 0 && hfmGeometry->joints.size() == 0) {
|
||||
throw QString("empty geometry, possibly due to an unsupported GLTF version");
|
||||
}
|
||||
} else {
|
||||
throw QString("unsupported format");
|
||||
}
|
||||
|
||||
// Add scripts to fbxgeometry
|
||||
// Add scripts to hfmGeometry
|
||||
if (!_mapping.value(SCRIPT_FIELD).isNull()) {
|
||||
QVariantList scripts = _mapping.values(SCRIPT_FIELD);
|
||||
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";
|
||||
} else {
|
||||
QMetaObject::invokeMethod(resource.data(), "setGeometryDefinition",
|
||||
Q_ARG(FBXGeometry::Pointer, fbxGeometry));
|
||||
Q_ARG(HFMGeometry::Pointer, hfmGeometry));
|
||||
}
|
||||
} else {
|
||||
throw QString("url is invalid");
|
||||
|
@ -262,7 +262,7 @@ public:
|
|||
virtual void downloadFinished(const QByteArray& data) override;
|
||||
|
||||
protected:
|
||||
Q_INVOKABLE void setGeometryDefinition(FBXGeometry::Pointer fbxGeometry);
|
||||
Q_INVOKABLE void setGeometryDefinition(HFMGeometry::Pointer hfmGeometry);
|
||||
|
||||
private:
|
||||
QVariantHash _mapping;
|
||||
|
@ -277,13 +277,13 @@ void GeometryDefinitionResource::downloadFinished(const QByteArray& data) {
|
|||
QThreadPool::globalInstance()->start(new GeometryReader(_self, _effectiveBaseURL, _mapping, data, _combineParts));
|
||||
}
|
||||
|
||||
void GeometryDefinitionResource::setGeometryDefinition(FBXGeometry::Pointer fbxGeometry) {
|
||||
void GeometryDefinitionResource::setGeometryDefinition(HFMGeometry::Pointer hfmGeometry) {
|
||||
// Assume ownership of the geometry pointer
|
||||
_fbxGeometry = fbxGeometry;
|
||||
_hfmGeometry = hfmGeometry;
|
||||
|
||||
// Copy materials
|
||||
QHash<QString, size_t> materialIDAtlas;
|
||||
for (const FBXMaterial& material : _fbxGeometry->materials) {
|
||||
for (const HFMMaterial& material : _hfmGeometry->materials) {
|
||||
materialIDAtlas[material.materialID] = _materials.size();
|
||||
_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<GeometryMeshParts> parts = std::make_shared<GeometryMeshParts>();
|
||||
int meshID = 0;
|
||||
for (const FBXMesh& mesh : _fbxGeometry->meshes) {
|
||||
for (const HFMMesh& mesh : _hfmGeometry->meshes) {
|
||||
// Copy mesh pointers
|
||||
meshes->emplace_back(mesh._mesh);
|
||||
int partID = 0;
|
||||
for (const FBXMeshPart& part : mesh.parts) {
|
||||
for (const HFMMeshPart& part : mesh.parts) {
|
||||
// Construct local parts
|
||||
parts->push_back(std::make_shared<MeshPart>(meshID, partID, (int)materialIDAtlas[part.materialID]));
|
||||
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
|
||||
Geometry::Geometry(const Geometry& geometry) {
|
||||
_fbxGeometry = geometry._fbxGeometry;
|
||||
_hfmGeometry = geometry._hfmGeometry;
|
||||
_meshes = geometry._meshes;
|
||||
_meshParts = geometry._meshParts;
|
||||
|
||||
|
@ -444,8 +444,8 @@ void GeometryResource::deleter() {
|
|||
}
|
||||
|
||||
void GeometryResource::setTextures() {
|
||||
if (_fbxGeometry) {
|
||||
for (const FBXMaterial& material : _fbxGeometry->materials) {
|
||||
if (_hfmGeometry) {
|
||||
for (const HFMMaterial& material : _hfmGeometry->materials) {
|
||||
_materials.push_back(std::make_shared<NetworkMaterial>(material, _textureBaseUrl));
|
||||
}
|
||||
}
|
||||
|
@ -512,7 +512,7 @@ const QString& NetworkMaterial::getTextureName(MapChannel channel) {
|
|||
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()) {
|
||||
// External file: search relative to the baseUrl, in case filename is relative
|
||||
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) {
|
||||
|
||||
if (baseUrl.isEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto url = getTextureUrl(baseUrl, fbxTexture);
|
||||
const auto texture = DependencyManager::get<TextureCache>()->getTexture(url, type, fbxTexture.content, fbxTexture.maxNumPixels);
|
||||
_textures[channel] = Texture { fbxTexture.name, texture };
|
||||
const auto url = getTextureUrl(baseUrl, hfmTexture);
|
||||
const auto texture = DependencyManager::get<TextureCache>()->getTexture(url, type, hfmTexture.content, hfmTexture.maxNumPixels);
|
||||
_textures[channel] = Texture { hfmTexture.name, texture };
|
||||
|
||||
auto map = std::make_shared<graphics::TextureMap>();
|
||||
if (texture) {
|
||||
map->setTextureSource(texture->_textureSource);
|
||||
}
|
||||
map->setTextureTransform(fbxTexture.transform);
|
||||
map->setTextureTransform(hfmTexture.transform);
|
||||
|
||||
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),
|
||||
_textures(MapChannel::NUM_MAP_CHANNELS)
|
||||
{
|
||||
|
|
|
@ -45,9 +45,9 @@ public:
|
|||
// Mutable, but must retain structure of vector
|
||||
using NetworkMaterials = std::vector<std::shared_ptr<NetworkMaterial>>;
|
||||
|
||||
bool isGeometryLoaded() const { return (bool)_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 std::shared_ptr<NetworkMaterial> getShapeMaterial(int shapeID) const;
|
||||
|
||||
|
@ -62,7 +62,7 @@ protected:
|
|||
friend class GeometryMappingResource;
|
||||
|
||||
// Shared across all geometries, constant throughout lifetime
|
||||
std::shared_ptr<const FBXGeometry> _fbxGeometry;
|
||||
std::shared_ptr<const HFMGeometry> _hfmGeometry;
|
||||
std::shared_ptr<const GeometryMeshes> _meshes;
|
||||
std::shared_ptr<const GeometryMeshParts> _meshParts;
|
||||
|
||||
|
@ -94,7 +94,7 @@ protected:
|
|||
|
||||
// Geometries may not hold onto textures while cached - that is for the texture cache
|
||||
// Instead, these methods clear and reset textures from the geometry when caching/loading
|
||||
bool shouldSetTextures() const { return _fbxGeometry && _materials.empty(); }
|
||||
bool shouldSetTextures() const { return _hfmGeometry && _materials.empty(); }
|
||||
void setTextures();
|
||||
void resetTextures();
|
||||
|
||||
|
@ -165,7 +165,7 @@ public:
|
|||
using MapChannel = graphics::Material::MapChannel;
|
||||
|
||||
NetworkMaterial() : _textures(MapChannel::NUM_MAP_CHANNELS) {}
|
||||
NetworkMaterial(const FBXMaterial& material, const QUrl& textureBaseUrl);
|
||||
NetworkMaterial(const HFMMaterial& material, const QUrl& textureBaseUrl);
|
||||
NetworkMaterial(const NetworkMaterial& material);
|
||||
|
||||
void setAlbedoMap(const QUrl& url, bool useAlphaChannel);
|
||||
|
@ -201,8 +201,8 @@ protected:
|
|||
|
||||
private:
|
||||
// Helpers for the ctors
|
||||
QUrl getTextureUrl(const QUrl& baseUrl, const FBXTexture& fbxTexture);
|
||||
graphics::TextureMapPointer fetchTextureMap(const QUrl& baseUrl, const FBXTexture& fbxTexture,
|
||||
QUrl getTextureUrl(const QUrl& baseUrl, const HFMTexture& hfmTexture);
|
||||
graphics::TextureMapPointer fetchTextureMap(const QUrl& baseUrl, const HFMTexture& hfmTexture,
|
||||
image::TextureUsage::Type type, MapChannel channel);
|
||||
graphics::TextureMapPointer fetchTextureMap(const QUrl& url, image::TextureUsage::Type type, MapChannel channel);
|
||||
|
||||
|
|
|
@ -32,8 +32,8 @@ bool CauterizedModel::updateGeometry() {
|
|||
bool needsFullUpdate = Model::updateGeometry();
|
||||
if (_isCauterized && needsFullUpdate) {
|
||||
assert(_cauterizeMeshStates.empty());
|
||||
const FBXGeometry& fbxGeometry = getFBXGeometry();
|
||||
foreach (const FBXMesh& mesh, fbxGeometry.meshes) {
|
||||
const HFMGeometry& hfmGeometry = getHFMGeometry();
|
||||
foreach (const HFMMesh& mesh, hfmGeometry.meshes) {
|
||||
Model::MeshState state;
|
||||
if (_useDualQuaternionSkinning) {
|
||||
state.clusterDualQuaternions.resize(mesh.clusters.size());
|
||||
|
@ -76,7 +76,7 @@ void CauterizedModel::createRenderItemSet() {
|
|||
// Run through all of the meshes, and place them into their segregated, but unsorted buckets
|
||||
int shapeID = 0;
|
||||
uint32_t numMeshes = (uint32_t)meshes.size();
|
||||
const FBXGeometry& fbxGeometry = getFBXGeometry();
|
||||
const HFMGeometry& hfmGeometry = getHFMGeometry();
|
||||
for (uint32_t i = 0; i < numMeshes; i++) {
|
||||
const auto& mesh = meshes.at(i);
|
||||
if (!mesh) {
|
||||
|
@ -86,7 +86,7 @@ void CauterizedModel::createRenderItemSet() {
|
|||
// Create the render payloads
|
||||
int numParts = (int)mesh->getNumParts();
|
||||
for (int partIndex = 0; partIndex < numParts; partIndex++) {
|
||||
initializeBlendshapes(fbxGeometry.meshes[i], i);
|
||||
initializeBlendshapes(hfmGeometry.meshes[i], i);
|
||||
|
||||
auto ptr = std::make_shared<CauterizedMeshPartPayload>(shared_from_this(), i, partIndex, shapeID, transform, offset);
|
||||
_modelMeshRenderItems << std::static_pointer_cast<ModelMeshPartPayload>(ptr);
|
||||
|
@ -109,13 +109,13 @@ void CauterizedModel::updateClusterMatrices() {
|
|||
return;
|
||||
}
|
||||
_needsUpdateClusterMatrices = false;
|
||||
const FBXGeometry& geometry = getFBXGeometry();
|
||||
const HFMGeometry& geometry = getHFMGeometry();
|
||||
|
||||
for (int i = 0; i < (int)_meshStates.size(); 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++) {
|
||||
const FBXCluster& cluster = mesh.clusters.at(j);
|
||||
const HFMCluster& cluster = mesh.clusters.at(j);
|
||||
if (_useDualQuaternionSkinning) {
|
||||
auto jointPose = _rig.getJointPose(cluster.jointIndex);
|
||||
Transform jointTransform(jointPose.rot(), jointPose.scale(), jointPose.trans());
|
||||
|
@ -145,10 +145,10 @@ void CauterizedModel::updateClusterMatrices() {
|
|||
|
||||
for (int i = 0; i < _cauterizeMeshStates.size(); 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++) {
|
||||
const FBXCluster& cluster = mesh.clusters.at(j);
|
||||
const HFMCluster& cluster = mesh.clusters.at(j);
|
||||
|
||||
if (_useDualQuaternionSkinning) {
|
||||
if (_cauterizeBoneSet.find(cluster.jointIndex) == _cauterizeBoneSet.end()) {
|
||||
|
|
|
@ -260,8 +260,8 @@ void ModelMeshPartPayload::initCache(const ModelPointer& model) {
|
|||
_hasColorAttrib = vertexFormat->hasAttribute(gpu::Stream::COLOR);
|
||||
_isSkinned = vertexFormat->hasAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT) && vertexFormat->hasAttribute(gpu::Stream::SKIN_CLUSTER_INDEX);
|
||||
|
||||
const FBXGeometry& geometry = model->getFBXGeometry();
|
||||
const FBXMesh& mesh = geometry.meshes.at(_meshIndex);
|
||||
const HFMGeometry& geometry = model->getHFMGeometry();
|
||||
const HFMMesh& mesh = geometry.meshes.at(_meshIndex);
|
||||
|
||||
_isBlendShaped = !mesh.blendshapes.isEmpty();
|
||||
_hasTangents = !mesh.tangents.isEmpty();
|
||||
|
|
|
@ -183,7 +183,7 @@ bool Model::shouldInvalidatePayloadShapeKey(int meshIndex) {
|
|||
return true;
|
||||
}
|
||||
|
||||
const FBXGeometry& geometry = getFBXGeometry();
|
||||
const HFMGeometry& geometry = getHFMGeometry();
|
||||
const auto& networkMeshes = getGeometry()->getMeshes();
|
||||
// if our index is ever out of range for either meshes or networkMeshes, then skip it, and set our _meshGroupsKnown
|
||||
// to false to rebuild out mesh groups.
|
||||
|
@ -278,7 +278,7 @@ void Model::setRenderItemsNeedUpdate() {
|
|||
|
||||
void Model::reset() {
|
||||
if (isLoaded()) {
|
||||
const FBXGeometry& geometry = getFBXGeometry();
|
||||
const HFMGeometry& geometry = getHFMGeometry();
|
||||
_rig.reset(geometry);
|
||||
emit rigReset();
|
||||
emit rigReady();
|
||||
|
@ -295,13 +295,13 @@ bool Model::updateGeometry() {
|
|||
_needsReload = false;
|
||||
|
||||
// TODO: should all Models have a valid _rig?
|
||||
if (_rig.jointStatesEmpty() && getFBXGeometry().joints.size() > 0) {
|
||||
if (_rig.jointStatesEmpty() && getHFMGeometry().joints.size() > 0) {
|
||||
initJointStates();
|
||||
assert(_meshStates.empty());
|
||||
|
||||
const FBXGeometry& fbxGeometry = getFBXGeometry();
|
||||
const HFMGeometry& hfmGeometry = getHFMGeometry();
|
||||
int i = 0;
|
||||
foreach (const FBXMesh& mesh, fbxGeometry.meshes) {
|
||||
foreach (const HFMMesh& mesh, hfmGeometry.meshes) {
|
||||
MeshState state;
|
||||
state.clusterDualQuaternions.resize(mesh.clusters.size());
|
||||
state.clusterMatrices.resize(mesh.clusters.size());
|
||||
|
@ -319,7 +319,7 @@ bool Model::updateGeometry() {
|
|||
|
||||
// virtual
|
||||
void Model::initJointStates() {
|
||||
const FBXGeometry& geometry = getFBXGeometry();
|
||||
const HFMGeometry& geometry = getHFMGeometry();
|
||||
glm::mat4 modelOffset = glm::scale(_scale) * glm::translate(_offset);
|
||||
|
||||
_rig.initJointStates(geometry, modelOffset);
|
||||
|
@ -363,7 +363,7 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g
|
|||
int bestShapeID = 0;
|
||||
int bestSubMeshIndex = 0;
|
||||
|
||||
const FBXGeometry& geometry = getFBXGeometry();
|
||||
const HFMGeometry& geometry = getHFMGeometry();
|
||||
if (!_triangleSetsValid) {
|
||||
calculateTriangleSets(geometry);
|
||||
}
|
||||
|
@ -506,7 +506,7 @@ bool Model::findParabolaIntersectionAgainstSubMeshes(const glm::vec3& origin, co
|
|||
int bestShapeID = 0;
|
||||
int bestSubMeshIndex = 0;
|
||||
|
||||
const FBXGeometry& geometry = getFBXGeometry();
|
||||
const HFMGeometry& geometry = getHFMGeometry();
|
||||
if (!_triangleSetsValid) {
|
||||
calculateTriangleSets(geometry);
|
||||
}
|
||||
|
@ -641,7 +641,7 @@ bool Model::convexHullContains(glm::vec3 point) {
|
|||
QMutexLocker locker(&_mutex);
|
||||
|
||||
if (!_triangleSetsValid) {
|
||||
calculateTriangleSets(getFBXGeometry());
|
||||
calculateTriangleSets(getHFMGeometry());
|
||||
}
|
||||
|
||||
// If we are inside the models box, then consider the submeshes...
|
||||
|
@ -753,14 +753,14 @@ bool Model::replaceScriptableModelMeshPart(scriptable::ScriptableModelBasePointe
|
|||
}
|
||||
// update triangles for picking
|
||||
{
|
||||
FBXGeometry geometry;
|
||||
HFMGeometry geometry;
|
||||
for (const auto& newMesh : meshes) {
|
||||
FBXMesh mesh;
|
||||
HFMMesh mesh;
|
||||
mesh._mesh = newMesh.getMeshPointer();
|
||||
mesh.vertices = buffer_helpers::mesh::attributeToVector<glm::vec3>(mesh._mesh, gpu::Stream::POSITION);
|
||||
int numParts = (int)newMesh.getMeshPointer()->getNumParts();
|
||||
for (int partID = 0; partID < numParts; partID++) {
|
||||
FBXMeshPart part;
|
||||
HFMMeshPart part;
|
||||
part.triangleIndices = buffer_helpers::bufferToVector<int>(mesh._mesh->getIndexBuffer(), "part.triangleIndices");
|
||||
mesh.parts << part;
|
||||
}
|
||||
|
@ -789,12 +789,12 @@ scriptable::ScriptableModelBase Model::getScriptableModel() {
|
|||
return result;
|
||||
}
|
||||
|
||||
const FBXGeometry& geometry = getFBXGeometry();
|
||||
const HFMGeometry& geometry = getHFMGeometry();
|
||||
int numberOfMeshes = geometry.meshes.size();
|
||||
int shapeID = 0;
|
||||
for (int i = 0; i < numberOfMeshes; i++) {
|
||||
const FBXMesh& fbxMesh = geometry.meshes.at(i);
|
||||
if (auto mesh = fbxMesh._mesh) {
|
||||
const HFMMesh& hfmMesh = geometry.meshes.at(i);
|
||||
if (auto mesh = hfmMesh._mesh) {
|
||||
result.append(mesh);
|
||||
|
||||
int numParts = (int)mesh->getNumParts();
|
||||
|
@ -808,7 +808,7 @@ scriptable::ScriptableModelBase Model::getScriptableModel() {
|
|||
return result;
|
||||
}
|
||||
|
||||
void Model::calculateTriangleSets(const FBXGeometry& geometry) {
|
||||
void Model::calculateTriangleSets(const HFMGeometry& geometry) {
|
||||
PROFILE_RANGE(render, __FUNCTION__);
|
||||
|
||||
int numberOfMeshes = geometry.meshes.size();
|
||||
|
@ -818,14 +818,14 @@ void Model::calculateTriangleSets(const FBXGeometry& geometry) {
|
|||
_modelSpaceMeshTriangleSets.resize(numberOfMeshes);
|
||||
|
||||
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();
|
||||
auto& meshTriangleSets = _modelSpaceMeshTriangleSets[i];
|
||||
meshTriangleSets.resize(numberOfParts);
|
||||
|
||||
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];
|
||||
|
||||
|
@ -1114,7 +1114,7 @@ Extents Model::getBindExtents() const {
|
|||
if (!isActive()) {
|
||||
return Extents();
|
||||
}
|
||||
const Extents& bindExtents = getFBXGeometry().bindExtents;
|
||||
const Extents& bindExtents = getHFMGeometry().bindExtents;
|
||||
Extents scaledExtents = { bindExtents.minimum * _scale, bindExtents.maximum * _scale };
|
||||
return scaledExtents;
|
||||
}
|
||||
|
@ -1128,12 +1128,12 @@ Extents Model::getMeshExtents() const {
|
|||
if (!isActive()) {
|
||||
return Extents();
|
||||
}
|
||||
const Extents& extents = 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
|
||||
// is captured in the offset matrix
|
||||
glm::vec3 minimum = glm::vec3(getFBXGeometry().offset * glm::vec4(extents.minimum, 1.0f));
|
||||
glm::vec3 maximum = glm::vec3(getFBXGeometry().offset * glm::vec4(extents.maximum, 1.0f));
|
||||
glm::vec3 minimum = glm::vec3(getHFMGeometry().offset * glm::vec4(extents.minimum, 1.0f));
|
||||
glm::vec3 maximum = glm::vec3(getHFMGeometry().offset * glm::vec4(extents.maximum, 1.0f));
|
||||
Extents scaledExtents = { minimum * _scale, maximum * _scale };
|
||||
return scaledExtents;
|
||||
}
|
||||
|
@ -1143,12 +1143,12 @@ Extents Model::getUnscaledMeshExtents() const {
|
|||
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
|
||||
// is captured in the offset matrix
|
||||
glm::vec3 minimum = glm::vec3(getFBXGeometry().offset * glm::vec4(extents.minimum, 1.0f));
|
||||
glm::vec3 maximum = glm::vec3(getFBXGeometry().offset * glm::vec4(extents.maximum, 1.0f));
|
||||
glm::vec3 minimum = glm::vec3(getHFMGeometry().offset * glm::vec4(extents.minimum, 1.0f));
|
||||
glm::vec3 maximum = glm::vec3(getHFMGeometry().offset * glm::vec4(extents.maximum, 1.0f));
|
||||
Extents scaledExtents = { minimum, maximum };
|
||||
|
||||
return scaledExtents;
|
||||
|
@ -1171,11 +1171,11 @@ void Model::setJointTranslation(int index, bool valid, const glm::vec3& translat
|
|||
}
|
||||
|
||||
int Model::getParentJointIndex(int jointIndex) const {
|
||||
return (isActive() && jointIndex != -1) ? getFBXGeometry().joints.at(jointIndex).parentIndex : -1;
|
||||
return (isActive() && jointIndex != -1) ? getHFMGeometry().joints.at(jointIndex).parentIndex : -1;
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -1275,7 +1275,7 @@ QStringList Model::getJointNames() const {
|
|||
Q_RETURN_ARG(QStringList, result));
|
||||
return result;
|
||||
}
|
||||
return isActive() ? getFBXGeometry().getJointNames() : QStringList();
|
||||
return isActive() ? getHFMGeometry().getJointNames() : QStringList();
|
||||
}
|
||||
|
||||
void Model::setScaleToFit(bool scaleToFit, const glm::vec3& dimensions, bool forceRescale) {
|
||||
|
@ -1415,12 +1415,12 @@ void Model::updateClusterMatrices() {
|
|||
}
|
||||
|
||||
_needsUpdateClusterMatrices = false;
|
||||
const FBXGeometry& geometry = getFBXGeometry();
|
||||
const HFMGeometry& geometry = getHFMGeometry();
|
||||
for (int i = 0; i < (int) _meshStates.size(); 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++) {
|
||||
const FBXCluster& cluster = mesh.clusters.at(j);
|
||||
const HFMCluster& cluster = mesh.clusters.at(j);
|
||||
if (_useDualQuaternionSkinning) {
|
||||
auto jointPose = _rig.getJointPose(cluster.jointIndex);
|
||||
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
|
||||
int shapeID = 0;
|
||||
uint32_t numMeshes = (uint32_t)meshes.size();
|
||||
auto& fbxGeometry = getFBXGeometry();
|
||||
auto& hfmGeometry = getHFMGeometry();
|
||||
for (uint32_t i = 0; i < numMeshes; i++) {
|
||||
const auto& mesh = meshes.at(i);
|
||||
if (!mesh) {
|
||||
|
@ -1515,7 +1515,7 @@ void Model::createRenderItemSet() {
|
|||
// Create the render payloads
|
||||
int numParts = (int)mesh->getNumParts();
|
||||
for (int partIndex = 0; partIndex < numParts; partIndex++) {
|
||||
initializeBlendshapes(fbxGeometry.meshes[i], i);
|
||||
initializeBlendshapes(hfmGeometry.meshes[i], i);
|
||||
_modelMeshRenderItems << std::make_shared<ModelMeshPartPayload>(shared_from_this(), i, partIndex, shapeID, transform, offset);
|
||||
auto material = getGeometry()->getShapeMaterial(shapeID);
|
||||
_modelMeshMaterialNames.push_back(material ? material->getName() : "");
|
||||
|
@ -1600,7 +1600,7 @@ void Model::removeMaterial(graphics::MaterialPointer material, const std::string
|
|||
class CollisionRenderGeometry : public Geometry {
|
||||
public:
|
||||
CollisionRenderGeometry(graphics::MeshPointer mesh) {
|
||||
_fbxGeometry = std::make_shared<FBXGeometry>();
|
||||
_hfmGeometry = std::make_shared<HFMGeometry>();
|
||||
std::shared_ptr<GeometryMeshes> meshes = std::make_shared<GeometryMeshes>();
|
||||
meshes->push_back(mesh);
|
||||
_meshes = meshes;
|
||||
|
@ -1656,9 +1656,9 @@ void Blender::run() {
|
|||
if (_model && _model->isLoaded()) {
|
||||
DETAILED_PROFILE_RANGE_EX(simulation_animation, __FUNCTION__, 0xFFFF0000, 0, { { "url", _model->getURL().toString() } });
|
||||
int offset = 0;
|
||||
auto meshes = _model->getFBXGeometry().meshes;
|
||||
auto meshes = _model->getHFMGeometry().meshes;
|
||||
int meshIndex = 0;
|
||||
foreach(const FBXMesh& mesh, meshes) {
|
||||
foreach(const HFMMesh& mesh, meshes) {
|
||||
auto modelMeshBlendshapeOffsets = _model->_blendshapeOffsets.find(meshIndex++);
|
||||
if (mesh.blendshapes.isEmpty() || modelMeshBlendshapeOffsets == _model->_blendshapeOffsets.end()) {
|
||||
// Not blendshaped or not initialized
|
||||
|
@ -1688,7 +1688,7 @@ void Blender::run() {
|
|||
}
|
||||
|
||||
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) {
|
||||
for (auto j = range.begin(); j < range.end(); j++) {
|
||||
|
@ -1731,7 +1731,7 @@ bool Model::maybeStartBlender() {
|
|||
return false;
|
||||
}
|
||||
|
||||
void Model::initializeBlendshapes(const FBXMesh& mesh, int index) {
|
||||
void Model::initializeBlendshapes(const HFMMesh& mesh, int index) {
|
||||
if (mesh.blendshapes.empty()) {
|
||||
// mesh doesn't have blendshape, did we allocate one though ?
|
||||
if (_blendshapeOffsets.find(index) != _blendshapeOffsets.end()) {
|
||||
|
|
|
@ -185,7 +185,7 @@ public:
|
|||
|
||||
/// Provided as a convenience, will crash if !isLoaded()
|
||||
// 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(); }
|
||||
|
||||
|
@ -450,7 +450,7 @@ protected:
|
|||
|
||||
bool _overrideModelTransform { 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
|
||||
|
||||
virtual void createRenderItemSet();
|
||||
|
@ -506,7 +506,7 @@ protected:
|
|||
|
||||
bool shouldInvalidatePayloadShapeKey(int meshIndex);
|
||||
|
||||
void initializeBlendshapes(const FBXMesh& mesh, int index);
|
||||
void initializeBlendshapes(const HFMMesh& mesh, int index);
|
||||
|
||||
private:
|
||||
float _loadingPriority { 0.0f };
|
||||
|
|
|
@ -41,14 +41,14 @@ void SoftAttachmentModel::updateClusterMatrices() {
|
|||
|
||||
_needsUpdateClusterMatrices = false;
|
||||
|
||||
const FBXGeometry& geometry = getFBXGeometry();
|
||||
const HFMGeometry& geometry = getHFMGeometry();
|
||||
|
||||
for (int i = 0; i < (int) _meshStates.size(); 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++) {
|
||||
const FBXCluster& cluster = mesh.clusters.at(j);
|
||||
const HFMCluster& cluster = mesh.clusters.at(j);
|
||||
|
||||
// TODO: cache these look-ups as an optimization
|
||||
int jointIndexOverride = getJointIndexOverride(cluster.jointIndex);
|
||||
|
|
|
@ -100,7 +100,7 @@ bool TestFbx::isReady() const {
|
|||
|
||||
void TestFbx::parseFbx(const QByteArray& fbxData) {
|
||||
QVariantHash mapping;
|
||||
FBXGeometry* fbx = readFBX(fbxData, mapping);
|
||||
HFMGeometry* fbx = readFBX(fbxData, mapping);
|
||||
size_t totalVertexCount = 0;
|
||||
size_t totalIndexCount = 0;
|
||||
size_t totalPartCount = 0;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
#include <render/ShapePipeline.h>
|
||||
|
||||
class FBXGeometry;
|
||||
class HFMGeometry;
|
||||
|
||||
class TestFbx : public GpuTestBase {
|
||||
size_t _partCount { 0 };
|
||||
|
|
|
@ -28,8 +28,8 @@ const glm::quat identity = glm::quat();
|
|||
const glm::quat quaterTurnAroundZ = glm::angleAxis(0.5f * PI, zAxis);
|
||||
|
||||
|
||||
void makeTestFBXJoints(FBXGeometry& geometry) {
|
||||
FBXJoint joint;
|
||||
void makeTestFBXJoints(HFMGeometry& geometry) {
|
||||
HFMJoint joint;
|
||||
joint.isFree = false;
|
||||
joint.freeLineage.clear();
|
||||
joint.parentIndex = -1;
|
||||
|
@ -79,7 +79,7 @@ void makeTestFBXJoints(FBXGeometry& geometry) {
|
|||
|
||||
// compute each joint's transform
|
||||
for (int i = 1; i < (int)geometry.joints.size(); ++i) {
|
||||
FBXJoint& j = geometry.joints[i];
|
||||
HFMJoint& j = geometry.joints[i];
|
||||
int parentIndex = j.parentIndex;
|
||||
// World = ParentWorld * T * (Roff * Rp) * Rpre * R * Rpost * (Rp-1 * Soff * Sp * S * Sp-1)
|
||||
j.transform = geometry.joints[parentIndex].transform *
|
||||
|
@ -96,7 +96,7 @@ void AnimInverseKinematicsTests::testSingleChain() {
|
|||
|
||||
AnimContext context(false, false, false, glm::mat4(), glm::mat4());
|
||||
|
||||
FBXGeometry geometry;
|
||||
HFMGeometry geometry;
|
||||
makeTestFBXJoints(geometry);
|
||||
|
||||
// create a skeleton and doll
|
||||
|
|
|
@ -54,8 +54,8 @@ SkeletonDumpApp::SkeletonDumpApp(int argc, char* argv[]) : QCoreApplication(argc
|
|||
return;
|
||||
}
|
||||
QByteArray blob = file.readAll();
|
||||
std::unique_ptr<FBXGeometry> fbxGeometry(readFBX(blob, QVariantHash()));
|
||||
std::unique_ptr<AnimSkeleton> skeleton(new AnimSkeleton(*fbxGeometry));
|
||||
std::unique_ptr<HFMGeometry> geometry(readFBX(blob, QVariantHash()));
|
||||
std::unique_ptr<AnimSkeleton> skeleton(new AnimSkeleton(*geometry));
|
||||
skeleton->dump(verbose);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,16 +19,16 @@
|
|||
|
||||
// FBXReader jumbles the order of the meshes by reading them back out of a hashtable. This will put
|
||||
// them back in the order in which they appeared in the file.
|
||||
bool FBXGeometryLessThan(const FBXMesh& e1, const FBXMesh& e2) {
|
||||
bool HFMGeometryLessThan(const HFMMesh& e1, const HFMMesh& e2) {
|
||||
return e1.meshIndex < e2.meshIndex;
|
||||
}
|
||||
void reSortFBXGeometryMeshes(FBXGeometry& geometry) {
|
||||
qSort(geometry.meshes.begin(), geometry.meshes.end(), FBXGeometryLessThan);
|
||||
void reSortHFMGeometryMeshes(HFMGeometry& geometry) {
|
||||
qSort(geometry.meshes.begin(), geometry.meshes.end(), HFMGeometryLessThan);
|
||||
}
|
||||
|
||||
|
||||
// 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) {
|
||||
qDebug() << "reading FBX file =" << filename << "...";
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ bool vhacd::VHACDUtil::loadFBX(const QString filename, FBXGeometry& result) {
|
|||
}
|
||||
try {
|
||||
QByteArray fbxContents = fbx.readAll();
|
||||
FBXGeometry::Pointer geom;
|
||||
HFMGeometry::Pointer geom;
|
||||
if (filename.toLower().endsWith(".obj")) {
|
||||
bool combineParts = false;
|
||||
geom = OBJReader().readOBJ(fbxContents, QVariantHash(), combineParts);
|
||||
|
@ -53,7 +53,7 @@ bool vhacd::VHACDUtil::loadFBX(const QString filename, FBXGeometry& result) {
|
|||
}
|
||||
result = *geom;
|
||||
|
||||
reSortFBXGeometryMeshes(result);
|
||||
reSortHFMGeometryMeshes(result);
|
||||
} catch (const QString& error) {
|
||||
qWarning() << "error reading" << filename << ":" << error;
|
||||
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
|
||||
triangleIndices.reserve(triangleIndices.size() + (size_t)meshPart.triangleIndices.size());
|
||||
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
|
||||
// is converted into a tetrahedron and made into its own mesh-part.
|
||||
|
||||
std::vector<int> triangleIndices;
|
||||
foreach (const FBXMeshPart &meshPart, mesh.parts) {
|
||||
foreach (const HFMMeshPart &meshPart, mesh.parts) {
|
||||
getTrianglesInMeshPart(meshPart, triangleIndices);
|
||||
}
|
||||
|
||||
|
@ -145,7 +145,7 @@ void vhacd::VHACDUtil::fattenMesh(const FBXMesh& mesh, const glm::mat4& geometry
|
|||
int index3 = result.vertices.size();
|
||||
result.vertices << p3; // add the new point to the result mesh
|
||||
|
||||
FBXMeshPart newMeshPart;
|
||||
HFMMeshPart newMeshPart;
|
||||
setMeshPartDefaults(newMeshPart, "unknown");
|
||||
newMeshPart.triangleIndices << index0 << index1 << index2;
|
||||
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;
|
||||
const int TRIANGLE_STRIDE = 3;
|
||||
for (int i = 0; i < meshPart.triangleIndices.size(); i += TRIANGLE_STRIDE) {
|
||||
|
@ -242,7 +242,7 @@ bool isClosedManifold(const std::vector<int>& triangleIndices) {
|
|||
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
|
||||
uint32_t numHulls = convexifier->GetNConvexHulls();
|
||||
if (_verbose) {
|
||||
|
@ -256,8 +256,8 @@ void vhacd::VHACDUtil::getConvexResults(VHACD::IVHACD* convexifier, FBXMesh& res
|
|||
VHACD::IVHACD::ConvexHull hull;
|
||||
convexifier->GetConvexHull(j, hull);
|
||||
|
||||
resultMesh.parts.append(FBXMeshPart());
|
||||
FBXMeshPart& resultMeshPart = resultMesh.parts.last();
|
||||
resultMesh.parts.append(HFMMeshPart());
|
||||
HFMMeshPart& resultMeshPart = resultMesh.parts.last();
|
||||
|
||||
int hullIndexStart = resultMesh.vertices.size();
|
||||
resultMesh.vertices.reserve(hullIndexStart + hull.m_nPoints);
|
||||
|
@ -288,9 +288,9 @@ float computeDt(uint64_t start) {
|
|||
return (float)(usecTimestampNow() - start) / (float)USECS_PER_SECOND;
|
||||
}
|
||||
|
||||
bool vhacd::VHACDUtil::computeVHACD(FBXGeometry& geometry,
|
||||
bool vhacd::VHACDUtil::computeVHACD(HFMGeometry& geometry,
|
||||
VHACD::IVHACD::Parameters params,
|
||||
FBXGeometry& result,
|
||||
HFMGeometry& result,
|
||||
float minimumMeshSize, float maximumMeshSize) {
|
||||
if (_verbose) {
|
||||
qDebug() << "meshes =" << geometry.meshes.size();
|
||||
|
@ -298,7 +298,7 @@ bool vhacd::VHACDUtil::computeVHACD(FBXGeometry& geometry,
|
|||
|
||||
// count the mesh-parts
|
||||
int numParts = 0;
|
||||
foreach (const FBXMesh& mesh, geometry.meshes) {
|
||||
foreach (const HFMMesh& mesh, geometry.meshes) {
|
||||
numParts += mesh.parts.size();
|
||||
}
|
||||
if (_verbose) {
|
||||
|
@ -308,15 +308,15 @@ bool vhacd::VHACDUtil::computeVHACD(FBXGeometry& geometry,
|
|||
VHACD::IVHACD * convexifier = VHACD::CreateVHACD();
|
||||
|
||||
result.meshExtents.reset();
|
||||
result.meshes.append(FBXMesh());
|
||||
FBXMesh &resultMesh = result.meshes.last();
|
||||
result.meshes.append(HFMMesh());
|
||||
HFMMesh &resultMesh = result.meshes.last();
|
||||
|
||||
const uint32_t POINT_STRIDE = 3;
|
||||
const uint32_t TRIANGLE_STRIDE = 3;
|
||||
|
||||
int meshIndex = 0;
|
||||
int validPartsFound = 0;
|
||||
foreach (const FBXMesh& mesh, geometry.meshes) {
|
||||
foreach (const HFMMesh& mesh, geometry.meshes) {
|
||||
|
||||
// find duplicate points
|
||||
int numDupes = 0;
|
||||
|
@ -354,7 +354,7 @@ bool vhacd::VHACDUtil::computeVHACD(FBXGeometry& geometry,
|
|||
|
||||
int partIndex = 0;
|
||||
std::vector<int> triangleIndices;
|
||||
foreach (const FBXMeshPart &meshPart, mesh.parts) {
|
||||
foreach (const HFMMeshPart &meshPart, mesh.parts) {
|
||||
triangleIndices.clear();
|
||||
getTrianglesInMeshPart(meshPart, triangleIndices);
|
||||
|
||||
|
@ -421,7 +421,7 @@ bool vhacd::VHACDUtil::computeVHACD(FBXGeometry& geometry,
|
|||
|
||||
triangleIndices.clear();
|
||||
for (auto index : openParts) {
|
||||
const FBXMeshPart &meshPart = mesh.parts[index];
|
||||
const HFMMeshPart &meshPart = mesh.parts[index];
|
||||
getTrianglesInMeshPart(meshPart, triangleIndices);
|
||||
}
|
||||
|
||||
|
|
|
@ -27,16 +27,16 @@ namespace vhacd {
|
|||
public:
|
||||
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,
|
||||
FBXGeometry& result,
|
||||
HFMGeometry& result,
|
||||
float minimumMeshSize, float maximumMeshSize);
|
||||
|
||||
void getConvexResults(VHACD::IVHACD* convexifier, FBXMesh& resultMesh) const;
|
||||
void getConvexResults(VHACD::IVHACD* convexifier, HFMMesh& resultMesh) const;
|
||||
|
||||
~VHACDUtil();
|
||||
|
||||
|
@ -55,6 +55,6 @@ namespace vhacd {
|
|||
};
|
||||
}
|
||||
|
||||
AABox getAABoxForMeshPart(const FBXMeshPart &meshPart);
|
||||
AABox getAABoxForMeshPart(const HFMMeshPart &meshPart);
|
||||
|
||||
#endif //hifi_VHACDUtil_h
|
||||
|
|
|
@ -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);
|
||||
if (!file.open(QIODevice::WriteOnly)) {
|
||||
qWarning() << "unable to write to" << outFileName;
|
||||
|
@ -56,9 +56,9 @@ bool VHACDUtilApp::writeOBJ(QString outFileName, FBXGeometry& geometry, bool out
|
|||
|
||||
int vertexIndexOffset = 0;
|
||||
|
||||
foreach (const FBXMesh& mesh, geometry.meshes) {
|
||||
foreach (const HFMMesh& mesh, geometry.meshes) {
|
||||
bool verticesHaveBeenOutput = false;
|
||||
foreach (const FBXMeshPart &meshPart, mesh.parts) {
|
||||
foreach (const HFMMeshPart &meshPart, mesh.parts) {
|
||||
if (whichMeshPart >= 0 && nth != (unsigned int) whichMeshPart) {
|
||||
nth++;
|
||||
continue;
|
||||
|
@ -297,7 +297,7 @@ VHACDUtilApp::VHACDUtilApp(int argc, char* argv[]) :
|
|||
}
|
||||
|
||||
// load the mesh
|
||||
FBXGeometry fbx;
|
||||
HFMGeometry fbx;
|
||||
auto begin = std::chrono::high_resolution_clock::now();
|
||||
if (!vUtil.loadFBX(inputFilename, fbx)){
|
||||
_returnCode = VHACD_RETURN_CODE_FAILURE_TO_READ;
|
||||
|
@ -315,8 +315,8 @@ VHACDUtilApp::VHACDUtilApp(int argc, char* argv[]) :
|
|||
QVector<QString> infileExtensions = {"fbx", "obj"};
|
||||
QString baseFileName = fileNameWithoutExtension(outputFilename, infileExtensions);
|
||||
int count = 0;
|
||||
foreach (const FBXMesh& mesh, fbx.meshes) {
|
||||
foreach (const FBXMeshPart &meshPart, mesh.parts) {
|
||||
foreach (const HFMMesh& mesh, fbx.meshes) {
|
||||
foreach (const HFMMeshPart &meshPart, mesh.parts) {
|
||||
QString outputFileName = baseFileName + "-" + QString::number(count) + ".obj";
|
||||
writeOBJ(outputFileName, fbx, outputCentimeters, count);
|
||||
count++;
|
||||
|
@ -358,7 +358,7 @@ VHACDUtilApp::VHACDUtilApp(int argc, char* argv[]) :
|
|||
}
|
||||
begin = std::chrono::high_resolution_clock::now();
|
||||
|
||||
FBXGeometry result;
|
||||
HFMGeometry result;
|
||||
bool success = vUtil.computeVHACD(fbx, params, result, minimumMeshSize, maximumMeshSize);
|
||||
|
||||
end = std::chrono::high_resolution_clock::now();
|
||||
|
@ -377,9 +377,9 @@ VHACDUtilApp::VHACDUtilApp(int argc, char* argv[]) :
|
|||
|
||||
int totalVertices = 0;
|
||||
int totalTriangles = 0;
|
||||
foreach (const FBXMesh& mesh, result.meshes) {
|
||||
foreach (const HFMMesh& mesh, result.meshes) {
|
||||
totalVertices += mesh.vertices.size();
|
||||
foreach (const FBXMeshPart &meshPart, mesh.parts) {
|
||||
foreach (const HFMMeshPart &meshPart, mesh.parts) {
|
||||
totalTriangles += meshPart.triangleIndices.size() / 3;
|
||||
// each quad was made into two triangles
|
||||
totalTriangles += 2 * meshPart.quadIndices.size() / 4;
|
||||
|
@ -398,17 +398,17 @@ VHACDUtilApp::VHACDUtilApp(int argc, char* argv[]) :
|
|||
}
|
||||
|
||||
if (fattenFaces) {
|
||||
FBXGeometry newFbx;
|
||||
FBXMesh result;
|
||||
HFMGeometry newFbx;
|
||||
HFMMesh result;
|
||||
|
||||
// count the mesh-parts
|
||||
unsigned int meshCount = 0;
|
||||
foreach (const FBXMesh& mesh, fbx.meshes) {
|
||||
foreach (const HFMMesh& mesh, fbx.meshes) {
|
||||
meshCount += mesh.parts.size();
|
||||
}
|
||||
|
||||
result.modelTransform = glm::mat4(); // Identity matrix
|
||||
foreach (const FBXMesh& mesh, fbx.meshes) {
|
||||
foreach (const HFMMesh& mesh, fbx.meshes) {
|
||||
vUtil.fattenMesh(mesh, fbx.offset, result);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ public:
|
|||
VHACDUtilApp(int argc, char* argv[]);
|
||||
~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; }
|
||||
|
||||
|
|
Loading…
Reference in a new issue