mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 18:23:54 +02:00
Save attachment data for attachment model/skeleton model combinations, let
scripts use those saved parameters so that you can tweak the location of (for example) the gun and have it saved appropriately.
This commit is contained in:
parent
acab09b89a
commit
c424f6ce69
6 changed files with 120 additions and 18 deletions
|
@ -513,6 +513,55 @@ void MyAvatar::loadData(QSettings* settings) {
|
|||
settings->endGroup();
|
||||
}
|
||||
|
||||
void MyAvatar::saveAttachmentData(const AttachmentData& attachment) const {
|
||||
QSettings* settings = Application::getInstance()->lockSettings();
|
||||
settings->beginGroup("savedAttachmentData");
|
||||
settings->beginGroup(_skeletonModel.getURL().toString());
|
||||
settings->beginGroup(attachment.modelURL.toString());
|
||||
|
||||
settings->setValue("jointName", attachment.jointName);
|
||||
settings->setValue("translation_x", attachment.translation.x);
|
||||
settings->setValue("translation_y", attachment.translation.y);
|
||||
settings->setValue("translation_z", attachment.translation.z);
|
||||
glm::vec3 eulers = safeEulerAngles(attachment.rotation);
|
||||
settings->setValue("rotation_x", eulers.x);
|
||||
settings->setValue("rotation_y", eulers.y);
|
||||
settings->setValue("rotation_z", eulers.z);
|
||||
settings->setValue("scale", attachment.scale);
|
||||
|
||||
settings->endGroup();
|
||||
settings->endGroup();
|
||||
settings->endGroup();
|
||||
Application::getInstance()->unlockSettings();
|
||||
}
|
||||
|
||||
AttachmentData MyAvatar::loadAttachmentData(const QUrl& modelURL) const {
|
||||
QSettings* settings = Application::getInstance()->lockSettings();
|
||||
settings->beginGroup("savedAttachmentData");
|
||||
settings->beginGroup(_skeletonModel.getURL().toString());
|
||||
settings->beginGroup(modelURL.toString());
|
||||
|
||||
AttachmentData attachment;
|
||||
attachment.modelURL = modelURL;
|
||||
attachment.jointName = settings->value("jointName").toString();
|
||||
attachment.translation.x = loadSetting(settings, "translation_x", 0.0f);
|
||||
attachment.translation.y = loadSetting(settings, "translation_y", 0.0f);
|
||||
attachment.translation.z = loadSetting(settings, "translation_z", 0.0f);
|
||||
glm::vec3 eulers;
|
||||
eulers.x = loadSetting(settings, "rotation_x", 0.0f);
|
||||
eulers.y = loadSetting(settings, "rotation_y", 0.0f);
|
||||
eulers.z = loadSetting(settings, "rotation_z", 0.0f);
|
||||
attachment.rotation = glm::quat(eulers);
|
||||
attachment.scale = loadSetting(settings, "scale", 1.0f);
|
||||
|
||||
settings->endGroup();
|
||||
settings->endGroup();
|
||||
settings->endGroup();
|
||||
Application::getInstance()->unlockSettings();
|
||||
|
||||
return attachment;
|
||||
}
|
||||
|
||||
int MyAvatar::parseDataAtOffset(const QByteArray& packet, int offset) {
|
||||
qDebug() << "Error: ignoring update packet for MyAvatar"
|
||||
<< " packetLength = " << packet.size()
|
||||
|
@ -592,6 +641,23 @@ void MyAvatar::setAttachmentData(const QVector<AttachmentData>& attachmentData)
|
|||
_billboardValid = false;
|
||||
}
|
||||
|
||||
void MyAvatar::attach(const QString& modelURL, const QString& jointName, const glm::vec3& translation,
|
||||
const glm::quat& rotation, float scale, bool allowDuplicates, bool useSaved) {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
Avatar::attach(modelURL, jointName, translation, rotation, scale, allowDuplicates, useSaved);
|
||||
return;
|
||||
}
|
||||
if (useSaved) {
|
||||
AttachmentData attachment = loadAttachmentData(modelURL);
|
||||
if (!attachment.jointName.isEmpty()) {
|
||||
Avatar::attach(modelURL, attachment.jointName, attachment.translation,
|
||||
attachment.rotation, attachment.scale, allowDuplicates, useSaved);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Avatar::attach(modelURL, jointName, translation, rotation, scale, allowDuplicates, useSaved);
|
||||
}
|
||||
|
||||
void MyAvatar::renderBody(RenderMode renderMode, float glowLevel) {
|
||||
if (!(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable())) {
|
||||
return; // wait until both models are loaded
|
||||
|
|
|
@ -66,6 +66,9 @@ public:
|
|||
void saveData(QSettings* settings);
|
||||
void loadData(QSettings* settings);
|
||||
|
||||
void saveAttachmentData(const AttachmentData& attachment) const;
|
||||
AttachmentData loadAttachmentData(const QUrl& modelURL) const;
|
||||
|
||||
// Set what driving keys are being pressed to control thrust levels
|
||||
void setDriveKeys(int key, float val) { _driveKeys[key] = val; };
|
||||
bool getDriveKeys(int key) { return _driveKeys[key] != 0.f; };
|
||||
|
@ -88,6 +91,10 @@ public:
|
|||
virtual void setSkeletonModelURL(const QUrl& skeletonModelURL);
|
||||
virtual void setAttachmentData(const QVector<AttachmentData>& attachmentData);
|
||||
|
||||
virtual void attach(const QString& modelURL, const QString& jointName = QString(),
|
||||
const glm::vec3& translation = glm::vec3(), const glm::quat& rotation = glm::quat(), float scale = 1.0f,
|
||||
bool allowDuplicates = false, bool useSaved = true);
|
||||
|
||||
virtual void setCollisionGroups(quint32 collisionGroups);
|
||||
|
||||
void setMotionBehaviorsByScript(quint32 flags);
|
||||
|
|
|
@ -76,27 +76,28 @@ void AttachmentsDialog::addAttachment(const AttachmentData& data) {
|
|||
_attachments->insertWidget(_attachments->count() - 1, new AttachmentPanel(this, data));
|
||||
}
|
||||
|
||||
static QDoubleSpinBox* createTranslationBox(AttachmentsDialog* dialog, float value) {
|
||||
static QDoubleSpinBox* createTranslationBox(AttachmentPanel* panel, float value) {
|
||||
QDoubleSpinBox* box = new QDoubleSpinBox();
|
||||
box->setSingleStep(0.01);
|
||||
box->setMinimum(-FLT_MAX);
|
||||
box->setMaximum(FLT_MAX);
|
||||
box->setValue(value);
|
||||
dialog->connect(box, SIGNAL(valueChanged(double)), SLOT(updateAttachmentData()));
|
||||
panel->connect(box, SIGNAL(valueChanged(double)), SLOT(updateAttachmentData()));
|
||||
return box;
|
||||
}
|
||||
|
||||
static QDoubleSpinBox* createRotationBox(AttachmentsDialog* dialog, float value) {
|
||||
static QDoubleSpinBox* createRotationBox(AttachmentPanel* panel, float value) {
|
||||
QDoubleSpinBox* box = new QDoubleSpinBox();
|
||||
box->setMinimum(-180.0);
|
||||
box->setMaximum(180.0);
|
||||
box->setWrapping(true);
|
||||
box->setValue(value);
|
||||
dialog->connect(box, SIGNAL(valueChanged(double)), SLOT(updateAttachmentData()));
|
||||
panel->connect(box, SIGNAL(valueChanged(double)), SLOT(updateAttachmentData()));
|
||||
return box;
|
||||
}
|
||||
|
||||
AttachmentPanel::AttachmentPanel(AttachmentsDialog* dialog, const AttachmentData& data) {
|
||||
AttachmentPanel::AttachmentPanel(AttachmentsDialog* dialog, const AttachmentData& data) :
|
||||
_dialog(dialog) {
|
||||
setFrameStyle(QFrame::StyledPanel);
|
||||
|
||||
QFormLayout* layout = new QFormLayout();
|
||||
|
@ -107,7 +108,7 @@ AttachmentPanel::AttachmentPanel(AttachmentsDialog* dialog, const AttachmentData
|
|||
layout->addRow("Model URL:", urlBox);
|
||||
urlBox->addWidget(_modelURL = new QLineEdit(data.modelURL.toString()), 1);
|
||||
_modelURL->setText(data.modelURL.toString());
|
||||
dialog->connect(_modelURL, SIGNAL(returnPressed()), SLOT(updateAttachmentData()));
|
||||
connect(_modelURL, SIGNAL(returnPressed()), SLOT(modelURLChanged()));
|
||||
QPushButton* chooseURL = new QPushButton("Choose");
|
||||
urlBox->addWidget(chooseURL);
|
||||
connect(chooseURL, SIGNAL(clicked(bool)), SLOT(chooseModelURL()));
|
||||
|
@ -120,26 +121,26 @@ AttachmentPanel::AttachmentPanel(AttachmentsDialog* dialog, const AttachmentData
|
|||
}
|
||||
}
|
||||
_jointName->setCurrentText(data.jointName);
|
||||
dialog->connect(_jointName, SIGNAL(currentIndexChanged(int)), SLOT(updateAttachmentData()));
|
||||
connect(_jointName, SIGNAL(currentIndexChanged(int)), SLOT(updateAttachmentData()));
|
||||
|
||||
QHBoxLayout* translationBox = new QHBoxLayout();
|
||||
translationBox->addWidget(_translationX = createTranslationBox(dialog, data.translation.x));
|
||||
translationBox->addWidget(_translationY = createTranslationBox(dialog, data.translation.y));
|
||||
translationBox->addWidget(_translationZ = createTranslationBox(dialog, data.translation.z));
|
||||
translationBox->addWidget(_translationX = createTranslationBox(this, data.translation.x));
|
||||
translationBox->addWidget(_translationY = createTranslationBox(this, data.translation.y));
|
||||
translationBox->addWidget(_translationZ = createTranslationBox(this, data.translation.z));
|
||||
layout->addRow("Translation:", translationBox);
|
||||
|
||||
QHBoxLayout* rotationBox = new QHBoxLayout();
|
||||
glm::vec3 eulers = glm::degrees(safeEulerAngles(data.rotation));
|
||||
rotationBox->addWidget(_rotationX = createRotationBox(dialog, eulers.x));
|
||||
rotationBox->addWidget(_rotationY = createRotationBox(dialog, eulers.y));
|
||||
rotationBox->addWidget(_rotationZ = createRotationBox(dialog, eulers.z));
|
||||
rotationBox->addWidget(_rotationX = createRotationBox(this, eulers.x));
|
||||
rotationBox->addWidget(_rotationY = createRotationBox(this, eulers.y));
|
||||
rotationBox->addWidget(_rotationZ = createRotationBox(this, eulers.z));
|
||||
layout->addRow("Rotation:", rotationBox);
|
||||
|
||||
layout->addRow("Scale:", _scale = new QDoubleSpinBox());
|
||||
_scale->setSingleStep(0.01);
|
||||
_scale->setMaximum(FLT_MAX);
|
||||
_scale->setValue(data.scale);
|
||||
dialog->connect(_scale, SIGNAL(valueChanged(double)), SLOT(updateAttachmentData()));
|
||||
connect(_scale, SIGNAL(valueChanged(double)), SLOT(updateAttachmentData()));
|
||||
|
||||
QPushButton* remove = new QPushButton("Delete");
|
||||
layout->addRow(remove);
|
||||
|
@ -165,5 +166,30 @@ void AttachmentPanel::chooseModelURL() {
|
|||
|
||||
void AttachmentPanel::setModelURL(const QString& url) {
|
||||
_modelURL->setText(url);
|
||||
emit _modelURL->returnPressed();
|
||||
modelURLChanged();
|
||||
}
|
||||
|
||||
void AttachmentPanel::modelURLChanged() {
|
||||
// check for saved attachment data
|
||||
AttachmentData attachment = Application::getInstance()->getAvatar()->loadAttachmentData(_modelURL->text());
|
||||
if (!attachment.jointName.isEmpty()) {
|
||||
_jointName->setCurrentText(attachment.jointName);
|
||||
_translationX->setValue(attachment.translation.x);
|
||||
_translationY->setValue(attachment.translation.y);
|
||||
_translationZ->setValue(attachment.translation.z);
|
||||
glm::vec3 eulers = glm::degrees(safeEulerAngles(attachment.rotation));
|
||||
_rotationX->setValue(eulers.x);
|
||||
_rotationY->setValue(eulers.y);
|
||||
_rotationZ->setValue(eulers.z);
|
||||
_scale->setValue(attachment.scale);
|
||||
}
|
||||
_dialog->updateAttachmentData();
|
||||
}
|
||||
|
||||
void AttachmentPanel::updateAttachmentData() {
|
||||
// save the attachment data under the model URL (if any)
|
||||
if (!_modelURL->text().isEmpty()) {
|
||||
Application::getInstance()->getAvatar()->saveAttachmentData(getAttachmentData());
|
||||
}
|
||||
_dialog->updateAttachmentData();
|
||||
}
|
||||
|
|
|
@ -60,9 +60,12 @@ private slots:
|
|||
|
||||
void chooseModelURL();
|
||||
void setModelURL(const QString& url);
|
||||
void modelURLChanged();
|
||||
void updateAttachmentData();
|
||||
|
||||
private:
|
||||
|
||||
AttachmentsDialog* _dialog;
|
||||
QLineEdit* _modelURL;
|
||||
QComboBox* _jointName;
|
||||
QDoubleSpinBox* _translationX;
|
||||
|
|
|
@ -686,11 +686,11 @@ void AvatarData::setAttachmentData(const QVector<AttachmentData>& attachmentData
|
|||
}
|
||||
|
||||
void AvatarData::attach(const QString& modelURL, const QString& jointName, const glm::vec3& translation,
|
||||
const glm::quat& rotation, float scale, bool allowDuplicates) {
|
||||
const glm::quat& rotation, float scale, bool allowDuplicates, bool useSaved) {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "attach", Q_ARG(const QString&, modelURL), Q_ARG(const QString&, jointName),
|
||||
Q_ARG(const glm::vec3&, translation), Q_ARG(const glm::quat&, rotation),
|
||||
Q_ARG(float, scale), Q_ARG(bool, allowDuplicates));
|
||||
Q_ARG(float, scale), Q_ARG(bool, allowDuplicates), Q_ARG(bool, useSaved));
|
||||
return;
|
||||
}
|
||||
QVector<AttachmentData> attachmentData = getAttachmentData();
|
||||
|
|
|
@ -242,7 +242,7 @@ public:
|
|||
|
||||
Q_INVOKABLE virtual void attach(const QString& modelURL, const QString& jointName = QString(),
|
||||
const glm::vec3& translation = glm::vec3(), const glm::quat& rotation = glm::quat(), float scale = 1.0f,
|
||||
bool allowDuplicates = false);
|
||||
bool allowDuplicates = false, bool useSaved = true);
|
||||
|
||||
Q_INVOKABLE void detachOne(const QString& modelURL, const QString& jointName = QString());
|
||||
Q_INVOKABLE void detachAll(const QString& modelURL, const QString& jointName = QString());
|
||||
|
|
Loading…
Reference in a new issue