mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-29 17:23:12 +02:00
- fst read/write should work
- images are being copied into the correct directory - scripts are added to fst upon project load - modal overlay fix
This commit is contained in:
parent
1da5b3fae2
commit
ad2d9bc79a
14 changed files with 177 additions and 60 deletions
|
@ -7,7 +7,7 @@ import "../controlsUit" 1.0 as HifiControls
|
|||
import "../stylesUit" 1.0
|
||||
import "../windows" as Windows
|
||||
import "../dialogs"
|
||||
import "avatarPackager"
|
||||
import "./avatarPackager" 1.0
|
||||
import "avatarapp" 1.0 as AvatarApp
|
||||
|
||||
Windows.ScrollingWindow {
|
||||
|
@ -29,32 +29,46 @@ Windows.ScrollingWindow {
|
|||
height: pane.height
|
||||
width: pane.width
|
||||
|
||||
Rectangle {
|
||||
id: modalOverlay
|
||||
anchors.fill: parent
|
||||
z: 20
|
||||
color: "#aa031b33"
|
||||
visible: false
|
||||
|
||||
// This mouse area captures the cursor events while the modalOverlay is active
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
propagateComposedEvents: false;
|
||||
hoverEnabled: true;
|
||||
}
|
||||
}
|
||||
|
||||
AvatarApp.MessageBox {
|
||||
id: popup
|
||||
anchors.fill: parent
|
||||
visible: false
|
||||
}
|
||||
|
||||
// FIXME: modal overlay does not show
|
||||
Column {
|
||||
id: avatarPackager
|
||||
anchors.fill: parent
|
||||
state: "main"
|
||||
states: [
|
||||
State {
|
||||
name: "main"
|
||||
name: AvatarPackagerState.main
|
||||
PropertyChanges { target: avatarPackagerHeader; title: qsTr("Avatar Packager"); faqEnabled: true; backButtonEnabled: false }
|
||||
PropertyChanges { target: avatarPackagerMain; visible: true }
|
||||
PropertyChanges { target: avatarPackagerFooter; content: avatarPackagerMain.footer }
|
||||
},
|
||||
State {
|
||||
name: "createProject"
|
||||
name: AvatarPackagerState.createProject
|
||||
PropertyChanges { target: avatarPackagerHeader; title: qsTr("Create Project") }
|
||||
PropertyChanges { target: createAvatarProject; visible: true }
|
||||
PropertyChanges { target: avatarPackagerFooter; content: createAvatarProject.footer }
|
||||
},
|
||||
State {
|
||||
name: "project"
|
||||
name: AvatarPackagerState.project
|
||||
PropertyChanges { target: avatarPackagerHeader; title: AvatarPackagerCore.currentAvatarProject.name }
|
||||
PropertyChanges { target: avatarProject; visible: true }
|
||||
PropertyChanges { target: avatarPackagerFooter; content: avatarProject.footer }
|
||||
|
@ -67,6 +81,8 @@ Windows.ScrollingWindow {
|
|||
}
|
||||
]
|
||||
|
||||
property alias showModalOverlay: modalOverlay.visible
|
||||
|
||||
AvatarPackagerHeader {
|
||||
id: avatarPackagerHeader
|
||||
onBackButtonClicked: {
|
||||
|
@ -119,7 +135,7 @@ Windows.ScrollingWindow {
|
|||
text: qsTr("New Project")
|
||||
colorScheme: root.colorScheme
|
||||
onClicked: {
|
||||
avatarPackager.state = "createProject";
|
||||
avatarPackager.state = AvatarPackagerState.createProject;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,7 +149,7 @@ Windows.ScrollingWindow {
|
|||
color: hifi.buttons.blue
|
||||
colorScheme: root.colorScheme
|
||||
onClicked: {
|
||||
// TODO: make the dialog modal
|
||||
avatarPackager.showModalOverlay = true;
|
||||
let browser = desktop.fileDialog({
|
||||
selectDirectory: false,
|
||||
dir: fileDialogHelper.pathToUrl(AvatarPackagerCore.AVATAR_PROJECTS_PATH),
|
||||
|
@ -142,14 +158,15 @@ Windows.ScrollingWindow {
|
|||
});
|
||||
|
||||
browser.canceled.connect(function() {
|
||||
|
||||
avatarPackager.showModalOverlay = false;
|
||||
});
|
||||
|
||||
browser.selectedFile.connect(function(fileUrl) {
|
||||
let fstFilePath = fileDialogHelper.urlToPath(fileUrl);
|
||||
let currentAvatarProject = AvatarPackagerCore.openAvatarProject(fstFilePath);
|
||||
if (currentAvatarProject) {
|
||||
avatarPackager.state = "project";
|
||||
avatarPackager.state = AvatarPackagerState.project;
|
||||
avatarPackager.showModalOverlay = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ Rectangle {
|
|||
|
||||
color: "#404040"
|
||||
height: content === defaultContent ? 0 : 74
|
||||
visible: content !== defaultContent
|
||||
width: parent.width
|
||||
|
||||
property var content: Item { id: defaultContent }
|
||||
|
|
|
@ -65,7 +65,7 @@ Rectangle {
|
|||
anchors.right: parent.right
|
||||
anchors.rightMargin: 16
|
||||
anchors.verticalCenter: faq.verticalCenter
|
||||
text: qsTr("FAQ")
|
||||
text: qsTr("Docs")
|
||||
color: "white"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
pragma Singleton
|
||||
import QtQuick 2.6
|
||||
|
||||
Item {
|
||||
id: singleton
|
||||
readonly property string main: "main"
|
||||
readonly property string project: "project"
|
||||
readonly property string createProject: "createProject"
|
||||
}
|
|
@ -27,7 +27,7 @@ Item {
|
|||
Window.alert('Failed to create project')
|
||||
return;
|
||||
}
|
||||
avatarPackager.state = "project";
|
||||
avatarPackager.state = AvatarPackagerState.project;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,26 @@ Item {
|
|||
height: parent.height
|
||||
width: parent.width
|
||||
|
||||
|
||||
property var errorMessages: QtObject {
|
||||
readonly property string fileExists: "A folder with that name already exists at that location. Please choose a different project name or location."
|
||||
}
|
||||
|
||||
RalewayRegular {
|
||||
id: errorMessage
|
||||
visible: text !== ""
|
||||
text: ""
|
||||
color: "#EA4C5F";
|
||||
wrapMode: Text.WordWrap
|
||||
size: 20
|
||||
anchors {
|
||||
top: createAvatarColumns.bottom
|
||||
bottom: parent.bottom
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
id: createAvatarColumns
|
||||
anchors.left: parent.left
|
||||
|
@ -45,6 +65,8 @@ Item {
|
|||
|
||||
spacing: 17
|
||||
|
||||
property string defaultFileBrowserPath: fileDialogHelper.pathToUrl(AvatarPackagerCore.AVATAR_PROJECTS_PATH)
|
||||
|
||||
ProjectInputControl {
|
||||
id: name
|
||||
label: "Name"
|
||||
|
@ -57,9 +79,8 @@ Item {
|
|||
colorScheme: root.colorScheme
|
||||
browseEnabled: true
|
||||
browseFolder: true
|
||||
browseDir: fileDialogHelper.pathToUrl(AvatarPackagerCore.AVATAR_PROJECTS_PATH)
|
||||
browseDir: text !== "" ? fileDialogHelper.pathToUrl(text) : createAvatarColumns.defaultFileBrowserPath
|
||||
browseTitle: "Project Location"
|
||||
text: fileDialogHelper.pathToUrl(AvatarPackagerCore.AVATAR_PROJECTS_PATH)
|
||||
onTextChanged: {
|
||||
//TODO: valid folder? Does project with name exist here already?
|
||||
}
|
||||
|
@ -71,11 +92,13 @@ Item {
|
|||
colorScheme: root.colorScheme
|
||||
browseEnabled: true
|
||||
browseFolder: false
|
||||
browseDir: fileDialogHelper.pathToUrl(AvatarPackagerCore.AVATAR_PROJECTS_PATH)
|
||||
browseDir: text !== "" ? fileDialogHelper.pathToUrl(text) : createAvatarColumns.defaultFileBrowserPath
|
||||
browseFilter: "Avatar Model File (*.fbx)"
|
||||
browseTitle: "Open Avatar Model (.fbx)"
|
||||
onTextChanged: {
|
||||
//TODO: try to get texture folder from fbx if none is set?
|
||||
if (avatarModel.text !== "") {
|
||||
textureFolder.browseDir = fileDialogHelper.pathToUrl(avatarModel.text.split('/')[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,7 +108,7 @@ Item {
|
|||
colorScheme: root.colorScheme
|
||||
browseEnabled: true
|
||||
browseFolder: true
|
||||
browseDir: fileDialogHelper.pathToUrl(AvatarPackagerCore.AVATAR_PROJECTS_PATH)
|
||||
browseDir: text !== "" ? fileDialogHelper.pathToUrl(text) : createAvatarColumns.defaultFileBrowserPath
|
||||
browseTitle: "Texture Folder"
|
||||
onTextChanged: {
|
||||
//TODO: valid folder?
|
||||
|
@ -93,16 +116,5 @@ Item {
|
|||
}
|
||||
}
|
||||
}
|
||||
RalewayRegular {
|
||||
text: "A folder with that name already exists at that location. Please choose a different project name or location."
|
||||
color: "#EA4C5F";
|
||||
wrapMode: Text.WordWrap
|
||||
size: 20
|
||||
anchors {
|
||||
top: createAvatarColumns.bottom
|
||||
bottom: parent.bottom
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ Column {
|
|||
text: qsTr("Browse")
|
||||
colorScheme: root.colorScheme
|
||||
onClicked: {
|
||||
// TODO: make the dialog modal
|
||||
avatarPackager.showModalOverlay = true;
|
||||
let browser = desktop.fileDialog({
|
||||
selectDirectory: browseFolder,
|
||||
dir: browseDir,
|
||||
|
@ -64,11 +64,12 @@ Column {
|
|||
});
|
||||
|
||||
browser.canceled.connect(function() {
|
||||
|
||||
avatarPackager.showModalOverlay = false;
|
||||
});
|
||||
|
||||
browser.selectedFile.connect(function(fileUrl) {
|
||||
input.text = fileDialogHelper.urlToPath(fileUrl);
|
||||
avatarPackager.showModalOverlay = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
2
interface/resources/qml/hifi/avatarPackager/qmldir
Normal file
2
interface/resources/qml/hifi/avatarPackager/qmldir
Normal file
|
@ -0,0 +1,2 @@
|
|||
module AvatarPackager
|
||||
singleton AvatarPackagerState 1.0 AvatarPackagerState.qml
|
|
@ -30,6 +30,9 @@ AvatarPackager::AvatarPackager() {
|
|||
qRegisterMetaType<AvatarPackager*>();
|
||||
qRegisterMetaType<AvatarProject*>();
|
||||
});
|
||||
|
||||
QDir defaultProjectsDir(AvatarProject::getDefaultProjectsPath());
|
||||
defaultProjectsDir.mkpath(".");
|
||||
}
|
||||
|
||||
bool AvatarPackager::open() {
|
||||
|
@ -57,7 +60,7 @@ AvatarProject* AvatarPackager::createAvatarProject(const QString& projectsFolder
|
|||
if (_currentAvatarProject) {
|
||||
_currentAvatarProject->deleteLater();
|
||||
}
|
||||
_currentAvatarProject = AvatarProject::createAvatarProject(avatarProjectName, avatarModelPath);
|
||||
_currentAvatarProject = AvatarProject::createAvatarProject(projectsFolder, avatarProjectName, avatarModelPath, textureFolder);
|
||||
qDebug() << "_currentAvatarProject has" << (QQmlEngine::objectOwnership(_currentAvatarProject) == QQmlEngine::CppOwnership ? "CPP" : "JS") << "OWNERSHIP";
|
||||
QQmlEngine::setObjectOwnership(_currentAvatarProject, QQmlEngine::CppOwnership);
|
||||
emit avatarProjectChanged();
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "FBXSerializer.h"
|
||||
#include <ui/TabletScriptingInterface.h>
|
||||
#include <graphics/TextureMap.h>
|
||||
#include "scripting/HMDScriptingInterface.h"
|
||||
|
||||
AvatarProject* AvatarProject::openAvatarProject(const QString& path) {
|
||||
|
@ -36,17 +37,25 @@ AvatarProject* AvatarProject::openAvatarProject(const QString& path) {
|
|||
return project;
|
||||
}
|
||||
|
||||
AvatarProject* AvatarProject::createAvatarProject(const QString& avatarProjectName, const QString& avatarModelPath) {
|
||||
AvatarProject* AvatarProject::createAvatarProject(const QString& projectsFolder, const QString& avatarProjectName, const QString& avatarModelPath, const QString& textureFolder) {
|
||||
if (!isValidNewProjectName(avatarProjectName)) {
|
||||
return nullptr;
|
||||
}
|
||||
QDir dir(getDefaultProjectsPath() + "/" + avatarProjectName);
|
||||
if (!dir.mkpath(".")) {
|
||||
QDir projectDir(projectsFolder + "/" + avatarProjectName);
|
||||
if (!projectDir.mkpath(".")) {
|
||||
return nullptr;
|
||||
}
|
||||
QDir projectTexturesDir(projectDir.path() + "/textures");
|
||||
if (!projectTexturesDir.mkpath(".")) {
|
||||
return nullptr;
|
||||
}
|
||||
QDir projectScriptsDir(projectDir.path() + "/scripts");
|
||||
if (!projectScriptsDir.mkpath(".")) {
|
||||
return nullptr;
|
||||
}
|
||||
const auto fileName = QFileInfo(avatarModelPath).fileName();
|
||||
const auto newModelPath = dir.absoluteFilePath(fileName);
|
||||
const auto newFSTPath = dir.absoluteFilePath("avatar.fst");
|
||||
const auto newModelPath = projectDir.absoluteFilePath(fileName);
|
||||
const auto newFSTPath = projectDir.absoluteFilePath("avatar.fst");
|
||||
QFile::copy(avatarModelPath, newModelPath);
|
||||
|
||||
QFileInfo fbxInfo(newModelPath);
|
||||
|
@ -66,10 +75,41 @@ AvatarProject* AvatarProject::createAvatarProject(const QString& avatarProjectNa
|
|||
qDebug() << "Error reading: " << error;
|
||||
return nullptr;
|
||||
}
|
||||
//TODO: copy/fix textures here:
|
||||
QStringList textures{};
|
||||
|
||||
FST* fst = FST::createFSTFromModel(newFSTPath, newModelPath, *hfmModel);
|
||||
auto addTextureToList = [&textures](hfm::Texture texture) mutable {
|
||||
if (!texture.filename.isEmpty() && texture.content.isEmpty() && !textures.contains(texture.filename)) {
|
||||
textures << texture.filename;
|
||||
}
|
||||
};
|
||||
|
||||
foreach(const HFMMaterial mat, hfmModel->materials) {
|
||||
addTextureToList(mat.normalTexture);
|
||||
addTextureToList(mat.albedoTexture);
|
||||
addTextureToList(mat.opacityTexture);
|
||||
addTextureToList(mat.glossTexture);
|
||||
addTextureToList(mat.roughnessTexture);
|
||||
addTextureToList(mat.specularTexture);
|
||||
addTextureToList(mat.metallicTexture);
|
||||
addTextureToList(mat.emissiveTexture);
|
||||
addTextureToList(mat.occlusionTexture);
|
||||
addTextureToList(mat.scatteringTexture);
|
||||
addTextureToList(mat.lightmapTexture);
|
||||
}
|
||||
|
||||
QDir textureDir(textureFolder.isEmpty() ? fbxInfo.absoluteDir() : textureFolder);
|
||||
|
||||
for (const auto& texture : textures) {
|
||||
QString sourcePath = textureDir.path() + "/" + texture;
|
||||
QString targetPath = projectTexturesDir.path() + "/" + texture;
|
||||
|
||||
QFileInfo sourceTexturePath(sourcePath);
|
||||
if (sourceTexturePath.exists()) {
|
||||
QFile::copy(sourcePath, targetPath);
|
||||
}
|
||||
}
|
||||
|
||||
auto fst = FST::createFSTFromModel(newFSTPath, newModelPath, *hfmModel);
|
||||
fst->setName(avatarProjectName);
|
||||
|
||||
if (!fst->write()) {
|
||||
|
@ -79,6 +119,22 @@ AvatarProject* AvatarProject::createAvatarProject(const QString& avatarProjectNa
|
|||
return new AvatarProject(fst);
|
||||
}
|
||||
|
||||
QStringList AvatarProject::getScriptPaths(const QDir& scriptsDir) {
|
||||
QStringList result{};
|
||||
constexpr auto flags = QDir::Files | QDir::NoSymLinks | QDir::NoDotAndDotDot | QDir::Hidden;
|
||||
if (!scriptsDir.exists()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
for (auto& script : scriptsDir.entryInfoList({}, flags)) {
|
||||
if (script.fileName().endsWith(".js")) {
|
||||
result.push_back("scripts/" + script.fileName());
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool AvatarProject::isValidNewProjectName(const QString& projectName) {
|
||||
QDir dir(getDefaultProjectsPath() + "/" + projectName);
|
||||
return !dir.exists();
|
||||
|
@ -92,6 +148,9 @@ AvatarProject::AvatarProject(FST* fst) {
|
|||
auto fileInfo = QFileInfo(getFSTPath());
|
||||
_directory = fileInfo.absoluteDir();
|
||||
|
||||
_fst->setScriptPaths(getScriptPaths(QDir(_directory.path() + "/scripts")));
|
||||
_fst->write();
|
||||
|
||||
//_projectFiles = _directory.entryList();
|
||||
refreshProjectFiles();
|
||||
|
||||
|
@ -125,8 +184,7 @@ MarketplaceItemUploader* AvatarProject::upload(bool updateExisting) {
|
|||
connect(uploader, &MarketplaceItemUploader::completed, this, [this, uploader]() {
|
||||
if (uploader->getError() == MarketplaceItemUploader::Error::None) {
|
||||
_fst->setMarketplaceID(uploader->getMarketplaceID());
|
||||
// TODO(thoys) uncomment this
|
||||
//_fst->write();
|
||||
_fst->write();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -36,11 +36,6 @@ class AvatarProject : public QObject {
|
|||
Q_PROPERTY(QString name READ getProjectName)
|
||||
|
||||
public:
|
||||
Q_INVOKABLE bool write() {
|
||||
// Write FST here
|
||||
return false;
|
||||
}
|
||||
|
||||
Q_INVOKABLE MarketplaceItemUploader* upload(bool updateExisting);
|
||||
Q_INVOKABLE void openInInventory();
|
||||
|
||||
|
@ -48,7 +43,8 @@ public:
|
|||
* returns the AvatarProject or a nullptr on failure.
|
||||
*/
|
||||
static AvatarProject* openAvatarProject(const QString& path);
|
||||
static AvatarProject* createAvatarProject(const QString& avatarProjectName, const QString& avatarModelPath);
|
||||
static AvatarProject* createAvatarProject(const QString& projectsFolder, const QString& avatarProjectName,
|
||||
const QString& avatarModelPath, const QString& textureFolder);
|
||||
|
||||
static bool isValidNewProjectName(const QString& projectName);
|
||||
|
||||
|
@ -61,7 +57,7 @@ private:
|
|||
AvatarProject(FST* fst);
|
||||
|
||||
~AvatarProject() {
|
||||
// TODO: cleanup FST / AvatarProjectUploader etc.
|
||||
_fst->deleteLater();
|
||||
}
|
||||
|
||||
Q_INVOKABLE QString getProjectName() const { return _fst->getName(); }
|
||||
|
@ -73,6 +69,7 @@ private:
|
|||
|
||||
void refreshProjectFiles();
|
||||
void appendDirectory(QString prefix, QDir dir);
|
||||
QStringList getScriptPaths(const QDir& scriptsDir);
|
||||
|
||||
FST* _fst;
|
||||
|
||||
|
|
|
@ -16,14 +16,23 @@
|
|||
#include <hfm/HFM.h>
|
||||
|
||||
FST::FST(const QString& fstPath, QVariantHash data) : _fstPath(fstPath) {
|
||||
if (data.contains(NAME_FIELD)) {
|
||||
_name = data[NAME_FIELD].toString();
|
||||
data.remove(NAME_FIELD);
|
||||
}
|
||||
|
||||
if (data.contains(FILENAME_FIELD)) {
|
||||
_modelPath = data[FILENAME_FIELD].toString();
|
||||
data.remove(FILENAME_FIELD);
|
||||
auto setValueFromFSTData = [&data] (const QString& propertyID, auto &targetProperty) mutable {
|
||||
if (data.contains(propertyID)) {
|
||||
targetProperty = data[propertyID].toString();
|
||||
data.remove(propertyID);
|
||||
}
|
||||
};
|
||||
setValueFromFSTData(NAME_FIELD, _name);
|
||||
setValueFromFSTData(FILENAME_FIELD, _modelPath);
|
||||
setValueFromFSTData(MARKETPLACE_ID_FIELD, _marketplaceID);
|
||||
|
||||
if (data.contains(SCRIPT_FIELD)) {
|
||||
QVariantList scripts = data.values(SCRIPT_FIELD);
|
||||
for (const auto& script : scripts) {
|
||||
_scriptPaths.push_back(script.toString());
|
||||
}
|
||||
data.remove(SCRIPT_FIELD);
|
||||
}
|
||||
|
||||
_other = data;
|
||||
|
@ -42,10 +51,8 @@ FST* FST::createFSTFromModel(QString fstPath, QString modelFilePath, const hfm::
|
|||
hfmModel.blendshapeChannelNames.contains("Squint_Right"));
|
||||
|
||||
mapping.insert(NAME_FIELD, QFileInfo(fstPath).baseName());
|
||||
QDir root(modelFilePath);
|
||||
mapping.insert(FILENAME_FIELD, root.relativeFilePath(fstPath));
|
||||
mapping.insert(FILENAME_FIELD, QFileInfo(modelFilePath).fileName());
|
||||
mapping.insert(TEXDIR_FIELD, "textures");
|
||||
mapping.insert(SCRIPT_FIELD, "scripts");
|
||||
|
||||
// mixamo/autodesk defaults
|
||||
mapping.insert(SCALE_FIELD, 1.0);
|
||||
|
@ -150,9 +157,13 @@ void FST::setModelPath(const QString& modelPath) {
|
|||
|
||||
QVariantHash FST::getMapping() {
|
||||
QVariantHash mapping;
|
||||
mapping.insertMulti(NAME_FIELD, _name);
|
||||
mapping.insertMulti(FILENAME_FIELD, _modelPath);
|
||||
mapping.unite(_other);
|
||||
mapping.insert(NAME_FIELD, _name);
|
||||
mapping.insert(FILENAME_FIELD, _modelPath);
|
||||
mapping.insert(MARKETPLACE_ID_FIELD, _marketplaceID);
|
||||
for (const auto& scriptPath : _scriptPaths) {
|
||||
mapping.insertMulti(SCRIPT_FIELD, scriptPath);
|
||||
}
|
||||
return mapping;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,9 @@ public:
|
|||
QUuid getMarketplaceID() const { return _marketplaceID; }
|
||||
void setMarketplaceID(QUuid marketplaceID) { _marketplaceID = marketplaceID; }
|
||||
|
||||
QStringList getScriptPaths() const { return _scriptPaths; }
|
||||
void setScriptPaths(QStringList scriptPaths) { _scriptPaths = scriptPaths; }
|
||||
|
||||
QString getPath() { return _fstPath; }
|
||||
|
||||
QVariantHash getMapping();
|
||||
|
@ -58,6 +61,8 @@ private:
|
|||
QString _modelPath{};
|
||||
QUuid _marketplaceID{};
|
||||
|
||||
QStringList _scriptPaths{};
|
||||
|
||||
QVariantHash _other{};
|
||||
};
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ void FSTReader::writeVariant(QBuffer& buffer, QVariantHash::const_iterator& it)
|
|||
|
||||
QByteArray FSTReader::writeMapping(const QVariantHash& mapping) {
|
||||
static const QStringList PREFERED_ORDER = QStringList() << NAME_FIELD << TYPE_FIELD << SCALE_FIELD << FILENAME_FIELD
|
||||
<< TEXDIR_FIELD << SCRIPT_FIELD << JOINT_FIELD << FREE_JOINT_FIELD
|
||||
<< MARKETPLACE_ID_FIELD << TEXDIR_FIELD << SCRIPT_FIELD << JOINT_FIELD << FREE_JOINT_FIELD
|
||||
<< BLENDSHAPE_FIELD << JOINT_INDEX_FIELD;
|
||||
QBuffer buffer;
|
||||
buffer.open(QIODevice::WriteOnly);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
static const QString NAME_FIELD = "name";
|
||||
static const QString TYPE_FIELD = "type";
|
||||
static const QString FILENAME_FIELD = "filename";
|
||||
static const QString MARKETPLACE_ID_FIELD = "marketplaceID";
|
||||
static const QString TEXDIR_FIELD = "texdir";
|
||||
static const QString LOD_FIELD = "lod";
|
||||
static const QString JOINT_INDEX_FIELD = "jointIndex";
|
||||
|
|
Loading…
Reference in a new issue