Skip to content

Commit

Permalink
Adding AutoJCM feature
Browse files Browse the repository at this point in the history
  • Loading branch information
David-Vodhanel committed Sep 26, 2021
1 parent fdec774 commit 536eef8
Show file tree
Hide file tree
Showing 10 changed files with 922 additions and 9 deletions.
37 changes: 35 additions & 2 deletions Unreal/DazStudioPlugin/DzUnrealAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#include "DzUnrealDialog.h"
#include "DzUnrealAction.h"
#include "DzUnrealMorphSelectionDialog.h"

DzUnrealAction::DzUnrealAction() :
DzRuntimePluginAction(tr("&Daz to Unreal"), tr("Send the selected node to Unreal."))
Expand Down Expand Up @@ -152,10 +153,42 @@ void DzUnrealAction::WriteConfiguration()
writer.finishObject();
}
}

writer.finishArray();


if (ExportMorphs)
{
DzMainWindow* mw = dzApp->getInterface();
DzUnrealMorphSelectionDialog* morphDialog = DzUnrealMorphSelectionDialog::Get(mw);
if (morphDialog->IsAutoJCMEnabled())
{
writer.startMemberArray("JointLinks", true);
QList<JointLinkInfo> JointLinks = morphDialog->GetActiveJointControlledMorphs(Selection);
foreach(JointLinkInfo linkInfo, JointLinks)
{
writer.startObject(true);
writer.addMember("Bone", linkInfo.Bone);
writer.addMember("Axis", linkInfo.Axis);
writer.addMember("Morph", linkInfo.Morph);
writer.addMember("Scalar", linkInfo.Scalar);
writer.addMember("Alpha", linkInfo.Alpha);
if (linkInfo.Keys.count() > 0)
{
writer.startMemberArray("Keys", true);
foreach(JointLinkKey key, linkInfo.Keys)
{
writer.startObject(true);
writer.addMember("Angle", key.Angle);
writer.addMember("Value", key.Value);
writer.finishObject();
}
writer.finishArray();
}
writer.finishObject();
}
writer.finishArray();
}
}

writer.startMemberArray("Subdivisions", true);
if (ExportSubdivisions)
SubdivisionDialog->WriteSubdivisions(writer);
Expand Down
189 changes: 189 additions & 0 deletions Unreal/DazStudioPlugin/DzUnrealMorphSelectionDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@
#include "dzproperty.h"
#include "dzsettings.h"
#include "dzmorph.h"
#include "dzcontroller.h"
#include "dznumericnodeproperty.h"
#include "dzerclink.h"
#include "dzbone.h"
#include "DzUnrealMorphSelectionDialog.h"

#include "QtGui/qlayout.h"
Expand Down Expand Up @@ -65,6 +69,8 @@ class SortingListItem : public QListWidgetItem {
DzUnrealMorphSelectionDialog::DzUnrealMorphSelectionDialog(QWidget *parent) :
DzBasicDialog(parent, DAZ_TO_UNREAL_PLUGIN_NAME)
{
settings = new QSettings("Daz 3D", "DazToUnreal");

morphListWidget = NULL;
morphExportListWidget = NULL;
morphTreeWidget = NULL;
Expand Down Expand Up @@ -132,19 +138,27 @@ DzUnrealMorphSelectionDialog::DzUnrealMorphSelectionDialog(QWidget *parent) :
QPushButton* TorsoJCMButton = new QPushButton("Torso");
QPushButton* ARKit81Button = new QPushButton("ARKit (Genesis8.1)");
QPushButton* FaceFX8Button = new QPushButton("FaceFX (Genesis8)");
autoJCMCheckBox = new QCheckBox("Auto JCM");
((QGridLayout*)JCMGroupBox->layout())->addWidget(ArmsJCMButton, 0, 0);
((QGridLayout*)JCMGroupBox->layout())->addWidget(LegsJCMButton, 0, 1);
((QGridLayout*)JCMGroupBox->layout())->addWidget(TorsoJCMButton, 0, 2);
((QGridLayout*)FaceGroupBox->layout())->addWidget(ARKit81Button, 0, 1);
((QGridLayout*)FaceGroupBox->layout())->addWidget(FaceFX8Button, 0, 2);
MorphGroupBox->layout()->addWidget(JCMGroupBox);
MorphGroupBox->layout()->addWidget(FaceGroupBox);
MorphGroupBox->layout()->addWidget(autoJCMCheckBox);

if (!settings->value("AutoJCMEnabled").isNull())
{
autoJCMCheckBox->setChecked(settings->value("AutoJCMEnabled").toBool());
}

connect(ArmsJCMButton, SIGNAL(released()), this, SLOT(HandleArmJCMMorphsButton()));
connect(LegsJCMButton, SIGNAL(released()), this, SLOT(HandleLegJCMMorphsButton()));
connect(TorsoJCMButton, SIGNAL(released()), this, SLOT(HandleTorsoJCMMorphsButton()));
connect(ARKit81Button, SIGNAL(released()), this, SLOT(HandleARKitGenesis81MorphsButton()));
connect(FaceFX8Button, SIGNAL(released()), this, SLOT(HandleFaceFXGenesis8Button()));
connect(autoJCMCheckBox, SIGNAL(clicked(bool)), this, SLOT(HandleAutoJCMCheckBoxChange(bool)));

treeLayout->addWidget(MorphGroupBox);
morphsLayout->addLayout(treeLayout);
Expand Down Expand Up @@ -223,6 +237,9 @@ void DzUnrealMorphSelectionDialog::PrepareDialog()
DzNode* ChildNode = Selection->getNodeChild(ChildIndex);
morphList.append(GetAvailableMorphs(ChildNode));
}

//GetActiveJointControlledMorphs(Selection);

UpdateMorphsTree();
HandlePresetChanged("LastUsed.csv");
}
Expand Down Expand Up @@ -337,6 +354,170 @@ QStringList DzUnrealMorphSelectionDialog::GetAvailableMorphs(DzNode* Node)
return newMorphList;
}

// Recursive function for finding all active JCM morphs for a node
QList<JointLinkInfo> DzUnrealMorphSelectionDialog::GetActiveJointControlledMorphs(DzNode* Node)
{
QList<JointLinkInfo> returnMorphs;
if (autoJCMCheckBox->isChecked())
{
if (Node == nullptr)
{
Node = dzScene->getPrimarySelection();

// For items like clothing, create the morph list from the character
DzNode* ParentFigureNode = Node;
while (ParentFigureNode->getNodeParent())
{
ParentFigureNode = ParentFigureNode->getNodeParent();
if (DzSkeleton* Skeleton = ParentFigureNode->getSkeleton())
{
if (DzFigure* Figure = qobject_cast<DzFigure*>(Skeleton))
{
Node = ParentFigureNode;
break;
}
}
}
}


DzObject* Object = Node->getObject();
DzShape* Shape = Object ? Object->getCurrentShape() : NULL;

for (int index = 0; index < Node->getNumProperties(); index++)
{
DzProperty* property = Node->getProperty(index);
returnMorphs.append(GetJointControlledMorphInfo(property));
}

if (Object)
{
for (int index = 0; index < Object->getNumModifiers(); index++)
{
DzModifier* modifier = Object->getModifier(index);
QString modName = modifier->getName();
QString modLabel = modifier->getLabel();
DzMorph* mod = qobject_cast<DzMorph*>(modifier);
if (mod)
{
for (int propindex = 0; propindex < modifier->getNumProperties(); propindex++)
{
DzProperty* property = modifier->getProperty(propindex);
returnMorphs.append(GetJointControlledMorphInfo(property));
}

}

}
}

}

return returnMorphs;
}

QList<JointLinkInfo> DzUnrealMorphSelectionDialog::GetJointControlledMorphInfo(DzProperty* property)
{
QList<JointLinkInfo> returnMorphs;

QString propName = property->getName();
QString propLabel = property->getLabel();
DzPresentation* presentation = property->getPresentation();
if (presentation && presentation->getType() == "Modifier/Corrective")
{
QString linkLabel;
QString linkDescription;
QString linkBone;
QString linkAxis;
QString linkBodyType;
double bodyStrength = 0.0f;
double currentBodyScalar = 0.0f;
double linkScalar = 0.0f;
bool isJCM = false;
QList<double> keys;
QList<double> keysValues;
QList<JointLinkKey> linkKeys;

for (int ControllerIndex = 0; ControllerIndex < property->getNumControllers(); ControllerIndex++)
{
DzController* controller = property->getController(ControllerIndex);

DzERCLink* link = qobject_cast<DzERCLink*>(controller);
if (link)
{
double value = link->getScalar();
QString linkProperty = link->getProperty()->getName();
QString linkObject = link->getProperty()->getOwner()->getName();
double currentValue = link->getProperty()->getDoubleValue();

DzBone* bone = qobject_cast<DzBone*>(link->getProperty()->getOwner());
if (bone)
{
linkLabel = propLabel;
linkDescription = controller->description();
linkBone = linkObject;
linkAxis = linkProperty;
linkScalar = value;
isJCM = true;

if (link->getType() == 6)
{
for (int keyIndex = 0; keyIndex < link->getNumKeyValues(); keyIndex++)
{
JointLinkKey newKey;
newKey.Angle = link->getKey(keyIndex);
newKey.Value = link->getKeyValue(keyIndex);
linkKeys.append(newKey);
keys.append(link->getKey(keyIndex));
keysValues.append(link->getKeyValue(keyIndex));
}
}
}
else
{
linkBodyType = linkObject;
bodyStrength = value;
currentBodyScalar = currentValue;
}
}
}

if (isJCM && currentBodyScalar > 0.0f)
{
JointLinkInfo linkInfo;
linkInfo.Bone = linkBone;
linkInfo.Axis = linkAxis;
linkInfo.Morph = linkLabel;
linkInfo.Scalar = linkScalar;
linkInfo.Alpha = currentBodyScalar;
linkInfo.Keys = linkKeys;
qDebug() << "Label " << linkLabel << " Description " << linkDescription << " Bone " << linkBone << " Axis " << linkAxis << " Alpha " << currentBodyScalar << " Scalar " << linkScalar;
if (!keys.isEmpty())
{
foreach(double key, keys)
{
qDebug() << key;
}

foreach(double key, keysValues)
{
qDebug() << key;
}

}

if (morphs.contains(linkLabel) && !morphsToExport.contains(morphs[linkLabel]))
{
morphsToExport.append(morphs[linkLabel]);
}

returnMorphs.append(linkInfo);

}
}
return returnMorphs;
}

// Build out the left tree
void DzUnrealMorphSelectionDialog::UpdateMorphsTree()
{
Expand Down Expand Up @@ -718,6 +899,11 @@ void DzUnrealMorphSelectionDialog::HandleFaceFXGenesis8Button()
RefreshExportMorphList();
}

void DzUnrealMorphSelectionDialog::HandleAutoJCMCheckBoxChange(bool checked)
{
settings->setValue("AutoJCMEnabled", checked);
}

// Refresh the Right export list
void DzUnrealMorphSelectionDialog::RefreshExportMorphList()
{
Expand Down Expand Up @@ -780,12 +966,15 @@ void DzUnrealMorphSelectionDialog::HandlePresetChanged(const QString& presetName
}

RefreshExportMorphList();
GetActiveJointControlledMorphs();
file.close();
}

// Get the morph string in the format for the Daz FBX Export
QString DzUnrealMorphSelectionDialog::GetMorphString()
{
GetActiveJointControlledMorphs();

if (morphsToExport.length() == 0)
{
return "";
Expand Down
28 changes: 28 additions & 0 deletions Unreal/DazStudioPlugin/DzUnrealMorphSelectionDialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class QTreeWidget;
class QTreeWidgetItem;
class QLineEdit;
class QComboBox;
class QCheckBox;

struct MorphInfo {
QString Name;
Expand All @@ -36,6 +37,22 @@ struct MorphInfo {
}
};

struct JointLinkKey
{
int Angle;
int Value;
};

struct JointLinkInfo
{
QString Bone;
QString Axis;
QString Morph;
double Scalar;
double Alpha;
QList<JointLinkKey> Keys;
};

class DzUnrealMorphSelectionDialog : public DzBasicDialog {
Q_OBJECT
public:
Expand Down Expand Up @@ -67,6 +84,10 @@ class DzUnrealMorphSelectionDialog : public DzBasicDialog {
// Used to rename them to the friendly name in Unreal
QMap<QString, QString> GetMorphRenaming();

bool IsAutoJCMEnabled() { return autoJCMCheckBox->isChecked(); }

// Recursive function for finding all active JCM morphs for a node
QList<JointLinkInfo> GetActiveJointControlledMorphs(DzNode* Node = nullptr);

public slots:
void FilterChanged(const QString& filter);
Expand All @@ -80,6 +101,7 @@ public slots:
void HandleTorsoJCMMorphsButton();
void HandleARKitGenesis81MorphsButton();
void HandleFaceFXGenesis8Button();
void HandleAutoJCMCheckBoxChange(bool checked);

private:

Expand All @@ -89,6 +111,9 @@ public slots:
// Recursive function for finding all morphs for a node
QStringList GetAvailableMorphs(DzNode* Node);

//
QList<JointLinkInfo> GetJointControlledMorphInfo(DzProperty* property);

void UpdateMorphsTree();

// Returns the tree node for the morph name (with path)
Expand Down Expand Up @@ -141,4 +166,7 @@ public slots:

QTreeWidgetItem* fullBodyMorphTreeItem;
QTreeWidgetItem* charactersTreeItem;
QCheckBox* autoJCMCheckBox;

QSettings* settings;
};
Loading

0 comments on commit 536eef8

Please sign in to comment.