diff -pruN --exclude build ./demo_clean/CMakeLists.txt ./demo_dev/CMakeLists.txt
---- ./demo_clean/CMakeLists.txt 2020-10-02 02:01:04.825787688 +0100
-+++ ./demo_dev/CMakeLists.txt 2020-10-01 23:29:15.530233484 +0100
+--- ./demo_clean/CMakeLists.txt 2022-09-14 12:08:43.000000000 +0100
++++ ./demo_dev/CMakeLists.txt 2022-10-11 20:33:48.181071509 +0100
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.16)
# Set app name.
set(APP_NAME Demo)
# Set directory paths.
-set(SDK_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../../..)
-+set(SDK_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../CubismSdkForNative-4-r.1)
++set(SDK_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../CubismSdkForNative-4-r.5.1)
set(CORE_PATH ${SDK_ROOT_PATH}/Core)
set(FRAMEWORK_PATH ${SDK_ROOT_PATH}/Framework)
set(THIRD_PARTY_PATH ${SDK_ROOT_PATH}/Samples/OpenGL/thirdParty)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
-@@ -64,6 +64,9 @@ target_link_libraries(Framework Live2DCu
+@@ -64,6 +64,11 @@ target_link_libraries(Framework Live2DCu
# Find opengl libraries.
find_package(OpenGL REQUIRED)
+# Add MouseTrackerForCubism
++find_package(PkgConfig)
++pkg_check_modules(GTKMM gtkmm-3.0)
+add_subdirectory(../.. MouseTrackerForCubism_build)
+
# Make executable app.
add_executable(${APP_NAME})
# Add source files.
-@@ -73,9 +76,11 @@ target_link_libraries(${APP_NAME}
+@@ -73,9 +78,20 @@ target_link_libraries(${APP_NAME}
Framework
glfw
${OPENGL_LIBRARIES}
)
# Specify include directories.
-target_include_directories(${APP_NAME} PRIVATE ${STB_PATH})
-+target_include_directories(${APP_NAME} PRIVATE ${STB_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/../../include)
++target_include_directories(${APP_NAME} PRIVATE ${STB_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/../../include ${GTKMM_INCLUDE_DIRS})
++
++# Copy GUI to build directory
++add_custom_command(
++ TARGET ${APP_NAME}
++ POST_BUILD
++ COMMAND
++ ${CMAKE_COMMAND} -E
++ copy ${CMAKE_CURRENT_SOURCE_DIR}/../../src/gui.glade $<TARGET_FILE_DIR:${APP_NAME}>/gui.glade
++)
# Copy resource directory to build directory.
add_custom_command(
diff -pruN --exclude build ./demo_clean/scripts/make_gcc ./demo_dev/scripts/make_gcc
---- ./demo_clean/scripts/make_gcc 2020-10-02 02:01:04.825787688 +0100
-+++ ./demo_dev/scripts/make_gcc 2020-10-01 23:43:42.213875065 +0100
-@@ -10,4 +10,4 @@ BUILD_PATH=$SCRIPT_PATH/../build/make_gc
+--- ./demo_clean/scripts/make_gcc 2022-09-14 12:08:43.000000000 +0100
++++ ./demo_dev/scripts/make_gcc 2021-04-28 12:18:50.948333190 +0100
+@@ -5,41 +5,9 @@ set -ue
+ SCRIPT_PATH=$(cd $(dirname $0) && pwd)
+ CMAKE_PATH=$SCRIPT_PATH/..
+ BUILD_PATH=$SCRIPT_PATH/../build/make_gcc
+-MINIMUM_DEMO="OFF"
+-DATA=""
+-
+-if [ "$#" -ne 0 ]; then
+- DATA="$1"
+-fi
+-
+-while :
+-do
+-
+- if [ -z "$DATA" ]; then
+- echo "Choose which format you would like to create the demo."
+- echo "Full version : 1"
+- echo "Minimum version : 2"
+- read -p "Your Choice : " DATA
+- fi
+-
+- case "$DATA" in
+- "1" )
+- echo "Making Full Demo"
+- MINIMUM_DEMO="OFF"
+- break ;;
+- "2" )
+- echo "Making Minimum Demo"
+- MINIMUM_DEMO="ON"
+- break ;;
+- * )
+- echo "You need to enter a valid number."
+- DATA="" ;;
+- esac
+-done
+
+ # Run CMake.
cmake -S "$CMAKE_PATH" \
-B "$BUILD_PATH" \
- -D CMAKE_BUILD_TYPE=Release
+- -D CMAKE_BUILD_TYPE=Release \
+- -D CSM_MINIMUM_DEMO=$MINIMUM_DEMO
-cd "$BUILD_PATH" && make
++ -D CMAKE_BUILD_TYPE=Release
+cd "$BUILD_PATH" && make -j4
diff -pruN --exclude build ./demo_clean/src/CMakeLists.txt ./demo_dev/src/CMakeLists.txt
---- ./demo_clean/src/CMakeLists.txt 2020-10-02 02:01:04.829787750 +0100
-+++ ./demo_dev/src/CMakeLists.txt 2020-10-01 22:47:24.842846271 +0100
-@@ -19,6 +19,4 @@ target_sources(${APP_NAME}
- ${CMAKE_CURRENT_SOURCE_DIR}/LAppView.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/LAppView.hpp
- ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
+--- ./demo_clean/src/CMakeLists.txt 2022-09-14 12:08:43.000000000 +0100
++++ ./demo_dev/src/CMakeLists.txt 2021-04-28 12:21:56.795134807 +0100
+@@ -1,49 +1,22 @@
+-if (CSM_MINIMUM_DEMO)
+- target_sources(${APP_NAME}
++target_sources(${APP_NAME}
+ PRIVATE
+ ${CMAKE_CURRENT_SOURCE_DIR}/LAppAllocator.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/LAppAllocator.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/LAppDefine.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/LAppDefine.hpp
++ ${CMAKE_CURRENT_SOURCE_DIR}/LAppDelegate.cpp
++ ${CMAKE_CURRENT_SOURCE_DIR}/LAppDelegate.hpp
++ ${CMAKE_CURRENT_SOURCE_DIR}/LAppLive2DManager.cpp
++ ${CMAKE_CURRENT_SOURCE_DIR}/LAppLive2DManager.hpp
++ ${CMAKE_CURRENT_SOURCE_DIR}/LAppModel.cpp
++ ${CMAKE_CURRENT_SOURCE_DIR}/LAppModel.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/LAppPal.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/LAppPal.hpp
++ ${CMAKE_CURRENT_SOURCE_DIR}/LAppSprite.cpp
++ ${CMAKE_CURRENT_SOURCE_DIR}/LAppSprite.hpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/LAppTextureManager.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/LAppTextureManager.hpp
+- ${CMAKE_CURRENT_SOURCE_DIR}/mainMinimum.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/TouchManager.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/TouchManager.hpp
- )
+- ${CMAKE_CURRENT_SOURCE_DIR}/CubismUserModelExtend.cpp
+- ${CMAKE_CURRENT_SOURCE_DIR}/CubismUserModelExtend.hpp
+- ${CMAKE_CURRENT_SOURCE_DIR}/CubismSampleViewMatrix.cpp
+- ${CMAKE_CURRENT_SOURCE_DIR}/CubismSampleViewMatrix.hpp
+- ${CMAKE_CURRENT_SOURCE_DIR}/MouseActionManager.cpp
+- ${CMAKE_CURRENT_SOURCE_DIR}/MouseActionManager.hpp
+- )
+-else ()
+- target_sources(${APP_NAME}
+- PRIVATE
+- ${CMAKE_CURRENT_SOURCE_DIR}/LAppAllocator.cpp
+- ${CMAKE_CURRENT_SOURCE_DIR}/LAppAllocator.hpp
+- ${CMAKE_CURRENT_SOURCE_DIR}/LAppDefine.cpp
+- ${CMAKE_CURRENT_SOURCE_DIR}/LAppDefine.hpp
+- ${CMAKE_CURRENT_SOURCE_DIR}/LAppDelegate.cpp
+- ${CMAKE_CURRENT_SOURCE_DIR}/LAppDelegate.hpp
+- ${CMAKE_CURRENT_SOURCE_DIR}/LAppWavFileHandler.cpp
+- ${CMAKE_CURRENT_SOURCE_DIR}/LAppWavFileHandler.hpp
+- ${CMAKE_CURRENT_SOURCE_DIR}/LAppLive2DManager.cpp
+- ${CMAKE_CURRENT_SOURCE_DIR}/LAppLive2DManager.hpp
+- ${CMAKE_CURRENT_SOURCE_DIR}/LAppModel.cpp
+- ${CMAKE_CURRENT_SOURCE_DIR}/LAppModel.hpp
+- ${CMAKE_CURRENT_SOURCE_DIR}/LAppPal.cpp
+- ${CMAKE_CURRENT_SOURCE_DIR}/LAppPal.hpp
+- ${CMAKE_CURRENT_SOURCE_DIR}/LAppSprite.cpp
+- ${CMAKE_CURRENT_SOURCE_DIR}/LAppSprite.hpp
+- ${CMAKE_CURRENT_SOURCE_DIR}/LAppTextureManager.cpp
+- ${CMAKE_CURRENT_SOURCE_DIR}/LAppTextureManager.hpp
+- ${CMAKE_CURRENT_SOURCE_DIR}/LAppView.cpp
+- ${CMAKE_CURRENT_SOURCE_DIR}/LAppView.hpp
+- ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
+- ${CMAKE_CURRENT_SOURCE_DIR}/TouchManager.cpp
+- ${CMAKE_CURRENT_SOURCE_DIR}/TouchManager.hpp
+- )
+-endif ()
++ ${CMAKE_CURRENT_SOURCE_DIR}/LAppView.cpp
++ ${CMAKE_CURRENT_SOURCE_DIR}/LAppView.hpp
++ ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
++)
+diff -pruN --exclude build ./demo_clean/src/LAppDefine.cpp ./demo_dev/src/LAppDefine.cpp
+--- ./demo_clean/src/LAppDefine.cpp 2022-09-14 12:08:43.000000000 +0100
++++ ./demo_dev/src/LAppDefine.cpp 2022-10-11 20:35:25.046676464 +0100
+@@ -65,11 +65,11 @@ namespace LAppDefine {
+ const csmInt32 PriorityForce = 3;
+
+ // デバッグ用ログの表示オプション
+- const csmBool DebugLogEnable = true;
++ const csmBool DebugLogEnable = false;
+ const csmBool DebugTouchLogEnable = false;
+
+ // Frameworkから出力するログのレベル設定
+- const CubismFramework::Option::LogLevel CubismLoggingLevel = CubismFramework::Option::LogLevel_Verbose;
++ const CubismFramework::Option::LogLevel CubismLoggingLevel = CubismFramework::Option::LogLevel_Warning;
+
+ // デフォルトのレンダーターゲットサイズ
+ const csmInt32 RenderTargetWidth = 1900;
diff -pruN --exclude build ./demo_clean/src/LAppDelegate.cpp ./demo_dev/src/LAppDelegate.cpp
---- ./demo_clean/src/LAppDelegate.cpp 2020-10-02 02:01:04.829787750 +0100
-+++ ./demo_dev/src/LAppDelegate.cpp 2020-10-01 22:47:24.698848890 +0100
+--- ./demo_clean/src/LAppDelegate.cpp 2022-09-14 12:08:43.000000000 +0100
++++ ./demo_dev/src/LAppDelegate.cpp 2021-04-28 12:18:50.948333190 +0100
@@ -45,7 +45,8 @@ void LAppDelegate::ReleaseInstance()
s_instance = NULL;
}
if (_window == NULL)
{
if (DebugLogEnable)
-@@ -95,10 +102,6 @@ bool LAppDelegate::Initialize()
+@@ -95,16 +102,11 @@ bool LAppDelegate::Initialize()
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// ウィンドウサイズ記憶
int width, height;
glfwGetWindowSize(LAppDelegate::GetInstance()->GetWindow(), &width, &height);
-@@ -111,8 +114,6 @@ bool LAppDelegate::Initialize()
+ _windowWidth = width;
+ _windowHeight = height;
+- glViewport(0, 0, _windowWidth, _windowHeight);
+
+ //AppViewの初期化
+ _view->Initialize();
+@@ -112,8 +114,6 @@ bool LAppDelegate::Initialize()
// Cubism3の初期化
InitializeCubism();
//load model
LAppLive2DManager::GetInstance();
-@@ -214,49 +215,6 @@ void LAppDelegate::InitializeCubism()
+@@ -155,7 +155,6 @@ void LAppDelegate::Run()
+ _windowWidth = width;
+ _windowHeight = height;
+ }
+- glViewport(0, 0, _windowWidth, _windowHeight);
+
+ // 時間更新
+ LAppPal::UpdateTime();
+@@ -216,49 +215,6 @@ void LAppDelegate::InitializeCubism()
LAppPal::UpdateTime();
}
GLuint LAppDelegate::CreateShader()
{
//バーテックスシェーダのコンパイル
-@@ -299,29 +257,9 @@ GLuint LAppDelegate::CreateShader()
+@@ -301,29 +257,9 @@ GLuint LAppDelegate::CreateShader()
return programId;
}
Csm::csmVector<string> LAppDelegate::Split(const std::string& baseString, char delimiter)
diff -pruN --exclude build ./demo_clean/src/LAppDelegate.hpp ./demo_dev/src/LAppDelegate.hpp
---- ./demo_clean/src/LAppDelegate.hpp 2020-10-02 02:01:04.829787750 +0100
-+++ ./demo_dev/src/LAppDelegate.hpp 2020-10-01 22:47:24.842846271 +0100
+--- ./demo_clean/src/LAppDelegate.hpp 2022-09-14 12:08:43.000000000 +0100
++++ ./demo_dev/src/LAppDelegate.hpp 2021-04-28 12:18:50.948333190 +0100
@@ -40,7 +40,8 @@ public:
/**
* @brief APPに必要なものを初期化する。
-
-};
diff -pruN --exclude build ./demo_clean/src/LAppLive2DManager.cpp ./demo_dev/src/LAppLive2DManager.cpp
---- ./demo_clean/src/LAppLive2DManager.cpp 2020-10-02 02:01:04.829787750 +0100
-+++ ./demo_dev/src/LAppLive2DManager.cpp 2020-10-02 02:00:49.961556700 +0100
-@@ -52,9 +52,10 @@ void LAppLive2DManager::ReleaseInstance(
+--- ./demo_clean/src/LAppLive2DManager.cpp 2022-09-14 12:08:43.000000000 +0100
++++ ./demo_dev/src/LAppLive2DManager.cpp 2022-10-11 20:35:42.982973401 +0100
+@@ -52,11 +52,11 @@ void LAppLive2DManager::ReleaseInstance(
LAppLive2DManager::LAppLive2DManager()
: _viewMatrix(NULL)
+ , _translateX(0.0f)
+ , _translateY(0.0f)
{
+ _viewMatrix = new CubismMatrix44();
+-
- ChangeScene(_sceneIndex);
}
LAppLive2DManager::~LAppLive2DManager()
-@@ -98,26 +99,6 @@ void LAppLive2DManager::OnTap(csmFloat32
+@@ -100,26 +100,6 @@ void LAppLive2DManager::OnTap(csmFloat32
{
LAppPal::PrintLog("[APP]tap point: {x:%.2f y:%.2f}", x, y);
}
}
void LAppLive2DManager::OnUpdate() const
-@@ -125,7 +106,9 @@ void LAppLive2DManager::OnUpdate() const
- CubismMatrix44 projection;
+@@ -127,10 +107,10 @@ void LAppLive2DManager::OnUpdate() const
int width, height;
glfwGetWindowSize(LAppDelegate::GetInstance()->GetWindow(), &width, &height);
-- projection.Scale(1.0f, static_cast<float>(width) / static_cast<float>(height));
-+ projection.Scale(_projScaleFactor,
-+ _projScaleFactor * static_cast<float>(width) / static_cast<float>(height));
-+ projection.Translate(_translateX, _translateY);
- if (_viewMatrix != NULL)
++ CubismMatrix44 projection;
+ csmUint32 modelCount = _models.GetSize();
+ for (csmUint32 i = 0; i < modelCount; ++i)
{
-@@ -148,26 +131,10 @@ void LAppLive2DManager::OnUpdate() const
+- CubismMatrix44 projection;
+ LAppModel* model = GetModel(i);
+
+ if (model->GetModel() == NULL)
+@@ -143,12 +123,15 @@ void LAppLive2DManager::OnUpdate() const
+ {
+ // 横に長いモデルを縦長ウィンドウに表示する際モデルの横サイズでscaleを算出する
+ model->GetModelMatrix()->SetWidth(2.0f);
+- projection.Scale(1.0f, static_cast<float>(width) / static_cast<float>(height));
++ projection.Scale(_projScaleFactor,
++ _projScaleFactor * static_cast<float>(width) / static_cast<float>(height));
+ }
+ else
+ {
+- projection.Scale(static_cast<float>(height) / static_cast<float>(width), 1.0f);
++ projection.Scale(_projScaleFactor * static_cast<float>(height) / static_cast<float>(width),
++ _projScaleFactor);
+ }
++ projection.Translate(_translateX, _translateY);
+
+ // 必要があればここで乗算
+ if (_viewMatrix != NULL)
+@@ -165,30 +148,14 @@ void LAppLive2DManager::OnUpdate() const
}
}
-}
-
-void LAppLive2DManager::ChangeScene(Csm::csmInt32 index)
-+void LAppLive2DManager::SetModel(std::string modelName)
++void LAppLive2DManager::SetModel(std::string modelName, bool useOldParamId)
{
- _sceneIndex = index;
- if (DebugLogEnable)
modelJsonName += ".model3.json";
ReleaseAllModel();
-@@ -215,3 +182,20 @@ csmUint32 LAppLive2DManager::GetModelNum
- {
- return _models.GetSize();
+- _models.PushBack(new LAppModel());
++ _models.PushBack(new LAppModel(useOldParamId));
+ _models[0]->LoadAssets(modelPath.c_str(), modelJsonName.c_str());
+
+ /*
+@@ -210,7 +177,7 @@ void LAppLive2DManager::ChangeScene(Csm:
+
+ #if defined(USE_RENDER_TARGET) || defined(USE_MODEL_RENDER_TARGET)
+ // モデル個別にαを付けるサンプルとして、もう1体モデルを作成し、少し位置をずらす
+- _models.PushBack(new LAppModel());
++ _models.PushBack(new LAppModel(useOldParamId));
+ _models[1]->LoadAssets(modelPath.c_str(), modelJsonName.c_str());
+ _models[1]->GetModelMatrix()->TranslateX(0.2f);
+ #endif
+@@ -239,3 +206,20 @@ void LAppLive2DManager::SetViewMatrix(Cu
+ _viewMatrix->GetArray()[i] = m->GetArray()[i];
+ }
}
+
+void LAppLive2DManager::SetTracker(MouseCursorTracker *tracker)
+ _translateY = translateY;
+}
diff -pruN --exclude build ./demo_clean/src/LAppLive2DManager.hpp ./demo_dev/src/LAppLive2DManager.hpp
---- ./demo_clean/src/LAppLive2DManager.hpp 2020-10-02 02:01:04.825787688 +0100
-+++ ./demo_dev/src/LAppLive2DManager.hpp 2020-10-01 23:36:24.583055381 +0100
+--- ./demo_clean/src/LAppLive2DManager.hpp 2022-09-14 12:08:43.000000000 +0100
++++ ./demo_dev/src/LAppLive2DManager.hpp 2021-04-28 12:18:50.948333190 +0100
@@ -6,12 +6,15 @@
*/
#pragma once
/**
* @brief サンプルアプリケーションにおいてCubismModelを管理するクラス<br>
* モデル生成と破棄、タップイベントの処理、モデル切り替えを行う。
-@@ -72,16 +75,12 @@ public:
+@@ -72,16 +75,14 @@ public:
void OnUpdate() const;
/**
+ *
+ * @param[in] modelName : Name of model, should be the same for both
+ * the directory and the model3.json file
++ * @param[in] useOldParamId : If true, translate new (Cubism 3+)
++ * parameter IDs to old (Cubism 2.1) ones
+ */
-+ void SetModel(std::string modelName);
++ void SetModel(std::string modelName, bool useOldParamId);
/**
* @brief モデル個数を得る
-@@ -89,6 +88,24 @@ public:
+@@ -94,6 +95,24 @@ public:
*/
- Csm::csmUint32 GetModelNum() const;
+ void SetViewMatrix(Live2D::Cubism::Framework::CubismMatrix44* m);
+ /**
+ * @brief Set the pointer to the MouseCursorTracker instance
private:
/**
* @brief コンストラクタ
-@@ -102,5 +119,8 @@ private:
+@@ -107,5 +126,8 @@ private:
Csm::CubismMatrix44* _viewMatrix; ///< モデル描画に用いるView行列
Csm::csmVector<LAppModel*> _models; ///< モデルインスタンスのコンテナ
+ float _translateY;
};
diff -pruN --exclude build ./demo_clean/src/LAppModel.cpp ./demo_dev/src/LAppModel.cpp
---- ./demo_clean/src/LAppModel.cpp 2020-10-02 02:01:04.825787688 +0100
-+++ ./demo_dev/src/LAppModel.cpp 2020-10-01 23:34:43.482626010 +0100
-@@ -21,6 +21,8 @@
+--- ./demo_clean/src/LAppModel.cpp 2022-09-14 12:08:43.000000000 +0100
++++ ./demo_dev/src/LAppModel.cpp 2021-04-28 12:26:56.699586813 +0100
+@@ -21,6 +21,10 @@
#include "LAppTextureManager.hpp"
#include "LAppDelegate.hpp"
+#include "mouse_cursor_tracker.h"
+
++#include <iostream>
++
using namespace Live2D::Cubism::Framework;
using namespace Live2D::Cubism::Framework::DefaultParameterId;
using namespace LAppDefine;
-@@ -49,6 +51,7 @@ LAppModel::LAppModel()
+@@ -45,22 +49,24 @@ namespace {
+ }
+ }
+
+-LAppModel::LAppModel()
++LAppModel::LAppModel(bool useOldParamId)
: CubismUserModel()
, _modelSetting(NULL)
, _userTimeSeconds(0.0f)
+ , _tracker(nullptr)
++ , _useOldParamId(useOldParamId)
{
if (DebugLogEnable)
{
-@@ -128,30 +131,6 @@ void LAppModel::SetupModel(ICubismModelS
- DeleteBuffer(buffer, path.GetRawString());
+ _debugMode = true;
}
-- //Expression
-- if (_modelSetting->GetExpressionCount() > 0)
+- _idParamAngleX = CubismFramework::GetIdManager()->GetId(ParamAngleX);
+- _idParamAngleY = CubismFramework::GetIdManager()->GetId(ParamAngleY);
+- _idParamAngleZ = CubismFramework::GetIdManager()->GetId(ParamAngleZ);
+- _idParamBodyAngleX = CubismFramework::GetIdManager()->GetId(ParamBodyAngleX);
+- _idParamEyeBallX = CubismFramework::GetIdManager()->GetId(ParamEyeBallX);
+- _idParamEyeBallY = CubismFramework::GetIdManager()->GetId(ParamEyeBallY);
++ _idParamAngleX = CubismFramework::GetIdManager()->GetId(_(ParamAngleX));
++ _idParamAngleY = CubismFramework::GetIdManager()->GetId(_(ParamAngleY));
++ _idParamAngleZ = CubismFramework::GetIdManager()->GetId(_(ParamAngleZ));
++ _idParamBodyAngleX = CubismFramework::GetIdManager()->GetId(_(ParamBodyAngleX));
++ _idParamEyeBallX = CubismFramework::GetIdManager()->GetId(_(ParamEyeBallX));
++ _idParamEyeBallY = CubismFramework::GetIdManager()->GetId(_(ParamEyeBallY));
+ }
+
+ LAppModel::~LAppModel()
+@@ -96,12 +102,6 @@ void LAppModel::LoadAssets(const csmChar
+
+ SetupModel(setting);
+
+- if (_model == NULL)
- {
-- const csmInt32 count = _modelSetting->GetExpressionCount();
-- for (csmInt32 i = 0; i < count; i++)
-- {
-- csmString name = _modelSetting->GetExpressionName(i);
-- csmString path = _modelSetting->GetExpressionFileName(i);
-- path = _modelHomeDir + path;
--
-- buffer = CreateBuffer(path.GetRawString(), &size);
-- ACubismMotion* motion = LoadExpression(buffer, size, name.GetRawString());
--
-- if (_expressions[name] != NULL)
-- {
-- ACubismMotion::Delete(_expressions[name]);
-- _expressions[name] = NULL;
-- }
-- _expressions[name] = motion;
+- LAppPal::PrintLog("Failed to LoadAssets().");
+- return;
+- }
-
-- DeleteBuffer(buffer, path.GetRawString());
-- }
+ CreateRenderer();
+
+ SetupTextures();
+@@ -196,7 +196,7 @@ void LAppModel::SetupModel(ICubismModelS
+ breathParameters.PushBack(CubismBreath::BreathParameterData(_idParamAngleY, 0.0f, 8.0f, 3.5345f, 0.5f));
+ breathParameters.PushBack(CubismBreath::BreathParameterData(_idParamAngleZ, 0.0f, 10.0f, 5.5345f, 0.5f));
+ breathParameters.PushBack(CubismBreath::BreathParameterData(_idParamBodyAngleX, 0.0f, 4.0f, 15.5345f, 0.5f));
+- breathParameters.PushBack(CubismBreath::BreathParameterData(CubismFramework::GetIdManager()->GetId(ParamBreath), 0.5f, 0.5f, 3.2345f, 0.5f));
++ breathParameters.PushBack(CubismBreath::BreathParameterData(CubismFramework::GetIdManager()->GetId(_(ParamBreath)), 0.5f, 0.5f, 3.2345f, 0.5f));
+
+ _breath->SetParameters(breathParameters);
+ }
+@@ -229,12 +229,6 @@ void LAppModel::SetupModel(ICubismModelS
+ }
+ }
+
+- if (_modelSetting == NULL || _modelMatrix == NULL)
+- {
+- LAppPal::PrintLog("Failed to SetupModel().");
+- return;
- }
-
- //Physics
- if (strcmp(_modelSetting->GetPhysicsFileName(), "") != 0)
- {
-@@ -335,59 +314,72 @@ void LAppModel::Update()
+ //Layout
+ csmMap<csmString, csmFloat32> layout;
+ _modelSetting->GetLayoutMap(layout);
+@@ -347,83 +341,118 @@ void LAppModel::Update()
const csmFloat32 deltaTimeSeconds = LAppPal::GetDeltaTime();
_userTimeSeconds += deltaTimeSeconds;
- if (!motionUpdated)
- {
- if (_eyeBlink != NULL)
-+ // NOTE: Apparently, this LoadParameters/SaveParameters pair
-+ // is needed for auto breath to work.
+ _model->LoadParameters(); // 前回セーブされた状態をロード
-+ if (_motionManager->IsFinished() && params.randomMotion)
++
++ int paramsMotionPriority = static_cast<int>(params.motionPriority);
++
++ if (paramsMotionPriority != PriorityNone)
{
- // メインモーションの更新がないとき
- _eyeBlink->UpdateParameters(_model, deltaTimeSeconds); // 目パチ
++ StartMotion(params.motionGroup.c_str(), params.motionNumber,
++ paramsMotionPriority);
++ }
++ else if (params.randomIdleMotion && _motionManager->IsFinished())
++ {
+ // モーションの再生がない場合、待機モーションの中からランダムで再生する
+ StartRandomMotion(MotionGroupIdle, PriorityIdle);
}
- }
-+ else
-+ {
-+ _motionManager->UpdateMotion(_model, deltaTimeSeconds); // モーションを更新
-+ }
-+ _model->SaveParameters(); // 状態を保存
- if (_expressionManager != NULL)
- {
- _expressionManager->UpdateMotion(_model, deltaTimeSeconds); // 表情でパラメータ更新(相対変化)
- }
++ // FIXME pose does not return to normal after motion
++ // if we don't have randomIdleMotion set
++ else
++ {
++ _motionManager->UpdateMotion(_model, deltaTimeSeconds); // モーションを更新
++ }
++ _model->SaveParameters(); // 状態を保存
- //ドラッグによる変化
- //ドラッグによる顔の向きの調整
- _model->AddParameterValue(_idParamAngleX, _dragX * 30); // -30から30の値を加える
- _model->AddParameterValue(_idParamAngleY, _dragY * 30);
- _model->AddParameterValue(_idParamAngleZ, _dragX * _dragY * -30);
-+ if (params.autoBlink && _eyeBlink)
++ if (params.expression != "")
+ {
-+ _eyeBlink->UpdateParameters(_model, deltaTimeSeconds);
++ SetExpression(params.expression.c_str());
+ }
-+ else
++ if (_expressionManager != NULL)
+ {
-+ _model->SetParameterValue(idMan->GetId("ParamEyeLOpen"),
-+ params.leftEyeOpenness);
-+ _model->SetParameterValue(idMan->GetId("ParamEyeROpen"),
-+ params.rightEyeOpenness);
++ _expressionManager->UpdateMotion(_model, deltaTimeSeconds); // 表情でパラメータ更新(相対変化)
+ }
- //ドラッグによる体の向きの調整
- _model->AddParameterValue(_idParamBodyAngleX, _dragX * 10); // -10から10の値を加える
-+ _model->SetParameterValue(idMan->GetId("ParamMouthForm"),
-+ params.mouthForm);
++ bool autoBlink = params.autoBlink && _eyeBlink;
++ auto eyeLOpenIt = params.live2d.find("ParamEyeLOpen");
++ auto eyeROpenIt = params.live2d.find("ParamEyeROpen");
- //ドラッグによる目の向きの調整
- _model->AddParameterValue(_idParamEyeBallX, _dragX); // -1から1の値を加える
- _model->AddParameterValue(_idParamEyeBallY, _dragY);
-+ if (params.useLipSync && _lipSync)
++ if (autoBlink)
+ {
-+ csmFloat32 value = params.lipSyncParam; // 0 to 1
++ // Handle blink first
++ _eyeBlink->UpdateParameters(_model, deltaTimeSeconds);
++ }
- // 呼吸など
- if (_breath != NULL)
- {
- _breath->UpdateParameters(_model, deltaTimeSeconds);
+- }
++ if (eyeLOpenIt != params.live2d.end())
++ {
++ // If value specified, override blinking
++ _model->SetParameterValue(idMan->GetId(_("ParamEyeLOpen")),
++ eyeLOpenIt->second);
++ }
++ else if (!autoBlink)
++ {
++ // If no value specified and no auto blink, set to 1
++ _model->SetParameterValue(idMan->GetId(_("ParamEyeLOpen")), 1);
+
+- // 物理演算の設定
+- if (_physics != NULL)
+- {
+- _physics->Evaluate(_model, deltaTimeSeconds);
+- }
++ }
+
+- // リップシンクの設定
+- if (_lipSync)
+- {
+- // リアルタイムでリップシンクを行う場合、システムから音量を取得して0〜1の範囲で値を入力します。
+- csmFloat32 value = 0.0f;
++ if (eyeROpenIt != params.live2d.end())
++ {
++ _model->SetParameterValue(idMan->GetId(_("ParamEyeROpen")),
++ eyeROpenIt->second);
++ }
++ else if (!autoBlink)
++ {
++ _model->SetParameterValue(idMan->GetId(_("ParamEyeROpen")), 1);
++ }
++
++
++ if (params.useLipSync && _lipSync)
++ {
++ csmFloat32 value = params.lipSyncParam; // 0 to 1
++
+ for (csmUint32 i = 0; i < _lipSyncIds.GetSize(); ++i)
+ {
+ _model->AddParameterValue(_lipSyncIds[i], value, 0.8f);
+ }
+ else
+ {
-+ _model->SetParameterValue(idMan->GetId("ParamMouthOpenY"),
-+ params.mouthOpenness);
++ _model->SetParameterValue(idMan->GetId(_("ParamMouthOpenY")),
++ params.live2d["ParamMouthOpenY"]);
+ }
+
-+ _model->SetParameterValue(idMan->GetId("ParamEyeLSmile"),
-+ params.leftEyeSmile);
-+ _model->SetParameterValue(idMan->GetId("ParamEyeRSmile"),
-+ params.rightEyeSmile);
-+ _model->SetParameterValue(idMan->GetId("ParamAngleX"),
-+ params.faceXAngle);
-+ _model->SetParameterValue(idMan->GetId("ParamAngleY"),
-+ params.faceYAngle);
-+ _model->SetParameterValue(idMan->GetId("ParamAngleZ"),
-+ params.faceZAngle);
-+ if (params.autoBreath && _breath)
++ for (auto const &entry : params.live2d)
+ {
++ std::string key = entry.first;
++ double val = entry.second;
+
+- // 状態更新/RMS値取得
+- _wavFileHandler.Update(deltaTimeSeconds);
+- value = _wavFileHandler.GetRms();
++ if (key != "ParamEyeLOpen" && key != "ParamEyeROpen" &&
++ key != "ParamMouthOpenY")
++ {
++ _model->SetParameterValue(idMan->GetId(_(key)), val);
++ }
++ }
+
+- for (csmUint32 i = 0; i < _lipSyncIds.GetSize(); ++i)
++ if (params.autoBreath && _breath)
+ {
+- _model->AddParameterValue(_lipSyncIds[i], value, 0.8f);
+ // Note: _model->LoadParameters and SaveParameters is needed
+ // before - see above.
+ _breath->UpdateParameters(_model, deltaTimeSeconds);
-+ }
- }
-
- // 物理演算の設定
-@@ -396,17 +388,6 @@ void LAppModel::Update()
- _physics->Evaluate(_model, deltaTimeSeconds);
+ }
}
-- // リップシンクの設定
-- if (_lipSync)
-- {
-- csmFloat32 value = 0; // リアルタイムでリップシンクを行う場合、システムから音量を取得して0〜1の範囲で値を入力します。
--
-- for (csmUint32 i = 0; i < _lipSyncIds.GetSize(); ++i)
-- {
-- _model->AddParameterValue(_lipSyncIds[i], value, 0.8f);
-- }
-- }
--
++ // 物理演算の設定
++ if (_physics != NULL)
++ {
++ _physics->Evaluate(_model, deltaTimeSeconds);
++ }
++
// ポーズの設定
if (_pose != NULL)
{
-@@ -626,3 +607,9 @@ Csm::Rendering::CubismOffscreenFrame_Ope
+@@ -492,7 +521,6 @@ CubismMotionQueueEntryHandle LAppModel::
+ {
+ csmString path = voice;
+ path = _modelHomeDir + path;
+- _wavFileHandler.Start(path);
+ }
+
+ if (_debugMode)
+@@ -644,3 +672,42 @@ Csm::Rendering::CubismOffscreenFrame_Ope
{
return _renderBuffer;
}
+ _tracker = tracker;
+}
+
++Csm::ICubismModelSetting* LAppModel::GetModelSetting(void) const
++{
++ return _modelSetting;
++}
++
++Csm::csmString LAppModel::_(std::string s)
++{
++ std::string ans;
++ if (_useOldParamId)
++ {
++ if (s == "ParamTere")
++ {
++ ans = "PARAM_CHEEK";
++ }
++ else
++ {
++ for (size_t i = 0; i < s.size(); i++)
++ {
++ if (std::isupper(s[i]) && i != 0)
++ {
++ ans += '_';
++ }
++ ans += std::toupper(s[i]);
++ }
++ }
++ }
++ else
++ {
++ ans = s;
++ }
++ return csmString(ans.c_str());
++}
++
diff -pruN --exclude build ./demo_clean/src/LAppModel.hpp ./demo_dev/src/LAppModel.hpp
---- ./demo_clean/src/LAppModel.hpp 2020-10-02 02:01:04.829787750 +0100
-+++ ./demo_dev/src/LAppModel.hpp 2020-10-01 23:35:39.254849094 +0100
-@@ -13,6 +13,7 @@
+--- ./demo_clean/src/LAppModel.hpp 2022-09-14 12:08:43.000000000 +0100
++++ ./demo_dev/src/LAppModel.hpp 2021-04-28 12:27:55.836457680 +0100
+@@ -13,7 +13,7 @@
#include <Type/csmRectF.hpp>
#include <Rendering/OpenGL/CubismOffscreenSurface_OpenGLES2.hpp>
+-#include "LAppWavFileHandler.hpp"
+#include "mouse_cursor_tracker.h"
/**
* @brief ユーザーが実際に使用するモデルの実装クラス<br>
-@@ -113,6 +114,13 @@ public:
+@@ -25,8 +25,11 @@ class LAppModel : public Csm::CubismUser
+ public:
+ /**
+ * @brief コンストラクタ
++ *
++ * @param[in] useOldParamId : If true, translate new (Cubism 3+)
++ * parameter IDs to old (Cubism 2.1) ones
+ */
+- LAppModel();
++ LAppModel(bool useOldParamId);
+
+ /**
+ * @brief デストラクタ
+@@ -114,6 +117,15 @@ public:
*/
Csm::Rendering::CubismOffscreenFrame_OpenGLES2& GetRenderBuffer();
+ */
+ void SetTracker(MouseCursorTracker *tracker);
+
++ Csm::ICubismModelSetting* GetModelSetting(void) const;
++
protected:
/**
* @brief モデルを描画する処理。モデルを描画する空間のView-Projection行列を渡す。
-@@ -183,6 +191,8 @@ private:
+@@ -167,6 +179,17 @@ private:
+ */
+ void ReleaseExpressions();
+
++ /**
++ * @brief Translate new (Cubism 3+) parameter IDs to old (Cubism 2.1) ones
++ *
++ * @param[in] s : New parameter ID
++ *
++ * @return Old parameter ID
++ */
++ Csm::csmString _(std::string s);
++
++ bool _useOldParamId;
++
+ Csm::ICubismModelSetting* _modelSetting; ///< モデルセッティング情報
+ Csm::csmString _modelHomeDir; ///< モデルセッティングが置かれたディレクトリ
+ Csm::csmFloat32 _userTimeSeconds; ///< デルタ時間の積算値[秒]
+@@ -183,9 +206,9 @@ private:
+ const Csm::CubismId* _idParamEyeBallX; ///< パラメータID: ParamEyeBallX
const Csm::CubismId* _idParamEyeBallY; ///< パラメータID: ParamEyeBallXY
+- LAppWavFileHandler _wavFileHandler; ///< wavファイルハンドラ
+-
Csm::Rendering::CubismOffscreenFrame_OpenGLES2 _renderBuffer; ///< フレームバッファ以外の描画先
+
+ MouseCursorTracker *_tracker;
diff -pruN --exclude build ./demo_clean/src/LAppPal.cpp ./demo_dev/src/LAppPal.cpp
---- ./demo_clean/src/LAppPal.cpp 2020-10-02 02:01:04.829787750 +0100
-+++ ./demo_dev/src/LAppPal.cpp 2020-10-01 22:47:24.722848453 +0100
+--- ./demo_clean/src/LAppPal.cpp 2022-09-14 12:08:43.000000000 +0100
++++ ./demo_dev/src/LAppPal.cpp 2021-04-28 12:18:50.952333251 +0100
@@ -6,6 +6,7 @@
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
-@@ -45,10 +46,7 @@ csmByte* LAppPal::LoadFileAsBytes(const
+@@ -36,7 +37,6 @@ csmByte* LAppPal::LoadFileAsBytes(const
+ if (stat(path, &statBuf) == 0)
+ {
+ size = statBuf.st_size;
+- PrintLog(path);
+ }
+
+ std::fstream file;
+@@ -45,10 +45,7 @@ csmByte* LAppPal::LoadFileAsBytes(const
file.open(path, std::ios::in | std::ios::binary);
if (!file.is_open())
{
}
file.read(buf, size);
diff -pruN --exclude build ./demo_clean/src/LAppTextureManager.cpp ./demo_dev/src/LAppTextureManager.cpp
---- ./demo_clean/src/LAppTextureManager.cpp 2020-10-02 02:01:04.833787812 +0100
-+++ ./demo_dev/src/LAppTextureManager.cpp 2020-10-01 22:47:24.654849690 +0100
+--- ./demo_clean/src/LAppTextureManager.cpp 2022-09-14 12:08:43.000000000 +0100
++++ ./demo_dev/src/LAppTextureManager.cpp 2021-04-28 12:18:50.952333251 +0100
@@ -96,6 +96,46 @@ LAppTextureManager::TextureInfo* LAppTex
}
{
for (Csm::csmUint32 i = 0; i < _textures.GetSize(); i++)
diff -pruN --exclude build ./demo_clean/src/LAppTextureManager.hpp ./demo_dev/src/LAppTextureManager.hpp
---- ./demo_clean/src/LAppTextureManager.hpp 2020-10-02 02:01:04.825787688 +0100
-+++ ./demo_dev/src/LAppTextureManager.hpp 2020-10-01 22:47:24.786847290 +0100
+--- ./demo_clean/src/LAppTextureManager.hpp 2022-09-14 12:08:43.000000000 +0100
++++ ./demo_dev/src/LAppTextureManager.hpp 2021-04-28 12:18:50.952333251 +0100
@@ -72,6 +72,8 @@ public:
*/
TextureInfo* CreateTextureFromPngFile(std::string fileName);
* @brief 画像の解放
*
diff -pruN --exclude build ./demo_clean/src/LAppView.cpp ./demo_dev/src/LAppView.cpp
---- ./demo_clean/src/LAppView.cpp 2020-10-02 02:01:04.833787812 +0100
-+++ ./demo_dev/src/LAppView.cpp 2020-10-01 22:47:24.602850636 +0100
+--- ./demo_clean/src/LAppView.cpp 2022-09-14 12:08:43.000000000 +0100
++++ ./demo_dev/src/LAppView.cpp 2021-04-28 12:18:50.952333251 +0100
@@ -13,7 +13,6 @@
#include "LAppLive2DManager.hpp"
#include "LAppTextureManager.hpp"
}
void LAppView::Initialize()
-@@ -97,9 +89,6 @@ void LAppView::Initialize()
+@@ -107,9 +99,6 @@ void LAppView::Initialize()
void LAppView::Render()
{
_back->Render();
LAppLive2DManager* Live2DManager = LAppLive2DManager::GetInstance();
-@@ -139,35 +128,17 @@ void LAppView::InitializeSprite()
+@@ -151,35 +140,17 @@ void LAppView::InitializeSprite()
glfwGetWindowSize(LAppDelegate::GetInstance()->GetWindow(), &width, &height);
LAppTextureManager* textureManager = LAppDelegate::GetInstance()->GetTextureManager();
// 画面全体を覆うサイズ
x = width * 0.5f;
y = height * 0.5f;
-@@ -175,52 +146,6 @@ void LAppView::InitializeSprite()
+@@ -187,52 +158,6 @@ void LAppView::InitializeSprite()
}
float LAppView::TransformViewX(float deviceX) const
{
float screenX = _deviceToScreen->TransformX(deviceX); // 論理座標変換した座標を取得。
-@@ -362,32 +287,4 @@ void LAppView::ResizeSprite()
+@@ -374,32 +299,4 @@ void LAppView::ResizeSprite()
_back->ResetRect(x, y, fWidth, fHeight);
}
}
- }
}
diff -pruN --exclude build ./demo_clean/src/LAppView.hpp ./demo_dev/src/LAppView.hpp
---- ./demo_clean/src/LAppView.hpp 2020-10-02 02:01:04.825787688 +0100
-+++ ./demo_dev/src/LAppView.hpp 2020-10-01 22:47:24.802846999 +0100
+--- ./demo_clean/src/LAppView.hpp 2022-09-14 12:08:43.000000000 +0100
++++ ./demo_dev/src/LAppView.hpp 2021-04-28 12:18:50.952333251 +0100
@@ -14,7 +14,6 @@
#include "CubismFramework.hpp"
#include <Rendering/OpenGL/CubismOffscreenSurface_OpenGLES2.hpp>
// レンダリング先を別ターゲットにする方式の場合に使用
LAppSprite* _renderSprite; ///< モードによっては_renderBufferのテクスチャを描画
diff -pruN --exclude build ./demo_clean/src/main.cpp ./demo_dev/src/main.cpp
---- ./demo_clean/src/main.cpp 2020-10-02 02:01:04.825787688 +0100
-+++ ./demo_dev/src/main.cpp 2020-10-01 23:42:12.845205308 +0100
-@@ -5,18 +5,154 @@
+--- ./demo_clean/src/main.cpp 2022-09-14 12:08:43.000000000 +0100
++++ ./demo_dev/src/main.cpp 2021-04-28 12:28:55.845339613 +0100
+@@ -5,18 +5,188 @@
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
+#include <thread>
+#include <stdexcept>
+#include <sstream>
++#include <vector>
++#include <utility>
++#include <string>
+
+#ifdef __cpp_lib_filesystem
+#include <filesystem>
+namespace fs = std::experimental::filesystem;
+#endif
+
++#include "ICubismModelSetting.hpp"
#include "LAppDelegate.hpp"
+#include "LAppLive2DManager.hpp"
++#include "LAppModel.hpp"
+#include "mouse_cursor_tracker.h"
+
+struct CmdArgs
+ float translateX;
+ float translateY;
+ std::string modelName;
++ bool oldId; // If true, translate new (Cubism 3+) parameter IDs to old (Cubism 2.1) IDs
+ std::string cfgPath; // Path to config file for MouseCursorTracker
+};
+
+ cmdArgs.windowHeight = 600;
+ cmdArgs.windowTitle = "MouseTrackerForCubism example";
+ cmdArgs.rootDir = fs::current_path();
-+ cmdArgs.scaleFactor = 8.0f;
++ cmdArgs.scaleFactor = 4.5f;
+ cmdArgs.translateX = 0.0f;
-+ cmdArgs.translateY = -2.8f;
++ cmdArgs.translateY = -3.1f;
+ cmdArgs.modelName = "Haru";
++ cmdArgs.oldId = false;
+ cmdArgs.cfgPath = "";
+
+ int i = 1;
+ {
+ cmdArgs.cfgPath = argv[i + 1];
+ }
++ else if (arg == "--old-param-id" || arg == "-o")
++ {
++ cmdArgs.oldId = (argv[i + 1][0] == '1');
++ }
+ else
+ {
+ throw std::runtime_error("Unrecognized argument: " + arg);
- LAppDelegate::GetInstance()->Run();
+ delegate->SetRootDirectory(cmdArgs.rootDir);
+
-+ MouseCursorTracker tracker(cmdArgs.cfgPath);
-+
-+ std::thread trackerThread(&MouseCursorTracker::mainLoop, &tracker);
-+
+ LAppLive2DManager *manager = LAppLive2DManager::GetInstance();
-+ manager->SetModel(cmdArgs.modelName);
++ manager->SetModel(cmdArgs.modelName, cmdArgs.oldId);
+
+ manager->SetProjectionScaleTranslate(cmdArgs.scaleFactor,
+ cmdArgs.translateX,
+ cmdArgs.translateY);
++
++ LAppModel *model = manager->GetModel(0);
++ if (!model) throw std::runtime_error("model is null");
++
++ Live2D::Cubism::Framework::ICubismModelSetting *modelSetting = model->GetModelSetting();
++ if (!modelSetting) throw std::runtime_error("modelSetting is null");
++
++ std::vector<std::pair<std::string, int> > motions;
++ int motionGroupCount = modelSetting->GetMotionGroupCount();
++ for (int i = 0; i < motionGroupCount; i++)
++ {
++ const char *motionGroup = modelSetting->GetMotionGroupName(i);
++ int motionCount = modelSetting->GetMotionCount(motionGroup);
++ motions.push_back(std::make_pair(std::string(motionGroup), motionCount));
++ }
++
++ std::vector<std::string> expressions;
++ int expCount = modelSetting->GetExpressionCount();
++ for (int i = 0; i < expCount; i++)
++ {
++ const char *expName = modelSetting->GetExpressionName(i);
++ expressions.push_back(std::string(expName));
++ }
++
++ MouseCursorTracker tracker(cmdArgs.cfgPath, motions, expressions);
++
++ std::thread trackerThread(&MouseCursorTracker::mainLoop, &tracker);
+ manager->SetTracker(&tracker);
+
+ delegate->Run();