diff --git a/Source/Programs/MayaUnrealLiveLinkPlugin/BuildMayaUnrealLiveLinkPlugin.xml b/Source/Programs/MayaUnrealLiveLinkPlugin/BuildMayaUnrealLiveLinkPlugin.xml
index a426fd4..24f888f 100644
--- a/Source/Programs/MayaUnrealLiveLinkPlugin/BuildMayaUnrealLiveLinkPlugin.xml
+++ b/Source/Programs/MayaUnrealLiveLinkPlugin/BuildMayaUnrealLiveLinkPlugin.xml
@@ -14,11 +14,7 @@
-
-
-
-
-
+
diff --git a/Source/Programs/MayaUnrealLiveLinkPlugin/BuildMayaUnrealLiveLinkPluginDebug.Bat b/Source/Programs/MayaUnrealLiveLinkPlugin/BuildMayaUnrealLiveLinkPluginDebug.Bat
new file mode 100644
index 0000000..9dcc380
--- /dev/null
+++ b/Source/Programs/MayaUnrealLiveLinkPlugin/BuildMayaUnrealLiveLinkPluginDebug.Bat
@@ -0,0 +1,37 @@
+@REM MIT License
+
+@REM Copyright (c) 2022 Autodesk, Inc.
+
+@REM Permission is hereby granted, free of charge, to any person obtaining a copy
+@REM of this software and associated documentation files (the "Software"), to deal
+@REM in the Software without restriction, including without limitation the rights
+@REM to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+@REM copies of the Software, and to permit persons to whom the Software is
+@REM furnished to do so, subject to the following conditions:
+
+@REM The above copyright notice and this permission notice shall be included in all
+@REM copies or substantial portions of the Software.
+
+@REM THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+@REM IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+@REM FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+@REM AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+@REM LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+@REM OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+@REM SOFTWARE.
+
+@echo off
+
+@rem If a platform is given then we build for it or we build Win64
+if "%~2" == "" (
+ @echo Missing Maya OS
+ @echo Building for Win64
+ SET MAYA_PLATFORM=Win64
+) else (
+ SET MAYA_PLATFORM=%2
+)
+
+if exist "%~dp0Staging\" (
+ RMDIR "%~dp0Staging" /S /Q
+)
+"%~dp0..\..\..\..\..\Build\BatchFiles\RunUAT.bat" BuildGraph -Script=Engine/Restricted/NotForLicensees/Source/Programs/MayaUnrealLiveLinkPlugin/BuildMayaUnrealLiveLinkPlugin.xml -Target="Stage Maya Plugin Module" -set:MayaVersion=%1 -set:MayaPlatform=%MAYA_PLATFORM% -set:BuildTarget="Debug" -NoXGE
diff --git a/Source/Programs/MayaUnrealLiveLinkPlugin/MayaUnrealLiveLinkPlugin.cpp b/Source/Programs/MayaUnrealLiveLinkPlugin/MayaUnrealLiveLinkPlugin.cpp
index c6c9bf6..509c341 100644
--- a/Source/Programs/MayaUnrealLiveLinkPlugin/MayaUnrealLiveLinkPlugin.cpp
+++ b/Source/Programs/MayaUnrealLiveLinkPlugin/MayaUnrealLiveLinkPlugin.cpp
@@ -1425,6 +1425,57 @@ constexpr char LiveLinkPlayheadSyncCommand::EnableFlag[];
constexpr char LiveLinkPlayheadSyncCommand::EnableFlagLong[];
bool LiveLinkPlayheadSyncCommand::bPlayHeadSync = true;
+const MString LiveLinkObjectTransformSyncCommandName("LiveLinkObjectTransformSync");
+
+class LiveLinkObjectTransformSyncCommand : public MPxCommand
+{
+ static bool bObjectTransformSync;
+
+public:
+ static constexpr char EnableFlag[] = "en";
+ static constexpr char EnableFlagLong[] = "enable";
+
+ static void cleanup() {}
+ static void* creator() { return new LiveLinkObjectTransformSyncCommand(); }
+
+ static MSyntax CreateSyntax()
+ {
+ MStatus Status;
+ MSyntax Syntax;
+
+ Syntax.enableQuery(true);
+
+ Status = Syntax.addFlag(EnableFlag, EnableFlagLong, MSyntax::kBoolean);
+ CHECK_MSTATUS(Status);
+
+ return Syntax;
+ }
+ MStatus doIt(const MArgList& args) override
+ {
+ MStatus Status;
+ MArgDatabase ArgData(syntax(), args, &Status);
+ CHECK_MSTATUS_AND_RETURN_IT(Status);
+
+ const bool bIsObjectTransformSyncEnabled = ArgData.isFlagSet(EnableFlagLong, &Status);
+ if (ArgData.isQuery())
+ {
+ setResult(bObjectTransformSync);
+ }
+ else
+ {
+ ArgData.getFlagArgument(EnableFlagLong, 0, bObjectTransformSync);
+ setResult(true);
+ }
+
+ return MS::kSuccess;
+ }
+
+ static bool IsEnabled() { return bObjectTransformSync; }
+};
+constexpr char LiveLinkObjectTransformSyncCommand::EnableFlag[];
+constexpr char LiveLinkObjectTransformSyncCommand::EnableFlagLong[];
+bool LiveLinkObjectTransformSyncCommand::bObjectTransformSync = true;
+
const MString LiveLinkPauseAnimSyncCommandName("LiveLinkPauseAnimSync");
class LiveLinkPauseAnimSyncCommand : public MPxCommand
@@ -1520,18 +1571,20 @@ std::atomic SendUpdatedData {false};
// Helper method to send data to unreal when SendUpdatedData is set.
void StreamDataToUnreal()
-{
- // Stream data only when this flag is set.
- if (!SendUpdatedData)
- {
- return;
- }
+{
+ if (!LiveLinkObjectTransformSyncCommand::IsEnabled()) {
+ // Stream data only when this flag is set.
+ if (!SendUpdatedData)
+ {
+ return;
+ }
- // Do we need this?
- if (gTimeChangedReceived)
- {
- gTimeChangedReceived = false;
- return;
+ // Do we need this?
+ if (gTimeChangedReceived)
+ {
+ gTimeChangedReceived = false;
+ return;
+ }
}
auto& StreamManager = MayaLiveLinkStreamManager::TheOne();
@@ -2478,7 +2531,7 @@ void OnPlaybackRangeChanged(void* ClientData)
if (DetectIdleEvent.IsValid())
{
DetectIdleEvent->Stop();
- DetectIdleEvent.Release();
+ DetectIdleEvent.Reset();
}
// Start the worker thread that will wait for additional user input before rebuilding the subjects
@@ -2672,6 +2725,9 @@ MStatus initializePlugin(MObject MayaPluginObject)
MayaPlugin.registerCommand(LiveLinkPlayheadSyncCommandName,
LiveLinkPlayheadSyncCommand::creator,
LiveLinkPlayheadSyncCommand::CreateSyntax);
+ MayaPlugin.registerCommand(LiveLinkObjectTransformSyncCommandName,
+ LiveLinkObjectTransformSyncCommand::creator,
+ LiveLinkObjectTransformSyncCommand::CreateSyntax);
MayaPlugin.registerCommand(LiveLinkPauseAnimSyncCommandName, LiveLinkPauseAnimSyncCommand::creator,
LiveLinkPauseAnimSyncCommand::CreateSyntax);
@@ -2700,7 +2756,7 @@ MStatus initializePlugin(MObject MayaPluginObject)
*/
MStatus uninitializePlugin(MObject MayaPluginObject)
{
- DetectIdleEvent.Release();
+ DetectIdleEvent.Reset();
// Get the plugin API for the plugin object
MFnPlugin MayaPlugin(MayaPluginObject);
diff --git a/Source/Programs/MayaUnrealLiveLinkPlugin/MayaUnrealLiveLinkPluginUI.py.in b/Source/Programs/MayaUnrealLiveLinkPlugin/MayaUnrealLiveLinkPluginUI.py.in
index 67347a9..c831edc 100644
--- a/Source/Programs/MayaUnrealLiveLinkPlugin/MayaUnrealLiveLinkPluginUI.py.in
+++ b/Source/Programs/MayaUnrealLiveLinkPlugin/MayaUnrealLiveLinkPluginUI.py.in
@@ -709,6 +709,21 @@ class MayaUnrealLiveLinkModel():
except:
pass
+ @staticmethod
+ def isObjectTransformSyncEnabled():
+ try:
+ return cmds.LiveLinkObjectTransformSync(q=True, enable=True)
+ except:
+ return True
+
+
+ @staticmethod
+ def enableObjectTransformSync(state):
+ try:
+ cmds.LiveLinkObjectTransformSync(enable=state)
+ except:
+ pass
+
@staticmethod
def pauseAnimSeqSync(state):
try:
diff --git a/Source/Programs/MayaUnrealLiveLinkPlugin/Subjects/MLiveLinkPropSubject.cpp b/Source/Programs/MayaUnrealLiveLinkPlugin/Subjects/MLiveLinkPropSubject.cpp
index 734b141..eb1bb3e 100644
--- a/Source/Programs/MayaUnrealLiveLinkPlugin/Subjects/MLiveLinkPropSubject.cpp
+++ b/Source/Programs/MayaUnrealLiveLinkPlugin/Subjects/MLiveLinkPropSubject.cpp
@@ -22,7 +22,7 @@
#include "MLiveLinkPropSubject.h"
#include "../MayaLiveLinkStreamManager.h"
-#include "MayaUnrealLiveLinkPlugin/MayaUnrealLiveLinkUtils.h"
+#include "../MayaUnrealLiveLinkUtils.h"
#include "LiveLinkTypes.h"
#include "Roles/MayaLiveLinkTimelineTypes.h"
diff --git a/Source/Programs/MayaUnrealLiveLinkPlugin/UnrealInitializer/UnrealInitializer.cpp b/Source/Programs/MayaUnrealLiveLinkPlugin/UnrealInitializer/UnrealInitializer.cpp
index c3f67f3..fe7a7bf 100644
--- a/Source/Programs/MayaUnrealLiveLinkPlugin/UnrealInitializer/UnrealInitializer.cpp
+++ b/Source/Programs/MayaUnrealLiveLinkPlugin/UnrealInitializer/UnrealInitializer.cpp
@@ -79,6 +79,10 @@ void UnrealInitializer::InitializeUnreal()
// Load UdpMessaging module needed by message bus.
FModuleManager::Get().LoadModule(TEXT("UdpMessaging"));
+ IPluginManager::Get().LoadModulesForEnabledPlugins(ELoadingPhase::PreDefault);
+ IPluginManager::Get().LoadModulesForEnabledPlugins(ELoadingPhase::Default);
+ IPluginManager::Get().LoadModulesForEnabledPlugins(ELoadingPhase::PostDefault);
+
InitializedOnce = true;
}
diff --git a/Source/Programs/MayaUnrealLiveLinkPlugin/scripts/UnrealLiveLinkController.py b/Source/Programs/MayaUnrealLiveLinkPlugin/scripts/UnrealLiveLinkController.py
index bb705c1..a8eb1ed 100644
--- a/Source/Programs/MayaUnrealLiveLinkPlugin/scripts/UnrealLiveLinkController.py
+++ b/Source/Programs/MayaUnrealLiveLinkPlugin/scripts/UnrealLiveLinkController.py
@@ -222,6 +222,15 @@ def enablePlayheadSync(self, state):
if self._Model:
self._Model.enablePlayheadSync(state)
+ def isObjectTransformSyncEnabled(self):
+ if self._Model:
+ self._Model.isObjectTransformSyncEnabled(state)
+ return False
+
+ def enableObjectTransformSync(self, state):
+ if self._Model:
+ self._Model.enableObjectTransformSync(state)
+
def pauseAnimSeqSync(self, state):
if self._Model:
self._Model.pauseAnimSeqSync(state)
diff --git a/Source/Programs/MayaUnrealLiveLinkPlugin/scripts/UnrealLiveLinkWindow.py b/Source/Programs/MayaUnrealLiveLinkPlugin/scripts/UnrealLiveLinkWindow.py
index 3fb6084..16748b4 100644
--- a/Source/Programs/MayaUnrealLiveLinkPlugin/scripts/UnrealLiveLinkWindow.py
+++ b/Source/Programs/MayaUnrealLiveLinkPlugin/scripts/UnrealLiveLinkWindow.py
@@ -147,9 +147,18 @@ def initUI(self):
self.syncTimeAction.setCheckable(True)
self.syncTimeAction.setChecked(False)
self.syncTimeAction.triggered.connect(self._enablePlayheadSync)
+
+ # Sync Object Transform
+ self.syncObjectTransformAction = QAction('Sync Object Transform', self)
+ self.syncObjectTransformAction.setToolTip('Enable to synchronize Maya object transform with Unreal in real time')
+ self.syncObjectTransformAction.setCheckable(True)
+ self.syncObjectTransformAction.setChecked(True)
+ self.syncObjectTransformAction.triggered.connect(self._enableObjectTransformSync)
+
# Add actions to Option Menu
self.optionsMenu.addAction(self.settingsAction)
self.optionsMenu.addAction(self.syncTimeAction)
+ self.optionsMenu.addAction(self.syncObjectTransformAction)
# Help Menu
helpMenu = menuBar.addMenu('Help')
@@ -317,6 +326,7 @@ def refreshUI(self):
if self.table:
self.table._refreshUI()
self.syncTimeAction.setChecked(self.Controller.isPlayheadSyncEnabled())
+ self.syncObjectTransformAction.setChecked(self.Controller.isObjectTransformSyncEnabled())
def showEvent(self, event):
unrealVersion = self.Controller.getLoadedUnrealVersion()
@@ -383,6 +393,9 @@ def enableControls(self, enable):
def _enablePlayheadSync(self, state):
self.Controller.enablePlayheadSync(self.syncTimeAction.isChecked())
+ def _enableObjectTransformSync(self, state):
+ self.Controller.enableObjectTransformSync(self.syncObjectTransformAction.isChecked())
+
def _pauseAnimSeqSync(self, state):
self.Controller.pauseAnimSeqSync(self._pauseAnimSyncButtonPauseState)
if self._pauseAnimSyncButtonPauseState: