mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-08 14:10:07 +02:00
Fix warnings related to deprecated usage of multiple keys in QHash and QMap
This replaces those uses with QMultiHash and QMultiMap
This commit is contained in:
parent
57167cdfef
commit
d77c8bbe41
17 changed files with 226 additions and 221 deletions
|
@ -89,12 +89,12 @@ bool ModelPackager::loadModel() {
|
||||||
qCDebug(interfaceapp) << "Reading FST file";
|
qCDebug(interfaceapp) << "Reading FST file";
|
||||||
_mapping = FSTReader::readMapping(fst.readAll());
|
_mapping = FSTReader::readMapping(fst.readAll());
|
||||||
fst.close();
|
fst.close();
|
||||||
|
|
||||||
_fbxInfo = QFileInfo(_modelFile.path() + "/" + _mapping.value(FILENAME_FIELD).toString());
|
_fbxInfo = QFileInfo(_modelFile.path() + "/" + _mapping.value(FILENAME_FIELD).toString());
|
||||||
} else {
|
} else {
|
||||||
_fbxInfo = QFileInfo(_modelFile.filePath());
|
_fbxInfo = QFileInfo(_modelFile.filePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
// open the fbx file
|
// open the fbx file
|
||||||
QFile fbx(_fbxInfo.filePath());
|
QFile fbx(_fbxInfo.filePath());
|
||||||
if (!_fbxInfo.exists() || !_fbxInfo.isFile() || !fbx.open(QIODevice::ReadOnly)) {
|
if (!_fbxInfo.exists() || !_fbxInfo.isFile() || !fbx.open(QIODevice::ReadOnly)) {
|
||||||
|
@ -132,7 +132,7 @@ bool ModelPackager::editProperties() {
|
||||||
QVariantHash joints = _mapping.value(JOINT_FIELD).toHash();
|
QVariantHash joints = _mapping.value(JOINT_FIELD).toHash();
|
||||||
if (!joints.contains("jointRoot")) {
|
if (!joints.contains("jointRoot")) {
|
||||||
qWarning() << "root joint not configured for skeleton.";
|
qWarning() << "root joint not configured for skeleton.";
|
||||||
|
|
||||||
QString message = "Your did not configure a root joint for your skeleton model.\n\nPackaging will be canceled.";
|
QString message = "Your did not configure a root joint for your skeleton model.\n\nPackaging will be canceled.";
|
||||||
QMessageBox msgBox;
|
QMessageBox msgBox;
|
||||||
msgBox.setWindowTitle("Model Packager");
|
msgBox.setWindowTitle("Model Packager");
|
||||||
|
@ -140,10 +140,10 @@ bool ModelPackager::editProperties() {
|
||||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||||
msgBox.setIcon(QMessageBox::Warning);
|
msgBox.setIcon(QMessageBox::Warning);
|
||||||
msgBox.exec();
|
msgBox.exec();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ bool ModelPackager::zipModel() {
|
||||||
QTemporaryDir dir;
|
QTemporaryDir dir;
|
||||||
dir.setAutoRemove(true);
|
dir.setAutoRemove(true);
|
||||||
QDir tempDir(dir.path());
|
QDir tempDir(dir.path());
|
||||||
|
|
||||||
QByteArray nameField = _mapping.value(NAME_FIELD).toByteArray();
|
QByteArray nameField = _mapping.value(NAME_FIELD).toByteArray();
|
||||||
tempDir.mkpath(nameField + "/textures");
|
tempDir.mkpath(nameField + "/textures");
|
||||||
tempDir.mkpath(nameField + "/scripts");
|
tempDir.mkpath(nameField + "/scripts");
|
||||||
|
@ -179,11 +179,11 @@ bool ModelPackager::zipModel() {
|
||||||
auto list = wdir.entryList(QDir::NoDotAndDotDot | QDir::AllEntries);
|
auto list = wdir.entryList(QDir::NoDotAndDotDot | QDir::AllEntries);
|
||||||
for (auto script : list) {
|
for (auto script : list) {
|
||||||
auto sc = tempDir.relativeFilePath(scriptDir.path()) + "/" + QUrl(script).fileName();
|
auto sc = tempDir.relativeFilePath(scriptDir.path()) + "/" + QUrl(script).fileName();
|
||||||
_mapping.insertMulti(SCRIPT_FIELD, sc);
|
_mapping.insert(SCRIPT_FIELD, sc);
|
||||||
}
|
}
|
||||||
copyDirectoryContent(wdir, scriptDir);
|
copyDirectoryContent(wdir, scriptDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy LODs
|
// Copy LODs
|
||||||
QVariantHash lodField = _mapping.value(LOD_FIELD).toHash();
|
QVariantHash lodField = _mapping.value(LOD_FIELD).toHash();
|
||||||
if (!lodField.empty()) {
|
if (!lodField.empty()) {
|
||||||
|
@ -196,16 +196,16 @@ bool ModelPackager::zipModel() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy FBX
|
// Copy FBX
|
||||||
QFile fbx(_fbxInfo.filePath());
|
QFile fbx(_fbxInfo.filePath());
|
||||||
QByteArray filenameField = _mapping.value(FILENAME_FIELD).toByteArray();
|
QByteArray filenameField = _mapping.value(FILENAME_FIELD).toByteArray();
|
||||||
QString newPath = fbxDir.path() + "/" + QFileInfo(filenameField).fileName();
|
QString newPath = fbxDir.path() + "/" + QFileInfo(filenameField).fileName();
|
||||||
fbx.copy(newPath);
|
fbx.copy(newPath);
|
||||||
|
|
||||||
// Correct FST
|
// Correct FST
|
||||||
_mapping[FILENAME_FIELD] = tempDir.relativeFilePath(newPath);
|
_mapping.replace(FILENAME_FIELD, tempDir.relativeFilePath(newPath));
|
||||||
_mapping[TEXDIR_FIELD] = tempDir.relativeFilePath(texDir.path());
|
_mapping.replace(TEXDIR_FIELD, tempDir.relativeFilePath(texDir.path()));
|
||||||
|
|
||||||
for (auto multi : _mapping.values(SCRIPT_FIELD)) {
|
for (auto multi : _mapping.values(SCRIPT_FIELD)) {
|
||||||
multi.fromValue(tempDir.relativeFilePath(scriptDir.path()) + multi.toString());
|
multi.fromValue(tempDir.relativeFilePath(scriptDir.path()) + multi.toString());
|
||||||
|
@ -219,15 +219,15 @@ bool ModelPackager::zipModel() {
|
||||||
qCDebug(interfaceapp) << "Couldn't write FST file" << fst.fileName();
|
qCDebug(interfaceapp) << "Couldn't write FST file" << fst.fileName();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QString saveDirPath = QFileDialog::getExistingDirectory(nullptr, "Save Model",
|
QString saveDirPath = QFileDialog::getExistingDirectory(nullptr, "Save Model",
|
||||||
"", QFileDialog::ShowDirsOnly);
|
"", QFileDialog::ShowDirsOnly);
|
||||||
if (saveDirPath.isEmpty()) {
|
if (saveDirPath.isEmpty()) {
|
||||||
qCDebug(interfaceapp) << "Invalid directory" << saveDirPath;
|
qCDebug(interfaceapp) << "Invalid directory" << saveDirPath;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDir saveDir(saveDirPath);
|
QDir saveDir(saveDirPath);
|
||||||
copyDirectoryContent(tempDir, saveDir);
|
copyDirectoryContent(tempDir, saveDir);
|
||||||
return true;
|
return true;
|
||||||
|
@ -243,11 +243,11 @@ void ModelPackager::populateBasicMapping(QVariantHash& mapping, QString filename
|
||||||
hfmModel.blendshapeChannelNames.contains("Blink_Left") &&
|
hfmModel.blendshapeChannelNames.contains("Blink_Left") &&
|
||||||
hfmModel.blendshapeChannelNames.contains("Blink_Right") &&
|
hfmModel.blendshapeChannelNames.contains("Blink_Right") &&
|
||||||
hfmModel.blendshapeChannelNames.contains("Squint_Right"));
|
hfmModel.blendshapeChannelNames.contains("Squint_Right"));
|
||||||
|
|
||||||
if (!mapping.contains(NAME_FIELD)) {
|
if (!mapping.contains(NAME_FIELD)) {
|
||||||
mapping.insert(NAME_FIELD, QFileInfo(filename).baseName());
|
mapping.insert(NAME_FIELD, QFileInfo(filename).baseName());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mapping.contains(FILENAME_FIELD)) {
|
if (!mapping.contains(FILENAME_FIELD)) {
|
||||||
QDir root(_modelFile.path());
|
QDir root(_modelFile.path());
|
||||||
mapping.insert(FILENAME_FIELD, root.relativeFilePath(filename));
|
mapping.insert(FILENAME_FIELD, root.relativeFilePath(filename));
|
||||||
|
@ -274,7 +274,7 @@ void ModelPackager::populateBasicMapping(QVariantHash& mapping, QString filename
|
||||||
if (!joints.contains("jointNeck")) {
|
if (!joints.contains("jointNeck")) {
|
||||||
joints.insert("jointNeck", hfmModel.jointIndices.contains("jointNeck") ? "jointNeck" : "Neck");
|
joints.insert("jointNeck", hfmModel.jointIndices.contains("jointNeck") ? "jointNeck" : "Neck");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!joints.contains("jointRoot")) {
|
if (!joints.contains("jointRoot")) {
|
||||||
joints.insert("jointRoot", "Hips");
|
joints.insert("jointRoot", "Hips");
|
||||||
}
|
}
|
||||||
|
@ -287,68 +287,68 @@ void ModelPackager::populateBasicMapping(QVariantHash& mapping, QString filename
|
||||||
if (!joints.contains("jointRightHand")) {
|
if (!joints.contains("jointRightHand")) {
|
||||||
joints.insert("jointRightHand", "RightHand");
|
joints.insert("jointRightHand", "RightHand");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!joints.contains("jointHead")) {
|
if (!joints.contains("jointHead")) {
|
||||||
const char* topName = likelyMixamoFile ? "HeadTop_End" : "HeadEnd";
|
const char* topName = likelyMixamoFile ? "HeadTop_End" : "HeadEnd";
|
||||||
joints.insert("jointHead", hfmModel.jointIndices.contains(topName) ? topName : "Head");
|
joints.insert("jointHead", hfmModel.jointIndices.contains(topName) ? topName : "Head");
|
||||||
}
|
}
|
||||||
|
|
||||||
mapping.insert(JOINT_FIELD, joints);
|
mapping.insert(JOINT_FIELD, joints);
|
||||||
|
|
||||||
// If there are no blendshape mappings, and we detect that this is likely a mixamo file,
|
// If there are no blendshape mappings, and we detect that this is likely a mixamo file,
|
||||||
// then we can add the default mixamo to blendshape mappings.
|
// then we can add the default mixamo to blendshape mappings.
|
||||||
if (!mapping.contains(BLENDSHAPE_FIELD) && likelyMixamoFile) {
|
if (!mapping.contains(BLENDSHAPE_FIELD) && likelyMixamoFile) {
|
||||||
QVariantHash blendshapes;
|
QVariantHash blendshapes;
|
||||||
blendshapes.insertMulti("BrowsD_L", QVariantList() << "BrowsDown_Left" << 1.0);
|
blendshapes.insert("BrowsD_L", QVariantList() << "BrowsDown_Left" << 1.0);
|
||||||
blendshapes.insertMulti("BrowsD_R", QVariantList() << "BrowsDown_Right" << 1.0);
|
blendshapes.insert("BrowsD_R", QVariantList() << "BrowsDown_Right" << 1.0);
|
||||||
blendshapes.insertMulti("BrowsU_C", QVariantList() << "BrowsUp_Left" << 1.0);
|
blendshapes.insert("BrowsU_C", QVariantList() << "BrowsUp_Left" << 1.0);
|
||||||
blendshapes.insertMulti("BrowsU_C", QVariantList() << "BrowsUp_Right" << 1.0);
|
blendshapes.insert("BrowsU_C", QVariantList() << "BrowsUp_Right" << 1.0);
|
||||||
blendshapes.insertMulti("BrowsU_L", QVariantList() << "BrowsUp_Left" << 1.0);
|
blendshapes.insert("BrowsU_L", QVariantList() << "BrowsUp_Left" << 1.0);
|
||||||
blendshapes.insertMulti("BrowsU_R", QVariantList() << "BrowsUp_Right" << 1.0);
|
blendshapes.insert("BrowsU_R", QVariantList() << "BrowsUp_Right" << 1.0);
|
||||||
blendshapes.insertMulti("ChinLowerRaise", QVariantList() << "Jaw_Up" << 1.0);
|
blendshapes.insert("ChinLowerRaise", QVariantList() << "Jaw_Up" << 1.0);
|
||||||
blendshapes.insertMulti("ChinUpperRaise", QVariantList() << "UpperLipUp_Left" << 0.5);
|
blendshapes.insert("ChinUpperRaise", QVariantList() << "UpperLipUp_Left" << 0.5);
|
||||||
blendshapes.insertMulti("ChinUpperRaise", QVariantList() << "UpperLipUp_Right" << 0.5);
|
blendshapes.insert("ChinUpperRaise", QVariantList() << "UpperLipUp_Right" << 0.5);
|
||||||
blendshapes.insertMulti("EyeBlink_L", QVariantList() << "Blink_Left" << 1.0);
|
blendshapes.insert("EyeBlink_L", QVariantList() << "Blink_Left" << 1.0);
|
||||||
blendshapes.insertMulti("EyeBlink_R", QVariantList() << "Blink_Right" << 1.0);
|
blendshapes.insert("EyeBlink_R", QVariantList() << "Blink_Right" << 1.0);
|
||||||
blendshapes.insertMulti("EyeOpen_L", QVariantList() << "EyesWide_Left" << 1.0);
|
blendshapes.insert("EyeOpen_L", QVariantList() << "EyesWide_Left" << 1.0);
|
||||||
blendshapes.insertMulti("EyeOpen_R", QVariantList() << "EyesWide_Right" << 1.0);
|
blendshapes.insert("EyeOpen_R", QVariantList() << "EyesWide_Right" << 1.0);
|
||||||
blendshapes.insertMulti("EyeSquint_L", QVariantList() << "Squint_Left" << 1.0);
|
blendshapes.insert("EyeSquint_L", QVariantList() << "Squint_Left" << 1.0);
|
||||||
blendshapes.insertMulti("EyeSquint_R", QVariantList() << "Squint_Right" << 1.0);
|
blendshapes.insert("EyeSquint_R", QVariantList() << "Squint_Right" << 1.0);
|
||||||
blendshapes.insertMulti("JawFwd", QVariantList() << "JawForeward" << 1.0);
|
blendshapes.insert("JawFwd", QVariantList() << "JawForeward" << 1.0);
|
||||||
blendshapes.insertMulti("JawLeft", QVariantList() << "JawRotateY_Left" << 0.5);
|
blendshapes.insert("JawLeft", QVariantList() << "JawRotateY_Left" << 0.5);
|
||||||
blendshapes.insertMulti("JawOpen", QVariantList() << "MouthOpen" << 0.7);
|
blendshapes.insert("JawOpen", QVariantList() << "MouthOpen" << 0.7);
|
||||||
blendshapes.insertMulti("JawRight", QVariantList() << "Jaw_Right" << 1.0);
|
blendshapes.insert("JawRight", QVariantList() << "Jaw_Right" << 1.0);
|
||||||
blendshapes.insertMulti("LipsFunnel", QVariantList() << "JawForeward" << 0.39);
|
blendshapes.insert("LipsFunnel", QVariantList() << "JawForeward" << 0.39);
|
||||||
blendshapes.insertMulti("LipsFunnel", QVariantList() << "Jaw_Down" << 0.36);
|
blendshapes.insert("LipsFunnel", QVariantList() << "Jaw_Down" << 0.36);
|
||||||
blendshapes.insertMulti("LipsFunnel", QVariantList() << "MouthNarrow_Left" << 1.0);
|
blendshapes.insert("LipsFunnel", QVariantList() << "MouthNarrow_Left" << 1.0);
|
||||||
blendshapes.insertMulti("LipsFunnel", QVariantList() << "MouthNarrow_Right" << 1.0);
|
blendshapes.insert("LipsFunnel", QVariantList() << "MouthNarrow_Right" << 1.0);
|
||||||
blendshapes.insertMulti("LipsFunnel", QVariantList() << "MouthWhistle_NarrowAdjust_Left" << 0.5);
|
blendshapes.insert("LipsFunnel", QVariantList() << "MouthWhistle_NarrowAdjust_Left" << 0.5);
|
||||||
blendshapes.insertMulti("LipsFunnel", QVariantList() << "MouthWhistle_NarrowAdjust_Right" << 0.5);
|
blendshapes.insert("LipsFunnel", QVariantList() << "MouthWhistle_NarrowAdjust_Right" << 0.5);
|
||||||
blendshapes.insertMulti("LipsFunnel", QVariantList() << "TongueUp" << 1.0);
|
blendshapes.insert("LipsFunnel", QVariantList() << "TongueUp" << 1.0);
|
||||||
blendshapes.insertMulti("LipsLowerClose", QVariantList() << "LowerLipIn" << 1.0);
|
blendshapes.insert("LipsLowerClose", QVariantList() << "LowerLipIn" << 1.0);
|
||||||
blendshapes.insertMulti("LipsLowerDown", QVariantList() << "LowerLipDown_Left" << 0.7);
|
blendshapes.insert("LipsLowerDown", QVariantList() << "LowerLipDown_Left" << 0.7);
|
||||||
blendshapes.insertMulti("LipsLowerDown", QVariantList() << "LowerLipDown_Right" << 0.7);
|
blendshapes.insert("LipsLowerDown", QVariantList() << "LowerLipDown_Right" << 0.7);
|
||||||
blendshapes.insertMulti("LipsLowerOpen", QVariantList() << "LowerLipOut" << 1.0);
|
blendshapes.insert("LipsLowerOpen", QVariantList() << "LowerLipOut" << 1.0);
|
||||||
blendshapes.insertMulti("LipsPucker", QVariantList() << "MouthNarrow_Left" << 1.0);
|
blendshapes.insert("LipsPucker", QVariantList() << "MouthNarrow_Left" << 1.0);
|
||||||
blendshapes.insertMulti("LipsPucker", QVariantList() << "MouthNarrow_Right" << 1.0);
|
blendshapes.insert("LipsPucker", QVariantList() << "MouthNarrow_Right" << 1.0);
|
||||||
blendshapes.insertMulti("LipsUpperClose", QVariantList() << "UpperLipIn" << 1.0);
|
blendshapes.insert("LipsUpperClose", QVariantList() << "UpperLipIn" << 1.0);
|
||||||
blendshapes.insertMulti("LipsUpperOpen", QVariantList() << "UpperLipOut" << 1.0);
|
blendshapes.insert("LipsUpperOpen", QVariantList() << "UpperLipOut" << 1.0);
|
||||||
blendshapes.insertMulti("LipsUpperUp", QVariantList() << "UpperLipUp_Left" << 0.7);
|
blendshapes.insert("LipsUpperUp", QVariantList() << "UpperLipUp_Left" << 0.7);
|
||||||
blendshapes.insertMulti("LipsUpperUp", QVariantList() << "UpperLipUp_Right" << 0.7);
|
blendshapes.insert("LipsUpperUp", QVariantList() << "UpperLipUp_Right" << 0.7);
|
||||||
blendshapes.insertMulti("MouthDimple_L", QVariantList() << "Smile_Left" << 0.25);
|
blendshapes.insert("MouthDimple_L", QVariantList() << "Smile_Left" << 0.25);
|
||||||
blendshapes.insertMulti("MouthDimple_R", QVariantList() << "Smile_Right" << 0.25);
|
blendshapes.insert("MouthDimple_R", QVariantList() << "Smile_Right" << 0.25);
|
||||||
blendshapes.insertMulti("MouthFrown_L", QVariantList() << "Frown_Left" << 1.0);
|
blendshapes.insert("MouthFrown_L", QVariantList() << "Frown_Left" << 1.0);
|
||||||
blendshapes.insertMulti("MouthFrown_R", QVariantList() << "Frown_Right" << 1.0);
|
blendshapes.insert("MouthFrown_R", QVariantList() << "Frown_Right" << 1.0);
|
||||||
blendshapes.insertMulti("MouthLeft", QVariantList() << "Midmouth_Left" << 1.0);
|
blendshapes.insert("MouthLeft", QVariantList() << "Midmouth_Left" << 1.0);
|
||||||
blendshapes.insertMulti("MouthRight", QVariantList() << "Midmouth_Right" << 1.0);
|
blendshapes.insert("MouthRight", QVariantList() << "Midmouth_Right" << 1.0);
|
||||||
blendshapes.insertMulti("MouthSmile_L", QVariantList() << "Smile_Left" << 1.0);
|
blendshapes.insert("MouthSmile_L", QVariantList() << "Smile_Left" << 1.0);
|
||||||
blendshapes.insertMulti("MouthSmile_R", QVariantList() << "Smile_Right" << 1.0);
|
blendshapes.insert("MouthSmile_R", QVariantList() << "Smile_Right" << 1.0);
|
||||||
blendshapes.insertMulti("Puff", QVariantList() << "CheekPuff_Left" << 1.0);
|
blendshapes.insert("Puff", QVariantList() << "CheekPuff_Left" << 1.0);
|
||||||
blendshapes.insertMulti("Puff", QVariantList() << "CheekPuff_Right" << 1.0);
|
blendshapes.insert("Puff", QVariantList() << "CheekPuff_Right" << 1.0);
|
||||||
blendshapes.insertMulti("Sneer", QVariantList() << "NoseScrunch_Left" << 0.75);
|
blendshapes.insert("Sneer", QVariantList() << "NoseScrunch_Left" << 0.75);
|
||||||
blendshapes.insertMulti("Sneer", QVariantList() << "NoseScrunch_Right" << 0.75);
|
blendshapes.insert("Sneer", QVariantList() << "NoseScrunch_Right" << 0.75);
|
||||||
blendshapes.insertMulti("Sneer", QVariantList() << "Squint_Left" << 0.5);
|
blendshapes.insert("Sneer", QVariantList() << "Squint_Left" << 0.5);
|
||||||
blendshapes.insertMulti("Sneer", QVariantList() << "Squint_Right" << 0.5);
|
blendshapes.insert("Sneer", QVariantList() << "Squint_Right" << 0.5);
|
||||||
mapping.insert(BLENDSHAPE_FIELD, blendshapes);
|
mapping.insert(BLENDSHAPE_FIELD, blendshapes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -362,7 +362,7 @@ void ModelPackager::listTextures() {
|
||||||
}
|
}
|
||||||
if (!mat.normalTexture.filename.isEmpty() && mat.normalTexture.content.isEmpty() &&
|
if (!mat.normalTexture.filename.isEmpty() && mat.normalTexture.content.isEmpty() &&
|
||||||
!_textures.contains(mat.normalTexture.filename)) {
|
!_textures.contains(mat.normalTexture.filename)) {
|
||||||
|
|
||||||
_textures << mat.normalTexture.filename;
|
_textures << mat.normalTexture.filename;
|
||||||
}
|
}
|
||||||
if (!mat.specularTexture.filename.isEmpty() && mat.specularTexture.content.isEmpty() &&
|
if (!mat.specularTexture.filename.isEmpty() && mat.specularTexture.content.isEmpty() &&
|
||||||
|
@ -387,7 +387,7 @@ bool ModelPackager::copyTextures(const QString& oldDir, const QDir& newDir) {
|
||||||
QString dirPath = newDir.relativeFilePath(QFileInfo(newPath).path());
|
QString dirPath = newDir.relativeFilePath(QFileInfo(newPath).path());
|
||||||
newDir.mkpath(dirPath);
|
newDir.mkpath(dirPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
QFile texFile(oldPath);
|
QFile texFile(oldPath);
|
||||||
if (texFile.exists() && texFile.open(QIODevice::ReadOnly)) {
|
if (texFile.exists() && texFile.open(QIODevice::ReadOnly)) {
|
||||||
// Check if texture needs to be recoded
|
// Check if texture needs to be recoded
|
||||||
|
@ -402,7 +402,7 @@ bool ModelPackager::copyTextures(const QString& oldDir, const QDir& newDir) {
|
||||||
image = image.scaled(MAX_TEXTURE_SIZE, MAX_TEXTURE_SIZE, Qt::KeepAspectRatio);
|
image = image.scaled(MAX_TEXTURE_SIZE, MAX_TEXTURE_SIZE, Qt::KeepAspectRatio);
|
||||||
mustRecode = true;
|
mustRecode = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy texture
|
// Copy texture
|
||||||
if (mustRecode) {
|
if (mustRecode) {
|
||||||
QFile newTexFile(newPath);
|
QFile newTexFile(newPath);
|
||||||
|
@ -415,14 +415,14 @@ bool ModelPackager::copyTextures(const QString& oldDir, const QDir& newDir) {
|
||||||
errors += QString("\n%1").arg(oldPath);
|
errors += QString("\n%1").arg(oldPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!errors.isEmpty()) {
|
if (!errors.isEmpty()) {
|
||||||
OffscreenUi::asyncWarning(nullptr, "ModelPackager::copyTextures()",
|
OffscreenUi::asyncWarning(nullptr, "ModelPackager::copyTextures()",
|
||||||
"Missing textures:" + errors);
|
"Missing textures:" + errors);
|
||||||
qCDebug(interfaceapp) << "ModelPackager::copyTextures():" << errors;
|
qCDebug(interfaceapp) << "ModelPackager::copyTextures():" << errors;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QVariantHash>
|
#include <QMultiHash>
|
||||||
|
|
||||||
#include "ui/ModelsBrowser.h"
|
#include "ui/ModelsBrowser.h"
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ private:
|
||||||
QString _texDir;
|
QString _texDir;
|
||||||
QString _scriptDir;
|
QString _scriptDir;
|
||||||
|
|
||||||
QVariantHash _mapping;
|
QMultiHash<QString, QVariant> _mapping;
|
||||||
std::shared_ptr<hfm::Model> _hfmModel;
|
std::shared_ptr<hfm::Model> _hfmModel;
|
||||||
QStringList _textures;
|
QStringList _textures;
|
||||||
QStringList _scripts;
|
QStringList _scripts;
|
||||||
|
|
|
@ -199,7 +199,7 @@ void Stats::updateStats(bool force) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Second column: ping
|
// Second column: ping
|
||||||
STAT_UPDATE(audioPing, audioMixerNode ? audioMixerNode->getPingMs() : -1);
|
STAT_UPDATE(audioPing, audioMixerNode ? audioMixerNode->getPingMs() : -1);
|
||||||
const int mixerLossRate = (int)roundf(_audioStats->data()->getMixerStream()->lossRateWindow() * 100.0f);
|
const int mixerLossRate = (int)roundf(_audioStats->data()->getMixerStream()->lossRateWindow() * 100.0f);
|
||||||
const int clientLossRate = (int)roundf(_audioStats->data()->getClientStream()->lossRateWindow() * 100.0f);
|
const int clientLossRate = (int)roundf(_audioStats->data()->getClientStream()->lossRateWindow() * 100.0f);
|
||||||
const int largestLossRate = mixerLossRate > clientLossRate ? mixerLossRate : clientLossRate;
|
const int largestLossRate = mixerLossRate > clientLossRate ? mixerLossRate : clientLossRate;
|
||||||
|
@ -484,7 +484,7 @@ void Stats::updateStats(bool force) {
|
||||||
// First iterate all the records, and for the ones that should be included, insert them into
|
// First iterate all the records, and for the ones that should be included, insert them into
|
||||||
// a new Map sorted by average time...
|
// a new Map sorted by average time...
|
||||||
bool onlyDisplayTopTen = Menu::getInstance()->isOptionChecked(MenuOption::OnlyDisplayTopTen);
|
bool onlyDisplayTopTen = Menu::getInstance()->isOptionChecked(MenuOption::OnlyDisplayTopTen);
|
||||||
QMap<float, QString> sortedRecords;
|
QMultiMap<float, QString> sortedRecords;
|
||||||
auto allRecords = PerformanceTimer::getAllTimerRecords();
|
auto allRecords = PerformanceTimer::getAllTimerRecords();
|
||||||
QMapIterator<QString, PerformanceTimerRecord> i(allRecords);
|
QMapIterator<QString, PerformanceTimerRecord> i(allRecords);
|
||||||
|
|
||||||
|
@ -492,7 +492,7 @@ void Stats::updateStats(bool force) {
|
||||||
i.next();
|
i.next();
|
||||||
if (includeTimingRecord(i.key())) {
|
if (includeTimingRecord(i.key())) {
|
||||||
float averageTime = (float)i.value().getMovingAverage() / (float)USECS_PER_MSEC;
|
float averageTime = (float)i.value().getMovingAverage() / (float)USECS_PER_MSEC;
|
||||||
sortedRecords.insertMulti(averageTime, i.key());
|
sortedRecords.insert(averageTime, i.key());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,9 +140,9 @@ void GeometryReader::run() {
|
||||||
}
|
}
|
||||||
|
|
||||||
HFMModel::Pointer hfmModel;
|
HFMModel::Pointer hfmModel;
|
||||||
QVariantHash serializerMapping = _mapping.second;
|
QMultiHash<QString, QVariant> serializerMapping = _mapping.second;
|
||||||
serializerMapping["combineParts"] = _combineParts;
|
serializerMapping.replace("combineParts",_combineParts);
|
||||||
serializerMapping["deduplicateIndices"] = true;
|
serializerMapping.replace("deduplicateIndices", true);
|
||||||
|
|
||||||
if (_url.path().toLower().endsWith(".gz")) {
|
if (_url.path().toLower().endsWith(".gz")) {
|
||||||
QByteArray uncompressedData;
|
QByteArray uncompressedData;
|
||||||
|
@ -247,7 +247,7 @@ void GeometryResource::downloadFinished(const QByteArray& data) {
|
||||||
if (scripts.size() > 0) {
|
if (scripts.size() > 0) {
|
||||||
_mapping.remove(SCRIPT_FIELD);
|
_mapping.remove(SCRIPT_FIELD);
|
||||||
for (auto &scriptPath : scripts) {
|
for (auto &scriptPath : scripts) {
|
||||||
_mapping.insertMulti(SCRIPT_FIELD, scriptPath);
|
_mapping.insert(SCRIPT_FIELD, scriptPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -417,7 +417,7 @@ HFMModel* FBXSerializer::extractHFMModel(const hifi::VariantHash& mapping, const
|
||||||
|
|
||||||
std::map<QString, HFMLight> lights;
|
std::map<QString, HFMLight> lights;
|
||||||
|
|
||||||
hifi::VariantHash blendshapeMappings = mapping.value("bs").toHash();
|
hifi::VariantMultiHash blendshapeMappings = mapping.value("bs").toHash();
|
||||||
|
|
||||||
QMultiHash<hifi::ByteArray, WeightedIndex> blendshapeIndices;
|
QMultiHash<hifi::ByteArray, WeightedIndex> blendshapeIndices;
|
||||||
for (int i = 0;; i++) {
|
for (int i = 0;; i++) {
|
||||||
|
|
|
@ -17,11 +17,11 @@
|
||||||
|
|
||||||
constexpr float DEFAULT_SCALE { 1.0f };
|
constexpr float DEFAULT_SCALE { 1.0f };
|
||||||
|
|
||||||
FST::FST(QString fstPath, QVariantHash data) : _fstPath(std::move(fstPath)) {
|
FST::FST(QString fstPath, QMultiHash<QString, QVariant> data) : _fstPath(std::move(fstPath)) {
|
||||||
|
|
||||||
auto setValueFromFSTData = [&data] (const QString& propertyID, auto &targetProperty) mutable {
|
auto setValueFromFSTData = [&data] (const QString& propertyID, auto &targetProperty) mutable {
|
||||||
if (data.contains(propertyID)) {
|
if (data.contains(propertyID)) {
|
||||||
targetProperty = data[propertyID].toString();
|
targetProperty = data.value(propertyID).toString();
|
||||||
data.remove(propertyID);
|
data.remove(propertyID);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -87,56 +87,56 @@ FST* FST::createFSTFromModel(const QString& fstPath, const QString& modelFilePat
|
||||||
// then we can add the default mixamo to blendshape mappings.
|
// then we can add the default mixamo to blendshape mappings.
|
||||||
if (likelyMixamoFile) {
|
if (likelyMixamoFile) {
|
||||||
QVariantHash blendshapes;
|
QVariantHash blendshapes;
|
||||||
blendshapes.insertMulti("BrowsD_L", QVariantList() << "BrowsDown_Left" << 1.0);
|
blendshapes.insert("BrowsD_L", QVariantList() << "BrowsDown_Left" << 1.0);
|
||||||
blendshapes.insertMulti("BrowsD_R", QVariantList() << "BrowsDown_Right" << 1.0);
|
blendshapes.insert("BrowsD_R", QVariantList() << "BrowsDown_Right" << 1.0);
|
||||||
blendshapes.insertMulti("BrowsU_C", QVariantList() << "BrowsUp_Left" << 1.0);
|
blendshapes.insert("BrowsU_C", QVariantList() << "BrowsUp_Left" << 1.0);
|
||||||
blendshapes.insertMulti("BrowsU_C", QVariantList() << "BrowsUp_Right" << 1.0);
|
blendshapes.insert("BrowsU_C", QVariantList() << "BrowsUp_Right" << 1.0);
|
||||||
blendshapes.insertMulti("BrowsU_L", QVariantList() << "BrowsUp_Left" << 1.0);
|
blendshapes.insert("BrowsU_L", QVariantList() << "BrowsUp_Left" << 1.0);
|
||||||
blendshapes.insertMulti("BrowsU_R", QVariantList() << "BrowsUp_Right" << 1.0);
|
blendshapes.insert("BrowsU_R", QVariantList() << "BrowsUp_Right" << 1.0);
|
||||||
blendshapes.insertMulti("ChinLowerRaise", QVariantList() << "Jaw_Up" << 1.0);
|
blendshapes.insert("ChinLowerRaise", QVariantList() << "Jaw_Up" << 1.0);
|
||||||
blendshapes.insertMulti("ChinUpperRaise", QVariantList() << "UpperLipUp_Left" << 0.5);
|
blendshapes.insert("ChinUpperRaise", QVariantList() << "UpperLipUp_Left" << 0.5);
|
||||||
blendshapes.insertMulti("ChinUpperRaise", QVariantList() << "UpperLipUp_Right" << 0.5);
|
blendshapes.insert("ChinUpperRaise", QVariantList() << "UpperLipUp_Right" << 0.5);
|
||||||
blendshapes.insertMulti("EyeBlink_L", QVariantList() << "Blink_Left" << 1.0);
|
blendshapes.insert("EyeBlink_L", QVariantList() << "Blink_Left" << 1.0);
|
||||||
blendshapes.insertMulti("EyeBlink_R", QVariantList() << "Blink_Right" << 1.0);
|
blendshapes.insert("EyeBlink_R", QVariantList() << "Blink_Right" << 1.0);
|
||||||
blendshapes.insertMulti("EyeOpen_L", QVariantList() << "EyesWide_Left" << 1.0);
|
blendshapes.insert("EyeOpen_L", QVariantList() << "EyesWide_Left" << 1.0);
|
||||||
blendshapes.insertMulti("EyeOpen_R", QVariantList() << "EyesWide_Right" << 1.0);
|
blendshapes.insert("EyeOpen_R", QVariantList() << "EyesWide_Right" << 1.0);
|
||||||
blendshapes.insertMulti("EyeSquint_L", QVariantList() << "Squint_Left" << 1.0);
|
blendshapes.insert("EyeSquint_L", QVariantList() << "Squint_Left" << 1.0);
|
||||||
blendshapes.insertMulti("EyeSquint_R", QVariantList() << "Squint_Right" << 1.0);
|
blendshapes.insert("EyeSquint_R", QVariantList() << "Squint_Right" << 1.0);
|
||||||
blendshapes.insertMulti("JawFwd", QVariantList() << "JawForeward" << 1.0);
|
blendshapes.insert("JawFwd", QVariantList() << "JawForeward" << 1.0);
|
||||||
blendshapes.insertMulti("JawLeft", QVariantList() << "JawRotateY_Left" << 0.5);
|
blendshapes.insert("JawLeft", QVariantList() << "JawRotateY_Left" << 0.5);
|
||||||
blendshapes.insertMulti("JawOpen", QVariantList() << "MouthOpen" << 0.7);
|
blendshapes.insert("JawOpen", QVariantList() << "MouthOpen" << 0.7);
|
||||||
blendshapes.insertMulti("JawRight", QVariantList() << "Jaw_Right" << 1.0);
|
blendshapes.insert("JawRight", QVariantList() << "Jaw_Right" << 1.0);
|
||||||
blendshapes.insertMulti("LipsFunnel", QVariantList() << "JawForeward" << 0.39);
|
blendshapes.insert("LipsFunnel", QVariantList() << "JawForeward" << 0.39);
|
||||||
blendshapes.insertMulti("LipsFunnel", QVariantList() << "Jaw_Down" << 0.36);
|
blendshapes.insert("LipsFunnel", QVariantList() << "Jaw_Down" << 0.36);
|
||||||
blendshapes.insertMulti("LipsFunnel", QVariantList() << "MouthNarrow_Left" << 1.0);
|
blendshapes.insert("LipsFunnel", QVariantList() << "MouthNarrow_Left" << 1.0);
|
||||||
blendshapes.insertMulti("LipsFunnel", QVariantList() << "MouthNarrow_Right" << 1.0);
|
blendshapes.insert("LipsFunnel", QVariantList() << "MouthNarrow_Right" << 1.0);
|
||||||
blendshapes.insertMulti("LipsFunnel", QVariantList() << "MouthWhistle_NarrowAdjust_Left" << 0.5);
|
blendshapes.insert("LipsFunnel", QVariantList() << "MouthWhistle_NarrowAdjust_Left" << 0.5);
|
||||||
blendshapes.insertMulti("LipsFunnel", QVariantList() << "MouthWhistle_NarrowAdjust_Right" << 0.5);
|
blendshapes.insert("LipsFunnel", QVariantList() << "MouthWhistle_NarrowAdjust_Right" << 0.5);
|
||||||
blendshapes.insertMulti("LipsFunnel", QVariantList() << "TongueUp" << 1.0);
|
blendshapes.insert("LipsFunnel", QVariantList() << "TongueUp" << 1.0);
|
||||||
blendshapes.insertMulti("LipsLowerClose", QVariantList() << "LowerLipIn" << 1.0);
|
blendshapes.insert("LipsLowerClose", QVariantList() << "LowerLipIn" << 1.0);
|
||||||
blendshapes.insertMulti("LipsLowerDown", QVariantList() << "LowerLipDown_Left" << 0.7);
|
blendshapes.insert("LipsLowerDown", QVariantList() << "LowerLipDown_Left" << 0.7);
|
||||||
blendshapes.insertMulti("LipsLowerDown", QVariantList() << "LowerLipDown_Right" << 0.7);
|
blendshapes.insert("LipsLowerDown", QVariantList() << "LowerLipDown_Right" << 0.7);
|
||||||
blendshapes.insertMulti("LipsLowerOpen", QVariantList() << "LowerLipOut" << 1.0);
|
blendshapes.insert("LipsLowerOpen", QVariantList() << "LowerLipOut" << 1.0);
|
||||||
blendshapes.insertMulti("LipsPucker", QVariantList() << "MouthNarrow_Left" << 1.0);
|
blendshapes.insert("LipsPucker", QVariantList() << "MouthNarrow_Left" << 1.0);
|
||||||
blendshapes.insertMulti("LipsPucker", QVariantList() << "MouthNarrow_Right" << 1.0);
|
blendshapes.insert("LipsPucker", QVariantList() << "MouthNarrow_Right" << 1.0);
|
||||||
blendshapes.insertMulti("LipsUpperClose", QVariantList() << "UpperLipIn" << 1.0);
|
blendshapes.insert("LipsUpperClose", QVariantList() << "UpperLipIn" << 1.0);
|
||||||
blendshapes.insertMulti("LipsUpperOpen", QVariantList() << "UpperLipOut" << 1.0);
|
blendshapes.insert("LipsUpperOpen", QVariantList() << "UpperLipOut" << 1.0);
|
||||||
blendshapes.insertMulti("LipsUpperUp", QVariantList() << "UpperLipUp_Left" << 0.7);
|
blendshapes.insert("LipsUpperUp", QVariantList() << "UpperLipUp_Left" << 0.7);
|
||||||
blendshapes.insertMulti("LipsUpperUp", QVariantList() << "UpperLipUp_Right" << 0.7);
|
blendshapes.insert("LipsUpperUp", QVariantList() << "UpperLipUp_Right" << 0.7);
|
||||||
blendshapes.insertMulti("MouthDimple_L", QVariantList() << "Smile_Left" << 0.25);
|
blendshapes.insert("MouthDimple_L", QVariantList() << "Smile_Left" << 0.25);
|
||||||
blendshapes.insertMulti("MouthDimple_R", QVariantList() << "Smile_Right" << 0.25);
|
blendshapes.insert("MouthDimple_R", QVariantList() << "Smile_Right" << 0.25);
|
||||||
blendshapes.insertMulti("MouthFrown_L", QVariantList() << "Frown_Left" << 1.0);
|
blendshapes.insert("MouthFrown_L", QVariantList() << "Frown_Left" << 1.0);
|
||||||
blendshapes.insertMulti("MouthFrown_R", QVariantList() << "Frown_Right" << 1.0);
|
blendshapes.insert("MouthFrown_R", QVariantList() << "Frown_Right" << 1.0);
|
||||||
blendshapes.insertMulti("MouthLeft", QVariantList() << "Midmouth_Left" << 1.0);
|
blendshapes.insert("MouthLeft", QVariantList() << "Midmouth_Left" << 1.0);
|
||||||
blendshapes.insertMulti("MouthRight", QVariantList() << "Midmouth_Right" << 1.0);
|
blendshapes.insert("MouthRight", QVariantList() << "Midmouth_Right" << 1.0);
|
||||||
blendshapes.insertMulti("MouthSmile_L", QVariantList() << "Smile_Left" << 1.0);
|
blendshapes.insert("MouthSmile_L", QVariantList() << "Smile_Left" << 1.0);
|
||||||
blendshapes.insertMulti("MouthSmile_R", QVariantList() << "Smile_Right" << 1.0);
|
blendshapes.insert("MouthSmile_R", QVariantList() << "Smile_Right" << 1.0);
|
||||||
blendshapes.insertMulti("Puff", QVariantList() << "CheekPuff_Left" << 1.0);
|
blendshapes.insert("Puff", QVariantList() << "CheekPuff_Left" << 1.0);
|
||||||
blendshapes.insertMulti("Puff", QVariantList() << "CheekPuff_Right" << 1.0);
|
blendshapes.insert("Puff", QVariantList() << "CheekPuff_Right" << 1.0);
|
||||||
blendshapes.insertMulti("Sneer", QVariantList() << "NoseScrunch_Left" << 0.75);
|
blendshapes.insert("Sneer", QVariantList() << "NoseScrunch_Left" << 0.75);
|
||||||
blendshapes.insertMulti("Sneer", QVariantList() << "NoseScrunch_Right" << 0.75);
|
blendshapes.insert("Sneer", QVariantList() << "NoseScrunch_Right" << 0.75);
|
||||||
blendshapes.insertMulti("Sneer", QVariantList() << "Squint_Left" << 0.5);
|
blendshapes.insert("Sneer", QVariantList() << "Squint_Left" << 0.5);
|
||||||
blendshapes.insertMulti("Sneer", QVariantList() << "Squint_Right" << 0.5);
|
blendshapes.insert("Sneer", QVariantList() << "Squint_Right" << 0.5);
|
||||||
mapping.insert(BLENDSHAPE_FIELD, blendshapes);
|
mapping.insert(BLENDSHAPE_FIELD, blendshapes);
|
||||||
}
|
}
|
||||||
return new FST(fstPath, mapping);
|
return new FST(fstPath, mapping);
|
||||||
|
@ -158,14 +158,14 @@ void FST::setModelPath(const QString& modelPath) {
|
||||||
emit modelPathChanged(modelPath);
|
emit modelPathChanged(modelPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantHash FST::getMapping() const {
|
QMultiHash<QString, QVariant> FST::getMapping() const {
|
||||||
QVariantHash mapping;
|
QMultiHash<QString, QVariant> mapping;
|
||||||
mapping.unite(_other);
|
mapping.unite(_other);
|
||||||
mapping.insert(NAME_FIELD, _name);
|
mapping.insert(NAME_FIELD, _name);
|
||||||
mapping.insert(FILENAME_FIELD, _modelPath);
|
mapping.insert(FILENAME_FIELD, _modelPath);
|
||||||
mapping.insert(MARKETPLACE_ID_FIELD, _marketplaceID);
|
mapping.insert(MARKETPLACE_ID_FIELD, _marketplaceID);
|
||||||
for (const auto& scriptPath : _scriptPaths) {
|
for (const auto& scriptPath : _scriptPaths) {
|
||||||
mapping.insertMulti(SCRIPT_FIELD, scriptPath);
|
mapping.insert(SCRIPT_FIELD, scriptPath);
|
||||||
}
|
}
|
||||||
return mapping;
|
return mapping;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ class FST : public QObject {
|
||||||
Q_PROPERTY(QUuid marketplaceID READ getMarketplaceID)
|
Q_PROPERTY(QUuid marketplaceID READ getMarketplaceID)
|
||||||
Q_PROPERTY(bool hasMarketplaceID READ getHasMarketplaceID NOTIFY marketplaceIDChanged)
|
Q_PROPERTY(bool hasMarketplaceID READ getHasMarketplaceID NOTIFY marketplaceIDChanged)
|
||||||
public:
|
public:
|
||||||
FST(QString fstPath, QVariantHash data);
|
FST(QString fstPath, QMultiHash<QString, QVariant> data);
|
||||||
|
|
||||||
static FST* createFSTFromModel(const QString& fstPath, const QString& modelFilePath, const hfm::Model& hfmModel);
|
static FST* createFSTFromModel(const QString& fstPath, const QString& modelFilePath, const hfm::Model& hfmModel);
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ public:
|
||||||
|
|
||||||
QString getPath() const { return _fstPath; }
|
QString getPath() const { return _fstPath; }
|
||||||
|
|
||||||
QVariantHash getMapping() const;
|
QMultiHash<QString, QVariant> getMapping() const;
|
||||||
|
|
||||||
bool write();
|
bool write();
|
||||||
|
|
||||||
|
|
|
@ -34,10 +34,10 @@ QVariantHash FSTReader::parseMapping(QIODevice* device) {
|
||||||
}
|
}
|
||||||
QByteArray name = sections.at(0).trimmed();
|
QByteArray name = sections.at(0).trimmed();
|
||||||
if (sections.size() == 2) {
|
if (sections.size() == 2) {
|
||||||
properties.insertMulti(name, sections.at(1).trimmed());
|
properties.insert(name, sections.at(1).trimmed());
|
||||||
} else if (sections.size() == 3) {
|
} else if (sections.size() == 3) {
|
||||||
QVariantHash heading = properties.value(name).toHash();
|
QVariantHash heading = properties.value(name).toHash();
|
||||||
heading.insertMulti(sections.at(1).trimmed(), sections.at(2).trimmed());
|
heading.insert(sections.at(1).trimmed(), sections.at(2).trimmed());
|
||||||
properties.insert(name, heading);
|
properties.insert(name, heading);
|
||||||
} else if (sections.size() >= 4) {
|
} else if (sections.size() >= 4) {
|
||||||
QVariantHash heading = properties.value(name).toHash();
|
QVariantHash heading = properties.value(name).toHash();
|
||||||
|
@ -45,7 +45,7 @@ QVariantHash FSTReader::parseMapping(QIODevice* device) {
|
||||||
for (int i = 2; i < sections.size(); i++) {
|
for (int i = 2; i < sections.size(); i++) {
|
||||||
contents.append(sections.at(i).trimmed());
|
contents.append(sections.at(i).trimmed());
|
||||||
}
|
}
|
||||||
heading.insertMulti(sections.at(1).trimmed(), contents);
|
heading.insert(sections.at(1).trimmed(), contents);
|
||||||
properties.insert(name, heading);
|
properties.insert(name, heading);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ static void removeBlendshape(QVariantHash& bs, const QString& key) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void splitBlendshapes(QVariantHash& bs, const QString& key, const QString& leftKey, const QString& rightKey) {
|
static void splitBlendshapes(hifi::VariantMultiHash& bs, const QString& key, const QString& leftKey, const QString& rightKey) {
|
||||||
if (bs.contains(key) && !(bs.contains(leftKey) || bs.contains(rightKey))) {
|
if (bs.contains(key) && !(bs.contains(leftKey) || bs.contains(rightKey))) {
|
||||||
// key has been split into leftKey and rightKey blendshapes
|
// key has been split into leftKey and rightKey blendshapes
|
||||||
QVariantList origShapes = bs.values(key);
|
QVariantList origShapes = bs.values(key);
|
||||||
|
@ -69,15 +69,15 @@ static void splitBlendshapes(QVariantHash& bs, const QString& key, const QString
|
||||||
QVariantList halfShape;
|
QVariantList halfShape;
|
||||||
halfShape.append(origShape[0]);
|
halfShape.append(origShape[0]);
|
||||||
halfShape.append(QVariant(0.5f * origShape[1].toFloat()));
|
halfShape.append(QVariant(0.5f * origShape[1].toFloat()));
|
||||||
bs.insertMulti(leftKey, halfShape);
|
bs.insert(leftKey, halfShape);
|
||||||
bs.insertMulti(rightKey, halfShape);
|
bs.insert(rightKey, halfShape);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert legacy blendshapes to arkit blendshapes
|
// convert legacy blendshapes to arkit blendshapes
|
||||||
static void fixUpLegacyBlendshapes(QVariantHash& properties) {
|
static void fixUpLegacyBlendshapes(QVariantHash & properties) {
|
||||||
QVariantHash bs = properties.value("bs").toHash();
|
hifi::VariantMultiHash bs = properties.value("bs").toHash();
|
||||||
|
|
||||||
// These blendshapes have no ARKit equivalent, so we remove them.
|
// These blendshapes have no ARKit equivalent, so we remove them.
|
||||||
removeBlendshape(bs, "JawChew");
|
removeBlendshape(bs, "JawChew");
|
||||||
|
@ -125,7 +125,7 @@ void FSTReader::writeVariant(QBuffer& buffer, QVariantHash::const_iterator& it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray FSTReader::writeMapping(const QVariantHash& mapping) {
|
QByteArray FSTReader::writeMapping(const hifi::VariantMultiHash& mapping) {
|
||||||
static const QStringList PREFERED_ORDER = QStringList() << NAME_FIELD << TYPE_FIELD << SCALE_FIELD << FILENAME_FIELD
|
static const QStringList PREFERED_ORDER = QStringList() << NAME_FIELD << TYPE_FIELD << SCALE_FIELD << FILENAME_FIELD
|
||||||
<< MARKETPLACE_ID_FIELD << TEXDIR_FIELD << SCRIPT_FIELD << JOINT_FIELD
|
<< MARKETPLACE_ID_FIELD << TEXDIR_FIELD << SCRIPT_FIELD << JOINT_FIELD
|
||||||
<< BLENDSHAPE_FIELD << JOINT_INDEX_FIELD;
|
<< BLENDSHAPE_FIELD << JOINT_INDEX_FIELD;
|
||||||
|
@ -175,9 +175,9 @@ FSTReader::ModelType FSTReader::getTypeFromName(const QString& name) {
|
||||||
_namesToTypes["head"] = HEAD_MODEL ;
|
_namesToTypes["head"] = HEAD_MODEL ;
|
||||||
_namesToTypes["body"] = BODY_ONLY_MODEL;
|
_namesToTypes["body"] = BODY_ONLY_MODEL;
|
||||||
_namesToTypes["body+head"] = HEAD_AND_BODY_MODEL;
|
_namesToTypes["body+head"] = HEAD_AND_BODY_MODEL;
|
||||||
|
|
||||||
// NOTE: this is not yet implemented, but will be used to allow you to attach fully independent models to your avatar
|
// NOTE: this is not yet implemented, but will be used to allow you to attach fully independent models to your avatar
|
||||||
_namesToTypes["attachment"] = ATTACHMENT_MODEL;
|
_namesToTypes["attachment"] = ATTACHMENT_MODEL;
|
||||||
}
|
}
|
||||||
return _namesToTypes[name];
|
return _namesToTypes[name];
|
||||||
}
|
}
|
||||||
|
@ -194,7 +194,7 @@ FSTReader::ModelType FSTReader::predictModelType(const QVariantHash& mapping) {
|
||||||
if (mapping.contains(TYPE_FIELD)) {
|
if (mapping.contains(TYPE_FIELD)) {
|
||||||
return FSTReader::getTypeFromName(mapping[TYPE_FIELD].toString());
|
return FSTReader::getTypeFromName(mapping[TYPE_FIELD].toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for blendshapes
|
// check for blendshapes
|
||||||
bool hasBlendshapes = mapping.contains(BLENDSHAPE_FIELD);
|
bool hasBlendshapes = mapping.contains(BLENDSHAPE_FIELD);
|
||||||
|
|
||||||
|
@ -210,15 +210,15 @@ FSTReader::ModelType FSTReader::predictModelType(const QVariantHash& mapping) {
|
||||||
//joint = jointNeck = Neck
|
//joint = jointNeck = Neck
|
||||||
//joint = jointHead = HeadTop_End
|
//joint = jointHead = HeadTop_End
|
||||||
|
|
||||||
bool hasBodyMinimumJoints = joints.contains("jointRoot") && joints.contains("jointLean") && joints.contains("jointNeck")
|
bool hasBodyMinimumJoints = joints.contains("jointRoot") && joints.contains("jointLean") && joints.contains("jointNeck")
|
||||||
&& joints.contains("jointHead");
|
&& joints.contains("jointHead");
|
||||||
|
|
||||||
bool isLikelyHead = hasBlendshapes || hasHeadMinimum;
|
bool isLikelyHead = hasBlendshapes || hasHeadMinimum;
|
||||||
|
|
||||||
if (isLikelyHead && hasBodyMinimumJoints) {
|
if (isLikelyHead && hasBodyMinimumJoints) {
|
||||||
return HEAD_AND_BODY_MODEL;
|
return HEAD_AND_BODY_MODEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isLikelyHead) {
|
if (isLikelyHead) {
|
||||||
return HEAD_MODEL;
|
return HEAD_MODEL;
|
||||||
}
|
}
|
||||||
|
@ -226,11 +226,11 @@ FSTReader::ModelType FSTReader::predictModelType(const QVariantHash& mapping) {
|
||||||
if (hasBodyMinimumJoints) {
|
if (hasBodyMinimumJoints) {
|
||||||
return BODY_ONLY_MODEL;
|
return BODY_ONLY_MODEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ENTITY_MODEL;
|
return ENTITY_MODEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<QString> FSTReader::getScripts(const QUrl& url, const QVariantHash& mapping) {
|
QVector<QString> FSTReader::getScripts(const QUrl& url, const hifi::VariantMultiHash& mapping) {
|
||||||
|
|
||||||
auto fstMapping = mapping.isEmpty() ? downloadMapping(url.toString()) : mapping;
|
auto fstMapping = mapping.isEmpty() ? downloadMapping(url.toString()) : mapping;
|
||||||
QVector<QString> scriptPaths;
|
QVector<QString> scriptPaths;
|
||||||
|
@ -250,7 +250,7 @@ QVector<QString> FSTReader::getScripts(const QUrl& url, const QVariantHash& mapp
|
||||||
return scriptPaths;
|
return scriptPaths;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantHash FSTReader::downloadMapping(const QString& url) {
|
hifi::VariantMultiHash FSTReader::downloadMapping(const QString& url) {
|
||||||
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
||||||
QNetworkRequest networkRequest = QNetworkRequest(url);
|
QNetworkRequest networkRequest = QNetworkRequest(url);
|
||||||
networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
|
networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
#include <QBuffer>
|
#include <QBuffer>
|
||||||
#include <QVariantHash>
|
#include <QVariantHash>
|
||||||
|
#include "shared/HifiTypes.h"
|
||||||
|
|
||||||
static const unsigned int FST_VERSION = 1;
|
static const unsigned int FST_VERSION = 1;
|
||||||
static const QString FST_VERSION_FIELD = "version";
|
static const QString FST_VERSION_FIELD = "version";
|
||||||
|
@ -50,16 +51,16 @@ public:
|
||||||
static QVariantHash readMapping(const QByteArray& data);
|
static QVariantHash readMapping(const QByteArray& data);
|
||||||
|
|
||||||
/// Writes an FST mapping to a byte array.
|
/// Writes an FST mapping to a byte array.
|
||||||
static QByteArray writeMapping(const QVariantHash& mapping);
|
static QByteArray writeMapping(const hifi::VariantMultiHash& mapping);
|
||||||
|
|
||||||
/// Predicts the type of model by examining the mapping
|
/// Predicts the type of model by examining the mapping
|
||||||
static ModelType predictModelType(const QVariantHash& mapping);
|
static ModelType predictModelType(const QVariantHash& mapping);
|
||||||
|
|
||||||
static QVector<QString> getScripts(const QUrl& fstUrl, const QVariantHash& mapping = QVariantHash());
|
static QVector<QString> getScripts(const QUrl& fstUrl, const hifi::VariantMultiHash& mapping = QVariantHash());
|
||||||
|
|
||||||
static QString getNameFromType(ModelType modelType);
|
static QString getNameFromType(ModelType modelType);
|
||||||
static FSTReader::ModelType getTypeFromName(const QString& name);
|
static FSTReader::ModelType getTypeFromName(const QString& name);
|
||||||
static QVariantHash downloadMapping(const QString& url);
|
static hifi::VariantMultiHash downloadMapping(const QString& url);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void writeVariant(QBuffer& buffer, QVariantHash::const_iterator& it);
|
static void writeVariant(QBuffer& buffer, QVariantHash::const_iterator& it);
|
||||||
|
|
|
@ -1548,7 +1548,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
||||||
|
|
||||||
// Build list of blendshapes from FST and model.
|
// Build list of blendshapes from FST and model.
|
||||||
typedef QPair<int, float> WeightedIndex;
|
typedef QPair<int, float> WeightedIndex;
|
||||||
hifi::VariantHash blendshapeMappings = mapping.value("bs").toHash();
|
hifi::VariantMultiHash blendshapeMappings = mapping.value("bs").toHash();
|
||||||
QMultiHash<QString, WeightedIndex> blendshapeIndices;
|
QMultiHash<QString, WeightedIndex> blendshapeIndices;
|
||||||
for (int i = 0;; ++i) {
|
for (int i = 0;; ++i) {
|
||||||
auto blendshapeName = QString(BLENDSHAPE_NAMES[i]);
|
auto blendshapeName = QString(BLENDSHAPE_NAMES[i]);
|
||||||
|
@ -1583,7 +1583,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
||||||
&& fileTargetNames.contains("viseme_O")
|
&& fileTargetNames.contains("viseme_O")
|
||||||
&& fileTargetNames.contains("mouthShrugLower");
|
&& fileTargetNames.contains("mouthShrugLower");
|
||||||
if (blendshapeMappings.count() == 0 && likelyReadyPlayerMeFile) {
|
if (blendshapeMappings.count() == 0 && likelyReadyPlayerMeFile) {
|
||||||
QHash<QString, QPair<QString, float>>::const_iterator synonym
|
QHash<QString, QPair<QString, float>>::const_iterator synonym
|
||||||
= READYPLAYERME_BLENDSHAPES_MAP.constBegin();
|
= READYPLAYERME_BLENDSHAPES_MAP.constBegin();
|
||||||
while (synonym != READYPLAYERME_BLENDSHAPES_MAP.constEnd()) {
|
while (synonym != READYPLAYERME_BLENDSHAPES_MAP.constEnd()) {
|
||||||
if (fileTargetNames.contains(synonym.key())) {
|
if (fileTargetNames.contains(synonym.key())) {
|
||||||
|
|
|
@ -301,7 +301,7 @@ void ResourceCache::refreshAll() {
|
||||||
clearUnusedResources();
|
clearUnusedResources();
|
||||||
resetUnusedResourceCounter();
|
resetUnusedResourceCounter();
|
||||||
|
|
||||||
QHash<QUrl, QHash<size_t, QWeakPointer<Resource>>> allResources;
|
QHash<QUrl, QMultiHash<size_t, QWeakPointer<Resource>>> allResources;
|
||||||
{
|
{
|
||||||
QReadLocker locker(&_resourcesLock);
|
QReadLocker locker(&_resourcesLock);
|
||||||
allResources = _resources;
|
allResources = _resources;
|
||||||
|
@ -339,7 +339,7 @@ QVariantList ResourceCache::getResourceList() {
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceCache::setRequestLimit(uint32_t limit) {
|
void ResourceCache::setRequestLimit(uint32_t limit) {
|
||||||
auto sharedItems = DependencyManager::get<ResourceCacheSharedItems>();
|
auto sharedItems = DependencyManager::get<ResourceCacheSharedItems>();
|
||||||
sharedItems->setRequestLimit(limit);
|
sharedItems->setRequestLimit(limit);
|
||||||
|
@ -418,7 +418,7 @@ void ResourceCache::addUnusedResource(const QSharedPointer<Resource>& resource)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
reserveUnusedResource(resource->getBytes());
|
reserveUnusedResource(resource->getBytes());
|
||||||
|
|
||||||
resource->setLRUKey(++_lastLRUKey);
|
resource->setLRUKey(++_lastLRUKey);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -447,7 +447,7 @@ void ResourceCache::reserveUnusedResource(qint64 resourceSize) {
|
||||||
_unusedResourcesSize + resourceSize > _unusedResourcesMaxSize) {
|
_unusedResourcesSize + resourceSize > _unusedResourcesMaxSize) {
|
||||||
// unload the oldest resource
|
// unload the oldest resource
|
||||||
QMap<int, QSharedPointer<Resource> >::iterator it = _unusedResources.begin();
|
QMap<int, QSharedPointer<Resource> >::iterator it = _unusedResources.begin();
|
||||||
|
|
||||||
it.value()->setCache(nullptr);
|
it.value()->setCache(nullptr);
|
||||||
auto size = it.value()->getBytes();
|
auto size = it.value()->getBytes();
|
||||||
|
|
||||||
|
@ -654,7 +654,7 @@ void Resource::refresh() {
|
||||||
_request = nullptr;
|
_request = nullptr;
|
||||||
ResourceCache::requestCompleted(_self);
|
ResourceCache::requestCompleted(_self);
|
||||||
}
|
}
|
||||||
|
|
||||||
_activeUrl = _url;
|
_activeUrl = _url;
|
||||||
init();
|
init();
|
||||||
ensureLoading();
|
ensureLoading();
|
||||||
|
@ -668,7 +668,7 @@ void Resource::allReferencesCleared() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_cache && isCacheable()) {
|
if (_cache && isCacheable()) {
|
||||||
// create and reinsert new shared pointer
|
// create and reinsert new shared pointer
|
||||||
QSharedPointer<Resource> self(this, &Resource::deleter);
|
QSharedPointer<Resource> self(this, &Resource::deleter);
|
||||||
setSelf(self);
|
setSelf(self);
|
||||||
reinsert();
|
reinsert();
|
||||||
|
@ -693,10 +693,10 @@ void Resource::init(bool resetLoaded) {
|
||||||
_loaded = false;
|
_loaded = false;
|
||||||
}
|
}
|
||||||
_attempts = 0;
|
_attempts = 0;
|
||||||
|
|
||||||
if (_url.isEmpty()) {
|
if (_url.isEmpty()) {
|
||||||
_startedLoading = _loaded = true;
|
_startedLoading = _loaded = true;
|
||||||
|
|
||||||
} else if (!(_url.isValid())) {
|
} else if (!(_url.isValid())) {
|
||||||
_startedLoading = _failedToLoad = true;
|
_startedLoading = _failedToLoad = true;
|
||||||
}
|
}
|
||||||
|
@ -820,7 +820,7 @@ void Resource::handleReplyFinished() {
|
||||||
} else {
|
} else {
|
||||||
handleFailedRequest(result);
|
handleFailedRequest(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
_request->disconnect(this);
|
_request->disconnect(this);
|
||||||
_request->deleteLater();
|
_request->deleteLater();
|
||||||
_request = nullptr;
|
_request = nullptr;
|
||||||
|
|
|
@ -91,7 +91,7 @@ private:
|
||||||
class ScriptableResource : public QObject {
|
class ScriptableResource : public QObject {
|
||||||
|
|
||||||
/*@jsdoc
|
/*@jsdoc
|
||||||
* Information about a cached resource. Created by {@link AnimationCache.prefetch}, {@link MaterialCache.prefetch},
|
* Information about a cached resource. Created by {@link AnimationCache.prefetch}, {@link MaterialCache.prefetch},
|
||||||
* {@link ModelCache.prefetch}, {@link SoundCache.prefetch}, or {@link TextureCache.prefetch}.
|
* {@link ModelCache.prefetch}, {@link SoundCache.prefetch}, or {@link TextureCache.prefetch}.
|
||||||
*
|
*
|
||||||
* @class ResourceObject
|
* @class ResourceObject
|
||||||
|
@ -212,7 +212,7 @@ public:
|
||||||
|
|
||||||
static void setRequestLimit(uint32_t limit);
|
static void setRequestLimit(uint32_t limit);
|
||||||
static uint32_t getRequestLimit() { return DependencyManager::get<ResourceCacheSharedItems>()->getRequestLimit(); }
|
static uint32_t getRequestLimit() { return DependencyManager::get<ResourceCacheSharedItems>()->getRequestLimit(); }
|
||||||
|
|
||||||
void setUnusedResourceCacheSize(qint64 unusedResourcesMaxSize);
|
void setUnusedResourceCacheSize(qint64 unusedResourcesMaxSize);
|
||||||
qint64 getUnusedResourceCacheSize() const { return _unusedResourcesMaxSize; }
|
qint64 getUnusedResourceCacheSize() const { return _unusedResourcesMaxSize; }
|
||||||
|
|
||||||
|
@ -222,7 +222,7 @@ public:
|
||||||
|
|
||||||
ResourceCache(QObject* parent = nullptr);
|
ResourceCache(QObject* parent = nullptr);
|
||||||
virtual ~ResourceCache();
|
virtual ~ResourceCache();
|
||||||
|
|
||||||
void refreshAll();
|
void refreshAll();
|
||||||
void clearUnusedResources();
|
void clearUnusedResources();
|
||||||
|
|
||||||
|
@ -284,7 +284,7 @@ private:
|
||||||
void resetResourceCounters();
|
void resetResourceCounters();
|
||||||
|
|
||||||
// Resources
|
// Resources
|
||||||
QHash<QUrl, QHash<size_t, QWeakPointer<Resource>>> _resources;
|
QHash<QUrl, QMultiHash<size_t, QWeakPointer<Resource>>> _resources;
|
||||||
QReadWriteLock _resourcesLock { QReadWriteLock::Recursive };
|
QReadWriteLock _resourcesLock { QReadWriteLock::Recursive };
|
||||||
int _lastLRUKey = 0;
|
int _lastLRUKey = 0;
|
||||||
|
|
||||||
|
@ -304,7 +304,7 @@ private:
|
||||||
class ScriptableResourceCache : public QObject {
|
class ScriptableResourceCache : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
// JSDoc 3.5.5 doesn't augment name spaces with @property definitions so the following properties JSDoc is copied to the
|
// JSDoc 3.5.5 doesn't augment name spaces with @property definitions so the following properties JSDoc is copied to the
|
||||||
// different exposed cache classes.
|
// different exposed cache classes.
|
||||||
|
|
||||||
/*@jsdoc
|
/*@jsdoc
|
||||||
|
@ -357,10 +357,10 @@ public:
|
||||||
* @example <caption>Prefetch a resource and wait until it has loaded.</caption>
|
* @example <caption>Prefetch a resource and wait until it has loaded.</caption>
|
||||||
* // Replace AnimationCache with MaterialCache, ModelCache, SoundCache, or TextureCache as appropriate.
|
* // Replace AnimationCache with MaterialCache, ModelCache, SoundCache, or TextureCache as appropriate.
|
||||||
* // TextureCache has its own version of this function.
|
* // TextureCache has its own version of this function.
|
||||||
*
|
*
|
||||||
* var resourceURL = "https://cdn-1.vircadia.com/eu-c-1/vircadia-public/clement/production/animations/sitting_idle.fbx";
|
* var resourceURL = "https://cdn-1.vircadia.com/eu-c-1/vircadia-public/clement/production/animations/sitting_idle.fbx";
|
||||||
* var resourceObject = AnimationCache.prefetch(resourceURL);
|
* var resourceObject = AnimationCache.prefetch(resourceURL);
|
||||||
*
|
*
|
||||||
* function checkIfResourceLoaded(state) {
|
* function checkIfResourceLoaded(state) {
|
||||||
* if (state === Resource.State.FINISHED) {
|
* if (state === Resource.State.FINISHED) {
|
||||||
* print("Resource loaded and ready.");
|
* print("Resource loaded and ready.");
|
||||||
|
@ -368,11 +368,11 @@ public:
|
||||||
* print("Resource not loaded.");
|
* print("Resource not loaded.");
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* // Resource may have already been loaded.
|
* // Resource may have already been loaded.
|
||||||
* print("Resource state: " + resourceObject.state);
|
* print("Resource state: " + resourceObject.state);
|
||||||
* checkIfResourceLoaded(resourceObject.state);
|
* checkIfResourceLoaded(resourceObject.state);
|
||||||
*
|
*
|
||||||
* // Resource may still be loading.
|
* // Resource may still be loading.
|
||||||
* resourceObject.stateChanged.connect(function (state) {
|
* resourceObject.stateChanged.connect(function (state) {
|
||||||
* print("Resource state changed to: " + state);
|
* print("Resource state changed to: " + state);
|
||||||
|
@ -380,7 +380,7 @@ public:
|
||||||
* });
|
* });
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE ScriptableResource* prefetch(const QUrl& url) { return prefetch(url, nullptr, std::numeric_limits<size_t>::max()); }
|
Q_INVOKABLE ScriptableResource* prefetch(const QUrl& url) { return prefetch(url, nullptr, std::numeric_limits<size_t>::max()); }
|
||||||
|
|
||||||
// FIXME: This function variation shouldn't be in the API.
|
// FIXME: This function variation shouldn't be in the API.
|
||||||
Q_INVOKABLE ScriptableResource* prefetch(const QUrl& url, void* extra, size_t extraHash);
|
Q_INVOKABLE ScriptableResource* prefetch(const QUrl& url, void* extra, size_t extraHash);
|
||||||
|
|
||||||
|
@ -443,7 +443,7 @@ public:
|
||||||
|
|
||||||
/// For loading resources, returns the number of bytes received.
|
/// For loading resources, returns the number of bytes received.
|
||||||
qint64 getBytesReceived() const { return _bytesReceived; }
|
qint64 getBytesReceived() const { return _bytesReceived; }
|
||||||
|
|
||||||
/// For loading resources, returns the number of total bytes (<= zero if unknown).
|
/// For loading resources, returns the number of total bytes (<= zero if unknown).
|
||||||
qint64 getBytesTotal() const { return _bytesTotal; }
|
qint64 getBytesTotal() const { return _bytesTotal; }
|
||||||
|
|
||||||
|
@ -452,7 +452,7 @@ public:
|
||||||
|
|
||||||
/// For loading resources, returns the load progress.
|
/// For loading resources, returns the load progress.
|
||||||
float getProgress() const { return (_bytesTotal <= 0) ? 0.0f : (float)_bytesReceived / _bytesTotal; }
|
float getProgress() const { return (_bytesTotal <= 0) ? 0.0f : (float)_bytesReceived / _bytesTotal; }
|
||||||
|
|
||||||
/// Refreshes the resource.
|
/// Refreshes the resource.
|
||||||
virtual void refresh();
|
virtual void refresh();
|
||||||
|
|
||||||
|
@ -461,7 +461,7 @@ public:
|
||||||
void setCache(ResourceCache* cache) { _cache = cache; }
|
void setCache(ResourceCache* cache) { _cache = cache; }
|
||||||
|
|
||||||
virtual void deleter() { allReferencesCleared(); }
|
virtual void deleter() { allReferencesCleared(); }
|
||||||
|
|
||||||
const QUrl& getURL() const { return _url; }
|
const QUrl& getURL() const { return _url; }
|
||||||
|
|
||||||
unsigned int getDownloadAttempts() { return _attempts; }
|
unsigned int getDownloadAttempts() { return _attempts; }
|
||||||
|
@ -557,15 +557,15 @@ public slots:
|
||||||
private:
|
private:
|
||||||
friend class ResourceCache;
|
friend class ResourceCache;
|
||||||
friend class ScriptableResource;
|
friend class ScriptableResource;
|
||||||
|
|
||||||
void setLRUKey(int lruKey) { _lruKey = lruKey; }
|
void setLRUKey(int lruKey) { _lruKey = lruKey; }
|
||||||
|
|
||||||
void retry();
|
void retry();
|
||||||
void reinsert();
|
void reinsert();
|
||||||
|
|
||||||
bool isInScript() const { return _isInScript; }
|
bool isInScript() const { return _isInScript; }
|
||||||
void setInScript(bool isInScript) { _isInScript = isInScript; }
|
void setInScript(bool isInScript) { _isInScript = isInScript; }
|
||||||
|
|
||||||
int _lruKey{ 0 };
|
int _lruKey{ 0 };
|
||||||
QTimer* _replyTimer{ nullptr };
|
QTimer* _replyTimer{ nullptr };
|
||||||
unsigned int _attempts{ 0 };
|
unsigned int _attempts{ 0 };
|
||||||
|
|
|
@ -69,7 +69,7 @@ ScriptEngines::ScriptEngines(ScriptEngine::Context context, const QUrl& defaultS
|
||||||
: _context(context), _defaultScriptsOverride(defaultScriptsOverride)
|
: _context(context), _defaultScriptsOverride(defaultScriptsOverride)
|
||||||
{
|
{
|
||||||
scriptGatekeeper.initialize();
|
scriptGatekeeper.initialize();
|
||||||
|
|
||||||
_scriptsModelFilter.setSourceModel(&_scriptsModel);
|
_scriptsModelFilter.setSourceModel(&_scriptsModel);
|
||||||
_scriptsModelFilter.sort(0, Qt::AscendingOrder);
|
_scriptsModelFilter.sort(0, Qt::AscendingOrder);
|
||||||
_scriptsModelFilter.setDynamicSortFilter(true);
|
_scriptsModelFilter.setDynamicSortFilter(true);
|
||||||
|
@ -198,7 +198,7 @@ void ScriptEngines::shutdownScripting() {
|
||||||
* @typedef {object} ScriptDiscoveryService.PublicScript
|
* @typedef {object} ScriptDiscoveryService.PublicScript
|
||||||
* @property {string} name - The script's file name.
|
* @property {string} name - The script's file name.
|
||||||
* @property {string} type - <code>"script"</code> or <code>"folder"</code>.
|
* @property {string} type - <code>"script"</code> or <code>"folder"</code>.
|
||||||
* <p class="important">Deprecated: This property is deprecated and will be removed. It currently always has the value,
|
* <p class="important">Deprecated: This property is deprecated and will be removed. It currently always has the value,
|
||||||
* <code>"script"</code>.</p>
|
* <code>"script"</code>.</p>
|
||||||
* @property {ScriptDiscoveryService.PublicScript[]} [children] - Only present if <code>type == "folder"</code>.
|
* @property {ScriptDiscoveryService.PublicScript[]} [children] - Only present if <code>type == "folder"</code>.
|
||||||
* <p class="important">Deprecated: This property is deprecated and will be removed. It currently is never present.
|
* <p class="important">Deprecated: This property is deprecated and will be removed. It currently is never present.
|
||||||
|
@ -266,7 +266,7 @@ QVariantList ScriptEngines::getLocal() {
|
||||||
/*@jsdoc
|
/*@jsdoc
|
||||||
* Information on a running script.
|
* Information on a running script.
|
||||||
* @typedef {object} ScriptDiscoveryService.RunningScript
|
* @typedef {object} ScriptDiscoveryService.RunningScript
|
||||||
* @property {boolean} local - <code>true</code> if the script is a local file (i.e., the scheme is "file"), <code>false</code>
|
* @property {boolean} local - <code>true</code> if the script is a local file (i.e., the scheme is "file"), <code>false</code>
|
||||||
* if it isn't (e.g., the scheme is "http").
|
* if it isn't (e.g., the scheme is "http").
|
||||||
* @property {string} name - The script's file name.
|
* @property {string} name - The script's file name.
|
||||||
* @property {string} path - The script's path and file name — excluding the scheme if a local file.
|
* @property {string} path - The script's path and file name — excluding the scheme if a local file.
|
||||||
|
@ -448,7 +448,7 @@ bool ScriptEngines::stopScript(const QString& rawScriptURL, bool restart) {
|
||||||
|
|
||||||
QReadLocker lock(&_scriptEnginesHashLock);
|
QReadLocker lock(&_scriptEnginesHashLock);
|
||||||
if (_scriptEnginesHash.contains(scriptURL)) {
|
if (_scriptEnginesHash.contains(scriptURL)) {
|
||||||
ScriptEnginePointer scriptEngine = _scriptEnginesHash[scriptURL];
|
ScriptEnginePointer scriptEngine = _scriptEnginesHash.value(scriptURL);
|
||||||
if (restart) {
|
if (restart) {
|
||||||
bool isUserLoaded = scriptEngine->isUserLoaded();
|
bool isUserLoaded = scriptEngine->isUserLoaded();
|
||||||
ScriptEngine::Type type = scriptEngine->getType();
|
ScriptEngine::Type type = scriptEngine->getType();
|
||||||
|
@ -561,7 +561,7 @@ void ScriptEngines::onScriptEngineLoaded(const QString& rawScriptURL) {
|
||||||
QWriteLocker lock(&_scriptEnginesHashLock);
|
QWriteLocker lock(&_scriptEnginesHashLock);
|
||||||
QUrl url = QUrl(rawScriptURL);
|
QUrl url = QUrl(rawScriptURL);
|
||||||
QUrl normalized = normalizeScriptURL(url);
|
QUrl normalized = normalizeScriptURL(url);
|
||||||
_scriptEnginesHash.insertMulti(normalized, scriptEngine);
|
_scriptEnginesHash.insert(normalized, scriptEngine);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update settings with new script
|
// Update settings with new script
|
||||||
|
|
|
@ -41,15 +41,15 @@ class ScriptEngine;
|
||||||
* @hifi-avatar
|
* @hifi-avatar
|
||||||
* @hifi-client-entity
|
* @hifi-client-entity
|
||||||
*
|
*
|
||||||
* @property {string} debugScriptUrl="" - The path and name of a script to debug using the "API Debugger" developer tool
|
* @property {string} debugScriptUrl="" - The path and name of a script to debug using the "API Debugger" developer tool
|
||||||
* (currentAPI.js). If set, the API Debugger dialog displays the objects and values exposed by the script using
|
* (currentAPI.js). If set, the API Debugger dialog displays the objects and values exposed by the script using
|
||||||
* {@link Script.registerValue} and similar.
|
* {@link Script.registerValue} and similar.
|
||||||
* @property {string} defaultScriptsPath - The path where the default scripts are located in the Interface installation.
|
* @property {string} defaultScriptsPath - The path where the default scripts are located in the Interface installation.
|
||||||
* <em>Read-only.</em>
|
* <em>Read-only.</em>
|
||||||
* @property {ScriptsModel} scriptsModel - Information on the scripts that are in the default scripts directory of the
|
* @property {ScriptsModel} scriptsModel - Information on the scripts that are in the default scripts directory of the
|
||||||
* Interface installation.
|
* Interface installation.
|
||||||
* <em>Read-only.</em>
|
* <em>Read-only.</em>
|
||||||
* @property {ScriptsModelFilter} scriptsModelFilter - Sorted and filtered information on the scripts that are in the default
|
* @property {ScriptsModelFilter} scriptsModelFilter - Sorted and filtered information on the scripts that are in the default
|
||||||
* scripts directory of the Interface installation.
|
* scripts directory of the Interface installation.
|
||||||
* <em>Read-only.</em>
|
* <em>Read-only.</em>
|
||||||
*/
|
*/
|
||||||
|
@ -83,13 +83,13 @@ public:
|
||||||
QString getDefaultScriptsLocation() const;
|
QString getDefaultScriptsLocation() const;
|
||||||
|
|
||||||
/*@jsdoc
|
/*@jsdoc
|
||||||
* Starts running an Interface script, if it isn't already running. The script is automatically loaded next time Interface
|
* Starts running an Interface script, if it isn't already running. The script is automatically loaded next time Interface
|
||||||
* starts.
|
* starts.
|
||||||
* <p>This is a synonym for calling {@link ScriptDiscoveryService.loadScript|loadScript} with just the script URL.</p>
|
* <p>This is a synonym for calling {@link ScriptDiscoveryService.loadScript|loadScript} with just the script URL.</p>
|
||||||
* <p class="availableIn"><strong>Supported Script Types:</strong> Interface Scripts • Avatar Scripts</p>
|
* <p class="availableIn"><strong>Supported Script Types:</strong> Interface Scripts • Avatar Scripts</p>
|
||||||
* <p>See also, {@link Script.load}.</p>
|
* <p>See also, {@link Script.load}.</p>
|
||||||
* @function ScriptDiscoveryService.loadOneScript
|
* @function ScriptDiscoveryService.loadOneScript
|
||||||
* @param {string} url - The path and name of the script. If a local file, including the <code>"file:///"</code> scheme is
|
* @param {string} url - The path and name of the script. If a local file, including the <code>"file:///"</code> scheme is
|
||||||
* optional.
|
* optional.
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE void loadOneScript(const QString& scriptFilename);
|
Q_INVOKABLE void loadOneScript(const QString& scriptFilename);
|
||||||
|
@ -99,15 +99,15 @@ public:
|
||||||
* <p class="availableIn"><strong>Supported Script Types:</strong> Interface Scripts • Avatar Scripts</p>
|
* <p class="availableIn"><strong>Supported Script Types:</strong> Interface Scripts • Avatar Scripts</p>
|
||||||
* <p>See also, {@link Script.load}.</p>
|
* <p>See also, {@link Script.load}.</p>
|
||||||
* @function ScriptDiscoveryService.loadScript
|
* @function ScriptDiscoveryService.loadScript
|
||||||
* @param {string} [url=""] - The path and name of the script. If a local file, including the <code>"file:///"</code>
|
* @param {string} [url=""] - The path and name of the script. If a local file, including the <code>"file:///"</code>
|
||||||
* scheme is optional.
|
* scheme is optional.
|
||||||
* @param {boolean} [isUserLoaded=true] - <code>true</code> if the user specifically loaded it, <code>false</code> if not
|
* @param {boolean} [isUserLoaded=true] - <code>true</code> if the user specifically loaded it, <code>false</code> if not
|
||||||
* (e.g., a script loaded it). If <code>false</code>, the script is not automatically loaded next time Interface starts.
|
* (e.g., a script loaded it). If <code>false</code>, the script is not automatically loaded next time Interface starts.
|
||||||
* @param {boolean} [loadScriptFromEditor=false] - <em>Not used.</em>
|
* @param {boolean} [loadScriptFromEditor=false] - <em>Not used.</em>
|
||||||
* @param {boolean} [activateMainWindow=false] - <em>Not used.</em>
|
* @param {boolean} [activateMainWindow=false] - <em>Not used.</em>
|
||||||
* @param {boolean} [reload=false] - <code>true</code> to redownload the script, <code>false</code> to use the copy from
|
* @param {boolean} [reload=false] - <code>true</code> to redownload the script, <code>false</code> to use the copy from
|
||||||
* the cache if available.
|
* the cache if available.
|
||||||
* @param {boolean} [quitWhenFinished=false] - <code>true</code> to close Interface when the script finishes,
|
* @param {boolean} [quitWhenFinished=false] - <code>true</code> to close Interface when the script finishes,
|
||||||
* <code>false</code> to not close Interface.
|
* <code>false</code> to not close Interface.
|
||||||
* @returns {object} An empty object, <code>{}</code>.
|
* @returns {object} An empty object, <code>{}</code>.
|
||||||
*/
|
*/
|
||||||
|
@ -117,11 +117,11 @@ public:
|
||||||
/*@jsdoc
|
/*@jsdoc
|
||||||
* Stops or restarts an Interface script.
|
* Stops or restarts an Interface script.
|
||||||
* @function ScriptDiscoveryService.stopScript
|
* @function ScriptDiscoveryService.stopScript
|
||||||
* @param {string} url - The path and name of the script. If a local file, including the <code>"file:///"</code> scheme is
|
* @param {string} url - The path and name of the script. If a local file, including the <code>"file:///"</code> scheme is
|
||||||
* optional.
|
* optional.
|
||||||
* @param {boolean} [restart=false] - <code>true</code> to redownload and restart the script, <code>false</code> to stop
|
* @param {boolean} [restart=false] - <code>true</code> to redownload and restart the script, <code>false</code> to stop
|
||||||
* it.
|
* it.
|
||||||
* @returns {boolean} <code>true</code> if the script was successfully stopped or restarted, <code>false</code> if it
|
* @returns {boolean} <code>true</code> if the script was successfully stopped or restarted, <code>false</code> if it
|
||||||
* wasn't (e.g., the script couldn't be found).
|
* wasn't (e.g., the script couldn't be found).
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE bool stopScript(const QString& scriptHash, bool restart = false);
|
Q_INVOKABLE bool stopScript(const QString& scriptHash, bool restart = false);
|
||||||
|
@ -134,7 +134,7 @@ public:
|
||||||
Q_INVOKABLE void reloadAllScripts();
|
Q_INVOKABLE void reloadAllScripts();
|
||||||
|
|
||||||
/*@jsdoc
|
/*@jsdoc
|
||||||
* Stops or restarts all Interface scripts. The scripts cache is not cleared. If restarting, avatar and client entity
|
* Stops or restarts all Interface scripts. The scripts cache is not cleared. If restarting, avatar and client entity
|
||||||
* scripts are also restarted.
|
* scripts are also restarted.
|
||||||
* @function ScriptDiscoveryService.stopAllScripts
|
* @function ScriptDiscoveryService.stopAllScripts
|
||||||
* @param {boolean} [restart=false] - <code>true</code> to restart the scripts, <code>false</code> to stop them.
|
* @param {boolean} [restart=false] - <code>true</code> to restart the scripts, <code>false</code> to stop them.
|
||||||
|
@ -158,7 +158,7 @@ public:
|
||||||
/*@jsdoc
|
/*@jsdoc
|
||||||
* Gets a list of all script files that are in the default scripts directory of the Interface installation.
|
* Gets a list of all script files that are in the default scripts directory of the Interface installation.
|
||||||
* @function ScriptDiscoveryService.getPublic
|
* @function ScriptDiscoveryService.getPublic
|
||||||
* @returns {ScriptDiscoveryService.PublicScript[]} All scripts in the "scripts" directory of the Interface
|
* @returns {ScriptDiscoveryService.PublicScript[]} All scripts in the "scripts" directory of the Interface
|
||||||
* installation.
|
* installation.
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE QVariantList getPublic();
|
Q_INVOKABLE QVariantList getPublic();
|
||||||
|
@ -181,7 +181,7 @@ public:
|
||||||
bool isStopped() const { return _isStopped; }
|
bool isStopped() const { return _isStopped; }
|
||||||
|
|
||||||
void addScriptEngine(ScriptEnginePointer);
|
void addScriptEngine(ScriptEnginePointer);
|
||||||
|
|
||||||
ScriptGatekeeper scriptGatekeeper;
|
ScriptGatekeeper scriptGatekeeper;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
@ -199,7 +199,7 @@ signals:
|
||||||
|
|
||||||
/*@jsdoc
|
/*@jsdoc
|
||||||
* Triggered when Interface, avatar, and client entity scripts are restarting as a result of
|
* Triggered when Interface, avatar, and client entity scripts are restarting as a result of
|
||||||
* {@link ScriptDiscoveryService.reloadAllScripts|reloadAllScripts} or
|
* {@link ScriptDiscoveryService.reloadAllScripts|reloadAllScripts} or
|
||||||
* {@link ScriptDiscoveryService.stopAllScripts|stopAllScripts}.
|
* {@link ScriptDiscoveryService.stopAllScripts|stopAllScripts}.
|
||||||
* @function ScriptDiscoveryService.scriptsReloading
|
* @function ScriptDiscoveryService.scriptsReloading
|
||||||
* @returns {Signal}
|
* @returns {Signal}
|
||||||
|
@ -344,7 +344,7 @@ protected:
|
||||||
|
|
||||||
ScriptEngine::Context _context;
|
ScriptEngine::Context _context;
|
||||||
QReadWriteLock _scriptEnginesHashLock;
|
QReadWriteLock _scriptEnginesHashLock;
|
||||||
QHash<QUrl, ScriptEnginePointer> _scriptEnginesHash;
|
QMultiHash<QUrl, ScriptEnginePointer> _scriptEnginesHash;
|
||||||
QSet<ScriptEnginePointer> _allKnownScriptEngines;
|
QSet<ScriptEnginePointer> _allKnownScriptEngines;
|
||||||
QMutex _allScriptsMutex;
|
QMutex _allScriptsMutex;
|
||||||
ScriptsModel _scriptsModel;
|
ScriptsModel _scriptsModel;
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
QVariantMap HifiConfigVariantMap::mergeCLParametersWithJSONConfig(const QStringList& argumentList) {
|
QVariantMap HifiConfigVariantMap::mergeCLParametersWithJSONConfig(const QStringList& argumentList) {
|
||||||
|
|
||||||
QVariantMap mergedMap;
|
QMultiMap<QString, QVariant> mergedMap;
|
||||||
|
|
||||||
// Add anything in the CL parameter list to the variant map.
|
// Add anything in the CL parameter list to the variant map.
|
||||||
// Take anything with a dash in it as a key, and the values after it as the value.
|
// Take anything with a dash in it as a key, and the values after it as the value.
|
||||||
|
@ -49,7 +49,7 @@ QVariantMap HifiConfigVariantMap::mergeCLParametersWithJSONConfig(const QStringL
|
||||||
|
|
||||||
if (nextKeyIndex == keyIndex + 1 || keyIndex == argumentList.size() - 1) {
|
if (nextKeyIndex == keyIndex + 1 || keyIndex == argumentList.size() - 1) {
|
||||||
// this option is simply a switch, so add it to the map with a value of `true`
|
// this option is simply a switch, so add it to the map with a value of `true`
|
||||||
mergedMap.insertMulti(key, QVariant(true));
|
mergedMap.insert(key, QVariant(true));
|
||||||
} else {
|
} else {
|
||||||
int maxIndex = (nextKeyIndex == -1) ? argumentList.size() : nextKeyIndex;
|
int maxIndex = (nextKeyIndex == -1) ? argumentList.size() : nextKeyIndex;
|
||||||
|
|
||||||
|
|
|
@ -15,10 +15,14 @@
|
||||||
#include <QVarLengthArray>
|
#include <QVarLengthArray>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
#include <QMultiHash>
|
||||||
|
#include <QMultiMap>
|
||||||
|
|
||||||
namespace hifi {
|
namespace hifi {
|
||||||
using ByteArray = QByteArray;
|
using ByteArray = QByteArray;
|
||||||
using VariantHash = QVariantHash;
|
using VariantHash = QVariantHash;
|
||||||
|
using VariantMultiHash = QMultiHash<QString, QVariant>;
|
||||||
|
using VariantMultiMap = QMultiMap<QString, QVariant>;
|
||||||
using URL = QUrl;
|
using URL = QUrl;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ public:
|
||||||
auto preset = _preset.get();
|
auto preset = _preset.get();
|
||||||
if (preset != _preset.getDefault() && _presets.contains(preset)) {
|
if (preset != _preset.getDefault() && _presets.contains(preset)) {
|
||||||
// Load the persisted configuration
|
// Load the persisted configuration
|
||||||
C::load(_presets[preset].toMap());
|
C::load(_presets.value(preset).toMap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,8 +79,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QVariantMap _default;
|
QMultiMap<QString, QVariant> _default;
|
||||||
QVariantMap _presets;
|
QMultiMap<QString, QVariant> _presets;
|
||||||
Setting::Handle<QString> _preset;
|
Setting::Handle<QString> _preset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue